Tex 能根据传入的 tex_strings 渲染公式,根据 tex_to_color_map 设置颜色,根据 tex_strings、isolate 和 tex_to_color_map 拆出 submobjects(比如用于 TransformMatchingTex )。TransformMatchingShapes 不香吗
# manimlib.mobject.svg.tex_mobject.Tex
class Tex(SingleStringTex):
CONFIG = {...}
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)
self.break_up_by_substrings()
self.set_color_by_tex_to_color_map(self.tex_to_color_map)
if self.organize_left_to_right:
self.organize_submobjects_left_to_right()
...digest_config 处理参数,接着调用 break_up_tex_strings 将 tex_strings 进一步按照 self.isolate 和 self.tex_to_color_map 拆分。
# manimlib.mobject.svg.tex_mobject.Tex.break_up_tex_strings
def break_up_tex_strings(self, tex_strings: Iterable[str]) -> Iterable[str]:
# Separate out any strings specified in the isolate
# or tex_to_color_map lists.
substrings_to_isolate = [*self.isolate, *self.tex_to_color_map.keys()]
if len(substrings_to_isolate) == 0:
return tex_strings
patterns = (
"({})".format(re.escape(ss))
for ss in substrings_to_isolate
)
pattern = "|".join(patterns)
pieces = []
for s in tex_strings:
if pattern:
pieces.extend(re.split(pattern, s))
else:
pieces.append(s)
return list(filter(lambda s: s, pieces))self.tex_strings 被拼在一起(中间用 self.arg_separator 连接,通常是 ""),存在 full_string 里。调用 SingleStringTex 生成 SVG。调用 self.break_up_by_substrings。这个函数大概是,根据 self.tex_strings 再分别调用 SingleStringTex 渲染 SVG 得到 sub_tex_mob,把它设置为自己的 submobjects。
# manimlib.mobject.svg.tex_mobject.Tex.break_up_by_substrings
def break_up_by_substrings(self):
"""
Reorganize existing submojects one layer
deeper based on the structure of tex_strings (as a list
of tex_strings)
"""
if len(self.tex_strings) == 1:
submob = self.copy()
self.set_submobjects([submob])
return self
new_submobjects = []
curr_index = 0
config = dict(self.CONFIG)
config["alignment"] = ""
for tex_string in self.tex_strings:
tex_string = tex_string.strip()
if len(tex_string) == 0:
continue
sub_tex_mob = SingleStringTex(tex_string, **config)
num_submobs = len(sub_tex_mob)
if num_submobs == 0:
continue
new_index = curr_index + num_submobs
sub_tex_mob.set_submobjects(self[curr_index:new_index])
new_submobjects.append(sub_tex_mob)
curr_index = new_index
self.set_submobjects(new_submobjects)
return self调用 self.set_color_by_tex_to_color_map 上色。
# manimlib.mobject.svg.tex_mobject.Tex.set_color_by_tex_to_color_map
def set_color_by_tex_to_color_map(
self,
tex_to_color_map: dict[str, ManimColor],
**kwargs
):
for tex, color in list(tex_to_color_map.items()):
self.set_color_by_tex(tex, color, **kwargs)
return selfset_color_by_tex 能对单个 tex 字符串上色。
# manimlib.mobject.svg.tex_mobject.Tex.set_color_by_tex
def set_color_by_tex(self, tex: str, color: ManimColor, **kwargs):
self.get_parts_by_tex(tex, **kwargs).set_color(color)
return selfget_parts_by_tex 查找 tex 对应的部分,包装成 VGroup 返回。
# manimlib.mobject.svg.tex_mobject.Tex.get_parts_by_tex
def get_parts_by_tex(
self, tex: str, substring: bool = True,
case_sensitive: bool = True
) -> VGroup:
def test(tex1, tex2):
if not case_sensitive:
tex1 = tex1.lower()
tex2 = tex2.lower()
if substring: return tex1 in tex2
else: return tex1 == tex2
return VGroup(*filter(
lambda m: isinstance(m, SingleStringTex) and test(tex, m.get_tex()),
self.submobjects
))若 self.organize_left_to_right,调用 self.organize_submobjects_left_to_right 把 self.submobjects 按横坐标排序(只是下标改变,位置不变)。