Skip to content

Commit 7a035d8

Browse files
committed
[docs] Generate all :board docs explicitly
1 parent 85b81b6 commit 7a035d8

File tree

5 files changed

+74
-32
lines changed

5 files changed

+74
-32
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ documentation.
163163
<td align="center">NUCLEO-L476RG</td>
164164
</tr><tr>
165165
<td align="center">OLIMEXINO-STM32</td>
166-
<td align="center">RASPBERRYPI</td>
166+
<td align="center">Raspberry Pi</td>
167167
<td align="center">SAMD21-MINI</td>
168168
<td align="center">STM32-F4VE</td>
169169
</tr><tr>

tools/scripts/docs_modm_io_generator.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,17 @@ def repopath(path):
2828
return Path(__file__).absolute().parents[2] / path
2929
def relpath(path):
3030
return os.path.relpath(path, str(repopath(".")))
31+
def rename_board(name):
32+
return name.replace("_", "-").replace(".", "-").replace(":", "-").upper()\
33+
.replace("BLUE-PILL", "Blue Pill") \
34+
.replace("BLACK-PILL", "Black Pill") \
35+
.replace("ARDUINO-UNO", "Arduino UNO") \
36+
.replace("ARDUINO-NANO", "Arduino NANO") \
37+
.replace("RASPBERRYPI", "Raspberry Pi")
3138

3239
sys.path.append(str(repopath("ext/modm-devices")))
3340
from modm_devices.device_identifier import *
3441

35-
3642
def get_targets():
3743
builder = lbuild.api.Builder()
3844
builder._load_repositories(repopath("repo.lb"))
@@ -75,7 +81,13 @@ def get_targets():
7581
for key, values in minimal_targets.items():
7682
target_list.append(sorted(values, key=lambda d: d.string)[-1])
7783

78-
return target_list
84+
# We must include all :board module targets manually
85+
board_list = []
86+
for board in repopath("src/modm/board").glob("*/board.xml"):
87+
target = re.search(r"< *option +name=\"modm:target\" *>(.*?)</ *option *>", board.read_text())[1]
88+
board_list.append( (board.parent.name.replace("_", "-"), target) )
89+
90+
return target_list, board_list
7991

8092

8193
def main():
@@ -92,13 +104,15 @@ def main():
92104
args = parser.parse_args()
93105

94106
device_list = []
107+
board_list = []
95108
if args.test:
96-
# test list
97109
device_list = ["hosted-linux", "atmega328p-au", "stm32f103c8t6", "stm32g474cet6", "samd21g18a-uu"]
110+
board_list = [("arduino-nano", "atmega328p-au"), ("arduino-uno", "atmega328p-au"), ("nucleo-g474re", "stm32g474ret6"),
111+
("blue-pill", "stm32f103c8t6"), ("feather-m0", "samd21g18a-uu")]
98112
elif args.test2:
99113
device_list = ["hosted-linux", "atmega328p-pu", "stm32f103zgt7", "stm32g474vet7"]
100114
else:
101-
device_list = get_targets()
115+
device_list, board_list = get_targets()
102116

103117
template_path = os.path.realpath(os.path.dirname(sys.argv[0]))
104118
cwd = Path().cwd()
@@ -115,11 +129,12 @@ def main():
115129
(output_dir / "develop/api").mkdir(parents=True)
116130
os.chdir(tempdir)
117131
print("Starting to generate documentation...")
118-
template_overview(output_dir, device_list, template_path)
132+
template_overview(output_dir, device_list, board_list, template_path)
119133
print("... for {} devices, estimated memory footprint is {} MB".format(len(device_list), (len(device_list)*70)+2000))
120134
with multiprocessing.Pool(args.jobs) as pool:
121135
# We can only pass one argument to pool.map
122-
devices = ["{}|{}|{}".format(modm_path, path_tempdir, d) for d in device_list]
136+
devices = ["{}|{}|{}|".format(modm_path, path_tempdir, dev) for dev in device_list]
137+
devices += ["{}|{}|{}|{}".format(modm_path, path_tempdir, dev, brd) for (brd, dev) in board_list]
123138
results = pool.map(create_target, devices)
124139
# output_dir.rename(cwd / 'modm-api-docs')
125140
if args.compress:
@@ -129,7 +144,7 @@ def main():
129144
# shutil.make_archive(str(cwd / 'modm-api-docs'), 'gztar', str(output_dir))
130145
else:
131146
final_output_dir = Path(args.output)
132-
if args.overwrite:
147+
if args.overwrite and final_output_dir.exists():
133148
for i in final_output_dir.iterdir():
134149
print('Removing {}'.format(i))
135150
if i.is_dir():
@@ -143,9 +158,10 @@ def main():
143158

