pdfmd-cli 3.19.8__tar.gz → 3.21.5__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 (41) hide show
  1. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/PKG-INFO +100 -4
  2. pdfmd_cli-3.19.8/pdfmd_cli.egg-info/PKG-INFO → pdfmd_cli-3.21.5/README.md +90 -23
  3. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/pdfmd.py +2468 -82
  4. pdfmd_cli-3.19.8/README.md → pdfmd_cli-3.21.5/pdfmd_cli.egg-info/PKG-INFO +119 -3
  5. pdfmd_cli-3.21.5/pdfmd_cli.egg-info/SOURCES.txt +36 -0
  6. pdfmd_cli-3.21.5/pdfmd_cli.egg-info/requires.txt +14 -0
  7. pdfmd_cli-3.21.5/pdfmd_cli.egg-info/top_level.txt +2 -0
  8. pdfmd_cli-3.21.5/pdfmd_inkmd/LICENSE +21 -0
  9. pdfmd_cli-3.21.5/pdfmd_inkmd/VENDORED.md +17 -0
  10. pdfmd_cli-3.21.5/pdfmd_inkmd/__init__.py +436 -0
  11. pdfmd_cli-3.21.5/pdfmd_inkmd/_kerning_data.py +4659 -0
  12. pdfmd_cli-3.21.5/pdfmd_inkmd/assets/fonts/DejaVuSans-LICENSE.txt +187 -0
  13. pdfmd_cli-3.21.5/pdfmd_inkmd/assets/fonts/DejaVuSans.ttf +0 -0
  14. pdfmd_cli-3.21.5/pdfmd_inkmd/ast.py +370 -0
  15. pdfmd_cli-3.21.5/pdfmd_inkmd/cidfont.py +511 -0
  16. pdfmd_cli-3.21.5/pdfmd_inkmd/embedded.py +346 -0
  17. pdfmd_cli-3.21.5/pdfmd_inkmd/embedded_metrics.py +102 -0
  18. pdfmd_cli-3.21.5/pdfmd_inkmd/emoji.py +466 -0
  19. pdfmd_cli-3.21.5/pdfmd_inkmd/emoji_font.py +451 -0
  20. pdfmd_cli-3.21.5/pdfmd_inkmd/fonts.py +490 -0
  21. pdfmd_cli-3.21.5/pdfmd_inkmd/html_filter.py +618 -0
  22. pdfmd_cli-3.21.5/pdfmd_inkmd/image_loader.py +414 -0
  23. pdfmd_cli-3.21.5/pdfmd_inkmd/layout.py +1663 -0
  24. pdfmd_cli-3.21.5/pdfmd_inkmd/parser.py +4317 -0
  25. pdfmd_cli-3.21.5/pdfmd_inkmd/pdf.py +1065 -0
  26. pdfmd_cli-3.21.5/pdfmd_inkmd/py.typed +0 -0
  27. pdfmd_cli-3.21.5/pdfmd_inkmd/render.py +2131 -0
  28. pdfmd_cli-3.21.5/pdfmd_inkmd/truetype.py +619 -0
  29. pdfmd_cli-3.21.5/pdfmd_inkmd/url_filter.py +233 -0
  30. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/pyproject.toml +18 -1
  31. pdfmd_cli-3.21.5/tests/test_lookup.py +239 -0
  32. pdfmd_cli-3.21.5/tests/test_native.py +582 -0
  33. pdfmd_cli-3.21.5/tests/test_packaging.py +117 -0
  34. pdfmd_cli-3.21.5/tests/test_sections.py +533 -0
  35. pdfmd_cli-3.19.8/pdfmd_cli.egg-info/SOURCES.txt +0 -10
  36. pdfmd_cli-3.19.8/pdfmd_cli.egg-info/requires.txt +0 -2
  37. pdfmd_cli-3.19.8/pdfmd_cli.egg-info/top_level.txt +0 -1
  38. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/LICENSE +0 -0
  39. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/pdfmd_cli.egg-info/dependency_links.txt +0 -0
  40. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/pdfmd_cli.egg-info/entry_points.txt +0 -0
  41. {pdfmd_cli-3.19.8 → pdfmd_cli-3.21.5}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pdfmd-cli
