Skip to content

fix(docx): preserve underlined text - #2017

Merged
Adam Fourney (afourney) merged 8 commits into
microsoft:mainfrom
he-yufeng:fix/docx-preserve-underline
Sep 3, 2026
Merged

Adam Fourney (afourney) merged 8 commits into
microsoft:mainfrom
he-yufeng:fix/docx-preserve-underline

Conversation

@he-yufeng

Copy link
Copy Markdown
Contributor

Summary

Fixes #35.

DOCX underlined runs were lost because Mammoth only emits underline markup when a style map for u is present, and the HTML-to-Markdown pass did not preserve <u> tags. This adds the missing default style map entry for DOCX conversion and keeps underline markup in the Markdown output.

To verify

  • PYTHONPATH=packages/markitdown/src python -m pytest packages/markitdown/tests/test_module_misc.py -k docx -q
  • PYTHONPATH=packages/markitdown/src python -m pytest packages/markitdown/tests/test_module_misc.py::test_docx_underlined_text_is_preserved packages/markitdown/tests/test_module_misc.py::test_docx_comments -q
  • python -m py_compile packages/markitdown/src/markitdown/converters/_docx_converter.py packages/markitdown/src/markitdown/converters/_markdownify.py packages/markitdown/tests/test_module_misc.py
  • git diff --check

@he-yufeng

Copy link
Copy Markdown
Contributor Author

Local re-check after cleaning up my environment:

  • PYTHONPATH=packages/markitdown/src python -m pytest packages/markitdown/tests/test_module_misc.py -q -k "underline or docx" -> 3 passed, 12 deselected
  • PYTHONPATH=packages/markitdown/src python -m py_compile packages/markitdown/src/markitdown/converters/_docx_converter.py packages/markitdown/src/markitdown/converters/_markdownify.py packages/markitdown/tests/test_module_misc.py -> passed
  • git diff --check origin/main...HEAD -> passed

The explicit PYTHONPATH is intentional here: my global Python had an editable markitdown install pointing at another local clone, so the first local run did not exercise this branch.

@afourney

Copy link
Copy Markdown
Member

Copilot resolve the merge conflicts in this pull request

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The OCR DOCX converter still drops underlines when plugins are enabled.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Preserves DOCX underline formatting as HTML in Markdown output.

Changes:

  • Adds Mammoth’s default underline style mapping.
  • Preserves <u> tags during Markdown conversion.
  • Adds an end-to-end DOCX regression test.
File summaries
File Description
_docx_converter.py Adds underline style mapping.
_markdownify.py Retains underline HTML markup.
test_module_misc.py Tests underlined DOCX text.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/markitdown/src/markitdown/converters/_docx_converter.py Outdated
Comment thread packages/markitdown/tests/test_module_misc.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…ix/docx-preserve-underline

# Conflicts:
#	packages/markitdown/src/markitdown/converters/_markdownify.py
#	packages/markitdown/tests/test_module_misc.py
Extract the underline style-map default into a shared
with_underline_style_map() helper and use it in both of
DocxConverterWithOCR's mammoth paths, so underlines survive DOCX
conversion in plugin mode as well.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Mammoth composes style mappings as custom + embedded + built-in defaults,
first match wins, so appending "u => u" to the caller's map placed it ahead
of any map embedded in the document: an embedded "u => em" silently lost to
the default.

Compose caller + embedded + "u => u" explicitly and call mammoth with
include_embedded_style_map=False, in a convert_docx_to_html() helper shared
by DocxConverter and DocxConverterWithOCR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The OCR package imports a new core helper without updating its compatible markitdown dependency range.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread packages/markitdown-ocr/src/markitdown_ocr/_docx_converter_with_ocr.py Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The OCR converter references pre_process_stream before assignment, causing every conversion to fail.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread packages/markitdown-ocr/src/markitdown_ocr/_docx_converter_with_ocr.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation preserves underline markup across all DOCX paths while retaining documented style-map precedence.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Underline not preserved

3 participants