Skip to content

Commit b27c373

Browse files
authored
Merge pull request #500 from neuromatch/jupyter-book-2
Jupyter book 2
2 parents 68d010d + c8a4ed4 commit b27c373

2 files changed

Lines changed: 36 additions & 39 deletions

File tree

generate_book_v2.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,7 @@ def make_myst_iframe(url, width="100%"):
304304
if platform == "Youtube":
305305
iframe_url = f"https://www.youtube.com/embed/{vid_id}?fs=1&rel=0"
306306
elif platform == "Bilibili":
307-
iframe_url = (
308-
f"https://player.bilibili.com/player.html?bvid={vid_id}&page=1"
309-
)
307+
iframe_url = f"https://player.bilibili.com/player.html?bvid={vid_id}&page=1&autoplay=0"
310308
else:
311309
print(
312310
f" Warning: unknown video platform '{platform}' (id={vid_id}), skipping"

parse_html_for_errors_v2.py

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,70 +14,69 @@
1414
outputs-container holds an error, then decompose the parent
1515
div[data-name="outputs-container"] so nothing is left behind.
1616
17+
JB2/MyST flattens output into slug-based directories rather than mirroring
18+
the input path structure. We therefore scan every index.html under the
19+
build output tree instead of constructing paths from materials.yml.
20+
1721
Run as: python parse_html_for_errors_v2.py student
1822
"""
1923

2024
import os
2125
import sys
22-
import yaml
2326
from bs4 import BeautifulSoup
2427

25-
ARG = sys.argv[1] # "student" or "instructor"
28+
sys.argv[1] # "student" or "instructor" — accepted but not used (kept for compat)
2629

2730
ERROR_STRINGS = ["NotImplementedError", "NameError"]
2831

32+
HTML_ROOT = "book/_build/html"
2933

30-
def main():
31-
with open("tutorials/materials.yml") as fh:
32-
materials = yaml.load(fh, Loader=yaml.FullLoader)
3334

34-
html_directory = "book/_build/html/"
35+
def main():
3536
total_removed = 0
36-
37-
for m in materials:
38-
name = f"{m['day']}_{''.join(m['name'].split())}"
39-
40-
notebook_paths = []
41-
if os.path.exists(f"tutorials/{name}/{m['day']}_Intro.ipynb"):
42-
notebook_paths.append(
43-
f"{html_directory}/tutorials/{name}/{ARG}/{m['day']}_Intro.html"
44-
)
45-
notebook_paths += [
46-
f"{html_directory}/tutorials/{name}/{ARG}/{m['day']}_Tutorial{i + 1}.html"
47-
for i in range(m["tutorials"])
48-
]
49-
if os.path.exists(f"tutorials/{name}/{m['day']}_Outro.ipynb"):
50-
notebook_paths.append(
51-
f"{html_directory}/tutorials/{name}/{ARG}/{m['day']}_Outro.html"
52-
)
53-
54-
for html_path in notebook_paths:
55-
if not os.path.exists(html_path):
56-
print(f" Warning: {html_path} not found, skipping")
37+
files_touched = 0
38+
39+
if not os.path.isdir(HTML_ROOT):
40+
print(
41+
f"ERROR: HTML output directory not found: {HTML_ROOT!r} (cwd={os.getcwd()!r})"
42+
)
43+
sys.exit(1)
44+
45+
all_index_files = []
46+
for dirpath, _dirnames, filenames in os.walk(HTML_ROOT):
47+
for fname in filenames:
48+
if fname == "index.html":
49+
all_index_files.append(os.path.join(dirpath, fname))
50+
print(f"Found {len(all_index_files)} index.html files under {HTML_ROOT}")
51+
52+
for dirpath, _dirnames, filenames in os.walk(HTML_ROOT):
53+
for fname in filenames:
54+
if fname != "index.html":
5755
continue
56+
html_path = os.path.join(dirpath, fname)
5857

5958
with open(html_path, encoding="utf-8") as f:
6059
contents = f.read()
6160

6261
parsed_html = BeautifulSoup(contents, features="html.parser")
6362
removed = strip_error_divs(parsed_html)
64-
total_removed += removed
6563

6664
# Put solution figures in center (matches JB1 behaviour)
6765
for img in parsed_html.find_all("img", alt=True):
6866
if img["alt"] == "Solution hint":
6967
img["align"] = "center"
7068
img["class"] = "align-center"
7169

72-
with open(html_path, "w", encoding="utf-8") as f:
73-
f.write(str(parsed_html))
74-
7570
if removed:
76-
print(
77-
f" Stripped {removed} error div(s) from {os.path.basename(html_path)}"
78-
)
79-
80-
print(f"Done. Removed {total_removed} error output div(s) total.")
71+
total_removed += removed
72+
files_touched += 1
73+
with open(html_path, "w", encoding="utf-8") as f:
74+
f.write(str(parsed_html))
75+
print(f" Stripped {removed} error div(s) from {html_path}")
76+
77+
print(
78+
f"Done. Removed {total_removed} error output div(s) from {files_touched} file(s)."
79+
)
8180

8281

8382
def strip_error_divs(parsed_html):

0 commit comments

Comments
 (0)