| 1 | # Native Formula Specification |
| 2 | |
| 3 | Shared authoring contract for editable PowerPoint math generated from exact |
| 4 | LaTeX, either inline in Slide-local prose or as a standalone block. |
| 5 | |
| 6 | ## 1. Trigger and Ownership |
| 7 | |
| 8 | **Trigger**: A page contains structural mathematical notation such as a |
| 9 | fraction, radical, integral, n-ary expression, limit, matrix, delimiter |
| 10 | construction, accent, or complex script. |
| 11 | |
| 12 | | Layer | Ownership | |
| 13 | |---|---| |
| 14 | | Default Strategist | Record exact mathematical content as a canonical delimiter-free LaTeX expression body; do not classify its implementation | |
| 15 | | Default Executor | Decide ordinary text versus inline native math versus block native math, then author the selected marker and SVG preview | |
| 16 | | Active Quick context | Perform both content and authoring responsibilities directly | |
| 17 | | SVG-to-PPTX exporter | Compile marker LaTeX to editable Office Math and replace only the registered preview | |
| 18 | |
| 19 | | Content form | Authoring choice | |
| 20 | |---|---| |
| 21 | | Short variables, percentages, simple assignments, or notation such as `O(n log n)` | Ordinary editable SVG text | |
| 22 | | One-line structural math embedded in prose whose native-height envelope fits the reserved row/module space | Inline native marker | |
| 23 | | Matrix, `cases`, `aligned`, multiline derivation, standalone high-structure expression, or vertically expanding math that cannot fit its prose row | Block native marker | |
| 24 | |
| 25 | The Strategist's `Mathematical content` field does not pre-decide this choice. |
| 26 | Formula handling is not a user-confirmed policy, image resource, manifest, or |
| 27 | `spec_lock.md images` entry. |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ## 2. Canonical Markers |
| 32 | |
| 33 | ### 2.1 Inline formula |
| 34 | |
| 35 | ```xml |
| 36 | <text x="120" y="240" font-size="28" fill="#173B57"> |
| 37 | The ratio <tspan data-pptx-inline-formula="\frac{a_i}{b_i}">aᵢ/bᵢ</tspan> remains stable. |
| 38 | </text> |
| 39 | ``` |
| 40 | |
| 41 | **Hard rule — one leaf run**: Put non-empty LaTeX directly in |
| 42 | `data-pptx-inline-formula` on a leaf `<tspan>`. Canonical authoring omits outer |
| 43 | `$...$`, `$$...$$`, `\(...\)`, and `\[...\]` delimiters, though the compiler |
| 44 | accepts and removes one complete outer pair. Give that `<tspan>` one non-empty |
| 45 | direct preview string with no leading/trailing whitespace, no child element, |
| 46 | and no `x`, `y`, `dx`, `dy`, or paragraph-layout metadata; spacing belongs to |
| 47 | the surrounding text. The marker inherits its computed size and visible solid |
| 48 | fill; exported math uses the project text language and Cambria Math. Local |
| 49 | `\color` / `\textcolor` scopes override the marker fill on both selectable |
| 50 | formula runs and non-selectable structural controls. `\boldsymbol` / `\bm` |
| 51 | also applies its bold-italic style to structural control glyphs. Neither form |
| 52 | changes unrelated marker defaults. |
| 53 | |
| 54 | **Hard rule — Slide-local ordinary text only**: Do not place an inline marker |
| 55 | inside a structured Layout placeholder, a Master/Layout layer, imported |
| 56 | preserved `txBody`, geometry transport subtree, another inline marker, or any |
| 57 | `data-pptx-replace-with` subtree. Export keeps the surrounding text runs in the |
| 58 | same `a:p` and replaces only the marker run with `a14:m > m:oMath`. |
| 59 | |
| 60 | **Hard rule — reserve native height**: Treat the parsed formula structure, not |
| 61 | its flat SVG preview, as vertical layout truth. Keep adjacent content outside |
| 62 | the native ascent/descent required by fractions, radicals, nested scripts, |
| 63 | n-ary limits, accents, and other stacked structures. The exporter and SVG |
| 64 | checker use the same structural envelope. If the prose row or root module |
| 65 | cannot reserve that space without overlap, isolate the formula line or use the |
| 66 | block marker. |
| 67 | |
| 68 | ### 2.2 Block formula |
| 69 | |
| 70 | ```xml |
| 71 | <g id="quadratic-formula" data-pptx-replace-with="formula" |
| 72 | data-pptx-x="190" data-pptx-y="245" |
| 73 | data-pptx-width="900" data-pptx-height="180" |
| 74 | data-pptx-bounds="190 245 900 180"> |
| 75 | <metadata type="application/json"><![CDATA[ |
| 76 | {"latex":"\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}", |
| 77 | "display":"block","font_size":42,"color":"#173B57","align":"center"} |
| 78 | ]]></metadata> |
| 79 | <text x="640" y="345" text-anchor="middle" |
| 80 | font-size="42" fill="#173B57">(-b ± √(b²−4ac)) / 2a</text> |
| 81 | </g> |
| 82 | ``` |
| 83 | |
| 84 | **Hard rule — block metadata is truth**: Write one direct |
| 85 | `<metadata type="application/json">` child with non-empty `latex`, `display: |
| 86 | block`, `font_size` in `(0, 400]`, a visible `color`, and `align: |
| 87 | left|center|right`. Use the same canonical delimiter-free form described above. |
| 88 | Give the group finite `data-pptx-x/y`, positive `data-pptx-width/height`, and |
| 89 | matching root-coordinate `data-pptx-bounds`. Export replaces the complete group |
| 90 | with `a14:m > m:oMathPara > m:oMath`. |
| 91 | |
| 92 | **Hard rule — preview is SVG, never fallback**: Make every marker preview |
| 93 | semantically equivalent with ordinary SVG text/shapes/lines/paths. Do not use |
| 94 | `<image>`, `<foreignObject>`, visible raw LaTeX, or another runtime renderer. |
| 95 | The exporter discards the registered preview and emits no picture branch. |
| 96 | |
| 97 | --- |
| 98 | |
| 99 | ## 3. Source, Failure, and Validation |
| 100 | |
| 101 | **Forward input profile**: The compiler implements every explicitly named |
| 102 | LaTeX-to-OMML input and behavior in Microsoft's documented |
| 103 | [Microsoft 365 LaTeX profile](https://learn.microsoft.com/en-us/office/math/latex) |
| 104 | (Windows 2606 / Mac 16.110) and |
| 105 | [mhchem profile](https://learn.microsoft.com/en-us/office/math/latex.mhchem) |
| 106 | (Windows 2605 / Mac 16.109). This includes outer delimiters, all listed symbols |
| 107 | and relations, fractions and binomials, roots, right and left scripts, |
| 108 | delimiters and `\middle`, accents, bars and group characters, limits, all 21 |
| 109 | listed n-ary operators, standard/custom functions, matrices and equation-array |
| 110 | environments, CD diagrams, fonts and local colors, boxes and phantoms, spacing, |
| 111 | global 0–9 argument macros, and the documented `\ce` chemistry grammar. The |
| 112 | closed command tables in `scripts/svg_to_pptx/native_objects/formula_profile.py` |
| 113 | are the executable vocabulary; the public compiler facade and OMML structure |
| 114 | gate live in `scripts/svg_to_pptx/native_objects/formula_compiler.py` and |
| 115 | `scripts/svg_to_pptx/native_objects/formula_omml.py`. Microsoft's open-ended |
| 116 | “etc.” wording for additional relation aliases does not define undisclosed |
| 117 | names; only explicitly named commands and retained project aliases are |
| 118 | contractual. |
| 119 | |
| 120 | Implementations: |
| 121 | [`formula.py`](../scripts/svg_to_pptx/native_objects/formula.py), |
| 122 | [`formula_ast.py`](../scripts/svg_to_pptx/native_objects/formula_ast.py), |
| 123 | [`formula_parser.py`](../scripts/svg_to_pptx/native_objects/formula_parser.py), |
| 124 | [`formula_run_properties.py`](../scripts/svg_to_pptx/native_objects/formula_run_properties.py), |
| 125 | [`inline_formula.py`](../scripts/svg_to_pptx/native_objects/inline_formula.py). |
| 126 | |
| 127 | **Native normalization**: `\dfrac` / `\tfrac`, `\dbinom` / `\tbinom`, and |
| 128 | continued-fraction alignment normalize to the corresponding OMML structure; |
| 129 | explicit big-delimiter grades become auto-sizing delimiters; `\mathscr` |
| 130 | normalizes to `\mathcal`; `smallmatrix` normalizes to `matrix`; PowerPoint array |
| 131 | columns become centered; style/size commands and equation tags are accepted but |
| 132 | not stored. Color is stored in generated formula runs and structural control |
| 133 | properties. |
| 134 | |
| 135 | **Narrow reverse import**: `pptx_to_svg.py` rebuilds a block formula marker or |
| 136 | same-paragraph inline marker only when one `a14:m` root passes this compiler's |
| 137 | closed OMML validator and its normalized structure can be serialized back to |
| 138 | LaTeX accepted by the same compiler. The reconstructed LaTeX is canonicalized; |
| 139 | it is not the original spelling. A formula-only `m:oMathPara` text shape becomes |
| 140 | one bounded block marker when its carrier also fits the unstyled rectangular |
| 141 | native-formula contract; carrier grouping, paint, effects, rotation, hyperlink, |
| 142 | or placeholder ownership force fallback instead of being silently discarded. |
| 143 | Supported `m:oMath` zones remain inline among their surrounding text runs. Both |
| 144 | forms receive a dependency-free linear SVG preview. This contract covers PPT |
| 145 | Master-emitted vocabulary, not arbitrary third-party OMML. Tolerant import |
| 146 | reports `formula-not-reconstructed`, renders readable formula text, and retains |
| 147 | a relationship-free unchanged source `txBody` as opaque metadata; strict import |
| 148 | stops instead. |
| 149 | |
| 150 | **Fail-closed boundary**: Input containing unknown commands or environments, |
| 151 | Microsoft's explicitly unsupported commands, unsupported mhchem arrows, |
| 152 | unescaped `%` comments, invalid macros, or any resource-limit overflow blocks |
| 153 | conversion. This is stricter than Microsoft 365's literal-text passthrough and |
| 154 | macro-limit behavior: PPT Master never leaks unresolved LaTeX into a released |
| 155 | slide. |
| 156 | |
| 157 | **Hard rule — repair LaTeX upstream**: Unsupported source or an invalid marker |
| 158 | blocks the page. Rewrite within the documented profile without changing the |
| 159 | planned mathematics; otherwise return it to the content owner. Never substitute |
| 160 | a PNG, flatten structural math into ordinary text, hand-write OMML, or leave raw |
| 161 | LaTeX visible. |
| 162 | |
| 163 | **Compatibility boundary**: The generated package uses standard editable Office |
| 164 | Math and retains the PowerPoint 2010+ package target. The executable profile is |
| 165 | pinned to the Microsoft documentation versions above. Repository verification |
| 166 | covers compilation, OMML structure, and PPTX packaging; it is not a complete |
| 167 | Microsoft 365 UI rendering/editability certification. Earlier PowerPoint |
| 168 | versions are not the source-profile baseline. WPS, Keynote, LibreOffice, and |
| 169 | other clients receive no embedded formula fallback and are outside the |
| 170 | rendering/editability contract. |
| 171 | |
| 172 | **Validation**: The first-page/final SVG checker validates every marker, |
| 173 | compiles its LaTeX, and applies the shared native-height envelope to page/module |
| 174 | text bounds before release; native export repeats validation and uses that |
| 175 | envelope for the generated text frame. |
| 176 |