Files
mantle-ai-trader/skills/docx/references/math-formulas.md
2026-06-06 05:21:10 +00:00

7.7 KiB
Executable File
Raw Permalink Blame History

Math Formulas — LaTeX → docx-js Mapping

Design Philosophy

GLM uses LaTeX as the formula input syntax, internally converting to docx-js Math objects.

Why not write OMML directly?

  • Models are naturally proficient in LaTeX (abundant in training data)
  • LaTeX is semantically clear and highly readable
  • Conversion layer is encapsulated internally, transparent to the user

Quick Start

const { Math: OoxmlMath, MathRun, MathFraction, MathSuperScript,
        MathSubScript, MathRadical, MathSum, MathSubSuperScript } = require("docx");

// Embed formula in paragraph
new Paragraph({
  alignment: AlignmentType.CENTER,
  children: [
    new OoxmlMath({
      children: [/* Math components */]
    })
  ]
})

LaTeX → docx-js Conversion Table

Basic Operations

LaTeX Meaning docx-js Implementation
x + y Addition new MathRun("x + y")
x - y Subtraction new MathRun("x y") (use Unicode minus )
x \times y Multiplication new MathRun("x × y")
x \div y Division new MathRun("x ÷ y")
x \pm y Plus-minus new MathRun("x ± y")
x \neq y Not equal new MathRun("x ≠ y")
x \leq y Less or equal new MathRun("x ≤ y")
x \geq y Greater or equal new MathRun("x ≥ y")

Fractions

LaTeX docx-js
\frac{a}{b} new MathFraction({ numerator: [new MathRun("a")], denominator: [new MathRun("b")] })
\frac{x+1}{x-1} new MathFraction({ numerator: [new MathRun("x+1")], denominator: [new MathRun("x1")] })

Superscripts & Subscripts

LaTeX docx-js
x^2 new MathSuperScript({ children: [new MathRun("x")], superScript: [new MathRun("2")] })
x_i new MathSubScript({ children: [new MathRun("x")], subScript: [new MathRun("i")] })
x_i^2 new MathSubSuperScript({ children: [new MathRun("x")], subScript: [new MathRun("i")], superScript: [new MathRun("2")] })

Radicals

LaTeX docx-js
\sqrt{x} new MathRadical({ children: [new MathRun("x")] })
\sqrt[3]{x} new MathRadical({ children: [new MathRun("x")], degree: [new MathRun("3")] })

Summation & Integrals

LaTeX docx-js
\sum_{i=1}^{n} new MathSum({ subScript: [new MathRun("i=1")], superScript: [new MathRun("n")], children: [new MathRun("aᵢ")] })

Greek Letters

Use Unicode characters directly:

// LaTeX → Unicode mapping
const GREEK = {
  "\\alpha": "α", "\\beta": "β", "\\gamma": "γ", "\\delta": "δ",
  "\\epsilon": "ε", "\\zeta": "ζ", "\\eta": "η", "\\theta": "θ",
  "\\iota": "ι", "\\kappa": "κ", "\\lambda": "λ", "\\mu": "μ",
  "\\nu": "ν", "\\xi": "ξ", "\\pi": "π", "\\rho": "ρ",
  "\\sigma": "σ", "\\tau": "τ", "\\phi": "φ", "\\chi": "χ",
  "\\psi": "ψ", "\\omega": "ω",
  "\\Alpha": "Α", "\\Beta": "Β", "\\Gamma": "Γ", "\\Delta": "Δ",
  "\\Theta": "Θ", "\\Lambda": "Λ", "\\Pi": "Π", "\\Sigma": "Σ",
  "\\Phi": "Φ", "\\Psi": "Ψ", "\\Omega": "Ω",
};

Complete Formula Examples

Quadratic Formula

LaTeX: x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}

new OoxmlMath({
  children: [
    new MathRun("x = "),
    new MathFraction({
      numerator: [
        new MathRun("b ± "),
        new MathRadical({
          children: [
            new MathSuperScript({
              children: [new MathRun("b")],
              superScript: [new MathRun("2")],
            }),
            new MathRun("  4ac"),
          ],
        }),
      ],
      denominator: [new MathRun("2a")],
    }),
  ],
})

Pythagorean Theorem

LaTeX: a^2 + b^2 = c^2

