DOCX math: a delimiter with several arguments keeps only the last one

オープン 初心者向け
#2,573 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@drakeo338 がすでに取り組んでいます。

2026年10月1日 から。

  • #2574 @drakeo338 による — オープン
  • #2636 @iosayin による — マージされずにクローズ
  • #2654 @iosayin による — オープン
  • #2665 @dajiaohuang による — オープン
  • #2757 @OUAO-FRANK による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
86/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
python
領域
tooling

調査の方向性

packages/markitdown/src/markitdown/converter_utils/docx/math/omml.py から始め、oMath2Latex.do_d、Pr、process_children_dict()、process_children_list() を読みます。Issue の XML 例を再実行し、すべての delimiter 引数が順序どおりに保持されること、および sepChr が明示的な場合、省略された場合、値がない場合に期待される区切り文字が生成されることを確認します。

索引モデルが issue の本文から書いたものです。

説明

When a Word equation contains a delimiter (<m:d>) with more than one argument, MarkItDown keeps only the last argument and drops the rest without any warning. The separator character (<m:sepChr>) is never read either.

Word writes this structure for the bracket templates "with separators" (Insert > Equation > Bracket), for example (a|b), {x|x>0} and bra-ket notation.

Repro

from xml.etree import ElementTree as ET
from markitdown.converter_utils.docx.math.omml import OMML_NS, oMath2Latex

M = f'xmlns:m="{OMML_NS[1:-1]}"'

def latex(xml):
    return oMath2Latex(ET.fromstring(f"<m:oMath {M}>{xml}</m:oMath>")).latex

r = lambda t: f"<m:r><m:t>{t}</m:t></m:r>"

# Explicit separator
print(latex(r("f") + '<m:d><m:dPr><m:sepChr m:val=","/></m:dPr>'
            f"<m:e>{r('x')}</m:e><m:e>{r('y')}</m:e></m:d>"))
# -> f\left(y\right)

# Set-builder braces, default separator (no sepChr)
print(latex('<m:d><m:dPr><m:begChr m:val="{"/><m:endChr m:val="}"/></m:dPr>'
            f"<m:e>{r('x')}</m:e><m:e>{r('x>0')}</m:e></m:d>"))
# -> \left\{x>0\right\}

End to end, adding the first equation to a copy of tests/test_files/equations.docx makes MarkItDown().convert() emit $$f\left(y\right)$$.

Expected vs actual

Input Expected Actual
f + <m:d> with sepChr=",", args x, y f\left(x,y\right) f\left(y\right)
<m:d> braces, no sepChr, args x, x>0 \left\{x|x>0\right\} \left\{x>0\right\}
<m:d> with sepChr=";", args a, b, c \left(a;b;c\right) \left(c\right)

In the OMML schema (ECMA-376 / ISO/IEC 29500-1, CT_D), <m:e> has maxOccurs="unbounded". The sepChr element "specifies the character that separates base arguments e in the delimiter object d". When the element is omitted, the separator is a vertical bar (U+2502). When it is present without m:val, there is no separator. See the Open XML SDK SeparatorChar reference, which reproduces the spec text. Dropping arguments silently loses document content.

Cause

In packages/markitdown/src/markitdown/converter_utils/docx/math/omml.py, oMath2Latex.do_d reads its children with process_children_dict(). That function returns a dict keyed by tag name, so each <m:e> overwrites the previous one and c_dict["e"] holds only the last argument. Separately, Pr.__val_tags (and Pr.tag2meth) do not include sepChr, so pr.sepChr is always None.

Suggested fix

In do_d, collect every <m:e> in order with process_children_list(elm, include=("e",)). Have Pr read sepChr, with an empty value when m:val is missing. Then join the arguments with the separator, falling back to | when sepChr is absent. A single-argument delimiter gives the same output as before.

Environment

  • markitdown main at 1f9530a (0.1.8)
  • Python 3.13, macOS

AI assistance: drafted with an AI coding assistant (Claude). The reproduction above was run locally against the current default branch.

主要言語
Python
スター
194k
フォーク
14.5k
平均マージ
1時間 43分
マージ済み PR(30日)
8

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートなし
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/markitdown のほかの issue

microsoft/markitdown の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。