You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Expose OMML equation content (m:oMath) - equations are silently dropped from Paragraph.text #95
Word stores equations as OMML — m:oMath inline in a paragraph, or m:oMathPara as a block-level sibling of w:p. Neither is reachable from the API, and the m namespace (http://schemas.openxmlformats.org/officeDocument/2006/math) is not even in oxml/ns.py's nsmap.
This is silent data loss rather than a missing convenience. Equation text lives in m:t inside m:r, not in w:t inside w:r, so:
Paragraph.text drops every equation in the paragraph with no indication one was there
Paragraph.runs and iter_inner_content() skip them
replace_text() and isolate_run() offsets are computed over text that does not match what the document shows
A document like The result is <equation> for all n reads back as The result is for all n.
(Font.oMath already exists but is unrelated — that is w:rPr/w:oMath, the flag marking a run as part of an equation, not the equation content.)
Where the prior art is
VanOord/vo-python-docx, branches equation_support and update_package, adds docx/oxml/math.py with CT_OMath and CT_OMathPara, docx/text/math.py with an Equation proxy exposing .raw_xml, and Paragraph.equations returning [Equation(eq, self) for eq in self._p.oMathPara_lst].
That is the minimum viable version — find the equations, hand back their XML. It is a reasonable first target; a full OMML object model is a much larger job and probably not worth it.
Shape
m in nsmap, and the schema is already vendored at ref/xsd/shared-math.xsd
CT_OMath / CT_OMathPara registered in oxml/__init__.py
Math proxy in a new docx/math.py with at least .xml and .text (the concatenation of the m:t descendants)
Paragraph.math / Document.math, and inclusion in Paragraph.iter_inner_content()
Decide explicitly
Whether Paragraph.text should include equation text. Including it is more truthful about the document's content and keeps replace_text() offsets honest, but it is a behaviour change for anyone parsing documents with equations. Given 2.0.0 already redefined Paragraph.text for tracked changes and w:fldSimple, doing it here in the same release is the cheaper moment. Whatever is chosen needs a HISTORY.rst entry.
Landed in #139. Paragraph.math, BlockItemContainer.math and Document.math, each Math offering .text, .xml and .is_display.
On the explicit decision the issue asked for: equation text is not included in Paragraph.text. Including it would describe the document more truthfully, but replace_text() and isolate_range() measure offsets against Paragraph.text and can only cut at run boundaries; equation text lives in m:t inside m:r and is unreachable to them, so including it would silently mis-target every replacement after the first equation in a paragraph. A wrong edit is worse than a missing character. In HISTORY.rst.
Activity
toxicphreAK commentedon Aug 5, 2026
Landed in #139.
Paragraph.math,BlockItemContainer.mathandDocument.math, eachMathoffering.text,.xmland.is_display.On the explicit decision the issue asked for: equation text is not included in
Paragraph.text. Including it would describe the document more truthfully, butreplace_text()andisolate_range()measure offsets againstParagraph.textand can only cut at run boundaries; equation text lives inm:tinsidem:rand is unreachable to them, so including it would silently mis-target every replacement after the first equation in a paragraph. A wrong edit is worse than a missing character. In HISTORY.rst.