mirror of
https://github.com/3b1b/manim.git
synced 2025-04-13 09:47:07 +00:00
Automatically identify the class name based on the specified line number. (#2280)
* identify the scene name based on the line number * resolving a minor bug in string_mobject * removing bug of string validation * Update manimlib/default_config.yml Co-authored-by: Splines <37160523+Splines@users.noreply.github.com> * Update manimlib/extract_scene.py Co-authored-by: Splines <37160523+Splines@users.noreply.github.com> * update search scene names --------- Co-authored-by: Splines <37160523+Splines@users.noreply.github.com>
This commit is contained in:
parent
96d44bd560
commit
24eefef5bf
5 changed files with 28 additions and 14 deletions
|
@ -5,13 +5,13 @@
|
||||||
# you are running manim. For 3blue1brown, for instance, mind is
|
# you are running manim. For 3blue1brown, for instance, mind is
|
||||||
# here: https://github.com/3b1b/videos/blob/master/custom_config.yml
|
# here: https://github.com/3b1b/videos/blob/master/custom_config.yml
|
||||||
|
|
||||||
# Alternatively, you can create it whereever you like, and on running
|
# Alternatively, you can create it wherever you like, and on running
|
||||||
# manim, pass in `--config_file /path/to/custom/config/file.yml`
|
# manim, pass in `--config_file /path/to/custom/config/file.yml`
|
||||||
|
|
||||||
directories:
|
directories:
|
||||||
# Set this to true if you want the path to video files
|
# Set this to true if you want the path to video files
|
||||||
# to match the directory structure of the path to the
|
# to match the directory structure of the path to the
|
||||||
# sourcecode generating that video
|
# source code generating that video
|
||||||
mirror_module_path: False
|
mirror_module_path: False
|
||||||
# Manim may write to and read from the file system, e.g.
|
# Manim may write to and read from the file system, e.g.
|
||||||
# to render videos and to look for svg/png assets. This
|
# to render videos and to look for svg/png assets. This
|
||||||
|
@ -44,7 +44,7 @@ window:
|
||||||
# If not full screen, the default to give it half the screen width
|
# If not full screen, the default to give it half the screen width
|
||||||
full_screen: False
|
full_screen: False
|
||||||
# Other optional specifications that override the above include:
|
# Other optional specifications that override the above include:
|
||||||
# position: (500, 500) # Specific position, in pixel coordiantes, for upper right corner
|
# position: (500, 500) # Specific position, in pixel coordinates, for upper right corner
|
||||||
# size: (1920, 1080) # Specific size, in pixels
|
# size: (1920, 1080) # Specific size, in pixels
|
||||||
camera:
|
camera:
|
||||||
resolution: (1920, 1080)
|
resolution: (1920, 1080)
|
||||||
|
|
|
@ -12,6 +12,7 @@ from manimlib.scene.interactive_scene import InteractiveScene
|
||||||
from manimlib.scene.scene import Scene
|
from manimlib.scene.scene import Scene
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
Module = importlib.util.types.ModuleType
|
Module = importlib.util.types.ModuleType
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
@ -142,7 +143,7 @@ def get_indent(code_lines: list[str], line_number: int) -> str:
|
||||||
return n_spaces * " "
|
return n_spaces * " "
|
||||||
|
|
||||||
|
|
||||||
def insert_embed_line_to_module(module: Module, line_number: int):
|
def insert_embed_line_to_module(module: Module, run_config: Dict) -> None:
|
||||||
"""
|
"""
|
||||||
This is hacky, but convenient. When user includes the argument "-e", it will try
|
This is hacky, but convenient. When user includes the argument "-e", it will try
|
||||||
to recreate a file that inserts the line `self.embed()` into the end of the scene's
|
to recreate a file that inserts the line `self.embed()` into the end of the scene's
|
||||||
|
@ -150,27 +151,42 @@ def insert_embed_line_to_module(module: Module, line_number: int):
|
||||||
the last line in the sourcefile which includes that string.
|
the last line in the sourcefile which includes that string.
|
||||||
"""
|
"""
|
||||||
lines = inspect.getsource(module).splitlines()
|
lines = inspect.getsource(module).splitlines()
|
||||||
|
line_number = run_config.embed_line
|
||||||
|
|
||||||
# Add the relevant embed line to the code
|
# Add the relevant embed line to the code
|
||||||
indent = get_indent(lines, line_number)
|
indent = get_indent(lines, line_number)
|
||||||
lines.insert(line_number, indent + "self.embed()")
|
lines.insert(line_number, indent + "self.embed()")
|
||||||
new_code = "\n".join(lines)
|
new_code = "\n".join(lines)
|
||||||
|
|
||||||
|
# When the user executes the `-e <line_number>` command
|
||||||
|
# without specifying scene_names, the nearest class name above
|
||||||
|
# `<line_number>` will be automatically used as 'scene_names'.
|
||||||
|
|
||||||
|
if not run_config.scene_names:
|
||||||
|
classes = list(filter(lambda line: line.startswith("class"), lines[:line_number]))
|
||||||
|
if classes:
|
||||||
|
from re import search
|
||||||
|
|
||||||
|
scene_name = search(r"(\w+)\(", classes[-1])
|
||||||
|
run_config.update(scene_names=[scene_name.group(1)])
|
||||||
|
else:
|
||||||
|
log.error(f"No 'class' found above {line_number}!")
|
||||||
|
|
||||||
# Execute the code, which presumably redefines the user's
|
# Execute the code, which presumably redefines the user's
|
||||||
# scene to include this embed line, within the relevant module.
|
# scene to include this embed line, within the relevant module.
|
||||||
code_object = compile(new_code, module.__name__, 'exec')
|
code_object = compile(new_code, module.__name__, 'exec')
|
||||||
exec(code_object, module.__dict__)
|
exec(code_object, module.__dict__)
|
||||||
|
|
||||||
|
|
||||||
def get_module(file_name: Optional[str], embed_line: Optional[int], is_reload: bool = False) -> Module:
|
def get_module(run_config: Dict) -> Module:
|
||||||
module = ModuleLoader.get_module(file_name, is_reload)
|
module = ModuleLoader.get_module(run_config.file_name, run_config.is_reload)
|
||||||
if embed_line:
|
if run_config.embed_line:
|
||||||
insert_embed_line_to_module(module, embed_line)
|
insert_embed_line_to_module(module, run_config)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
|
||||||
def main(scene_config: Dict, run_config: Dict):
|
def main(scene_config: Dict, run_config: Dict):
|
||||||
module = get_module(run_config.file_name, run_config.embed_line, run_config.is_reload)
|
module = get_module(run_config)
|
||||||
all_scene_classes = get_scene_classes(module)
|
all_scene_classes = get_scene_classes(module)
|
||||||
scenes = get_scenes_to_render(all_scene_classes, scene_config, run_config)
|
scenes = get_scenes_to_render(all_scene_classes, scene_config, run_config)
|
||||||
if len(scenes) == 0:
|
if len(scenes) == 0:
|
||||||
|
|
|
@ -43,6 +43,7 @@ class SampleSpace(Rectangle):
|
||||||
fill_opacity=fill_opacity,
|
fill_opacity=fill_opacity,
|
||||||
stroke_width=stroke_width,
|
stroke_width=stroke_width,
|
||||||
stroke_color=stroke_color,
|
stroke_color=stroke_color,
|
||||||
|
**kwargs
|
||||||
)
|
)
|
||||||
self.default_label_scale_val = default_label_scale_val
|
self.default_label_scale_val = default_label_scale_val
|
||||||
|
|
||||||
|
|
|
@ -122,8 +122,8 @@ class StringMobject(SVGMobject, ABC):
|
||||||
# of submobject which are and use those for labels
|
# of submobject which are and use those for labels
|
||||||
unlabelled_submobs = submobs
|
unlabelled_submobs = submobs
|
||||||
labelled_content = self.get_content(is_labelled=True)
|
labelled_content = self.get_content(is_labelled=True)
|
||||||
labelled_file = self.get_file_path_by_content(labelled_content)
|
labelled_file = self.get_svg_string_by_content(labelled_content)
|
||||||
labelled_submobs = super().mobjects_from_file(labelled_file)
|
labelled_submobs = super().mobjects_from_svg_string(labelled_file)
|
||||||
self.labelled_submobs = labelled_submobs
|
self.labelled_submobs = labelled_submobs
|
||||||
self.unlabelled_submobs = unlabelled_submobs
|
self.unlabelled_submobs = unlabelled_submobs
|
||||||
|
|
||||||
|
|
|
@ -176,9 +176,6 @@ class MarkupText(StringMobject):
|
||||||
self.disable_ligatures = disable_ligatures
|
self.disable_ligatures = disable_ligatures
|
||||||
self.isolate = isolate
|
self.isolate = isolate
|
||||||
|
|
||||||
if not isinstance(self, Text):
|
|
||||||
self.validate_markup_string(text)
|
|
||||||
|
|
||||||
super().__init__(text, height=height, **kwargs)
|
super().__init__(text, height=height, **kwargs)
|
||||||
|
|
||||||
if self.t2g:
|
if self.t2g:
|
||||||
|
|
Loading…
Add table
Reference in a new issue