3
- Version: 3.19.8
3
+ Version: 3.21.5
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
@@ -14,8 +14,17 @@ Classifier: Topic :: Text Processing :: Markup :: LaTeX
14
14
  Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
+ License-File: pdfmd_inkmd/LICENSE
18
+ License-File: pdfmd_inkmd/assets/fonts/DejaVuSans-LICENSE.txt
17
19
  Requires-Dist: pyyaml
18
20
  Requires-Dist: pypdf
21
+ Provides-Extra: math
22
+ Requires-Dist: pymd2pdf<0.7,>=0.6; python_version >= "3.11" and extra == "math"
23
+ Requires-Dist: matplotlib; extra == "math"
24
+ Provides-Extra: emoji
25
+ Requires-Dist: inkmd<0.6,>=0.5; extra == "emoji"
26
+ Provides-Extra: pandoc
27
+ Requires-Dist: pypandoc_binary; extra == "pandoc"
19
28
  Dynamic: license-file
20
29
 
21
30
  # pdfmd
@@ -78,9 +87,13 @@ To update later, run `pipx upgrade pdfmd-cli`. (The package is named
78
87
  The command is still `pdfmd`. For the latest unreleased code, use `pipx
79
88
  install git+https://github.com/aliperdehan/pdfmd`.)
80
89
 
