Rewritten from Python to Rust. Same input, same output shape, same prices.
- Default memory 4096 MB → 1024 MB. The Actor-start fee is charged once up
to 1 GB and then once per extra GB, so every run used to carry four start fees
before doing any work. It now carries one. Measured peak memory is 99 MB on
the heaviest case tried: a 9-page PDF with OCR forced on every page.
- A 15-page paper is parsed in 0.26 s (previously several seconds), which
also means far more runs finish inside the five seconds of compute Apify
covers for free.
- Lower memory means more of your runs fit inside your account's limit at once:
16 in parallel at 1 GB, against 4 at 4 GB.
- Two-column pages are read one column at a time. Columns usually share
their baselines, so the lines are now cut at the gutter rather than reordered
whole — a two-column paper no longer comes out as alternating half-sentences.
A table is explicitly not treated as two columns.
- Heading levels are decided across the whole document, not per page, so a
section heading on page 12 nests under the title on page 1 in
heading_path.
- Word spacing fixed on LaTeX-generated PDFs. Those files often contain no
space characters at all, positioning each word instead; text could previously
come out as
basedsolelyonattention.
- Sideways text no longer interrupts the reading order. Margin stamps (the
arXiv identifier, for instance) are kept, but appended after the page's text
instead of scattered one character at a time between its paragraphs.
- Tracked deletions in Word documents no longer appear in the output.
- Spreadsheet formula cells with no cached result are reported instead of
silently reading as empty.
- A hung OCR page is now killed after 60 seconds and the run continues.
- PDF parsing is serialised: the underlying engine is not safe to call from
several threads at once, and doing so could crash a run outright.
The PDF engine is now PDFium (BSD-3-Clause) instead of PyMuPDF (AGPL-3.0). No
dependency in the tree is copyleft. See LICENSING.md.