Doclingdocling 2.127.0 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
26 small wins to finish your pathNext lesson

Converting a PDF

Twelve lessons in, the call does not change. What changes is what happens behind it: a PDF goes through a layout model rather than a parser, and the first run downloads it.

The file is returns.pdf from lesson 1, the one that turned out to be drawing instructions. Two pages of the shop's returns policy, made by make_returns_pdf.py, which writes the whole thing with string formatting and no PDF library at all.

Example
from docling.document_converter import DocumentConverter

document = DocumentConverter().convert("returns.pdf").document
print(document.export_to_markdown())

Four headings and four paragraphs, in order, from a file where none of that was written down. Nothing in the PDF says Returns is a heading; it says draw those characters at that position in a twenty point bold font. A model looked at the page and decided.

What the first run downloads

That call took several seconds longer than any call so far, and on a machine that has never converted a PDF it takes a minute or two. Docling fetches its layout model and its table model the first time they are needed and caches them under your home directory.

bash
docling-tools models download

Running that command first does the same download up front, which is what you want in a container image or on a machine that will be offline later. It is installed with Docling, not separately.

The same object as before

Example
for item, depth in document.iterate_items():
    print(depth, item.self_ref, item.label, "|", item.text[:30])

Labels, addresses and reading order, exactly as in lesson 4. Everything you learned about the document object applies here, which is the point of Docling having one document object.

Two things that are new

Example
print(document.num_pages(), "pages")
for number, page in sorted(document.pages.items()):
    print("page", number, int(page.size.width), "by", int(page.size.height))

A PDF has pages, so document.pages is filled in. The size is in points, seventy-two to the inch, so 612 by 792 is US Letter. The other new thing is that every piece now knows which page it came from, which is lesson 14.

Reuse the converter. Building a DocumentConverter is what loads the models. Making a new one inside a loop reloads them for every file and turns a two second job into a two minute one.
Try it yourself
  • Convert the PDF twice in one script and time both calls.
  • Delete ~/.cache/docling and convert again to see the download happen.
  • Run export_to_markdown(labels={DocItemLabel.SECTION_HEADER}) on it.

Slow is fine. Stopping is the only problem.