MathJax and SVG Integration
Relevant source files
The following files were used as context for generating this wiki page:
The SICP-Rust project utilizes a sophisticated pipeline for rendering mathematical notation and vector graphics in its HTML5 and EPUB3 versions. By integrating MathJax v3 and Scalable Vector Graphics (SVG), the project ensures that complex mathematical expressions from the original "Structure and Interpretation of Computer Programs" are displayed with high typographic quality across various devices and screen sizes. Sources: README.md:1-12
This integration relies on a two-stage process for mathematics: extracting LaTeX strings and converting them to MathML via MathJax, and subsequently injecting the resulting markup into the final documents. SVGs are used for book diagrams and are managed through metadata generation scripts to ensure correct property tagging for EPUB3 compliance. Sources: get-math.js:1-14, create_metafiles.rb:1-10
Mathematics Processing Pipeline
The project implements a decoupled system for handling mathematical expressions using two primary Node.js scripts: get-math.js and put-math.js. This allows for the pre-computation and caching of MathML content in a JSON database. Sources: get-math.js:1-10, put-math.js:1-10
LaTeX Extraction and Conversion
The get-math.js script scans input files for LaTeX strings delimited by \( (inline) or \[ (display). It uses the MathJax v3 library (mathjax-full) to convert these strings into MathML nodes, which are then serialized and stored in a JSON database. Sources: get-math.js:14-17, get-math.js:56-58
The diagram above illustrates the extraction and conversion flow from source LaTeX to a cached MathML database. Sources: get-math.js:70-134
MathML Injection
The put-math.js script performs the reverse operation. It reads the JSON database and replaces LaTeX delimiters in the output files with the corresponding MathML markup. If a mapping is not found, it wraps the LaTeX in a blue span for visual debugging. Sources: put-math.js:38-54
| Component | Purpose | Technology |
|---|---|---|
| get-math.js | Extracts LaTeX and generates MathML database | Node.js, MathJax-full v3 |
| put-math.js | Injects MathML into output HTML/EPUB files | Node.js |
| JSON DB | Persistent storage for LaTeX-to-MathML mappings | JSON |
Sources: get-math.js:1-14, put-math.js:1-14
SVG Integration and Metadata
Scalable Vector Graphics are used for diagrams and the book cover. The create_metafiles.rb script automates the inclusion of these assets into the EPUB3 container, ensuring that items containing SVGs or MathML are correctly identified in the package manifest. Sources: create_metafiles.rb:1-8, README.md:12-14
Manifest and Property Tagging
The Ruby script scans files for <math> tags and <object> (used for SVG) tags to apply the required EPUB3 properties:
- mathml: Applied if the file contains a
<math>tag. - svg: Applied if the file contains an
<object>tag or if the file itself is an SVG image.
Sources: create_metafiles.rb:120-133
This diagram shows how properties are assigned to items in the EPUB manifest based on content detection. Sources: create_metafiles.rb:123-134
Styling and Layout
The visual presentation of mathematics and graphics is controlled via html/css/style.css. Specific rules are defined for MathML and MathJax components to ensure they harmonize with the project's typography, which primarily uses the "Linux Libertine O" and "Linux Biolinum O" font families. Sources: html/css/style.css:41-45, html/css/style.css:273-333
Key Style Configurations
- Math Alignment: MathML and code elements allow line breaks (
white-space: normal) to support responsive design. Sources: html/css/style.css:284-287 - Vertical Spacing: Block-level math (
math[display="block"]) is given a vertical margin of1em. Sources: html/css/style.css:288-290 - Coloration: MathJax output is styled differently depending on its context; for instance, it is colored
#606060within Lisp code blocks and#a07040within Roman text. Sources: html/css/style.css:169-175 - Font Matching: MathML fonts are specifically mapped to
STIXGeneralfor better mathematical symbol representation. Sources: html/css/style.css:274-276
| Element | Style Property | Value |
|---|---|---|
math | white-space | normal |
math[display="block"] | margin | 1em 0 |
mtext | font-family | STIXGeneral |
.lisp .MathJax | color | #606060 |
Sources: html/css/style.css:169-290
Client-Side Processing and Highlighting
While the primary math pipeline is server-side, the project uses batch-prettify-node.js and prettify.js for syntax highlighting, which must coexist with mathematical markup. Sources: batch-prettify-node.js:1-12
The batch-prettify-node.js script uses jsdom to simulate a browser environment, injecting prettify.js and language handlers (Lisp/Scheme and Rust) to process code blocks. This script explicitly identifies <pre> tags with classes lisp, rust, or example for processing, which may contain inline MathML after the put-math.js stage. Sources: batch-prettify-node.js:32-42, batch-prettify-node.js:80-86
Prettifier Interaction
The prettify.js library is configured to treat these blocks carefully. In the project's implementation, the language extension is often bluntly set to Scheme (scm) to ensure consistent highlighting of SICP code examples. Sources: js/highlight/prettify.js:1016-1018
The integration ensures that mathematical symbols within code blocks—often used for conceptual explanations—maintain their formatting while the surrounding code is highlighted. Sources: html/css/style.css:169-171
Conclusion
The MathJax and SVG integration in SICP-Rust is a multi-stage workflow designed for high-fidelity conversion of Texinfo source to modern e-book formats. By combining static pre-rendering of MathML with dynamic metadata generation and robust CSS styling, the project provides a responsive and typographically accurate reading experience. Sources: README.md:1-12, get-math.js:132-134