Structure translation, not just text extraction

Lesson 2's plain text file didn't really test MarkItDown, there was no structure to preserve or lose. Office formats are different: a Word doc has headings and paragraphs, a slide deck has slides and bullets, a spreadsheet has rows and columns. This lesson converts one of each and looks at exactly how that structure maps to Markdown.

Source formatStructure in the sourceStructure in the Markdown output
.docx (Word)Paragraphs, and paragraphs styled as "Heading 1/2/..."Plain text lines; only paragraphs using an actual heading style become # headings
.pptx (PowerPoint)Slides, each with a title and bullet points<!-- Slide number: N --> marker per slide, slide title as a heading, bullets as a list
.xlsx (Excel)Sheets, each a grid of rows/columnsA Markdown pipe table per sheet, header row becomes the table header

A gotcha worth knowing: heading styles vs. bold text

fixtures/remote_work_memo.docx has section labels like "Summary" and "What Is Covered" that look like headings when you read the memo. But they were written as plain bold text, not with Word's built-in "Heading 1" paragraph style. MarkItDown's docx converter maps Word's style, not its visual appearance, to Markdown headings. Bold text that looks like a heading stays a plain paragraph. If you need reliable heading structure out of a docx conversion, the source document needs to actually use Word's heading styles, formatting alone isn't enough.

The code, piece by piece

def show(md: MarkItDown, filename: str, note: str) -> None:
result = md.convert(FIXTURES_DIR / filename)
print(f"=== {filename} ===")
...

Same .convert() call as Lesson 2, three times, once per format. The call itself doesn't change shape at all between formats, MarkItDown handles the format-specific logic internally based on what it detects.

Checkpoint

  • docx: paragraphs become text lines; only Word's built-in heading styles, not bold formatting, become Markdown # headings.
  • pptx: each slide gets an HTML-comment marker, its title becomes a heading, true bulleted-list placeholders become Markdown lists.
  • xlsx: each sheet becomes a Markdown pipe table, sheet name as a heading above it.
  • General rule: MarkItDown follows the source document's actual structural metadata, not its visual appearance, worth checking your real documents if the converted structure looks off.

If anything here still feels unclear, ask before moving to Lesson 4.