Structure, not a string
Lesson 2 called export_to_markdown() and stopped there, a string was enough for that lesson. But result.document is not a string, it's a DoclingDocument, a real object graph: separate collections for text items, tables, and pictures, each one a structured item with its own label, not a character range you'd have to re-parse out of Markdown. export_to_markdown() is one view onto that graph. This lesson looks at the graph itself.
The three collections
doc.texts # every paragraph, heading, list item, captiondoc.tables # every detected table, as structured cells, not textdoc.pictures # every detected figure or image regionEach collection holds items in the order docling's backend produced them, not necessarily reading order, that's what iterate_items() is for.
Reading order with iterate_items()
for item, level in doc.iterate_items(): ...This walks the whole document, texts, tables, and pictures together, in the order a person would actually read the page: title first, sections in sequence, a table where the table appears, not batched at the end. export_to_markdown() calls this same method internally, you're looking at exactly the traversal that produces the Markdown output, just before it gets serialized to a string.
Every text item has a .label (section_header, text, and more labels you'll see in later lessons like list_item and caption) telling you what kind of text it is, this is the structural information a plain PDF text extractor throws away.
Checkpoint
DoclingDocument: a structured object graph, not a string,doc.texts,doc.tables,doc.pictureshold real typed items.iterate_items(): walks the whole document in reading order, the same traversalexport_to_markdown()uses internally..label: every text item knows what kind of text it is (section_header,text, and more), structure a plain PDF text extractor would have discarded.
If anything here still feels unclear, ask before moving to Lesson 4.