pytex-preprocessor 0.1.0__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.
- pytex/__init__.py +87 -0
- pytex/commands/__init__.py +51 -0
- pytex/commands/biblatex.py +98 -0
- pytex/commands/builtin.py +598 -0
- pytex/commands/captions.py +56 -0
- pytex/commands/cleveref.py +43 -0
- pytex/commands/colors.py +60 -0
- pytex/commands/conditionals.py +62 -0
- pytex/commands/counters.py +85 -0
- pytex/commands/definitions.py +109 -0
- pytex/commands/floats.py +93 -0
- pytex/commands/font.py +138 -0
- pytex/commands/fontawesome.py +88 -0
- pytex/commands/fontspec.py +75 -0
- pytex/commands/geometry.py +25 -0
- pytex/commands/glossaries.py +126 -0
- pytex/commands/graphics.py +68 -0
- pytex/commands/hooks.py +58 -0
- pytex/commands/hyperref.py +57 -0
- pytex/commands/lengths.py +200 -0
- pytex/commands/listings.py +63 -0
- pytex/commands/mdframed.py +43 -0
- pytex/commands/picture.py +32 -0
- pytex/commands/setspace.py +38 -0
- pytex/commands/tables.py +123 -0
- pytex/helpers/__init__.py +3 -0
- pytex/helpers/coerce.py +13 -0
- pytex/helpers/parenting.py +13 -0
- pytex/helpers/sanitize.py +54 -0
- pytex/helpers/with_package.py +61 -0
- pytex/interface/__init__.py +3 -0
- pytex/interface/control_sequence.py +29 -0
- pytex/interface/package.py +52 -0
- pytex/interface/tex.py +41 -0
- pytex/model/__init__.py +25 -0
- pytex/model/color.py +203 -0
- pytex/model/concat.py +31 -0
- pytex/model/control_sequence.py +72 -0
- pytex/model/document.py +120 -0
- pytex/model/document_class.py +29 -0
- pytex/model/empty.py +19 -0
- pytex/model/environment.py +30 -0
- pytex/model/image.py +137 -0
- pytex/model/include.py +21 -0
- pytex/model/length.py +54 -0
- pytex/model/math.py +401 -0
- pytex/model/package.py +132 -0
- pytex/model/raw.py +61 -0
- pytex/packages.py +221 -0
- pytex/registry.py +49 -0
- pytex_builder/__init__.py +8 -0
- pytex_builder/build.py +175 -0
- pytex_builder/console.py +77 -0
- pytex_builder/render.py +90 -0
- pytex_builder/tectonic.py +370 -0
- pytex_hsrtreport/__init__.py +116 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-Bold.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-BoldItalic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-Book.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-BookItalic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-Medium.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-MediumItalic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-Strong.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-Thin.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Blender/Blender-ThinItalic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-Black.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-Bold.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-BoldItalic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-Italic.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-Medium.ttf +0 -0
- pytex_hsrtreport/assets/fonts/DIN/DIN-Regular.ttf +0 -0
- pytex_hsrtreport/assets/fonts/Times New Roman.ttf +0 -0
- pytex_hsrtreport/assets/logos/ASTA.svg +79 -0
- pytex_hsrtreport/assets/logos/DUMMY.png +0 -0
- pytex_hsrtreport/assets/logos/DUMMY_FOOT.png +0 -0
- pytex_hsrtreport/assets/logos/ECHO.svg +226 -0
- pytex_hsrtreport/assets/logos/HSRT.pdf +0 -0
- pytex_hsrtreport/assets/logos/INF.pdf +0 -0
- pytex_hsrtreport/assets/logos/STUPA.pdf +0 -0
- pytex_hsrtreport/assets/logos/Skyline.pdf +0 -0
- pytex_hsrtreport/boxes.py +215 -0
- pytex_hsrtreport/citations.py +21 -0
- pytex_hsrtreport/cleveref_names.py +47 -0
- pytex_hsrtreport/colors.py +30 -0
- pytex_hsrtreport/document.py +307 -0
- pytex_hsrtreport/fonts.py +66 -0
- pytex_hsrtreport/glossary.py +61 -0
- pytex_hsrtreport/hyperref_config.py +49 -0
- pytex_hsrtreport/listings.py +90 -0
- pytex_hsrtreport/logos.py +234 -0
- pytex_hsrtreport/pagebreak.py +67 -0
- pytex_hsrtreport/pagesetup.py +33 -0
- pytex_hsrtreport/tex/pagesetup.tex +76 -0
- pytex_hsrtreport/titlepage.py +136 -0
- pytex_hsrtreport/variants.py +24 -0
- pytex_hsrtreport/voting.py +96 -0
- pytex_hsrtreport/watermark.py +63 -0
- pytex_hsrtreport/wordcount.py +33 -0
- pytex_koma/__init__.py +90 -0
- pytex_koma/commands.py +296 -0
- pytex_koma/document.py +138 -0
- pytex_markdown/__init__.py +62 -0
- pytex_markdown/convert.py +271 -0
- pytex_markdown/escape.py +11 -0
- pytex_preprocessor-0.1.0.dist-info/METADATA +82 -0
- pytex_preprocessor-0.1.0.dist-info/RECORD +119 -0
- pytex_preprocessor-0.1.0.dist-info/WHEEL +5 -0
- pytex_preprocessor-0.1.0.dist-info/entry_points.txt +2 -0
- pytex_preprocessor-0.1.0.dist-info/top_level.txt +7 -0
- pytex_protocol/__init__.py +37 -0
- pytex_protocol/convert.py +202 -0
- pytex_protocol/document.py +91 -0
- pytex_protocol/entries.py +96 -0
- pytex_protocol/frontmatter.py +80 -0
- pytex_protocol/header.py +139 -0
- pytex_protocol/shortcodes.py +130 -0
- pytex_protocol/signatures.py +84 -0
- pytex_tikz/__init__.py +25 -0
- pytex_tikz/tikz.py +272 -0
pytex/model/math.py
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
from ..helpers.with_package import with_package
|
|
2
|
+
from ..interface.tex import TeX
|
|
3
|
+
from ..packages import AMSFONTS, AMSMATH
|
|
4
|
+
from ..registry import Registry
|
|
5
|
+
from .concat import Concat
|
|
6
|
+
from .control_sequence import ControlSequence, Parameter
|
|
7
|
+
from .environment import Environment
|
|
8
|
+
from .raw import Raw
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"Align",
|
|
12
|
+
"AlignStar",
|
|
13
|
+
"BBmatrix",
|
|
14
|
+
"Bar",
|
|
15
|
+
"Binom",
|
|
16
|
+
"Bmatrix",
|
|
17
|
+
"Cases",
|
|
18
|
+
"Ddot",
|
|
19
|
+
"Dfrac",
|
|
20
|
+
"DisplayMath",
|
|
21
|
+
"Dot",
|
|
22
|
+
"Eqref",
|
|
23
|
+
"Equation",
|
|
24
|
+
"EquationStar",
|
|
25
|
+
"Frac",
|
|
26
|
+
"Gather",
|
|
27
|
+
"GatherStar",
|
|
28
|
+
"Hat",
|
|
29
|
+
"IIInt",
|
|
30
|
+
"IInt",
|
|
31
|
+
"Int",
|
|
32
|
+
"LabelM",
|
|
33
|
+
"Lim",
|
|
34
|
+
"Math",
|
|
35
|
+
"Mathbb",
|
|
36
|
+
"Mathbf",
|
|
37
|
+
"Mathcal",
|
|
38
|
+
"Mathfrak",
|
|
39
|
+
"Mathit",
|
|
40
|
+
"Mathrm",
|
|
41
|
+
"Mathsf",
|
|
42
|
+
"Mathtt",
|
|
43
|
+
"Matrix",
|
|
44
|
+
"Multline",
|
|
45
|
+
"OInt",
|
|
46
|
+
"Operatorname",
|
|
47
|
+
"Overbrace",
|
|
48
|
+
"Overline",
|
|
49
|
+
"Pmatrix",
|
|
50
|
+
"Prod",
|
|
51
|
+
"Split",
|
|
52
|
+
"Sqrt",
|
|
53
|
+
"Sub",
|
|
54
|
+
"SubSuper",
|
|
55
|
+
"Substack",
|
|
56
|
+
"Sum",
|
|
57
|
+
"Super",
|
|
58
|
+
"Text",
|
|
59
|
+
"Tfrac",
|
|
60
|
+
"Tilde",
|
|
61
|
+
"Underbrace",
|
|
62
|
+
"UnderlineM",
|
|
63
|
+
"VVmatrix",
|
|
64
|
+
"Vec",
|
|
65
|
+
"Vmatrix",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@Registry.add
|
|
70
|
+
def Math(body: TeX | str) -> TeX:
|
|
71
|
+
return Concat(
|
|
72
|
+
ControlSequence("(", ()),
|
|
73
|
+
body,
|
|
74
|
+
ControlSequence(")", ()),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@Registry.add
|
|
79
|
+
def DisplayMath(body: TeX | str) -> TeX:
|
|
80
|
+
return Concat(
|
|
81
|
+
ControlSequence("[", ()),
|
|
82
|
+
body,
|
|
83
|
+
ControlSequence("]", ()),
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@Registry.add
|
|
88
|
+
def Equation(body: TeX | str) -> TeX:
|
|
89
|
+
return Environment("equation", body)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@Registry.add
|
|
93
|
+
def EquationStar(body: TeX | str) -> TeX:
|
|
94
|
+
return Environment("equation*", body)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@Registry.add
|
|
98
|
+
@with_package(AMSMATH)
|
|
99
|
+
def Align(body: TeX | str) -> TeX:
|
|
100
|
+
return Environment("align", body)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@Registry.add
|
|
104
|
+
@with_package(AMSMATH)
|
|
105
|
+
def AlignStar(body: TeX | str) -> TeX:
|
|
106
|
+
return Environment("align*", body)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@Registry.add
|
|
110
|
+
@with_package(AMSMATH)
|
|
111
|
+
def Gather(body: TeX | str) -> TeX:
|
|
112
|
+
return Environment("gather", body)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@Registry.add
|
|
116
|
+
@with_package(AMSMATH)
|
|
117
|
+
def GatherStar(body: TeX | str) -> TeX:
|
|
118
|
+
return Environment("gather*", body)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@Registry.add
|
|
122
|
+
@with_package(AMSMATH)
|
|
123
|
+
def Multline(body: TeX | str) -> TeX:
|
|
124
|
+
return Environment("multline", body)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@Registry.add
|
|
128
|
+
@with_package(AMSMATH)
|
|
129
|
+
def Split(body: TeX | str) -> TeX:
|
|
130
|
+
return Environment("split", body)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@Registry.add
|
|
134
|
+
@with_package(AMSMATH)
|
|
135
|
+
def Cases(body: TeX | str) -> TeX:
|
|
136
|
+
return Environment("cases", body)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _matrix(kind: str, rows: list[list[TeX | str]]) -> TeX:
|
|
140
|
+
body_str = " \\\\ ".join(" & ".join(str(c) for c in row) for row in rows)
|
|
141
|
+
return Environment(kind, Raw(body_str))
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@Registry.add
|
|
145
|
+
@with_package(AMSMATH)
|
|
146
|
+
def Matrix(rows: list[list[TeX | str]]) -> TeX:
|
|
147
|
+
return _matrix("matrix", rows)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@Registry.add
|
|
151
|
+
@with_package(AMSMATH)
|
|
152
|
+
def Pmatrix(rows: list[list[TeX | str]]) -> TeX:
|
|
153
|
+
return _matrix("pmatrix", rows)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@Registry.add
|
|
157
|
+
@with_package(AMSMATH)
|
|
158
|
+
def Bmatrix(rows: list[list[TeX | str]]) -> TeX:
|
|
159
|
+
return _matrix("bmatrix", rows)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@Registry.add
|
|
163
|
+
@with_package(AMSMATH)
|
|
164
|
+
def Vmatrix(rows: list[list[TeX | str]]) -> TeX:
|
|
165
|
+
return _matrix("vmatrix", rows)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
@Registry.add
|
|
169
|
+
@with_package(AMSMATH)
|
|
170
|
+
def BBmatrix(rows: list[list[TeX | str]]) -> TeX:
|
|
171
|
+
return _matrix("Bmatrix", rows)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@Registry.add
|
|
175
|
+
@with_package(AMSMATH)
|
|
176
|
+
def VVmatrix(rows: list[list[TeX | str]]) -> TeX:
|
|
177
|
+
return _matrix("Vmatrix", rows)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
@Registry.add
|
|
181
|
+
def Frac(num: TeX | str, den: TeX | str) -> TeX:
|
|
182
|
+
return ControlSequence("frac", (Parameter(num), Parameter(den)))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@Registry.add
|
|
186
|
+
@with_package(AMSMATH)
|
|
187
|
+
def Dfrac(num: TeX | str, den: TeX | str) -> TeX:
|
|
188
|
+
return ControlSequence("dfrac", (Parameter(num), Parameter(den)))
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@Registry.add
|
|
192
|
+
@with_package(AMSMATH)
|
|
193
|
+
def Tfrac(num: TeX | str, den: TeX | str) -> TeX:
|
|
194
|
+
return ControlSequence("tfrac", (Parameter(num), Parameter(den)))
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@Registry.add
|
|
198
|
+
@with_package(AMSMATH)
|
|
199
|
+
def Binom(top: TeX | str, bot: TeX | str) -> TeX:
|
|
200
|
+
return ControlSequence("binom", (Parameter(top), Parameter(bot)))
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@Registry.add
|
|
204
|
+
def Sqrt(body: TeX | str, n: TeX | str | None = None) -> TeX:
|
|
205
|
+
if n is None:
|
|
206
|
+
return ControlSequence("sqrt", (Parameter(body),))
|
|
207
|
+
return ControlSequence("sqrt", (Parameter(n, optional=True), Parameter(body)))
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _sub_super(base: TeX, sub: TeX | str | None, sup: TeX | str | None) -> TeX:
|
|
211
|
+
parts: list[TeX | str] = [base]
|
|
212
|
+
if sub is not None:
|
|
213
|
+
parts.append(Raw("_{"))
|
|
214
|
+
parts.append(sub)
|
|
215
|
+
parts.append(Raw("}"))
|
|
216
|
+
if sup is not None:
|
|
217
|
+
parts.append(Raw("^{"))
|
|
218
|
+
parts.append(sup)
|
|
219
|
+
parts.append(Raw("}"))
|
|
220
|
+
return Concat(*parts)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@Registry.add
|
|
224
|
+
def Sub(base: TeX | str, sub: TeX | str) -> TeX:
|
|
225
|
+
return _sub_super(base if isinstance(base, TeX) else Raw(base), sub, None)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@Registry.add
|
|
229
|
+
def Super(base: TeX | str, sup: TeX | str) -> TeX:
|
|
230
|
+
return _sub_super(base if isinstance(base, TeX) else Raw(base), None, sup)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@Registry.add
|
|
234
|
+
def SubSuper(base: TeX | str, sub: TeX | str, sup: TeX | str) -> TeX:
|
|
235
|
+
return _sub_super(base if isinstance(base, TeX) else Raw(base), sub, sup)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@Registry.add
|
|
239
|
+
def Sum(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
240
|
+
return _sub_super(ControlSequence("sum", ()), lower, upper)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@Registry.add
|
|
244
|
+
def Prod(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
245
|
+
return _sub_super(ControlSequence("prod", ()), lower, upper)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@Registry.add
|
|
249
|
+
def Int(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
250
|
+
return _sub_super(ControlSequence("int", ()), lower, upper)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@Registry.add
|
|
254
|
+
def OInt(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
255
|
+
return _sub_super(ControlSequence("oint", ()), lower, upper)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@Registry.add
|
|
259
|
+
@with_package(AMSMATH)
|
|
260
|
+
def IInt(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
261
|
+
return _sub_super(ControlSequence("iint", ()), lower, upper)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
@Registry.add
|
|
265
|
+
@with_package(AMSMATH)
|
|
266
|
+
def IIInt(lower: TeX | str | None = None, upper: TeX | str | None = None) -> TeX:
|
|
267
|
+
return _sub_super(ControlSequence("iiint", ()), lower, upper)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
@Registry.add
|
|
271
|
+
def Lim(var: TeX | str, to: TeX | str) -> TeX:
|
|
272
|
+
return _sub_super(
|
|
273
|
+
ControlSequence("lim", ()),
|
|
274
|
+
Concat(
|
|
275
|
+
var if isinstance(var, TeX) else Raw(var),
|
|
276
|
+
Raw(" \\to "),
|
|
277
|
+
to if isinstance(to, TeX) else Raw(to),
|
|
278
|
+
),
|
|
279
|
+
None,
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
@Registry.add
|
|
284
|
+
@with_package(AMSMATH)
|
|
285
|
+
def Text(body: TeX | str) -> TeX:
|
|
286
|
+
return ControlSequence("text", (Parameter(body),))
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
@Registry.add
|
|
290
|
+
@with_package(AMSFONTS)
|
|
291
|
+
def Mathbb(body: TeX | str) -> TeX:
|
|
292
|
+
return ControlSequence("mathbb", (Parameter(body),))
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@Registry.add
|
|
296
|
+
def Mathcal(body: TeX | str) -> TeX:
|
|
297
|
+
return ControlSequence("mathcal", (Parameter(body),))
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@Registry.add
|
|
301
|
+
@with_package(AMSFONTS)
|
|
302
|
+
def Mathfrak(body: TeX | str) -> TeX:
|
|
303
|
+
return ControlSequence("mathfrak", (Parameter(body),))
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@Registry.add
|
|
307
|
+
def Mathbf(body: TeX | str) -> TeX:
|
|
308
|
+
return ControlSequence("mathbf", (Parameter(body),))
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
@Registry.add
|
|
312
|
+
def Mathit(body: TeX | str) -> TeX:
|
|
313
|
+
return ControlSequence("mathit", (Parameter(body),))
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@Registry.add
|
|
317
|
+
def Mathrm(body: TeX | str) -> TeX:
|
|
318
|
+
return ControlSequence("mathrm", (Parameter(body),))
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@Registry.add
|
|
322
|
+
def Mathsf(body: TeX | str) -> TeX:
|
|
323
|
+
return ControlSequence("mathsf", (Parameter(body),))
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
@Registry.add
|
|
327
|
+
def Mathtt(body: TeX | str) -> TeX:
|
|
328
|
+
return ControlSequence("mathtt", (Parameter(body),))
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
@Registry.add
|
|
332
|
+
def Overline(body: TeX | str) -> TeX:
|
|
333
|
+
return ControlSequence("overline", (Parameter(body),))
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
@Registry.add
|
|
337
|
+
def UnderlineM(body: TeX | str) -> TeX:
|
|
338
|
+
return ControlSequence("underline", (Parameter(body),))
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@Registry.add
|
|
342
|
+
def Overbrace(body: TeX | str) -> TeX:
|
|
343
|
+
return ControlSequence("overbrace", (Parameter(body),))
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@Registry.add
|
|
347
|
+
def Underbrace(body: TeX | str) -> TeX:
|
|
348
|
+
return ControlSequence("underbrace", (Parameter(body),))
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
@Registry.add
|
|
352
|
+
def Hat(body: TeX | str) -> TeX:
|
|
353
|
+
return ControlSequence("hat", (Parameter(body),))
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
@Registry.add
|
|
357
|
+
def Tilde(body: TeX | str) -> TeX:
|
|
358
|
+
return ControlSequence("tilde", (Parameter(body),))
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
@Registry.add
|
|
362
|
+
def Bar(body: TeX | str) -> TeX:
|
|
363
|
+
return ControlSequence("bar", (Parameter(body),))
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
@Registry.add
|
|
367
|
+
def Vec(body: TeX | str) -> TeX:
|
|
368
|
+
return ControlSequence("vec", (Parameter(body),))
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
@Registry.add
|
|
372
|
+
def Dot(body: TeX | str) -> TeX:
|
|
373
|
+
return ControlSequence("dot", (Parameter(body),))
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
@Registry.add
|
|
377
|
+
def Ddot(body: TeX | str) -> TeX:
|
|
378
|
+
return ControlSequence("ddot", (Parameter(body),))
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
@Registry.add
|
|
382
|
+
def LabelM(name: str) -> TeX:
|
|
383
|
+
return ControlSequence("label", (Parameter(name),))
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
@Registry.add
|
|
387
|
+
@with_package(AMSMATH)
|
|
388
|
+
def Eqref(name: str) -> TeX:
|
|
389
|
+
return ControlSequence("eqref", (Parameter(name),))
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
@Registry.add
|
|
393
|
+
@with_package(AMSMATH)
|
|
394
|
+
def Operatorname(name: str) -> TeX:
|
|
395
|
+
return ControlSequence("operatorname", (Parameter(name),))
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
@Registry.add
|
|
399
|
+
@with_package(AMSMATH)
|
|
400
|
+
def Substack(body: TeX | str) -> TeX:
|
|
401
|
+
return ControlSequence("substack", (Parameter(body),))
|
pytex/model/package.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from logging import Logger
|
|
2
|
+
from typing import Self, override
|
|
3
|
+
|
|
4
|
+
from ..interface.package import PackageProtocol
|
|
5
|
+
from ..interface.tex import TeX
|
|
6
|
+
from ..registry import Registry
|
|
7
|
+
|
|
8
|
+
__all__ = ["DefinePackage", "Package"]
|
|
9
|
+
|
|
10
|
+
PACKAGES = dict[str, "Package"]()
|
|
11
|
+
|
|
12
|
+
type PackageOption = str | tuple[str, str]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@Registry.add
|
|
16
|
+
class Package(PackageProtocol, TeX):
|
|
17
|
+
_name: str
|
|
18
|
+
_after: set[Self]
|
|
19
|
+
_incompatible: set[Self]
|
|
20
|
+
_options: set[PackageOption]
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: str,
|
|
25
|
+
after: set[Self] | frozenset[Self] | None = None,
|
|
26
|
+
incompatible: set[Self] | frozenset[Self] | None = None,
|
|
27
|
+
options: set[PackageOption] | frozenset[PackageOption] | None = None,
|
|
28
|
+
) -> None:
|
|
29
|
+
self._name, self._after, self._incompatible, self._options = (
|
|
30
|
+
name,
|
|
31
|
+
set(after or set()),
|
|
32
|
+
set(incompatible or set()),
|
|
33
|
+
set(options or set()),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
@override
|
|
38
|
+
def name(self) -> str:
|
|
39
|
+
return self._name
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
@override
|
|
43
|
+
def after(self) -> frozenset[Self]:
|
|
44
|
+
return frozenset(self._after)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
@override
|
|
48
|
+
def incompatible(self) -> frozenset[Self]:
|
|
49
|
+
return frozenset(self._incompatible)
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
@override
|
|
53
|
+
def options(self) -> frozenset[PackageOption]:
|
|
54
|
+
return frozenset(self._options)
|
|
55
|
+
|
|
56
|
+
def amend(
|
|
57
|
+
self,
|
|
58
|
+
after: set[Self] | frozenset[Self] | None = None,
|
|
59
|
+
incompatible: set[Self] | frozenset[Self] | None = None,
|
|
60
|
+
) -> None:
|
|
61
|
+
if after is not None:
|
|
62
|
+
self._after |= after
|
|
63
|
+
if incompatible is not None:
|
|
64
|
+
self._incompatible |= incompatible
|
|
65
|
+
|
|
66
|
+
def __post_init__(self) -> None:
|
|
67
|
+
if self.name not in PACKAGES:
|
|
68
|
+
PACKAGES[self.name] = self
|
|
69
|
+
else:
|
|
70
|
+
Logger(self.__class__.__name__).warning(
|
|
71
|
+
f"Multiple Instances of {self.name} in circulation!"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def _options_string(self) -> str:
|
|
76
|
+
return (
|
|
77
|
+
f"[{
|
|
78
|
+
','.join(
|
|
79
|
+
item if isinstance(item, str) else f'{item[0]}={item[1]}'
|
|
80
|
+
for item in self.options
|
|
81
|
+
)
|
|
82
|
+
}]"
|
|
83
|
+
if len(self.options) != 0
|
|
84
|
+
else ""
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
@override
|
|
89
|
+
def rendered(self) -> str:
|
|
90
|
+
"""Render this object to a valid LaTeX-String"""
|
|
91
|
+
|
|
92
|
+
return f"\\usepackage{self._options_string}{{{self.name}}}"
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
@override
|
|
96
|
+
def children(self) -> tuple[Self, ...]:
|
|
97
|
+
return ()
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
@override
|
|
101
|
+
def requires(self) -> frozenset[Self]:
|
|
102
|
+
return frozenset(self.after)
|
|
103
|
+
|
|
104
|
+
@override
|
|
105
|
+
def __str__(self) -> str:
|
|
106
|
+
return self.rendered
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@Registry.add
|
|
110
|
+
def DefinePackage(
|
|
111
|
+
name: str,
|
|
112
|
+
after: set[Package] | None = None,
|
|
113
|
+
incompatible: set[Package] | None = None,
|
|
114
|
+
options: set[PackageOption] | None = None,
|
|
115
|
+
) -> Package:
|
|
116
|
+
after, incompatible, options = (
|
|
117
|
+
after or set(),
|
|
118
|
+
incompatible or set(),
|
|
119
|
+
options or set(),
|
|
120
|
+
)
|
|
121
|
+
if name in PACKAGES:
|
|
122
|
+
PACKAGES[name].amend(after=after, incompatible=incompatible)
|
|
123
|
+
return PACKAGES[name]
|
|
124
|
+
|
|
125
|
+
pkg = Package(
|
|
126
|
+
name=name,
|
|
127
|
+
after=after,
|
|
128
|
+
incompatible=incompatible,
|
|
129
|
+
options=options,
|
|
130
|
+
)
|
|
131
|
+
PACKAGES[name] = pkg
|
|
132
|
+
return pkg
|
pytex/model/raw.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# pyright: reportAny=false
|
|
2
|
+
import re
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import override
|
|
5
|
+
|
|
6
|
+
from ..interface.tex import TeX
|
|
7
|
+
from ..registry import Registry
|
|
8
|
+
|
|
9
|
+
__all__ = ["Raw", "pytex_namespace"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _nested_inner(depth: int) -> str:
|
|
13
|
+
inner = r"[^()]*"
|
|
14
|
+
for _ in range(depth):
|
|
15
|
+
inner = rf"(?:[^()]|\({inner}\))*"
|
|
16
|
+
return inner
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
PATTERN = re.compile(
|
|
20
|
+
rf"\\iffalse\s*\{{\s*pytex\s*\((?P<expr>{_nested_inner(8)})\)\s*\}}\s*\\fi",
|
|
21
|
+
re.DOTALL,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def pytex_namespace(extra: dict[str, object] | None = None) -> dict[str, object]:
|
|
26
|
+
"""Namespace used to ``eval`` ``pytex(...)`` expressions.
|
|
27
|
+
|
|
28
|
+
Exposes Python builtins plus every Registry-registered factory, so the same
|
|
29
|
+
names work in both escape hatches: ``\\iffalse{pytex(...)}\\fi`` (TeX) and
|
|
30
|
+
``[//]: # "..."`` (Markdown).
|
|
31
|
+
"""
|
|
32
|
+
return {
|
|
33
|
+
"__builtins__": __builtins__,
|
|
34
|
+
**Registry.namespace(),
|
|
35
|
+
**(extra or {}),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _evaluate(content: str, extra: dict[str, object]) -> str:
|
|
40
|
+
namespace = pytex_namespace(extra)
|
|
41
|
+
|
|
42
|
+
def _sub(match: re.Match[str]) -> str:
|
|
43
|
+
return str(eval(match.group("expr"), namespace))
|
|
44
|
+
|
|
45
|
+
return PATTERN.sub(_sub, content)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@Registry.add
|
|
49
|
+
@dataclass
|
|
50
|
+
class Raw(TeX):
|
|
51
|
+
content: str
|
|
52
|
+
namespace: dict[str, object] | None = field(default=None)
|
|
53
|
+
allow_replacements: bool = True
|
|
54
|
+
_parent: "TeX | None" = field(default=None, init=False, compare=False, repr=False)
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
@override
|
|
58
|
+
def rendered(self) -> str:
|
|
59
|
+
if not self.allow_replacements or "\\iffalse" not in self.content:
|
|
60
|
+
return self.content
|
|
61
|
+
return _evaluate(self.content, self.namespace or {})
|