pytex-preprocessor 0.4.6__tar.gz → 1.0.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.
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/PKG-INFO +79 -14
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/README.md +78 -13
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/pyproject.toml +7 -3
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/builtin.py +1 -1
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/font.py +22 -18
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/lengths.py +20 -2
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/control_sequence.py +0 -2
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/image.py +4 -1
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/package.py +0 -2
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/template.py +8 -7
- pytex_preprocessor-1.0.0/src/pytex_api/__init__.py +197 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_compile.py +279 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_models.py +125 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_policy.py +186 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_render.py +86 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_sandbox.py +442 -0
- pytex_preprocessor-1.0.0/src/pytex_api/_security.py +184 -0
- pytex_preprocessor-1.0.0/src/pytex_api/sandbox_init.py +198 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/build.py +133 -2
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/render.py +36 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/tectonic.py +43 -5
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/variants.py +41 -10
- pytex_preprocessor-1.0.0/src/pytex_components/__init__.py +58 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/boxes.py +14 -5
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/watermark.py +1 -1
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/__init__.py +28 -26
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/document.py +19 -9
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/listings.py +9 -9
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/logos.py +24 -7
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/tex/pagesetup.tex +11 -1
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/titlepage.py +20 -10
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/convert.py +22 -26
- pytex_preprocessor-1.0.0/src/pytex_markdown/glyphs.py +257 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/convert.py +6 -6
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/entries.py +2 -2
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/header.py +1 -1
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/shortcodes.py +6 -5
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/PKG-INFO +79 -14
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/SOURCES.txt +17 -7
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/entry_points.txt +1 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/top_level.txt +2 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/LICENSE +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/setup.cfg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/biblatex.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/captions.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/cleveref.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/colors.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/conditionals.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/counters.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/definitions.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/floats.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/fontawesome.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/fontspec.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/geometry.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/glossaries.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/graphics.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/hooks.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/hyperref.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/listings.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/mdframed.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/picture.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/setspace.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/commands/tables.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/helpers/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/helpers/coerce.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/helpers/parenting.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/helpers/sanitize.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/helpers/with_package.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/interface/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/interface/control_sequence.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/interface/package.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/interface/tex.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/color.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/comment.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/concat.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/document.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/document_class.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/empty.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/environment.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/include.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/length.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/math.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/model/raw.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/packages.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex/registry.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_analyze/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_analyze/analyze.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_analyze/optimize.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/console.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/tex2py.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_builder/tree.py +0 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/citations.py +0 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/cleveref_names.py +0 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/pagebreak.py +0 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/voting.py +0 -0
- {pytex_preprocessor-0.4.6/src/pytex_hsrtreport → pytex_preprocessor-1.0.0/src/pytex_components}/wordcount.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Bold.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-BoldItalic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Book.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-BookItalic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Medium.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-MediumItalic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Strong.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Thin.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-ThinItalic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Black.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Bold.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-BoldItalic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Italic.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Medium.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Regular.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/fonts/Times New Roman.ttf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/ASTA.svg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/DUMMY.png +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/DUMMY_FOOT.png +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/ECHO.svg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/HSRT.pdf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/INF.pdf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/MAKERS-Icon.svg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/MAKERS-RAlign.svg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/MAKERS.svg +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/STUPA.pdf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/assets/logos/Skyline.pdf +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/colors.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/fonts.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/glossary.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/hyperref_config.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/pagesetup.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_hsrtreport/variants.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_koma/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_koma/commands.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_koma/document.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/escape.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/frontmatter.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/document.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_markdown/protocol/signatures.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/dependency_links.txt +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_preprocessor.egg-info/requires.txt +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_protocol/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_protocol/frontmatter.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_tikz/__init__.py +0 -0
- {pytex_preprocessor-0.4.6 → pytex_preprocessor-1.0.0}/src/pytex_tikz/tikz.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytex-preprocessor
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Type-safe LaTeX document generation with Python
|
|
5
5
|
Author-email: Frederik Beimgraben <frederik@beimgraben.net>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -821,13 +821,40 @@ Plain Python works too: $3^2 = \iffalse{pytex(3 ** 2)}\fi$.
|
|
|
821
821
|
| `--no-shell-escape` | shell-escape on | disable shell-escape |
|
|
822
822
|
| `-t`, `--tree` | off | also print the input's `TeX`-node tree (`tree`-style) before rendering/building |
|
|
823
823
|
| `-f`, `--force` | off | skip the optimize + analysis pass and build even if problems are found |
|
|
824
|
-
| `--variant STYLE` | auto-detect | Markdown output style (`plain`, `report`, `protocol-asta`, `protocol-stupa`) |
|
|
824
|
+
| `--variant STYLE` | auto-detect | Markdown output style (`plain`, `report`, `report-makers`, `protocol-asta`, `protocol-stupa`) |
|
|
825
825
|
| `--config JSON` | none | JSON object of document-class params, merged over the frontmatter |
|
|
826
|
+
| `--untrusted` | off (trusted) | render foreign input through the trust policy (see [Security](#security-and-trust)) |
|
|
827
|
+
| `--trust-level LEVEL` | `trusted` | `trusted`, `sandboxed`, or `untrusted` (see [Security](#security-and-trust)) |
|
|
826
828
|
|
|
827
829
|
Shell-escape is on by default because inline images decode their base64
|
|
828
830
|
payloads at compile time. The build runs tectonic, then `makeindex` (for
|
|
829
831
|
`glossaries`/acronyms), then reruns tectonic when an index changed.
|
|
830
832
|
|
|
833
|
+
### Security and trust
|
|
834
|
+
|
|
835
|
+
By default the CLI runs in a **trusted** context: it imports and executes `.py`
|
|
836
|
+
inputs, evaluates `.tex` `pytex(...)` replacements and Markdown `eval`
|
|
837
|
+
comments, and enables shell-escape. That is code execution by design — it is
|
|
838
|
+
how PyTeX documents work — and is safe **only for documents you wrote
|
|
839
|
+
yourself**. Do not run the default CLI on a file from a source you do not
|
|
840
|
+
trust.
|
|
841
|
+
|
|
842
|
+
To render input from a foreign or untrusted source, pass `--untrusted` (or
|
|
843
|
+
`--trust-level {sandboxed,untrusted}`). These route the build through the
|
|
844
|
+
`pytex_api` trust policy, which:
|
|
845
|
+
|
|
846
|
+
- refuses `.py` / `.tex.py` inputs (no Python execution),
|
|
847
|
+
- leaves `.tex` `pytex(...)` markers and Markdown `eval` comments inert,
|
|
848
|
+
- forces shell-escape **off** and rejects code-/file-surface packages
|
|
849
|
+
(`minted`, `shellesc`, `pythontex`, …) and anything off the package
|
|
850
|
+
allowlist,
|
|
851
|
+
- applies CPU/memory/output resource limits, and
|
|
852
|
+
- for `sandboxed`, additionally requires the Podman OS sandbox for PDF builds.
|
|
853
|
+
|
|
854
|
+
`--untrusted` is shorthand for `--trust-level untrusted`. The two flags are
|
|
855
|
+
mutually exclusive; `trusted` is the default, so existing invocations are
|
|
856
|
+
unchanged.
|
|
857
|
+
|
|
831
858
|
Output is minimal and color-tagged (`==>`, `note:`, `warning:`, `error:`),
|
|
832
859
|
following tectonic's style; on failure it points at the likely cause and the
|
|
833
860
|
log file. Set `NO_COLOR` to disable color.
|
|
@@ -877,10 +904,11 @@ Document (article)
|
|
|
877
904
|
| `pytex` | core node model, `Document`, math, tables, graphics, and factories for the common LaTeX packages (biblatex, cleveref, glossaries, hyperref, listings, ...). |
|
|
878
905
|
| `pytex_koma` | KOMA-Script classes and commands (`Addchap`, `Minisec`, `KOMAoptions`, ...). |
|
|
879
906
|
| `pytex_tikz` | TikZ pictures and primitives (`TikzPicture`, `Draw`, `Node`, `Circle`, ...). |
|
|
880
|
-
| `
|
|
907
|
+
| `pytex_components` | reusable, template-agnostic widgets: colored callout boxes (`ColoredBox` + presets), a voting tally, draft watermark, word-count and smart-pagebreak macros, a clickable author-year citation, German cleveref labels. |
|
|
908
|
+
| `pytex_markdown` | Markdown -> native `TeX` conversion (see below), including `pytex_markdown.protocol` (STUPA/AStA meeting minutes) and `pytex_markdown.frontmatter` (YAML frontmatter parsing). |
|
|
881
909
|
| `pytex_analyze` | static checks over the node tree (dangling refs, duplicate labels, missing images), plus `Optimize` to simplify a tree render-equivalently. |
|
|
882
|
-
| `pytex_hsrtreport` | HSRT report document class,
|
|
883
|
-
| `pytex_protocol` |
|
|
910
|
+
| `pytex_hsrtreport` | HSRT report document class, title pages, logos, and HSRT colors/fonts/glossary helpers. Builds on `pytex_components` (and re-exports it for compatibility). |
|
|
911
|
+
| `pytex_protocol` | deprecated alias for `pytex_markdown.protocol` (kept as a re-export shim). |
|
|
884
912
|
|
|
885
913
|
## Markdown
|
|
886
914
|
|
|
@@ -893,15 +921,23 @@ body = Markdown("# Title\n\nText with **bold**, `code`, [a link](https://x).")
|
|
|
893
921
|
body = IncludeMarkdown("notes.md", base_level=-1) # base_level=-1: # -> \chapter
|
|
894
922
|
```
|
|
895
923
|
|
|
896
|
-
Headings, emphasis, inline/fenced code, lists, links, images,
|
|
897
|
-
thematic breaks map to the standard pytex library; text is
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
```md
|
|
902
|
-
> [!NOTE] -> InfoBox > [!IMPORTANT] -> ImportantBox
|
|
903
|
-
> [!TIP] -> SuccessBox > [!WARNING] -> WarningBox
|
|
904
|
-
```
|
|
924
|
+
Headings, emphasis, inline/fenced code, lists, links, images, GFM tables, block
|
|
925
|
+
quotes and thematic breaks map to the standard pytex library; text is
|
|
926
|
+
LaTeX-escaped. Some extras on top of plain Markdown:
|
|
927
|
+
|
|
928
|
+
- **GitHub-style callouts** become colored boxes (from `pytex_components`):
|
|
929
|
+
```md
|
|
930
|
+
> [!NOTE] -> InfoBox > [!IMPORTANT] -> ImportantBox
|
|
931
|
+
> [!TIP] -> SuccessBox > [!WARNING] -> WarningBox
|
|
932
|
+
```
|
|
933
|
+
- **Citations** in Pandoc syntax: `[@key]` / `[@key, p. 5]` -> `\autocite`,
|
|
934
|
+
`[@a; @b]` -> a combined cite, and a narrative `@key` -> `\textcite`.
|
|
935
|
+
- **Bibliography** from frontmatter — `bibliography:` is either inline BibTeX (a
|
|
936
|
+
`|` block scalar) or a path to a `.bib` file; reports print a numbered
|
|
937
|
+
`\printbibliography`.
|
|
938
|
+
- ASCII **math arrows** (`->`, `=>`, `<->`, ...) become inline math arrows, the
|
|
939
|
+
**euro sign** `€` becomes a font-independent `\euro{}`, and tables get a bit of
|
|
940
|
+
vertical breathing room.
|
|
905
941
|
|
|
906
942
|
Both factories are registered, so they work in `\iffalse{pytex(...)}\fi`
|
|
907
943
|
replacements in `.tex` sources too.
|
|
@@ -915,6 +951,7 @@ document chosen by `--variant`:
|
|
|
915
951
|
| --- | --- |
|
|
916
952
|
| `plain` | a bare `Document` (default class `article`); `#` -> `\section`. |
|
|
917
953
|
| `report` | an HSRT report with title page and table of contents; `#` -> `\chapter`. |
|
|
954
|
+
| `report-makers` | a `report` branded with the MAKERS logo (title page + footer). |
|
|
918
955
|
| `protocol-asta` | an AStA meeting protocol (HSRT report, AStA logos). |
|
|
919
956
|
| `protocol-stupa` | a StuPa meeting protocol (HSRT report, StuPa logos). |
|
|
920
957
|
|
|
@@ -933,6 +970,13 @@ object. For styles with a title page (`report`), the title is taken from
|
|
|
933
970
|
`title:`/`--config` if given, otherwise from the first `#` heading (which is then
|
|
934
971
|
not also rendered as a chapter).
|
|
935
972
|
|
|
973
|
+
The report styles read further frontmatter keys: `author`, `abstract`,
|
|
974
|
+
`keywords`, title-page `datalines` (a list of `"Label: value"` entries),
|
|
975
|
+
`bibliography` (see [Markdown](#markdown)), `logos` (title-page logos — vendored
|
|
976
|
+
names like `INF`/`MAKERS` and/or paths to custom image files), and the labels
|
|
977
|
+
`abstract_heading` / `keywords_heading` to rename the default "Abstract" /
|
|
978
|
+
"Keywords" sections.
|
|
979
|
+
|
|
936
980
|
## Converting LaTeX to PyTeX
|
|
937
981
|
|
|
938
982
|
`pytex-tex2py` turns an existing `.tex` file into an equivalent `.tex.py`
|
|
@@ -961,6 +1005,27 @@ pytex examples/replacements.py.tex --build
|
|
|
961
1005
|
pytex examples/notes.md --build
|
|
962
1006
|
```
|
|
963
1007
|
|
|
1008
|
+
## Stability
|
|
1009
|
+
|
|
1010
|
+
From 1.0 the project follows [Semantic Versioning](https://semver.org). The
|
|
1011
|
+
public API is what each package exports through its top-level `__all__`:
|
|
1012
|
+
everything reachable as `from pytex import X` (and the same for `pytex_koma`,
|
|
1013
|
+
`pytex_tikz`, `pytex_components`, `pytex_markdown`, `pytex_analyze`,
|
|
1014
|
+
`pytex_hsrtreport`). Breaking those names needs a major version bump.
|
|
1015
|
+
|
|
1016
|
+
Also part of the contract: the registry keys exposed to `\iffalse{pytex(...)}\fi`
|
|
1017
|
+
markers — they are the factory names, so renaming a registered factory is a
|
|
1018
|
+
breaking change (which is why the `\fill` length is `Fill_len`, leaving the bare
|
|
1019
|
+
`Fill` key to the TikZ path command).
|
|
1020
|
+
|
|
1021
|
+
Internal and not covered by the guarantee: any name with a leading underscore,
|
|
1022
|
+
modules whose name starts with an underscore (e.g. `pytex_api._policy`,
|
|
1023
|
+
`pytex_api._compile`), and anything not listed in a package's `__all__`. Import
|
|
1024
|
+
those at your own risk.
|
|
1025
|
+
|
|
1026
|
+
Deprecated shims (`pytex_protocol`, the `pytex.commands.lengths.Fill` alias) keep
|
|
1027
|
+
working with a `DeprecationWarning` and may be removed in the next major release.
|
|
1028
|
+
|
|
964
1029
|
## License
|
|
965
1030
|
|
|
966
1031
|
GNU General Public License v3.0 or later (GPL-3.0-or-later). See
|
|
@@ -129,13 +129,40 @@ Plain Python works too: $3^2 = \iffalse{pytex(3 ** 2)}\fi$.
|
|
|
129
129
|
| `--no-shell-escape` | shell-escape on | disable shell-escape |
|
|
130
130
|
| `-t`, `--tree` | off | also print the input's `TeX`-node tree (`tree`-style) before rendering/building |
|
|
131
131
|
| `-f`, `--force` | off | skip the optimize + analysis pass and build even if problems are found |
|
|
132
|
-
| `--variant STYLE` | auto-detect | Markdown output style (`plain`, `report`, `protocol-asta`, `protocol-stupa`) |
|
|
132
|
+
| `--variant STYLE` | auto-detect | Markdown output style (`plain`, `report`, `report-makers`, `protocol-asta`, `protocol-stupa`) |
|
|
133
133
|
| `--config JSON` | none | JSON object of document-class params, merged over the frontmatter |
|
|
134
|
+
| `--untrusted` | off (trusted) | render foreign input through the trust policy (see [Security](#security-and-trust)) |
|
|
135
|
+
| `--trust-level LEVEL` | `trusted` | `trusted`, `sandboxed`, or `untrusted` (see [Security](#security-and-trust)) |
|
|
134
136
|
|
|
135
137
|
Shell-escape is on by default because inline images decode their base64
|
|
136
138
|
payloads at compile time. The build runs tectonic, then `makeindex` (for
|
|
137
139
|
`glossaries`/acronyms), then reruns tectonic when an index changed.
|
|
138
140
|
|
|
141
|
+
### Security and trust
|
|
142
|
+
|
|
143
|
+
By default the CLI runs in a **trusted** context: it imports and executes `.py`
|
|
144
|
+
inputs, evaluates `.tex` `pytex(...)` replacements and Markdown `eval`
|
|
145
|
+
comments, and enables shell-escape. That is code execution by design — it is
|
|
146
|
+
how PyTeX documents work — and is safe **only for documents you wrote
|
|
147
|
+
yourself**. Do not run the default CLI on a file from a source you do not
|
|
148
|
+
trust.
|
|
149
|
+
|
|
150
|
+
To render input from a foreign or untrusted source, pass `--untrusted` (or
|
|
151
|
+
`--trust-level {sandboxed,untrusted}`). These route the build through the
|
|
152
|
+
`pytex_api` trust policy, which:
|
|
153
|
+
|
|
154
|
+
- refuses `.py` / `.tex.py` inputs (no Python execution),
|
|
155
|
+
- leaves `.tex` `pytex(...)` markers and Markdown `eval` comments inert,
|
|
156
|
+
- forces shell-escape **off** and rejects code-/file-surface packages
|
|
157
|
+
(`minted`, `shellesc`, `pythontex`, …) and anything off the package
|
|
158
|
+
allowlist,
|
|
159
|
+
- applies CPU/memory/output resource limits, and
|
|
160
|
+
- for `sandboxed`, additionally requires the Podman OS sandbox for PDF builds.
|
|
161
|
+
|
|
162
|
+
`--untrusted` is shorthand for `--trust-level untrusted`. The two flags are
|
|
163
|
+
mutually exclusive; `trusted` is the default, so existing invocations are
|
|
164
|
+
unchanged.
|
|
165
|
+
|
|
139
166
|
Output is minimal and color-tagged (`==>`, `note:`, `warning:`, `error:`),
|
|
140
167
|
following tectonic's style; on failure it points at the likely cause and the
|
|
141
168
|
log file. Set `NO_COLOR` to disable color.
|
|
@@ -185,10 +212,11 @@ Document (article)
|
|
|
185
212
|
| `pytex` | core node model, `Document`, math, tables, graphics, and factories for the common LaTeX packages (biblatex, cleveref, glossaries, hyperref, listings, ...). |
|
|
186
213
|
| `pytex_koma` | KOMA-Script classes and commands (`Addchap`, `Minisec`, `KOMAoptions`, ...). |
|
|
187
214
|
| `pytex_tikz` | TikZ pictures and primitives (`TikzPicture`, `Draw`, `Node`, `Circle`, ...). |
|
|
188
|
-
| `
|
|
215
|
+
| `pytex_components` | reusable, template-agnostic widgets: colored callout boxes (`ColoredBox` + presets), a voting tally, draft watermark, word-count and smart-pagebreak macros, a clickable author-year citation, German cleveref labels. |
|
|
216
|
+
| `pytex_markdown` | Markdown -> native `TeX` conversion (see below), including `pytex_markdown.protocol` (STUPA/AStA meeting minutes) and `pytex_markdown.frontmatter` (YAML frontmatter parsing). |
|
|
189
217
|
| `pytex_analyze` | static checks over the node tree (dangling refs, duplicate labels, missing images), plus `Optimize` to simplify a tree render-equivalently. |
|
|
190
|
-
| `pytex_hsrtreport` | HSRT report document class,
|
|
191
|
-
| `pytex_protocol` |
|
|
218
|
+
| `pytex_hsrtreport` | HSRT report document class, title pages, logos, and HSRT colors/fonts/glossary helpers. Builds on `pytex_components` (and re-exports it for compatibility). |
|
|
219
|
+
| `pytex_protocol` | deprecated alias for `pytex_markdown.protocol` (kept as a re-export shim). |
|
|
192
220
|
|
|
193
221
|
## Markdown
|
|
194
222
|
|
|
@@ -201,15 +229,23 @@ body = Markdown("# Title\n\nText with **bold**, `code`, [a link](https://x).")
|
|
|
201
229
|
body = IncludeMarkdown("notes.md", base_level=-1) # base_level=-1: # -> \chapter
|
|
202
230
|
```
|
|
203
231
|
|
|
204
|
-
Headings, emphasis, inline/fenced code, lists, links, images,
|
|
205
|
-
thematic breaks map to the standard pytex library; text is
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
```md
|
|
210
|
-
> [!NOTE] -> InfoBox > [!IMPORTANT] -> ImportantBox
|
|
211
|
-
> [!TIP] -> SuccessBox > [!WARNING] -> WarningBox
|
|
212
|
-
```
|
|
232
|
+
Headings, emphasis, inline/fenced code, lists, links, images, GFM tables, block
|
|
233
|
+
quotes and thematic breaks map to the standard pytex library; text is
|
|
234
|
+
LaTeX-escaped. Some extras on top of plain Markdown:
|
|
235
|
+
|
|
236
|
+
- **GitHub-style callouts** become colored boxes (from `pytex_components`):
|
|
237
|
+
```md
|
|
238
|
+
> [!NOTE] -> InfoBox > [!IMPORTANT] -> ImportantBox
|
|
239
|
+
> [!TIP] -> SuccessBox > [!WARNING] -> WarningBox
|
|
240
|
+
```
|
|
241
|
+
- **Citations** in Pandoc syntax: `[@key]` / `[@key, p. 5]` -> `\autocite`,
|
|
242
|
+
`[@a; @b]` -> a combined cite, and a narrative `@key` -> `\textcite`.
|
|
243
|
+
- **Bibliography** from frontmatter — `bibliography:` is either inline BibTeX (a
|
|
244
|
+
`|` block scalar) or a path to a `.bib` file; reports print a numbered
|
|
245
|
+
`\printbibliography`.
|
|
246
|
+
- ASCII **math arrows** (`->`, `=>`, `<->`, ...) become inline math arrows, the
|
|
247
|
+
**euro sign** `€` becomes a font-independent `\euro{}`, and tables get a bit of
|
|
248
|
+
vertical breathing room.
|
|
213
249
|
|
|
214
250
|
Both factories are registered, so they work in `\iffalse{pytex(...)}\fi`
|
|
215
251
|
replacements in `.tex` sources too.
|
|
@@ -223,6 +259,7 @@ document chosen by `--variant`:
|
|
|
223
259
|
| --- | --- |
|
|
224
260
|
| `plain` | a bare `Document` (default class `article`); `#` -> `\section`. |
|
|
225
261
|
| `report` | an HSRT report with title page and table of contents; `#` -> `\chapter`. |
|
|
262
|
+
| `report-makers` | a `report` branded with the MAKERS logo (title page + footer). |
|
|
226
263
|
| `protocol-asta` | an AStA meeting protocol (HSRT report, AStA logos). |
|
|
227
264
|
| `protocol-stupa` | a StuPa meeting protocol (HSRT report, StuPa logos). |
|
|
228
265
|
|
|
@@ -241,6 +278,13 @@ object. For styles with a title page (`report`), the title is taken from
|
|
|
241
278
|
`title:`/`--config` if given, otherwise from the first `#` heading (which is then
|
|
242
279
|
not also rendered as a chapter).
|
|
243
280
|
|
|
281
|
+
The report styles read further frontmatter keys: `author`, `abstract`,
|
|
282
|
+
`keywords`, title-page `datalines` (a list of `"Label: value"` entries),
|
|
283
|
+
`bibliography` (see [Markdown](#markdown)), `logos` (title-page logos — vendored
|
|
284
|
+
names like `INF`/`MAKERS` and/or paths to custom image files), and the labels
|
|
285
|
+
`abstract_heading` / `keywords_heading` to rename the default "Abstract" /
|
|
286
|
+
"Keywords" sections.
|
|
287
|
+
|
|
244
288
|
## Converting LaTeX to PyTeX
|
|
245
289
|
|
|
246
290
|
`pytex-tex2py` turns an existing `.tex` file into an equivalent `.tex.py`
|
|
@@ -269,6 +313,27 @@ pytex examples/replacements.py.tex --build
|
|
|
269
313
|
pytex examples/notes.md --build
|
|
270
314
|
```
|
|
271
315
|
|
|
316
|
+
## Stability
|
|
317
|
+
|
|
318
|
+
From 1.0 the project follows [Semantic Versioning](https://semver.org). The
|
|
319
|
+
public API is what each package exports through its top-level `__all__`:
|
|
320
|
+
everything reachable as `from pytex import X` (and the same for `pytex_koma`,
|
|
321
|
+
`pytex_tikz`, `pytex_components`, `pytex_markdown`, `pytex_analyze`,
|
|
322
|
+
`pytex_hsrtreport`). Breaking those names needs a major version bump.
|
|
323
|
+
|
|
324
|
+
Also part of the contract: the registry keys exposed to `\iffalse{pytex(...)}\fi`
|
|
325
|
+
markers — they are the factory names, so renaming a registered factory is a
|
|
326
|
+
breaking change (which is why the `\fill` length is `Fill_len`, leaving the bare
|
|
327
|
+
`Fill` key to the TikZ path command).
|
|
328
|
+
|
|
329
|
+
Internal and not covered by the guarantee: any name with a leading underscore,
|
|
330
|
+
modules whose name starts with an underscore (e.g. `pytex_api._policy`,
|
|
331
|
+
`pytex_api._compile`), and anything not listed in a package's `__all__`. Import
|
|
332
|
+
those at your own risk.
|
|
333
|
+
|
|
334
|
+
Deprecated shims (`pytex_protocol`, the `pytex.commands.lengths.Fill` alias) keep
|
|
335
|
+
working with a `DeprecationWarning` and may be removed in the next major release.
|
|
336
|
+
|
|
272
337
|
## License
|
|
273
338
|
|
|
274
339
|
GNU General Public License v3.0 or later (GPL-3.0-or-later). See
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pytex-preprocessor"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "1.0.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Frederik Beimgraben", email="frederik@beimgraben.net" },
|
|
10
10
|
]
|
|
@@ -23,6 +23,7 @@ dev = ["pytest", "ruff", "basedpyright"]
|
|
|
23
23
|
[project.scripts]
|
|
24
24
|
pytex = "pytex_builder.build:main"
|
|
25
25
|
pytex-tex2py = "pytex_builder.tex2py:main"
|
|
26
|
+
pytex-sandbox-init = "pytex_api.sandbox_init:main"
|
|
26
27
|
|
|
27
28
|
[tool.setuptools.packages.find]
|
|
28
29
|
where = ["src"]
|
|
@@ -43,7 +44,10 @@ target-version = "py313"
|
|
|
43
44
|
src = ["src", "tests"]
|
|
44
45
|
# Uses Python 3.14 t-string syntax; the py313 target cannot parse it. Excluded
|
|
45
46
|
# from lint/format (it is exercised by pytest on 3.14).
|
|
46
|
-
|
|
47
|
+
# `examples/` is illustrative-only and not part of the CI lint scope (`ruff
|
|
48
|
+
# {check,format} src tests`); excluding it keeps a bare `ruff check` matching CI
|
|
49
|
+
# instead of choking on example-only files (some also use 3.14 t-strings).
|
|
50
|
+
extend-exclude = ["tests/pytex/test_template.py", "examples"]
|
|
47
51
|
|
|
48
52
|
[tool.ruff.lint]
|
|
49
53
|
select = [
|
|
@@ -85,4 +89,4 @@ ignore = ["N802"]
|
|
|
85
89
|
"src/pytex_builder/tectonic.py" = ["E501"]
|
|
86
90
|
|
|
87
91
|
[tool.ruff.lint.isort]
|
|
88
|
-
known-first-party = ["pytex", "pytex_builder", "pytex_koma", "pytex_tikz", "pytex_hsrtreport", "pytex_markdown"]
|
|
92
|
+
known-first-party = ["pytex_components", "pytex", "pytex_builder", "pytex_koma", "pytex_tikz", "pytex_hsrtreport", "pytex_markdown"]
|
|
@@ -543,7 +543,7 @@ def Verb(body: str, delim: str = "|") -> TeX:
|
|
|
543
543
|
|
|
544
544
|
|
|
545
545
|
# Size switches moved to pytex/commands/font.py (zero-arg ControlSequence wrappers).
|
|
546
|
-
# Compose with `Concat(
|
|
546
|
+
# Compose with `Concat(large(), " body")` for inline use.
|
|
547
547
|
|
|
548
548
|
|
|
549
549
|
@Registry.add
|
|
@@ -3,28 +3,28 @@ from ..model.control_sequence import ControlSequence, Parameter
|
|
|
3
3
|
from ..registry import Registry
|
|
4
4
|
|
|
5
5
|
__all__ = [
|
|
6
|
+
"LARGE",
|
|
6
7
|
"Bfseries",
|
|
7
8
|
"Fontsize",
|
|
8
|
-
"Footnotesize",
|
|
9
9
|
"Huge",
|
|
10
|
-
"HugeBig",
|
|
11
10
|
"Itshape",
|
|
12
11
|
"Large",
|
|
13
|
-
"LargeBig",
|
|
14
|
-
"LargeMid",
|
|
15
12
|
"Mdseries",
|
|
16
13
|
"Normalfont",
|
|
17
|
-
"Normalsize",
|
|
18
14
|
"Rmfamily",
|
|
19
|
-
"Scriptsize",
|
|
20
15
|
"Scshape",
|
|
21
16
|
"Selectfont",
|
|
22
17
|
"Sffamily",
|
|
23
18
|
"Slshape",
|
|
24
|
-
"Small",
|
|
25
|
-
"Tiny",
|
|
26
19
|
"Ttfamily",
|
|
27
20
|
"Upshape",
|
|
21
|
+
"footnotesize",
|
|
22
|
+
"huge",
|
|
23
|
+
"large",
|
|
24
|
+
"normalsize",
|
|
25
|
+
"scriptsize",
|
|
26
|
+
"small",
|
|
27
|
+
"tiny",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
|
|
@@ -88,51 +88,55 @@ def Normalfont() -> TeX:
|
|
|
88
88
|
return ControlSequence("normalfont", ())
|
|
89
89
|
|
|
90
90
|
|
|
91
|
+
# Size switches use the LaTeX command spelling verbatim as the factory name:
|
|
92
|
+
# `\large`/`\Large`/`\LARGE` and `\huge`/`\Huge` differ only by case, which
|
|
93
|
+
# PascalCase cannot encode without a collision. Python identifiers are
|
|
94
|
+
# case-sensitive, so `large`/`Large`/`LARGE` map one-to-one and predictably.
|
|
91
95
|
@Registry.add
|
|
92
|
-
def
|
|
96
|
+
def tiny() -> TeX:
|
|
93
97
|
return ControlSequence("tiny", ())
|
|
94
98
|
|
|
95
99
|
|
|
96
100
|
@Registry.add
|
|
97
|
-
def
|
|
101
|
+
def scriptsize() -> TeX:
|
|
98
102
|
return ControlSequence("scriptsize", ())
|
|
99
103
|
|
|
100
104
|
|
|
101
105
|
@Registry.add
|
|
102
|
-
def
|
|
106
|
+
def footnotesize() -> TeX:
|
|
103
107
|
return ControlSequence("footnotesize", ())
|
|
104
108
|
|
|
105
109
|
|
|
106
110
|
@Registry.add
|
|
107
|
-
def
|
|
111
|
+
def small() -> TeX:
|
|
108
112
|
return ControlSequence("small", ())
|
|
109
113
|
|
|
110
114
|
|
|
111
115
|
@Registry.add
|
|
112
|
-
def
|
|
116
|
+
def normalsize() -> TeX:
|
|
113
117
|
return ControlSequence("normalsize", ())
|
|
114
118
|
|
|
115
119
|
|
|
116
120
|
@Registry.add
|
|
117
|
-
def
|
|
121
|
+
def large() -> TeX:
|
|
118
122
|
return ControlSequence("large", ())
|
|
119
123
|
|
|
120
124
|
|
|
121
125
|
@Registry.add
|
|
122
|
-
def
|
|
126
|
+
def Large() -> TeX:
|
|
123
127
|
return ControlSequence("Large", ())
|
|
124
128
|
|
|
125
129
|
|
|
126
130
|
@Registry.add
|
|
127
|
-
def
|
|
131
|
+
def LARGE() -> TeX:
|
|
128
132
|
return ControlSequence("LARGE", ())
|
|
129
133
|
|
|
130
134
|
|
|
131
135
|
@Registry.add
|
|
132
|
-
def
|
|
136
|
+
def huge() -> TeX:
|
|
133
137
|
return ControlSequence("huge", ())
|
|
134
138
|
|
|
135
139
|
|
|
136
140
|
@Registry.add
|
|
137
|
-
def
|
|
141
|
+
def Huge() -> TeX:
|
|
138
142
|
return ControlSequence("Huge", ())
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
1
3
|
from ..interface.tex import TeX
|
|
2
4
|
from ..model.control_sequence import ControlSequence, Parameter
|
|
3
5
|
from ..model.length import Length
|
|
@@ -11,7 +13,7 @@ __all__ = [
|
|
|
11
13
|
"Baselinestretch",
|
|
12
14
|
"Columnsep",
|
|
13
15
|
"Columnwidth",
|
|
14
|
-
"
|
|
16
|
+
"Fill_len",
|
|
15
17
|
"Footskip",
|
|
16
18
|
"Headheight",
|
|
17
19
|
"Headsep",
|
|
@@ -196,5 +198,21 @@ def Arraystretch_len() -> Length:
|
|
|
196
198
|
|
|
197
199
|
|
|
198
200
|
@Registry.add
|
|
199
|
-
def
|
|
201
|
+
def Fill_len() -> Length:
|
|
200
202
|
return _const("fill")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def __getattr__(name: str) -> object:
|
|
206
|
+
# `Fill` (the ``\fill`` rubber length) was renamed to `Fill_len` so its
|
|
207
|
+
# registry key no longer collides with `pytex_tikz.Fill` (the ``\fill`` path
|
|
208
|
+
# command). The suffix mirrors `Arraystretch_len`, which already dodges the
|
|
209
|
+
# `Arraystretch` table command the same way. Kept as a deprecated alias.
|
|
210
|
+
if name == "Fill":
|
|
211
|
+
warnings.warn(
|
|
212
|
+
"pytex.commands.lengths.Fill was renamed to Fill_len to free the "
|
|
213
|
+
+ "'Fill' registry key for pytex_tikz.Fill; import Fill_len instead.",
|
|
214
|
+
DeprecationWarning,
|
|
215
|
+
stacklevel=2,
|
|
216
|
+
)
|
|
217
|
+
return Fill_len
|
|
218
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -59,7 +59,10 @@ class IncludeImage(TeX):
|
|
|
59
59
|
if src.suffix.lower() in PDF_COMPAT:
|
|
60
60
|
return src
|
|
61
61
|
if src.suffix.lower() == ".svg":
|
|
62
|
-
|
|
62
|
+
# Content-address the cache: hash the SVG bytes, not its path, so an
|
|
63
|
+
# edited source reconverts instead of reusing a stale PDF that
|
|
64
|
+
# happens to live at the same path-derived name.
|
|
65
|
+
digest = hashlib.sha1(src.read_bytes()).hexdigest()[:10]
|
|
63
66
|
return Path("build") / f"{src.stem}-{digest}.pdf"
|
|
64
67
|
raise ValueError(f"unsupported image extension: {src.suffix}")
|
|
65
68
|
|
|
@@ -65,13 +65,14 @@ _CONVERSIONS = {"r": repr, "s": str, "a": ascii}
|
|
|
65
65
|
|
|
66
66
|
def tex(template: _Template) -> TeX:
|
|
67
67
|
"""Render a t-string into a `TeX` tree (see the module docstring)."""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
return Concat(
|
|
69
|
+
*(
|
|
70
|
+
Raw(item) # literal LaTeX
|
|
71
|
+
if isinstance(item, str)
|
|
72
|
+
else _coerce(item.value, item.conversion, item.format_spec)
|
|
73
|
+
for item in template
|
|
74
|
+
)
|
|
75
|
+
)
|
|
75
76
|
|
|
76
77
|
|
|
77
78
|
def _coerce(value: object, conversion: str | None = None, spec: object = "") -> TeX:
|