You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.footer is set (PageContent.tsx:105), and the live lecture-wasm site shows no licence text (verified 2026-09-11).
When mathjax_path points at MathJax 3, the book theme adds a set of macros, including \epsilon → \varepsilon, \EE, \RR and \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 \epsilon to the lunate ϵ (U+03F5) and \varepsilon to ε (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_config of its own (_config.yml:79), so it relies on the theme's macros. It uses \epsilon in python_by_example.md (example). The fa, fr, zh-cn and ml editions also set no mathjax3_config and use \epsilon in the same lecture (default branches, checked 2026-09-11).
Repos with their own mathjax3_config have 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 a macro key (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.ipynb opens with a markdown cell of \newcommand definitions. How macros reach notebooks exported by mystmd is not yet settled.
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_url is set, and takes the notebook repo from that key rather than from repository_url (launch.py:40, launch.py:181-183, _config.yml:60-61).
If the derived name is not a real notebooks repo, the Colab link is dead. lecture-wasm sets github to QuantEcon/lecture-wasm (myst.yml:16). Its live Colab link points at QuantEcon/lecture-wasm.notebooks, which returns HTTP 404 (verified 2026-09-11).
Sphinx wrote each lecture's {raw} jupyter logo 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.
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.
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.
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
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):
docs/migrating.md covers all eleven items in the table above. Each item names the Sphinx setting or behaviour it replaces, what to do (a myst.yml entry, a file, a source rewrite or a workflow setting), and a link to the page with the detail.
The maths item includes a project.math example that maps \epsilon to \varepsilon, says it applies to repos without their own mathjax3_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: 0 on every workflow checkout that builds HTML.
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 site keys the theme uses" table in docs/configuration.md lists project.description and project.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.
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-themeto this theme has to set up several things inmyst.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.ymlkeys 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 neitherdocs/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
htmlsection, setsproject.githubonly from a top-levelrepository.url, and typessphinx.configas an opaque record thatupgradeConfignever reads (config.ts:99-106, config.ts:147-236, config.ts:185-200). lecture-python-programming, for example, has no top-levelrepositorykey and keeps these settings undersphinx.config(_config.yml:17-69).Item by item:
site.parts.footeris set (PageContent.tsx:105), and the live lecture-wasm site shows no licence text (verified 2026-09-11).site.parts.footerfile replaces the whole default. A migrating repo adds nothing unless its content is under other terms.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).math:entries from project or page frontmatter, plus a built-in\mbox(mdast.ts:341, math.ts:25-27, math.ts:214-227).\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).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).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).arma.ipynbopens with a markdown cell of\newcommanddefinitions. How macros reach notebooks exported by mystmd is not yet settled.project.plugins, and the build needs the full git history (docs/git-metadata.md:13-26).fetch-depth: 0(ci.yml:11-13, publish.yml:26-28). The experimental jb2 PR-preview workflow checks out without it (ci.yml:11).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).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).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).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.{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.{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).{raw}blocks in the lecture sources.{raw}blocks across 18 lecture repos have no mystmd rendering: 549 notebook headers, 2 embedded iframes and 3 HTML tables (counted 2026-09-11).{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.html.baseurl(checked 2026-09-11), and Sphinx emits each page's canonical link from it.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.about_py.htmlbecomesabout-py/.rediraffe_redirectsmap, and four also carry sphinx-reredirectsredirects.site.redirectsmap.language:frin the fr edition (_config.yml:20) andzh_CNin lecture-python.zh-cn (_config.yml:37).current_languageandlanguagesunderhtml_theme_options(fr _config.yml:52, en _config.yml:38-51).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).html_theme_options.analytics.google_analytics_id(_config.yml:68-69). The study found an ID on 19 of the 21 lecture sites.site.options.analytics_google(template.yml:93-98, Document.tsx:147-150).html_theme_options(_config.yml:4, _config.yml:66-67). The study found both on all 21 lecture sites.$.tsx:55-61, _index.tsx:45-47). docs/configuration.md does not list either key (configuration.md:47-54).The experimental jb2 conversion in QuantEcon/lecture-python-programming#363 (open) does not yet carry most of these. Its myst.yml sets
project.githuband a footer, but noplugins,math, description, keywords orsite.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 fromquantecon-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.site.parts.footerfile, which replaces the defaultmathjax3_configproject.mathentries:\epsilon→\varepsilonfor repos without their ownmathjax3_config, plus eachmathjax3_configmacro, with array-form macros rewritten as stringsproject.plugins, andfetch-depth: 0on every workflow checkout that builds HTML, PR previews includednb_repository_url,nb_branch,nb_path_to_notebooks,path_to_docsandlaunch_buttons.colab_urllaunch_notebook_repo(fromnb_repository_url),launch_colab: true, andlaunch_notebook_branch,launch_notebook_dirandlaunch_notebook_source_dirwhere the Sphinx config sets their counterparts. A repo with no notebooks repository sets none of them and shows no Launch (#205){raw} jupyterblock at the top of each lecture fileproject.settings.myst_to_ipynb.headerinmyst.yml(QuantEcon/mystmd#108){raw}blocks: the notebook header, embedded iframes, HTML tableshtml.baseurlsite.options.site_url, the site's public URL (for examplehttps://python-programming.quantecon.org/).htmlpath, plus therediraffe_redirectsand sphinx-reredirectsredirectsmapssite.redirectslanguage, andcurrent_language/languagesunderhtml_theme_optionssite.options.current_languageas a BCP 47 code (for examplezh-cnfor Sphinxzh_CN), andsite.options.languagesas a YAML block stringhtml_theme_options.analytics.google_analytics_idsite.options.analytics_googledescription, anddescription/keywordsunderhtml_theme_optionsproject.descriptionandproject.keywordssitekeys the theme uses" table lists themSphinx 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.mdpoints 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):quantecon_project,header_organisation,header_organisation_url,dark_logo,html_logohtml_logois Sphinx coreauthors_label,mainpage_author_fontsizepersistent_sidebar,home_page_in_tocpersistent_sidebaris open in #214contents_autoexpand(itsFalsemode)last_modified_date_formatinline_literal_boxannouncement_expires,announcement_styleexercise_style,proof_minimal_theme,togglebutton_hinthtml_css_files,html_js_filessingle_page,expand_sections,plugins_listThe maths recipe to include. Checked 2026-09-11 with the theme's KaTeX 0.16.33:
\epsilonrenders as U+03F5 by default and as U+03B5 with this macro.Some items depend on work still open, so the page should describe the state as it stands when it lands:
{raw}blocks render as literal HTML source under lecture page titles #204.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.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.fetch-depth: 0on every workflow checkout that builds HTML.launch_notebook_repoonly when that repository exists, and says that a site without one shows no Launch.site.parts.footerfile replaces the whole default.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.{raw}blocks render as literal HTML source under lecture page titles #204 and says it runs before a repo's first mystmd build.html.baseurltosite.options.site_url, and says that canonical links andog:urlneed it.sphinx.config, where the lecture configs keep these settings.sitekeys the theme uses" table in docs/configuration.md listsproject.descriptionandproject.keywords.Context
{raw}source items came from the Notebook header{raw}blocks render as literal HTML source under lecture page titles #204 review decision (row X02).maind504555 (the v2.7.0 release commit); the study itself cited 5260864.{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).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).