Repository navigation
Lecture repos moving off the Sphinx theme have no checklist of what myst.yml and CI must now set #209
Description
Part of #147 (parity study 2026-09-11 — migration readiness).
Revised in place 2026-09-11: the footer item follows the #203 decision (a theme default); two items came out of the #204 decision (the notebook header setting and the {raw} source rewrite); the launch item follows the #205 decision (explicit, opt-in launch options); and the #207 review added the site URL and old URLs items; and #210's close moved the Sphinx options with no counterpart into this page.
Problem
A lecture repo moving from quantecon-book-theme to this theme has to set up several things in myst.yml, in its lecture sources or in CI that its Sphinx build handled another way. Three came with the Sphinx theme and needed no per-repo setup: a hard-coded licence footer, a built-in MathJax macro set, and a per-page git lookup for "Last changed". The rest are set per repo today, but under _config.yml keys this theme does not read: the notebooks repo, the document language, the Google Analytics ID, and the description and keywords. The lecture sources also carry Sphinx-only {raw} blocks, and the notebook header now has to come from configuration. The docs explain most of the new mechanisms one feature at a time. No page lists them as steps for a migrating repo, and neither docs/ nor the README mentions maths macros at all.
mystmd's Jupyter Book config upgrade does not carry these settings across either. It reads the analytics ID only from the html section, sets project.github only from a top-level repository.url, and types sphinx.config as an opaque record that upgradeConfig never reads (config.ts:99-106, config.ts:147-236, config.ts:185-200). lecture-python-programming, for example, has no top-level repository key and keeps these settings under sphinx.config (_config.yml:17-69).
Item by item:
- Licence footer.
- The book theme puts the CC BY-SA 4.0 badge, the licence sentence and "A theme by QuantEcon" on every page (layout.html:353-361).
- Today this theme renders a footer only when
site.parts.footeris set (PageContent.tsx:105), and the live lecture-wasm site shows no licence text (verified 2026-09-11). - Decided on Decide how the CC BY-SA licence footer survives the cutover: a theme default or a per-repo footer.md #203: the theme will render that notice and credit by default when a site sets no footer, and a
site.parts.footerfile replaces the whole default. A migrating repo adds nothing unless its content is under other terms.
- Maths macros.
- When
mathjax_pathpoints at MathJax 3, the book theme adds a set of macros, including\epsilon→\varepsilon,\EE,\RRand\argmax(layout.html:14-50, __init__.py:631-635). - Here KaTeX renders the maths at build time. The only macros it gets are the
math:entries from project or page frontmatter, plus a built-in\mbox(mdast.ts:341, math.ts:25-27, math.ts:214-227). - KaTeX maps
\epsilonto the lunate ϵ (U+03F5) and\varepsilonto ε (U+03B5) (katex 0.16.33 in the theme's node_modules, dist/katex.js lines 4764 and 4784). - lecture-python-programming loads MathJax 3 with no
mathjax3_configof its own (_config.yml:79), so it relies on the theme's macros. It uses\epsilonin python_by_example.md (example). The fa, fr, zh-cn and ml editions also set nomathjax3_configand use\epsilonin the same lecture (default branches, checked 2026-09-11). - Repos with their own
mathjax3_confighave macros to port as well. lecture-python.myst writes two of them in MathJax's[definition, nargs]array form (_config.yml:107-112).math:does not accept that form: each macro must be a string, or an object with amacrokey (validators.ts:11-19). An array value is dropped with a "must be object, not array" validation error (checked 2026-09-11). - The Sphinx-built notebooks carry the macros too: lecture-python-advanced.notebooks'
arma.ipynbopens with a markdown cell of\newcommanddefinitions. How macros reach notebooks exported by mystmd is not yet settled.
- When
- "Last changed".
- The book theme runs git itself for every page (__init__.py:665-684).
- Here the git-metadata plugin has to be listed under
project.plugins, and the build needs the full git history (docs/git-metadata.md:13-26). - lecture-python-programming's Sphinx CI and publish workflows already check out with
fetch-depth: 0(ci.yml:11-13, publish.yml:26-28). The experimental jb2 PR-preview workflow checks out without it (ci.yml:11).
- Notebook launch repo.
- The book theme builds launch links only when
nb_repository_urlis set, and takes the notebook repo from that key rather than fromrepository_url(launch.py:40, launch.py:181-183, _config.yml:60-61). - This theme derives it from
project.github: it drops a.mystsuffix and appends.notebooks, unlesslaunch_repo_urlorlaunch_repo_suffixis set (LaunchButton.tsx:15-18, launchUrls.ts:30-43, docs/launch.md:8-23). - If the derived name is not a real notebooks repo, the Colab link is dead. lecture-wasm sets
githubto QuantEcon/lecture-wasm (myst.yml:16). Its live Colab link points at QuantEcon/lecture-wasm.notebooks, which returns HTTP 404 (verified 2026-09-11). - Decided on Launch control cannot be turned off and links to a nonexistent notebooks repo on sites without one #205: Launch becomes opt-in and explicit. It renders only when
launch_notebook_repois set andlaunch_colabis true, and no repository name is guessed. Three Sphinx sites whosenb_repository_urlnames a missing repository are fixed separately, in Drop nb_repository_url, which points at a notebooks repo that does not exist lecture-dp#60, Drop nb_repository_url, which points at a notebooks repo that does not exist lecture-python.zh-cn#279 and Drop nb_repository_url, which points at a notebooks repo that does not exist lecture-intro.zh-cn#305.
- The book theme builds launch links only when
- Notebook header.
- Sphinx wrote each lecture's
{raw} jupyterlogo header into its exported notebook. On mystmd the block shows as literal markup under the page title, and the fork's ipynb export drops it. - Decided on Notebook header
{raw}blocks render as literal HTML source under lecture page titles #204: the header comes from a project setting,settings.myst_to_ipynb.headerinmyst.yml, which the ipynb export writes as each notebook's first cell (ipynb export has no project-level notebook header, so the QuantEcon logo is copied into 549 lecture source files as raw blocks mystmd#108, not yet shipped).
- Sphinx wrote each lecture's
{raw}blocks in the lecture sources.- 554
{raw}blocks across 18 lecture repos have no mystmd rendering: 549 notebook headers, 2 embedded iframes and 3 HTML tables (counted 2026-09-11). - Decided on Notebook header
{raw}blocks render as literal HTML source under lecture page titles #204: a scripted rewrite runs before a repo's first mystmd build. It deletes the header blocks, turns the iframes into{iframe}and keeps the tables as HTML in the Markdown.
- 554
- Site URL.
- Every lecture repository's Sphinx config sets
html.baseurl(checked 2026-09-11), and Sphinx emits each page's canonical link from it. - This theme reads
site.options.site_urlforog:url, and for the canonical link once Pages emit no rel=canonical, and the favicon link 404s on sites served under a sub-path #207 ships. Without it neither is emitted. Neither lecture-wasm nor thejb2branch sets it today.
- Every lecture repository's Sphinx config sets
- Old URLs.
- Page URLs change at cutover:
about_py.htmlbecomesabout-py/. - 17 repositories' Sphinx configs carry a
rediraffe_redirectsmap, and four also carry sphinx-reredirectsredirects. - mystmd writes no redirects yet. The site build cannot redirect old page URLs, so every link to a Sphinx lecture page breaks at the move to mystmd mystmd#113 proposes redirect pages for the old Sphinx paths and a
site.redirectsmap.
- Page URLs change at cutover:
- Document language.
- Some editions set Sphinx
language:frin the fr edition (_config.yml:20) andzh_CNin lecture-python.zh-cn (_config.yml:37). - Some also set
current_languageandlanguagesunderhtml_theme_options(fr _config.yml:52, en _config.yml:38-51). - This theme reads only
site.options.current_language, and without it the page is markedlang="en"(i18n.ts:187-191, root.tsx:247). The same value setsog:locale(seo.ts:107-108) and marks the current entry in the language switcher (docs/rtl-support.md:10-26).
- Some editions set Sphinx
- Analytics.
- Lecture configs put the Google Analytics ID under
html_theme_options.analytics.google_analytics_id(_config.yml:68-69). The study found an ID on 19 of the 21 lecture sites. - This theme reads
site.options.analytics_google(template.yml:93-98, Document.tsx:147-150).
- Lecture configs put the Google Analytics ID under
- Description and keywords.
- Lecture configs set these at the top level and under
html_theme_options(_config.yml:4, _config.yml:66-67). The study found both on all 21 lecture sites. - This theme reads them from page, project or site frontmatter (
$.tsx:55-61, _index.tsx:45-47). docs/configuration.md does not list either key (configuration.md:47-54). - A comma-separated keywords string, as the Sphinx configs use, is split into a list (site/validators.ts:141-149, applied to project frontmatter at project/validators.ts:78).
- Lecture configs set these at the top level and under
The experimental jb2 conversion in QuantEcon/lecture-python-programming#363 (open) does not yet carry most of these. Its myst.yml sets project.github and a footer, but no plugins, math, description, keywords or site.options (myst.yml:16-18, myst.yml:90-96). Under #203 its footer.md is to be removed so the theme default applies.
Proposed change
Add a migration checklist page, docs/migrating.md, for lecture repos moving from quantecon-book-theme, and link it from the Pages table in docs/index.md:25-38. For each item, the page says what it replaces in the Sphinx build, what to do in the MyST build, and which page has the detail. This change is documentation only.
| Checklist item | Replaces (Sphinx) | Do in the MyST build | Detail in |
|---|---|---|---|
| Licence footer | the footer hard-coded in the theme | nothing, since the theme renders the CC BY-SA 4.0 notice and credit by default (#203). Only a repo whose content is under other terms adds a site.parts.footer file, which replaces the default |
docs/layout.md |
| Maths macros | the theme's MathJax macros, or the repo's own mathjax3_config |
project.math entries: \epsilon → \varepsilon for repos without their own mathjax3_config, plus each mathjax3_config macro, with array-form macros rewritten as strings |
this page (no docs page covers maths) |
| "Last changed" | the theme's own git lookup | the git-metadata plugin under project.plugins, and fetch-depth: 0 on every workflow checkout that builds HTML, PR previews included |
docs/git-metadata.md |
| Launch notebooks | nb_repository_url, nb_branch, nb_path_to_notebooks, path_to_docs and launch_buttons.colab_url |
only if the notebooks repository exists: launch_notebook_repo (from nb_repository_url), launch_colab: true, and launch_notebook_branch, launch_notebook_dir and launch_notebook_source_dir where the Sphinx config sets their counterparts. A repo with no notebooks repository sets none of them and shows no Launch (#205) |
docs/launch.md |
| Notebook header | the {raw} jupyter block at the top of each lecture file |
project.settings.myst_to_ipynb.header in myst.yml (QuantEcon/mystmd#108) |
the fork's docs/settings.md, once QuantEcon/mystmd#108 ships |
| Lecture sources | Sphinx-only {raw} blocks: the notebook header, embedded iframes, HTML tables |
run the source rewrite decided on #204 before the first mystmd build | #204 |
| Site URL | html.baseurl |
site.options.site_url, the site's public URL (for example https://python-programming.quantecon.org/) |
docs/configuration.md |
| Old URLs | every page's .html path, plus the rediraffe_redirects and sphinx-reredirects redirects maps |
the redirects from QuantEcon/mystmd#113, once it ships: old Sphinx paths redirect automatically, and each map entry moves to site.redirects |
QuantEcon/mystmd#113 |
| Document language | Sphinx language, and current_language / languages under html_theme_options |
site.options.current_language as a BCP 47 code (for example zh-cn for Sphinx zh_CN), and site.options.languages as a YAML block string |
docs/rtl-support.md |
| Analytics | html_theme_options.analytics.google_analytics_id |
site.options.analytics_google |
docs/configuration.md |
| Description and keywords | top-level description, and description / keywords under html_theme_options |
project.description and project.keywords |
docs/configuration.md, once its "Other site keys the theme uses" table lists them |
Sphinx options with no counterpart. The page also carries a single table of the book-theme options that have no counterpart in this theme, each with its reason: unused by the lecture sites, inert in the book theme, dropped by an earlier decision, or open in a named issue. docs/index.md points its promise ("where a Sphinx option has no counterpart, its page says so") at this table, and the docs review task on #147 makes that change. The keys, carried over from #210 (theme keys are in the book theme's theme.conf unless noted):
| Keys | Source | Study rows |
|---|---|---|
quantecon_project, header_organisation, header_organisation_url, dark_logo, html_logo |
theme.conf lines 39, 24, 25 and 13; html_logo is Sphinx core |
F033, F020, F014 |
authors_label, mainpage_author_fontsize |
theme.conf lines 10 and 29 | F082, F007 |
persistent_sidebar, home_page_in_toc |
theme.conf lines 37 and 26; persistent_sidebar is open in #214 |
F005, F003 |
contents_autoexpand (its False mode) |
theme.conf line 30 | F011 |
last_modified_date_format |
__init__.py L674 | F084 |
inline_literal_box |
theme.conf line 20; the decision is open in #180 | F036 |
announcement_expires, announcement_style |
theme.conf lines 7-8; the banner itself is already documented as not offered | F017, F018 |
exercise_style, proof_minimal_theme, togglebutton_hint |
sphinx-exercise, sphinx-proof and sphinx-togglebutton settings | F050, F051, F049 |
html_css_files, html_js_files |
Sphinx core | X03 |
single_page, expand_sections, plugins_list |
theme.conf lines 43, 19 and 38; inert in the book theme itself | F093 |
The maths recipe to include. Checked 2026-09-11 with the theme's KaTeX 0.16.33: \epsilon renders as U+03F5 by default and as U+03B5 with this macro.
project:
math:
'\epsilon': '\varepsilon'Some items depend on work still open, so the page should describe the state as it stands when it lands:
- Launch item. Use the option names decided on Launch control cannot be turned off and links to a nonexistent notebooks repo on sites without one #205, and say that a site without a notebooks repository shows no Launch. Whether the theme also checks that each notebook exists before showing Launch is deferred on Launch control cannot be turned off and links to a nonexistent notebooks repo on sites without one #205, so describe what has shipped when the page lands.
- Notebook header item. Say whether ipynb export has no project-level notebook header, so the QuantEcon logo is copied into 549 lecture source files as raw blocks mystmd#108 has shipped.
- Lecture sources item. Say where the rewrite script lives, which is still open on Notebook header
{raw}blocks render as literal HTML source under lecture page titles #204. - Old URLs item. Say whether The site build cannot redirect old page URLs, so every link to a Sphinx lecture page breaks at the move to mystmd mystmd#113 has shipped.
Acceptance criteria
-
docs/migrating.mdcovers all eleven items in the table above. Each item names the Sphinx setting or behaviour it replaces, what to do (amyst.ymlentry, a file, a source rewrite or a workflow setting), and a link to the page with the detail. - The maths item includes a
project.mathexample that maps\epsilonto\varepsilon, says it applies to repos without their ownmathjax3_config, and says MathJax's[definition, nargs]array-form macros must be rewritten as strings. - The git-metadata item gives the plugin URL form from docs/git-metadata.md and requires
fetch-depth: 0on every workflow checkout that builds HTML. - The launch item maps each Sphinx launch key to its Launch control cannot be turned off and links to a nonexistent notebooks repo on sites without one #205 option, says to set
launch_notebook_repoonly when that repository exists, and says that a site without one shows no Launch. - The footer item says the theme renders the licence notice by default (Decide how the CC BY-SA licence footer survives the cutover: a theme default or a per-repo footer.md #203), and that a
site.parts.footerfile replaces the whole default. - The notebook header item names
settings.myst_to_ipynb.header, and says whether ipynb export has no project-level notebook header, so the QuantEcon logo is copied into 549 lecture source files as raw blocks mystmd#108 has shipped. - The lecture sources item links the rewrite from Notebook header
{raw}blocks render as literal HTML source under lecture page titles #204 and says it runs before a repo's first mystmd build. - The site URL item maps
html.baseurltosite.options.site_url, and says that canonical links andog:urlneed it. - The old URLs item lists the repository's redirect maps, and says what The site build cannot redirect old page URLs, so every link to a Sphinx lecture page breaks at the move to mystmd mystmd#113 does with them or that it has not shipped.
- The page carries the no-counterpart table, and gives every key in it a reason.
- The page says these steps are manual: mystmd's Jupyter Book config upgrade does not read
sphinx.config, where the lecture configs keep these settings. - The docs/index.md Pages table links the new page.
- The "Other
sitekeys the theme uses" table in docs/configuration.md listsproject.descriptionandproject.keywords. - The PR changes documentation only.
Context
- Source: the 2026-09-11 book-theme parity study, rows F015, F047, F084, F076, F081, F087 and F089 (report section 3.4, "Add to the migration checklist"). The study rates F087 and F089 as implemented; they appear here only as migration steps. The notebook header and
{raw}source items came from the Notebook header{raw}blocks render as literal HTML source under lecture page titles #204 review decision (row X02). - Evidence was re-checked at theme
maind504555 (the v2.7.0 release commit); the study itself cited 5260864. - Related: Book-theme parity cutover — tracking #147 (the cutover gate).
- Related: Retire the in-repo git-metadata plugin once the standalone release exists in quantecon-plugins.mystmd #157, retiring the in-repo git-metadata plugin once quantecon-plugins.mystmd has a standalone release. It will change the plugin URL this page gives.
- Related: [Experimental] Build the lectures with QuantEcon/mystmd instead of jupyter-book lecture-python-programming#363, the experimental jb2 conversion.
- Related: Decide how the CC BY-SA licence footer survives the cutover: a theme default or a per-repo footer.md #203 (licence-footer decision, F015), Notebook header
{raw}blocks render as literal HTML source under lecture page titles #204 (notebook header and{raw}rewrite, X02), Launch control cannot be turned off and links to a nonexistent notebooks repo on sites without one #205 (the launch gap for sites with no notebooks repo, F073 and F076), and ipynb export has no project-level notebook header, so the QuantEcon logo is copied into 549 lecture source files as raw blocks mystmd#108 (the notebook header setting). - Related: Pages emit no rel=canonical, and the favicon link 404s on sites served under a sub-path #207 (canonical links, which need
site_url) and The site build cannot redirect old page URLs, so every link to a Sphinx lecture page breaks at the move to mystmd mystmd#113 (redirects for the old URLs).
Activity
mmcky commentedon Sep 11, 2026
Revision — 2026-09-11
Revised in place to carry the review decisions:
settings.myst_to_ipynb.headerinmyst.yml(ipynb export has no project-level notebook header, so the QuantEcon logo is copied into 549 lecture source files as raw blocks mystmd#108), from the Notebook header{raw}blocks render as literal HTML source under lecture page titles #204 decision.{raw}rewrite decided on Notebook header{raw}blocks render as literal HTML source under lecture page titles #204, run before a repo's first mystmd build.The checklist now has nine items, and the acceptance criteria match.
mmcky commentedon Sep 11, 2026
Revised in place: the launch item now follows the #205 decision. Launch is opt-in, and each Sphinx launch key maps to a
launch_notebook_*option orlaunch_colab.launch_notebook_repois set only when that notebooks repository exists. Whether the theme also checks each notebook before showing Launch is deferred on #205.mmcky commentedon Sep 11, 2026
Revised in place after the #207 review, adding two checklist items. Site URL maps Sphinx
html.baseurltosite.options.site_url, which canonical links andog:urlneed. Old URLs covers each repository's redirect maps and the redirects QuantEcon/mystmd#113 proposes. The checklist now has eleven items.mmcky commentedon Sep 11, 2026
Revised in place: #210 was closed during the review of #147, and its table of Sphinx options with no counterpart moved here. The migration page now carries that table, with a reason for each key, and
docs/index.mdwill point there.