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.
Files changed (252) hide show
  1. texsmith/__init__.py +107 -0
  2. texsmith/_alias.py +59 -0
  3. texsmith/adapters/__init__.py +6 -0
  4. texsmith/adapters/docker.py +258 -0
  5. texsmith/adapters/handlers/__init__.py +3 -0
  6. texsmith/adapters/handlers/_assets.py +363 -0
  7. texsmith/adapters/handlers/_helpers.py +62 -0
  8. texsmith/adapters/handlers/_mermaid.py +122 -0
  9. texsmith/adapters/handlers/admonitions.py +267 -0
  10. texsmith/adapters/handlers/basic.py +228 -0
  11. texsmith/adapters/handlers/blocks.py +851 -0
  12. texsmith/adapters/handlers/code.py +309 -0
  13. texsmith/adapters/handlers/inline.py +937 -0
  14. texsmith/adapters/handlers/links.py +239 -0
  15. texsmith/adapters/handlers/media.py +380 -0
  16. texsmith/adapters/latex/__init__.py +10 -0
  17. texsmith/adapters/latex/engines/__init__.py +726 -0
  18. texsmith/adapters/latex/engines/latex/__init__.py +26 -0
  19. texsmith/adapters/latex/engines/latex/log.py +720 -0
  20. texsmith/adapters/latex/engines/latex/runner.py +28 -0
  21. texsmith/adapters/latex/engines/tectonic/__init__.py +38 -0
  22. texsmith/adapters/latex/formatter.py +297 -0
  23. texsmith/adapters/latex/latexmk.py +148 -0
  24. texsmith/adapters/latex/partials/acronym.tex +1 -0
  25. texsmith/adapters/latex/partials/add.tex +1 -0
  26. texsmith/adapters/latex/partials/addition.tex +1 -0
  27. texsmith/adapters/latex/partials/blockquote.tex +3 -0
  28. texsmith/adapters/latex/partials/callout.tex +3 -0
  29. texsmith/adapters/latex/partials/choices.tex +5 -0
  30. texsmith/adapters/latex/partials/citation.tex +1 -0
  31. texsmith/adapters/latex/partials/codeblock.tex +7 -0
  32. texsmith/adapters/latex/partials/codeblock_listings.tex +5 -0
  33. texsmith/adapters/latex/partials/codeblock_pygments.tex +5 -0
  34. texsmith/adapters/latex/partials/codeblock_verbatim.tex +12 -0
  35. texsmith/adapters/latex/partials/codeinline.tex +1 -0
  36. texsmith/adapters/latex/partials/codeinlinett.tex +1 -0
  37. texsmith/adapters/latex/partials/comment.tex +1 -0
  38. texsmith/adapters/latex/partials/del.tex +1 -0
  39. texsmith/adapters/latex/partials/deletion.tex +1 -0
  40. texsmith/adapters/latex/partials/description_list.tex +5 -0
  41. texsmith/adapters/latex/partials/enquote.tex +1 -0
  42. texsmith/adapters/latex/partials/epigraph.tex +1 -0
  43. texsmith/adapters/latex/partials/exercises_solutions.tex +7 -0
  44. texsmith/adapters/latex/partials/figure.tex +33 -0
  45. texsmith/adapters/latex/partials/figure_tcolorbox.tex +15 -0
  46. texsmith/adapters/latex/partials/footnote.tex +3 -0
  47. texsmith/adapters/latex/partials/glossary.tex +1 -0
  48. texsmith/adapters/latex/partials/heading.tex +14 -0
  49. texsmith/adapters/latex/partials/highlight.tex +25 -0
  50. texsmith/adapters/latex/partials/horizontal_rule.tex +1 -0
  51. texsmith/adapters/latex/partials/href.tex +1 -0
  52. texsmith/adapters/latex/partials/icon.tex +1 -0
  53. texsmith/adapters/latex/partials/include.tex +1 -0
  54. texsmith/adapters/latex/partials/index.tex +1 -0
  55. texsmith/adapters/latex/partials/italic.tex +1 -0
  56. texsmith/adapters/latex/partials/keystroke.tex +46 -0
  57. texsmith/adapters/latex/partials/label.tex +1 -0
  58. texsmith/adapters/latex/partials/list_acronyms.tex +5 -0
  59. texsmith/adapters/latex/partials/list_glossary.tex +8 -0
  60. texsmith/adapters/latex/partials/multicolumn.tex +3 -0
  61. texsmith/adapters/latex/partials/ordered_list.tex +5 -0
  62. texsmith/adapters/latex/partials/pagestyle.tex +1 -0
  63. texsmith/adapters/latex/partials/ref.tex +1 -0
  64. texsmith/adapters/latex/partials/regex.tex +1 -0
  65. texsmith/adapters/latex/partials/smallcaps.tex +1 -0
  66. texsmith/adapters/latex/partials/strikethrough.tex +1 -0
  67. texsmith/adapters/latex/partials/strong.tex +1 -0
  68. texsmith/adapters/latex/partials/subscript.tex +1 -0
  69. texsmith/adapters/latex/partials/substitution.tex +1 -0
  70. texsmith/adapters/latex/partials/superscript.tex +1 -0
  71. texsmith/adapters/latex/partials/tabbed.tex +3 -0
  72. texsmith/adapters/latex/partials/table.tex +48 -0
  73. texsmith/adapters/latex/partials/underline.tex +1 -0
  74. texsmith/adapters/latex/partials/unordered_list.tex +5 -0
  75. texsmith/adapters/latex/partials/url.tex +1 -0
  76. texsmith/adapters/latex/pygments.py +98 -0
  77. texsmith/adapters/latex/pyxindy.py +64 -0
  78. texsmith/adapters/latex/renderer.py +220 -0
  79. texsmith/adapters/latex/tectonic.py +366 -0
  80. texsmith/adapters/latex/utils.py +86 -0
  81. texsmith/adapters/markdown/__init__.py +342 -0
  82. texsmith/adapters/plugins/__init__.py +8 -0
  83. texsmith/adapters/plugins/material.py +174 -0
  84. texsmith/adapters/plugins/snippet.py +1734 -0
  85. texsmith/adapters/transformers/__init__.py +122 -0
  86. texsmith/adapters/transformers/base.py +140 -0
  87. texsmith/adapters/transformers/strategies.py +1456 -0
  88. texsmith/adapters/transformers/utils.py +59 -0
  89. texsmith/api/__init__.py +80 -0
  90. texsmith/api/_utils.py +56 -0
  91. texsmith/api/document.py +645 -0
  92. texsmith/api/pipeline.py +229 -0
  93. texsmith/api/service.py +648 -0
  94. texsmith/api/templates.py +287 -0
  95. texsmith/core/__init__.py +6 -0
  96. texsmith/core/bibliography/__init__.py +57 -0
  97. texsmith/core/bibliography/collection.py +354 -0
  98. texsmith/core/bibliography/doi.py +194 -0
  99. texsmith/core/bibliography/issues.py +15 -0
  100. texsmith/core/bibliography/parsing.py +45 -0
  101. texsmith/core/callouts.py +99 -0
  102. texsmith/core/config.py +191 -0
  103. texsmith/core/context.py +242 -0
  104. texsmith/core/conversion/__init__.py +103 -0
  105. texsmith/core/conversion/core.py +780 -0
  106. texsmith/core/conversion/debug.py +87 -0
  107. texsmith/core/conversion/inputs.py +474 -0
  108. texsmith/core/conversion/renderer.py +578 -0
  109. texsmith/core/conversion/templates.py +646 -0
  110. texsmith/core/conversion_contexts.py +95 -0
  111. texsmith/core/diagnostics.py +118 -0
  112. texsmith/core/exceptions.py +41 -0
  113. texsmith/core/fonts/__init__.py +3 -0
  114. texsmith/core/fragments/__init__.py +716 -0
  115. texsmith/core/fragments/base.py +117 -0
  116. texsmith/core/metadata.py +280 -0
  117. texsmith/core/mustache.py +86 -0
  118. texsmith/core/partials.py +20 -0
  119. texsmith/core/rules.py +394 -0
  120. texsmith/core/templates/__init__.py +58 -0
  121. texsmith/core/templates/base.py +343 -0
  122. texsmith/core/templates/builtins.py +68 -0
  123. texsmith/core/templates/context_usage.py +137 -0
  124. texsmith/core/templates/loader.py +303 -0
  125. texsmith/core/templates/manifest.py +861 -0
  126. texsmith/core/templates/runtime.py +347 -0
  127. texsmith/core/templates/text.py +14 -0
  128. texsmith/core/templates/wrapper.py +340 -0
  129. texsmith/core/user_dir.py +179 -0
  130. texsmith/devtools.py +28 -0
  131. texsmith/extensions/__init__.py +162 -0
  132. texsmith/extensions/index/__init__.py +21 -0
  133. texsmith/extensions/index/markdown.py +94 -0
  134. texsmith/extensions/index/mkdocs_plugin.py +136 -0
  135. texsmith/extensions/index/registry.py +57 -0
  136. texsmith/extensions/index/renderer.py +183 -0
  137. texsmith/extensions/index/templates/index.tex +1 -0
  138. texsmith/extensions/latex_raw.py +115 -0
  139. texsmith/extensions/latex_text.py +117 -0
  140. texsmith/extensions/mermaid.py +267 -0
  141. texsmith/extensions/missing_footnotes.py +125 -0
  142. texsmith/extensions/multi_citations.py +54 -0
  143. texsmith/extensions/progressbar/__init__.py +9 -0
  144. texsmith/extensions/progressbar/markdown.py +212 -0
  145. texsmith/extensions/progressbar/renderer.py +117 -0
  146. texsmith/extensions/smallcaps.py +48 -0
  147. texsmith/extensions/texlogos/__init__.py +10 -0
  148. texsmith/extensions/texlogos/markdown.py +236 -0
  149. texsmith/extensions/texlogos/renderer.py +81 -0
  150. texsmith/extensions/texlogos/specs.py +66 -0
  151. texsmith/fonts/__init__.py +57 -0
  152. texsmith/fonts/cache.py +46 -0
  153. texsmith/fonts/constants.py +60 -0
  154. texsmith/fonts/coverage.py +275 -0
  155. texsmith/fonts/downloader.py +103 -0
  156. texsmith/fonts/fallback.py +438 -0
  157. texsmith/fonts/html_scripts.py +168 -0
  158. texsmith/fonts/logging.py +127 -0
  159. texsmith/fonts/pipeline.py +338 -0
  160. texsmith/fonts/scripts.py +493 -0
  161. texsmith/fonts/ucharclasses.py +164 -0
  162. texsmith/fragments/__init__.py +11 -0
  163. texsmith/fragments/bibliography/__init__.py +65 -0
  164. texsmith/fragments/bibliography/fragment.toml +3 -0
  165. texsmith/fragments/bibliography/ts-bibliography-backmatter.jinja.tex +35 -0
  166. texsmith/fragments/bibliography/ts-bibliography.jinja.tex +10 -0
  167. texsmith/fragments/callouts/__init__.py +88 -0
  168. texsmith/fragments/callouts/fragment.toml +3 -0
  169. texsmith/fragments/callouts/ts-callouts.jinja.sty +129 -0
  170. texsmith/fragments/code/__init__.py +82 -0
  171. texsmith/fragments/code/fragment.toml +3 -0
  172. texsmith/fragments/code/ts-code.jinja.sty +140 -0
  173. texsmith/fragments/extra/__init__.py +180 -0
  174. texsmith/fragments/extra/fragment.toml +3 -0
  175. texsmith/fragments/extra/ts-extra.jinja.tex +13 -0
  176. texsmith/fragments/fonts/__init__.py +880 -0
  177. texsmith/fragments/fonts/fragment.toml +3 -0
  178. texsmith/fragments/fonts/ts-fonts.jinja.sty +292 -0
  179. texsmith/fragments/frame/__init__.py +170 -0
  180. texsmith/fragments/frame/fragment.toml +3 -0
  181. texsmith/fragments/frame/ts-frame.tex.jinja +49 -0
  182. texsmith/fragments/geometry/__init__.py +169 -0
  183. texsmith/fragments/geometry/fragment.toml +3 -0
  184. texsmith/fragments/geometry/paper.py +526 -0
  185. texsmith/fragments/geometry/ts_geometry.tex.jinja +53 -0
  186. texsmith/fragments/glossary/__init__.py +67 -0
  187. texsmith/fragments/glossary/fragment.toml +3 -0
  188. texsmith/fragments/glossary/ts-glossary-backmatter.jinja.tex +5 -0
  189. texsmith/fragments/glossary/ts-glossary.jinja.sty +28 -0
  190. texsmith/fragments/index/__init__.py +66 -0
  191. texsmith/fragments/index/fragment.toml +3 -0
  192. texsmith/fragments/index/ts-index-backmatter.jinja.tex +3 -0
  193. texsmith/fragments/index/ts-index.jinja.sty +12 -0
  194. texsmith/fragments/keystrokes/__init__.py +69 -0
  195. texsmith/fragments/keystrokes/fragment.toml +3 -0
  196. texsmith/fragments/keystrokes/ts-keystrokes.jinja.sty +20 -0
  197. texsmith/fragments/todolist/__init__.py +71 -0
  198. texsmith/fragments/todolist/fragment.toml +3 -0
  199. texsmith/fragments/todolist/ts-todolist.jinja.sty +21 -0
  200. texsmith/fragments/typesetting/__init__.py +214 -0
  201. texsmith/fragments/typesetting/fragment.toml +3 -0
  202. texsmith/fragments/typesetting/ts-typesetting.tex.jinja +81 -0
  203. texsmith/index.py +26 -0
  204. texsmith/plugins/__init__.py +14 -0
  205. texsmith/progressbar.py +8 -0
  206. texsmith/quotes.py +40 -0
  207. texsmith/smart_dashes.py +66 -0
  208. texsmith/templates/__init__.py +3 -0
  209. texsmith/templates/article/README.md +33 -0
  210. texsmith/templates/article/__init__.py +281 -0
  211. texsmith/templates/article/template/manifest.toml +125 -0
  212. texsmith/templates/article/template/mermaid-config.json +18 -0
  213. texsmith/templates/article/template/template.tex +74 -0
  214. texsmith/templates/book/README.md +26 -0
  215. texsmith/templates/book/__init__.py +75 -0
  216. texsmith/templates/book/overrides/codeblock.tex +7 -0
  217. texsmith/templates/book/overrides/codeinline.tex +1 -0
  218. texsmith/templates/book/template/fixtoc.sty +81 -0
  219. texsmith/templates/book/template/manifest.toml +198 -0
  220. texsmith/templates/book/template/template.tex +314 -0
  221. texsmith/templates/common/__init__.py +1 -0
  222. texsmith/templates/common/latexmkrc +46 -0
  223. texsmith/templates/letter/README.md +59 -0
  224. texsmith/templates/letter/__init__.py +495 -0
  225. texsmith/templates/letter/demo.md +31 -0
  226. texsmith/templates/letter/fonts/modernline bold.otf +0 -0
  227. texsmith/templates/letter/fonts/modernline.otf +0 -0
  228. texsmith/templates/letter/manifest.toml +197 -0
  229. texsmith/templates/letter/template/callouts.jinja.sty +290 -0
  230. texsmith/templates/letter/template/template.tex +123 -0
  231. texsmith/templates/snippet/README.md +21 -0
  232. texsmith/templates/snippet/__init__.py +80 -0
  233. texsmith/templates/snippet/template/manifest.toml +66 -0
  234. texsmith/templates/snippet/template/template.tex +47 -0
  235. texsmith/texlogos.py +15 -0
  236. texsmith/ui/__init__.py +6 -0
  237. texsmith/ui/cli/__init__.py +22 -0
  238. texsmith/ui/cli/_options.py +338 -0
  239. texsmith/ui/cli/app.py +65 -0
  240. texsmith/ui/cli/bibliography.py +300 -0
  241. texsmith/ui/cli/commands/__init__.py +14 -0
  242. texsmith/ui/cli/commands/render.py +1128 -0
  243. texsmith/ui/cli/commands/templates.py +397 -0
  244. texsmith/ui/cli/diagnostics.py +36 -0
  245. texsmith/ui/cli/presenter.py +663 -0
  246. texsmith/ui/cli/state.py +263 -0
  247. texsmith/ui/cli/utils.py +235 -0
  248. texsmith-0.0.2.dev0.dist-info/METADATA +187 -0
  249. texsmith-0.0.2.dev0.dist-info/RECORD +252 -0
  250. texsmith-0.0.2.dev0.dist-info/WHEEL +4 -0
  251. texsmith-0.0.2.dev0.dist-info/entry_points.txt +22 -0
  252. texsmith-0.0.2.dev0.dist-info/licenses/LICENSE.md +21 -0
