|
1 | 1 | import os |
2 | | -import re |
3 | 2 | import subprocess |
4 | 3 | import sys |
5 | 4 |
|
|
76 | 75 | "logo": { |
77 | 76 | "image_dark": "_static/RoboVerse86.22.svg", |
78 | 77 | }, |
| 78 | + # Top navbar shows only the two cross-subsite links (MetaSim ↔ RoboVerse) |
| 79 | + # via ``external_links`` (rendered through our overridden navbar-nav |
| 80 | + # template). All in-site navigation lives in the left sidebar. |
79 | 81 | "navbar_center": ["version-switcher", "navbar-nav"], |
| 82 | + "external_links": [ |
| 83 | + {"name": "MetaSim", "url": "/metasim/"}, |
| 84 | + {"name": "RoboVerse", "url": "/roboverse/"}, |
| 85 | + {"name": "FAQ", "url": "/FAQ/"}, |
| 86 | + ], |
80 | 87 | "show_version_warning_banner": False, |
81 | 88 | "switcher": { |
82 | 89 | "json_url": json_url, |
|
100 | 107 | html_show_sphinx = False |
101 | 108 | html_static_path = ["_static"] |
102 | 109 |
|
| 110 | +# Homepage shows only the body content (hero-style intro, no left rail); |
| 111 | +# every other page renders our custom sidebar-section-nav template, which |
| 112 | +# shows the captioned global toctree with ``startdepth=0 + includehidden=True`` |
| 113 | +# so even root-of-section pages get a populated sidebar. |
| 114 | +html_sidebars = { |
| 115 | + "index": [], |
| 116 | + "**": ["sidebar-section-nav.html"], |
| 117 | +} |
| 118 | + |
103 | 119 | ### Autodoc configurations ### |
104 | 120 | autoclass_content = "class" |
105 | 121 | autodoc_typehints = "signature" |
@@ -229,85 +245,6 @@ def generate_task_markdown(app): |
229 | 245 | ) |
230 | 246 |
|
231 | 247 |
|
232 | | -_NAVBAR_LABELS = { |
233 | | - "dataset_benchmark": {"short": "Dataset", "full": "Dataset and Benchmark"}, |
234 | | - "roboverse_learn": {"short": "Learn", "full": "RoboVerse Learn"}, |
235 | | - "FAQ": {"short": "FAQ", "full": "Frequently Asked Questions"}, |
236 | | -} |
237 | | - |
238 | | - |
239 | | -def _active_navbar_section(pagename): |
240 | | - section = pagename.split("/", 1)[0] |
241 | | - return section if section in _NAVBAR_LABELS else None |
242 | | - |
243 | | - |
244 | | -def _navbar_section_from_href(href, active_section): |
245 | | - if href == "#": |
246 | | - return active_section |
247 | | - for section in _NAVBAR_LABELS: |
248 | | - if href.endswith(f"{section}/index.html"): |
249 | | - return section |
250 | | - return None |
251 | | - |
252 | | - |
253 | | -def _replace_navbar_item_label(match, active_section): |
254 | | - item_html = match.group(0) |
255 | | - href_match = re.search(r'href="([^"]+)"', item_html) |
256 | | - if href_match is None: |
257 | | - return item_html |
258 | | - |
259 | | - section = _navbar_section_from_href(href_match.group(1), active_section) |
260 | | - if section is None: |
261 | | - return item_html |
262 | | - |
263 | | - label_kind = "full" if section == active_section else "short" |
264 | | - label = _NAVBAR_LABELS[section][label_kind] |
265 | | - return re.sub(r"(>)[^<>]+(</a>)", rf"\1{label}\2", item_html, count=1) |
266 | | - |
267 | | - |
268 | | -def _rewrite_navbar_labels(html, pagename): |
269 | | - active_section = _active_navbar_section(pagename) |
270 | | - |
271 | | - def rewrite_navbar(match): |
272 | | - navbar_html = match.group(0) |
273 | | - return re.sub( |
274 | | - r'<li class="nav-item[^"]*">.*?</li>', |
275 | | - lambda item_match: _replace_navbar_item_label(item_match, active_section), |
276 | | - navbar_html, |
277 | | - flags=re.DOTALL, |
278 | | - ) |
279 | | - |
280 | | - return re.sub( |
281 | | - r'<ul class="bd-navbar-elements navbar-nav">.*?</ul>', |
282 | | - rewrite_navbar, |
283 | | - html, |
284 | | - flags=re.DOTALL, |
285 | | - ) |
286 | | - |
287 | | - |
288 | | -def normalize_navbar_labels(app, exception): |
289 | | - if exception is not None or app.builder.name != "html": |
290 | | - return |
291 | | - |
292 | | - outdir = os.path.abspath(app.outdir) |
293 | | - for section in ("", *[f"{section}/" for section in _NAVBAR_LABELS]): |
294 | | - html_path = os.path.join(outdir, section, "index.html") |
295 | | - if not os.path.exists(html_path): |
296 | | - continue |
297 | | - |
298 | | - pagename = "index" if section == "" else f"{section.rstrip('/')}/index" |
299 | | - with open(html_path, encoding="utf-8") as f: |
300 | | - html = f.read() |
301 | | - |
302 | | - rewritten = _rewrite_navbar_labels(html, pagename) |
303 | | - if rewritten == html: |
304 | | - continue |
305 | | - |
306 | | - with open(html_path, "w", encoding="utf-8") as f: |
307 | | - f.write(rewritten) |
308 | | - |
309 | | - |
310 | 248 | def setup(app): |
311 | 249 | app.connect("autodoc-skip-member", skip_member) |
312 | 250 | app.connect("builder-inited", generate_task_markdown) |
313 | | - app.connect("build-finished", normalize_navbar_labels) |
0 commit comments