pdfdown 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. pdfdown-0.1.0/.gitignore +11 -0
  2. pdfdown-0.1.0/LICENSE +21 -0
  3. pdfdown-0.1.0/PKG-INFO +373 -0
  4. pdfdown-0.1.0/README.md +342 -0
  5. pdfdown-0.1.0/corpus/office-report.pdf +0 -0
  6. pdfdown-0.1.0/corpus/office-slides.pdf +0 -0
  7. pdfdown-0.1.0/packaging/homebrew/pdfdown.rb +28 -0
  8. pdfdown-0.1.0/packaging/npm/README.md +13 -0
  9. pdfdown-0.1.0/packaging/npm/bin/pdfdown.js +88 -0
  10. pdfdown-0.1.0/packaging/npm/package.json +27 -0
  11. pdfdown-0.1.0/pyproject.toml +53 -0
  12. pdfdown-0.1.0/scripts/equation_sheet.py +58 -0
  13. pdfdown-0.1.0/scripts/eval_equations.py +28 -0
  14. pdfdown-0.1.0/scripts/fresh_machine_check.sh +14 -0
  15. pdfdown-0.1.0/scripts/make_office_samples.py +77 -0
  16. pdfdown-0.1.0/scripts/mddiff.py +6 -0
  17. pdfdown-0.1.0/scripts/release_check.sh +19 -0
  18. pdfdown-0.1.0/scripts/side_by_side.py +89 -0
  19. pdfdown-0.1.0/scripts/snapshot.py +22 -0
  20. pdfdown-0.1.0/scripts/try.py +13 -0
  21. pdfdown-0.1.0/scripts/warm_cache.py +8 -0
  22. pdfdown-0.1.0/scripts/worddiff.py +13 -0
  23. pdfdown-0.1.0/src/pdfdown/__init__.py +1 -0
  24. pdfdown-0.1.0/src/pdfdown/cleanup/__init__.py +36 -0
  25. pdfdown-0.1.0/src/pdfdown/cleanup/captions.py +126 -0
  26. pdfdown-0.1.0/src/pdfdown/cleanup/figures.py +62 -0
  27. pdfdown-0.1.0/src/pdfdown/cleanup/furniture.py +49 -0
  28. pdfdown-0.1.0/src/pdfdown/cleanup/notes.py +25 -0
  29. pdfdown-0.1.0/src/pdfdown/cleanup/order.py +119 -0
  30. pdfdown-0.1.0/src/pdfdown/cleanup/retext.py +34 -0
  31. pdfdown-0.1.0/src/pdfdown/cleanup/stitch.py +63 -0
  32. pdfdown-0.1.0/src/pdfdown/cli.py +128 -0
  33. pdfdown-0.1.0/src/pdfdown/document.py +136 -0
  34. pdfdown-0.1.0/src/pdfdown/edits.py +88 -0
  35. pdfdown-0.1.0/src/pdfdown/engine.py +102 -0
  36. pdfdown-0.1.0/src/pdfdown/equations.py +335 -0
  37. pdfdown-0.1.0/src/pdfdown/export.py +182 -0
  38. pdfdown-0.1.0/src/pdfdown/locks.py +12 -0
  39. pdfdown-0.1.0/src/pdfdown/pdftext.py +336 -0
  40. pdfdown-0.1.0/src/pdfdown/pipeline.py +46 -0
  41. pdfdown-0.1.0/src/pdfdown/quality.py +65 -0
  42. pdfdown-0.1.0/src/pdfdown/tui/__init__.py +0 -0
  43. pdfdown-0.1.0/src/pdfdown/tui/app.py +576 -0
  44. pdfdown-0.1.0/src/pdfdown/tui/screens.py +184 -0
  45. pdfdown-0.1.0/tests/test_conversion.py +123 -0
  46. pdfdown-0.1.0/tests/test_tui.py +62 -0
  47. pdfdown-0.1.0/tests/test_units.py +134 -0
@@ -0,0 +1,11 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.egg-info/
4
+ dist/
5
+ out/
6
+ .pdfdown-cache/
7
+ corpus/*.pdf
8
+ !corpus/office-report.pdf
9
+ !corpus/office-slides.pdf
10
+ docs/recording/frames/
11
+ pdfdown-output/
pdfdown-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Md Rafsun Sheikh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pdfdown-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,373 @@
1
+ Metadata-Version: 2.5
2
+ Name: pdfdown
3
+ Version: 0.1.0
4
+ Summary: A terminal app that turns PDFs, especially research articles, into clean Markdown with tables, cropped figures and equations.
5
+ Project-URL: Homepage, https://github.com/rafsunsheikh/pdfdown
6
+ Project-URL: Issues, https://github.com/rafsunsheikh/pdfdown/issues
7
+ Author: Md Rafsun Sheikh
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: docling,latex,markdown,pdf,research,tui
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Scientific/Engineering
18
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
19
+ Requires-Python: <3.15,>=3.10
20
+ Requires-Dist: docling>=2.60
21
+ Requires-Dist: latex2mathml>=3.77
22
+ Requires-Dist: pillow>=10
23
+ Requires-Dist: pix2tex>=0.1.4
24
+ Requires-Dist: pypdfium2>=4.30
25
+ Requires-Dist: textual-image>=0.8
26
+ Requires-Dist: textual>=0.80
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
29
+ Requires-Dist: pytest>=8; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ <a id="readme-top"></a>
33
+
34
+ [![PyPI][pypi-shield]][pypi-url]
35
+ [![Python][python-shield]][pypi-url]
36
+ [![Issues][issues-shield]][issues-url]
37
+ [![License][license-shield]][license-url]
38
+
39
+ <br />
40
+ <div align="center">
41
+ <picture>
42
+ <source media="(prefers-color-scheme: dark)" srcset="docs/images/logo-dark.svg">
43
+ <img src="docs/images/logo-light.svg" alt="pdfdown" width="420">
44
+ </picture>
45
+ <p align="center">
46
+ A terminal app that turns PDFs, especially research articles, into clean Markdown:
47
+ one column of continuous text, rebuilt tables, cropped figures in the right places, and checked equations.
48
+ <br /><br />
49
+ <a href="#getting-started"><strong>Get started »</strong></a>
50
+ <br /><br />
51
+ <a href="#usage">Usage</a>
52
+ &middot;
53
+ <a href="#examples">Examples</a>
54
+ &middot;
55
+ <a href="#how-it-works">How it works</a>
56
+ &middot;
57
+ <a href="https://github.com/rafsunsheikh/pdfdown/issues">Report Bug</a>
58
+ &middot;
59
+ <a href="https://github.com/rafsunsheikh/pdfdown/issues">Request Feature</a>
60
+ </p>
61
+ </div>
62
+
63
+ <details>
64
+ <summary>Table of Contents</summary>
65
+ <ol>
66
+ <li><a href="#about-the-project">About The Project</a></li>
67
+ <li><a href="#getting-started">Getting Started</a>
68
+ <ul>
69
+ <li><a href="#prerequisites">Prerequisites</a></li>
70
+ <li><a href="#installation">Installation</a></li>
71
+ </ul>
72
+ </li>
73
+ <li><a href="#usage">Usage</a>
74
+ <ul>
75
+ <li><a href="#the-terminal-app">The terminal app</a></li>
76
+ <li><a href="#without-the-app">Without the app</a></li>
77
+ <li><a href="#what-you-get">What you get</a></li>
78
+ </ul>
79
+ </li>
80
+ <li><a href="#examples">Examples</a></li>
81
+ <li><a href="#how-it-works">How it works</a></li>
82
+ <li><a href="#similar-projects">Similar projects</a>
83
+ <ul>
84
+ <li><a href="#why-pdfdown">Why pdfdown</a></li>
85
+ <li><a href="#when-another-tool-is-the-better-choice">When another tool is the better choice</a></li>
86
+ </ul>
87
+ </li>
88
+ <li><a href="#limitations">Limitations</a></li>
89
+ <li><a href="#development">Development</a></li>
90
+ <li><a href="#license">License</a></li>
91
+ <li><a href="#contact">Contact</a></li>
92
+ </ol>
93
+ </details>
94
+
95
+ ## About The Project
96
+
97
+ ![pdfdown converting a physics paper: the Markdown, the raw source, a figure and its page, an equation rejected by the check with the reason, the LaTeX editor, and the report](docs/images/pdfdown-demo.gif)
98
+
99
+ <sub>Recorded in a terminal without image support, so previews are drawn with coloured blocks. In Ghostty, kitty, WezTerm or iTerm2 they are sharp. ([MP4 version](docs/images/pdfdown-demo.mp4))</sub>
100
+
101
+ Copying text out of a research paper usually gives you broken lines, words split by hyphens, two columns mixed together, page headers in the middle of sentences, and no figures. pdfdown gives you a Markdown file you can read, search, quote and edit:
102
+
103
+ * **Any PDF, research articles first.** Journal articles and preprints, office documents and slides exported to PDF.
104
+ * **Columns become one column.** Two-column and multi-column pages are read in the right order and written as a single column.
105
+ * **Continuous sentences.** Line breaks inside paragraphs are removed and hyphenated words are joined again, so paragraph breaks appear only where the paper has them. A paragraph cut off by a column, page or figure is stitched back together.
106
+ * **Tables are rebuilt** as Markdown tables, or as HTML tables when they have merged cells.
107
+ * **Figures are cropped** from the page as sharp images and placed exactly where they belong, each followed by its caption.
108
+ * **Equations you can trust.** Every equation goes in as a cropped image first. It is replaced by LaTeX only when the LaTeX has been checked against the PDF itself, letter by letter. Otherwise the exact image stays.
109
+ * **Superscripts and subscripts survive**, so citations read "prizes<sup>2–9</sup>" and variables read "t<sub>0</sub>".
110
+ * **Clutter is removed:** running headers and footers, page numbers, journal badges and axis labels that leaked into the text.
111
+ * **You stay in control.** In the terminal app you can switch any equation between LaTeX and image, fix its LaTeX with a live check, adjust any crop, or hide an element. Your changes are kept for the next run.
112
+ * **Private by design.** Everything runs on your own computer. Your PDFs are never uploaded anywhere, so unpublished or confidential papers are safe to convert.
113
+
114
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
115
+
116
+ ## Getting Started
117
+
118
+ ### Prerequisites
119
+
120
+ * macOS or Linux, and **Python 3.10 to 3.14** (or [uv][uv-url], which fetches the right Python by itself).
121
+ * About **2.5 GB of free disk space**: about 1.3 GB for the program and about 1.1 GB for the page-reading models, which are downloaded once on first use.
122
+ * For sharp image previews inside the app, a terminal that can show pictures, such as Ghostty, kitty, WezTerm or iTerm2. Other terminals show a coarse preview, and the files on disk are full quality either way.
123
+
124
+ ### Installation
125
+
126
+ Pick one:
127
+
128
+ ```bash
129
+ uv tool install pdfdown # recommended
130
+ pipx install pdfdown
131
+ pip install pdfdown # inside a Python 3.10 to 3.14 environment
132
+ npm install -g @rafsunsheikh/pdfdown # needs uv or Python 3.10 to 3.14
133
+ brew install rafsunsheikh/tap/pdfdown
134
+ ```
135
+
136
+ Check it:
137
+
138
+ ```bash
139
+ pdfdown --version
140
+ ```
141
+
142
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
143
+
144
+ ## Usage
145
+
146
+ ### The terminal app
147
+
148
+ ```bash
149
+ pdfdown # open the app and add PDFs with the a key
150
+ pdfdown paper.pdf # open it with a PDF queued
151
+ pdfdown papers/ # queue every PDF in a folder
152
+ ```
153
+
154
+ PDFs are converted in the background, one at a time. The first conversion of a long article takes about a minute; opening the same PDF again takes about a second.
155
+
156
+ On the left are your files and the figures, tables and equations of the selected one. On the right are tabs:
157
+
158
+ | Tab | What it shows |
159
+ | --- | --- |
160
+ | Markdown | the converted document |
161
+ | Source | the raw Markdown text |
162
+ | Element | the selected figure, table or equation: its crop, its LaTeX, and why the LaTeX was accepted or rejected |
163
+ | Page | the whole page, with the crop marked in red |
164
+ | Report | what the cleanup changed, and any problems that are left |
165
+ | Log | progress messages |
166
+
167
+ Keys:
168
+
169
+ | Key | Does |
170
+ | --- | --- |
171
+ | `a` | add PDFs |
172
+ | `t` | switch an equation between LaTeX and image |
173
+ | `e` | edit an equation's LaTeX; it is checked against the PDF as you type (Ctrl+S saves) |
174
+ | `h` | try harder: read the equation again from sharper and wider crops |
175
+ | `c` | adjust a crop: Tab picks the edge, arrows move it, `s` changes the step, Enter saves |
176
+ | `x` | hide or show an element |
177
+ | `v` | open the selected image in your image viewer |
178
+ | `o` | open the output folder |
179
+ | `R` | convert the selected PDF again |
180
+ | `1` to `6` | switch tabs: Markdown, Source, Element, Page, Report, Log |
181
+ | `q` | quit |
182
+
183
+ ### Without the app
184
+
185
+ ```bash
186
+ pdfdown --batch paper.pdf -o notes/ # convert, print progress, no app
187
+ pdfdown --batch papers/ -o notes/ # a whole folder
188
+ pdfdown check notes/paper/paper.md # list problems left in a converted file
189
+ ```
190
+
191
+ Options:
192
+
193
+ | Option | Does |
194
+ | --- | --- |
195
+ | `-o, --out DIR` | where to write; each PDF gets its own folder (default `./pdfdown-output`) |
196
+ | `--no-latex` | keep every equation as an image |
197
+ | `--no-tables` | crop tables as images instead of rebuilding them |
198
+ | `--ocr` | read scanned PDFs that have no text layer |
199
+ | `--device` | `auto` (default), `cpu`, `mps` (Apple GPU) or `cuda` (Nvidia GPU) |
200
+
201
+ ### What you get
202
+
203
+ For `paper.pdf`, pdfdown writes:
204
+
205
+ ```
206
+ pdfdown-output/paper/
207
+ ├── paper.md the Markdown
208
+ ├── figures/figure-1.png cropped figures (figure-2a.png, figure-2b.png for panels)
209
+ ├── tables/table-1.png table crops, used when a table cannot be rebuilt as text
210
+ ├── equations/eq-1.png equation crops, used where LaTeX did not pass the check
211
+ └── pdfdown-edits.json the changes you made in the app
212
+ ```
213
+
214
+ The Markdown links to its images by relative paths, so keep the folder together when you move or share it.
215
+
216
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
217
+
218
+ ## Examples
219
+
220
+ Three open-access papers (all CC BY 4.0, credited in [`examples/README.md`](examples/README.md)), converted with `pdfdown --batch` and no hand edits. Each folder holds the original PDF, the Markdown, and the cropped figures and equations. Open the Markdown on GitHub to see it rendered, equations included.
221
+
222
+ | Paper | Layout | Result |
223
+ | --- | --- | --- |
224
+ | Alminas, Burba and Juzeliūnas, *Imaginary magnetic fields for ultracold atoms* ([arXiv:2610.06793][ex-physics-arxiv]) | two columns, physics journal style, 105 equations | [PDF](examples/imaginary-magnetic-fields/imaginary-magnetic-fields.pdf) · [Markdown](examples/imaginary-magnetic-fields/imaginary-magnetic-fields.md) · 23 equations as checked LaTeX, 82 as images |
225
+ | Touvron et al., *LLaMA: Open and Efficient Foundation Language Models* ([arXiv:2302.13971][ex-llama-arxiv]) | two columns, many tables | [PDF](examples/llama/llama.pdf) · [Markdown](examples/llama/llama.md) · 16 tables, all rebuilt as text |
226
+ | Rafailov et al., *Direct Preference Optimization* ([arXiv:2305.18290][ex-dpo-arxiv]) | one column, long derivations | [PDF](examples/dpo/dpo.pdf) · [Markdown](examples/dpo/dpo.md) · 11 equations as checked LaTeX, 22 as images |
227
+
228
+ Each picture shows a page of the PDF on the left and the same part of the Markdown, as GitHub renders it, on the right.
229
+
230
+ **Two-column physics paper, page 3.** Equation 7 passed the check and became LaTeX. Equations 8 and 9 did not, so they are exact images: the model's reading of equation 9 wrote a plain B where the paper has a calligraphic ℬ, and the check caught it. The text runs on across the column break.
231
+
232
+ ![Page 3 of the physics paper beside its Markdown](docs/images/example-physics.png)
233
+
234
+ **LLaMA, page 2.** Table 1 is rebuilt as a Markdown table with its caption, and the two columns read as one.
235
+
236
+ ![Page 2 of LLaMA beside its Markdown](docs/images/example-llama.png)
237
+
238
+ **DPO, page 4.** Equations (4) and (5) are checked LaTeX; (6) and (7) did not pass and are exact images of the originals. Inline formulas stay as text with superscripts and subscripts; stacked fractions inside a sentence come out flattened (see [Limitations](#limitations)).
239
+
240
+ ![Page 4 of DPO beside its Markdown](docs/images/example-dpo.png)
241
+
242
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
243
+
244
+ ## How it works
245
+
246
+ A PDF doesn't store "paragraphs", "figures" or "columns". It stores drawing instructions: put the letter "A" at this position in this font, draw a line here, paint an image there. pdfdown rebuilds the document's structure from those instructions in five stages.
247
+
248
+ **1. Find the parts of each page.** Each page is looked at as a picture, the way a person would look at it. Every region gets a box and a label: title, heading, text, figure, table, equation, caption, footnote, page header or page footer. Then the boxes are put in reading order. On a two-column page that means the whole left column from top to bottom, then the right column, which is how the columns become one column. Each table's rows, columns and merged cells are worked out too. This is the slow step, so its result is saved: opening the same PDF again takes about a second.
249
+
250
+ **2. Rebuild the text from the PDF's own characters.** Every character is read again straight from the PDF, together with its exact position and size:
251
+
252
+ * *Superscripts and subscripts.* A character smaller than its neighbours and raised becomes a superscript; smaller and lowered becomes a subscript. That is how "prizes2–9" becomes "prizes<sup>2–9</sup>".
253
+ * *Hyphenated words.* "interpre-" at the end of one line and "tation" on the next become "interpretation". A hyphen is kept when the paper itself uses the hyphenated word elsewhere, as in "AI-augmented".
254
+ * *Line breaks.* The lines of a paragraph are joined into continuous sentences.
255
+
256
+ **3. Clean up the article.** A chain of small steps undoes the habits of journal layouts:
257
+
258
+ | Step | What it fixes | Example |
259
+ | --- | --- | --- |
260
+ | Headers and footers | text repeated near the top or bottom of many pages is removed | the journal name and volume on every page, page numbers |
261
+ | Figure text | short text inside or right beside a figure is dropped | axis labels such as "Time" |
262
+ | Captions | finds "Fig. 2 \|", "Table 1:" and "Extended Data Fig. 3 \|", joins captions split into pieces, and attaches each one to its figure or table | a caption split across two columns becomes one |
263
+ | Stitching | a paragraph that stops mid-sentence is joined to the next one that carries on in lower case; a figure in between moves after it | "...on the basis of" + "41,298,433 papers..." |
264
+ | Notes | footnotes and affiliations move to a Notes section at the end | |
265
+ | Badges | tiny images without a caption are dropped | a "Check for updates" badge |
266
+
267
+ **4. Crop figures, tables and equations.** pdfdown does not pull image files out of the PDF, because many figures are not images at all: charts are often drawn as lines and text, and one figure can be made of many pieces. Instead it takes the figure's box, adds a small margin, and draws that part of the page again at three times the PDF's normal resolution. The crop includes everything you see in the box, such as axis labels, panel letters and legends, and line drawings stay sharp.
268
+
269
+ For example, the box for Figure 2 on page 3 becomes `figures/figure-2.png`, and the Markdown gets:
270
+
271
+ ```markdown
272
+ ![Fig. 2 | Model accuracy by year...](figures/figure-2.png)
273
+
274
+ *Fig. 2 | Model accuracy by year...*
275
+ ```
276
+
277
+ Tables are written as Markdown tables when they are simple, as HTML tables when they have merged cells, and as the cropped image only when neither works.
278
+
279
+ Equations go in as cropped images first. Then each crop is read as LaTeX, and the LaTeX replaces the image only when it passes two checks against the PDF:
280
+
281
+ 1. Its letters and digits match the PDF's own characters inside the equation, count for count, and the characters printed small in the PDF are the subscripts and superscripts in the LaTeX.
282
+ 2. It renders without errors.
283
+
284
+ So a reading such as "Atention", or "headi" where the paper has "head" with a subscript i, is rejected and the exact image stays. You can always fix it by hand in the app.
285
+
286
+ **5. Write the Markdown.** The parts are written in reading order: headings, paragraphs, lists, tables, image links with relative paths, and `$$ ... $$` for equations that passed. The changes you made in the app are applied on every run.
287
+
288
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
289
+
290
+ ## Similar projects
291
+
292
+ Several good open-source tools convert PDFs to Markdown. This is how pdfdown compares with four well-known ones, based on their own documentation, licence files and source code as of November 2026.
293
+
294
+ | | pdfdown | [Marker][marker-url] | [MinerU][mineru-url] | [Nougat][nougat-url] | [MarkItDown][markitdown-url] |
295
+ | --- | --- | --- | --- | --- | --- |
296
+ | Display equations | LaTeX **only when checked against the PDF**, otherwise the exact image | LaTeX, not checked | LaTeX, not checked | LaTeX, not checked | plain text |
297
+ | Inline math | text with superscripts and subscripts | LaTeX | LaTeX | LaTeX | plain text |
298
+ | Figures | cropped from the page at 3x, placed with their captions | extracted and linked | cropped and linked | none | none |
299
+ | Tables | Markdown, or HTML when cells are merged | Markdown (merged cells flattened) or HTML | HTML | LaTeX | Markdown, guessed from word positions |
300
+ | Review and fix results | terminal app: switch, edit and check LaTeX, adjust crops, hide; edits kept | demo web app | web app with layout views | none | none |
301
+ | Hardware | laptop CPU or Apple GPU | needs a local model server (vLLM or llama.cpp) | default mode plans for about 8 GB of GPU memory | GPU expected | CPU |
302
+ | Licence | code MIT; models Apache 2.0, CDLA-Permissive-2.0 and MIT; no usage caps | code Apache 2.0; model weights free only below $5M funding or revenue | custom licence with user and revenue thresholds and a required attribution | code MIT; base model weights non-commercial | MIT |
303
+ | Maintained | yes | yes | yes | no release since 2023 | yes |
304
+
305
+ ### Why pdfdown
306
+
307
+ 1. **It never writes LaTeX it has not checked.** The other model-based tools write whatever their model reads. A model that reads "α" as "a", or drops a subscript, produces an equation that looks right and is wrong, and nothing tells you. pdfdown checks every equation against the characters printed in the PDF and keeps the exact image when they disagree, so an equation in your Markdown is either verified or an image of the original.
308
+ 2. **You can see and fix every element.** The terminal app lists every figure, table and equation with its crop and the reason for each choice. You can switch an equation between LaTeX and image, fix LaTeX with a live check, move a crop's edges, or hide an element, and your changes are applied again on every re-run. The other tools give you a file and leave the checking to you.
309
+ 3. **Figures look like the paper.** Each figure is drawn again from its area of the page at three times the normal resolution, so charts made of lines and text stay sharp and keep their axis labels, panel letters and legends.
310
+ 4. **Simple licensing, simple hardware.** No revenue caps, no non-commercial model weights, no attribution clauses, no GPU server. It installs with one command and runs on a laptop, without sending your PDFs anywhere.
311
+
312
+ ### When another tool is the better choice
313
+
314
+ * **You need inline math as LaTeX:** Marker or MinerU.
315
+ * **Scanned books, handwriting or many languages:** MinerU.
316
+ * **Thousands of documents on GPUs:** Marker or MinerU.
317
+ * **Word, PowerPoint or e-book files, or a quick text dump for an AI tool:** MarkItDown.
318
+
319
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
320
+
321
+ ## Limitations
322
+
323
+ * **Many equations stay as images.** That is on purpose: LaTeX is used only when it can be verified. In the papers tested, between a fifth and a half of the display equations came out as LaTeX (fewer in notation-heavy physics, more in machine learning papers); you can fix the rest in the app with `e` or `h`.
324
+ * **Inline math** inside sentences is kept as text with superscripts and subscripts, not converted to LaTeX. Simple inline math reads well ("λ<sup>t−1</sup>", "W ∈ R<sup>K×H</sup>"), but fractions, roots and stacked symbols inside a sentence come out flattened or out of order, especially in math-heavy physics papers.
325
+ * **Scanned PDFs** need `--ocr`, and their equations always stay as images, because there is no text to check the LaTeX against.
326
+ * **Tested on macOS.** Linux should work but has not been tested yet. Windows is not supported yet.
327
+
328
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
329
+
330
+ ## Development
331
+
332
+ ```bash
333
+ git clone https://github.com/rafsunsheikh/pdfdown.git
334
+ cd pdfdown
335
+ uv venv -p 3.12 && uv pip install -e ".[dev]"
336
+ .venv/bin/python -m pytest
337
+ ```
338
+
339
+ The tests use two sample PDFs in `corpus/` made for this project and the three CC BY papers in `examples/`. Tests that need other well-known papers (for example the BERT, Adam and "Attention Is All You Need" preprints from arXiv) are skipped when those files are not present, because their licences do not allow redistributing them here.
340
+
341
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
342
+
343
+ ## License
344
+
345
+ Distributed under the MIT License. See [`LICENSE`][license-url] for details.
346
+
347
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
348
+
349
+ ## Contact
350
+
351
+ Md Rafsun Sheikh: [github.com/rafsunsheikh][profile-url]
352
+
353
+ Project link: [github.com/rafsunsheikh/pdfdown][repo-url]
354
+
355
+ <p align="right">(<a href="#readme-top">back to top</a>)</p>
356
+
357
+ [pypi-shield]: https://img.shields.io/pypi/v/pdfdown.svg?style=for-the-badge
358
+ [pypi-url]: https://pypi.org/project/pdfdown/
359
+ [python-shield]: https://img.shields.io/pypi/pyversions/pdfdown.svg?style=for-the-badge
360
+ [issues-shield]: https://img.shields.io/github/issues/rafsunsheikh/pdfdown.svg?style=for-the-badge
361
+ [issues-url]: https://github.com/rafsunsheikh/pdfdown/issues
362
+ [license-shield]: https://img.shields.io/github/license/rafsunsheikh/pdfdown.svg?style=for-the-badge
363
+ [license-url]: https://github.com/rafsunsheikh/pdfdown/blob/main/LICENSE
364
+ [repo-url]: https://github.com/rafsunsheikh/pdfdown
365
+ [profile-url]: https://github.com/rafsunsheikh
366
+ [uv-url]: https://docs.astral.sh/uv/
367
+ [marker-url]: https://github.com/datalab-to/marker
368
+ [mineru-url]: https://github.com/opendatalab/MinerU
369
+ [nougat-url]: https://github.com/facebookresearch/nougat
370
+ [markitdown-url]: https://github.com/microsoft/markitdown
371
+ [ex-physics-arxiv]: https://arxiv.org/abs/2610.06793
372
+ [ex-llama-arxiv]: https://arxiv.org/abs/2302.13971
373
+ [ex-dpo-arxiv]: https://arxiv.org/abs/2305.18290