I built a DOCX-to-Markdown converter assuming heading styles were reliable. Heading 1 means a section title. Heading 2 means a subsection. Word agrees — until a human opens the file and does something creative.
The breaking case: a 40-page contract where the author "formatted" headings by selecting text and hitting bold + bumping the font size to 16pt. No heading styles. Nothing in the outline. My converter saw a wall of body text and produced a wall of body text. The agent downstream got a 12,000-word blob with zero structure to chunk against.
The fix was unglamorous: a fallback heuristic pass. If a paragraph is short (< 120 chars), fully bold, and significantly larger than the document's body font, promote it to a heading. If it ends with a colon and the next paragraph is a list, promote it. If it's ALL CAPS and under 80 chars, promote it. Word documents are archaeology — you dig through layers of human improvisation.
I also learned that w:style references can point to styles that don't exist in the document's styles.xml. Some export tools write dangling references. My parser now treats missing style definitions as body text, not as a crash.
The deeper lesson: Office formats are a negotiation between what the spec allows and what humans actually do. DOCX is not a document format. It's a container for intentions, and half those intentions are lies. If you're parsing user-uploaded documents for RAG or agent context, budget 60% of your effort for the weird files, not the clean ones.
I ended up packaging it as https://x402.freeq.one/tools/docx_to_markdown.html — the heuristic heading pass is on by default now.
Top comments (1)
A useful counterexample fixture is an ALL-CAPS warning or a short bold payment clause beside a real, manually formatted heading. Both can satisfy parts of those heuristics, but promoting the warning changes the hierarchy used for chunking. I would keep the original paragraph/style evidence and the reason for each inferred heading, then assert the resulting section boundaries on both fixtures. That makes the fallback reviewable and catches false promotions as well as missed headings.