RaTeX Project Structure
July 12, 2026 · View on GitHub
Current layout as of the codebase. RA (Rust) + TeX.
Root Layout
RaTeX/
├── Cargo.toml # Workspace root
├── README.md # Main docs (EN); KaTeX gaps: *KaTeX differences (commands & DOM)*
├── README.zh-CN.md # Main docs (ZH); *与 KaTeX 的差异(命令 / DOM)*
├── CONTRIBUTING.md # Build, test, golden workflow, PR notes
├── SECURITY.md # How to report vulnerabilities
├── LICENSE # MIT
├── .gitignore
├── .github/
│ └── workflows/
│ ├── ci.yml # Build + Clippy + Test
│ ├── pages.yml # GitHub Pages (demo)
│ └── release-*.yml # crates.io, npm, pub.dev, iOS/Android/RN
│
├── crates/ # Rust crates
│ ├── ratex-types/ # Shared types (DisplayList, Color, etc.)
│ ├── ratex-font/ # Font metrics + symbol tables (KaTeX-compatible)
│ ├── ratex-lexer/ # LaTeX → token stream
│ ├── ratex-parser/ # Token stream → ParseNode AST
│ ├── ratex-layout/ # AST → LayoutBox → DisplayList
│ ├── ratex-katex-fonts/ # KaTeX TTF blobs for embed-fonts (crates.io–safe path)
│ ├── ratex-font-loader/ # Shared lazy font loading/cache for PNG/SVG/PDF
│ ├── ratex-ffi/ # C ABI: LaTeX → DisplayList JSON (+ Android JNI)
│ ├── ratex-cairo/ # DisplayList → Cairo context (native Linux / GTK base)
│ ├── ratex-gtk4/ # GTK4 widget subclass for native Linux rendering
│ ├── ratex-render/ # DisplayList → PNG (tiny-skia, server-side)
│ ├── ratex-wasm/ # WASM: LaTeX → DisplayList JSON (browser)
│ ├── ratex-svg/ # SVG export: DisplayList → SVG string (vector output)
│ ├── ratex-pdf/ # PDF export: DisplayList → PDF (pdf-writer, embedded fonts)
│ └── ratex-unicode-font/ # System Unicode / CJK font discovery for fallback rendering
│
├── platforms/
│ ├── ios/ # Swift + XCFramework + CoreGraphics
│ ├── android/ # Kotlin + AAR + JNI/Canvas
│ ├── gtk/ # GTK4 Linux docs, C/GI metadata, and C/Python/Vala examples
│ ├── flutter/ # Dart FFI + widget
│ ├── react-native/ # Native module + iOS/Android views
│ └── web/ # npm package `ratex-wasm`: WASM + TypeScript web-render
│
├── tools/ # Dev / comparison scripts
│ ├── mhchem_reference.js # KaTeX mhchem.js reference; → data/*.json via generate_mhchem_data.mjs
│ ├── generate_mhchem_data.mjs # Export machines.json + patterns_regex.json (see docs/MHCHEM_DATA.md)
│ ├── dump_mhchem_structure.mjs # Optional: state machine stats dump
│ ├── extract_mhchem_manual_examples.mjs # gh-pages manual → tests/golden/test_case_ce.txt
│ ├── convert_metrics.py # KaTeX fontMetricsData.js → Rust
│ ├── convert_symbols.py # KaTeX symbols.js → Rust
│ ├── golden_compare/ # Golden PNG comparison + reference generators (KaTeX/mhchem, MathJax prooftree)
│ ├── layout_compare/ # Layout box vs KaTeX (katex_layout.mjs + compare_layouts.py)
│ ├── lexer_compare/ # Token output vs KaTeX lexer
│ └── parser_compare/ # Parser comparison
│
├── tests/
│ └── golden/ # Golden test assets
│ ├── fixtures/ # KaTeX reference PNGs (per test case)
│ ├── fixtures_ce/ # KaTeX+mhchem reference PNGs (optional; for test_case_ce)
│ ├── fixtures_prooftree/ # MathJax+bussproofs reference PNGs (optional; for test_cases_prooftree)
│ ├── output/ # RaTeX-rendered PNGs (from ratex-render)
│ ├── output_ce/ # RaTeX mhchem renders (from update_golden_output.sh)
│ ├── output_prooftree/ # RaTeX bussproofs/prooftree PNG renders
│ ├── output_svg_prooftree/ # RaTeX bussproofs/prooftree SVG renders
│ ├── test_cases.txt # One LaTeX formula per line
│ ├── test_case_ce.txt # mhchem \\ce / \\pu examples (fixtures_ce/ refs); parser uses Rust mhchem
│ ├── test_cases_prooftree.txt # bussproofs \\begin{prooftree} examples
│
├── scripts/
│ ├── set-version.sh # Sync version to all platform manifests
│ ├── sync-katex-ttf-to-font-crate.sh # Copy KaTeX *.ttf → crates/ratex-katex-fonts/fonts/
│ ├── update_golden_output.sh # Renders all test_cases.txt → output/
│ ├── update_golden_prooftree.sh # Renders test_cases_prooftree.txt → output_prooftree/ + output_svg_prooftree/
│ ├── test-unicode-font.sh # Batch PNG/SVG/PDF render of test-formulas.txt across system / env fonts (CJK regression)
│ ├── test-formulas.txt # Sample lines for test-unicode-font.sh
│ └── fonts/ # Optional bundled fonts for tests (e.g. NotoSansCJKsc)
│
└── demo/ # Web demo + sample apps (web, ios, android, flutter, RN, jvm)
Cargo.toml (Workspace)
[workspace]
resolver = "2"
members = [
"crates/ratex-types",
"crates/ratex-font",
"crates/ratex-lexer",
"crates/ratex-parser",
"crates/ratex-layout",
"crates/ratex-katex-fonts",
"crates/ratex-font-loader",
"crates/ratex-ffi",
"crates/ratex-render",
"crates/ratex-svg",
"crates/ratex-wasm",
"crates/ratex-pdf",
"crates/ratex-unicode-font",
]
[workspace.package]
version = "0.0.16" # 与根目录 VERSION 及 scripts/set-version.sh 同步;见 RELEASING.md
edition = "2021"
authors = ["RaTeX Contributors"]
license = "MIT"
repository = "https://github.com/erweixin/RaTeX"
homepage = "https://github.com/erweixin/RaTeX"
documentation = "https://github.com/erweixin/RaTeX#readme"
[workspace.dependencies]
# 节选:各 ratex-* crate 使用 path + 与 workspace 对齐的 version;完整依赖表见仓库根 Cargo.toml
ratex-types = { path = "crates/ratex-types", version = "0.0.16" }
ratex-font = { path = "crates/ratex-font", version = "0.0.16" }
# …
phf = { version = "0.11", features = ["macros"] }
thiserror = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Crates (summary)
| Crate | Role |
|---|---|
| ratex-types | DisplayList, DisplayItem (GlyphPath, Line, Rect, Path), Color, PathCommand, MathStyle |
| ratex-font | KaTeX font metrics, symbol tables; data/metrics_data.rs, data/symbols_data.rs (generated) |
| ratex-lexer | LaTeX string → token stream |
| ratex-parser | Token stream → ParseNode AST (macro expansion, functions); mhchem \ce / \pu; bussproofs prooftree; auto-numbering for equation / align / gather / alignat (non-starred) and trailing-row \tag / \nonumber / \notag |
| ratex-layout | AST → LayoutBox tree → to_display_list → DisplayList |
| ratex-katex-fonts | Bundled KaTeX .ttf files + embed API; optional dep for ratex-svg / ratex-render / ratex-pdf embed-fonts |
| ratex-font-loader | Shared lazy font source/cache planner for PNG/SVG/PDF; cache entries are keyed by embedded/directory/system source |
| ratex-ffi | C ABI: ratex_parse_and_layout → DisplayList JSON; Android jni module when targeting Android |
| ratex-render | DisplayList → PNG via tiny-skia + ab_glyph (server/CI); embed-fonts uses ratex-katex-fonts |
| ratex-wasm | WASM: parse + layout → DisplayList JSON for browser |
| ratex-svg | SVG export: DisplayList → SVG string; standalone reads TTF from font_dir; embed-fonts uses ratex-katex-fonts; cli adds render-svg binary |
| ratex-pdf | PDF export: DisplayList → PDF via pdf-writer + font subsetting; embed-fonts uses ratex-katex-fonts; cli adds render-pdf binary |
| ratex-unicode-font | System Unicode / CJK font discovery; used by ratex-render, ratex-svg, ratex-pdf for fallback rendering of CJK / emoji / other glyphs absent from KaTeX font set |
ratex-types — DisplayItem (actual shape)
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum DisplayItem {
GlyphPath {
x: f64, y: f64,
scale: f64,
font: String,
char_code: u32,
commands: Vec<PathCommand>,
color: Color,
},
Line { x: f64, y: f64, width: f64, thickness: f64, color: Color },
Rect { x: f64, y: f64, width: f64, height: f64, color: Color },
Path {
x: f64, y: f64,
commands: Vec<PathCommand>,
fill: bool,
color: Color,
},
}
ratex-font layout
crates/ratex-font/
├── Cargo.toml
└── src/
├── lib.rs
├── font_id.rs # FontId enum
├── metrics.rs # CharMetrics, math constants
├── symbols.rs # Symbol lookup
└── data/ # Generated (do not edit by hand)
├── mod.rs
├── metrics_data.rs
└── symbols_data.rs
ratex-ffi
Exports a C ABI used by iOS (static lib / XCFramework), Android (JNI), Flutter (Dart FFI), and React Native (native module). Main entry: parse LaTeX and return a heap-allocated JSON DisplayList string; callers free with ratex_free_display_list. On failure, use ratex_get_last_error. See crate-level docs in crates/ratex-ffi/src/lib.rs.
ratex-render layout
crates/ratex-render/
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── main.rs # CLI binary (stdin → PNGs)
│ └── renderer.rs # DisplayList → tiny-skia rasterize
└── tests/
└── golden_test.rs # Compares output/ vs fixtures/ (ink score)
ratex-wasm
WASM crate; exports renderLatex(latex: string) => string (DisplayList JSON). Consumed by platforms/web (TypeScript + Canvas 2D).
ratex-svg
SVG export crate. Converts a DisplayList into an SVG string via render_to_svg(list, opts).
crates/ratex-svg/
├── Cargo.toml
└── src/
├── lib.rs # render_to_svg + SvgOptions; GlyphPath→<text>, Line/Rect→<rect>, Path→<path>
├── standalone.rs # (feature=standalone) load KaTeX TTF, convert glyph outlines to <path> data
└── bin/
└── render_svg.rs # CLI binary (feature=cli): stdin LaTeX → SVG files
Features:
| Feature | Description |
|---|---|
standalone | Embed glyph outlines as <path> using ab_glyph (requires KaTeX TTF files). Produces self-contained SVGs with no external font dependency. |
cli | Enables the render-svg binary (implies standalone + pulls in ratex-layout / ratex-parser). |
SvgOptions fields: font_size (em units, default 40.0), padding (default 10.0), stroke_width (default 1.5), embed_glyphs (use <path> outlines), font_dir (KaTeX TTF directory for standalone mode). render_to_svg retains the default rgba(...) paint syntax. Use render_to_svg_with_color_syntax(..., SvgColorSyntax::Rgb) (or pass render-svg --office-compatible-colors) to emit rgb(...) plus opacity attributes instead.
ratex-pdf
PDF export crate. Converts a DisplayList to PDF bytes via render_to_pdf(list, &PdfOptions).
crates/ratex-pdf/
├── Cargo.toml
└── src/
├── lib.rs
├── fonts.rs # load KaTeX TTF (disk or embed-fonts), subset, embed CIDFontType2
├── renderer.rs # content stream, paths, text
└── bin/
└── render_pdf.rs # CLI binary (feature=cli): stdin LaTeX → one PDF per line
Features:
| Feature | Description |
|---|---|
embed-fonts | Load TTFs from ratex-katex-fonts (no on-disk font_dir required). |
cli | Enables the render-pdf binary (implies embed-fonts + ratex-layout / ratex-parser). The CLI’s --font-dir flag does not affect embedding (same as any embed-fonts build). |
PdfOptions fields: font_size, padding, stroke_width, font_dir (KaTeX TTF directory when embed-fonts is off; must be set — PdfOptions::default uses an empty font_dir. When embed-fonts is on, font_dir is ignored.)
Dependency graph
ratex-types (base types)
↑
ratex-font (metrics + symbols)
↑
ratex-lexer
↑
ratex-parser
↑
ratex-layout
↑
├── ratex-ffi (C ABI for native)
├── ratex-render ─┐ (PNG)
├── ratex-wasm │ (browser JSON)
├── ratex-svg ├── ratex-unicode-font (CJK fallback loader)
└── ratex-pdf ┘ (PDF)
↑
platforms/ (ios, android, flutter, react-native, web)
platforms/gtk contains the Linux desktop GObject package metadata for the RatexGtk-1.0 namespace: the public C header, GIR file, Vala VAPI, pkg-config template, and C/Python/Vala smoke examples. The implementation lives in crates/ratex-gtk4.
Golden test workflow
- Reference PNGs:
tests/golden/fixtures/(from KaTeX, one per line intest_cases.txt). - RaTeX output:
scripts/update_golden_output.shrunsratex-renderto producetests/golden/output/*.png. - Comparison:
tools/golden_compare/compare_golden.py(or Rust testcrates/ratex-render/tests/golden_test.rs) compares output vs fixtures (e.g. ink-coverage threshold).
See also docs/MHCHEM_DATA.md (updating \ce / \pu JSON from KaTeX mhchem). Contributing: root CONTRIBUTING.md; releases: RELEASING.md.