Fix teething problems found while triaging the SICPy launch - #1318
Merged
Conversation
…ntime The interactive site's table of contents wasn't documented anywhere, so nobody noticed it needed to stay in sync with the published chapter range (SICP_PUBLISHED_CHAPTERS, #1316). The frontend has since been fixed to fetch these at runtime instead of snapshotting them. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEaJ8SQRH4QkXir4JSs4S
<AMP/> in the XML source (used because a literal & can't appear raw in XML text) was translated to the JSON output as the HTML entity string "&" rather than the character "&". That's correct for an HTML sink, but the frontend renders JSON #text nodes as plain React text (ParseJson.tsx's handleText), which doesn't decode HTML entities, so readers saw the literal string "&" instead of "&". Affects any <AMP/> in the XML sources, currently: the SICPy CWI mention in chapter1.xml, and two References citations (Wiley & Sons, Harper & Row) shared by both SICP JS and SICPy. The PDF is unaffected — it goes through the separate LaTeX converter (parseXmlLatex.js), which never called this function. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEaJ8SQRH4QkXir4JSs4S
Chapter/section/exercise/figure/footnote references from a published chapter into a later, still-gated one (SICP_PUBLISHED_CHAPTERS, #1316) showed as "Chapter" with no number in the interactive site and "??" in the PDF, because labels are only ever registered for chapters the build actually visits, and unpublished chapters are skipped entirely. json: label/exercise/figure/footnote registration now runs over the *entire* book unconditionally (see forceIncludeAllChapters), so a forward reference resolves to a real number and href; only that resolution is kept; unpublished chapters' actual page content is still never written to json_<lang>/. The href just 404s into "this section is in preparation" until that chapter is published, same as any other unpublished link. pdf: chapters are now brought in with \include instead of \input, and every chapter's .tex fragment is generated unconditionally (gating moves entirely to \includeonly). \include reads every listed chapter's .aux regardless of \includeonly, so scripts/do.sh now does a two-pass compile when SICP_PUBLISHED_CHAPTERS is set: a throwaway "shadow" pass typesets every chapter once to populate each one's .aux with real label numbers, then the real "publish" pass restricts \includeonly to the actually-published subset, resolving forward \ref/\pageref against the .aux the shadow pass left behind. Verified locally: SICPy's forward references (chap:state -> 3, chap:meta -> 4, plus section/figure/exercise/footnote refs) all resolve to real numbers/hrefs in json_py, and the compiled sicpy.pdf shows "Chapter 3"/"Chapter 4" with zero "??" across all 229 pages. SICP JS (unaffected edition, no chapters ever gated) still builds cleanly at 640 pages with the \include switch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RsEaJ8SQRH4QkXir4JSs4S
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four fixes found while triaging the newly-launched interactive Python edition. The first three follow directly from #1316 (
SICP_PUBLISHED_CHAPTERSgate); the fourth is an unrelated pre-existing bug surfaced during the same triage.README.md: documents that the frontend fetchestoc.json/toc-navigation.jsonat runtime (companion to the frontend fix in source-academy/frontend#4273 — the frontend previously snapshotted these into its own repo, which is how the TOC went stale after the gate merged).&in the interactive editions:<AMP/>in the XML source was translated to the JSON output as the HTML entity string"&"instead of the character&. Correct for an HTML sink, but the frontend renders JSON#textnodes as plain React text, which doesn't decode HTML entities. Affects both SICP JS and SICPy (sharedparseXmlJson.js) — e.g. "Centrum Wiskunde & Informatica" and the References section's "John Wiley & Sons" / "Harper & Row". The PDF was unaffected (separate LaTeX converter).json_<lang>/. The href just 404s into the frontend's "this section is in preparation" message until that chapter is published.\includeinstead of\input, with every chapter's.texfragment generated unconditionally and gating moved entirely to\includeonly.scripts/do.shdoes a two-pass compile whenSICP_PUBLISHED_CHAPTERSis set: a throwaway shadow pass typesets every chapter once to populate each one's.auxwith real label numbers, then the real publish pass restricts\includeonlyto the published subset, resolving forward\ref/\pagerefagainst the.auxthe shadow pass left behind.chap=/variant=scheme for every edition; that's correct for SICP JS (part of the js-slangChapterenum), but Python is a Conductor-based language directory entry (python1..python4) addressed vialanguage=/variant=instead, sochap=was never meaningful to it and the evaluator just stayed on whatever chapter it already had open.Test plan
SICP_EDITION=py SICP_PUBLISHED_CHAPTERS=2 yarn json— verifiedchap:state→ "3",chap:meta→ "4", plus exercise/figure/footnote refs (e.g.4.1.2#ex-4.7,4.1.3#footnote-1) all resolve to real hrefs; zero unpublished content injson_py//toc.json; zero literal&; snippet hashes now readlanguage=python&variant=N&prgrm=...yarn json(JS edition) — zeroREF not foundwarnings, zero literal&, snippet hashes unchanged (chap=N&variant=...&prgrm=...)SICP_EDITION=py SICP_PUBLISHED_CHAPTERS=2 yarn pdf— compiledsicpy.pdf(229 pages) shows "Chapter 3"/"Chapter 4", zero??anywhereSICP_EDITION=js yarn pdf(unaffected edition, never gated) — builds cleanly, 640 pages, zero undefined refs, confirming the\includeswitch doesn't regress itFound but not fixed here (flagged for editorial follow-up, not a pipeline issue): two pre-existing broken labels in the still-draft chapter 3/4 XML —
foot:function-decl-vs-lambda(referenced twice from chapter 3, but its<LABEL>doesn't exist anywhere) andfoot:value_producingvs. the actually-definedfoot:value_producing_2(naming mismatch). These only surfaced now because the shadow pass fully typesets those chapters; they don't affect the shipped PDF since chapters 3/4 aren't printed yet.🤖 Generated with Claude Code
https://claude.ai/code/session_01RsEaJ8SQRH4QkXir4JSs4S