144159

145160
def create_target(argument):
146-
modm_path, tempdir, device = argument.split("|")
161+
modm_path, tempdir, device, board = argument.split("|")
162+
output_dir = board if board else device
147163
try:
148-
print("Generating documentation for {} ...".format(device))
164+
print("Generating documentation for {} ...".format(output_dir))
149165

150166
options = ["modm:target={0}".format(device)]
151167
if device.startswith("at"):
@@ -154,9 +170,12 @@ def create_target(argument):
154170
builder.load([Path(modm_path) / "repo.lb", Path(modm_path) / "test/repo.lb"])
155171
modules = sorted(builder.parser.modules.keys())
156172

157-
# Only allow the first board module to be built (they overwrite each others files)
158-
first_board = next((m for m in modules if ":board:" in m), None)
159-
modules = [m for m in modules if ":board" not in m or m == first_board]
173+
if board:
174+
chosen_board = "modm:board:{}".format(board)
175+
else:
176+
# Only allow the first board module to be built (they overwrite each others files)
177+
chosen_board = next((m for m in modules if ":board:" in m), None)
178+
modules = [m for m in modules if ":board" not in m or m == chosen_board]
160179

161180
# Remove :tinyusb:host modules, they conflict with :tinyusb:device modules
162181
modules = [m for m in modules if ":tinyusb:host" not in m]
@@ -165,23 +184,25 @@ def create_target(argument):
165184
# exist are include as dependencies of the :platform modules.
166185
modules = [m for m in modules if ":architecture" not in m]
167186

168-
builder.build(device, modules)
187+
builder.build(output_dir, modules)
169188

170-
print('Executing: (cd {}/modm/docs/ && doxypress doxypress.json)'.format(device))
171-
os.system('(cd {}/modm/docs/ && doxypress doxypress.json > /dev/null 2>&1)'.format(device))
172-
(Path(tempdir) / device / "modm/docs/html").rename(Path(tempdir) / 'output/develop/api' / device)
173-
print("Finished generating documentation for device {}.".format(device))
189+
print('Executing: (cd {}/modm/docs/ && doxypress doxypress.json)'.format(output_dir))
190+
os.system('(cd {}/modm/docs/ && doxypress doxypress.json > /dev/null 2>&1)'.format(output_dir))
191+
(Path(tempdir) / output_dir / "modm/docs/html").rename(Path(tempdir) / 'output/develop/api' / output_dir)
192+
print("Finished generating documentation for device {}.".format(output_dir))
174193
return True
175194
except Exception as e:
176-
print("Error generating documentation for device {}: {}".format(device, e))
195+
print("Error generating documentation for device {}: {}".format(output_dir, e))
177196
return False
178197

179198

180-
def template_overview(output_dir, device_list, template_path):
199+
def template_overview(output_dir, device_list, board_list, template_path):
181200
html = Environment(loader=FileSystemLoader(template_path)).get_template("docs_modm_io_index.html.in").render(
182201
devices=device_list,
202+
boards=[(b, rename_board(b), d) for (b,d) in board_list],
183203
date=datetime.datetime.now().strftime("%d.%m.%Y, %H:%M"),
184-
num_devices=len(device_list))
204+
num_devices=len(device_list),
205+
num_boards=len(board_list))
185206
with open(str(output_dir) + "/index.html","w+") as f:
186207
f.write(html)
187208
with open(str(output_dir) + "/robots.txt","w+") as f:

