| 1 | # Native equation fixtures for the math model |
| 2 | |
| 3 | `native-editor/` is OneNote 2010 typing five expressions through its equation |
| 4 | editor (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 |
| 8 | left 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 |
| 11 | object controls and the text-run data naming each object's kind (29 |
| 12 | subscript, 30 sub-superscript, 13 brackets, 21 n-ary with its operator |
| 13 | symbol). `crates/onestore/tests/page_math.rs` renders every expression from |
| 14 | the stored section and compares it with the exported MathML byte for byte; |
| 15 | together with `corpus/m6/native-math-01` (superscripts, a fraction, inline |
| 16 | Greek) 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 |
| 22 | paragraph. Its MathML adds radicals (25: `msqrt`, or `mroot` with the |
| 23 | degree 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 |
| 25 | overbar (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, |
| 29 | its 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 |
| 33 | column count on the opening run's `0x0c003451`), equation arrays (15: rows |
| 34 | with `maligngroup` and a `malignmark` for each `&`), an upper limit (33: |
| 35 | `mover`), boxes (11: `mpadded`; 12: `menclose notation="box"`) and an n-ary |
| 36 | operator 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 |
| 40 | equation of both fixtures copied as a new paragraph, then two expressions |
| 41 | built from `Math` trees (`x^2+1` and a fraction with a superscript in its |
| 42 | denominator) through `Math::paragraph`. The writer stores each as OneNote |
| 43 | does: the linear text, one run per span with a Cambria Math italic style |
| 44 | carrying the math flags and the math language, the text-run data array |
| 45 | naming 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 |
| 47 | equals `expected-mathml.json` (the native fixtures' exports plus the two |
| 48 | built expressions) and `page-000.png` shows the equations rendered. |
| 49 | `tools/test_math_edit.py` checks both without a VM. |
| 50 | |
| 51 | Regenerate the editor fixture with `tools/native_math.py |
| 52 | corpus/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 |
| 58 | of the forms above and adding `e^(x+1)`, `\alpha+\beta` (which stays linear |
| 59 | text: 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 |
| 61 | object, 17 with U+2061, around a limit; not built by the linear reading |
| 62 | here) and `{a+b}`; `x_i^2` kept the editor's “Type equation here.” |
| 63 | placeholder (11 with `⬚`), as the editor was still opening. |
| 64 | |
| 65 | `native-linear/` is the linear form OneNote 2010 shows and stores after |
| 66 | Equation Tools, Design, Linear, applied to each equation of a session like the |
| 67 | fourth one plus `x^2+1` and `(a+b)/(c+d)`. It was authored interactively in a |
| 68 | lab clone through its desktop agent (clicking each equation, then Linear), as |
| 69 | the key tips and the equation's context menu would not switch it from a |
| 70 | script; `notebook/links.one` is the section OneNote saved on closing. Each |
| 71 | equation becomes one run of math between objects: letters in mathematical |
| 72 | italic, 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`, `□𝑥`, `▭𝑥`, `¯𝑥`, |
| 75 | and 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, |
| 79 | writes each tree back as the linear text OneNote showed, and rebuilds every |
| 80 | native equation from its linear form; `crates/canvas/src/editor/equation.rs` |
| 81 | types 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, |
| 84 | driven by `tools/native_enter.py`: Enter at an equation's start moves the |
| 85 | equation to a paragraph of its own; inside the equation's own row it stores a |
| 86 | line break (`\r`, a plain run) in the paragraph, the equation's two sides |
| 87 | becoming two equations (two MathML blocks in the read); inside a fraction's |
| 88 | denominator it makes that argument an equation array (15, `█`) of the two |
| 89 | parts; at a link's start the whole link, field code and label, moves down. An |
| 90 | interactive 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 |
| 92 | compares every paragraph's runs, and `page_math.rs` compares each equation's |
| 93 | MathML with the read. |