Convert OMML equations in .docx files to MathType OLE objects
Project description
omml-converter
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:AlternateContentfallback, 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
- OMML → MathML (
omml_to_mathml.py) — parse Office math into standard MathML. - MathML → MTEF (
mathml_to_mtef.py) — encode MathType 5.0 equation records. - MTEF → Equation Native stream (
mtef.py) — wrap in the MTEF stream header. - 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.DSMT6OLE 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc063748dffa5f8b231d5ebcee61f81a0c13bb96f1b85c001549cb87341915fd
|
|
| MD5 |
d56b5641c3ee4d640b09e78e8b8ac66d
|
|
| BLAKE2b-256 |
5849427e07ac0ade43ebff6264a2e42d3d6482d38f12d08b02758749dffcfa53
|
Provenance
The following attestation bundles were made for omml_converter-0.1.0.tar.gz:
Publisher:
release.yml on bohdanbodnarenko/omml-converter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omml_converter-0.1.0.tar.gz -
Subject digest:
dc063748dffa5f8b231d5ebcee61f81a0c13bb96f1b85c001549cb87341915fd - Sigstore transparency entry: 1693758812
- Sigstore integration time:
-
Permalink:
bohdanbodnarenko/omml-converter@ed3fb9d9dcae17deaceee3756120d51d2d0f360c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/bohdanbodnarenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ed3fb9d9dcae17deaceee3756120d51d2d0f360c -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eab3834c6eaa6ab562f23c9a5d5bf951e3eb55c3246b25371e115ef8cf193265
|
|
| MD5 |
a4377c995dbc03200ed6d47bce244e5f
|
|
| BLAKE2b-256 |
38605af2f4a9ff79363bd33a11b516cd970325b5b0338162dd4d986514c0711b
|
Provenance
The following attestation bundles were made for omml_converter-0.1.0-py3-none-any.whl:
Publisher:
release.yml on bohdanbodnarenko/omml-converter
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omml_converter-0.1.0-py3-none-any.whl -
Subject digest:
eab3834c6eaa6ab562f23c9a5d5bf951e3eb55c3246b25371e115ef8cf193265 - Sigstore transparency entry: 1693759022
- Sigstore integration time:
-
Permalink:
bohdanbodnarenko/omml-converter@ed3fb9d9dcae17deaceee3756120d51d2d0f360c -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/bohdanbodnarenko
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ed3fb9d9dcae17deaceee3756120d51d2d0f360c -
Trigger Event:
push
-
Statement type: