Repository navigation
jax_intro renders its Chinese figure title as tofu — live to readers for three months #77
Description
Activity
A runtime scan of the published site finds two more broken pages, and they are a different defect from this one.
bin/check-tofuinproject-translationreads the missing-glyph warnings where they actually land — myst-nb renders the kernel'sUserWarninginto the published HTML as stderr output. Pointing it at https://quantecon.github.io/lecture-python-programming.zh-cn:Page Characters lost jax_intro密钥拆分树 — this issue, fixed in #78 matplotlib样式: — missing from Liberation Sans, not DejaVu pandas_panel业人份低元况分占口国均实家就工平年最欧比洲状百美资际() Both new pages already carry the font block, so they are not the same defect.
matplotlib.md— the block is set and then clobberedThe font block sits at line 83. The lecture then demonstrates style sheets:
plt.style.use(style)at line 307,plt.style.use('default')at 395 and 451, andplt.rcParams.update(parameters)at 422.style.use()resets rcParams to the style's own values, which wipesfont.family— hence glyphs missing from Liberation Sans, a style sheet's font rather than the fallback default.Fix options: re-apply
font.familyafter eachstyle.use(), wrap the demonstrations inplt.rc_context(), or leave the demonstration figures' labels in English since the lecture is about styling rather than about the data.pandas_panel.md— not yet explainedIts block was added 2026-03-20 (
93dfab0), before bothpublish-2026may14andpublish-2026jun19, so the block was live at publish and the labels still lost their glyphs. That needs a targeted look; I have not diagnosed it. Worth checking for a later rcParams reset, an execution failure that skipped the block's cell, or a figure drawn before the block runs.Method note
Source-level analysis found only
jax_introin this repo; the runtime scan found three. The two approaches are complementary — static analysis catches unpublished defects, runtime catches what readers actually see plus anything built dynamically. Both are worth keeping.- added a commit that references this issue
on Jul 24, 2026 Verified fixed on the live site — closing.
What landed
Page Fix Shipped in jax_introfont block restored #78 matplotlibre-apply font.familyinsidedraw_graphsafter eachplt.style.use(style)#87 ( 0153f28)pandas_panelfont family passed through sns.set_theme(rc=...)#87 ( 0153f28)matplotlibandpandas_panelwere the two extra pages found by the runtime scan in the comment above, and they were a different defect from the original one here — not a missing font block, butplt.style.use()andsns.set_theme()resettingfont.familyafter the i18n cell had set it.Verification
The publish workflow completed successfully against
0153f28on 2026-08-07, so the fix is live rather than only onmain. Fetching the three published pages and grepping for the missing-glyph warnings where they actually land — myst-nb renders the kernel'sUserWarninginto the page as stderr output, which is whatbin/check-tofukeys on — returns clean on all three:jax_intro.html— HTTP 200, nofindfont/missing from fontoccurrencesmatplotlib.html— HTTP 200, cleanpandas_panel.html— HTTP 200, clean
Scope note: this checks the three pages named in this issue, not the full estate. A repo-wide sweep would be worth running separately if the goal is to confirm no fourth page is affected.
The two structural gaps this issue documented are unchanged and are not closed by this: Sphinx's
-Wstill cannot see kernel-sideUserWarnings, and thesphinx-tojupyterstep still swallows execution errors via theexit(self.execution_status_code)path. Those want the CI tofu detector proposed in the linked report rather than being tracked here.
jax_intro.md:544sets a Chinese figure title —ax.set_title("PRNG 密钥拆分树", fontsize=13, pad=10)— and the lecture carries no matplotlib font configuration. matplotlib falls back to DejaVu Sans, which has no CJK coverage, so the title renders as tofu: blank rectangles in an otherwise valid PNG.This one is live. The font block was stripped in
4120371(2026-04-12), the title was re-translated to Chinese two days later, and the block was never restored. This edition has published three times since, so readers have been seeing a boxed-out figure title for roughly three months. It is the only instance in the estate that has actually reached readers — the intermediate and intro editions have the same defect but have not published since it appeared.Fix
Restore the block above first plotting use:
Check the path against this repo before committing — the estate currently has two conventions for a byte-identical asset (
lectures/fonts/in 136 lectures across the other editions,lectures/_fonts/in 17 here and in the engine's output), and standardising on one is a separate item in the program review.Why CI did not catch it
The missing-glyph warning is a
UserWarningraised inside the Jupyter kernel subprocess. Sphinx's-Wonly escalates Sphinx-logger warnings, so it never sees it; myst-nb renders it into the published page as stderr output instead. No CI log in the estate has ever containedfindfontorGlyph … missing.Separately and more seriously for this repo: the
-n -W --keep-goingon the sphinx-tojupyter step is inert —sphinx_tojupyter/builders/jupyter.py:297callsexit(self.execution_status_code), initialised to 0 and never set, so that step swallows all execution errors. That also bounds what #76 achieves.Context
Root cause, the recommendation against reverting to
usetex, and a proposed CI tofu detector: project-translation reports/2026-07-24-cjk-font-rendering-review.md.