Repository: 3b1b/manim
File: manimlib/extract_scene.py (Python)

Code before:
        return ""

    # Either return its leading spaces, or add for if it ends with colon
    n_spaces = len(line) - len(line.lstrip())
    if line.endswith(":"):
        n_spaces += 4
    return n_spaces * " "


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,
    # it should automatically identifies the nearest class
    # defined above `<line_number>` as 'scene_names'.
    classes = list(filter(lambda line: line.startswith("class"), lines[:line_number]))
    if classes:
        from re import search

        name_search = search(r"(\w+)\(", classes[-1])
        run_config.update(scene_names=[name_search.group(1)])
    else:
        log.error(f"No 'class' has been 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(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)

Review comment (suggestion):
```suggestion
    # it should automatically identify the nearest class
```

Code after:
        return ""

    # Either return its leading spaces, or add for if it ends with colon
    n_spaces = len(line) - len(line.lstrip())
    if line.endswith(":"):
        n_spaces += 4
    return n_spaces * " "


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(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