postext 1.70.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.
@@ -0,0 +1,8 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ .pytest_cache/
4
+ .mypy_cache/
5
+ .ruff_cache/
6
+ .venv/
7
+ build/
8
+ dist/
postext-1.70.5/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Postext contributors
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.
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.5
2
+ Name: postext
3
+ Version: 1.70.5
4
+ Summary: Typeset books from Python with Postext: PDF, HTML, EPUB, page images and Word from a .postext book or Markdown, through the self-contained postext command line.
5
+ Project-URL: Homepage, https://postext.dev/
6
+ Project-URL: Documentation, https://postext.dev/en/docs/command-line#python
7
+ Project-URL: Source, https://github.com/drnachio/postext/tree/main/packages/postext-python
8
+ Project-URL: Issues, https://github.com/drnachio/postext/issues
9
+ Author: Postext contributors
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: book,epub,layout,markdown,pdf,postext,typesetting
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: MacOS
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Topic :: Printing
21
+ Classifier: Topic :: Text Processing :: Markup :: Markdown
22
+ Classifier: Typing :: Typed
23
+ Requires-Python: >=3.9
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest>=7; extra == 'test'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # postext for Python
29
+
30
+ Typeset books from Python with [Postext](https://postext.dev/): a print-ready
31
+ PDF, HTML pages, an EPUB, page images or a Word document from a `.postext`
32
+ book, a book folder or loose Markdown files.
33
+
34
+ ```bash
35
+ pip install postext
36
+ ```
37
+
38
+ ```python
39
+ import postext
40
+
41
+ report = postext.pdf("book.postext", out="book.pdf", set={"page.dpi": 300})
42
+ print(report.output.pages, "pages")
43
+ for warning in report.warnings:
44
+ print(warning) # warning missingFont (chapters/02.md:14): …
45
+
46
+ pdf = postext.pdf_bytes(open("book.postext", "rb").read()) # bytes in, bytes out
47
+ ```
48
+
49
+ The package drives the self-contained `postext` command line, the same
50
+ executable as `brew install drnachio/postext/postext` or `npx postext-cli`:
51
+ the layout is the Sandbox's, and the same book breaks into the same pages.
52
+ The wheel is pure Python with no dependencies. The executable of your
53
+ system (185 to 230 MB, too large for a wheel) is downloaded on first use
54
+ from the GitHub Release of the package's version, checked against the
55
+ release's `SHA256SUMS` and kept in the cache:
56
+
57
+ | System | Executable |
58
+ | --- | --- |
59
+ | macOS, Apple silicon / Intel | `postext-macos-arm64` / `postext-macos-x64` |
60
+ | Linux x86-64 / ARM64 (glibc) | `postext-linux-x64` / `postext-linux-arm64` |
61
+ | Linux x86-64, musl (Alpine) | `postext-linux-x64-musl` |
62
+ | Windows x64 (and ARM, emulated) | `postext-windows-x64.exe` |
63
+
64
+ | Environment variable | Effect |
65
+ | --- | --- |
66
+ | `POSTEXT_BIN` | Run this executable instead (Homebrew, Scoop, a local build); nothing is downloaded |
67
+ | `POSTEXT_CACHE_DIR` | Cache folder (default `~/.cache/postext`, `%LOCALAPPDATA%\postext\cache` on Windows); executables go in `bin/<version>/`, downloaded fonts in `fonts/` |
68
+ | `POSTEXT_RELEASE_URL` | Download from a mirror: a URL with `{version}` where the release's files are |
69
+
70
+ `python -m postext pdf book.postext -o book.pdf` runs the command line
71
+ itself.
72
+
73
+ ## Commands
74
+
75
+ Every command of the command line is a function. Each runs the command with
76
+ `--json` and returns its report.
77
+
78
+ | Function | Command | Returns |
79
+ | --- | --- | --- |
80
+ | `pdf(book, out=…, pdfx=…, profile=…, color_space=…)` | `postext pdf` | `Report` |
81
+ | `html(book, out=…, mode=…, assets=…)` | `postext html` | `Report` |
82
+ | `epub(book, out=…, layout=…, cover=…)` | `postext epub` | `Report` |
83
+ | `image(book, page="#1", out=…, dpi=…, format=…)` | `postext image` | `ImageReport` |
84
+ | `images(book, out="pages/", pages=…, pattern=…)` | `postext images` | `Report` |
85
+ | `docx(book, out=…, variant=…)` | `postext docx` | `Report` |
86
+ | `import_docx(docx, book=None, out=…, dry_run=…)` | `postext import-docx` | `ImportDocxReport` |
87
+ | `pack(book, out=…)` / `unpack(bundle, out=…)` | `postext pack` / `unpack` | `Report` / `UnpackReport` |
88
+ | `info(book, pages=True)` | `postext info` | `InfoReport` |
89
+ | `check(book, strict=True)` | `postext check` | `CheckReport` |
90
+ | `build(book, pdf=…, html=…, epub=…, images=…, docx=…)` | `postext build` | `Report` |
91
+
92
+ `book` is a path (a `.postext` file, a book folder, a Markdown file), a list
93
+ of Markdown files (the chapters, in order), or the bytes of a `.postext`
94
+ bundle. The commands that read a book take the book options:
95
+
96
+ ```python
97
+ postext.pdf(
98
+ ["01.md", "02.md"],
99
+ out="notes.pdf",
100
+ name="Notes", # --name
101
+ config={"page": {"sizePreset": "A5"}}, # --config (a dict or a file)
102
+ set={"bodyText.fontSize.value": 11}, # --set, one per key
103
+ locale="es", # --locale
104
+ chapters=range(1, 3), # --chapters 1-2 (also 3, "1,3-5", [1, 3])
105
+ resources="img/", fonts="fonts/", # --resources, --fonts
106
+ font_dirs=["~/Fonts"], # --font-dir
107
+ offline=True, # --offline: never download fonts
108
+ )
109
+ ```
110
+
111
+ ### Reports and warnings
112
+
113
+ A `Report` has `ok`, `command`, `version`, `exit_code`, `pages`, `book`
114
+ (name, id, locale, chapters), `outputs` (`Output`: kind, path, size,
115
+ pages), `warnings` (`Diagnostic`: kind, message, severity, at, page, data),
116
+ `timings` and `raw`, the whole JSON object. `InfoReport` adds `chapters`,
117
+ `resources` and `fonts`; `CheckReport` adds `passed`, `error_count`,
118
+ `warning_count`, `contrast`, `reflow` and `preflight`.
119
+
120
+ ### Bytes out
121
+
122
+ `out="-"` (or `postext.STDOUT`) writes to stdout and returns the bytes in
123
+ `report.content`; `pdf_bytes`, `html_bytes`, `epub_bytes`, `image_bytes`,
124
+ `docx_bytes` and `pack_bytes` return them directly. A book given as bytes
125
+ with no `out` comes back as bytes.
126
+
127
+ ### Errors
128
+
129
+ | Exception | When |
130
+ | --- | --- |
131
+ | `PostextError` | The command failed (exit code 1); `err.report` and `err.stderr` say why |
132
+ | `UsageError` | A wrong option or value (exit code 2) |
133
+ | `ProblemsFound` | `check` found an error (any warning with `strict`), or `import_docx` could not apply an edit (exit code 3); `raise_on_problems=False` returns the report instead |
134
+ | `BinaryNotFound` | No executable for this system, a failed download or checksum, or a `POSTEXT_BIN` that is not a file |
135
+
136
+ ### One executable, many runs
137
+
138
+ `postext.Postext(binary=None, cwd=None, env=None, timeout=None, offline=None, font_dirs=None)`
139
+ has the same methods with its own executable, folder, environment and
140
+ timeout. `Postext().run(["build", "book/", "--pdf", "b.pdf", "--watch"], capture=False)`
141
+ runs any command as typed.
142
+
143
+ Each call starts the executable again. A mode that keeps one engine
144
+ running between calls is planned.
145
+
146
+ ## Docs
147
+
148
+ - Command line: https://postext.dev/en/docs/command-line#python
149
+ - Source: https://github.com/drnachio/postext/tree/main/packages/postext-python
150
+
151
+ MIT licence.
@@ -0,0 +1,124 @@
1
+ # postext for Python
2
+
3
+ Typeset books from Python with [Postext](https://postext.dev/): a print-ready
4
+ PDF, HTML pages, an EPUB, page images or a Word document from a `.postext`
5
+ book, a book folder or loose Markdown files.
6
+
7
+ ```bash
8
+ pip install postext
9
+ ```
10
+
11
+ ```python
12
+ import postext
13
+
14
+ report = postext.pdf("book.postext", out="book.pdf", set={"page.dpi": 300})
15
+ print(report.output.pages, "pages")
16
+ for warning in report.warnings:
17
+ print(warning) # warning missingFont (chapters/02.md:14): …
18
+
19
+ pdf = postext.pdf_bytes(open("book.postext", "rb").read()) # bytes in, bytes out
20
+ ```
21
+
22
+ The package drives the self-contained `postext` command line, the same
23
+ executable as `brew install drnachio/postext/postext` or `npx postext-cli`:
24
+ the layout is the Sandbox's, and the same book breaks into the same pages.
25
+ The wheel is pure Python with no dependencies. The executable of your
26
+ system (185 to 230 MB, too large for a wheel) is downloaded on first use
27
+ from the GitHub Release of the package's version, checked against the
28
+ release's `SHA256SUMS` and kept in the cache:
29
+
30
+ | System | Executable |
31
+ | --- | --- |
32
+ | macOS, Apple silicon / Intel | `postext-macos-arm64` / `postext-macos-x64` |
33
+ | Linux x86-64 / ARM64 (glibc) | `postext-linux-x64` / `postext-linux-arm64` |
34
+ | Linux x86-64, musl (Alpine) | `postext-linux-x64-musl` |
35
+ | Windows x64 (and ARM, emulated) | `postext-windows-x64.exe` |
36
+
37
+ | Environment variable | Effect |
38
+ | --- | --- |
39
+ | `POSTEXT_BIN` | Run this executable instead (Homebrew, Scoop, a local build); nothing is downloaded |
40
+ | `POSTEXT_CACHE_DIR` | Cache folder (default `~/.cache/postext`, `%LOCALAPPDATA%\postext\cache` on Windows); executables go in `bin/<version>/`, downloaded fonts in `fonts/` |
41
+ | `POSTEXT_RELEASE_URL` | Download from a mirror: a URL with `{version}` where the release's files are |
42
+
43
+ `python -m postext pdf book.postext -o book.pdf` runs the command line
44
+ itself.
45
+
46
+ ## Commands
47
+
48
+ Every command of the command line is a function. Each runs the command with
49
+ `--json` and returns its report.
50
+
51
+ | Function | Command | Returns |
52
+ | --- | --- | --- |
53
+ | `pdf(book, out=…, pdfx=…, profile=…, color_space=…)` | `postext pdf` | `Report` |
54
+ | `html(book, out=…, mode=…, assets=…)` | `postext html` | `Report` |
55
+ | `epub(book, out=…, layout=…, cover=…)` | `postext epub` | `Report` |
56
+ | `image(book, page="#1", out=…, dpi=…, format=…)` | `postext image` | `ImageReport` |
57
+ | `images(book, out="pages/", pages=…, pattern=…)` | `postext images` | `Report` |
58
+ | `docx(book, out=…, variant=…)` | `postext docx` | `Report` |
59
+ | `import_docx(docx, book=None, out=…, dry_run=…)` | `postext import-docx` | `ImportDocxReport` |
60
+ | `pack(book, out=…)` / `unpack(bundle, out=…)` | `postext pack` / `unpack` | `Report` / `UnpackReport` |
61
+ | `info(book, pages=True)` | `postext info` | `InfoReport` |
62
+ | `check(book, strict=True)` | `postext check` | `CheckReport` |
63
+ | `build(book, pdf=…, html=…, epub=…, images=…, docx=…)` | `postext build` | `Report` |
64
+
65
+ `book` is a path (a `.postext` file, a book folder, a Markdown file), a list
66
+ of Markdown files (the chapters, in order), or the bytes of a `.postext`
67
+ bundle. The commands that read a book take the book options:
68
+
69
+ ```python
70
+ postext.pdf(
71
+ ["01.md", "02.md"],
72
+ out="notes.pdf",
73
+ name="Notes", # --name
74
+ config={"page": {"sizePreset": "A5"}}, # --config (a dict or a file)
75
+ set={"bodyText.fontSize.value": 11}, # --set, one per key
76
+ locale="es", # --locale
77
+ chapters=range(1, 3), # --chapters 1-2 (also 3, "1,3-5", [1, 3])
78
+ resources="img/", fonts="fonts/", # --resources, --fonts
79
+ font_dirs=["~/Fonts"], # --font-dir
80
+ offline=True, # --offline: never download fonts
81
+ )
82
+ ```
83
+
84
+ ### Reports and warnings
85
+
86
+ A `Report` has `ok`, `command`, `version`, `exit_code`, `pages`, `book`
87
+ (name, id, locale, chapters), `outputs` (`Output`: kind, path, size,
88
+ pages), `warnings` (`Diagnostic`: kind, message, severity, at, page, data),
89
+ `timings` and `raw`, the whole JSON object. `InfoReport` adds `chapters`,
90
+ `resources` and `fonts`; `CheckReport` adds `passed`, `error_count`,
91
+ `warning_count`, `contrast`, `reflow` and `preflight`.
92
+
93
+ ### Bytes out
94
+
95
+ `out="-"` (or `postext.STDOUT`) writes to stdout and returns the bytes in
96
+ `report.content`; `pdf_bytes`, `html_bytes`, `epub_bytes`, `image_bytes`,
97
+ `docx_bytes` and `pack_bytes` return them directly. A book given as bytes
98
+ with no `out` comes back as bytes.
99
+
100
+ ### Errors
101
+
102
+ | Exception | When |
103
+ | --- | --- |
104
+ | `PostextError` | The command failed (exit code 1); `err.report` and `err.stderr` say why |
105
+ | `UsageError` | A wrong option or value (exit code 2) |
106
+ | `ProblemsFound` | `check` found an error (any warning with `strict`), or `import_docx` could not apply an edit (exit code 3); `raise_on_problems=False` returns the report instead |
107
+ | `BinaryNotFound` | No executable for this system, a failed download or checksum, or a `POSTEXT_BIN` that is not a file |
108
+
109
+ ### One executable, many runs
110
+
111
+ `postext.Postext(binary=None, cwd=None, env=None, timeout=None, offline=None, font_dirs=None)`
112
+ has the same methods with its own executable, folder, environment and
113
+ timeout. `Postext().run(["build", "book/", "--pdf", "b.pdf", "--watch"], capture=False)`
114
+ runs any command as typed.
115
+
116
+ Each call starts the executable again. A mode that keeps one engine
117
+ running between calls is planned.
118
+
119
+ ## Docs
120
+
121
+ - Command line: https://postext.dev/en/docs/command-line#python
122
+ - Source: https://github.com/drnachio/postext/tree/main/packages/postext-python
123
+
124
+ MIT licence.
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.26"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "postext"
7
+ dynamic = ["version"]
8
+ description = "Typeset books from Python with Postext: PDF, HTML, EPUB, page images and Word from a .postext book or Markdown, through the self-contained postext command line."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.9"
13
+ authors = [{ name = "Postext contributors" }]
14
+ keywords = ["postext", "typesetting", "pdf", "epub", "markdown", "book", "layout"]
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: MacOS",
19
+ "Operating System :: Microsoft :: Windows",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Topic :: Printing",
24
+ "Topic :: Text Processing :: Markup :: Markdown",
25
+ "Typing :: Typed",
26
+ ]
27
+ dependencies = []
28
+
29
+ [project.optional-dependencies]
30
+ test = ["pytest>=7"]
31
+
32
+ [project.urls]
33
+ Homepage = "https://postext.dev/"
34
+ Documentation = "https://postext.dev/en/docs/command-line#python"
35
+ Source = "https://github.com/drnachio/postext/tree/main/packages/postext-python"
36
+ Issues = "https://github.com/drnachio/postext/issues"
37
+
38
+ [tool.hatch.version]
39
+ path = "src/postext/_version.py"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/postext"]
43
+
44
+ [tool.hatch.build.targets.sdist]
45
+ include = ["src/postext", "tests", "README.md", "LICENSE", "pyproject.toml"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
49
+
50
+ [tool.ruff]
51
+ line-length = 140
52
+ target-version = "py39"
53
+
54
+ [tool.ruff.lint]
55
+ select = ["F", "E9", "B"]
@@ -0,0 +1,123 @@
1
+ """Postext from Python.
2
+
3
+ Typesets books with the self-contained ``postext`` command line: PDF, HTML,
4
+ EPUB, page images and Word from a ``.postext`` book, a book folder or loose
5
+ Markdown. The executable of this system is downloaded from the GitHub
6
+ Release of this package's version on first use, checked against its SHA256
7
+ and cached; ``POSTEXT_BIN`` points at one already installed.
8
+
9
+ import postext
10
+
11
+ report = postext.pdf("book.postext", out="book.pdf", set={"page.dpi": 300})
12
+ print(report.output.pages, [str(w) for w in report.warnings])
13
+
14
+ pdf = postext.pdf_bytes(open("book.postext", "rb").read())
15
+
16
+ Every function runs the command with ``--json`` and returns its report
17
+ (:class:`Report` and kin). A failure raises :class:`PostextError`
18
+ (:class:`UsageError` for a wrong call, :class:`ProblemsFound` when ``check``
19
+ finds problems). :class:`Postext` runs a given executable, in a given folder
20
+ or with a timeout.
21
+ """
22
+
23
+ from ._binary import cache_dir, cached_binary, download_binary, find_binary, platform_file
24
+ from ._client import STDOUT, BookInput, Books, Postext
25
+ from ._errors import BinaryNotFound, PostextError, ProblemsFound, UsageError
26
+ from ._report import (
27
+ BookSummary,
28
+ ChapterInfo,
29
+ CheckReport,
30
+ Diagnostic,
31
+ FontInfo,
32
+ ImageReport,
33
+ ImportDocxReport,
34
+ InfoReport,
35
+ Output,
36
+ PageRef,
37
+ Report,
38
+ UnpackReport,
39
+ )
40
+ from ._version import __version__
41
+
42
+ _default = Postext()
43
+
44
+ pdf = _default.pdf
45
+ html = _default.html
46
+ epub = _default.epub
47
+ image = _default.image
48
+ images = _default.images
49
+ docx = _default.docx
50
+ import_docx = _default.import_docx
51
+ pack = _default.pack
52
+ unpack = _default.unpack
53
+ info = _default.info
54
+ check = _default.check
55
+ build = _default.build
56
+
57
+ pdf_bytes = _default.pdf_bytes
58
+ html_bytes = _default.html_bytes
59
+ epub_bytes = _default.epub_bytes
60
+ image_bytes = _default.image_bytes
61
+ docx_bytes = _default.docx_bytes
62
+ pack_bytes = _default.pack_bytes
63
+
64
+ run = _default.run
65
+
66
+
67
+ def binary() -> str:
68
+ """The path of the executable the functions run (downloaded on first call)."""
69
+ return str(find_binary())
70
+
71
+
72
+ __all__ = [
73
+ "__version__",
74
+ "Postext",
75
+ "STDOUT",
76
+ "BookInput",
77
+ "Books",
78
+ # commands
79
+ "pdf",
80
+ "html",
81
+ "epub",
82
+ "image",
83
+ "images",
84
+ "docx",
85
+ "import_docx",
86
+ "pack",
87
+ "unpack",
88
+ "info",
89
+ "check",
90
+ "build",
91
+ "pdf_bytes",
92
+ "html_bytes",
93
+ "epub_bytes",
94
+ "image_bytes",
95
+ "docx_bytes",
96
+ "pack_bytes",
97
+ "run",
98
+ # executable
99
+ "binary",
100
+ "find_binary",
101
+ "download_binary",
102
+ "platform_file",
103
+ "cache_dir",
104
+ "cached_binary",
105
+ # reports
106
+ "Report",
107
+ "InfoReport",
108
+ "CheckReport",
109
+ "ImageReport",
110
+ "ImportDocxReport",
111
+ "UnpackReport",
112
+ "Output",
113
+ "Diagnostic",
114
+ "BookSummary",
115
+ "ChapterInfo",
116
+ "FontInfo",
117
+ "PageRef",
118
+ # errors
119
+ "PostextError",
120
+ "UsageError",
121
+ "ProblemsFound",
122
+ "BinaryNotFound",
123
+ ]
@@ -0,0 +1,8 @@
1
+ """``python -m postext pdf book.postext -o book.pdf``: the command line itself,
2
+ downloaded on first use like the functions'."""
3
+
4
+ import sys
5
+
6
+ from ._client import _main
7
+
8
+ sys.exit(_main())