manim 0.17.0__py3-none-any.whl → 0.19.1__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.
- manim/__init__.py +11 -6
- manim/__main__.py +62 -19
- manim/_config/__init__.py +10 -9
- manim/_config/cli_colors.py +26 -9
- manim/_config/default.cfg +1 -3
- manim/_config/logger_utils.py +23 -13
- manim/_config/utils.py +662 -468
- manim/animation/animation.py +164 -18
- manim/animation/changing.py +34 -23
- manim/animation/composition.py +265 -67
- manim/animation/creation.py +208 -26
- manim/animation/fading.py +16 -18
- manim/animation/growing.py +35 -15
- manim/animation/indication.py +150 -76
- manim/animation/movement.py +56 -22
- manim/animation/numbers.py +64 -6
- manim/animation/rotation.py +78 -7
- manim/animation/specialized.py +6 -7
- manim/animation/speedmodifier.py +13 -10
- manim/animation/transform.py +14 -11
- manim/animation/transform_matching_parts.py +3 -4
- manim/animation/updaters/mobject_update_utils.py +152 -30
- manim/animation/updaters/update.py +10 -7
- manim/camera/camera.py +182 -118
- manim/camera/mapping_camera.py +34 -3
- manim/camera/moving_camera.py +95 -74
- manim/camera/multi_camera.py +23 -15
- manim/camera/three_d_camera.py +70 -52
- manim/cli/__init__.py +17 -0
- manim/cli/cfg/group.py +76 -44
- manim/cli/checkhealth/checks.py +192 -0
- manim/cli/checkhealth/commands.py +90 -0
- manim/cli/default_group.py +158 -25
- manim/cli/init/commands.py +33 -25
- manim/cli/plugins/commands.py +16 -3
- manim/cli/render/commands.py +72 -60
- manim/cli/render/ease_of_access_options.py +4 -3
- manim/cli/render/global_options.py +59 -17
- manim/cli/render/output_options.py +6 -5
- manim/cli/render/render_options.py +98 -33
- manim/constants.py +109 -59
- manim/data_structures.py +31 -0
- manim/mobject/frame.py +8 -5
- manim/mobject/geometry/__init__.py +1 -0
- manim/mobject/geometry/arc.py +277 -135
- manim/mobject/geometry/boolean_ops.py +32 -31
- manim/mobject/geometry/labeled.py +376 -0
- manim/mobject/geometry/line.py +192 -87
- manim/mobject/geometry/polygram.py +224 -58
- manim/mobject/geometry/shape_matchers.py +61 -25
- manim/mobject/geometry/tips.py +122 -48
- manim/mobject/graph.py +1027 -419
- manim/mobject/graphing/coordinate_systems.py +533 -278
- manim/mobject/graphing/functions.py +53 -32
- manim/mobject/graphing/number_line.py +123 -65
- manim/mobject/graphing/probability.py +88 -62
- manim/mobject/graphing/scale.py +33 -19
- manim/mobject/logo.py +118 -28
- manim/mobject/matrix.py +87 -83
- manim/mobject/mobject.py +912 -442
- manim/mobject/opengl/dot_cloud.py +16 -5
- manim/mobject/opengl/opengl_compatibility.py +4 -2
- manim/mobject/opengl/opengl_geometry.py +254 -153
- manim/mobject/opengl/opengl_image_mobject.py +3 -1
- manim/mobject/opengl/opengl_mobject.py +779 -482
- manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
- manim/mobject/opengl/opengl_surface.py +14 -92
- manim/mobject/opengl/opengl_three_dimensions.py +12 -8
- manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
- manim/mobject/svg/brace.py +173 -41
- manim/mobject/svg/svg_mobject.py +139 -53
- manim/mobject/table.py +61 -68
- manim/mobject/text/code_mobject.py +193 -539
- manim/mobject/text/numbers.py +81 -34
- manim/mobject/text/tex_mobject.py +130 -78
- manim/mobject/text/text_mobject.py +288 -164
- manim/mobject/three_d/polyhedra.py +111 -13
- manim/mobject/three_d/three_d_utils.py +17 -8
- manim/mobject/three_d/three_dimensions.py +239 -106
- manim/mobject/types/image_mobject.py +50 -30
- manim/mobject/types/point_cloud_mobject.py +120 -75
- manim/mobject/types/vectorized_mobject.py +841 -408
- manim/mobject/value_tracker.py +105 -38
- manim/mobject/vector_field.py +50 -31
- manim/opengl/__init__.py +3 -3
- manim/plugins/__init__.py +14 -1
- manim/plugins/plugins_flags.py +10 -14
- manim/renderer/cairo_renderer.py +65 -50
- manim/renderer/opengl_renderer.py +89 -69
- manim/renderer/opengl_renderer_window.py +39 -18
- manim/renderer/shader.py +123 -87
- manim/renderer/shader_wrapper.py +44 -28
- manim/renderer/vectorized_mobject_rendering.py +38 -10
- manim/scene/moving_camera_scene.py +32 -3
- manim/scene/scene.py +507 -242
- manim/scene/scene_file_writer.py +371 -220
- manim/scene/section.py +20 -16
- manim/scene/three_d_scene.py +14 -22
- manim/scene/vector_space_scene.py +223 -129
- manim/scene/zoomed_scene.py +46 -41
- manim/typing.py +990 -0
- manim/utils/bezier.py +1823 -371
- manim/utils/caching.py +12 -5
- manim/utils/color/AS2700.py +236 -0
- manim/utils/color/BS381.py +318 -0
- manim/utils/color/DVIPSNAMES.py +96 -0
- manim/utils/color/SVGNAMES.py +179 -0
- manim/utils/color/X11.py +533 -0
- manim/utils/color/XKCD.py +952 -0
- manim/utils/color/__init__.py +61 -0
- manim/utils/color/core.py +1667 -0
- manim/utils/color/manim_colors.py +218 -0
- manim/utils/commands.py +48 -20
- manim/utils/config_ops.py +39 -19
- manim/utils/debug.py +8 -7
- manim/utils/deprecation.py +86 -39
- manim/utils/docbuild/__init__.py +17 -0
- manim/utils/docbuild/autoaliasattr_directive.py +236 -0
- manim/utils/docbuild/autocolor_directive.py +99 -0
- manim/utils/docbuild/manim_directive.py +94 -41
- manim/utils/docbuild/module_parsing.py +245 -0
- manim/utils/exceptions.py +6 -0
- manim/utils/family.py +5 -3
- manim/utils/family_ops.py +17 -4
- manim/utils/file_ops.py +27 -17
- manim/utils/hashing.py +55 -45
- manim/utils/images.py +13 -7
- manim/utils/ipython_magic.py +13 -7
- manim/utils/iterables.py +163 -120
- manim/utils/module_ops.py +66 -24
- manim/utils/opengl.py +77 -24
- manim/utils/parameter_parsing.py +32 -0
- manim/utils/paths.py +30 -33
- manim/utils/polylabel.py +235 -0
- manim/utils/qhull.py +218 -0
- manim/utils/rate_functions.py +98 -32
- manim/utils/simple_functions.py +25 -33
- manim/utils/sounds.py +7 -1
- manim/utils/space_ops.py +188 -115
- manim/utils/testing/__init__.py +17 -0
- manim/utils/testing/_frames_testers.py +13 -8
- manim/utils/testing/_show_diff.py +5 -3
- manim/utils/testing/_test_class_makers.py +34 -18
- manim/utils/testing/frames_comparison.py +37 -19
- manim/utils/tex.py +130 -198
- manim/utils/tex_file_writing.py +77 -47
- manim/utils/tex_templates.py +2 -1
- manim/utils/unit.py +6 -5
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
- manim-0.19.1.dist-info/RECORD +220 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
- manim-0.19.1.dist-info/entry_points.txt +3 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
- manim/cli/new/group.py +0 -189
- manim/communitycolors.py +0 -9
- manim/gui/__init__.py +0 -0
- manim/gui/gui.py +0 -82
- manim/plugins/import_plugins.py +0 -43
- manim/utils/color.py +0 -552
- manim-0.17.0.dist-info/RECORD +0 -206
- manim-0.17.0.dist-info/entry_points.txt +0 -4
- /manim/cli/{new → checkhealth}/__init__.py +0 -0
- {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -12,6 +12,8 @@ r"""Mobjects representing text rendered using LaTeX.
|
|
|
12
12
|
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
from manim.utils.color import BLACK, ManimColor, ParsableManimColor
|
|
16
|
+
|
|
15
17
|
__all__ = [
|
|
16
18
|
"SingleStringMathTex",
|
|
17
19
|
"MathTex",
|
|
@@ -24,24 +26,21 @@ __all__ = [
|
|
|
24
26
|
import itertools as it
|
|
25
27
|
import operator as op
|
|
26
28
|
import re
|
|
29
|
+
from collections.abc import Iterable, Sequence
|
|
27
30
|
from functools import reduce
|
|
28
31
|
from textwrap import dedent
|
|
29
|
-
from typing import
|
|
32
|
+
from typing import Any
|
|
30
33
|
|
|
31
|
-
from
|
|
34
|
+
from typing_extensions import Self
|
|
32
35
|
|
|
33
36
|
from manim import config, logger
|
|
34
37
|
from manim.constants import *
|
|
35
38
|
from manim.mobject.geometry.line import Line
|
|
36
39
|
from manim.mobject.svg.svg_mobject import SVGMobject
|
|
37
|
-
from manim.mobject.types.vectorized_mobject import
|
|
40
|
+
from manim.mobject.types.vectorized_mobject import VGroup, VMobject
|
|
38
41
|
from manim.utils.tex import TexTemplate
|
|
39
42
|
from manim.utils.tex_file_writing import tex_to_svg_file
|
|
40
43
|
|
|
41
|
-
SCALE_FACTOR_PER_FONT_POINT = 1 / 960
|
|
42
|
-
|
|
43
|
-
tex_string_to_mob_map = {}
|
|
44
|
-
|
|
45
44
|
|
|
46
45
|
class SingleStringMathTex(SVGMobject):
|
|
47
46
|
"""Elementary building block for rendering text with LaTeX.
|
|
@@ -61,25 +60,22 @@ class SingleStringMathTex(SVGMobject):
|
|
|
61
60
|
should_center: bool = True,
|
|
62
61
|
height: float | None = None,
|
|
63
62
|
organize_left_to_right: bool = False,
|
|
64
|
-
tex_environment: str = "align*",
|
|
63
|
+
tex_environment: str | None = "align*",
|
|
65
64
|
tex_template: TexTemplate | None = None,
|
|
66
65
|
font_size: float = DEFAULT_FONT_SIZE,
|
|
67
|
-
|
|
66
|
+
color: ParsableManimColor | None = None,
|
|
67
|
+
**kwargs: Any,
|
|
68
68
|
):
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# makes it so that color isn't explicitly passed for these mobs,
|
|
72
|
-
# and can instead inherit from the parent
|
|
73
|
-
kwargs["color"] = VMobject().color
|
|
69
|
+
if color is None:
|
|
70
|
+
color = VMobject().color
|
|
74
71
|
|
|
75
72
|
self._font_size = font_size
|
|
76
73
|
self.organize_left_to_right = organize_left_to_right
|
|
77
74
|
self.tex_environment = tex_environment
|
|
78
75
|
if tex_template is None:
|
|
79
76
|
tex_template = config["tex_template"]
|
|
80
|
-
self.tex_template = tex_template
|
|
77
|
+
self.tex_template: TexTemplate = tex_template
|
|
81
78
|
|
|
82
|
-
assert isinstance(tex_string, str)
|
|
83
79
|
self.tex_string = tex_string
|
|
84
80
|
file_name = tex_to_svg_file(
|
|
85
81
|
self._get_modified_expression(tex_string),
|
|
@@ -91,6 +87,7 @@ class SingleStringMathTex(SVGMobject):
|
|
|
91
87
|
should_center=should_center,
|
|
92
88
|
stroke_width=stroke_width,
|
|
93
89
|
height=height,
|
|
90
|
+
color=color,
|
|
94
91
|
path_string_config={
|
|
95
92
|
"should_subdivide_sharp_curves": True,
|
|
96
93
|
"should_remove_null_curves": True,
|
|
@@ -108,16 +105,16 @@ class SingleStringMathTex(SVGMobject):
|
|
|
108
105
|
if self.organize_left_to_right:
|
|
109
106
|
self._organize_submobjects_left_to_right()
|
|
110
107
|
|
|
111
|
-
def __repr__(self):
|
|
108
|
+
def __repr__(self) -> str:
|
|
112
109
|
return f"{type(self).__name__}({repr(self.tex_string)})"
|
|
113
110
|
|
|
114
111
|
@property
|
|
115
|
-
def font_size(self):
|
|
112
|
+
def font_size(self) -> float:
|
|
116
113
|
"""The font size of the tex mobject."""
|
|
117
114
|
return self.height / self.initial_height / SCALE_FACTOR_PER_FONT_POINT
|
|
118
115
|
|
|
119
116
|
@font_size.setter
|
|
120
|
-
def font_size(self, font_val):
|
|
117
|
+
def font_size(self, font_val: float) -> None:
|
|
121
118
|
if font_val <= 0:
|
|
122
119
|
raise ValueError("font_size must be greater than 0.")
|
|
123
120
|
elif self.height > 0:
|
|
@@ -128,13 +125,13 @@ class SingleStringMathTex(SVGMobject):
|
|
|
128
125
|
# font_size does not depend on current size.
|
|
129
126
|
self.scale(font_val / self.font_size)
|
|
130
127
|
|
|
131
|
-
def _get_modified_expression(self, tex_string):
|
|
128
|
+
def _get_modified_expression(self, tex_string: str) -> str:
|
|
132
129
|
result = tex_string
|
|
133
130
|
result = result.strip()
|
|
134
131
|
result = self._modify_special_strings(result)
|
|
135
132
|
return result
|
|
136
133
|
|
|
137
|
-
def _modify_special_strings(self, tex):
|
|
134
|
+
def _modify_special_strings(self, tex: str) -> str:
|
|
138
135
|
tex = tex.strip()
|
|
139
136
|
should_add_filler = reduce(
|
|
140
137
|
op.or_,
|
|
@@ -178,8 +175,8 @@ class SingleStringMathTex(SVGMobject):
|
|
|
178
175
|
tex = self._remove_stray_braces(tex)
|
|
179
176
|
|
|
180
177
|
for context in ["array"]:
|
|
181
|
-
begin_in = ("\\begin{%s}" % context) in tex
|
|
182
|
-
end_in = ("\\end{%s}" % context) in tex
|
|
178
|
+
begin_in = ("\\begin{%s}" % context) in tex # noqa: UP031
|
|
179
|
+
end_in = ("\\end{%s}" % context) in tex # noqa: UP031
|
|
183
180
|
if begin_in ^ end_in:
|
|
184
181
|
# Just turn this into a blank string,
|
|
185
182
|
# which means caller should leave a
|
|
@@ -187,14 +184,13 @@ class SingleStringMathTex(SVGMobject):
|
|
|
187
184
|
tex = ""
|
|
188
185
|
return tex
|
|
189
186
|
|
|
190
|
-
def _remove_stray_braces(self, tex):
|
|
187
|
+
def _remove_stray_braces(self, tex: str) -> str:
|
|
191
188
|
r"""
|
|
192
189
|
Makes :class:`~.MathTex` resilient to unmatched braces.
|
|
193
190
|
|
|
194
191
|
This is important when the braces in the TeX code are spread over
|
|
195
192
|
multiple arguments as in, e.g., ``MathTex(r"e^{i", r"\tau} = 1")``.
|
|
196
193
|
"""
|
|
197
|
-
|
|
198
194
|
# "\{" does not count (it's a brace literal), but "\\{" counts (it's a new line and then brace)
|
|
199
195
|
num_lefts = tex.count("{") - tex.count("\\{") + tex.count("\\\\{")
|
|
200
196
|
num_rights = tex.count("}") - tex.count("\\}") + tex.count("\\\\}")
|
|
@@ -206,18 +202,25 @@ class SingleStringMathTex(SVGMobject):
|
|
|
206
202
|
num_rights += 1
|
|
207
203
|
return tex
|
|
208
204
|
|
|
209
|
-
def _organize_submobjects_left_to_right(self):
|
|
205
|
+
def _organize_submobjects_left_to_right(self) -> Self:
|
|
210
206
|
self.sort(lambda p: p[0])
|
|
211
207
|
return self
|
|
212
208
|
|
|
213
|
-
def get_tex_string(self):
|
|
209
|
+
def get_tex_string(self) -> str:
|
|
214
210
|
return self.tex_string
|
|
215
211
|
|
|
216
|
-
def init_colors(self, propagate_colors=True):
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
212
|
+
def init_colors(self, propagate_colors: bool = True) -> Self:
|
|
213
|
+
for submobject in self.submobjects:
|
|
214
|
+
# needed to preserve original (non-black)
|
|
215
|
+
# TeX colors of individual submobjects
|
|
216
|
+
if submobject.color != BLACK:
|
|
217
|
+
continue
|
|
218
|
+
submobject.color = self.color
|
|
219
|
+
if config.renderer == RendererType.OPENGL:
|
|
220
|
+
submobject.init_colors()
|
|
221
|
+
elif config.renderer == RendererType.CAIRO:
|
|
222
|
+
submobject.init_colors(propagate_colors=propagate_colors)
|
|
223
|
+
return self
|
|
221
224
|
|
|
222
225
|
|
|
223
226
|
class MathTex(SingleStringMathTex):
|
|
@@ -253,21 +256,22 @@ class MathTex(SingleStringMathTex):
|
|
|
253
256
|
|
|
254
257
|
def __init__(
|
|
255
258
|
self,
|
|
256
|
-
*tex_strings,
|
|
259
|
+
*tex_strings: str,
|
|
257
260
|
arg_separator: str = " ",
|
|
258
261
|
substrings_to_isolate: Iterable[str] | None = None,
|
|
259
|
-
tex_to_color_map: dict[str,
|
|
260
|
-
tex_environment: str = "align*",
|
|
261
|
-
**kwargs,
|
|
262
|
+
tex_to_color_map: dict[str, ParsableManimColor] | None = None,
|
|
263
|
+
tex_environment: str | None = "align*",
|
|
264
|
+
**kwargs: Any,
|
|
262
265
|
):
|
|
263
266
|
self.tex_template = kwargs.pop("tex_template", config["tex_template"])
|
|
264
267
|
self.arg_separator = arg_separator
|
|
265
268
|
self.substrings_to_isolate = (
|
|
266
269
|
[] if substrings_to_isolate is None else substrings_to_isolate
|
|
267
270
|
)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
+
if tex_to_color_map is None:
|
|
272
|
+
self.tex_to_color_map: dict[str, ParsableManimColor] = {}
|
|
273
|
+
else:
|
|
274
|
+
self.tex_to_color_map = tex_to_color_map
|
|
271
275
|
self.tex_environment = tex_environment
|
|
272
276
|
self.brace_notation_split_occurred = False
|
|
273
277
|
self.tex_strings = self._break_up_tex_strings(tex_strings)
|
|
@@ -299,12 +303,14 @@ class MathTex(SingleStringMathTex):
|
|
|
299
303
|
if self.organize_left_to_right:
|
|
300
304
|
self._organize_submobjects_left_to_right()
|
|
301
305
|
|
|
302
|
-
def _break_up_tex_strings(self, tex_strings):
|
|
306
|
+
def _break_up_tex_strings(self, tex_strings: Sequence[str]) -> list[str]:
|
|
303
307
|
# Separate out anything surrounded in double braces
|
|
304
308
|
pre_split_length = len(tex_strings)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
309
|
+
tex_strings_brace_splitted = [
|
|
310
|
+
re.split("{{(.*?)}}", str(t)) for t in tex_strings
|
|
311
|
+
]
|
|
312
|
+
tex_strings_combined = sum(tex_strings_brace_splitted, [])
|
|
313
|
+
if len(tex_strings_combined) > pre_split_length:
|
|
308
314
|
self.brace_notation_split_occurred = True
|
|
309
315
|
|
|
310
316
|
# Separate out any strings specified in the isolate
|
|
@@ -322,19 +328,19 @@ class MathTex(SingleStringMathTex):
|
|
|
322
328
|
pattern = "|".join(patterns)
|
|
323
329
|
if pattern:
|
|
324
330
|
pieces = []
|
|
325
|
-
for s in
|
|
331
|
+
for s in tex_strings_combined:
|
|
326
332
|
pieces.extend(re.split(pattern, s))
|
|
327
333
|
else:
|
|
328
|
-
pieces =
|
|
334
|
+
pieces = tex_strings_combined
|
|
329
335
|
return [p for p in pieces if p]
|
|
330
336
|
|
|
331
|
-
def _break_up_by_substrings(self):
|
|
337
|
+
def _break_up_by_substrings(self) -> Self:
|
|
332
338
|
"""
|
|
333
339
|
Reorganize existing submobjects one layer
|
|
334
340
|
deeper based on the structure of tex_strings (as a list
|
|
335
341
|
of tex_strings)
|
|
336
342
|
"""
|
|
337
|
-
new_submobjects = []
|
|
343
|
+
new_submobjects: list[VMobject] = []
|
|
338
344
|
curr_index = 0
|
|
339
345
|
for tex_string in self.tex_strings:
|
|
340
346
|
sub_tex_mob = SingleStringMathTex(
|
|
@@ -347,10 +353,6 @@ class MathTex(SingleStringMathTex):
|
|
|
347
353
|
curr_index + num_submobs + len("".join(self.arg_separator.split()))
|
|
348
354
|
)
|
|
349
355
|
if num_submobs == 0:
|
|
350
|
-
# For cases like empty tex_strings, we want the corresponding
|
|
351
|
-
# part of the whole MathTex to be a VectorizedPoint
|
|
352
|
-
# positioned in the right part of the MathTex
|
|
353
|
-
sub_tex_mob.submobjects = [VectorizedPoint()]
|
|
354
356
|
last_submob_index = min(curr_index, len(self.submobjects) - 1)
|
|
355
357
|
sub_tex_mob.move_to(self.submobjects[last_submob_index], RIGHT)
|
|
356
358
|
else:
|
|
@@ -360,8 +362,10 @@ class MathTex(SingleStringMathTex):
|
|
|
360
362
|
self.submobjects = new_submobjects
|
|
361
363
|
return self
|
|
362
364
|
|
|
363
|
-
def get_parts_by_tex(
|
|
364
|
-
|
|
365
|
+
def get_parts_by_tex(
|
|
366
|
+
self, tex: str, substring: bool = True, case_sensitive: bool = True
|
|
367
|
+
) -> VGroup:
|
|
368
|
+
def test(tex1: str, tex2: str) -> bool:
|
|
365
369
|
if not case_sensitive:
|
|
366
370
|
tex1 = tex1.lower()
|
|
367
371
|
tex2 = tex2.lower()
|
|
@@ -372,45 +376,82 @@ class MathTex(SingleStringMathTex):
|
|
|
372
376
|
|
|
373
377
|
return VGroup(*(m for m in self.submobjects if test(tex, m.get_tex_string())))
|
|
374
378
|
|
|
375
|
-
def get_part_by_tex(self, tex, **kwargs):
|
|
379
|
+
def get_part_by_tex(self, tex: str, **kwargs: Any) -> MathTex | None:
|
|
376
380
|
all_parts = self.get_parts_by_tex(tex, **kwargs)
|
|
377
381
|
return all_parts[0] if all_parts else None
|
|
378
382
|
|
|
379
|
-
def set_color_by_tex(
|
|
383
|
+
def set_color_by_tex(
|
|
384
|
+
self, tex: str, color: ParsableManimColor, **kwargs: Any
|
|
385
|
+
) -> Self:
|
|
380
386
|
parts_to_color = self.get_parts_by_tex(tex, **kwargs)
|
|
381
387
|
for part in parts_to_color:
|
|
382
388
|
part.set_color(color)
|
|
383
389
|
return self
|
|
384
390
|
|
|
385
|
-
def
|
|
391
|
+
def set_opacity_by_tex(
|
|
392
|
+
self,
|
|
393
|
+
tex: str,
|
|
394
|
+
opacity: float = 0.5,
|
|
395
|
+
remaining_opacity: float | None = None,
|
|
396
|
+
**kwargs: Any,
|
|
397
|
+
) -> Self:
|
|
398
|
+
"""
|
|
399
|
+
Sets the opacity of the tex specified. If 'remaining_opacity' is specified,
|
|
400
|
+
then the remaining tex will be set to that opacity.
|
|
401
|
+
|
|
402
|
+
Parameters
|
|
403
|
+
----------
|
|
404
|
+
tex
|
|
405
|
+
The tex to set the opacity of.
|
|
406
|
+
opacity
|
|
407
|
+
Default 0.5. The opacity to set the tex to
|
|
408
|
+
remaining_opacity
|
|
409
|
+
Default None. The opacity to set the remaining tex to.
|
|
410
|
+
If None, then the remaining tex will not be changed
|
|
411
|
+
"""
|
|
412
|
+
if remaining_opacity is not None:
|
|
413
|
+
self.set_opacity(opacity=remaining_opacity)
|
|
414
|
+
for part in self.get_parts_by_tex(tex):
|
|
415
|
+
part.set_opacity(opacity)
|
|
416
|
+
return self
|
|
417
|
+
|
|
418
|
+
def set_color_by_tex_to_color_map(
|
|
419
|
+
self, texs_to_color_map: dict[str, ParsableManimColor], **kwargs: Any
|
|
420
|
+
) -> Self:
|
|
386
421
|
for texs, color in list(texs_to_color_map.items()):
|
|
387
422
|
try:
|
|
388
423
|
# If the given key behaves like tex_strings
|
|
389
424
|
texs + ""
|
|
390
|
-
self.set_color_by_tex(texs, color, **kwargs)
|
|
425
|
+
self.set_color_by_tex(texs, ManimColor(color), **kwargs)
|
|
391
426
|
except TypeError:
|
|
392
427
|
# If the given key is a tuple
|
|
393
428
|
for tex in texs:
|
|
394
|
-
self.set_color_by_tex(tex, color, **kwargs)
|
|
429
|
+
self.set_color_by_tex(tex, ManimColor(color), **kwargs)
|
|
395
430
|
return self
|
|
396
431
|
|
|
397
|
-
def index_of_part(self, part):
|
|
432
|
+
def index_of_part(self, part: MathTex) -> int:
|
|
398
433
|
split_self = self.split()
|
|
399
434
|
if part not in split_self:
|
|
400
435
|
raise ValueError("Trying to get index of part not in MathTex")
|
|
401
436
|
return split_self.index(part)
|
|
402
437
|
|
|
403
|
-
def index_of_part_by_tex(self, tex, **kwargs):
|
|
438
|
+
def index_of_part_by_tex(self, tex: str, **kwargs: Any) -> int:
|
|
404
439
|
part = self.get_part_by_tex(tex, **kwargs)
|
|
440
|
+
if part is None:
|
|
441
|
+
return -1
|
|
405
442
|
return self.index_of_part(part)
|
|
406
443
|
|
|
407
|
-
def sort_alphabetically(self):
|
|
444
|
+
def sort_alphabetically(self) -> None:
|
|
408
445
|
self.submobjects.sort(key=lambda m: m.get_tex_string())
|
|
409
446
|
|
|
410
447
|
|
|
411
448
|
class Tex(MathTex):
|
|
412
449
|
r"""A string compiled with LaTeX in normal mode.
|
|
413
450
|
|
|
451
|
+
The color can be set using
|
|
452
|
+
the ``color`` argument. Any parts of the ``tex_string`` that are colored by the
|
|
453
|
+
TeX commands ``\color`` or ``\textcolor`` will retain their original color.
|
|
454
|
+
|
|
414
455
|
Tests
|
|
415
456
|
-----
|
|
416
457
|
|
|
@@ -422,7 +463,11 @@ class Tex(MathTex):
|
|
|
422
463
|
"""
|
|
423
464
|
|
|
424
465
|
def __init__(
|
|
425
|
-
self,
|
|
466
|
+
self,
|
|
467
|
+
*tex_strings: str,
|
|
468
|
+
arg_separator: str = "",
|
|
469
|
+
tex_environment: str | None = "center",
|
|
470
|
+
**kwargs: Any,
|
|
426
471
|
):
|
|
427
472
|
super().__init__(
|
|
428
473
|
*tex_strings,
|
|
@@ -433,7 +478,8 @@ class Tex(MathTex):
|
|
|
433
478
|
|
|
434
479
|
|
|
435
480
|
class BulletedList(Tex):
|
|
436
|
-
"""
|
|
481
|
+
"""A bulleted list.
|
|
482
|
+
|
|
437
483
|
Examples
|
|
438
484
|
--------
|
|
439
485
|
|
|
@@ -451,18 +497,20 @@ class BulletedList(Tex):
|
|
|
451
497
|
|
|
452
498
|
def __init__(
|
|
453
499
|
self,
|
|
454
|
-
*items,
|
|
455
|
-
buff=MED_LARGE_BUFF,
|
|
456
|
-
dot_scale_factor=2,
|
|
457
|
-
tex_environment=None,
|
|
458
|
-
**kwargs,
|
|
500
|
+
*items: str,
|
|
501
|
+
buff: float = MED_LARGE_BUFF,
|
|
502
|
+
dot_scale_factor: float = 2,
|
|
503
|
+
tex_environment: str | None = None,
|
|
504
|
+
**kwargs: Any,
|
|
459
505
|
):
|
|
460
506
|
self.buff = buff
|
|
461
507
|
self.dot_scale_factor = dot_scale_factor
|
|
462
508
|
self.tex_environment = tex_environment
|
|
463
509
|
line_separated_items = [s + "\\\\" for s in items]
|
|
464
510
|
super().__init__(
|
|
465
|
-
*line_separated_items,
|
|
511
|
+
*line_separated_items,
|
|
512
|
+
tex_environment=tex_environment,
|
|
513
|
+
**kwargs,
|
|
466
514
|
)
|
|
467
515
|
for part in self:
|
|
468
516
|
dot = MathTex("\\cdot").scale(self.dot_scale_factor)
|
|
@@ -470,10 +518,14 @@ class BulletedList(Tex):
|
|
|
470
518
|
part.add_to_back(dot)
|
|
471
519
|
self.arrange(DOWN, aligned_edge=LEFT, buff=self.buff)
|
|
472
520
|
|
|
473
|
-
def fade_all_but(self, index_or_string, opacity=0.5):
|
|
521
|
+
def fade_all_but(self, index_or_string: int | str, opacity: float = 0.5) -> None:
|
|
474
522
|
arg = index_or_string
|
|
475
523
|
if isinstance(arg, str):
|
|
476
|
-
part = self.get_part_by_tex(arg)
|
|
524
|
+
part: VGroup | VMobject | None = self.get_part_by_tex(arg)
|
|
525
|
+
if part is None:
|
|
526
|
+
raise Exception(
|
|
527
|
+
f"Could not locate part by provided tex string '{arg}'."
|
|
528
|
+
)
|
|
477
529
|
elif isinstance(arg, int):
|
|
478
530
|
part = self.submobjects[arg]
|
|
479
531
|
else:
|
|
@@ -486,7 +538,8 @@ class BulletedList(Tex):
|
|
|
486
538
|
|
|
487
539
|
|
|
488
540
|
class Title(Tex):
|
|
489
|
-
"""
|
|
541
|
+
"""A mobject representing an underlined title.
|
|
542
|
+
|
|
490
543
|
Examples
|
|
491
544
|
--------
|
|
492
545
|
.. manim:: TitleExample
|
|
@@ -504,13 +557,12 @@ class Title(Tex):
|
|
|
504
557
|
|
|
505
558
|
def __init__(
|
|
506
559
|
self,
|
|
507
|
-
*text_parts,
|
|
508
|
-
include_underline=True,
|
|
509
|
-
match_underline_width_to_text=False,
|
|
510
|
-
underline_buff=MED_SMALL_BUFF,
|
|
511
|
-
**kwargs,
|
|
560
|
+
*text_parts: str,
|
|
561
|
+
include_underline: bool = True,
|
|
562
|
+
match_underline_width_to_text: bool = False,
|
|
563
|
+
underline_buff: float = MED_SMALL_BUFF,
|
|
564
|
+
**kwargs: Any,
|
|
512
565
|
):
|
|
513
|
-
|
|
514
566
|
self.include_underline = include_underline
|
|
515
567
|
self.match_underline_width_to_text = match_underline_width_to_text
|
|
516
568
|
self.underline_buff = underline_buff
|