Environment
- pymupdf4llm 1.28.0, PyMuPDF 1.28.0, pymupdf-layout 1.28.0
- Python 3.11, Linux container on arm64
- Also checked against the 1.28.2 wheels: same behaviour
Summary
In layout mode, blocks classified as formula lose their text entirely in the output. Blocks classified as picture keep their text, but formula blocks do not, even with force_text=True (the default). When write_images and embed_images are both False (the defaults), no image is produced either, so the block contributes nothing at all.
Combined with a classification issue, this silently removed 50 paragraphs of body text from one of our documents.
What we observe
Our documents are Korean legal texts (statutes and insurance policy terms). The layout analyzer classifies the “supplementary provisions” sections as formula.
import pymupdf, pymupdf4llm
doc = pymupdf.open("statute.pdf")
page = doc[58]
page.get_layout(return_raw=True)
for b in page.layout_information:
if b["class_name"] == "formula":
print(repr(page.get_textbox(pymupdf.Rect(b["group_bbox"])).strip()))
Output:
'부 칙 <2010. 5. 7.>'
'제1조(시행일) 이 규정은 2010년 5월 7일부터 시행한다. 부 칙 <2015. 7. 16.>'
'제1조(시행일) 이 규정은 세종특별자치시가 조합에 가입한 날부터 효력을 발생한다. ...'
'제1조(시행일) 이 규정은 조합회의 의결이 있는 날부터 시행한다.'
This is ordinary body text. It states the effective dates of the regulation. None of it appears in the result of pymupdf4llm.to_markdown(doc).
Where it happens
In pymupdf4llm/helpers/document_layout.py, the markdown emitter (1.28.0 around line 814, 1.28.2 around line 1007):
if btype in ("picture", "formula"):
... # write or embed the image
# output text in image if requested
if box.textlines:
if btype == "picture": # formula is not included here
md_string += picture_text_to_md(...)
string_lengths.append(len(md_string))
continue
box.textlines is populated for formula blocks as well, but it is only emitted fo path has the same shape (1.28.2 around line 1138).
Since we do not write or embed images, the branch above appends only "\n\n" and tho warning or log entry.
Impact
In a 179 page document with 138 text pages, 50 paragraphs were missing from the marked because we compare the output against the raw text layer. In legal and insurancedocuments, the affected sections carry effective dates and transitional rules, so losing them is not acceptable for us.
For comparison, running the same document in legacy mode (use_layout(False)) does not lose these paragraphs.
Questions
- Is it intentional that
formulablocks do not emit their text whilepictureblocks do? If so, what is the reasoning, given thatforce_textdefaults toTrue? - Is there any option to have the text of
formulablocks included in the output? - Is it known that this kind of layout, a short heading line followed by one or two short provisions, tends to be classified as
formula? We see it consistently across several Korean statute documents.
We are happy to provide a small sample PDF that reproduces this if that helps.