new OoxmlMath({
  children: [
    new MathSuperScript({ children: [new MathRun("a")], superScript: [new MathRun("2")] }),
    new MathRun(" + "),
    new MathSuperScript({ children: [new MathRun("b")], superScript: [new MathRun("2")] }),
    new MathRun(" = "),
    new MathSuperScript({ children: [new MathRun("c")], superScript: [new MathRun("2")] }),
  ],
})

Trigonometric Identity

LaTeX: \sin^2\theta + \cos^2\theta = 1

new OoxmlMath({
  children: [
    new MathSuperScript({ children: [new MathRun("sin")], superScript: [new MathRun("2")] }),
    new MathRun("θ + "),
    new MathSuperScript({ children: [new MathRun("cos")], superScript: [new MathRun("2")] }),
    new MathRun("θ = 1"),
  ],
})

Common Exam Formula Templates

Middle School Math

// Quadratic discriminant
const discriminant = new OoxmlMath({
  children: [
    new MathRun("Δ = "),
    new MathSuperScript({ children: [new MathRun("b")], superScript: [new MathRun("2")] }),
    new MathRun("  4ac"),
  ],
});

// Circle area
const circleArea = new OoxmlMath({
  children: [
    new MathRun("S = π"),
    new MathSuperScript({ children: [new MathRun("r")], superScript: [new MathRun("2")] }),
  ],
});

High School Math

// Logarithm change of base
const logChange = new OoxmlMath({
  children: [
    new MathSubScript({ children: [new MathRun("log")], subScript: [new MathRun("a")] }),
    new MathRun("b = "),
    new MathFraction({
      numerator: [new MathRun("ln b")],
      denominator: [new MathRun("ln a")],
    }),
  ],
});

// Arithmetic series sum
const arithmeticSum = new OoxmlMath({
  children: [
    new MathSubScript({ children: [new MathRun("S")], subScript: [new MathRun("n")] }),
    new MathRun(" = "),
    new MathFraction({
      numerator: [
        new MathRun("n("),
        new MathSubScript({ children: [new MathRun("a")], subScript: [new MathRun("1")] }),
        new MathRun(" + "),
        new MathSubScript({ children: [new MathRun("a")], subScript: [new MathRun("n")] }),
        new MathRun(")"),
      ],
      denominator: [new MathRun("2")],
    }),
  ],
});

Physics

// Newton's second law
const newton2 = new OoxmlMath({
  children: [new MathRun("F = ma")],
});

// Kinetic energy
const kineticEnergy = new OoxmlMath({
  children: [
    new MathSubScript({ children: [new MathRun("E")], subScript: [new MathRun("k")] }),
    new MathRun(" = "),
    new MathFraction({
      numerator: [new MathRun("1")],
      denominator: [new MathRun("2")],
    }),
    new MathRun("m"),
    new MathSuperScript({ children: [new MathRun("v")], superScript: [new MathRun("2")] }),
  ],
});

Complexity Fallback Strategy

When formulas are too complex (nesting >3 levels) for docx-js Math, fall back to matplotlib PNG rendering:

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

def latex_to_png(latex_str: str, output_path: str, fontsize: int = 14, dpi: int = 200):
    """Render LaTeX formula as PNG image"""
    fig, ax = plt.subplots(figsize=(0.1, 0.1))
    ax.axis("off")
    text = ax.text(0, 0.5, f"${latex_str}$", fontsize=fontsize,
                   transform=ax.transAxes, verticalalignment="center")

    fig.canvas.draw()
    bbox = text.get_window_extent(fig.canvas.get_renderer())
    fig.set_size_inches(bbox.width / dpi + 0.2, bbox.height / dpi + 0.2)

    plt.savefig(output_path, dpi=dpi, bbox_inches="tight",
                pad_inches=0.05, transparent=True)
    plt.close()
    return output_path

Then embed the PNG in the document:

const formulaImg = fs.readFileSync("formula.png");
new Paragraph({
  alignment: AlignmentType.CENTER,
  children: [new ImageRun({
    data: formulaImg,
    transformation: { width: 300, height: 40 }, // adjust based on actual size
    type: "png",
  })],
})

Fallback rules:

  • Nested fractions >2 levels → fallback
  • Matrices/determinants → fallback
  • Complex integrals (multiple integrals + limits + integrand) → fallback
  • Piecewise functions → fallback
  • All other cases → prefer docx-js Math