mirror of
https://github.com/3b1b/manim.git
synced 2025-08-05 16:49:03 +00:00
Kill CONFIG in tex_mobject.py
This commit is contained in:
parent
d4b6bf40e5
commit
7aa5c83a14
1 changed files with 113 additions and 84 deletions
|
@ -4,7 +4,7 @@ from functools import reduce
|
||||||
import operator as op
|
import operator as op
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from manimlib.constants import BLACK, WHITE
|
from manimlib.constants import BLACK, WHITE, GREY_C
|
||||||
from manimlib.constants import DOWN, LEFT, RIGHT, UP
|
from manimlib.constants import DOWN, LEFT, RIGHT, UP
|
||||||
from manimlib.constants import FRAME_WIDTH
|
from manimlib.constants import FRAME_WIDTH
|
||||||
from manimlib.constants import MED_LARGE_BUFF, MED_SMALL_BUFF, SMALL_BUFF
|
from manimlib.constants import MED_LARGE_BUFF, MED_SMALL_BUFF, SMALL_BUFF
|
||||||
|
@ -18,7 +18,7 @@ from manimlib.utils.tex_file_writing import tex_content_to_svg_file
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from typing import Iterable
|
from typing import Iterable, List, Dict, Sequence
|
||||||
from manimlib.constants import ManimColor
|
from manimlib.constants import ManimColor
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,29 +26,43 @@ SCALE_FACTOR_PER_FONT_POINT = 0.001
|
||||||
|
|
||||||
|
|
||||||
class SingleStringTex(SVGMobject):
|
class SingleStringTex(SVGMobject):
|
||||||
CONFIG = {
|
def __init__(
|
||||||
"height": None,
|
self,
|
||||||
"fill_opacity": 1.0,
|
tex_string: str,
|
||||||
"stroke_width": 0,
|
height: float | None = None,
|
||||||
"svg_default": {
|
fill_color: ManimColor = WHITE,
|
||||||
"fill_color": WHITE,
|
fill_opacity: float = 1.0,
|
||||||
},
|
stroke_width: float = 0,
|
||||||
"path_string_config": {
|
svg_default: dict = dict(fill_color=WHITE),
|
||||||
"should_subdivide_sharp_curves": True,
|
path_string_config: dict = dict(
|
||||||
"should_remove_null_curves": True,
|
should_subdivide_sharp_curves=True,
|
||||||
},
|
should_remove_null_curves=True,
|
||||||
"font_size": 48,
|
),
|
||||||
"alignment": "\\centering",
|
font_size: int = 48,
|
||||||
"math_mode": True,
|
alignment: str = R"\centering",
|
||||||
"organize_left_to_right": False,
|
math_mode: bool = True,
|
||||||
"template": "",
|
organize_left_to_right: bool = False,
|
||||||
"additional_preamble": "",
|
template: str = "",
|
||||||
}
|
additional_preamble: str = "",
|
||||||
|
**kwargs
|
||||||
def __init__(self, tex_string: str, **kwargs):
|
):
|
||||||
assert isinstance(tex_string, str)
|
|
||||||
self.tex_string = tex_string
|
self.tex_string = tex_string
|
||||||
super().__init__(**kwargs)
|
self.height = height
|
||||||
|
self.svg_default = svg_default
|
||||||
|
self.path_string_config = path_string_config
|
||||||
|
self.font_size = font_size
|
||||||
|
self.alignment = alignment
|
||||||
|
self.math_mode = math_mode
|
||||||
|
self.organize_left_to_right = organize_left_to_right
|
||||||
|
self.template = template
|
||||||
|
self.additional_preamble = additional_preamble
|
||||||
|
|
||||||
|
super().__init__(
|
||||||
|
fill_color=fill_color,
|
||||||
|
fill_opacity=fill_opacity,
|
||||||
|
stroke_width=stroke_width,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
if self.height is None:
|
if self.height is None:
|
||||||
self.scale(SCALE_FACTOR_PER_FONT_POINT * self.font_size)
|
self.scale(SCALE_FACTOR_PER_FONT_POINT * self.font_size)
|
||||||
|
@ -178,27 +192,30 @@ class SingleStringTex(SVGMobject):
|
||||||
|
|
||||||
|
|
||||||
class Tex(SingleStringTex):
|
class Tex(SingleStringTex):
|
||||||
CONFIG = {
|
def __init__(
|
||||||
"arg_separator": "",
|
self,
|
||||||
"isolate": [],
|
*tex_strings: str,
|
||||||
"tex_to_color_map": {},
|
arg_separator: str = "",
|
||||||
}
|
isolate: List[str] = [],
|
||||||
|
tex_to_color_map: Dict[str, ManimColor] = {},
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
self.tex_strings = self.break_up_tex_strings(
|
||||||
|
tex_strings,
|
||||||
|
substrings_to_isolate=[*isolate, *tex_to_color_map.keys()]
|
||||||
|
)
|
||||||
|
full_string = arg_separator.join(self.tex_strings)
|
||||||
|
|
||||||
def __init__(self, *tex_strings: str, **kwargs):
|
|
||||||
digest_config(self, kwargs)
|
|
||||||
self.tex_strings = self.break_up_tex_strings(tex_strings)
|
|
||||||
full_string = self.arg_separator.join(self.tex_strings)
|
|
||||||
super().__init__(full_string, **kwargs)
|
super().__init__(full_string, **kwargs)
|
||||||
self.break_up_by_substrings()
|
self.break_up_by_substrings(self.tex_strings)
|
||||||
self.set_color_by_tex_to_color_map(self.tex_to_color_map)
|
self.set_color_by_tex_to_color_map(tex_to_color_map)
|
||||||
|
|
||||||
if self.organize_left_to_right:
|
if self.organize_left_to_right:
|
||||||
self.organize_submobjects_left_to_right()
|
self.organize_submobjects_left_to_right()
|
||||||
|
|
||||||
def break_up_tex_strings(self, tex_strings: Iterable[str]) -> Iterable[str]:
|
def break_up_tex_strings(self, tex_strings: Iterable[str], substrings_to_isolate: List[str] = []) -> Iterable[str]:
|
||||||
# Separate out any strings specified in the isolate
|
# Separate out any strings specified in the isolate
|
||||||
# or tex_to_color_map lists.
|
# or tex_to_color_map lists.
|
||||||
substrings_to_isolate = [*self.isolate, *self.tex_to_color_map.keys()]
|
|
||||||
if len(substrings_to_isolate) == 0:
|
if len(substrings_to_isolate) == 0:
|
||||||
return tex_strings
|
return tex_strings
|
||||||
patterns = (
|
patterns = (
|
||||||
|
@ -214,30 +231,28 @@ class Tex(SingleStringTex):
|
||||||
pieces.append(s)
|
pieces.append(s)
|
||||||
return list(filter(lambda s: s, pieces))
|
return list(filter(lambda s: s, pieces))
|
||||||
|
|
||||||
def break_up_by_substrings(self):
|
def break_up_by_substrings(self, tex_strings: Iterable[str]):
|
||||||
"""
|
"""
|
||||||
Reorganize existing submojects one layer
|
Reorganize existing submojects one layer
|
||||||
deeper based on the structure of tex_strings (as a list
|
deeper based on the structure of tex_strings (as a list
|
||||||
of tex_strings)
|
of tex_strings)
|
||||||
"""
|
"""
|
||||||
if len(self.tex_strings) == 1:
|
if len(list(tex_strings)) == 1:
|
||||||
submob = self.copy()
|
submob = self.copy()
|
||||||
self.set_submobjects([submob])
|
self.set_submobjects([submob])
|
||||||
return self
|
return self
|
||||||
new_submobjects = []
|
new_submobjects = []
|
||||||
curr_index = 0
|
curr_index = 0
|
||||||
config = dict(self.CONFIG)
|
for tex_string in tex_strings:
|
||||||
config["alignment"] = ""
|
|
||||||
for tex_string in self.tex_strings:
|
|
||||||
tex_string = tex_string.strip()
|
tex_string = tex_string.strip()
|
||||||
if len(tex_string) == 0:
|
if len(tex_string) == 0:
|
||||||
continue
|
continue
|
||||||
sub_tex_mob = SingleStringTex(tex_string, **config)
|
sub_tex_mob = SingleStringTex(tex_string)
|
||||||
num_submobs = len(sub_tex_mob)
|
num_submobs = len(sub_tex_mob)
|
||||||
if num_submobs == 0:
|
if num_submobs == 0:
|
||||||
continue
|
continue
|
||||||
new_index = curr_index + num_submobs
|
new_index = curr_index + num_submobs
|
||||||
sub_tex_mob.set_submobjects(self[curr_index:new_index])
|
sub_tex_mob.set_submobjects(self.submobjects[curr_index:new_index])
|
||||||
new_submobjects.append(sub_tex_mob)
|
new_submobjects.append(sub_tex_mob)
|
||||||
curr_index = new_index
|
curr_index = new_index
|
||||||
self.set_submobjects(new_submobjects)
|
self.set_submobjects(new_submobjects)
|
||||||
|
@ -313,30 +328,43 @@ class Tex(SingleStringTex):
|
||||||
|
|
||||||
|
|
||||||
class TexText(Tex):
|
class TexText(Tex):
|
||||||
CONFIG = {
|
def __init__(
|
||||||
"math_mode": False,
|
self,
|
||||||
"arg_separator": "",
|
*tex_strings: str,
|
||||||
}
|
math_mode: bool = False,
|
||||||
|
arg_separator: str = "",
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
super().__init__(
|
||||||
|
*tex_strings,
|
||||||
|
math_mode=math_mode,
|
||||||
|
arg_separator=arg_separator,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BulletedList(TexText):
|
class BulletedList(TexText):
|
||||||
CONFIG = {
|
def __init__(
|
||||||
"buff": MED_LARGE_BUFF,
|
self,
|
||||||
"dot_scale_factor": 2,
|
*items: str,
|
||||||
"alignment": "",
|
buff: float = MED_LARGE_BUFF,
|
||||||
}
|
dot_scale_factor: float = 2.0,
|
||||||
|
alignment: str = "",
|
||||||
def __init__(self, *items: str, **kwargs):
|
**kwargs
|
||||||
line_separated_items = [s + "\\\\" for s in items]
|
):
|
||||||
TexText.__init__(self, *line_separated_items, **kwargs)
|
super().__init__(
|
||||||
|
*(s + R"\\" for s in items),
|
||||||
|
alignment=alignment,
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
for part in self:
|
for part in self:
|
||||||
dot = Tex("\\cdot").scale(self.dot_scale_factor)
|
dot = Tex(R"\cdot").scale(dot_scale_factor)
|
||||||
dot.next_to(part[0], LEFT, SMALL_BUFF)
|
dot.next_to(part[0], LEFT, SMALL_BUFF)
|
||||||
part.add_to_back(dot)
|
part.add_to_back(dot)
|
||||||
self.arrange(
|
self.arrange(
|
||||||
DOWN,
|
DOWN,
|
||||||
aligned_edge=LEFT,
|
aligned_edge=LEFT,
|
||||||
buff=self.buff
|
buff=buff
|
||||||
)
|
)
|
||||||
|
|
||||||
def fade_all_but(self, index_or_string: int | str, opacity: float = 0.5) -> None:
|
def fade_all_but(self, index_or_string: int | str, opacity: float = 0.5) -> None:
|
||||||
|
@ -354,39 +382,40 @@ class BulletedList(TexText):
|
||||||
other_part.set_fill(opacity=opacity)
|
other_part.set_fill(opacity=opacity)
|
||||||
|
|
||||||
|
|
||||||
class TexFromPresetString(Tex):
|
class TexTextFromPresetString(TexText):
|
||||||
CONFIG = {
|
tex: str = ""
|
||||||
# To be filled by subclasses
|
default_color: ManimColor = WHITE
|
||||||
"tex": None,
|
|
||||||
"color": None,
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
digest_config(self, kwargs)
|
super().__init__(
|
||||||
Tex.__init__(self, self.tex, **kwargs)
|
self.tex,
|
||||||
self.set_color(self.color)
|
color=kwargs.pop("color", self.default_color),
|
||||||
|
**kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Title(TexText):
|
class Title(TexText):
|
||||||
CONFIG = {
|
def __init__(
|
||||||
"scale_factor": 1,
|
self,
|
||||||
"include_underline": True,
|
*text_parts: str,
|
||||||
"underline_width": FRAME_WIDTH - 2,
|
scale_factor: float = 1.0,
|
||||||
|
include_underline: bool = True,
|
||||||
|
underline_width: float = FRAME_WIDTH - 2,
|
||||||
# This will override underline_width
|
# This will override underline_width
|
||||||
"match_underline_width_to_text": False,
|
match_underline_width_to_text: bool = False,
|
||||||
"underline_buff": MED_SMALL_BUFF,
|
underline_buff: float = SMALL_BUFF,
|
||||||
}
|
underline_style: dict = dict(stroke_width=2, stroke_color=GREY_C),
|
||||||
|
**kwargs
|
||||||
def __init__(self, *text_parts: str, **kwargs):
|
):
|
||||||
TexText.__init__(self, *text_parts, **kwargs)
|
super().__init__(*text_parts, **kwargs)
|
||||||
self.scale(self.scale_factor)
|
self.scale(scale_factor)
|
||||||
self.to_edge(UP)
|
self.to_edge(UP)
|
||||||
if self.include_underline:
|
if include_underline:
|
||||||
underline = Line(LEFT, RIGHT)
|
underline = Line(LEFT, RIGHT, **underline_style)
|
||||||
underline.next_to(self, DOWN, buff=self.underline_buff)
|
underline.next_to(self, DOWN, buff=underline_buff)
|
||||||
if self.match_underline_width_to_text:
|
if match_underline_width_to_text:
|
||||||
underline.match_width(self)
|
underline.match_width(self)
|
||||||
else:
|
else:
|
||||||
underline.set_width(self.underline_width)
|
underline.set_width(underline_width)
|
||||||
self.add(underline)
|
self.add(underline)
|
||||||
self.underline = underline
|
self.underline = underline
|
||||||
|
|
Loading…
Add table
Reference in a new issue