Skip to main content

Convert OMML equations in .docx files to MathType OLE objects

Project description

omml-converter

CI PyPI Python versions License: MIT

Convert the math equations in a Microsoft Word .docx from OMML (Office Math Markup Language, Word's native equation format) into embedded MathType OLE objects (Equation.DSMT6) — without Word, MathType, or any Microsoft software installed. Pure Python.

The original OMML is preserved as a fallback, so every equation stays visible in ordinary Word while MathType-aware tooling can pick up the embedded objects.

Why

Some publishers, journal submission systems, and downstream tools expect Word documents whose equations are MathType objects rather than native Office math. Producing those normally requires a Windows machine with MathType installed. omml-converter does the conversion offline and cross-platform.

Features

  • Pure Python, no Word/MathType/COM dependency — runs anywhere.
  • Converts a wide range of OMML constructs (see below).
  • Keeps the original OMML as an mc:AlternateContent fallback, so equations never disappear in standard Word.
  • Writes valid OLE Compound File Binary (CFB v3) streams and MTEF 5.0 content.
  • Per-equation error isolation: one bad equation never aborts the whole file.

Installation

pip install omml-converter

Or run it without installing, using pipx or uv:

pipx install omml-converter
# or
uvx omml-converter input.docx

Requires Python 3.12+.

Usage

omml-converter input.docx

Writes input_mathtype.docx next to the input. Choose the output path with -o:

omml-converter input.docx -o converted.docx
omml-converter input.docx --verbose      # show each equation as it converts
omml-converter input.docx --quiet        # only print errors
omml-converter --version

Options

Option Description
input Input .docx file (required).
-o, --output Output path (default: <input>_mathtype.docx).
-v, --verbose Log every equation as it is converted.
-q, --quiet Suppress progress; print errors only.
--version Print the version and exit.
-h, --help Show help and exit.

Exit codes

Code Meaning
0 Success — all equations converted (or none present).
1 Bad input (missing / non-.docx / unreadable) or one or more equations failed.
2 Invalid command-line arguments (from argparse).

The output .docx is always written when the input is readable; equations that fail to convert are left as their original OMML.

Use as a library

from omml_converter import convert

summary = convert("input.docx", "output.docx")
print(summary.found, summary.converted, summary.skipped, summary.errors)

How it works

Each m:oMath equation is taken through a four-stage pipeline and embedded back into the document:

.docx ──▶ OMML  ──▶  MathML  ──▶  MTEF 5.0  ──▶  OLE (CFB)  ──▶ .docx
        omml_to_   mathml_to_      mtef.py        ole.py      (re-zipped)
        mathml.py  mtef.py
  1. OMML → MathML (omml_to_mathml.py) — parse Office math into standard MathML.
  2. MathML → MTEF (mathml_to_mtef.py) — encode MathType 5.0 equation records.
  3. MTEF → Equation Native stream (mtef.py) — wrap in the MTEF stream header.
  4. Equation Native → OLE (ole.py) — build a minimal OLE Compound File.

The OLE object is inserted via mc:AlternateContent: a Choice requiring a namespace Word doesn't recognise (so Word renders the OMML Fallback), while MathType-aware tooling locates the embedded Equation.DSMT6 object.

Supported constructs

Fractions · radicals (square and nth root) · subscripts, superscripts and sub-superscripts · n-ary operators (sum, product, integral) · functions · delimiters · accents and bars · matrices and equation arrays · phantoms and boxes · Greek letters and common operators.

Limitations

  • Targets MathType 5.0 / Equation.DSMT6 OLE objects specifically.
  • Visual rendering of the OLE object requires a MathType-aware consumer; in plain Word the OMML fallback is what you see.
  • Highly unusual or malformed OMML may be skipped (reported on stderr) rather than producing an incorrect object.

Development

git clone https://github.com/bohdanbodnarenko/omml-converter.git
cd omml-converter
uv sync                       # create the venv and install dev deps
uv run pytest                 # run the test suite (with coverage)
uv run ruff check src tests   # lint
uv run ruff format src tests  # format
uv run mypy                   # type-check
uv run pre-commit install     # enable git hooks (optional)

See CONTRIBUTING.md for details.

Releasing

Tagging vX.Y.Z triggers .github/workflows/release.yml, which builds and publishes to PyPI via trusted publishing. This requires a one-time PyPI publisher configuration for the repository.

License

MIT © Bohdan Bodnarenko

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

omml_converter-0.1.0.tar.gz (34.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

omml_converter-0.1.0-py3-none-any.whl (21.1 kB view details)

Uploaded Python 3

File details

Details for the file omml_converter-0.1.0.tar.gz.

File metadata

  • Download URL: omml_converter-0.1.0.tar.gz
  • Upload date:
  • Size: 34.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for omml_converter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dc063748dffa5f8b231d5ebcee61f81a0c13bb96f1b85c001549cb87341915fd
MD5 d56b5641c3ee4d640b09e78e8b8ac66d
BLAKE2b-256 5849427e07ac0ade43ebff6264a2e42d3d6482d38f12d08b02758749dffcfa53

See more details on using hashes here.

Provenance

The following attestation bundles were made for omml_converter-0.1.0.tar.gz:

Publisher: release.yml on bohdanbodnarenko/omml-converter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file omml_converter-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: omml_converter-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for omml_converter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 eab3834c6eaa6ab562f23c9a5d5bf951e3eb55c3246b25371e115ef8cf193265
MD5 a4377c995dbc03200ed6d47bce244e5f
BLAKE2b-256 38605af2f4a9ff79363bd33a11b516cd970325b5b0338162dd4d986514c0711b

See more details on using hashes here.

Provenance

The following attestation bundles were made for omml_converter-0.1.0-py3-none-any.whl:

Publisher: release.yml on bohdanbodnarenko/omml-converter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page