Skip to main content
TrimItDown

Documents → LLM-ready Markdown. PDFs checked page by page, scans handed to review.

Read this in: English (this file) · русский

PyPI License: MIT

trimitdown turns PDF, Word (docx), PowerPoint (pptx), Excel (xlsx/xls) and Outlook (.msg) files into Markdown meant to be pasted into an LLM or read by an agent. The objective is the fewest tokens with the information preserved: a real table becomes a Markdown table, a page whose text cannot be trusted says so instead of passing as text.

It is a command-line tool and a Python library, and it works offline. Since 0.2.0 this package is the whole product; see Earlier releases for the desktop app and the Docker server.

Install

Requires Python 3.10+.

uv tool install trimitdown     # or: pipx install trimitdown
uvx trimitdown convert report.pdf   # once, without installing

A plain pip install into the system Python is refused on many distributions and on Homebrew (PEP 668); the commands above put the package in an isolated environment. Inside your own virtual environment, pip install trimitdown is fine.

PDF needs nothing more. Word, PowerPoint, Excel and Outlook need the office extra:

uv tool install "trimitdown[office]"     # or: pip install "trimitdown[office]"

The extra does not install on Python 3.15 yet: it needs onnxruntime, which has no 3.15 wheels so far. PDF conversion works there. Without the extra, converting an office file fails with a message naming the extra.

Convert

trimitdown convert report.pdf -o report.md
trimitdown convert - --type pdf < report.pdf     # from a stream

Without -o, Markdown goes to standard output.

from trimitdown.convert import convert_path

result = convert_path("report.pdf")
result.text            # the Markdown
result.pages           # PDFs: how each page was routed, and why
result.tokens_after    # cl100k tokens of the Markdown

Non-PDF formats go through Microsoft's MarkItDown.

How PDFs are handled

PDFs go through pdf-inspector, which gave the best structure in our measurements (headings, tables with and without rules) and the fewest tokens. It also loses text without saying so — whole pages come back empty while their text layer is intact, and on some pages Cyrillic comes back as Latin with no warning. So every page is checked against an independent decoder (pypdf) and takes one of five paths:

Path When What the page contributes
accept pdf-inspector read the page its Markdown, unchanged
substitute pdf-inspector lost text the layer still has the text layer as plain text
scan no text layer, or an OCR layer under a page image a marker, or the OCR layer with a note that it is unverified
corrupt a text layer every decoder reads as garbage a marker
blank no text layer and nothing on the page nothing

The loss check is counted per script (Cyrillic, Latin, Greek, CJK…), so a page where one alphabet silently replaced another is caught even though the number of letters did not change.

Markers look like this, one line each:

[trimitdown: page 12 has no usable text layer (scan)]
[trimitdown: page 14: OCR layer, not verified]

When any page did not come from pdf-inspector, convert prints one line to standard error, for example 7 pages: 1 accept, 2 substitute, 2 scan, 1 corrupt, 1 blank; 3 need review. A clean document converts silently.

Review: scans and unreadable pages

trimitdown does not do OCR itself and does not review anything. It prepares the pages that need a look for an agent (or a person) who does:

trimitdown convert scan.pdf --review-dir out/

writes

out/document.md the converted document, with a <!-- page N --> anchor before each page
out/manifest.json every page: its path and reasons, image, candidate text, OCR status, metrics
out/REVIEW.md the review procedure: OCR first, then compare with the image and correct only the differences
out/pages/pNNNN.png an image of each page to review (the source scan when it is the whole page, otherwise a 300 dpi render)
out/candidates/pNNNN.txt the text to start from: the PDF's own OCR layer, or fresh Tesseract output; empty if there is none
out/reviewed/ where the reviewer writes

Tesseract is optional and external. It is looked for in --tesseract, TRIMITDOWN_TESSERACT, PATH, then the usual install locations; the defaults are the measured ones (-l rus --psm 3, orientation from --psm 0), changed with --ocr-lang and --tessdata-dir. Without Tesseract, or without the language data, pages still go to review with an empty candidate, and the manifest and standard error say why.

