Appearance
Math Equations (LaTeX / MathML → OMML)
The math: option on a text item emits a native, editable PowerPoint equation (OMML inside PowerPoint's <a14:m> markup-compatibility envelope). That option takes raw OMML. The @shbernal/ts-pptx/math subpath lets you author the equation in LaTeX or MathML instead and get the OMML to hand it.
LaTeX --temml--> MathML --mathml2omml--> OMML --> { math: … } on addTextInstall the converters
The converters are optional peer dependencies: the core package does not pull them in, so consumers who never author math carry no extra weight. Install them to use this subpath:
sh
npm install temml mathml2ommltemml: LaTeX → MathML (MIT).mathml2omml: MathML → OMML (LGPL-3.0-or-later).
mathml2omml is LGPL. It is never bundled into this package's output (it stays a separate, replaceable dependency in your node_modules), and because it is opt-in, consumers with policies against LGPL can simply not install it.
Node-only. This subpath loads the converters synchronously via Node's
createRequire, so it runs under Node, not in a browser bundle. It is an authoring helper; the OMML it produces is plain data you can persist and feed tomath:from anywhere.
Usage
js
import TsPptx from '@shbernal/ts-pptx'
import { latexToOmml } from '@shbernal/ts-pptx/math'
const pptx = new TsPptx()
const slide = pptx.addSlide()
slide.addText([{ math: latexToOmml('x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}') }], {
x: 1,
y: 2,
w: 8,
h: 1,
})
await pptx.writeFile({ fileName: 'quadratic.pptx' })The item's math value fully controls the paragraph; any text on the same item is ignored (see TextProps.math).
API
latexToOmml(latex, opts?)
Convert a LaTeX math expression to OMML.
latex: string: e.g.\sum_{i=1}^{n} i = \frac{n(n+1)}{2}.opts.display?: boolean(defaulttrue) selects display (block) math: render indisplayModeand wrap the result in a centered<m:oMathPara>display paragraph. Withdisplay: false, temml renders in inline mode and a bare<m:oMath>is returned.- Returns OMML:
<m:oMathPara>…</m:oMathPara>(display) or<m:oMath>…</m:oMath>(inline). Both are accepted by themath:option; pass thedisplay: falseform together withinline: trueon the text item to flow the equation mid-paragraph (see Inline math). - Throws on invalid LaTeX, surfacing temml's parse position, e.g.
Invalid LaTeX (position 6): ….
mathmlToOmml(mathml)
Convert a MathML string (<math>…</math>) to OMML.
- Returns a bare
<m:oMath>…</m:oMath>with no namespace declarations (themath:envelope supplies themprefix at emit time).
Output form
Both functions emit OMML in the m: (http://schemas.openxmlformats.org/officeDocument/2006/math) namespace with no namespace declarations of their own: the <a14:m> envelope that math: authors declares m. mathmlToOmml always returns a bare <m:oMath>; latexToOmml returns that same <m:oMath> wrapped in a centered <m:oMathPara> unless display: false. All three shapes (inner OMML, <m:oMath>, <m:oMathPara>) are valid inputs to math:.
Inline math
By default a math: item is emitted as its own centered display-math paragraph. To flow an equation in a sentence, between plain text runs, set inline: true on the text item and give it the bare <m:oMath> form (latexToOmml(tex, { display: false }) or mathmlToOmml(mathml)):
js
import { latexToOmml } from '@shbernal/ts-pptx/math'
slide.addText(
[
{ text: 'where ' },
{ math: latexToOmml('x^2+1=y', { display: false }), inline: true },
{ text: ' holds' },
],
{ x: 1, y: 1, w: 8, h: 1 }
)The equation is emitted as an <a14:m><m:oMath> run (no <m:oMathPara>) within the same paragraph as the surrounding runs. The Requires="a14" envelope stays at the shape level, exactly as for display math.
Scope and limits
- No LaTeX preprocessing / macro packages: the input goes straight to temml. Custom macros,
\usepackage, and environments temml does not support are out of scope. - No raster fallback: output relies on the
Requires="a14"envelope, understood by PowerPoint 2010+. There is nomc:Fallbackimage for non-a14 consumers. - Fidelity is temml + mathml2omml's, with one correction applied in between. Accent commands (
\hat,\bar,\vec,\ddot, …) used to render as<m:limUpp>(an over-limit, with limit spacing), because temml emits a bare<mover>and mathml2omml keys strictly offaccent="true".latexToOmmlnow stamps that attribute, and swaps temml's spacing modifier (U+02C6, U+2192) for the combining mark ECMA-376 §22.1.2.20 says anaccPrcharacter should be (U+0302, U+20D7), so accents come out as<m:acc>with the character Word itself writes. This applies tolatexToOmmlonly:mathmlToOmmlpasses your MathML through as written, because there theaccentattribute is yours to set. Constructs that were already mapping well are untouched:\widehatand\overbracestay<m:groupChr>,\overline/\underlinestay<m:borderBox>,\stackrelstays<m:limUpp>. Two cases remain limits by necessity:\utildeand other under-accents (OMML has no under-accent object, and the symmetricaccentunder="true"would move the mark above the base), and\ddddot, whose two-character operator has no singlem:chr. See issue #6.
Error policy
Invalid LaTeX throws (with temml's parse position) rather than emitting a degenerate equation: consistent with the library's no-silent-coercion rule. Wrap calls in try/catch if you convert untrusted input.