1# Native equation fixtures for the math model
2
3`native-editor/` is OneNote 2010 typing five expressions through its equation
4editor (Alt+=) on the Rust-authored link page, driven by
5`tools/native_math.py` (`equations.ahk` is the AutoHotkey session,
6`equations.png` the desktop afterwards): `a_1+b_2`, `x_i^2`, `(a+b)`,
7`\int_0^1 x dx` and `\sum_(i=1)^n i`; `\sqrt(x+1)` did not build up and
8left an empty paragraph. `before-read/` is the COM read before typing,
9`read/` the read afterwards with each expression exported as MathML, and
10`notebook/` the section OneNote saved: the linear text with U+FDD0/FDEE/FDEF
11object controls and the text-run data naming each object's kind (29
12subscript, 30 sub-superscript, 13 brackets, 21 n-ary with its operator
13symbol). `crates/onestore/tests/page_math.rs` renders every expression from
14the stored section and compares it with the exported MathML byte for byte;
15together with `corpus/m6/native-math-01` (superscripts, a fraction, inline
16Greek) that covers the kinds `onestore::page::Math` claims.
17
18`native-editor-2/` is a second session (`ONESTORE_MATH_EQUATIONS` on
19`tools/native_math.py`): `\sqrt x+1`, `\cbrt(x)`, `\sqrt(n&x)`, `a/b`,
20`\lim_(x\to 0) f(x)` (the `\lim` stayed literal), `\prod_(k=1)^n k`,
21`[a+b]`, `\overline(x)` and `x\hat`; `\sqrt (x+1)` again left an empty
22paragraph. Its MathML adds radicals (25: `msqrt`, or `mroot` with the
23degree second), a lower limit (19: `munder`, with the upright `lim` as one
24`mi` in a row), a product, named fences (`mfenced open="[" close="]"`), an
25overbar (23: `mover accent="false"` with a stretchy bar) and an accent (10:
26`mover accent="true"` with the combining circumflex exported as `^`).
27
28`native-editor-3/` is a third session: `\matrix(1&2@3&4)` (exported inline,
29its trailing `(\matrix(a&b@c&d))` staying literal text), `\eqarray(x&=1@y&=2)`,
30`x\above 2`, `x\below 2`, `\box(x)`, `\rect(x)`, `\underline(x)` (a literal
31`▱` before fences), `\iint x dx dy` (a bare operator), `f(x)/(x^2+1)` and
32`\sum^n x`. Its MathML adds matrices (20: `mtable` of cells row by row, the
33column count on the opening run's `0x0c003451`), equation arrays (15: rows
34with `maligngroup` and a `malignmark` for each `&`), an upper limit (33:
35`mover`), boxes (11: `mpadded`; 12: `menclose notation="box"`) and an n-ary
36operator with one empty limit (`mover`, or `msup` for integrals).
37
38`written/candidate` is the page writer's output for
39`equations_are_written_and_read_back`: on a fresh section, every native
40equation of both fixtures copied as a new paragraph, then two expressions
41built from `Math` trees (`x^2+1` and a fraction with a superscript in its
42denominator) through `Math::paragraph`. The writer stores each as OneNote
43does: the linear text, one run per span with a Cambria Math italic style
44carrying the math flags and the math language, the text-run data array
45naming each run's object, and the math language marker on the text object.
46`written/cold` is the OneNote 2010 read of that section: its exported MathML
47equals `expected-mathml.json` (the native fixtures' exports plus the two
48built expressions) and `page-000.png` shows the equations rendered.
49`tools/test_math_edit.py` checks both without a VM.
50
51Regenerate the editor fixture with `tools/native_math.py
52corpus/link-edit/candidate OUTPUT` and the written one with
53`ONESTORE_MATH_EXPORT` set while running the test, then
54`tools/native_runner.py OUTPUT COLD --expected-pages 1 --collect-notebook
55--screenshots`.
56
57`native-editor-4/` is a fourth `tools/native_math.py` session repeating most
58of the forms above and adding `e^(x+1)`, `\alpha+\beta` (which stays linear
59text: one run between objects, Greek in mathematical italic),
60`(a+b)/(c+d)`, `x^2+y^2=z^2`, `lim_(n\to\infty) a_n` (a function-apply
61object, 17 with U+2061, around a limit; not built by the linear reading
62here) and `{a+b}`; `x_i^2` kept the editor's “Type equation here.”
63placeholder (11 with `⬚`), as the editor was still opening.
64
65`native-linear/` is the linear form OneNote 2010 shows and stores after
66Equation Tools, Design, Linear, applied to each equation of a session like the
67fourth one plus `x^2+1` and `(a+b)/(c+d)`. It was authored interactively in a
68lab clone through its desktop agent (clicking each equation, then Linear), as
69the key tips and the equation's context menu would not switch it from a
70script; `notebook/links.one` is the section OneNote saved on closing. Each
71equation becomes one run of math between objects: letters in mathematical
72italic, arguments of more than one factor in parentheses, an n-ary body after
73`▒` inside `〖〗`, `√(n&x)` for a root's degree and `∛` for a cube root,
74`■(1&2@3&4)` and `█(x&=1@y&=2)` for arrays, `𝑥┴2`, `𝑥┬2`, `□𝑥`, `▭𝑥`, `¯𝑥`,
75and an accent after a no-break space.
76
77`crates/onestore/tests/page_math.rs` builds every typed expression with
78`Math::from_linear` and compares it with what the editor stored, run by run,
79writes each tree back as the linear text OneNote showed, and rebuilds every
80native equation from its linear form; `crates/canvas/src/editor/equation.rs`
81types the same keys into the canvas editor, building up at each space.
82
83`native-enter/` is OneNote 2010 pressing Enter around equations and a link,
84driven by `tools/native_enter.py`: Enter at an equation's start moves the
85equation to a paragraph of its own; inside the equation's own row it stores a
86line break (`\r`, a plain run) in the paragraph, the equation's two sides
87becoming two equations (two MathML blocks in the read); inside a fraction's
88denominator it makes that argument an equation array (15, `█`) of the two
89parts; at a link's start the whole link, field code and label, moves down. An
90interactive session showed that Enter inside a link opens it instead.
91`crates/canvas/tests/links_equations.rs` presses the same keys in the editor and
92compares every paragraph's runs, and `page_math.rs` compares each equation's
93MathML with the read.