Other options: --ocr-fresh (OCR scans that already carry an OCR layer), --no-ocr, --review-substitute (send substitute pages too), --review-markers ru|en (the marks the procedure asks for: [неразборчиво], === стр. N === by default, or [illegible], === page N ===).

When the review is done:

trimitdown assemble out/ -o report.md

puts each reviewed page in place of its marker. It reads reviewed/doc.txt with one === стр. N === (or === page N ===) header per page, or one reviewed/pNNNN.txt per page, and refuses a page reviewed twice, a page that does not exist or a page that was not sent for review.

Readable text in a text layer does not prove its digits right. For the pages that were not sent, trimitdown render report.pdf --pages 5,7 -o img/ writes page images to check them against.

From Python: trimitdown.review.prepare_review, assemble and render_pages.

Limitations

  • No built-in OCR, and no review performed by the program: scans need Tesseract and a reviewer.
  • A loss of Latin letters alone is not checked. On the 200-document benchmark the Latin check replaced good structured Markdown (headings) with plain text more often than it recovered text, so it ships switched off (GATE_LATIN in text_metrics.py). Cyrillic replaced by Latin is still caught: that is a loss of Cyrillic.
  • Text under an image (an OCR layer of a different shape, or text an overlay was meant to hide) is accepted as text; the review manifest records how much of each page is under images.
  • The garbage detector behind corrupt raised no false alarm on 2,795 real pages, but how well it catches a genuinely broken text layer has not been measured: no such page was in the test corpora.
  • Slower than pdf-inspector alone, because every page is also decoded by pypdf to catch a silent loss. On 180 pages of Russian tax forms the route took 62 s against 5.6 s; on the 200-document benchmark, 48 ms per document against 7. pdfium as the second decoder makes the same decisions on every real page measured and is about five times faster, but it shares pdf-inspector's blind spot on text carried by ActualText, so it is not used.
  • Password-protected PDFs are refused.

Earlier releases

Up to 0.1.2 TrimItDown also shipped a desktop app for Windows and macOS, a self-hosted Docker server with an iPhone PWA, and a Scoop manifest. They are no longer released. Their last builds are attached to v0.1.2, the Scoop bucket in this repository stays pointed at it, and the code remains in the tree — see DEVELOPMENT.md. The PDF engine they use, trimitdown-pdf, is described in docs/pdf-engine.md; this package no longer depends on it.

Repository layout

Contributing

Bug reports and PRs are welcome — see CONTRIBUTING.md and DEVELOPMENT.md.

License and credits

Code is MIT. PDFs are read with pdf-inspector (MIT), pypdf (BSD) and pypdfium2 (Apache-2.0 / BSD, with PDFium); other formats with MarkItDown (Microsoft, MIT). See THIRD_PARTY_NOTICES.md.

Metadata

Release files for trimitdown 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for trimitdown 0.2.0
File Size Uploaded Provenance
trimitdown-0.2.0.tar.gz 815.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for trimitdown 0.2.0
File Interpreter ABI Platform
trimitdown-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / trimitdown-0.2.0.tar.gz

Download URL trimitdown-0.2.0.tar.gz
Size 815.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a80093085ed2be51451c5c2b2ba8bd9f3f534ecdefac50c72424594b39b4fa1f
BLAKE2b-256 checksum
How to use checksums
40f26e7e371f0bd19ec3a735d861683bf79c2667527d7e1359a8228fb3e57951
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Release files / trimitdown-0.2.0-py3-none-any.whl

Download URL trimitdown-0.2.0-py3-none-any.whl
Size 813.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
12eb9d7dee571733533ef7245bfe2927445c4e1f855fab29f96c6b89b75cd66d
BLAKE2b-256 checksum
How to use checksums
d80a16447a95a1642afc78bc44aa8fe75d47159ceac90c5a59b3e8311921ae95
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

Security for trimitdown 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for trimitdown-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 20, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page