mirror of
https://github.com/ManimCommunity/manim.git
synced 2026-06-22 10:01:47 +00:00
Apply Black's formatting.
This commit is contained in:
parent
114e676da4
commit
da73e6074c
12 changed files with 241 additions and 169 deletions
|
|
@ -17,22 +17,21 @@
|
|||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Manim'
|
||||
copyright = '2019, EulerTour'
|
||||
author = 'EulerTour'
|
||||
project = "Manim"
|
||||
copyright = "2019, EulerTour"
|
||||
author = "EulerTour"
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
master_doc = 'index'
|
||||
master_doc = "index"
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
]
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
templates_path = ["_templates"]
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
|
|
@ -45,9 +44,9 @@ exclude_patterns = []
|
|||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme = "sphinx_rtd_theme"
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['assets']
|
||||
html_static_path = ["assets"]
|
||||
|
|
|
|||
112
logo/logo.py
112
logo/logo.py
|
|
@ -2,6 +2,7 @@ from manim import *
|
|||
|
||||
NEW_BLUE = "#68a8e1"
|
||||
|
||||
|
||||
class Thumbnail(GraphScene):
|
||||
CONFIG = {
|
||||
"y_max": 8,
|
||||
|
|
@ -13,13 +14,15 @@ class Thumbnail(GraphScene):
|
|||
|
||||
def show_function_graph(self):
|
||||
self.setup_axes(animate=False)
|
||||
|
||||
def func(x):
|
||||
return 0.1 * (x + 3-5) * (x - 3-5) * (x-5) + 5
|
||||
return 0.1 * (x + 3 - 5) * (x - 3 - 5) * (x - 5) + 5
|
||||
|
||||
def rect(x):
|
||||
return 2.775*(x-1.5)+3.862
|
||||
recta = self.get_graph(rect,x_min=-1,x_max=5)
|
||||
graph = self.get_graph(func,x_min=0.2,x_max=9)
|
||||
return 2.775 * (x - 1.5) + 3.862
|
||||
|
||||
recta = self.get_graph(rect, x_min=-1, x_max=5)
|
||||
graph = self.get_graph(func, x_min=0.2, x_max=9)
|
||||
graph.set_color(NEW_BLUE)
|
||||
input_tracker_p1 = ValueTracker(1.5)
|
||||
input_tracker_p2 = ValueTracker(3.5)
|
||||
|
|
@ -37,29 +40,40 @@ class Thumbnail(GraphScene):
|
|||
return self.coords_to_point(0, get_y_value(input_tracker))
|
||||
|
||||
def get_graph_point(input_tracker):
|
||||
return self.coords_to_point(get_x_value(input_tracker), get_y_value(input_tracker))
|
||||
return self.coords_to_point(
|
||||
get_x_value(input_tracker), get_y_value(input_tracker)
|
||||
)
|
||||
|
||||
def get_v_line(input_tracker):
|
||||
return DashedLine(get_x_point(input_tracker), get_graph_point(input_tracker), stroke_width=2)
|
||||
return DashedLine(
|
||||
get_x_point(input_tracker),
|
||||
get_graph_point(input_tracker),
|
||||
stroke_width=2,
|
||||
)
|
||||
|
||||
def get_h_line(input_tracker):
|
||||
return DashedLine(get_graph_point(input_tracker), get_y_point(input_tracker), stroke_width=2)
|
||||
#
|
||||
return DashedLine(
|
||||
get_graph_point(input_tracker),
|
||||
get_y_point(input_tracker),
|
||||
stroke_width=2,
|
||||
)
|
||||
|
||||
#
|
||||
input_triangle_p1 = RegularPolygon(n=3, start_angle=TAU / 4)
|
||||
output_triangle_p1 = RegularPolygon(n=3, start_angle=0)
|
||||
for triangle in input_triangle_p1, output_triangle_p1:
|
||||
triangle.set_fill(WHITE, 1)
|
||||
triangle.set_stroke(width=0)
|
||||
triangle.scale(0.1)
|
||||
#
|
||||
#
|
||||
input_triangle_p2 = RegularPolygon(n=3, start_angle=TAU / 4)
|
||||
output_triangle_p2 = RegularPolygon(n=3, start_angle=0)
|
||||
for triangle in input_triangle_p2, output_triangle_p2:
|
||||
triangle.set_fill(WHITE, 1)
|
||||
triangle.set_stroke(width=0)
|
||||
triangle.scale(0.1)
|
||||
|
||||
#
|
||||
|
||||
#
|
||||
x_label_p1 = TexMobject("a")
|
||||
output_label_p1 = TexMobject("f(a)")
|
||||
x_label_p2 = TexMobject("b")
|
||||
|
|
@ -83,11 +97,8 @@ class Thumbnail(GraphScene):
|
|||
graph_dot_p1.move_to(get_graph_point(input_tracker_p1))
|
||||
graph_dot_p2.move_to(get_graph_point(input_tracker_p2))
|
||||
|
||||
|
||||
#
|
||||
self.play(
|
||||
ShowCreation(graph),
|
||||
)
|
||||
self.play(ShowCreation(graph),)
|
||||
# Animacion del punto a
|
||||
self.add_foreground_mobject(graph_dot_p1)
|
||||
self.add_foreground_mobject(graph_dot_p2)
|
||||
|
|
@ -106,7 +117,7 @@ class Thumbnail(GraphScene):
|
|||
ShowCreation(h_line_p2),
|
||||
Write(output_label_p2),
|
||||
DrawBorderThenFill(output_triangle_p2),
|
||||
run_time=0.5
|
||||
run_time=0.5,
|
||||
)
|
||||
self.add(
|
||||
input_triangle_p2,
|
||||
|
|
@ -119,58 +130,61 @@ class Thumbnail(GraphScene):
|
|||
)
|
||||
###################
|
||||
pendiente_recta = self.get_secant_slope_group(
|
||||
1.9, recta, dx = 1.4,
|
||||
df_label = None,
|
||||
dx_label = None,
|
||||
dx_line_color = PURPLE,
|
||||
df_line_color= ORANGE,
|
||||
)
|
||||
1.9,
|
||||
recta,
|
||||
dx=1.4,
|
||||
df_label=None,
|
||||
dx_label=None,
|
||||
dx_line_color=PURPLE,
|
||||
df_line_color=ORANGE,
|
||||
)
|
||||
grupo_secante = self.get_secant_slope_group(
|
||||
1.5, graph, dx = 2,
|
||||
df_label = None,
|
||||
dx_label = None,
|
||||
dx_line_color = "#942357",
|
||||
df_line_color= "#3f7d5c",
|
||||
secant_line_color = RED,
|
||||
1.5,
|
||||
graph,
|
||||
dx=2,
|
||||
df_label=None,
|
||||
dx_label=None,
|
||||
dx_line_color="#942357",
|
||||
df_line_color="#3f7d5c",
|
||||
secant_line_color=RED,
|
||||
)
|
||||
|
||||
|
||||
self.add(
|
||||
input_triangle_p2,
|
||||
graph_dot_p2,
|
||||
v_line_p2,
|
||||
h_line_p2,
|
||||
output_triangle_p2,
|
||||
input_triangle_p2, graph_dot_p2, v_line_p2, h_line_p2, output_triangle_p2,
|
||||
)
|
||||
self.play(FadeIn(grupo_secante))
|
||||
|
||||
kwargs = {
|
||||
"x_min" : 4,
|
||||
"x_max" : 9,
|
||||
"fill_opacity" : 0.75,
|
||||
"stroke_width" : 0.25,
|
||||
"x_min": 4,
|
||||
"x_max": 9,
|
||||
"fill_opacity": 0.75,
|
||||
"stroke_width": 0.25,
|
||||
}
|
||||
self.graph=graph
|
||||
iteraciones=6
|
||||
|
||||
self.graph = graph
|
||||
iteraciones = 6
|
||||
|
||||
self.rect_list = self.get_riemann_rectangles_list(
|
||||
graph, iteraciones,start_color=PURPLE,end_color=ORANGE, **kwargs
|
||||
graph, iteraciones, start_color=PURPLE, end_color=ORANGE, **kwargs
|
||||
)
|
||||
flat_rects = self.get_riemann_rectangles(
|
||||
self.get_graph(lambda x : 0), dx = 0.5,start_color=invert_color(PURPLE),end_color=invert_color(ORANGE),**kwargs
|
||||
self.get_graph(lambda x: 0),
|
||||
dx=0.5,
|
||||
start_color=invert_color(PURPLE),
|
||||
end_color=invert_color(ORANGE),
|
||||
**kwargs
|
||||
)
|
||||
rects = self.rect_list[0]
|
||||
self.transform_between_riemann_rects(
|
||||
flat_rects, rects,
|
||||
replace_mobject_with_target_in_scene = True,
|
||||
run_time=0.9
|
||||
flat_rects, rects, replace_mobject_with_target_in_scene=True, run_time=0.9
|
||||
)
|
||||
|
||||
# adding manim
|
||||
picture = Group(*self.mobjects)
|
||||
picture.scale(0.6).to_edge(LEFT, buff=SMALL_BUFF)
|
||||
manim = TextMobject("Manim").set_height(1.5) \
|
||||
.next_to(picture, RIGHT) \
|
||||
.shift(DOWN * 0.7)
|
||||
manim = (
|
||||
TextMobject("Manim")
|
||||
.set_height(1.5)
|
||||
.next_to(picture, RIGHT)
|
||||
.shift(DOWN * 0.7)
|
||||
)
|
||||
self.add(manim)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import traceback
|
|||
import importlib.util
|
||||
import types
|
||||
|
||||
from .config import file_writer_config,args
|
||||
from .config import file_writer_config, args
|
||||
from .utils import cfg_subcmds
|
||||
from .scene.scene import Scene
|
||||
from .utils.sounds import play_error_sound
|
||||
|
|
@ -157,12 +157,12 @@ def get_module(file_name):
|
|||
|
||||
|
||||
def main():
|
||||
if hasattr(args,"subcommands"):
|
||||
if hasattr(args, "subcommands"):
|
||||
if "cfg" in args.subcommands:
|
||||
if args.cfg_subcommand is not None:
|
||||
subcommand=args.cfg_subcommand
|
||||
subcommand = args.cfg_subcommand
|
||||
if subcommand == "write":
|
||||
cfg_subcmds.write(args.level,args.open)
|
||||
cfg_subcmds.write(args.level, args.open)
|
||||
elif subcommand == "show":
|
||||
cfg_subcmds.show()
|
||||
elif subcommand == "export":
|
||||
|
|
@ -170,7 +170,6 @@ def main():
|
|||
else:
|
||||
logger.error("No argument provided; Exiting...")
|
||||
|
||||
|
||||
else:
|
||||
module = get_module(file_writer_config["input_file"])
|
||||
all_scene_classes = get_scene_classes_from_module(module)
|
||||
|
|
|
|||
|
|
@ -87,8 +87,10 @@ def _parse_config(config_parser, args):
|
|||
|
||||
args, config_parser, file_writer_config, successfully_read_files = _run_config()
|
||||
if _from_command_line():
|
||||
logger.info(f"Read configuration files: {[os.path.abspath(cfgfile) for cfgfile in successfully_read_files]}")
|
||||
if not(hasattr(args,"subcommands")):
|
||||
logger.info(
|
||||
f"Read configuration files: {[os.path.abspath(cfgfile) for cfgfile in successfully_read_files]}"
|
||||
)
|
||||
if not (hasattr(args, "subcommands")):
|
||||
_init_dirs(file_writer_config)
|
||||
config = _parse_config(config_parser, args)
|
||||
camera_config = config
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from rich.progress import track
|
|||
from rich.style import Style
|
||||
from rich.errors import StyleSyntaxError
|
||||
|
||||
__all__ = ["write","show","export"]
|
||||
__all__ = ["write", "show", "export"]
|
||||
|
||||
RICH_COLOUR_INSTRUCTIONS = """[red]The default colour is used by the input statement.
|
||||
If left empty, the default colour will be used.[/red]
|
||||
|
|
@ -25,6 +25,7 @@ If left empty, the default colour will be used.[/red]
|
|||
|
||||
console = Console()
|
||||
|
||||
|
||||
def is_valid_style(style):
|
||||
"""Checks whether the entered color is a valid color according to rich
|
||||
Parameters
|
||||
|
|
@ -71,7 +72,9 @@ def replace_keys(default):
|
|||
def write(level=None, openfile=False):
|
||||
config = _run_config()[1]
|
||||
config_paths = _paths_config_file() + [os.path.abspath("manim.cfg")]
|
||||
console.print("[yellow bold]Manim Configuration File Writer[/yellow bold]", justify="center")
|
||||
console.print(
|
||||
"[yellow bold]Manim Configuration File Writer[/yellow bold]", justify="center"
|
||||
)
|
||||
|
||||
USER_CONFIG_MSG = f"""A configuration file at [yellow]{config_paths[1]}[/yellow] has been created with your required changes.
|
||||
This will be used when running the manim command. If you want to override this config,
|
||||
|
|
@ -84,7 +87,7 @@ To save your theme please save that file and place it in your current working di
|
|||
action = "save this as"
|
||||
|
||||
for category in config:
|
||||
console.print(f"{category}",style="bold green underline")
|
||||
console.print(f"{category}", style="bold green underline")
|
||||
default = config[category]
|
||||
if category == "logger":
|
||||
console.print(RICH_COLOUR_INSTRUCTIONS)
|
||||
|
|
@ -94,8 +97,12 @@ To save your theme please save that file and place it in your current working di
|
|||
temp = input()
|
||||
if temp:
|
||||
while not is_valid_style(temp):
|
||||
console.print("[red bold]Invalid style. Try again.[/red bold]")
|
||||
console.print(f"Enter the style for {key}:", style=key, end="")
|
||||
console.print(
|
||||
"[red bold]Invalid style. Try again.[/red bold]"
|
||||
)
|
||||
console.print(
|
||||
f"Enter the style for {key}:", style=key, end=""
|
||||
)
|
||||
temp = input()
|
||||
else:
|
||||
default[key] = temp
|
||||
|
|
@ -103,16 +110,20 @@ To save your theme please save that file and place it in your current working di
|
|||
|
||||
else:
|
||||
for key in default:
|
||||
if default[key] in ["True","False"]:
|
||||
if default[key] in ["True", "False"]:
|
||||
console.print(
|
||||
f"Enter value for {key} (defaults to {default[key]}):", end="")
|
||||
f"Enter value for {key} (defaults to {default[key]}):",
|
||||
end="",
|
||||
)
|
||||
temp = input()
|
||||
if temp:
|
||||
while not temp.lower().capitalize() in ["True","False"]:
|
||||
while not temp.lower().capitalize() in ["True", "False"]:
|
||||
console.print(
|
||||
"[red bold]Invalid value. Try again.[/red bold]")
|
||||
"[red bold]Invalid value. Try again.[/red bold]"
|
||||
)
|
||||
console.print(
|
||||
f"Enter the style for {key}:", style=key, end="")
|
||||
f"Enter the style for {key}:", style=key, end=""
|
||||
)
|
||||
temp = input()
|
||||
else:
|
||||
default[key] = temp
|
||||
|
|
@ -130,38 +141,38 @@ To save your theme please save that file and place it in your current working di
|
|||
else:
|
||||
action_to_userpath = ""
|
||||
|
||||
if action_to_userpath.lower() == "y" or level=="user":
|
||||
if action_to_userpath.lower() == "y" or level == "user":
|
||||
cfg_file_path = os.path.join(
|
||||
guarantee_existence(
|
||||
os.path.dirname(config_paths[1])
|
||||
),"manim.cfg")
|
||||
guarantee_existence(os.path.dirname(config_paths[1])), "manim.cfg"
|
||||
)
|
||||
console.print(USER_CONFIG_MSG)
|
||||
else:
|
||||
cfg_file_path = os.path.join(
|
||||
guarantee_existence(
|
||||
os.path.dirname(config_paths[2])
|
||||
),"manim.cfg")
|
||||
guarantee_existence(os.path.dirname(config_paths[2])), "manim.cfg"
|
||||
)
|
||||
console.print(CWD_CONFIG_MSG)
|
||||
with open(cfg_file_path, "w") as fp:
|
||||
config.write(fp)
|
||||
if openfile:
|
||||
open_file(cfg_file_path)
|
||||
|
||||
|
||||
def show():
|
||||
current_config = finalized_configs_dict()
|
||||
for category in current_config:
|
||||
console.print(f"{category}",style="bold green underline")
|
||||
console.print(f"{category}", style="bold green underline")
|
||||
for entry in current_config[category]:
|
||||
if category=="logger":
|
||||
console.print(f"{entry} :",end="")
|
||||
if category == "logger":
|
||||
console.print(f"{entry} :", end="")
|
||||
console.print(
|
||||
f" {current_config[category][entry]}",
|
||||
style=current_config[category][entry]
|
||||
)
|
||||
style=current_config[category][entry],
|
||||
)
|
||||
else:
|
||||
console.print(f"{entry} : {current_config[category][entry]}")
|
||||
console.print("\n")
|
||||
|
||||
|
||||
def export(path):
|
||||
config = _run_config()[1]
|
||||
if os.path.abspath(path) == os.path.abspath(os.getcwd()):
|
||||
|
|
@ -169,19 +180,20 @@ def export(path):
|
|||
"""You are reading the config from the same directory you are exporting to.
|
||||
This means that the exported config will overwrite the config for this directory.
|
||||
Are you sure you want to continue? (y/n)""",
|
||||
style="red bold", end=""
|
||||
)
|
||||
proceed = True if input().lower()=="y" else False
|
||||
style="red bold",
|
||||
end="",
|
||||
)
|
||||
proceed = True if input().lower() == "y" else False
|
||||
else:
|
||||
proceed = True
|
||||
if proceed:
|
||||
if not os.path.isdir(path):
|
||||
console.print(f"Creating folder: {path}.",style="red bold")
|
||||
console.print(f"Creating folder: {path}.", style="red bold")
|
||||
os.mkdir(path)
|
||||
with open(os.path.join(path,"manim.cfg"),"w") as outpath:
|
||||
with open(os.path.join(path, "manim.cfg"), "w") as outpath:
|
||||
config.write(outpath)
|
||||
from_path = os.path.join(os.getcwd(),'manim.cfg')
|
||||
to_path = os.path.join(path,'manim.cfg')
|
||||
from_path = os.path.join(os.getcwd(), "manim.cfg")
|
||||
to_path = os.path.join(path, "manim.cfg")
|
||||
console.print(f"Exported final Config at {from_path} to {to_path}.")
|
||||
else:
|
||||
console.print("Aborted...", style="red bold")
|
||||
|
|
|
|||
|
|
@ -16,9 +16,16 @@ import colour
|
|||
from .. import constants
|
||||
from .tex import TexTemplate, TexTemplateFromFile
|
||||
|
||||
__all__ = ["_run_config", "_paths_config_file", "_from_command_line", "finalized_configs_dict"]
|
||||
__all__ = [
|
||||
"_run_config",
|
||||
"_paths_config_file",
|
||||
"_from_command_line",
|
||||
"finalized_configs_dict",
|
||||
]
|
||||
|
||||
min_argvs = 3 if "-m" in sys.argv[0] else 2
|
||||
|
||||
|
||||
def _parse_file_writer_config(config_parser, args):
|
||||
"""Parse config files and CLI arguments into a single dictionary."""
|
||||
# By default, use the CLI section of the digested .cfg files
|
||||
|
|
@ -31,9 +38,11 @@ def _parse_file_writer_config(config_parser, args):
|
|||
# the .cfg files, only from CLI arguments.
|
||||
# If a subcommand is given, manim will not render a video and
|
||||
# thus these specific input/output files are not needed.
|
||||
if not(hasattr(args,"subcommands")):
|
||||
if not (hasattr(args, "subcommands")):
|
||||
fw_config["input_file"] = args.file
|
||||
fw_config["scene_names"] = args.scene_names if args.scene_names is not None else []
|
||||
fw_config["scene_names"] = (
|
||||
args.scene_names if args.scene_names is not None else []
|
||||
)
|
||||
fw_config["output_file"] = args.output_file
|
||||
|
||||
# Handle all options that are directly overridden by CLI
|
||||
|
|
@ -136,31 +145,29 @@ def _parse_cli(arg_list, input=True):
|
|||
if input:
|
||||
# If the only command is `manim`, we want both subcommands like `cfg`
|
||||
# and mandatory positional arguments like `file` to show up in the help section.
|
||||
if len(sys.argv) == min_argvs-1 or _subcommands_exist():
|
||||
if len(sys.argv) == min_argvs - 1 or _subcommands_exist():
|
||||
subparsers = parser.add_subparsers(dest="subcommands")
|
||||
cfg_related = subparsers.add_parser('cfg')
|
||||
cfg_related = subparsers.add_parser("cfg")
|
||||
cfg_subparsers = cfg_related.add_subparsers(dest="cfg_subcommand")
|
||||
|
||||
cfg_write_parser = cfg_subparsers.add_parser('write')
|
||||
cfg_write_parser = cfg_subparsers.add_parser("write")
|
||||
cfg_write_parser.add_argument(
|
||||
"--level",
|
||||
choices=["user", "cwd"],
|
||||
default=None,
|
||||
help="Specify if this config is for user or just the working directory."
|
||||
)
|
||||
cfg_write_parser.add_argument(
|
||||
"--open",
|
||||
action="store_const",
|
||||
const=True,
|
||||
default = False
|
||||
help="Specify if this config is for user or just the working directory.",
|
||||
)
|
||||
cfg_subparsers.add_parser('show')
|
||||
cfg_write_parser.add_argument(
|
||||
"--open", action="store_const", const=True, default=False
|
||||
)
|
||||
cfg_subparsers.add_parser("show")
|
||||
|
||||
cfg_export_parser = cfg_subparsers.add_parser("export")
|
||||
cfg_export_parser.add_argument("--dir",default=os.getcwd())
|
||||
cfg_export_parser.add_argument("--dir", default=os.getcwd())
|
||||
|
||||
if (len(sys.argv) == min_argvs-1 or
|
||||
not _subcommands_exist(ignore = ["--help","-h"])):
|
||||
if len(sys.argv) == min_argvs - 1 or not _subcommands_exist(
|
||||
ignore=["--help", "-h"]
|
||||
):
|
||||
parser.add_argument(
|
||||
"file", help="path to file holding the python code for the scene",
|
||||
)
|
||||
|
|
@ -343,12 +350,15 @@ def _parse_cli(arg_list, input=True):
|
|||
parser.add_argument(
|
||||
"--config_file", help="Specify the configuration file",
|
||||
)
|
||||
parsed=parser.parse_args(arg_list)
|
||||
if hasattr(parsed,"subcommands"):
|
||||
setattr(parsed, "cfg_subcommand",
|
||||
parsed = parser.parse_args(arg_list)
|
||||
if hasattr(parsed, "subcommands"):
|
||||
setattr(
|
||||
parsed,
|
||||
"cfg_subcommand",
|
||||
cfg_related.parse_args(
|
||||
sys.argv[min_argvs -(0 if min_argvs == 2 else 1):]
|
||||
).cfg_subcommand)
|
||||
sys.argv[min_argvs - (0 if min_argvs == 2 else 1) :]
|
||||
).cfg_subcommand,
|
||||
)
|
||||
|
||||
return parsed
|
||||
|
||||
|
|
@ -364,6 +374,7 @@ def _init_dirs(config):
|
|||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
|
||||
|
||||
def _from_command_line():
|
||||
"""Determine if manim was called from the command line."""
|
||||
# Manim can be called from the command line in three different
|
||||
|
|
@ -379,11 +390,13 @@ def _from_command_line():
|
|||
|
||||
return from_cli_command or from_python_m
|
||||
|
||||
|
||||
def _from_dunder_main():
|
||||
dunder_main_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
"__main__.py")
|
||||
return sys.argv[0]==dunder_main_path
|
||||
os.path.dirname(os.path.dirname(__file__)), "__main__.py"
|
||||
)
|
||||
return sys.argv[0] == dunder_main_path
|
||||
|
||||
|
||||
def _paths_config_file():
|
||||
library_wide = os.path.abspath(
|
||||
|
|
@ -411,14 +424,16 @@ def _paths_config_file():
|
|||
def _run_config():
|
||||
# Config files to be parsed, in ascending priority
|
||||
config_files = _paths_config_file()
|
||||
if _from_command_line() or _from_dunder_main():
|
||||
if _from_command_line() or _from_dunder_main():
|
||||
args = _parse_cli(sys.argv[1:])
|
||||
if not hasattr(args,"subcommands"):
|
||||
if not hasattr(args, "subcommands"):
|
||||
if args.config_file is not None:
|
||||
if os.path.exists(args.config_file):
|
||||
config_files.append(args.config_file)
|
||||
else:
|
||||
raise FileNotFoundError(f"Config file {args.config_file} doesn't exist")
|
||||
raise FileNotFoundError(
|
||||
f"Config file {args.config_file} doesn't exist"
|
||||
)
|
||||
else:
|
||||
script_directory_file_config = os.path.join(
|
||||
os.path.dirname(args.file), "manim.cfg"
|
||||
|
|
@ -426,7 +441,7 @@ def _run_config():
|
|||
if os.path.exists(script_directory_file_config):
|
||||
config_files.append(script_directory_file_config)
|
||||
else:
|
||||
working_directory_file_config = os.path.join(os.getcwd(),"manim.cfg")
|
||||
working_directory_file_config = os.path.join(os.getcwd(), "manim.cfg")
|
||||
if os.path.exists(working_directory_file_config):
|
||||
config_files.append(working_directory_file_config)
|
||||
|
||||
|
|
@ -443,14 +458,16 @@ def _run_config():
|
|||
file_writer_config = _parse_file_writer_config(config_parser, args)
|
||||
return args, config_parser, file_writer_config, successfully_read_files
|
||||
|
||||
|
||||
def finalized_configs_dict():
|
||||
config=_run_config()[1]
|
||||
config = _run_config()[1]
|
||||
return {section: dict(config[section]) for section in config.sections()}
|
||||
|
||||
def _subcommands_exist(ignore = []):
|
||||
NON_ANIM_UTILS = ["cfg","--help","-h"]
|
||||
|
||||
def _subcommands_exist(ignore=[]):
|
||||
NON_ANIM_UTILS = ["cfg", "--help", "-h"]
|
||||
NON_ANIM_UTILS = [util for util in NON_ANIM_UTILS if util not in ignore]
|
||||
|
||||
not_only_manim = len(sys.argv) > min_argvs-1
|
||||
not_only_manim = len(sys.argv) > min_argvs - 1
|
||||
sub_command_exists = any(a == item for a in sys.argv for item in NON_ANIM_UTILS)
|
||||
return not_only_manim and sub_command_exists
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ def get_sorted_integer_files(
|
|||
indexed_files.sort(key=lambda p: p[0])
|
||||
return list(map(lambda p: os.path.join(directory, p[1]), indexed_files))
|
||||
|
||||
|
||||
def open_file(file_path):
|
||||
current_os = platform.system()
|
||||
if current_os == "Windows":
|
||||
|
|
|
|||
|
|
@ -3,49 +3,67 @@ import os
|
|||
import sys
|
||||
import urllib.request
|
||||
|
||||
if 'Windows' in platform.system():
|
||||
if "Windows" in platform.system():
|
||||
# In case the python version is 3.6 and the system is 32-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo
|
||||
if sys.version[:3]=='3.6' and platform.machine()=='x86':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp36-cp36m-win32.whl", "pycairo-1.19.1-cp36-cp36m-win32.whl")
|
||||
if sys.version[:3] == "3.6" and platform.machine() == "x86":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp36-cp36m-win32.whl",
|
||||
"pycairo-1.19.1-cp36-cp36m-win32.whl",
|
||||
)
|
||||
os.system("pip install pycairo-1.19.1-cp36-cp36m-win32.whl")
|
||||
os.remove("pycairo-1.19.1-cp37-cp37m-win32.whl")
|
||||
|
||||
# In case the python version is 3.6 and the system is 64-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo
|
||||
elif sys.version[:3]=='3.6' and platform.machine()=='AMD64':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp36-cp36m-win_amd64.whl", "pycairo-1.19.1-cp36-cp36m-win_amd64.whl")
|
||||
elif sys.version[:3] == "3.6" and platform.machine() == "AMD64":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp36-cp36m-win_amd64.whl",
|
||||
"pycairo-1.19.1-cp36-cp36m-win_amd64.whl",
|
||||
)
|
||||
print("Sucessfully downloaded Cairo for your system")
|
||||
print("Installing Cairo")
|
||||
os.system("pip install pycairo-1.19.1-cp36-cp36m-win_amd64.whl")
|
||||
os.remove("pycairo-1.19.1-cp36-cp36m-win_amd64.whl")
|
||||
|
||||
|
||||
# In case the python version is 3.7 and the system is 32-bit, try pycairo‑1.19.1‑cp37‑cp37m‑win32.whl version of cairo
|
||||
elif sys.version[:3]=='3.7' and platform.machine()=='x86':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp37-cp37m-win32.whl", "pycairo-1.19.1-cp37-cp37m-win32.whl")
|
||||
elif sys.version[:3] == "3.7" and platform.machine() == "x86":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp37-cp37m-win32.whl",
|
||||
"pycairo-1.19.1-cp37-cp37m-win32.whl",
|
||||
)
|
||||
print("Sucessfully downloaded Cairo for your system")
|
||||
print("Installing Cairo")
|
||||
os.system("pip install pycairo-1.19.1-cp37-cp37m-win32.whl")
|
||||
os.remove("pycairo-1.19.1-cp37-cp37m-win32.whl")
|
||||
|
||||
# In case the python version is 3.7 and the system is AMD64, try pycairo-1.19.1-cp37-cp37m-win_amd64.whl version of cairo
|
||||
elif sys.version[:3]=='3.7' and platform.machine()=='AMD64':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp37-cp37m-win_amd64.whl", "pycairo-1.19.1-cp37-cp37m-win_amd64.whl")
|
||||
elif sys.version[:3] == "3.7" and platform.machine() == "AMD64":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp37-cp37m-win_amd64.whl",
|
||||
"pycairo-1.19.1-cp37-cp37m-win_amd64.whl",
|
||||
)
|
||||
print("Sucessfully downloaded Cairo for your system")
|
||||
print("Installing Cairo")
|
||||
os.system("pip install pycairo-1.19.1-cp37-cp37m-win_amd64.whl")
|
||||
os.remove("pycairo-1.19.1-cp37-cp37m-win_amd64.whl")
|
||||
|
||||
|
||||
# In case the python version is 3.8 and the system is 32-bit, try pycairo-1.19.1-cp38-cp38-win32.whl version of cairo
|
||||
elif sys.version[:3]=='3.8' and platform.machine()=='x86':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp38-cp38-win32.whl", "pycairo-1.19.1-cp38-cp38-win32.whl")
|
||||
elif sys.version[:3] == "3.8" and platform.machine() == "x86":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp38-cp38-win32.whl",
|
||||
"pycairo-1.19.1-cp38-cp38-win32.whl",
|
||||
)
|
||||
print("Sucessfully downloaded Cairo for your system")
|
||||
print("Installing Cairo")
|
||||
os.system("pip install pycairo-1.19.1-cp38-cp38-win32.whl")
|
||||
os.remove("pycairo-1.19.1-cp38-cp38-win32.whl")
|
||||
|
||||
|
||||
# In case the python version is 3.8 and the system is AMD64, try pycairo-1.19.1-cp38-cp38-win_amd64.whl version of cairo
|
||||
elif sys.version[:3]=='3.8' and platform.machine()=='AMD64':
|
||||
urllib.request.urlretrieve("https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp38-cp38-win_amd64.whl", "pycairo-1.19.1-cp38-cp38-win_amd64.whl")
|
||||
elif sys.version[:3] == "3.8" and platform.machine() == "AMD64":
|
||||
urllib.request.urlretrieve(
|
||||
"https://download.lfd.uci.edu/pythonlibs/w3jqiv8s/pycairo-1.19.1-cp38-cp38-win_amd64.whl",
|
||||
"pycairo-1.19.1-cp38-cp38-win_amd64.whl",
|
||||
)
|
||||
print("Sucessfully downloaded Cairo for your system")
|
||||
print("Installing Cairo")
|
||||
os.system("pip install pycairo-1.19.1-cp38-cp38-win_amd64.whl")
|
||||
os.remove("pycairo-1.19.1-cp38-cp38-win_amd64.whl")
|
||||
os.remove("pycairo-1.19.1-cp38-cp38-win_amd64.whl")
|
||||
|
|
|
|||
7
setup.py
7
setup.py
|
|
@ -6,12 +6,9 @@ setup(
|
|||
description="Animation engine for explanatory math videos",
|
||||
license="MIT",
|
||||
packages=find_namespace_packages(),
|
||||
package_data={ "manim": ["*.tex", "*.cfg"] },
|
||||
package_data={"manim": ["*.tex", "*.cfg"]},
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"manim=manim.__main__:main",
|
||||
"manimcm=manim.__main__:main",
|
||||
]
|
||||
"console_scripts": ["manim=manim.__main__:main", "manimcm=manim.__main__:main",]
|
||||
},
|
||||
install_requires=[
|
||||
"colour",
|
||||
|
|
|
|||
|
|
@ -35,11 +35,12 @@ def pytest_collection_modifyitems(config, items):
|
|||
def python_version():
|
||||
return "python3" if sys.platform == "darwin" else "python"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def reset_cfg_file():
|
||||
cfgfilepath = os.path.join(os.path.dirname(__file__),"test_cli", "manim.cfg")
|
||||
cfgfilepath = os.path.join(os.path.dirname(__file__), "test_cli", "manim.cfg")
|
||||
with open(cfgfilepath) as cfgfile:
|
||||
original = cfgfile.read()
|
||||
yield
|
||||
with open(cfgfilepath,"w") as cfgfile:
|
||||
cfgfile.write(original)
|
||||
with open(cfgfilepath, "w") as cfgfile:
|
||||
cfgfile.write(original)
|
||||
|
|
|
|||
|
|
@ -3,13 +3,18 @@ import os
|
|||
import shutil
|
||||
|
||||
from test_cli import capture
|
||||
|
||||
this_folder = os.path.dirname(__file__)
|
||||
|
||||
|
||||
def test_cfg_help(python_version):
|
||||
"""Test if Manim successfully adds configparsers when a subcommand is invoked."""
|
||||
command = f"cd {this_folder} && {python_version} -m manim cfg --help"
|
||||
out, err, exitcode = capture(command, use_shell=True)
|
||||
assert exitcode == 0, f"The cfg subcommand help is not working as intended.\nError : {err}"
|
||||
assert (
|
||||
exitcode == 0
|
||||
), f"The cfg subcommand help is not working as intended.\nError : {err}"
|
||||
|
||||
|
||||
def test_cfg_show(python_version):
|
||||
"""Test if the `manim cfg show` command works as intended."""
|
||||
|
|
@ -18,15 +23,19 @@ def test_cfg_show(python_version):
|
|||
assert exitcode == 0
|
||||
assert f"{os.path.sep}tests{os.path.sep}".encode("utf-8") in out, err
|
||||
|
||||
|
||||
def test_cfg_export(python_version):
|
||||
"""Test if the `manim cfg export` command works as intended."""
|
||||
command = f"cd {this_folder} && {python_version} -m manim cfg export --dir temp"
|
||||
out, err, exitcode = capture(command, use_shell=True)
|
||||
assert exitcode == 0, f"The cfg subcommand export is not working as intended.\nError : {err}"
|
||||
assert os.path.exists(os.path.join(this_folder,"temp","manim.cfg"))
|
||||
with open(os.path.join(this_folder,"temp","manim.cfg"),"r") as writtencfg:
|
||||
assert (
|
||||
exitcode == 0
|
||||
), f"The cfg subcommand export is not working as intended.\nError : {err}"
|
||||
assert os.path.exists(os.path.join(this_folder, "temp", "manim.cfg"))
|
||||
with open(os.path.join(this_folder, "temp", "manim.cfg"), "r") as writtencfg:
|
||||
assert "sound = True" in writtencfg.read(), err
|
||||
shutil.rmtree(os.path.join(this_folder,"temp"))
|
||||
shutil.rmtree(os.path.join(this_folder, "temp"))
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("reset_cfg_file")
|
||||
def test_cfg_write(python_version):
|
||||
|
|
@ -39,9 +48,11 @@ def test_cfg_write(python_version):
|
|||
out, err, exitcode = capture(
|
||||
command,
|
||||
instream=open(os.path.join(this_folder, "write_cfg_sbcmd_input.txt")),
|
||||
use_shell=True
|
||||
)
|
||||
assert exitcode == 0, f"The cfg subcommand write is not working as intended.\nError : {err}"
|
||||
use_shell=True,
|
||||
)
|
||||
assert (
|
||||
exitcode == 0
|
||||
), f"The cfg subcommand write is not working as intended.\nError : {err}"
|
||||
|
||||
with open(cfgfilepath,"r") as cfgfile:
|
||||
with open(cfgfilepath, "r") as cfgfile:
|
||||
assert "sound = False" in cfgfile.read()
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ from shutil import rmtree
|
|||
import pytest
|
||||
|
||||
|
||||
def capture(command,instream=None, use_shell=False):
|
||||
proc = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=instream,
|
||||
shell = use_shell
|
||||
)
|
||||
def capture(command, instream=None, use_shell=False):
|
||||
proc = subprocess.Popen(
|
||||
command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
stdin=instream,
|
||||
shell=use_shell,
|
||||
)
|
||||
out, err = proc.communicate()
|
||||
return out, err, proc.returncode
|
||||
|
||||
|
|
@ -75,8 +76,8 @@ def test_dash_as_name(python_version):
|
|||
command = [python_version, "-m", "manim", "-", "-l", "--media_dir", path_output]
|
||||
out, err, exitcode = capture(
|
||||
command,
|
||||
instream = open(os.path.join(os.path.dirname(__file__), "dash_test_script.txt"))
|
||||
)
|
||||
instream=open(os.path.join(os.path.dirname(__file__), "dash_test_script.txt")),
|
||||
)
|
||||
assert exitcode == 0, err
|
||||
assert os.path.exists(
|
||||
os.path.join(path_output, "videos", "-", "480p15", "DashAsNameTest.mp4")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue