pdfmd-cli 3.23.17__tar.gz → 3.24.19__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.
- {pdfmd_cli-3.23.17/pdfmd_cli.egg-info → pdfmd_cli-3.24.19}/PKG-INFO +237 -7
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/README.md +234 -6
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd.py +1752 -70
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19/pdfmd_cli.egg-info}/PKG-INFO +237 -7
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_cli.egg-info/SOURCES.txt +28 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_cli.egg-info/requires.txt +3 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_cli.egg-info/top_level.txt +2 -0
- pdfmd_cli-3.24.19/pdfmd_office/__init__.py +29 -0
- pdfmd_cli-3.24.19/pdfmd_office/docx.py +426 -0
- pdfmd_cli-3.24.19/pdfmd_office/docx_post.py +92 -0
- pdfmd_cli-3.24.19/pdfmd_office/fonts.py +39 -0
- pdfmd_cli-3.24.19/pdfmd_office/fragments.py +232 -0
- pdfmd_cli-3.24.19/pdfmd_office/labels.py +131 -0
- pdfmd_cli-3.24.19/pdfmd_office/odt.py +155 -0
- pdfmd_cli-3.24.19/pdfmd_office/office.lua +1408 -0
- pdfmd_cli-3.24.19/pdfmd_office/spec.py +106 -0
- pdfmd_cli-3.24.19/pdfmd_office/units.py +117 -0
- pdfmd_cli-3.24.19/pdfmd_setup/__init__.py +26 -0
- pdfmd_cli-3.24.19/pdfmd_setup/fancy.py +192 -0
- pdfmd_cli-3.24.19/pdfmd_setup/plain.py +113 -0
- pdfmd_cli-3.24.19/pdfmd_setup/registry.py +221 -0
- pdfmd_cli-3.24.19/pdfmd_unicode/_tessdata_catalog.py +133 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/colorfont.py +50 -1
- pdfmd_cli-3.24.19/pdfmd_unicode/tessdata.py +160 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pyproject.toml +4 -1
- pdfmd_cli-3.24.19/tests/test_api.py +69 -0
- pdfmd_cli-3.24.19/tests/test_apple_emoji.py +59 -0
- pdfmd_cli-3.24.19/tests/test_completion.py +47 -0
- pdfmd_cli-3.24.19/tests/test_csv_table.py +62 -0
- pdfmd_cli-3.24.19/tests/test_display_path.py +43 -0
- pdfmd_cli-3.24.19/tests/test_doctor.py +45 -0
- pdfmd_cli-3.24.19/tests/test_install_ocr.py +57 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_native.py +1 -1
- pdfmd_cli-3.24.19/tests/test_office.py +476 -0
- pdfmd_cli-3.24.19/tests/test_office_latex.py +411 -0
- pdfmd_cli-3.24.19/tests/test_setup.py +218 -0
- pdfmd_cli-3.24.19/tests/test_tessdata.py +102 -0
- pdfmd_cli-3.24.19/tests/test_text_input.py +69 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/LICENSE +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_cli.egg-info/dependency_links.txt +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_cli.egg-info/entry_points.txt +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/LICENSE +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/VENDORED.md +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/__init__.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/_kerning_data.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/assets/fonts/DejaVuSans-LICENSE.txt +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/assets/fonts/DejaVuSans.ttf +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/ast.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/cidfont.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/embedded.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/embedded_metrics.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/emoji.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/emoji_font.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/fonts.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/html_filter.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/image_loader.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/layout.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/parser.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/pdf.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/py.typed +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/render.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/truetype.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_inkmd/url_filter.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/__init__.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/_catalog.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/_scripts.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/emoji.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/fonts.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/install.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/plan.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/scripts.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/pdfmd_unicode/translit.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/setup.cfg +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_attach.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_cache_location.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_config.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_lookup.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_packaging.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_pdf_input.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_polish.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_sections.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_translit.py +0 -0
- {pdfmd_cli-3.23.17 → pdfmd_cli-3.24.19}/tests/test_unicode.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdfmd-cli
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.24.19
|
|
4
4
|
Summary: One command from Markdown to a good-looking PDF: a Pandoc wrapper with smart defaults, project-file discovery and a multi-engine fallback chain
|
|
5
5
|
Author: Ali Perdekhan
|
|
6
6
|
License-Expression: MIT
|
|
@@ -28,6 +28,8 @@ Requires-Dist: pypinyin; extra == "translit"
|
|
|
28
28
|
Requires-Dist: anyascii; extra == "translit"
|
|
29
29
|
Provides-Extra: pandoc
|
|
30
30
|
Requires-Dist: pypandoc_binary; extra == "pandoc"
|
|
31
|
+
Provides-Extra: tui
|
|
32
|
+
Requires-Dist: prompt_toolkit>=3; extra == "tui"
|
|
31
33
|
Dynamic: license-file
|
|
32
34
|
|
|
33
35
|
# pdfmd
|
|
@@ -74,6 +76,16 @@ turns that knowledge into defaults:
|
|
|
74
76
|
- **It doesn't give up on the first engine.** If `lualatex` fails or isn't
|
|
75
77
|
installed, it tries the next engine, then the next, and tells you why each
|
|
76
78
|
one failed.
|
|
79
|
+
- **It handles every script and emoji.** Text the main font cannot draw (Arabic,
|
|
80
|
+
Hebrew, Chinese, Japanese, Korean, Greek, Cyrillic with Kazakh letters, Indic and
|
|
81
|
+
more) is set run by run in an installed font for its script, emoji become colour
|
|
82
|
+
pictures, and `pdfmd --install fonts` fetches missing fonts without admin rights
|
|
83
|
+
(see [Other scripts](#other-scripts)).
|
|
84
|
+
- **It finds documents by name, in any script.** `pdfmd glyukoza` opens
|
|
85
|
+
`Глюкоза.md`; with `--translit` packs, `pdfmd tyche` finds `Τύχη.md` and
|
|
86
|
+
`pdfmd mingyun` finds `命運.md`.
|
|
87
|
+
- **It reads PDFs too.** `pdfmd paper.pdf` restores a PDF's own embedded source or
|
|
88
|
+
OCRs the pages to Markdown (see [PDF to Markdown](#pdf-to-markdown)).
|
|
77
89
|
- **It shows what it did.** Every automatic decision prints an `AUTO` line,
|
|
78
90
|
`-v` shows the exact Pandoc command, and every default can be switched off.
|
|
79
91
|
|
|
@@ -121,8 +133,12 @@ brew install --cask mactex-no-gui # optional: full LaTeX (large)
|
|
|
121
133
|
|
|
122
134
|
```sh
|
|
123
135
|
sudo apt install pipx pandoc texlive-xetex # Debian/Ubuntu
|
|
136
|
+
sudo dnf install pipx pandoc texlive-xetex # Fedora (add Typst with `pdfmd --install typst`)
|
|
137
|
+
sudo pacman -S python-pipx pandoc-cli typst texlive # Arch
|
|
124
138
|
```
|
|
125
139
|
|
|
140
|
+
On any Linux, `pdfmd --install full` (Pandoc and Typst) needs no package manager and no root.
|
|
141
|
+
|
|
126
142
|
```powershell
|
|
127
143
|
py -m pip install --user pipx; py -m pipx ensurepath # Windows
|
|
128
144
|
winget install --id JohnMacFarlane.Pandoc; winget install --id Typst.Typst
|
|
@@ -175,6 +191,34 @@ OK quarto (only needed for .qmd files) (/usr/local/bin/quarto)
|
|
|
175
191
|
The numbers are the fallback order, and also shortcuts: `-e 6` means
|
|
176
192
|
`-e typst`.
|
|
177
193
|
|
|
194
|
+
For everything at once, `pdfmd --doctor` is one page on the Markdown-to-PDF tools, fonts
|
|
195
|
+
and emoji, PDF reading (batchocr, Tesseract, Poppler, OCR languages), your config file and
|
|
196
|
+
the cache, ending with the command that fixes each missing piece:
|
|
197
|
+
|
|
198
|
+
```console
|
|
199
|
+
$ pdfmd --doctor
|
|
200
|
+
...
|
|
201
|
+
Reading PDFs (PDF to Markdown):
|
|
202
|
+
OK batchocr 1.2.4
|
|
203
|
+
MISS tesseract: not found
|
|
204
|
+
MISS poppler: not found
|
|
205
|
+
|
|
206
|
+
1 thing(s) to fix:
|
|
207
|
+
1. tesseract (scanned PDFs) and poppler (scanned PDFs)
|
|
208
|
+
brew install tesseract poppler
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Tab completion
|
|
212
|
+
|
|
213
|
+
`pdfmd --completion bash|zsh|fish` prints a completion script, generated from the command
|
|
214
|
+
line itself so it never goes out of date:
|
|
215
|
+
|
|
216
|
+
```sh
|
|
217
|
+
pdfmd --completion zsh > ~/.zfunc/_pdfmd # ~/.zfunc in $fpath, then compinit
|
|
218
|
+
pdfmd --completion bash > ~/.local/share/bash-completion/completions/pdfmd
|
|
219
|
+
pdfmd --completion fish > ~/.config/fish/completions/pdfmd.fish
|
|
220
|
+
```
|
|
221
|
+
|
|
178
222
|
### No Pandoc? The built-in fallback
|
|
179
223
|
|
|
180
224
|
On a machine with no Pandoc, or Pandoc but no PDF engine, `pdfmd` does not
|
|
@@ -305,6 +349,110 @@ pdfmd lecture --to typst -o lecture.typ
|
|
|
305
349
|
pdfmd lecture -o lecture.tex # a complete, compilable .tex, not a fragment
|
|
306
350
|
```
|
|
307
351
|
|
|
352
|
+
### Word and OpenDocument output
|
|
353
|
+
|
|
354
|
+
Plain Pandoc ignores `papersize`, `geometry`, `mainfont` and `fontsize` when it writes `.docx`
|
|
355
|
+
or `.odt`: you get a Letter page in the default fonts. pdfmd writes them into the *reference
|
|
356
|
+
document* Pandoc builds the file from, so the page and the text follow the same front matter as the PDF:
|
|
357
|
+
|
|
358
|
+
| Front matter | In the Word file |
|
|
359
|
+
|---|---|
|
|
360
|
+
| `papersize: a4` (also `letter`, `legal`, `a5`, `b5`..., `classoption: [a4paper, landscape]`) | page size and orientation |
|
|
361
|
+
| `geometry:` (a list, `margin=2cm`, `top=1in,left=...`, `paperwidth=...`) or `margin:` | page margins |
|
|
362
|
+
| `mainfont`, `sansfont`, `monofont`, `CJKmainfont`, `fontsize`, `linestretch`, `lang`, `indent` | body, heading and code fonts, sizes, line spacing, language, first-line indent |
|
|
363
|
+
|
|
364
|
+
A `.docx` carries font *names*, not fonts, and the person opening it has Times New Roman, not
|
|
365
|
+
STIX Two Text. So well-known fonts Word does not ship are mapped to the closest one it does (STIX
|
|
366
|
+
Two Text, Libertinus, Latin Modern to Times New Roman; Helvetica Neue, Inter to Arial; JetBrains
|
|
367
|
+
Mono, Menlo, Fira Code to Consolas), with an `AUTO OFFICE` note; `office: {fonts: exact}` keeps
|
|
368
|
+
your names. Without any of these keys pdfmd's own look applies: black bold headings sized like a LaTeX
|
|
369
|
+
article, a centred title block, booktabs-style table rules, Times New Roman and Consolas.
|
|
370
|
+
|
|
371
|
+
**Your own template.** A reference document decides the page and fonts itself, and pdfmd then
|
|
372
|
+
changes only what the document's `office:` block names. It is found, in order, as
|
|
373
|
+
`office: {reference-doc: FILE}`, `<name>-reference.docx` or `reference.docx` (`.dotx` works too,
|
|
374
|
+
`.odt`/`.ott` for ODT, `.pptx`/`.potx` for slides) beside the document, in its `metadata/` folder or
|
|
375
|
+
beside its metadata files, and finally in `~/.config/pdfmd/`. Pandoc's own `--reference-doc` is left
|
|
376
|
+
alone. Only builds whose output is `.docx`/`.odt`/`.pptx` look for one. `pdfmd --init-reference`
|
|
377
|
+
writes `reference.docx` (also `odt`, `pptx`): Pandoc's styles with pdfmd's look, to restyle in Word.
|
|
378
|
+
|
|
379
|
+
A template keeps its own style names. `office: {styles: {Heading1: LRH1, BodyText: LRNormal, Table: TableGrid}}`
|
|
380
|
+
makes the Heading 1, Body Text and table Pandoc writes look like the template's own `LR H1`, `LR Normal` and
|
|
381
|
+
`Table Grid` (a missing Pandoc style is created from the source); `office: {replace: {NULAB-KICKER: "Course
|
|
382
|
+
wording"}}` rewrites text in the template's headers and footers; `office: {title-page: true}` gives the first
|
|
383
|
+
page a page of its own, without header or footer.
|
|
384
|
+
|
|
385
|
+
**A LaTeX package can tell pdfmd about itself.** Beside a package's `.sty` (or in an `office/` or `pdfmd/` folder there)
|
|
386
|
+
pdfmd looks for `<package>-pdfmd.yaml`, and for its Word support: `<package>-reference.docx`/`.dotx`,
|
|
387
|
+
`<package>-office.lua` (the profile above) and `<package>-office.yaml` (the `office:` defaults, with `by-option:`
|
|
388
|
+
entries for what an option of `\usepackage[opt]{package}` adds). A document that loads the package gets all of it with
|
|
389
|
+
no setting of its own, and a package without these files behaves exactly as before.
|
|
390
|
+
|
|
391
|
+
`<package>-pdfmd.yaml` holds `latex-keys:`, the front-matter keys the package's macros are filled from
|
|
392
|
+
(`experiment: LabExperiment` turns `experiment: Titration` into `\renewcommand{\LabExperiment}{Titration}` after the
|
|
393
|
+
preamble), and an optional `office:` section, the same as `<package>-office.yaml`, for a package that wants one file:
|
|
394
|
+
|
|
395
|
+
```yaml
|
|
396
|
+
latex-keys:
|
|
397
|
+
experiment: LabExperiment
|
|
398
|
+
group: LabGroup
|
|
399
|
+
office:
|
|
400
|
+
reference-doc: house.dotx
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
```yaml
|
|
404
|
+
pdfmd-options:
|
|
405
|
+
office:
|
|
406
|
+
reference-doc: ../templates/house.dotx # or leave it to be found
|
|
407
|
+
papersize: a4 # change just this on top of the template
|
|
408
|
+
fonts: exact # keep STIX Two Text and friends as named
|
|
409
|
+
style: plain # no pdfmd look (headings, title block, table rules)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
`--no-auto officeref` turns the search off, `--no-auto officestyle` leaves Pandoc's default alone.
|
|
413
|
+
|
|
414
|
+
**LaTeX in the document.** Pandoc turns `$x^2$` into a Word equation and drops everything else of
|
|
415
|
+
LaTeX. For `.docx` and `.odt` pdfmd adds a filter that makes it native where it can:
|
|
416
|
+
|
|
417
|
+
- `\ce{Ag+(aq) + Cl-(aq) -> AgCl(s)}` (mhchem) and `\si{\gram\per\mole}`, `\SI{5}{\milli\liter}`,
|
|
418
|
+
`\num{1.5e-3}` (siunitx) become formatted text with real subscripts, charges and units, and, inside
|
|
419
|
+
math, Word equation pieces;
|
|
420
|
+
- `\begin{equation}`, `align`, `reaction`... become Word equations with their number at the right;
|
|
421
|
+
- raw `figure`, `tabular`, lists, `\emph`, `\newpage`... are read by Pandoc's own LaTeX reader;
|
|
422
|
+
- `\ref`, `\eqref`, `\cref`, `\Cref`, `\pageref` and the "Figure 3." in front of a caption use the numbers
|
|
423
|
+
LaTeX itself gave (pdfmd builds the PDF once, in its cache, and reads the `.aux`; reused while the sources
|
|
424
|
+
are older), with the caption separator (`labelsep=`) and `\crefname`s of your preamble;
|
|
425
|
+
- **what is left is drawn by LaTeX**: tikz, chemfig, a house style's own macros, math Pandoc cannot convert are compiled in
|
|
426
|
+
*your document's own preamble* (the same fonts, packages and macros as the PDF, one fragment to a page), and the
|
|
427
|
+
pages go into the Word file as vector pictures: an SVG with a 300 dpi PNG fallback (Word 2016 and later draw the SVG,
|
|
428
|
+
LibreOffice and older readers the PNG). An inline fragment sits on the text's baseline, a wide one is scaled to the
|
|
429
|
+
text width, a figure's caption stays text with its number. `\includegraphics{plot.pdf}` and `` (Word cannot
|
|
430
|
+
show a PDF) are converted the same way. Pictures are cached by content, so a rebuild draws only what changed
|
|
431
|
+
(`pdfmd --clear-cache` empties it). A fragment that will not compile is named in a warning and left out; the rest of
|
|
432
|
+
the document is built. Needs `pdftocairo` (Poppler) and a LaTeX engine; without them the fragments are reported only.
|
|
433
|
+
- **a house style's own macros** can be told to pdfmd: `office.lua` (or `<name>-office.lua`) beside the document, in its
|
|
434
|
+
`metadata/` folder or in `~/.config/pdfmd/`, or `office: {profile: FILE}`, is a small Lua file:
|
|
435
|
+
`return {ignore = {"\\LabCaptionBegin"}, commands = {prelab = function(args) return {pandoc.Strong{pandoc.Str("[pre-lab " .. args[1] .. "]")}} end}}`
|
|
436
|
+
says which macros to drop and what the others mean in a Word file (a command may return text, or blocks such as a
|
|
437
|
+
native table); an optional `pandoc = function(doc, helpers)` hook may restructure the whole document. The helpers
|
|
438
|
+
include `inlines(tex)`/`blocks(tex)` (LaTeX read with the filter's own math, `\ce` and `\si` applied),
|
|
439
|
+
`read_file(name)` (a file the document's `\input` would find), `number_caption(table, "table")`, `labels()`,
|
|
440
|
+
`preamble()`, `meta()`, `warn(text)`; a profile can thus build a house table from the package's own data, as nulabreport
|
|
441
|
+
does for `\chemicals`.
|
|
442
|
+
- what cannot be done at all is named in a warning (`-v` lists it).
|
|
443
|
+
|
|
444
|
+
`pdfmd report.md --check-docx` says what a Word build would make native and what it would draw as pictures, naming the
|
|
445
|
+
environment or macro behind each (`the tikzpicture environment`, `the macro \irspectrum`), without drawing or writing anything: a
|
|
446
|
+
quick way to see what is left to give a recipe (see the profile below).
|
|
447
|
+
|
|
448
|
+
`pdfmd-options: {office: {latex: off}}` or `--no-auto officelatex` skips all of it, `office: {labels: off}`
|
|
449
|
+
skips the PDF build (numbers are then counted).
|
|
450
|
+
|
|
451
|
+
The same filter serves the other outputs when LaTeX is the problem: **the soffice fallback** (the Word file above, then LibreOffice: `pdfmd -e soffice report.md` is the `.docx` as LibreOffice draws it) now
|
|
452
|
+
keeps the page size, margins and fonts, shows equations and draws what LaTeX can; a **Typst or WeasyPrint run after LaTeX
|
|
453
|
+
failed** gets what the document says in LaTeX as native text or pictures instead of nothing; and HTML, Typst and
|
|
454
|
+
WeasyPrint builds do it on request (`pdfmd-options: {office: {latex: auto}}`).
|
|
455
|
+
|
|
308
456
|
### Stopping part-way
|
|
309
457
|
|
|
310
458
|
`--stop-at` ends the build after a stage; everything before it runs as normal:
|
|
@@ -461,10 +609,32 @@ options of [M1ck4's pdfmd](https://github.com/M1ck4/pdfmd) (`--ocr`, `--lang`,
|
|
|
461
609
|
work as they did. Install the reader once:
|
|
462
610
|
|
|
463
611
|
```sh
|
|
464
|
-
pdfmd --install batchocr # pip install batchocr[md] from its GitHub release
|
|
465
|
-
|
|
612
|
+
pdfmd --install batchocr # pip install batchocr[md] from its GitHub release,
|
|
613
|
+
# then offers the system programs below
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
Scanned pages also need **Tesseract** (OCR) and **Poppler** (`pdftotext`, `pdftoppm`).
|
|
617
|
+
Those are separate programs with their own builds for every platform, so pdfmd does not
|
|
618
|
+
bundle them; `--install batchocr` finds your package manager (Homebrew, apt, dnf, pacman,
|
|
619
|
+
zypper, apk, scoop, Chocolatey or winget), shows the exact command and, on an interactive
|
|
620
|
+
terminal, runs it if you say yes (`PDFMD_NO_PROMPT=1` only prints it). By hand:
|
|
621
|
+
|
|
622
|
+
```sh
|
|
623
|
+
brew install tesseract poppler # macOS (and Linuxbrew)
|
|
624
|
+
sudo apt install tesseract-ocr poppler-utils # Debian/Ubuntu; dnf: tesseract poppler-utils
|
|
625
|
+
scoop install tesseract poppler # Windows (or choco install ...)
|
|
466
626
|
```
|
|
467
627
|
|
|
628
|
+
OCR languages are packs of their own. `pdfmd --install ocr` lists the Tesseract languages
|
|
629
|
+
pdfmd can fetch, and `pdfmd --install ocr:rus,kaz` (or `ru`, `kazakh`, `zh`, `ja`...) downloads
|
|
630
|
+
them into pdfmd's own folder, with no admin rights and each file checked against a checksum
|
|
631
|
+
pinned in pdfmd (the compact `tessdata_fast` models, Apache-2.0; English and the orientation
|
|
632
|
+
model come along). `pdfmd scan.pdf --lang rus` then uses that folder whenever it has every
|
|
633
|
+
language you asked for, and Tesseract's own languages otherwise (a `TESSDATA_PREFIX` you set
|
|
634
|
+
always wins). `pdfmd --uninstall ocr:rus` removes one. The package managers have them too:
|
|
635
|
+
`brew install tesseract-lang`, `apt install tesseract-ocr-rus`, `dnf install
|
|
636
|
+
tesseract-langpack-rus`. `pdfmd --check-dependencies` reports batchocr, Tesseract and Poppler.
|
|
637
|
+
|
|
468
638
|
Credits and licences: batchocr's Markdown structure stages are M1ck4's
|
|
469
639
|
(MIT; that project is archived) and are vendored inside batchocr with their
|
|
470
640
|
licence. PyMuPDF, which they use, is AGPL-3.0: it is installed as its own
|
|
@@ -491,6 +661,25 @@ comma inside a field). The text is Helvetica, so letters outside Latin-1 become
|
|
|
491
661
|
their base letter or `?`. `--attach-links` stores each linked file as
|
|
492
662
|
`linked/PATH` and puts a paperclip in the margin beside the link.
|
|
493
663
|
|
|
664
|
+
### Use it from Python
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
import pdfmd
|
|
668
|
+
|
|
669
|
+
pdfmd.convert_file("report.md", "docx") # -> Path("report.docx")
|
|
670
|
+
pdfmd.convert_file("report.md", "pdf", "out/report.pdf", variables={"geometry": "margin=2cm"},
|
|
671
|
+
extra_args=["--engine", "typst"])
|
|
672
|
+
html = pdfmd.convert_text("# Hi\n\nSome *text*.\n", "html") # str for text formats, bytes for pdf/docx/odt/pptx/epub
|
|
673
|
+
rst = pdfmd.convert_text(open("notes.rst").read(), "docx", format="rst")
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
Each call runs the command-line tool (as `pypandoc` runs Pandoc), so a document builds exactly as `pdfmd` would build it,
|
|
677
|
+
with all the auto-discovery of the document's folder, and nothing in the caller's process is touched. The source is not
|
|
678
|
+
stamped or backed up unless you ask (`stamp=True`, `backup=True`). A failure raises `pdfmd.PdfmdError` (with
|
|
679
|
+
`returncode`, `stdout` and `stderr`); `check=False` returns the path anyway. `metadata=` takes metadata files,
|
|
680
|
+
`variables=` a dict of Pandoc variables, `extra_args=` anything else the command line takes, `cwd=` the folder it runs
|
|
681
|
+
in and `timeout=` seconds.
|
|
682
|
+
|
|
494
683
|
### Other command names: `mdpdf` and `inkmd`
|
|
495
684
|
|
|
496
685
|
pdfmd also installs `mdpdf` and `inkmd` commands that take those tools' own keys
|
|
@@ -643,6 +832,10 @@ Measured values:
|
|
|
643
832
|
<img src="https://raw.githubusercontent.com/aliperdehan/pdfmd/main/docs/results.png" width="480" alt="A CSV file rendered as a table">
|
|
644
833
|
</p>
|
|
645
834
|
|
|
835
|
+
- Cells are read as Pandoc Markdown (`H~2~O`, `$x^2$`, `\ce{...}`, `[@key]`); `reader="gfm"` makes them plain GFM.
|
|
836
|
+
- A caption is the line after the block (`: Caption {#tbl:id}`, or `Table: Caption`), or `caption="Caption"` inside the
|
|
837
|
+
braces, with the identifier as `#tbl:id` there too. A caption in the attributes wins over a line after the block.
|
|
838
|
+
- A relative `file=` is found beside the document (and along the resource path), wherever Pandoc runs.
|
|
646
839
|
- The delimiter is detected from the extension (`.tsv` means tab), or set
|
|
647
840
|
with `delimiter=";"`.
|
|
648
841
|
- The first row is the header unless you add `header="false"`.
|
|
@@ -663,6 +856,15 @@ pdfmd analysis.qmd # handed to Quarto, so code chunks actually run
|
|
|
663
856
|
pdfmd page.html # anything else Pandoc can read (give the extension)
|
|
664
857
|
```
|
|
665
858
|
|
|
859
|
+
**A plain-text file as Markdown (opt-in).** `pdfmd notes.txt --text-to-markdown` reads a `.txt` file the way a person typed it
|
|
860
|
+
and guesses its structure: headings (capitals, `1.2 Title`, `====` underlines), bullet and numbered lists, tables from
|
|
861
|
+
columns separated by runs of spaces, indented blocks as code, hard-wrapped lines joined into paragraphs. The words never
|
|
862
|
+
change (the letters and digits of the result are the input's), and a text that measures as garbled (symbol soup, OCR
|
|
863
|
+
noise, replacement characters) gets paragraphs only, with the rule that fired printed. `MODE` is `auto` (default),
|
|
864
|
+
`force` (guess even in a garbled text) or `paragraphs`. It needs batchocr 1.2.5 (`pdfmd --install batchocr`), writes `notes.md`
|
|
865
|
+
beside the text (never over a file that is there) and builds from it; with `-o x.md` the conversion is all it does.
|
|
866
|
+
Off unless asked: `--text-to-markdown`, or `options: {text-to-markdown: auto}` in the config file (or `pdfmd --setup`).
|
|
867
|
+
|
|
666
868
|
## What it does automatically
|
|
667
869
|
|
|
668
870
|
Most of these print an `AUTO` line, and each can be switched off individually.
|
|
@@ -703,6 +905,12 @@ The cause is usually one of these automatic decisions, and `-v` names it.
|
|
|
703
905
|
|
|
704
906
|
### Other scripts
|
|
705
907
|
|
|
908
|
+
<p align="center">
|
|
909
|
+
<img src="https://raw.githubusercontent.com/aliperdehan/pdfmd/main/docs/scripts.png" width="560" alt="examples/scripts.md: Kazakh, Greek, Arabic, Hebrew, Chinese, Japanese, Korean and Hindi text, and emoji, in one PDF">
|
|
910
|
+
</p>
|
|
911
|
+
|
|
912
|
+
(That is [`examples/scripts.md`](https://github.com/aliperdehan/pdfmd/blob/main/examples/scripts.md), built with no configuration.)
|
|
913
|
+
|
|
706
914
|
A document that mixes scripts needs more than one font. With lualatex or
|
|
707
915
|
xelatex, `pdfmd` reads the character tables of your installed fonts, finds
|
|
708
916
|
the characters the main font cannot draw and sets each run of them in a font
|
|
@@ -744,10 +952,10 @@ Emoji are set as pictures with lualatex and xelatex (which cannot draw colour
|
|
|
744
952
|
fonts): each emoji, flag, skin tone, family or keycap is looked up in the colour
|
|
745
953
|
emoji font (`pdfmd --install emoji`, a system Noto Color Emoji, or else Apple Color Emoji on
|
|
746
954
|
a Mac), its picture taken out of the font file and included at the height of the text, in
|
|
747
|
-
inline code and code blocks too. Apple's font is read
|
|
748
|
-
emoji, skin tones and
|
|
749
|
-
|
|
750
|
-
for those). The pictures
|
|
955
|
+
inline code and code blocks too. Apple's font is read through its glyph names (the same
|
|
956
|
+
way for single emoji, skin tones, flags, keycaps and the joined emoji it has a glyph for,
|
|
957
|
+
such as a woman scientist); the few it composes in tables pdfmd does not read (a family of
|
|
958
|
+
four, say) are reported as undrawable (install Noto for those). The pictures
|
|
751
959
|
are kept in pdfmd's cache folder; a `.tex` written with `--to latex` points
|
|
752
960
|
there.
|
|
753
961
|
|
|
@@ -831,6 +1039,27 @@ options:
|
|
|
831
1039
|
pdf-engine: lualatex
|
|
832
1040
|
```
|
|
833
1041
|
|
|
1042
|
+
**`pdfmd --setup`** changes the same defaults from a menu, without editing the files: a numbered list (nothing to
|
|
1043
|
+
install, works over ssh), each setting with its choices and what they mean. It covers what a document would otherwise
|
|
1044
|
+
say in `pdfmd-options:` or its front matter, for every document:
|
|
1045
|
+
|
|
1046
|
+
- *global metadata* (a `metadata.yaml` beside the config file, below anything a document's own folder says): author, language,
|
|
1047
|
+
paper size, font size, page geometry, main and code font, line spacing, coloured links, table of contents, and for
|
|
1048
|
+
citations the bibliography file, the CSL style and linked citations;
|
|
1049
|
+
- characters a font lacks or none draws, fonts for other scripts, romanization packs;
|
|
1050
|
+
- the citation engine, the PDF engine, the default output format, HTML (one file, math method), LaTeX and reference
|
|
1051
|
+
numbers in Word files;
|
|
1052
|
+
- PDF finishing (header, footer, bookmarks, attached links) and the source file (the "Compiled with..." stamp, backups,
|
|
1053
|
+
comment stripping, attaching the source and its files to the PDF);
|
|
1054
|
+
- the cache, reading `.txt` as Markdown, and which of pdfmd's automatic behaviours (`--no-auto` kinds) are off.
|
|
1055
|
+
|
|
1056
|
+
Choosing 0 (for a text, `-`) gives a setting its built-in default back; `s` saves, `q` quits. The files are rewritten without your
|
|
1057
|
+
comments (the old one is kept as `.bak`). The same keys can be written by hand under `options:` of `config.yaml`. A
|
|
1058
|
+
full-screen version is optional: `pdfmd --install tui` (prompt_toolkit, about 1 MB), then `pdfmd --setup fancy`, or set
|
|
1059
|
+
"This setup screen" to fancy to make it the one `pdfmd --setup` opens. The first time pdfmd finishes a build in a terminal
|
|
1060
|
+
with no config file yet, it prints one `TIP` line about `--setup` (never in a pipe, in CI, or from the Python API;
|
|
1061
|
+
`PDFMD_NO_PROMPT=1` silences it).
|
|
1062
|
+
|
|
834
1063
|
The decisions pdfmd remembers for you (the Lua filters it trusts, an offer you
|
|
835
1064
|
dismissed) live in the same folder, not in `~/.cache/pdfmd`, so cleaning the cache
|
|
836
1065
|
(`--clear-cache`) cannot lose them; files from an older version are moved there
|
|
@@ -890,6 +1119,7 @@ read with `pdfinfo -meta`. Turn this off with `--no-stamp-pdf-metadata`.
|
|
|
890
1119
|
|
|
891
1120
|
## Reference
|
|
892
1121
|
|
|
1122
|
+
- [`docs/recipes.md`](https://github.com/aliperdehan/pdfmd/blob/main/docs/recipes.md) has short "how do I..." answers: a paper in several scripts, a scanned PDF to Markdown, a folder with a house style, a book from many files.
|
|
893
1123
|
- `pdfmd --help` lists every flag.
|
|
894
1124
|
- The docstring at the top of [`pdfmd.py`](https://github.com/aliperdehan/pdfmd/blob/main/pdfmd.py) is the full reference
|
|
895
1125
|
for each behaviour and its edge cases.
|