@@ -0,0 +1,75 @@
1
+ """Book template integration for TeXSmith."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Iterable, Mapping
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ from texsmith.adapters.latex.utils import escape_latex_chars
10
+ from texsmith.core.templates import TemplateError, WrappableTemplate
11
+
12
+
13
+ _PACKAGE_ROOT = Path(__file__).parent.resolve()
14
+
15
+
16
+ class Template(WrappableTemplate):
17
+ """Expose the book template as a wrappable template instance."""
18
+
19
+ def __init__(self) -> None:
20
+ try:
21
+ super().__init__(_PACKAGE_ROOT)
22
+ except TemplateError as exc:
23
+ raise TemplateError(f"Failed to initialise book template: {exc}") from exc
24
+
25
+ def prepare_context(
26
+ self,
27
+ latex_body: str,
28
+ *,
29
+ overrides: Mapping[str, Any] | None = None,
30
+ ) -> dict[str, Any]:
31
+ context = super().prepare_context(latex_body, overrides=overrides)
32
+ context["ts_extra_disable_hyperref"] = True
33
+
34
+ raw_authors = context.pop("authors", None)
35
+ author_value = self._format_authors(raw_authors)
36
+ if author_value:
37
+ context["author"] = author_value
38
+ else:
39
+ context.pop("author", None)
40
+ context.pop("press", None)
41
+ return context
42
+
43
+ def _coerce_string(self, value: Any) -> str | None:
44
+ if value is None:
45
+ return None
46
+ candidate = value.strip() if isinstance(value, str) else str(value).strip()
47
+ return candidate or None
48
+
49
+ def _format_authors(self, payload: Any) -> str | None:
50
+ if not payload:
51
+ return None
52
+ if not isinstance(payload, Iterable) or isinstance(payload, (str, bytes)):
53
+ return None
54
+
55
+ formatted: list[str] = []
56
+ for item in payload:
57
+ if not isinstance(item, Mapping):
58
+ continue
59
+ name_value = self._coerce_string(item.get("name"))
60
+ if not name_value:
61
+ continue
62
+ name_tex = escape_latex_chars(name_value)
63
+ affiliation = self._coerce_string(item.get("affiliation"))
64
+ if affiliation:
65
+ affiliation_tex = escape_latex_chars(affiliation)
66
+ formatted.append(f"{name_tex}\\thanks{{{affiliation_tex}}}")
67
+ else:
68
+ formatted.append(name_tex)
69
+
70
+ if not formatted:
71
+ return None
72
+ return " \\and ".join(formatted)
73
+
74
+
75
+ __all__ = ["Template"]
@@ -0,0 +1,7 @@
1
+ %\leavevmode % Required to avoid a bug in the tcolorbox package
2
+ \begin{code}{\VAR{language|default('text')}}{\BLOCK{if filename}\VAR{filename}\BLOCK{endif}}{
3
+ \BLOCK{- if baselinestretch}baselinestretch=\VAR{baselinestretch}, \BLOCK{endif}
4
+ \BLOCK{- if linenos}linenos, \BLOCK{endif -}
5
+ \BLOCK{- if highlight }, highlightlines={\VAR{','.join(highlight)}}\BLOCK{endif -}
6
+ }
7
+ \VAR{code}\end{code}
@@ -0,0 +1 @@
1
+ \mintinline{\BLOCK{if language}\VAR{language}\BLOCK{else}text\BLOCK{endif}}\VAR{delimiter}\VAR{text}\VAR{delimiter}
@@ -0,0 +1,81 @@
1
+ \NeedsTeXFormat{LaTeX2e}
2
+ \ProvidesPackage{fixtoc}[2025/12/03 Dynamic TOC widths]
3
+
4
+ \RequirePackage{refcount}
5
+
6
+ \gdef\LASTPART{0}
7
+ \gdef\LASTCHAPTER{0}
8
+ \gdef\LASTSECTION{0}
9
+ \newcounter{tssectionmax}
10
+ \makeatletter
11
+ \AddToHook{cmd/part/before}{\protected@write\@mainaux{}{\gdef\string\LASTPART{\arabic{part}}}}
12
+ \AddToHook{cmd/chapter/before}{\protected@write\@mainaux{}{\gdef\string\LASTCHAPTER{\arabic{chapter}}}}
13
+ \newcommand*\tsAfterSectionHook{%
14
+ \ifnum\numexpr\value{section}+1\relax>\value{tssectionmax}%
15
+ \setcounter{tssectionmax}{\value{section}}%
16
+ \addtocounter{tssectionmax}{1}%
17
+ \fi
18
+ }
19
+ \AddToHook{cmd/section/before}{\tsAfterSectionHook}
20
+ \AddToHook{shipout/lastpage}{%
21
+ \protected@write\@mainaux{}{\string\gdef\string\LASTSECTION{\arabic{tssectionmax}}}%
22
+ }
23
+ \makeatother
24
+
25
+ \AtBeginDocument{%
26
+ \setcounter{tssectionmax}{\LASTSECTION}%
27
+ \computemaxpartnumberwidth
28
+ \computemaxchapternumberwidth
29
+ \computemaxsectionnumberwidth
30
+ }
31
+ \renewcommand{\cftpartpresnum}{\partname\ }
32
+
33
+ \ExplSyntaxOn
34
+ \NewDocumentCommand{\computemaxpartnumberwidth}{}
35
+ {
36
+ \dim_set:Nn \l_tmpa_dim {0pt}
37
+ \int_step_inline:nn { \use:c{LASTPART}+1 }
38
+ {
39
+ \settowidth{\l_tmpb_dim}
40
+ {
41
+ \cftpartfont \cftpartpresnum \int_to_Roman:n {##1}
42
+ }
43
+ \dim_compare:nT { \l_tmpb_dim > \l_tmpa_dim } { \dim_set:Nn \l_tmpa_dim { \l_tmpb_dim } }
44
+ }
45
+ \addtolength{\l_tmpa_dim}{1em}
46
+ \setlength{\cftpartnumwidth}{\l_tmpa_dim}
47
+ }
48
+ \NewDocumentCommand{\computemaxchapternumberwidth}{}
49
+ {
50
+ \dim_set:Nn \l_tmpa_dim {0pt}
51
+ \int_step_inline:nn { \use:c{LASTCHAPTER}+1 }
52
+ {
53
+ \settowidth{\l_tmpb_dim}
54
+ {
55
+ \cftchapterfont \cftchapterpresnum \int_to_arabic:n {##1} \cftchapteraftersnum
56
+ }
57
+ \dim_compare:nT { \l_tmpb_dim > \l_tmpa_dim } { \dim_set:Nn \l_tmpa_dim { \l_tmpb_dim } }
58
+ }
59
+ \addtolength{\l_tmpa_dim}{1em}
60
+ \setlength{\cftchapternumwidth}{\l_tmpa_dim}
61
+ }
62
+ \NewDocumentCommand{\computemaxsectionnumberwidth}{}
63
+ {
64
+ \dim_set:Nn \l_tmpa_dim {0pt}
65
+ \int_set:Nn \l_tmpa_int { \value{chapter} }
66
+ \int_set:Nn \l_tmpb_int { \value{section} }
67
+ \int_step_inline:nn { \int_max:nn {1}{ \use:c{LASTSECTION} } }
68
+ {
69
+ \int_set:cn { c@section } {##1}
70
+ \int_set:cn { c@chapter } { \use:c{LASTCHAPTER} }
71
+ \settowidth{\l_tmpb_dim}
72
+ { \cftsectionfont \cftsectionpresnum \thesection \cftsectionaftersnum }
73
+ \dim_compare:nT { \l_tmpb_dim > \l_tmpa_dim }
74
+ { \dim_set:Nn \l_tmpa_dim { \l_tmpb_dim } }
75
+ }
76
+ \int_set:cn { c@chapter } { \l_tmpa_int }
77
+ \int_set:cn { c@section } { \l_tmpb_int }
78
+ \addtolength{\l_tmpa_dim}{1em}
79
+ \setlength{\cftsectionnumwidth}{\l_tmpa_dim}
80
+ }
81
+ \ExplSyntaxOff
@@ -0,0 +1,198 @@
1
+ [compat]
2
+ texsmith = ">=0.6,<1.0"
3
+
4
+ [latex.template]
5
+ name = "book"
6
+ version = "0.2.0"
7
+ entrypoint = "template/template.tex"
8
+ engine = "lualatex"
9
+ shell_escape = false
10
+ texlive_year = 2023
11
+ tlmgr_packages = [
12
+ "babel",
13
+ "babel-french",
14
+ "csquotes",
15
+ "fontspec",
16
+ "fancyvrb",
17
+ "geometry",
18
+ "hyperref",
19
+ "longtable",
20
+ "microtype",
21
+ "titlesec",
22
+ "titletoc",
23
+ "xcolor",
24
+ "xunicode",
25
+ ]
26
+ override = ["codeblock.tex", "codeinline.tex"]
27
+ fragments = [
28
+ "ts-geometry",
29
+ "ts-typesetting",
30
+ "ts-fonts",
31
+ "ts-extra",
32
+ "ts-keystrokes",
33
+ "ts-callouts",
34
+ "ts-code",
35
+ "ts-glossary",
36
+ "ts-index",
37
+ "ts-bibliography",
38
+ "ts-todolist",
39
+ ]
40
+
41
+ [latex.template.attributes.base_level]
42
+ default = 0
43
+ type = "integer"
44
+ sources = ["base_level"]
45
+ description = "Base heading level offset for slots (0 = chapter, -1 = part)."
46
+
47
+ [latex.template.attributes.title]
48
+ default = "A LaTeX Book Template"
49
+ type = "string"
50
+ escape = "latex"
51
+ allow_empty = true
52
+ sources = ["title"]
53
+
54
+ [latex.template.attributes.subtitle]
55
+ default = "An example of a book template for MkDocs LaTeX"
56
+ type = "string"
57
+ escape = "latex"
58
+ allow_empty = true
59
+ sources = ["subtitle"]
60
+
61
+ [latex.template.attributes.authors]
62
+ default = []
63
+ type = "list"
64
+ sources = ["authors"]
65
+
66
+ [latex.template.attributes.email]
67
+ default = "john.doe@acme.corp"
68
+ type = "string"
69
+ escape = "latex"
70
+ allow_empty = true
71
+ sources = ["email"]
72
+
73
+ [latex.template.attributes.date]
74
+ default = ""
75
+ type = "string"
76
+ escape = "latex"
77
+ allow_empty = true
78
+ sources = ["date"]
79
+
80
+ [latex.template.attributes.language]
81
+ default = "english"
82
+ type = "string"
83
+ allow_empty = false
84
+ normaliser = "babel_language"
85
+ sources = ["language"]
86
+ description = "Language for hyphenation and document terms (babel)."
87
+
88
+ [latex.template.attributes.documentclass]
89
+ default = "memoir"
90
+ type = "string"
91
+ allow_empty = false
92
+ sources = ["documentclass"]
93
+ description = "Document class to use (memoir by default)."
94
+
95
+ [latex.template.attributes.hyperref_options]
96
+ default = "colorlinks=true, linkcolor=black, citecolor=black, plainpages=false, unicode=true, urlcolor=urlcolor"
97
+ type = "string"
98
+ allow_empty = true
99
+ sources = ["hyperref_options"]
100
+ description = "Custom hyperref options appended to defaults."
101
+
102
+ [latex.template.attributes.edition]
103
+ default = ""
104
+ type = "string"
105
+ allow_empty = true
106
+ sources = ["edition"]
107
+ description = "Edition label rendered in imprint."
108
+
109
+ [latex.template.attributes.publisher]
110
+ default = ""
111
+ type = "string"
112
+ allow_empty = true
113
+ sources = ["publisher"]
114
+ description = "Publisher string rendered in imprint."
115
+
116
+ [latex.template.attributes.imprint_thanks]
117
+ default = ""
118
+ type = "string"
119
+ allow_empty = true
120
+ format = "markdown"
121
+ sources = ["imprint.thanks", "imprint_thanks"]
122
+ description = "Imprint thanks paragraph (Markdown)."
123
+
124
+ [latex.template.attributes.imprint_license]
125
+ default = ""
126
+ type = "string"
127
+ allow_empty = true
128
+ format = "markdown"
129
+ sources = ["imprint.license", "imprint_license"]
130
+ description = "Imprint license paragraph (Markdown)."
131
+
132
+ [latex.template.attributes.imprint_copyright]
133
+ default = ""
134
+ type = "string"
135
+ allow_empty = true
136
+ format = "markdown"
137
+ sources = ["imprint.copyright", "imprint_copyright"]
138
+ description = "Imprint copyright paragraph (Markdown)."
139
+
140
+ [latex.template.attributes.glossary]
141
+ default = false
142
+ type = "boolean"
143
+ sources = ["glossary"]
144
+ description = "Enable glossary section."
145
+
146
+ [latex.template.attributes.glossary_style]
147
+ default = "long3col"
148
+ type = "string"
149
+ allow_empty = false
150
+ sources = ["glossary_style"]
151
+ description = "Glossary style to use."
152
+
153
+ [latex.template.attributes.listoffigures]
154
+ default = true
155
+ type = "boolean"
156
+ sources = ["listoffigures"]
157
+ description = "Render list of figures when figures exist."
158
+
159
+ [latex.template.attributes.listoftables]
160
+ default = true
161
+ type = "boolean"
162
+ sources = ["listoftables"]
163
+ description = "Render list of tables when tables exist."
164
+
165
+ [latex.template.attributes.part]
166
+ default = false
167
+ type = "boolean"
168
+ sources = ["part"]
169
+ description = "Use parts above chapters (adjusts mainmatter depth)."
170
+
171
+
172
+ [latex.template.slots.frontmatter]
173
+ depth = "chapter"
174
+
175
+ [latex.template.slots.dedication]
176
+ depth = "chapter"
177
+ strip_heading = true
178
+
179
+ [latex.template.slots.mainmatter]
180
+ default = true
181
+ depth = "chapter"
182
+
183
+ [latex.template.slots.preface]
184
+ base_level = 0
185
+
186
+ [latex.template.slots.backmatter]
187
+ depth = "chapter"
188
+
189
+ [latex.template.slots.appendix]
190
+ depth = "chapter"
191
+ description = "Appendix content inserted before backmatter."
192
+
193
+ [latex.template.slots.colophon]
194
+ depth = "chapter"
195
+ strip_heading = true
196
+
197
+ [latex.template.assets]
198
+ "fixtoc.sty" = { source = "template/fixtoc.sty" }
@@ -0,0 +1,314 @@
1
+ \documentclass\VAR{documentclass_options|default('')}{\VAR{documentclass|default('memoir')}}
2
+
3
+ \usepackage{amssymb} % Additional math symbols
4
+ \usepackage{nicefrac} % For support of: ½, ⅔...
5
+ \usepackage{xurl} % For better URL line breaking reduce overfull hbox
6
+
7
+ \usepackage[svgnames,dvipsnames,x11names]{xcolor}
8
+ \VAR{extra_packages}
9
+
10
+ \usepackage{fancyhdr}
11
+
12
+ \usepackage{graphicx} % For including images
13
+ \usepackage{multicol}
14
+ \usepackage{booktabs}
15
+ \usepackage{csquotes}
16
+ \usepackage{epigraph}
17
+ \usepackage{capt-of}
18
+ \usepackage{enumitem}
19
+ \usepackage{etoolbox}
20
+ \usepackage{tocloft}
21
+ \usepackage{caption}
22
+ \usepackage[colorlinks=true, linkcolor=DarkBlue, urlcolor=DarkBlue, citecolor=DarkBlue]{hyperref}
23
+ \usepackage[\VAR{language|default('english')}]{babel}
24
+ \usepackage{emptypage}
25
+ \usepackage{fixtoc} % Custom package to fix TOC number widths
26
+
27
+ \graphicspath{{assets/}}
28
+
29
+ %
30
+ % Heading style
31
+ %
32
+ \chapterstyle{default} % ou ton style préféré (vehttp, ell, etc.)
33
+
34
+ \renewcommand*{\partnamefont}{\normalfont\sffamily\Huge\bfseries\scshape}
35
+ \renewcommand*{\partnumfont}{\normalfont\sffamily\Huge\bfseries}
36
+ \renewcommand*{\parttitlefont}{\normalfont\sffamily\Huge\bfseries}
37
+
38
+ \renewcommand*{\chapnamefont}{\normalfont\sffamily\Large\scshape}
39
+ \renewcommand*{\chapnumfont}{\normalfont\sffamily\Huge\bfseries}
40
+ \renewcommand*{\chaptitlefont}{\normalfont\sffamily\Huge\bfseries}
41
+ \setsecheadstyle{\sffamily\Large\bfseries}
42
+ \setsubsecheadstyle{\sffamily\large\bfseries}
43
+
44
+ %
45
+ % Table of contents style
46
+ %
47
+ \renewcommand{\cftpartfont}{\sffamily\Large\bfseries}
48
+ \renewcommand{\cftpartpagefont}{\sffamily\Large\bfseries}
49
+ \renewcommand{\cftpartpresnum}{\partname~}
50
+
51
+ %
52
+ % Adjust spacing
53
+ %
54
+
55
+ % Prevent too many overful \hbox (with some fonts)
56
+ \tolerance=2000
57
+ \emergencystretch=10pt
58
+ \hfuzz=1pt
59
+ \hbadness=2000
60
+
61
+ % Give more spaces on Table of content (between numbers and text)
62
+ \setlength{\cftpartnumwidth}{4em}
63
+ \setlength{\cftsectionnumwidth}{3em}
64
+ \setlength{\cftsubsectionnumwidth}{3.5em}
65
+ \setlength{\cftfigurenumwidth}{3em}
66
+ \setlength{\cfttablenumwidth}{3em}
67
+
68
+ % Make quotations italic and smaller
69
+ \AtBeginEnvironment{displayquote}{\small\itshape}
70
+
71
+ % Fit table to page width while keeping tabular optional args (alignment)
72
+ \let\oldtabular\tabular
73
+ \let\endoldtabular\endtabular
74
+
75
+ \newsavebox{\mytablebox}
76
+ \renewenvironment{tabular}[2][c]
77
+ {\begin{lrbox}{\mytablebox}\small\oldtabular[#1]{#2}} % Temporary box to store table
78
+ {\endoldtabular\end{lrbox}%
79
+ \ifdim\wd\mytablebox>\linewidth
80
+ \resizebox{\linewidth}{!}{\usebox{\mytablebox}} % Adjust to fit line width
81
+ \else
82
+ \usebox{\mytablebox} % Otherwise, use the table as is
83
+ \fi
84
+ }
85
+
86
+ \newif\ifgeometryduplex
87
+ \BLOCK{ if geometry_duplex|default(false) }\geometryduplextrue\BLOCK{ else }\geometryduplexfalse\BLOCK{ endif }
88
+
89
+ %
90
+ % Headers and footers
91
+ %
92
+
93
+ % No line on the footer
94
+ \renewcommand{\footrulewidth}{0pt}
95
+
96
+ % Part head pages
97
+ \fancypagestyle{part}{%
98
+ \fancyhf{}
99
+ \renewcommand{\headrulewidth}{0pt}
100
+ }
101
+
102
+ % Chapter head pages
103
+ \fancypagestyle{plain}{%
104
+ \fancyhf{}
105
+ \renewcommand{\headrulewidth}{0pt}
106
+ \ifgeometryduplex
107
+ \fancyfoot[LE,RO]{\thepage}
108
+ \else
109
+ \fancyfoot[RO]{\thepage}
110
+ \fi
111
+ }
112
+
113
+ % Mainmatter regular page style
114
+ \fancypagestyle{fancy}{%
115
+ \fancyhf{}
116
+ \renewcommand{\headrulewidth}{0.5pt}
117
+ \ifgeometryduplex
118
+ \fancyhead[LE]{\scshape \leftmark}
119
+ \fancyhead[RO]{\scshape \rightmark}
120
+ \fancyfoot[LE,RO]{\thepage}
121
+ \else
122
+ \fancyhead[RO]{\scshape \rightmark}
123
+ \fancyhead[LO]{\scshape \leftmark}
124
+ \fancyfoot[RO]{\thepage}
125
+ \fi
126
+ }
127
+ \makeatletter
128
+ \nouppercaseheads
129
+ \renewcommand{\chaptermark}[1]{%
130
+ \markboth{\thechapter\quad #1}{}%
131
+ }
132
+ \renewcommand{\sectionmark}[1]{%
133
+ \markright{\thesection\quad #1}%
134
+ }
135
+ \makeatother
136
+
137
+ % Associate the part page style to the part
138
+ \patchcmd{\part}{\thispagestyle{plain}}{\thispagestyle{part}}{}{}
139
+
140
+ \newcommand{\changelocaltocdepth}[1]{%
141
+ \addtocontents{toc}{\protect\setcounter{tocdepth}{#1}}%
142
+ \setcounter{tocdepth}{#1}%
143
+ }
144
+
145
+ \apptocmd{\frontmatter}{%
146
+ \pagestyle{plain}%
147
+ \changelocaltocdepth{1}%
148
+ \setcounter{secnumdepth}{0}
149
+ }{}{}
150
+
151
+ \apptocmd{\mainmatter}{%
152
+ \pagestyle{fancy}%
153
+ \changelocaltocdepth{2}%
154
+ \setcounter{secnumdepth}{2}
155
+ }{}{}
156
+
157
+ %
158
+ % Tweaks
159
+ %
160
+
161
+ % Allow hyphenation after a hyphen
162
+ \providecommand{\allowhyphens}{\ifvmode\else\nobreak\hspace{0pt}\fi}
163
+
164
+ % To number paragraphs and subparagraphs
165
+ \setcounter{secnumdepth}{5}
166
+
167
+ % Paragraph indentation
168
+ % \setlength{\parindent}{0pt}
169
+ \setlength\parskip{\smallskipamount}
170
+
171
+ % Avoid orphans at the end of a page, encourage page breaks if there are
172
+ % a section with less than 3 lines
173
+ % https://tex.stackexchange.com/a/723704/85416
174
+ \makeatletter
175
+ \patchcmd\@afterheading{\clubpenalty \@M}{\clubpenalties 3 \@M\@M 5000 }{%
176
+ \typeout{patched}}{\typeout{patch failed}
177
+ }
178
+ \makeatother
179
+
180
+ % Allow for short text below parts
181
+ % https://tex.stackexchange.com/a/336401/85416
182
+ % \makeatletter
183
+ % \newcommand{\extraPartText}[1]{\def\@extraPartText{#1}}
184
+ % \pretocmd{\@endpart}{\vspace{8ex}\begingroup\centering\@extraPartText\par\endgroup\let\@extraPartText\relax}{}{}
185
+ % \makeatother
186
+
187
+ % Description item and text are displayed by default on the same line
188
+ % this is not very readable. This command changes the style to display
189
+ % the description text on the next line.
190
+ % https://tex.stackexchange.com/a/430454/85416
191
+ % https://tex.stackexchange.com/a/726879/85416
192
+ \AddToHook{cmd/descriptionlabel/after}{\rule[-8pt]{0pt}{0pt}}
193
+ \setlist[description]{
194
+ style=nextline,
195
+ labelindent=0pt,
196
+ leftmargin=1cm,
197
+ itemindent=\dimexpr-5pt-\labelsep\relax
198
+ }
199
+
200
+
201
+ \newcommand{\booktitle}{\VAR{title}}
202
+ \newcommand{\booksubtitle}{\VAR{subtitle}}
203
+ \newcommand{\bookauthor}{\VAR{author|default('', true)}}
204
+ \newcommand{\bookemail}{\VAR{email}}
205
+ \newcommand{\bookpublisher}{\VAR{publisher}}
206
+ \newcommand{\bookedition}{\VAR{edition}}
207
+ \BLOCK{ set effective_date = date|default('')|trim }
208
+ \newcommand{\bookdate}{\BLOCK{ if effective_date }\VAR{date}\BLOCK{ else }\today\BLOCK{ endif }}
209
+
210
+ \title{\Huge\bfseries\booktitle}
211
+ \author{\bookauthor}
212
+ \makeatletter
213
+ \gdef\@subtitle{\booksubtitle}
214
+ \gdef\@authoremail{\bookemail}
215
+ \makeatother
216
+ \newcommand{\subtitletext}{\booksubtitle}
217
+ \newcommand{\authorname}{\bookauthor}
218
+ \newcommand{\authoremail}{\bookemail}
219
+ \providecommand{\texsmithEmoji}[1]{#1}
220
+
221
+ \definecolor{indigo(dye)}{rgb}{0.0, 0.25, 0.42}
222
+
223
+ \BLOCK{ if glossary }\input{glossary}\BLOCK{ endif }
224
+
225
+ \begin{document}
226
+ \hypersetup{pageanchor=false}
227
+ \frontmatter
228
+ \maketitle
229
+ \thispagestyle{empty}
230
+ \BLOCK{ if imprint_thanks|trim or imprint_license|trim or imprint_copyright|trim }
231
+ \cleardoublepage
232
+ \thispagestyle{plain}
233
+ \phantomsection
234
+ \BLOCK{ if imprint_thanks|trim }
235
+ \subsection*{Thanks}
236
+ \VAR{imprint_thanks}
237
+ \BLOCK{ endif }
238
+ \BLOCK{ if imprint_license|trim }
239
+ \subsection*{License}
240
+ \VAR{imprint_license}
241
+ \BLOCK{ endif }
242
+ \BLOCK{ if imprint_copyright|trim }
243
+ \subsection*{Copyright}
244
+ \VAR{imprint_copyright}
245
+ \BLOCK{ endif }
246
+ \BLOCK{ endif }
247
+
248
+ \BLOCK{ if dedication|trim }
249
+ \cleardoublepage
250
+ \thispagestyle{plain}
251
+ \phantomsection
252
+ \begin{center}
253
+ \vspace*{3cm}
254
+ {\Large\itshape \VAR{dedication}}
255
+ \end{center}
256
+ \BLOCK{ endif }
257
+
258
+ \thispagestyle{empty}
259
+
260
+ \raggedbottom
261
+
262
+
263
+ \BLOCK{ if preface|trim }
264
+ \cleardoublepage
265
+ \thispagestyle{plain}
266
+ \begingroup
267
+ \setsecnumdepth{none}
268
+ \phantomsection
269
+ \VAR{preface}
270
+ \endgroup
271
+ \BLOCK{ endif }
272
+
273
+ \VAR{frontmatter}
274
+
275
+ \clearpage
276
+ \tableofcontents*
277
+
278
+ \hypersetup{pageanchor=true}
279
+ \mainmatter
280
+
281
+ \VAR{mainmatter}
282
+
283
+ \BLOCK{ if appendix }
284
+ \appendix
285
+ \VAR{appendix}
286
+ \BLOCK{ endif }
287
+
288
+ \backmatter
289
+
290
+ \BLOCK{ if listoffigures }
291
+ \ifnum\value{figure}>0
292
+ \clearpage
293
+ \listoffigures
294
+ \fi
295
+ \BLOCK{ endif }
296
+ \BLOCK{ if listoftables }
297
+ \ifnum\value{table}>0
298
+ \clearpage
299
+ \listoftables
300
+ \fi
301
+ \BLOCK{ endif }
302
+
303
+ \VAR{backmatter}
304
+ \VAR{fragment_backmatter}
305
+
306
+ \BLOCK{ if colophon|trim }
307
+ \cleardoublepage
308
+ \phantomsection
309
+ \addcontentsline{toc}{chapter}{Colophon}
310
+ \chapter*{Colophon}
311
+ \VAR{colophon}
312
+ \BLOCK{ endif }
313
+
314
+ \end{document}
@@ -0,0 +1 @@
1
+ """Shared LaTeX assets reused by built-in templates."""