8
8
9
9
import copy
10
10
import re
11
+ import warnings
11
12
from dataclasses import dataclass , field
12
13
from pathlib import Path
13
14
from typing import Any
16
17
17
18
from manim .typing import StrPath
18
19
19
- _DEFAULT_PREAMBLE = r"""
20
- \usepackage[english]{babel}
20
+ _DEFAULT_PREAMBLE = r"""\usepackage[english]{babel}
21
21
\usepackage{amsmath}
22
- \usepackage{amssymb}
23
- """
22
+ \usepackage{amssymb}"""
24
23
25
24
_BEGIN_DOCUMENT = r"\begin{document}"
26
25
_END_DOCUMENT = r"\end{document}"
30
29
class TexTemplate :
31
30
"""TeX templates are used to create ``Tex`` and ``MathTex`` objects."""
32
31
33
- _body : str = field (init = False )
32
+ _body : str = field (default = "" , init = False )
34
33
"""A custom body, can be set from a file."""
35
34
36
35
tex_compiler : str = "latex"
@@ -40,29 +39,32 @@ class TexTemplate:
40
39
"""The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf``."""
41
40
42
41
documentclass : str = r"\documentclass[preview]{standalone}"
43
- r"""The command defining the documentclass, e.g. ``\\ documentclass[preview]{standalone}``."""
42
+ r"""The command defining the documentclass, e.g. ``\documentclass[preview]{standalone}``."""
44
43
45
44
preamble : str = _DEFAULT_PREAMBLE
46
- r"""The document's preamble, i.e. the part between ``\\ documentclass`` and ``\ \begin{document}``."""
45
+ r"""The document's preamble, i.e. the part between ``\documentclass`` and ``\begin{document}``."""
47
46
48
47
placeholder_text : str = "YourTextHere"
49
48
"""Text in the document that will be replaced by the expression to be rendered."""
50
49
51
50
post_doc_commands : str = ""
52
- r"""Text (definitions, commands) to be inserted at right after ``\\ begin{document}``, e.g. ``\ \boldmath``."""
51
+ r"""Text (definitions, commands) to be inserted at right after ``\begin{document}``, e.g. ``\boldmath``."""
53
52
54
53
@property
55
54
def body (self ) -> str :
56
55
"""The entire TeX template."""
57
56
return self ._body or "\n " .join (
58
- [
59
- self .documentclass ,
60
- self .preamble ,
61
- _BEGIN_DOCUMENT ,
62
- self .post_doc_commands ,
63
- self .placeholder_text ,
64
- _END_DOCUMENT ,
65
- ]
57
+ filter (
58
+ None ,
59
+ [
60
+ self .documentclass ,
61
+ self .preamble ,
62
+ _BEGIN_DOCUMENT ,
63
+ self .post_doc_commands ,
64
+ self .placeholder_text ,
65
+ _END_DOCUMENT ,
66
+ ],
67
+ )
66
68
)
67
69
68
70
@body .setter
@@ -80,63 +82,44 @@ def from_file(cls, file: StrPath = "tex_template.tex", **kwargs: Any) -> Self:
80
82
instance .body = Path (file ).read_text (encoding = "utf-8" )
81
83
return instance
82
84
83
- def _texcode_for_environment (self , environment : str ) -> tuple [str , str ]:
84
- r"""Processes the tex_environment string to return the correct ``\\begin{environment}[extra]{extra}`` and
85
- ``\\end{environment}`` strings.
86
-
87
- Parameters
88
- ----------
89
- environment
90
- The tex_environment as a string. Acceptable formats include:
91
- ``{align*}``, ``align*``, ``{tabular}[t]{cccl}``, ``tabular}{cccl``, ``\\begin{tabular}[t]{cccl}``.
92
-
93
- Returns
94
- -------
95
- Tuple[:class:`str`, :class:`str`]
96
- A pair of strings representing the opening and closing of the tex environment, e.g.
97
- ``\\begin{tabular}{cccl}`` and ``\\end{tabular}``
98
- """
99
-
100
- environment .removeprefix (r"\begin" ).removeprefix ("{" )
101
-
102
- # The \begin command takes everything and closes with a brace
103
- begin = r"\begin{" + environment
104
- # If it doesn't end on } or ], assume missing }
105
- if not begin .endswith (("}" , "]" )):
106
- begin += "}"
107
-
108
- # While the \end command terminates at the first closing brace
109
- split_at_brace = re .split ("}" , environment , 1 )
110
- end = r"\end{" + split_at_brace [0 ] + "}"
111
-
112
- return begin , end
113
-
114
85
def add_to_preamble (self , txt : str , prepend : bool = False ) -> Self :
115
86
r"""Adds text to the TeX template's preamble (e.g. definitions, packages). Text can be inserted at the beginning or at the end of the preamble.
116
87
117
88
Parameters
118
89
----------
119
90
txt
120
- String containing the text to be added, e.g. ``\\ usepackage{hyperref}``.
91
+ String containing the text to be added, e.g. ``\usepackage{hyperref}``.
121
92
prepend
122
- Whether the text should be added at the beginning of the preamble, i.e. right after ``\\ documentclass``.
123
- Default is to add it at the end of the preamble, i.e. right before ``\\ begin{document}``.
93
+ Whether the text should be added at the beginning of the preamble, i.e. right after ``\documentclass``.
94
+ Default is to add it at the end of the preamble, i.e. right before ``\begin{document}``.
124
95
"""
96
+ if self ._body :
97
+ warnings .warn (
98
+ "This TeX template was created with a fixed body, trying to add text the preamble will have no effect." ,
99
+ UserWarning ,
100
+ stacklevel = 2 ,
101
+ )
125
102
if prepend :
126
103
self .preamble = txt + "\n " + self .preamble
127
104
else :
128
105
self .preamble += "\n " + txt
129
106
return self
130
107
131
108
def add_to_document (self , txt : str ) -> Self :
132
- r"""Adds text to the TeX template just after \\ begin{document}, e.g. ``\ \boldmath``.
109
+ r"""Adds text to the TeX template just after \begin{document}, e.g. ``\boldmath``.
133
110
134
111
Parameters
135
112
----------
136
113
txt
137
114
String containing the text to be added.
138
115
"""
139
- self .post_doc_commands += "\n " + txt + "\n "
116
+ if self ._body :
117
+ warnings .warn (
118
+ "This TeX template was created with a fixed body, trying to add text the document will have no effect." ,
119
+ UserWarning ,
120
+ stacklevel = 2 ,
121
+ )
122
+ self .post_doc_commands += txt
140
123
return self
141
124
142
125
def get_texcode_for_expression (self , expression : str ) -> str :
@@ -145,7 +128,7 @@ def get_texcode_for_expression(self, expression: str) -> str:
145
128
Parameters
146
129
----------
147
130
expression
148
- The string containing the expression to be typeset, e.g. ``$\\ sqrt{2}$``
131
+ The string containing the expression to be typeset, e.g. ``$\sqrt{2}$``
149
132
150
133
Returns
151
134
-------
@@ -162,7 +145,7 @@ def get_texcode_for_expression_in_env(
162
145
Parameters
163
146
----------
164
147
expression
165
- The string containing the expression to be typeset, e.g. ``$\\ sqrt{2}$``.
148
+ The string containing the expression to be typeset, e.g. ``$\sqrt{2}$``.
166
149
environment
167
150
The string containing the environment in which the expression should be typeset, e.g. ``align*``.
168
151
@@ -171,11 +154,43 @@ def get_texcode_for_expression_in_env(
171
154
:class:`str`
172
155
LaTeX code based on template, containing the given expression inside its environment, ready for typesetting
173
156
"""
174
- begin , end = self . _texcode_for_environment (environment )
157
+ begin , end = _texcode_for_environment (environment )
175
158
return self .body .replace (
176
159
self .placeholder_text , "\n " .join ([begin , expression , end ])
177
160
)
178
161
179
162
def copy (self ) -> Self :
180
163
"""Create a deep copy of the TeX template instance."""
181
164
return copy .deepcopy (self )
165
+
166
+
167
+ def _texcode_for_environment (environment : str ) -> tuple [str , str ]:
168
+ r"""Processes the tex_environment string to return the correct ``\begin{environment}[extra]{extra}`` and
169
+ ``\end{environment}`` strings.
170
+
171
+ Parameters
172
+ ----------
173
+ environment
174
+ The tex_environment as a string. Acceptable formats include:
175
+ ``{align*}``, ``align*``, ``{tabular}[t]{cccl}``, ``tabular}{cccl``, ``\begin{tabular}[t]{cccl}``.
176
+
177
+ Returns
178
+ -------
179
+ Tuple[:class:`str`, :class:`str`]
180
+ A pair of strings representing the opening and closing of the tex environment, e.g.
181
+ ``\begin{tabular}{cccl}`` and ``\end{tabular}``
182
+ """
183
+
184
+ environment .removeprefix (r"\begin" ).removeprefix ("{" )
185
+
186
+ # The \begin command takes everything and closes with a brace
187
+ begin = r"\begin{" + environment
188
+ # If it doesn't end on } or ], assume missing }
189
+ if not begin .endswith (("}" , "]" )):
190
+ begin += "}"
191
+
192
+ # While the \end command terminates at the first closing brace
193
+ split_at_brace = re .split ("}" , environment , 1 )
194
+ end = r"\end{" + split_at_brace [0 ] + "}"
195
+
196
+ return begin , end
0 commit comments