RaTeX Documentation

repository·main·Indexed 23 days ago

https://github.com/erweixin/ratex

RaTeX is a high-performance, KaTeX-compatible math rendering engine written in pure Rust. It provides pixel-identical math rendering across Mobile, Web, Server, and Desktop platforms without requiring a JavaScript runtime or WebView. The project includes support for Android, iOS, JVM, Flutter, and React Native, as well as the ratex-katex-fonts crate for embedded KaTeX .ttf font files.

Tokens
59.1K
Snippets
121
Records
324
Agent score
74%

What's inside RaTeX

  1. Overview of RaTeX

    main
    RaTeX is a pure Rust implementation of a KaTeX-compatible mathematical rendering engine. Unlike KaTeX, which relies on a JavaScript engine (V8) and the DOM, RaTeX uses a Rust core to generate a display list that can be rendered natively on various platforms without a WebView or JavaScript runtime. This makes it suitable for high-performance, low-memory, and offline-capable applications on mobile, desktop, and server environments.
  2. What is RaTeX?

    main
    RaTeX is a KaTeX-compatible math rendering engine written in pure Rust. Unlike KaTeX, which requires a JavaScript runtime or a WebView, RaTeX uses a single Rust core to produce a display list that can be rendered natively on various platforms. This makes it suitable for environments where a heavy JS engine or WebView is undesirable, such as mobile apps (iOS, Android), Flutter, React Native, or server-side environments.
  3. What the RaTeX SPM macOS Demo validates

    main

    The macOS SPM demo is designed to check the following integration points:

    • SPM Exposure: Ensures Package.swift correctly exposes RaTeX on macOS.
    • FFI Resolution: Verifies that RaTeXFFI resolves correctly from the local XCFramework via SPM.
    • Parsing: Confirms RaTeXEngine.parse functions correctly within a macOS application environment.
    • SwiftUI Rendering: Validates that RaTeXFormula can render through SwiftUI using NSViewRepresentable.
  4. How formula numbering and `\tag` work in RaTeX

    main

    RaTeX follows KaTeX-style layout for numbered display environments.

    Automatic Numbering

    • Environments like equation, align, alignat, and gather generate sequential numbers (1), (2), etc., for each logical line.
    • Starred environments (e.g., equation*, align*) and inner environments (e.g., aligned, alignedat, split, gathered) do not participate in automatic numbering.

    Manual Tagging

    • Use \tag{...} or \tag*{...} at the end of a line to replace the automatic number with a custom label.
    • An empty \tag{} suppresses the number for that line.
    • Use \nonumber or \notag at the end of a line to remove the number. \notag and \nonumber are equivalent.
    • Note: You cannot use both \tag and \nonumber/\notag on the same line.

    Note: Each formula string is treated independently, starting numbering from (1).

  5. Supported Math and Chemistry Syntax

    main

    RaTeX supports a wide range of LaTeX math and chemistry syntax, aligned with KaTeX:

    • Standard Math: Fractions, radicals, integrals, matrices, environments, and stretchy delimiters.
    • Chemistry: Full mhchem support using \ce and \pu commands.
    • Physics Units: IUPAC-compliant value + unit expressions using \pu.
    • Proof Trees: bussproofs-style prooftree environments for inference rules and sequent calculi.

    Note on Proof Trees: Supported commands include \AxiomC / \AXC, unary through quinary inference commands (\UnaryInfC, \BinaryInfC, etc.), \LeftLabel / \RightLabel, \solidLine, \dashedLine, and \fCenter. Commands like \InsertBetweenHyps, \ScoreTree, \Cell, and \noCell are not yet implemented.

    % Chemistry example
    \ce{H2SO4 + 2NaOH -> Na2SO4 + 2H2O}
    \ce{Fe^{2+} + 2e- -> Fe}
    \pu{1.5e-3 mol//L}
    
    % Proof tree example
    \begin{prooftree}
    \AxiomC{A \fCenter B}
    \LeftLabel{cut}
    \RightLabel{\alpha}
    \UnaryInfC{C \fCenter D}
    \end{prooftree}
  6. Align RaTeX formulas with text baselines

    main

    RaTeX supports baseline alignment out of the box:

    1. Simple Alignment: For HStack or Text alignment, use HStack(alignment: .firstTextBaseline). RaTeXFormula reports its math baseline through .alignmentGuide(.firstTextBaseline), making it compatible with standard SwiftUI text alignment.
    2. Complex Wrapping: For inline formulas mixed with text that require automatic line wrapping, use a custom Layout (like FlowLayout) that reads the RaTeXFormulaAscentKey. This key carries the formula's ascent (distance from baseline to top) to ensure correct alignment during wrapping.
    // Simple baseline alignment
    HStack(alignment: .firstTextBaseline) {
        Text("Euler's identity:")
        RaTeXFormula(latex: #"e^{i\pi}+1=0"#, fontSize: 17, displayMode: false)
    }
  7. Coordinate system in RaTeX

    main

    The coordinate system used by RaTeX is consistent across iOS and Android:

    • All coordinates are in em units.
    • To get screen coordinates (logical pixels), multiply the em units by the fontSize.
    • The Y-axis increases downward from the top of the bounding box.
    • The baseline is located at Y = height * fontSize.
  8. How RaTeX manages multi-platform versions

    main

    RaTeX uses a unified versioning strategy where a single Git tag (e.g., v0.0.10) triggers releases across multiple platforms. To ensure consistency, all packages within the same tag must share the same version number. The version is synchronized across several key files:

    • Single Source of Truth: The VERSION file in the root directory.
    • Rust Crates: Cargo.toml via [workspace.package].version.
    • Flutter: platforms/flutter/pubspec.yaml.
    • Web (WASM): platforms/web/package.json.
    • React Native: platforms/react-native/package.json.
    • Android/iOS/JVM: Versions are derived from the Git tag during the release workflow (using -PlibraryVersion). Locally, Gradle reads from the root VERSION file if no parameter is passed.
  9. Understand RaTeX golden test scoring and metrics

    main

    RaTeX visual testing uses indexed manifests and specific scoring metrics to evaluate render quality against a KaTeX reference.

    Manifests and Indexing

    Reference and RaTeX generation each write a temporary manifest (e.g., tests/golden/fixtures/reference-manifest.json).

    • Formulas are indexed continuously (0001..NNNN).
    • Blank lines and lines starting with # or % are comments and do not consume an index.
    • The report enforces: formula_count == fixture_count == output_count == report_case_count.

    Scoring Metrics

    • rendered_mean: The average score of all successfully scored cases.
    • coverage: The ratio of scored cases to eligible (non-policy) cases.
    • raw_coverage: The ratio of scored cases to all cases (including policy exclusions).
    • coverage_adjusted_mean: The metric gated by --min-mean.

    Case Statuses

    Every report case is assigned one of the following statuses:

    • scored
    • missing_fixture
    • missing_output
    • parse_error
    • layout_error
    • render_error
    • unsupported
  10. How baseline alignment works in RaTeX

    main

    RaTeX components support baseline alignment, allowing them to sit on the same line as standard text in both Flexbox rows and <Text> components.

    In a Flex row: Use alignItems: 'baseline' on the parent container. Inside <Text>: Use style={{ alignSelf: 'baseline' }} on the RaTeXView component.

    Note: InlineTeX automatically uses displayMode={false} for all formulas to ensure they behave as inline elements.

    // In a Flex row
    <View style={{ flexDirection: 'row', alignItems: 'baseline' }}>
      <Text>f(x) =</Text>
      <RaTeXView latex={'\\frac{a}{b}'} fontSize={16} displayMode={false} />
    </View>
    
    // Inside a <Text> component
    <Text>
      compare y with{' '} 
      <RaTeXView latex="y" fontSize={16} displayMode={false} style={{ alignSelf: 'baseline' }} />{' '} 
      mid-sentence
    </Text>
  11. Understand RaTeX stack-safety and depth limits

    main

    RaTeX is designed to be stack-safe across native, mobile, and WebAssembly hosts by enforcing a strict input-depth policy. This prevents stack overflow vulnerabilities when processing untrusted LaTeX input.

    Depth Limits

    The maximum supported cumulative recursive or structural depth is 32.

    • Depth 32: Accepted.
    • Depth 33: Rejected with a ParseError containing the message Recursion limit exceeded.

    Cumulative Budget

    The depth budget is cumulative across all enclosing structures. You do not get a fresh allowance for each new structure; instead, nested structures consume the existing budget.

    Examples of depth-consuming structures:

    • Recursively nested parser expressions (groups, radicals, fractions, \left...\right, scripts).
    • Unbraced structural arguments (e.g., nested \tag chains).
    • Nested macro expansion paths.
    • Unicode combining-accent chains.
    • prooftree branches, conclusions, and labels.
    • mhchem sub-state-machine calls and nested texify values.

    Special Case: mhchem Because mhchem uses internal sub-state machines, visible nested \ce{...} commands consume extra budget. Consequently, a visible nesting depth of 31 is accepted, but a depth of 32 is rejected.

    Error Handling

    Over-limit input is never truncated or partially ignored; it is rejected entirely. The parser, layout, and to_display_list methods will return errors rather than attempting to render partial results.

  12. How the RatexFormula widget handles color

    main

    The RatexFormula GTK4 widget manages text color based on the following hierarchy:

    1. Unset color property: The widget uses the current GTK foreground text color (theme-derived).
    2. Set color property: The widget uses the specific color provided to the property as the default for the formula.
    3. Inline LaTeX overrides: Commands like \color or \textcolor within the LaTeX string act as per-item overrides and take precedence.