Mova0.5 pre-release⌕
☰
home / docs / latex — built-in LaTeX support

latex — built-in LaTeX support

Goal: built-in, compiled LaTeX support. Math-mode formulas → our own tree (enums) → back to canonical LaTeX or plain text. Everything is in the binary, no external TeX needed; on the website formulas are drawn by KaTeX. Its place in the mini-lab is described in Smart annotator — layers, context, memory, "Mini-lab".

How it is built

filewhat it does
data/commands.txt + build.rsa single command table → enums Sym (TeX class, Unicode, whether it is a delimiter), FracKind, Accent, Font, TextStyle, Stack, XArrow, EnvKind and constant matches: name → Entry, character (≤, α) → Sym, environment → EnvKind. The first form is canonical for printing (\leq → \le). A duplicate form or an unknown kind or class is a build error
lex.rsmath-mode lexer (TeX rules: \alpha eats spaces, % is a comment, spaces merge) and a stack stream onto which a macro pushes its body
macros.rs\newcommand/\renewcommand/\providecommand with [n][default], \def with #1…#9 (and with delimiters, as in TeX: \def\pair(#1,#2){…}), \let (keeps the old value), \DeclareMathOperator(*); Macros::scan(tex) collects definitions from a document
parse.rsparser: tokens → Node; errors with a byte position (Error::column, Error::context — a ⟦ mark in the source)
ast.rstree: Row, Num, Char, Sym, Group, Frac, Sqrt, Scripts (base, scripts, primes), OpName, LeftRight/Middle, Env (tables), Font, Text, Accent, Stack, XArrow, Class, Not, Unknown (name, arguments, position). Span does not take part in ==
print.rsto_latex (canonical LaTeX), to_text (Unicode: (a + b)/2, x², ℝⁿ, matrix (a b; c d)), to_sexpr (debugging), to_latex_faulty (deliberate defects for the negative control)
gate.rsround-trip gate parse(print(parse(x))) == parse(x); affected — whether a defect touches the tree (for a precise negative control)
extract.rsformulas from .tex: $…$, $$…$$, \(…\), \[…\], equation, align, alignat{n}, gather, multline, eqnarray, flalign, displaymath, math (and starred forms); comments, \$, \verb, verbatim are skipped; $…$ does not cross an empty line
tomath.rs (feature math)bridge to math::Expr and back (see below)
main.rs, corpus.rsCLI: parse, tex, corpus (arXiv metadata .xml.gz, .tex)

What is supported

Bridge to math::Expr (feature math)

to_expr covers a subset: numbers, variables, + − · × / ÷ and implicit multiplication, unary minus, fractions, roots (\sqrt[3]{x} → x^(1/3)), powers, \sin \cos \tan \exp \ln, absolute value |x|, parentheses ((x+1)^2 — in TeX the script attaches to ), and the bridge accounts for this), e, \pi. \sin 2x = sin(2x), \sin x\cos x = sin(x)·cos(x), \sin^2 x = (sin x)². \frac{1}{2} (an irreducible fraction of integers) is a rational literal; \frac{2}{4} stays a division (no step is lost). to_relation handles a chain a = b ≤ c. A refusal carries the kind of reason ("variable", "script", "function", "construct", "relation", "syntax", …). from_expr is the reverse side: printing math steps and answers in LaTeX; a test checks Expr → LaTeX → tree → Expr on 35 expressions (with normalization Div(1,2) ≡ 1/2). math::Expr may change after the v2 merge — the bridge will be fixed at merge time.

CLI

cargo build --release [--features math]
../target/release/latex parse '\frac{a+b}{2} \le \sqrt[3]{x}'   # tree, LaTeX, text, unknowns, round trip (and math::Expr)
../target/release/latex tex main.tex chap1.tex -v                # document formulas with macros from all files
../target/release/latex corpus $MOVA_DATA/raw/math/arxiv-oai --out DIR [--math] [--fault swapfrac|dropsup|droplast] [--limit N]

Measurements (26.09, 1 thread)

Real formulas — arXiv abstracts and titles from the library pilot (arxiv-oai, OAI-PMH arXivRaw metadata, 868 .xml.gz; the library has no .tex sources): 789 040 records after removing 316 757 duplicates between sets, 2 540 333 formulas (729 362 distinct).

measurevalue
parsed2 539 822 (99.98 %); 511 errors — all on the author's side (unclosed {, % in reformatted abstracts swallowing \end{…}, $ inside a formula)
without Unknown2 474 313 (97.40 %); distinct formulas — 94.51 %
round trip2 539 822 of 2 539 822 green (100 %)
bridge to math::Expr8.96 % (expression 7.91 %, relation 1.05 %); the main reason for refusals is variables outside x y z t u v w n (math::Var)
speedparsing 1.7–1.8 M formulas/s (18–19 MB/s of formula text; spread due to box load, three runs); gate (print + reparse) ~1 M/s; the whole run with gzip and XML — 18–19 s

Top unknowns are author macros without a preamble (abstracts have none): \R 7530, \Z 2892, \C 2576, \F 1449, \eps 1244, \A, \Q, \g, \N, \RR… In .tex they are expanded by Macros::scan. Full list — unknown.tsv.

A real multi-file document (the IRSTLM manual, 29 .tex in raw/ext, read-only): 101 formulas, all parsed without Unknown, macros from the main file.

Negative controls

cargo test and cargo test --features math are green (unit, end-to-end, bridge, property on random inputs).

Independent tests (tests3, 26.09)

Licenses

What v1 lacks

Licence

Elamur Cosmic License (Elamur Cosmic License). Third-party data keeps its own terms, as noted where it is used.

This page in Markdown → https://md.mova.elamur.ai/free/en/docs/latex/