3
3
4
4
Generate quick API indexes in Restructured Text Format for Sphinx documentation.
5
5
"""
6
+ import math
6
7
import sys
8
+ from collections import defaultdict
9
+ from functools import lru_cache
7
10
from pathlib import Path
8
11
from typing import List
12
+ import logging
13
+
14
+ log = logging .getLogger (__name__ )
9
15
10
16
# Ensure we get utility and Arcade imports first
11
17
sys .path .insert (0 , str (Path (__file__ ).parent .resolve ()))
14
20
import arcade
15
21
from doc_helpers .vfs import Vfs
16
22
23
+
24
+ def announce_templating (var_name ):
25
+ _v = globals ()[var_name ]
26
+ log .warning (f"Templated { var_name } as { _v !r} " )
27
+
28
+ # The following are provided via runpy.run_path's init_globals keyword
29
+ # in conf.py. Uncomment for easy debugger run without IDE config.
30
+ try :
31
+ _ = GIT_REF # noqa
32
+ except Exception as _ :
33
+ GIT_REF = "development"
34
+ announce_templating ("GIT_REF" )
35
+ try :
36
+ _URL_BASE = "https://github.com/pythonarcade/arcade"
37
+ _ = FMT_URL_REF_PAGE # noqa
38
+ except Exception as _ :
39
+ FMT_URL_REF_PAGE = f"{ _URL_BASE } /blob/{ GIT_REF } /{{}}"
40
+ announce_templating ("FMT_URL_REF_PAGE" )
41
+ try :
42
+ _ = FMT_URL_REF_EMBED # noqa
43
+ except Exception as _ :
44
+ FMT_URL_REF_EMBED = f"{ _URL_BASE } /blob/{ GIT_REF } /{{}}?raw=true"
45
+ announce_templating ("FMT_URL_REF_EMBED" )
46
+
47
+
17
48
MODULE_DIR = Path (__file__ ).parent .resolve ()
18
49
ARCADE_ROOT = MODULE_DIR .parent
19
50
RESOURCE_DIR = ARCADE_ROOT / "arcade" / "resources"
20
51
OUT_FILE = ARCADE_ROOT / "doc" / "api_docs" / "resources.rst"
21
- RESOURCE_URL = "https://github.com/pythonarcade/arcade/blob/development/{}?raw=true"
22
52
23
- COLUMNS = 3
53
+
24
54
# Metadata for the resource list: utils\create_resource_list.py
25
55
skip_extensions = [
26
56
".glsl" ,
@@ -39,6 +69,22 @@ def skipped_file(file_path: Path):
39
69
return file_path .suffix in skip_extensions
40
70
41
71
72
+ MAX_COLS : dict [str , int ] = defaultdict (lambda : 3 )
73
+ MAX_COLS [":resources:sounds/" ] = 2
74
+
75
+
76
+ @lru_cache (maxsize = None )
77
+ def get_header_num_cols (resource_stub : str , n_files = math .inf ) -> int :
78
+ return int (min (MAX_COLS [resource_stub ], n_files ))
79
+
80
+
81
+ @lru_cache (maxsize = None )
82
+ def get_column_widths_for_n (n : int ) -> str :
83
+ width = str (100 // n )
84
+ return ' ' .join ((width for _ in range (n )))
85
+
86
+
87
+ @lru_cache (maxsize = None ) # Cache b/c re-using elsewhere
42
88
def create_resource_path (
43
89
path : Path ,
44
90
prefix : str = "" ,
@@ -71,18 +117,25 @@ def process_resource_directory(out, dir: Path):
71
117
# out.write("-" * len(cur_node.name) + "\n\n")
72
118
73
119
file_list = [item for item in path .iterdir () if not (item .is_dir () or skipped_file (item ))]
74
- if len (file_list ) > 0 :
120
+ num_files = len (file_list )
121
+ if num_files > 0 :
122
+
75
123
# header_title = f":resources:{path.relative_to(RESOURCE_DIR).as_posix()}/"
76
- header_title = create_resource_path (path , suffix = "/" )
77
- if header_title == ":resources:images/" :
124
+ raw_header = create_resource_path (path , suffix = "/" )
125
+ header_title = raw_header [:- 2 ] if raw_header .endswith ("./" ) else raw_header
126
+
127
+ if raw_header == ":resources:images/" :
78
128
for f in file_list :
79
129
print (f .name )
80
130
# out.write(f"\n{header_title}\n")
81
131
# out.write("-" * (len(header_title)) + "\n\n")
82
132
133
+ n_cols = get_header_num_cols (raw_header , num_files )
134
+ widths = get_column_widths_for_n (n_cols )
135
+
83
136
out .write (f"\n " )
84
- out .write (f".. list-table:: { header_title } \n " )
85
- out .write (f" :widths: 33 33 33 \n " )
137
+ out .write (f".. list-table:: \" { header_title } \" \n " )
138
+ out .write (f" :widths: { widths } \n " )
86
139
out .write (f" :header-rows: 0\n " )
87
140
out .write (f" :class: resource-table\n \n " )
88
141
@@ -92,46 +145,65 @@ def process_resource_directory(out, dir: Path):
92
145
process_resource_directory (out , path )
93
146
94
147
148
+ SUFFIX_TO_AUDIO_TYPE = {
149
+ '.wav' : 'x-wav' ,
150
+ '.ogg' : 'ogg' ,
151
+ '.mp3' : 'mpeg' ,
152
+ }
153
+ SUFFIX_TO_VIDEO_TYPE = {
154
+ '.mp4' : 'mp4' ,
155
+ '.webm' : 'webm' ,
156
+ '.avi' : 'avi'
157
+ }
158
+
95
159
def process_resource_files (out , file_list : List [Path ]):
96
- start_row = True
97
160
cell_count = 0
98
161
162
+ prefix = create_resource_path (file_list [0 ].parent , suffix = "/" )
163
+
164
+ COLUMNS = get_header_num_cols (prefix , len (file_list ))
165
+
166
+ log .info (f"Processing { prefix = !r} with { COLUMNS = !r} " )
99
167
for path in file_list :
100
168
resource_path = path .relative_to (ARCADE_ROOT ).as_posix ()
169
+ suffix = path .suffix
101
170
102
171
if cell_count % COLUMNS == 0 :
103
172
start_row = "*"
104
- if path .suffix in [".png" , ".jpg" , ".gif" , ".svg" ]:
173
+ else :
174
+ start_row = " "
175
+ name = path .name
176
+ resource_copyable = f"{ create_resource_path (path )} "
177
+ if suffix in [".png" , ".jpg" , ".gif" , ".svg" ]:
105
178
out .write (f" { start_row } - .. image:: ../../{ resource_path } \n \n " )
106
- out .write (f" { path . name } \n " )
107
- cell_count += 1
108
- elif path . suffix == ".wav" :
109
- file_path = RESOURCE_URL . format ( resource_path )
179
+ out .write (f" { name } \n " )
180
+ elif suffix in SUFFIX_TO_AUDIO_TYPE :
181
+ file_path = FMT_URL_REF_EMBED . format ( resource_path )
182
+ src_type = SUFFIX_TO_AUDIO_TYPE [ suffix ]
110
183
out .write (f" { start_row } - .. raw:: html\n \n " )
111
- out .write (f" <audio controls><source src='{ file_path } ' type='audio/x-wav'></audio><br />{ path .name } \n " )
112
- cell_count += 1
113
- elif path .suffix == ".mp3" :
114
- file_path = RESOURCE_URL .format (resource_path )
184
+ out .write (f" <audio controls><source src='{ file_path } ' type='audio/{ src_type } '></audio>\n " )
185
+ out .write (f" <br /><code class='literal'>"{ resource_copyable } "</code>\n " )
186
+ # out.write(f" <br /><a href={FMT_URL_REF_PAGE.format(resource_path)}>{path.name} on GitHub</a>\n")
187
+ elif suffix in SUFFIX_TO_VIDEO_TYPE :
188
+ file_path = FMT_URL_REF_EMBED .format (resource_path )
189
+ src_type = SUFFIX_TO_VIDEO_TYPE [suffix ]
115
190
out .write (f" { start_row } - .. raw:: html\n \n " )
116
- out .write (f" <audio controls><source src='{ file_path } ' type='audio/mpeg'></audio><br />{ path .name } \n " )
117
- cell_count += 1
118
- elif path .suffix == ".ogg" :
119
- file_path = RESOURCE_URL .format (resource_path )
120
- out .write (f" { start_row } - .. raw:: html\n \n " )
121
- out .write (f" <audio controls><source src='{ file_path } ' type='audio/ogg'></audio><br />{ path .name } \n " )
122
- cell_count += 1
123
- elif path .suffix == ".glsl" :
124
- file_path = RESOURCE_URL .format (resource_path )
125
- out .write (f" { start_row } - `{ path .name } <{ file_path } >`_\n " )
126
- # out.write(f" {start_row} - .. raw:: html\n\n")
127
- # out.write(f" <audio controls><source src='{file_path}' type='audio/ogg'></audio><br />{path.name}\n")
128
- cell_count += 1
191
+ out .write (f" <video style=\" max-width: 100%\" controls><source src='{ file_path } ' type='video/{ src_type } '></video>\n " )
192
+ out .write (f" <br /><code class='literal'>"{ resource_copyable } "</code>\n " )
193
+ elif suffix == ".glsl" :
194
+ file_path = FMT_URL_REF_PAGE .format (resource_path )
195
+ out .write (f" { start_row } - `{ path } <{ file_path } >`_\n " )
196
+ # Link Tiled maps
197
+ elif suffix == ".json" :
198
+ file_path = FMT_URL_REF_PAGE .format (resource_path )
199
+ out .write (f" { start_row } - `{ name } <{ file_path } >`_\n " )
129
200
else :
130
- out .write (f" { start_row } - { path . name } \n " )
131
- cell_count += 1
132
-
133
- start_row = " "
201
+ out .write (f" { start_row } - { name } \n " )
202
+ # The below doesn't work because of how raw HTML / Sphinx images interact:
203
+ # out.write(f" <br /><code class='literal'>{resource_copyable}</code>\n")
204
+ cell_count += 1
134
205
206
+ # Finish any remaining columns with empty cells
135
207
while cell_count % COLUMNS > 0 :
136
208
out .write (f" -\n " )
137
209
cell_count += 1
@@ -161,8 +233,10 @@ def resources():
161
233
out .close ()
162
234
print ("Done creating resources.rst" )
163
235
236
+
164
237
vfs = Vfs ()
165
238
239
+
166
240
def main ():
167
241
resources ()
168
242
vfs .write ()
0 commit comments