tools/scripts/docs_modm_io_index.html.in

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ input, select {
4242
input[type=text] {
4343
background-color: #f1f1f1;
4444
width: 100%;
45-
text-transform: uppercase;
4645
}
4746
input[type=text]::placeholder {
4847
text-transform: none;
@@ -60,7 +59,6 @@ input[type=submit] {
6059
top: 100%;
6160
left: 0;
6261
right: 0;
63-
text-transform: uppercase;
6462
}
6563
.autocomplete-items div {
6664
padding: 10px;
@@ -85,24 +83,26 @@ input[type=submit] {
8583
<h1>API documentation</h1>
8684
</header>
8785
<main>
88-
<p id="numtargets">Documentation is available for {{ num_devices }} devices.</p>
86+
<p id="numtargets">Documentation is available for {{ num_devices }} devices and {{ num_boards }} boards.</p>
8987
<h3>Select your target:</h3>
9088
<form autocomplete="off" action="javascript:showDocumentation()">
9189
<table>
9290
<tr>
93-
<td>Version/Release</td>
94-
<td>Microcontroller</td>
91+
<!-- <td>Version/Release</td> -->
92+
<td>Device or Board</td>
9593
<td>&nbsp;</td>
9694
</tr>
9795
<tr>
96+
<!--
9897
<td>
9998
<select id="releaseinput" name="releases">
10099
<option>develop</option>
101100
</select>
102101
</td>
102+
-->
103103
<td>
104104
<div class="autocomplete" style="width:300px;">
105-
<input id="targetinput" type="text" name="target" placeholder="Type e.g. 'F407'">
105+
<input id="targetinput" type="text" name="target" placeholder="Search for e.g. 'F469' or 'NUCLEO'">
106106
</div>
107107
</td>
108108
<td>
@@ -112,15 +112,23 @@ input[type=submit] {
112112
</table>
113113
</form>
114114
<br />
115-
<small>For most microcontrollers-sub-families only the variant with largest pin-count and memory is available.</small>
115+
<small>For most microcontroller sub-families only the variant with largest pin-count and memory is available.</small>
116116
<p>Last updated: {{ date }}</p>
117117

118118
<script type="text/javascript">
119119
var devices = [
120120
{% for d in devices %}
121-
"{{ d }}",
121+
"{{ d | upper }}",
122+
{% endfor %}
123+
{% for (_, b, _) in boards %}
124+
"{{ b }}",
122125
{% endfor %}
123126
];
127+
var name2board = {
128+
{% for (b, n, _) in boards %}
129+
"{{ n }}": "{{ b }}",
130+
{% endfor %}
131+
};
124132
var targetinput = document.getElementById("targetinput");
125133
var currentFocus;
126134
function showDocumentation() {
@@ -133,6 +141,7 @@ function showDocumentation() {
133141
}, 5000);
134142
return;
135143
}
144+
/*
136145
if(!releaseinput.value) {
137146
releaseinput.style.transition = "border 5ms ease-out";
138147
releaseinput.style.borderColor = "red";
@@ -143,6 +152,9 @@ function showDocumentation() {
143152
return;
144153
}
145154
var url = "/" + releaseinput.value + "/api/" + targetinput.value + "/";
155+
*/
156+
n2b = name2board[targetinput.value]
157+
var url = "/develop/api/" + (n2b ? n2b : targetinput.value).toLowerCase() + "/";
146158
location.href = url;
147159
}
148160
targetinput.addEventListener("input", function(event) {
@@ -219,10 +231,13 @@ document.addEventListener("click", function (element) {
219231
</script>
220232
<noscript>
221233
<h3>Select your target</h3>
222-
<input type="text" id="input" placeholder="Type e.g. 'F407'" />
234+
<input type="text" id="input" placeholder="Search for e.g. 'F469' or 'NUCLEO'"/>
223235
<ul>
236+
{% for (board, name, _) in boards %}
237+
<li id="{{ board }}"><a href="/develop/api/{{ board }}/">{{ name }}</a></li>
238+
{% endfor %}
224239
{% for d in devices %}
225-
<li id="{{ d }}"><a href="/develop/api/{{ d }}/">{{ d }}</a></li>
240+
<li id="{{ d }}"><a href="/develop/api/{{ d }}/">{{ d | upper }}</a></li>
226241
{% endfor %}
227242
</ul>
228243
</noscript>

tools/scripts/generate_module_docs.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,14 @@ def get_modules(builder, limit=None):
5555
else:
5656
targets.append(d)
5757

58+
# We must include all :board module targets for reproducibility!!!
59+
for board in repopath("src/modm/board").glob("*/board.xml"):
60+
target = re.search(r"< *option +name=\"modm:target\" *>(.*?)</ *option *>", board.read_text())
61+
targets.append(target[1])
62+
5863
if limit is not None:
5964
targets = targets[:limit]
60-
targets = sorted(targets)
65+
targets = sorted(list(set(targets)))
6166

6267
# Prime the repositories and get all module files
6368
mfiles = []

tools/scripts/synchronize_docs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def name(raw_name):
5151
.replace("BLACK-PILL", "Black Pill")\
5252
.replace("ARDUINO-UNO", "Arduino UNO")\
5353
.replace("ARDUINO-NANO", "Arduino NANO")\
54+
.replace("RASPBERRYPI", "Raspberry Pi")\
5455
.replace("GENERIC", "Generic")\
5556
.replace("LINUX", "Linux")\
5657
.replace("WINDOWS", "Windows")\

0 commit comments

Comments
 (0)