texsmith 0.0.2.dev0__py3-none-any.whl
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.
- texsmith/__init__.py +107 -0
- texsmith/_alias.py +59 -0
- texsmith/adapters/__init__.py +6 -0
- texsmith/adapters/docker.py +258 -0
- texsmith/adapters/handlers/__init__.py +3 -0
- texsmith/adapters/handlers/_assets.py +363 -0
- texsmith/adapters/handlers/_helpers.py +62 -0
- texsmith/adapters/handlers/_mermaid.py +122 -0
- texsmith/adapters/handlers/admonitions.py +267 -0
- texsmith/adapters/handlers/basic.py +228 -0
- texsmith/adapters/handlers/blocks.py +851 -0
- texsmith/adapters/handlers/code.py +309 -0
- texsmith/adapters/handlers/inline.py +937 -0
- texsmith/adapters/handlers/links.py +239 -0
- texsmith/adapters/handlers/media.py +380 -0
- texsmith/adapters/latex/__init__.py +10 -0
- texsmith/adapters/latex/engines/__init__.py +726 -0
- texsmith/adapters/latex/engines/latex/__init__.py +26 -0
- texsmith/adapters/latex/engines/latex/log.py +720 -0
- texsmith/adapters/latex/engines/latex/runner.py +28 -0
- texsmith/adapters/latex/engines/tectonic/__init__.py +38 -0
- texsmith/adapters/latex/formatter.py +297 -0
- texsmith/adapters/latex/latexmk.py +148 -0
- texsmith/adapters/latex/partials/acronym.tex +1 -0
- texsmith/adapters/latex/partials/add.tex +1 -0
- texsmith/adapters/latex/partials/addition.tex +1 -0
- texsmith/adapters/latex/partials/blockquote.tex +3 -0
- texsmith/adapters/latex/partials/callout.tex +3 -0
- texsmith/adapters/latex/partials/choices.tex +5 -0
- texsmith/adapters/latex/partials/citation.tex +1 -0
- texsmith/adapters/latex/partials/codeblock.tex +7 -0
- texsmith/adapters/latex/partials/codeblock_listings.tex +5 -0
- texsmith/adapters/latex/partials/codeblock_pygments.tex +5 -0
- texsmith/adapters/latex/partials/codeblock_verbatim.tex +12 -0
- texsmith/adapters/latex/partials/codeinline.tex +1 -0
- texsmith/adapters/latex/partials/codeinlinett.tex +1 -0
- texsmith/adapters/latex/partials/comment.tex +1 -0
- texsmith/adapters/latex/partials/del.tex +1 -0
- texsmith/adapters/latex/partials/deletion.tex +1 -0
- texsmith/adapters/latex/partials/description_list.tex +5 -0
- texsmith/adapters/latex/partials/enquote.tex +1 -0
- texsmith/adapters/latex/partials/epigraph.tex +1 -0
- texsmith/adapters/latex/partials/exercises_solutions.tex +7 -0
- texsmith/adapters/latex/partials/figure.tex +33 -0
- texsmith/adapters/latex/partials/figure_tcolorbox.tex +15 -0
- texsmith/adapters/latex/partials/footnote.tex +3 -0
- texsmith/adapters/latex/partials/glossary.tex +1 -0
- texsmith/adapters/latex/partials/heading.tex +14 -0
- texsmith/adapters/latex/partials/highlight.tex +25 -0
- texsmith/adapters/latex/partials/horizontal_rule.tex +1 -0
- texsmith/adapters/latex/partials/href.tex +1 -0
- texsmith/adapters/latex/partials/icon.tex +1 -0
- texsmith/adapters/latex/partials/include.tex +1 -0
- texsmith/adapters/latex/partials/index.tex +1 -0
- texsmith/adapters/latex/partials/italic.tex +1 -0
- texsmith/adapters/latex/partials/keystroke.tex +46 -0
- texsmith/adapters/latex/partials/label.tex +1 -0
- texsmith/adapters/latex/partials/list_acronyms.tex +5 -0
- texsmith/adapters/latex/partials/list_glossary.tex +8 -0
- texsmith/adapters/latex/partials/multicolumn.tex +3 -0
- texsmith/adapters/latex/partials/ordered_list.tex +5 -0
- texsmith/adapters/latex/partials/pagestyle.tex +1 -0
- texsmith/adapters/latex/partials/ref.tex +1 -0
- texsmith/adapters/latex/partials/regex.tex +1 -0
- texsmith/adapters/latex/partials/smallcaps.tex +1 -0
- texsmith/adapters/latex/partials/strikethrough.tex +1 -0
- texsmith/adapters/latex/partials/strong.tex +1 -0
- texsmith/adapters/latex/partials/subscript.tex +1 -0
- texsmith/adapters/latex/partials/substitution.tex +1 -0
- texsmith/adapters/latex/partials/superscript.tex +1 -0
- texsmith/adapters/latex/partials/tabbed.tex +3 -0
- texsmith/adapters/latex/partials/table.tex +48 -0
- texsmith/adapters/latex/partials/underline.tex +1 -0
- texsmith/adapters/latex/partials/unordered_list.tex +5 -0
- texsmith/adapters/latex/partials/url.tex +1 -0
- texsmith/adapters/latex/pygments.py +98 -0
- texsmith/adapters/latex/pyxindy.py +64 -0
- texsmith/adapters/latex/renderer.py +220 -0
- texsmith/adapters/latex/tectonic.py +366 -0
- texsmith/adapters/latex/utils.py +86 -0
- texsmith/adapters/markdown/__init__.py +342 -0
- texsmith/adapters/plugins/__init__.py +8 -0
- texsmith/adapters/plugins/material.py +174 -0
- texsmith/adapters/plugins/snippet.py +1734 -0
- texsmith/adapters/transformers/__init__.py +122 -0
- texsmith/adapters/transformers/base.py +140 -0
- texsmith/adapters/transformers/strategies.py +1456 -0
- texsmith/adapters/transformers/utils.py +59 -0
- texsmith/api/__init__.py +80 -0
- texsmith/api/_utils.py +56 -0
- texsmith/api/document.py +645 -0
- texsmith/api/pipeline.py +229 -0
- texsmith/api/service.py +648 -0
- texsmith/api/templates.py +287 -0
- texsmith/core/__init__.py +6 -0
- texsmith/core/bibliography/__init__.py +57 -0
- texsmith/core/bibliography/collection.py +354 -0
- texsmith/core/bibliography/doi.py +194 -0
- texsmith/core/bibliography/issues.py +15 -0
- texsmith/core/bibliography/parsing.py +45 -0
- texsmith/core/callouts.py +99 -0
- texsmith/core/config.py +191 -0
- texsmith/core/context.py +242 -0
- texsmith/core/conversion/__init__.py +103 -0
- texsmith/core/conversion/core.py +780 -0
- texsmith/core/conversion/debug.py +87 -0
- texsmith/core/conversion/inputs.py +474 -0
- texsmith/core/conversion/renderer.py +578 -0
- texsmith/core/conversion/templates.py +646 -0
- texsmith/core/conversion_contexts.py +95 -0
- texsmith/core/diagnostics.py +118 -0
- texsmith/core/exceptions.py +41 -0
- texsmith/core/fonts/__init__.py +3 -0
- texsmith/core/fragments/__init__.py +716 -0
- texsmith/core/fragments/base.py +117 -0
- texsmith/core/metadata.py +280 -0
- texsmith/core/mustache.py +86 -0
- texsmith/core/partials.py +20 -0
- texsmith/core/rules.py +394 -0
- texsmith/core/templates/__init__.py +58 -0
- texsmith/core/templates/base.py +343 -0
- texsmith/core/templates/builtins.py +68 -0
- texsmith/core/templates/context_usage.py +137 -0
- texsmith/core/templates/loader.py +303 -0
- texsmith/core/templates/manifest.py +861 -0
- texsmith/core/templates/runtime.py +347 -0
- texsmith/core/templates/text.py +14 -0
- texsmith/core/templates/wrapper.py +340 -0
- texsmith/core/user_dir.py +179 -0
- texsmith/devtools.py +28 -0
- texsmith/extensions/__init__.py +162 -0
- texsmith/extensions/index/__init__.py +21 -0
- texsmith/extensions/index/markdown.py +94 -0
- texsmith/extensions/index/mkdocs_plugin.py +136 -0
- texsmith/extensions/index/registry.py +57 -0
- texsmith/extensions/index/renderer.py +183 -0
- texsmith/extensions/index/templates/index.tex +1 -0
- texsmith/extensions/latex_raw.py +115 -0
- texsmith/extensions/latex_text.py +117 -0
- texsmith/extensions/mermaid.py +267 -0
- texsmith/extensions/missing_footnotes.py +125 -0
- texsmith/extensions/multi_citations.py +54 -0
- texsmith/extensions/progressbar/__init__.py +9 -0
- texsmith/extensions/progressbar/markdown.py +212 -0
- texsmith/extensions/progressbar/renderer.py +117 -0
- texsmith/extensions/smallcaps.py +48 -0
- texsmith/extensions/texlogos/__init__.py +10 -0
- texsmith/extensions/texlogos/markdown.py +236 -0
- texsmith/extensions/texlogos/renderer.py +81 -0
- texsmith/extensions/texlogos/specs.py +66 -0
- texsmith/fonts/__init__.py +57 -0
- texsmith/fonts/cache.py +46 -0
- texsmith/fonts/constants.py +60 -0
- texsmith/fonts/coverage.py +275 -0
- texsmith/fonts/downloader.py +103 -0
- texsmith/fonts/fallback.py +438 -0
- texsmith/fonts/html_scripts.py +168 -0
- texsmith/fonts/logging.py +127 -0
- texsmith/fonts/pipeline.py +338 -0
- texsmith/fonts/scripts.py +493 -0
- texsmith/fonts/ucharclasses.py +164 -0
- texsmith/fragments/__init__.py +11 -0
- texsmith/fragments/bibliography/__init__.py +65 -0
- texsmith/fragments/bibliography/fragment.toml +3 -0
- texsmith/fragments/bibliography/ts-bibliography-backmatter.jinja.tex +35 -0
- texsmith/fragments/bibliography/ts-bibliography.jinja.tex +10 -0
- texsmith/fragments/callouts/__init__.py +88 -0
- texsmith/fragments/callouts/fragment.toml +3 -0
- texsmith/fragments/callouts/ts-callouts.jinja.sty +129 -0
- texsmith/fragments/code/__init__.py +82 -0
- texsmith/fragments/code/fragment.toml +3 -0
- texsmith/fragments/code/ts-code.jinja.sty +140 -0
- texsmith/fragments/extra/__init__.py +180 -0
- texsmith/fragments/extra/fragment.toml +3 -0
- texsmith/fragments/extra/ts-extra.jinja.tex +13 -0
- texsmith/fragments/fonts/__init__.py +880 -0
- texsmith/fragments/fonts/fragment.toml +3 -0
- texsmith/fragments/fonts/ts-fonts.jinja.sty +292 -0
- texsmith/fragments/frame/__init__.py +170 -0
- texsmith/fragments/frame/fragment.toml +3 -0
- texsmith/fragments/frame/ts-frame.tex.jinja +49 -0
- texsmith/fragments/geometry/__init__.py +169 -0
- texsmith/fragments/geometry/fragment.toml +3 -0
- texsmith/fragments/geometry/paper.py +526 -0
- texsmith/fragments/geometry/ts_geometry.tex.jinja +53 -0
- texsmith/fragments/glossary/__init__.py +67 -0
- texsmith/fragments/glossary/fragment.toml +3 -0
- texsmith/fragments/glossary/ts-glossary-backmatter.jinja.tex +5 -0
- texsmith/fragments/glossary/ts-glossary.jinja.sty +28 -0
- texsmith/fragments/index/__init__.py +66 -0
- texsmith/fragments/index/fragment.toml +3 -0
- texsmith/fragments/index/ts-index-backmatter.jinja.tex +3 -0
- texsmith/fragments/index/ts-index.jinja.sty +12 -0
- texsmith/fragments/keystrokes/__init__.py +69 -0
- texsmith/fragments/keystrokes/fragment.toml +3 -0
- texsmith/fragments/keystrokes/ts-keystrokes.jinja.sty +20 -0
- texsmith/fragments/todolist/__init__.py +71 -0
- texsmith/fragments/todolist/fragment.toml +3 -0
- texsmith/fragments/todolist/ts-todolist.jinja.sty +21 -0
- texsmith/fragments/typesetting/__init__.py +214 -0
- texsmith/fragments/typesetting/fragment.toml +3 -0
- texsmith/fragments/typesetting/ts-typesetting.tex.jinja +81 -0
- texsmith/index.py +26 -0
- texsmith/plugins/__init__.py +14 -0
- texsmith/progressbar.py +8 -0
- texsmith/quotes.py +40 -0
- texsmith/smart_dashes.py +66 -0
- texsmith/templates/__init__.py +3 -0
- texsmith/templates/article/README.md +33 -0
- texsmith/templates/article/__init__.py +281 -0
- texsmith/templates/article/template/manifest.toml +125 -0
- texsmith/templates/article/template/mermaid-config.json +18 -0
- texsmith/templates/article/template/template.tex +74 -0
- texsmith/templates/book/README.md +26 -0
- texsmith/templates/book/__init__.py +75 -0
- texsmith/templates/book/overrides/codeblock.tex +7 -0
- texsmith/templates/book/overrides/codeinline.tex +1 -0
- texsmith/templates/book/template/fixtoc.sty +81 -0
- texsmith/templates/book/template/manifest.toml +198 -0
- texsmith/templates/book/template/template.tex +314 -0
- texsmith/templates/common/__init__.py +1 -0
- texsmith/templates/common/latexmkrc +46 -0
- texsmith/templates/letter/README.md +59 -0
- texsmith/templates/letter/__init__.py +495 -0
- texsmith/templates/letter/demo.md +31 -0
- texsmith/templates/letter/fonts/modernline bold.otf +0 -0
- texsmith/templates/letter/fonts/modernline.otf +0 -0
- texsmith/templates/letter/manifest.toml +197 -0
- texsmith/templates/letter/template/callouts.jinja.sty +290 -0
- texsmith/templates/letter/template/template.tex +123 -0
- texsmith/templates/snippet/README.md +21 -0
- texsmith/templates/snippet/__init__.py +80 -0
- texsmith/templates/snippet/template/manifest.toml +66 -0
- texsmith/templates/snippet/template/template.tex +47 -0
- texsmith/texlogos.py +15 -0
- texsmith/ui/__init__.py +6 -0
- texsmith/ui/cli/__init__.py +22 -0
- texsmith/ui/cli/_options.py +338 -0
- texsmith/ui/cli/app.py +65 -0
- texsmith/ui/cli/bibliography.py +300 -0
- texsmith/ui/cli/commands/__init__.py +14 -0
- texsmith/ui/cli/commands/render.py +1128 -0
- texsmith/ui/cli/commands/templates.py +397 -0
- texsmith/ui/cli/diagnostics.py +36 -0
- texsmith/ui/cli/presenter.py +663 -0
- texsmith/ui/cli/state.py +263 -0
- texsmith/ui/cli/utils.py +235 -0
- texsmith-0.0.2.dev0.dist-info/METADATA +187 -0
- texsmith-0.0.2.dev0.dist-info/RECORD +252 -0
- texsmith-0.0.2.dev0.dist-info/WHEEL +4 -0
- texsmith-0.0.2.dev0.dist-info/entry_points.txt +22 -0
- texsmith-0.0.2.dev0.dist-info/licenses/LICENSE.md +21 -0
texsmith/api/pipeline.py
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"""Conversion helpers that expose a friendly façade over the core engine.
|
|
2
|
+
|
|
3
|
+
Architecture
|
|
4
|
+
: `RenderSettings` stores optional overrides for parser selection, asset
|
|
5
|
+
copying, manifest generation, and diagnostic outputs. A dedicated dataclass
|
|
6
|
+
keeps configuration immutable unless explicitly copied.
|
|
7
|
+
: `LaTeXFragment` represents the output of a single document conversion and
|
|
8
|
+
records where it was written on disk, keeping post-processing logic decoupled
|
|
9
|
+
from the rendering pass.
|
|
10
|
+
: `ConversionBundle` collects fragments and offers convenience methods like
|
|
11
|
+
`combined_output` for quick previews or testing.
|
|
12
|
+
: `convert_documents` bridges `Document` inputs, renders them through the
|
|
13
|
+
conversion engine, and yields the populated bundle.
|
|
14
|
+
|
|
15
|
+
Implementation Rationale
|
|
16
|
+
: Splitting settings, fragments, and bundles into separate dataclasses keeps the
|
|
17
|
+
API explicit. Callers can introspect or extend the workflow without threading
|
|
18
|
+
ad-hoc dictionaries through their code.
|
|
19
|
+
: Supporting multiple documents in a single call enables batch rendering and
|
|
20
|
+
powers template sessions. The helper ensures file names are deduplicated and
|
|
21
|
+
optional outputs, such as manifests, remain consistent.
|
|
22
|
+
|
|
23
|
+
Usage Example
|
|
24
|
+
:
|
|
25
|
+
>>> from pathlib import Path
|
|
26
|
+
>>> from tempfile import TemporaryDirectory
|
|
27
|
+
>>> from texsmith.api.document import Document
|
|
28
|
+
>>> from texsmith.api.pipeline import convert_documents
|
|
29
|
+
>>> with TemporaryDirectory() as tmpdir:
|
|
30
|
+
... source = Path(tmpdir) / "intro.md"
|
|
31
|
+
... _ = source.write_text("# Intro\\nContent")
|
|
32
|
+
... output_dir = Path(tmpdir) / "build"
|
|
33
|
+
... bundle = convert_documents([Document.from_markdown(source)], output_dir=output_dir)
|
|
34
|
+
... (output_dir / "intro.tex").exists()
|
|
35
|
+
True
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from __future__ import annotations
|
|
39
|
+
|
|
40
|
+
from collections.abc import Iterable, Mapping, Sequence
|
|
41
|
+
import copy
|
|
42
|
+
from dataclasses import dataclass
|
|
43
|
+
from pathlib import Path
|
|
44
|
+
from typing import TYPE_CHECKING, Any
|
|
45
|
+
|
|
46
|
+
from ..core.bibliography.collection import BibliographyCollection
|
|
47
|
+
from ..core.conversion.core import ConversionResult, convert_document
|
|
48
|
+
from ..core.conversion.renderer import TemplateFragment
|
|
49
|
+
from ..core.diagnostics import DiagnosticEmitter, NullEmitter
|
|
50
|
+
from ._utils import build_unique_stem_map
|
|
51
|
+
from .document import Document
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if TYPE_CHECKING: # pragma: no cover - type checking only
|
|
55
|
+
from texsmith.core.context import DocumentState
|
|
56
|
+
|
|
57
|
+
from ..core.templates import TemplateRuntime
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
__all__ = [
|
|
61
|
+
"ConversionBundle",
|
|
62
|
+
"LaTeXFragment",
|
|
63
|
+
"RenderSettings",
|
|
64
|
+
"convert_documents",
|
|
65
|
+
"to_template_fragments",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@dataclass(slots=True)
|
|
70
|
+
class RenderSettings:
|
|
71
|
+
"""Engine-level knobs applied during conversion."""
|
|
72
|
+
|
|
73
|
+
parser: str | None = None
|
|
74
|
+
disable_fallback_converters: bool = False
|
|
75
|
+
copy_assets: bool = True
|
|
76
|
+
convert_assets: bool = False
|
|
77
|
+
hash_assets: bool = False
|
|
78
|
+
manifest: bool = False
|
|
79
|
+
persist_debug_html: bool = False
|
|
80
|
+
language: str | None = None
|
|
81
|
+
legacy_latex_accents: bool = False
|
|
82
|
+
diagrams_backend: str | None = None
|
|
83
|
+
|
|
84
|
+
def copy(self) -> RenderSettings:
|
|
85
|
+
"""Create a deep copy of the settings to avoid cross-run mutations."""
|
|
86
|
+
return copy.deepcopy(self)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@dataclass(slots=True)
|
|
90
|
+
class LaTeXFragment:
|
|
91
|
+
"""Represents a rendered LaTeX fragment."""
|
|
92
|
+
|
|
93
|
+
document: Document
|
|
94
|
+
latex: str
|
|
95
|
+
stem: str
|
|
96
|
+
output_path: Path | None = None
|
|
97
|
+
conversion: ConversionResult | None = None
|
|
98
|
+
|
|
99
|
+
def write_to(self, target: Path) -> None:
|
|
100
|
+
"""Persist the fragment to disk so later template steps can reference it."""
|
|
101
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
target.write_text(self.latex, encoding="utf-8")
|
|
103
|
+
self.output_path = target
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@dataclass(slots=True)
|
|
107
|
+
class ConversionBundle:
|
|
108
|
+
"""Collection returned by :func:`convert_documents`."""
|
|
109
|
+
|
|
110
|
+
fragments: list[LaTeXFragment]
|
|
111
|
+
|
|
112
|
+
def combined_output(self) -> str:
|
|
113
|
+
"""Concatenate all fragments separated by blank lines for quick previews."""
|
|
114
|
+
return "\n\n".join(fragment.latex for fragment in self.fragments if fragment.latex)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def convert_documents(
|
|
118
|
+
documents: Sequence[Document],
|
|
119
|
+
*,
|
|
120
|
+
output_dir: Path | None = None,
|
|
121
|
+
settings: RenderSettings | None = None,
|
|
122
|
+
emitter: DiagnosticEmitter | None = None,
|
|
123
|
+
bibliography_files: Iterable[Path] | None = None,
|
|
124
|
+
template: str | None = None,
|
|
125
|
+
template_runtime: TemplateRuntime | None = None,
|
|
126
|
+
template_overrides: Mapping[str, Any] | None = None,
|
|
127
|
+
wrap_document: bool = True,
|
|
128
|
+
shared_state: DocumentState | None = None,
|
|
129
|
+
write_fragments: bool | None = None,
|
|
130
|
+
) -> ConversionBundle:
|
|
131
|
+
"""Convert one or more documents into LaTeX fragments while coordinating shared state."""
|
|
132
|
+
if not documents:
|
|
133
|
+
raise ValueError("At least one document is required for conversion.")
|
|
134
|
+
|
|
135
|
+
settings = settings.copy() if settings is not None else RenderSettings()
|
|
136
|
+
unique_stems = build_unique_stem_map([doc.source_path for doc in documents])
|
|
137
|
+
|
|
138
|
+
shared_bibliography: BibliographyCollection | None = None
|
|
139
|
+
seen_bibliography_issues: set[tuple[str, str | None, str | None]] = set()
|
|
140
|
+
|
|
141
|
+
if bibliography_files:
|
|
142
|
+
shared_bibliography = BibliographyCollection()
|
|
143
|
+
shared_bibliography.load_files(bibliography_files)
|
|
144
|
+
|
|
145
|
+
fragments: list[LaTeXFragment] = []
|
|
146
|
+
should_write_fragments = write_fragments if write_fragments is not None else True
|
|
147
|
+
state = shared_state
|
|
148
|
+
active_emitter = emitter or NullEmitter()
|
|
149
|
+
|
|
150
|
+
for _index, document in enumerate(documents):
|
|
151
|
+
context = document.to_context()
|
|
152
|
+
target_dir = Path(output_dir) if output_dir is not None else Path("build")
|
|
153
|
+
slot_overrides = document.slots.selectors()
|
|
154
|
+
result = convert_document(
|
|
155
|
+
document=context,
|
|
156
|
+
output_dir=target_dir,
|
|
157
|
+
parser=settings.parser,
|
|
158
|
+
disable_fallback_converters=settings.disable_fallback_converters,
|
|
159
|
+
copy_assets=settings.copy_assets,
|
|
160
|
+
convert_assets=settings.convert_assets,
|
|
161
|
+
hash_assets=settings.hash_assets,
|
|
162
|
+
manifest=settings.manifest,
|
|
163
|
+
template=template,
|
|
164
|
+
persist_debug_html=settings.persist_debug_html,
|
|
165
|
+
language=settings.language,
|
|
166
|
+
diagrams_backend=settings.diagrams_backend,
|
|
167
|
+
slot_overrides=slot_overrides or None,
|
|
168
|
+
bibliography_files=list(bibliography_files or []),
|
|
169
|
+
legacy_latex_accents=settings.legacy_latex_accents,
|
|
170
|
+
emitter=active_emitter,
|
|
171
|
+
template_overrides=template_overrides,
|
|
172
|
+
state=None if wrap_document else state,
|
|
173
|
+
template_runtime=template_runtime,
|
|
174
|
+
wrap_document=wrap_document,
|
|
175
|
+
preloaded_bibliography=shared_bibliography,
|
|
176
|
+
seen_bibliography_issues=seen_bibliography_issues,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
if not wrap_document:
|
|
180
|
+
state = result.document_state or state
|
|
181
|
+
|
|
182
|
+
stem = unique_stems[document.source_path]
|
|
183
|
+
fragment = LaTeXFragment(
|
|
184
|
+
document=document,
|
|
185
|
+
latex=result.latex_output,
|
|
186
|
+
stem=stem,
|
|
187
|
+
conversion=result,
|
|
188
|
+
)
|
|
189
|
+
if output_dir is not None and should_write_fragments:
|
|
190
|
+
target = target_dir / f"{stem}.tex"
|
|
191
|
+
fragment.write_to(target)
|
|
192
|
+
fragments.append(fragment)
|
|
193
|
+
|
|
194
|
+
return ConversionBundle(fragments=fragments)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def to_template_fragments(bundle: ConversionBundle) -> list[TemplateFragment]:
|
|
198
|
+
"""Convert API fragments into the core template fragment contract to keep template engines decoupled from API types."""
|
|
199
|
+
fragments: list[TemplateFragment] = []
|
|
200
|
+
for fragment in bundle.fragments:
|
|
201
|
+
conversion = fragment.conversion
|
|
202
|
+
if conversion is None:
|
|
203
|
+
raise ValueError("Template rendering requires conversion metadata for each fragment.")
|
|
204
|
+
|
|
205
|
+
document = fragment.document
|
|
206
|
+
slot_includes: set[str] = set()
|
|
207
|
+
if document is not None and hasattr(document, "slots"):
|
|
208
|
+
slot_includes = set(document.slots.includes())
|
|
209
|
+
|
|
210
|
+
fragments.append(
|
|
211
|
+
TemplateFragment(
|
|
212
|
+
stem=fragment.stem,
|
|
213
|
+
latex=conversion.latex_output,
|
|
214
|
+
default_slot=conversion.default_slot or "mainmatter",
|
|
215
|
+
slot_outputs=dict(conversion.slot_outputs),
|
|
216
|
+
slot_includes=slot_includes,
|
|
217
|
+
document_state=conversion.document_state,
|
|
218
|
+
bibliography_path=conversion.bibliography_path,
|
|
219
|
+
template_engine=conversion.template_engine,
|
|
220
|
+
requires_shell_escape=conversion.template_shell_escape,
|
|
221
|
+
template_overrides=dict(conversion.template_overrides),
|
|
222
|
+
output_path=fragment.output_path,
|
|
223
|
+
front_matter=document.front_matter,
|
|
224
|
+
source_path=document.source_path,
|
|
225
|
+
rule_descriptions=list(conversion.rule_descriptions),
|
|
226
|
+
assets=dict(conversion.assets_map),
|
|
227
|
+
)
|
|
228
|
+
)
|
|
229
|
+
return fragments
|