Clean up get_module_with_inserted_embed_line, only accept line number as embed arg

This commit is contained in:
Grant Sanderson
2024-12-06 10:39:02 -06:00
parent d357e21c1d
commit dd0aa14442

View File

@ -9,6 +9,7 @@ import os
import screeninfo import screeninfo
import sys import sys
import yaml import yaml
from pathlib import Path
from functools import lru_cache from functools import lru_cache
@ -144,12 +145,8 @@ def parse_cli():
) )
parser.add_argument( parser.add_argument(
"-e", "--embed", "-e", "--embed",
nargs="?",
const="",
help="Creates a new file where the line `self.embed` is inserted " + \ help="Creates a new file where the line `self.embed` is inserted " + \
"into the Scenes construct method. " + \ "at the corresponding line number"
"If a string is passed in, the line will be inserted below the " + \
"last line of code including that string."
) )
parser.add_argument( parser.add_argument(
"-r", "--resolution", "-r", "--resolution",
@ -210,12 +207,19 @@ def get_manim_dir():
return os.path.abspath(os.path.join(manimlib_dir, "..")) return os.path.abspath(os.path.join(manimlib_dir, ".."))
def get_indent(line: str): def get_indent(code_lines: list[str], line_number: int):
return len(line) - len(line.lstrip()) for line in code_lines[line_number:0:-1]:
if len(line.strip()) == 0:
continue
n_spaces = len(line) - len(line.lstrip())
if line.endswith(":"):
n_spaces += 4
return n_spaces
return 0
def get_module_with_inserted_embed_line( def get_module_with_inserted_embed_line(
file_name: str, scene_name: str, line_marker: str file_name: str, scene_name: str, line_number: int
): ):
""" """
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
@ -223,59 +227,24 @@ def get_module_with_inserted_embed_line(
construct method. If there is an argument passed in, it will insert the line after 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. the last line in the sourcefile which includes that string.
""" """
with open(file_name, 'r') as fp: lines = Path(file_name).read_text().splitlines()
lines = fp.readlines()
try: scene_line_numbers = [
scene_line_number = next( n for n, line in enumerate(lines)
i for i, line in enumerate(lines) if line.startswith("class SurfaceTest")
if line.startswith(f"class {scene_name}") ]
) if len(scene_line_numbers) == 0:
except StopIteration:
log.error(f"No scene {scene_name}") log.error(f"No scene {scene_name}")
return return
scene_line_number = scene_line_numbers[0]
prev_line_num = -1 n_spaces = get_indent(lines, line_number - 1)
n_spaces = None inserted_line = " " * n_spaces + "self.embed()"
if len(line_marker) == 0:
# Find the end of the construct method
in_construct = False
for index in range(scene_line_number, len(lines) - 1):
line = lines[index]
if line.lstrip().startswith("def construct"):
in_construct = True
n_spaces = get_indent(line) + 4
elif in_construct:
if len(line.strip()) > 0 and get_indent(line) < (n_spaces or 0):
prev_line_num = index - 1
break
if prev_line_num < 0:
prev_line_num = len(lines) - 1
elif line_marker.isdigit():
# Treat the argument as a line number
prev_line_num = int(line_marker) - 1
elif len(line_marker) > 0:
# Treat the argument as a string
try:
prev_line_num = next(
i
for i in range(scene_line_number, len(lines) - 1)
if line_marker in lines[i]
)
except StopIteration:
log.error(f"No lines matching {line_marker}")
sys.exit(2)
# Insert the embed line, rewrite file, then write it back when done
if n_spaces is None:
n_spaces = get_indent(lines[prev_line_num])
inserted_line = " " * n_spaces + "self.embed()\n"
new_lines = list(lines) new_lines = list(lines)
new_lines.insert(prev_line_num + 1, inserted_line) new_lines.insert(line_number, inserted_line)
new_file = file_name.replace(".py", "_insert_embed.py") new_file = file_name.replace(".py", "_insert_embed.py")
with open(new_file, 'w') as fp: Path(new_file).write_text("\n".join(new_lines))
fp.writelines(new_lines)
from manimlib.reload_manager import reload_manager from manimlib.reload_manager import reload_manager
module = ModuleLoader.get_module(new_file, is_during_reload=reload_manager.is_reload) module = ModuleLoader.get_module(new_file, is_during_reload=reload_manager.is_reload)
@ -293,7 +262,7 @@ def get_scene_module(args: Namespace) -> Module:
return ModuleLoader.get_module(args.file) return ModuleLoader.get_module(args.file)
else: else:
return get_module_with_inserted_embed_line( return get_module_with_inserted_embed_line(
args.file, args.scene_names[0], args.embed args.file, args.scene_names[0], int(args.embed)
) )