Skip to content

Commit

Permalink
Automatically identify the class name based on the specified line num…
Browse files Browse the repository at this point in the history
…ber. (#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 <[email protected]>

* Update manimlib/extract_scene.py

Co-authored-by: Splines <[email protected]>

* update search scene names

---------

Co-authored-by: Splines <[email protected]>
  • Loading branch information
Varniex and Splines authored Dec 28, 2024
1 parent 96d44bd commit 24eefef
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 14 deletions.
6 changes: 3 additions & 3 deletions manimlib/default_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
# you are running manim. For 3blue1brown, for instance, mind is
# 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`

directories:
# Set this to true if you want the path to video files
# to match the directory structure of the path to the
# sourcecode generating that video
# source code generating that video
mirror_module_path: False
# Manim may write to and read from the file system, e.g.
# to render videos and to look for svg/png assets. This
Expand Down Expand Up @@ -44,7 +44,7 @@ window:
# If not full screen, the default to give it half the screen width
full_screen: False
# 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
camera:
resolution: (1920, 1080)
Expand Down
28 changes: 22 additions & 6 deletions manimlib/extract_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from manimlib.scene.scene import Scene

from typing import TYPE_CHECKING

if TYPE_CHECKING:
Module = importlib.util.types.ModuleType
from typing import Optional
Expand Down Expand Up @@ -142,35 +143,50 @@ def get_indent(code_lines: list[str], line_number: int) -> str:
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
to recreate a file that inserts the line `self.embed()` into the end of the scene's
construct method. If there is an argument passed in, it will insert the line after
the last line in the sourcefile which includes that string.
"""
lines = inspect.getsource(module).splitlines()
line_number = run_config.embed_line

# Add the relevant embed line to the code
indent = get_indent(lines, line_number)
lines.insert(line_number, indent + "self.embed()")
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
# scene to include this embed line, within the relevant module.
code_object = compile(new_code, module.__name__, 'exec')
exec(code_object, module.__dict__)


def get_module(file_name: Optional[str], embed_line: Optional[int], is_reload: bool = False) -> Module:
module = ModuleLoader.get_module(file_name, is_reload)
if embed_line:
insert_embed_line_to_module(module, embed_line)
def get_module(run_config: Dict) -> Module:
module = ModuleLoader.get_module(run_config.file_name, run_config.is_reload)
if run_config.embed_line:
insert_embed_line_to_module(module, run_config)
return module


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)
scenes = get_scenes_to_render(all_scene_classes, scene_config, run_config)
if len(scenes) == 0:
Expand Down
1 change: 1 addition & 0 deletions manimlib/mobject/probability.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def __init__(
fill_opacity=fill_opacity,
stroke_width=stroke_width,
stroke_color=stroke_color,
**kwargs
)
self.default_label_scale_val = default_label_scale_val

Expand Down
4 changes: 2 additions & 2 deletions manimlib/mobject/svg/string_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ def mobjects_from_svg_string(self, svg_string: str) -> list[VMobject]:
# of submobject which are and use those for labels
unlabelled_submobs = submobs
labelled_content = self.get_content(is_labelled=True)
labelled_file = self.get_file_path_by_content(labelled_content)
labelled_submobs = super().mobjects_from_file(labelled_file)
labelled_file = self.get_svg_string_by_content(labelled_content)
labelled_submobs = super().mobjects_from_svg_string(labelled_file)
self.labelled_submobs = labelled_submobs
self.unlabelled_submobs = unlabelled_submobs

Expand Down
3 changes: 0 additions & 3 deletions manimlib/mobject/svg/text_mobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ def __init__(
self.disable_ligatures = disable_ligatures
self.isolate = isolate

if not isinstance(self, Text):
self.validate_markup_string(text)

super().__init__(text, height=height, **kwargs)

if self.t2g:
Expand Down

0 comments on commit 24eefef

Please sign in to comment.