81
- `pdfmd` drives programs that pip can't install, so you also need:
90
+ For the full pipeline, `pdfmd` drives programs that pip can't install, so you
91
+ also need (without them it still makes a plain PDF; see
92
+ [No Pandoc?](#no-pandoc-the-built-in-fallback) below). The quickest way, with no
93
+ admin rights, is `pdfmd --install full`, which puts Pandoc and Typst in pdfmd's own
94
+ folders; the system installers below do the same job:
82
95
 
83
- - **[Pandoc](https://pandoc.org/installing.html)** (required)
96
+ - **[Pandoc](https://pandoc.org/installing.html)**
84
97
  - **at least one PDF engine**. [Typst](https://typst.app) is the quickest
85
98
  start; a TeX distribution (MacTeX, TeX Live) gives the best results and
86
99
  is what you need for LaTeX packages and math-heavy documents.
@@ -111,7 +124,8 @@ Office files.
111
124
  <details>
112
125
  <summary>Without pipx</summary>
113
126
 
114
- `pdfmd.py` is a single file that needs Python 3.10+. It also runs
127
+ `pdfmd.py` is a single file that needs Python 3.10+ (with `pdfmd_inkmd/`
128
+ beside it for the no-Pandoc fallback). It also runs
115
129
  directly, and `pyyaml`/`pypdf` are optional (features that need them are
116
130
  skipped with a warning):
117
131
 
@@ -145,6 +159,63 @@ OK quarto (only needed for .qmd files) (/usr/local/bin/quarto)
145
159
  The numbers are the fallback order, and also shortcuts: `-e 6` means
146
160
  `-e typst`.
147
161
 
162
+ ### No Pandoc? The built-in fallback
163
+
164
+ On a machine with no Pandoc, or Pandoc but no PDF engine, `pdfmd` does not
165
+ stop: it builds a plain PDF with a pure-Python renderer that `pip` installed
166
+ with it, and says so.
167
+
168
+ ```console
169
+ $ pdfmd notes.md
170
+ NOTE Pandoc was not found: building with the built-in renderer (inkmd). The output is plain ...
171
+ NATIVE notes.md via inkmd
172
+ WARN native (inkmd): notes.md: 2 math expression(s) set as plain text (Unicode, sub/superscripts, display math centred); ...
173
+ OK notes.md
174
+ ```
175
+
176
+ - **inkmd** is built in (vendored in `pdfmd_inkmd/`, about 2 MB, standard
177
+ library only, works offline, same input gives the same bytes). It reads
178
+ GitHub-flavoured Markdown: headings, emphasis, lists, task lists, tables,
179
+ code blocks, quotes, links, images, and PNG/JPEG. It cannot typeset math,
180
+ so formulas are set as readable text instead: Greek letters and operators
181
+ as Unicode, `x^2` and `x_i` as super/subscripts, `\frac{a}{b}` as `a/b`,
182
+ and display math (`$$...$$`, `\begin{equation}`, `aligned`) as its own
183
+ centred lines. No bookmarks, no page numbers.
184
+ - **md2pdf** ([pymd2pdf](https://pypi.org/project/pymd2pdf/), ReportLab based) is
185
+ used when installed, for documents with footnotes, math or a title:
186
+ `pdfmd --install math` (same as `pip install "pdfmd-cli[math]"`; about
187
+ 150 MB, Python 3.11+, installs matplotlib so formulas render offline, centred,
188
+ as real math; the few matplotlib cannot read are set as text like inkmd's).
189
+ Footnotes, bookmarks and syntax-highlighted code come with it.
190
+ - `pdfmd --install emoji` (`pdfmd-cli[emoji]`, about 11 MB) adds the colour
191
+ emoji font; without it emoji print as `[rocket]`-style labels.
192
+ - `pdfmd --install full` leaves the fallback behind: it installs **Pandoc** (the
193
+ real binary from PyPI's `pypandoc_binary`, about 35 MB, also `--install pandoc`
194
+ / `pdfmd-cli[pandoc]`) and **Typst** (Typst's own release from GitHub, about
195
+ 15 MB, also `--install typst`, checked against the SHA-256 GitHub lists) into
196
+ pdfmd's own folders (`~/.local/share/pdfmd/bin`, `%LOCALAPPDATA%\pdfmd\bin`),
197
+ with no admin rights. A Pandoc or Typst already on your PATH always wins; to
198
+ remove them, `pip uninstall pypandoc_binary` and delete the `typst` file.
199
+
200
+ Every input is treated as GitHub-flavoured Markdown. Pandoc-only syntax is
201
+ converted where possible (`\newpage` and `<!-- pagebreak -->` become a page
202
+ break, footnotes become endnotes for inkmd, `$` prices are not mistaken for math)
203
+ and removed otherwise (heading and image attributes, `:::` divs, raw LaTeX,
204
+ `<!-- comments -->`), with one warning per kind. CSV tables
205
+ (`::: {.csv file="data.csv"}`) work as they do with Pandoc. The title, author and date in the
206
+ front matter become a title block and the PDF's own title and author; other
207
+ front-matter keys (`documentclass`, `header-includes`, `pdfmd-options`) are
208
+ listed as not used. There are no filters, preambles, citations, slides, parts or
209
+ report mode, and only Markdown input: for any of those, `pdfmd --install full`
210
+ (or `brew install pandoc typst`, `winget install JohnMacFarlane.Pandoc Typst.Typst`).
211
+
212
+ The built-in renderer is chosen automatically only when there is no Pandoc
213
+ route; a Pandoc build that fails never falls back to it. Ask for it with
214
+ `-e inkmd`, `-e md2pdf` or `-e native`, or `pdf-engine: inkmd` in `pdfmd-options`.
215
+ When it runs on a terminal and had to leave something out, `pdfmd` offers the
216
+ upgrades above (set `PDFMD_NO_PROMPT=1` to silence that; choosing "don't ask
217
+ again" remembers it).
218
+
148
219
  ## Usage
149
220
 
150
221
  Every command below can be run from inside [`examples/`](https://github.com/aliperdehan/pdfmd/tree/main/examples/).
@@ -161,6 +232,31 @@ pdfmd lecture -w # watch: rebuild on every save, until Ctrl+C
161
232
  A bare name is looked up as `<name>.md`. The name can contain dots:
162
233
  `pdfmd notes-v1.2` builds `notes-v1.2.md`.
163
234
 
235
+ If no file has exactly that name, pdfmd also looks at what each document is
236
+ called inside: its title, and any `pdfmd-options: {alias: ...}`. Case, spaces,
237
+ `_`, `-`, accents and script don't matter (`pdfmd animportantdocument` finds
238
+ `An Important Document.md`; `pdfmd glyukoza` finds a document titled
239
+ `Глюкоза`), and a unique *start* of a name or title works too, with a warning
240
+ saying what it matched (`pdfmd animp`, `pdfmd glucose`). A name that fits two
241
+ documents is an error, never a guess; `--no-auto lookup` switches the guessing
242
+ off. An exact file name always wins.
243
+
244
+ ### One section
245
+
246
+ `pdfmd doc#onlyapart` builds just the section whose heading is "Only a Part"
247
+ (down to the next heading of the same or a higher level), written as
248
+ `doc.only-a-part.pdf` beside the document. Headings are named the way files
249
+ are: case, spaces and spelling don't matter, a unique start works (with a
250
+ warning), and so does a `{#label}`. `doc##yield` asks for a level-2 heading,
251
+ `doc#results/yield` for one under another, `doc#a+b` for several, and
252
+ `pdfmd '#yield'` uses the folder's only Markdown file. `pdfmd doc --list-parts`
253
+ shows what can be named. In a document split into parts the same names work
254
+ for headings inside the parts.
255
+
256
+ Anything with a `{#label}` can be named too: `pdfmd doc#fig:setup` builds just
257
+ that figure, `doc#eq:energy` that equation, and likewise a table, a fenced div,
258
+ a code block or a span (the figure's number restarts at 1).
259
+
164
260
  ### Other output formats
165
261
 
166
262
  The format is taken from `-o`'s extension, or given explicitly with `--to`:
@@ -1,23 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: pdfmd-cli
3
- Version: 3.19.8
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
- Author: Ali Perdekhan
6
- License-Expression: MIT
7
- Project-URL: Homepage, https://github.com/aliperdehan/pdfmd
8
- Project-URL: Changelog, https://github.com/aliperdehan/pdfmd/blob/main/CHANGELOG.md
9
- Keywords: pandoc,markdown,pdf,latex,cli
10
- Classifier: Environment :: Console
11
- Classifier: Programming Language :: Python :: 3
12
- Classifier: Topic :: Text Processing :: Markup :: Markdown
13
- Classifier: Topic :: Text Processing :: Markup :: LaTeX
14
- Requires-Python: >=3.10
15
- Description-Content-Type: text/markdown
16
- License-File: LICENSE
17
- Requires-Dist: pyyaml
18
- Requires-Dist: pypdf
19
- Dynamic: license-file
20
-
21
1
  # pdfmd
22
2
 
23
3
  [![Test](https://github.com/aliperdehan/pdfmd/actions/workflows/publish.yml/badge.svg)](https://github.com/aliperdehan/pdfmd/actions/workflows/publish.yml) [![PyPI](https://img.shields.io/pypi/v/pdfmd-cli)](https://pypi.org/project/pdfmd-cli/)
@@ -78,9 +58,13 @@ To update later, run `pipx upgrade pdfmd-cli`. (The package is named
78
58
  The command is still `pdfmd`. For the latest unreleased code, use `pipx
79
59
  install git+https://github.com/aliperdehan/pdfmd`.)
80
60
 
81
- `pdfmd` drives programs that pip can't install, so you also need:
61
+ For the full pipeline, `pdfmd` drives programs that pip can't install, so you
62
+ also need (without them it still makes a plain PDF; see
63
+ [No Pandoc?](#no-pandoc-the-built-in-fallback) below). The quickest way, with no
64
+ admin rights, is `pdfmd --install full`, which puts Pandoc and Typst in pdfmd's own
65
+ folders; the system installers below do the same job:
82
66
 
83
- - **[Pandoc](https://pandoc.org/installing.html)** (required)
67
+ - **[Pandoc](https://pandoc.org/installing.html)**
84
68
  - **at least one PDF engine**. [Typst](https://typst.app) is the quickest
85
69
  start; a TeX distribution (MacTeX, TeX Live) gives the best results and
86
70
  is what you need for LaTeX packages and math-heavy documents.
@@ -111,7 +95,8 @@ Office files.
111
95
  <details>
112
96
  <summary>Without pipx</summary>
113
97
 
114
- `pdfmd.py` is a single file that needs Python 3.10+. It also runs
98
+ `pdfmd.py` is a single file that needs Python 3.10+ (with `pdfmd_inkmd/`
99
+ beside it for the no-Pandoc fallback). It also runs
115
100
  directly, and `pyyaml`/`pypdf` are optional (features that need them are
116
101
  skipped with a warning):
117
102
 
@@ -145,6 +130,63 @@ OK quarto (only needed for .qmd files) (/usr/local/bin/quarto)
145
130
  The numbers are the fallback order, and also shortcuts: `-e 6` means
146
131
  `-e typst`.
147
132
 
133
+ ### No Pandoc? The built-in fallback
134
+
135
+ On a machine with no Pandoc, or Pandoc but no PDF engine, `pdfmd` does not
136
+ stop: it builds a plain PDF with a pure-Python renderer that `pip` installed
137
+ with it, and says so.
138
+
139
+ ```console
140
+ $ pdfmd notes.md
141
+ NOTE Pandoc was not found: building with the built-in renderer (inkmd). The output is plain ...
142
+ NATIVE notes.md via inkmd
143
+ WARN native (inkmd): notes.md: 2 math expression(s) set as plain text (Unicode, sub/superscripts, display math centred); ...
144
+ OK notes.md
145
+ ```
146
+
147
+ - **inkmd** is built in (vendored in `pdfmd_inkmd/`, about 2 MB, standard
148
+ library only, works offline, same input gives the same bytes). It reads
149
+ GitHub-flavoured Markdown: headings, emphasis, lists, task lists, tables,
150
+ code blocks, quotes, links, images, and PNG/JPEG. It cannot typeset math,
151
+ so formulas are set as readable text instead: Greek letters and operators
152
+ as Unicode, `x^2` and `x_i` as super/subscripts, `\frac{a}{b}` as `a/b`,
153
+ and display math (`$$...$$`, `\begin{equation}`, `aligned`) as its own
154
+ centred lines. No bookmarks, no page numbers.
155
+ - **md2pdf** ([pymd2pdf](https://pypi.org/project/pymd2pdf/), ReportLab based) is
156
+ used when installed, for documents with footnotes, math or a title:
157
+ `pdfmd --install math` (same as `pip install "pdfmd-cli[math]"`; about
158
+ 150 MB, Python 3.11+, installs matplotlib so formulas render offline, centred,
159
+ as real math; the few matplotlib cannot read are set as text like inkmd's).
160
+ Footnotes, bookmarks and syntax-highlighted code come with it.
161
+ - `pdfmd --install emoji` (`pdfmd-cli[emoji]`, about 11 MB) adds the colour
162
+ emoji font; without it emoji print as `[rocket]`-style labels.
163
+ - `pdfmd --install full` leaves the fallback behind: it installs **Pandoc** (the
164
+ real binary from PyPI's `pypandoc_binary`, about 35 MB, also `--install pandoc`
165
+ / `pdfmd-cli[pandoc]`) and **Typst** (Typst's own release from GitHub, about
166
+ 15 MB, also `--install typst`, checked against the SHA-256 GitHub lists) into
167
+ pdfmd's own folders (`~/.local/share/pdfmd/bin`, `%LOCALAPPDATA%\pdfmd\bin`),
168
+ with no admin rights. A Pandoc or Typst already on your PATH always wins; to
169
+ remove them, `pip uninstall pypandoc_binary` and delete the `typst` file.
170
+
171
+ Every input is treated as GitHub-flavoured Markdown. Pandoc-only syntax is
172
+ converted where possible (`\newpage` and `<!-- pagebreak -->` become a page
173
+ break, footnotes become endnotes for inkmd, `$` prices are not mistaken for math)
174
+ and removed otherwise (heading and image attributes, `:::` divs, raw LaTeX,
175
+ `<!-- comments -->`), with one warning per kind. CSV tables
176
+ (`::: {.csv file="data.csv"}`) work as they do with Pandoc. The title, author and date in the
177
+ front matter become a title block and the PDF's own title and author; other
178
+ front-matter keys (`documentclass`, `header-includes`, `pdfmd-options`) are
179
+ listed as not used. There are no filters, preambles, citations, slides, parts or
180
+ report mode, and only Markdown input: for any of those, `pdfmd --install full`
181
+ (or `brew install pandoc typst`, `winget install JohnMacFarlane.Pandoc Typst.Typst`).
182
+
183
+ The built-in renderer is chosen automatically only when there is no Pandoc
184
+ route; a Pandoc build that fails never falls back to it. Ask for it with
185
+ `-e inkmd`, `-e md2pdf` or `-e native`, or `pdf-engine: inkmd` in `pdfmd-options`.
186
+ When it runs on a terminal and had to leave something out, `pdfmd` offers the
187
+ upgrades above (set `PDFMD_NO_PROMPT=1` to silence that; choosing "don't ask
188
+ again" remembers it).
189
+
148
190
  ## Usage
149
191
 
150
192
  Every command below can be run from inside [`examples/`](https://github.com/aliperdehan/pdfmd/tree/main/examples/).
@@ -161,6 +203,31 @@ pdfmd lecture -w # watch: rebuild on every save, until Ctrl+C
161
203
  A bare name is looked up as `<name>.md`. The name can contain dots:
162
204
  `pdfmd notes-v1.2` builds `notes-v1.2.md`.
163
205
 
206
+ If no file has exactly that name, pdfmd also looks at what each document is
207
+ called inside: its title, and any `pdfmd-options: {alias: ...}`. Case, spaces,
208
+ `_`, `-`, accents and script don't matter (`pdfmd animportantdocument` finds
209
+ `An Important Document.md`; `pdfmd glyukoza` finds a document titled
210
+ `Глюкоза`), and a unique *start* of a name or title works too, with a warning
211
+ saying what it matched (`pdfmd animp`, `pdfmd glucose`). A name that fits two
212
+ documents is an error, never a guess; `--no-auto lookup` switches the guessing
213
+ off. An exact file name always wins.
214
+
215
+ ### One section
216
+
217
+ `pdfmd doc#onlyapart` builds just the section whose heading is "Only a Part"
218
+ (down to the next heading of the same or a higher level), written as
219
+ `doc.only-a-part.pdf` beside the document. Headings are named the way files
220
+ are: case, spaces and spelling don't matter, a unique start works (with a
221
+ warning), and so does a `{#label}`. `doc##yield` asks for a level-2 heading,
222
+ `doc#results/yield` for one under another, `doc#a+b` for several, and
223
+ `pdfmd '#yield'` uses the folder's only Markdown file. `pdfmd doc --list-parts`
224
+ shows what can be named. In a document split into parts the same names work
225
+ for headings inside the parts.
226
+
227
+ Anything with a `{#label}` can be named too: `pdfmd doc#fig:setup` builds just
228
+ that figure, `doc#eq:energy` that equation, and likewise a table, a fenced div,
229
+ a code block or a span (the figure's number restarts at 1).
230
+
164
231
  ### Other output formats
165
232
 
166
233
  The format is taken from `-o`'s extension, or given explicitly with `--to`: