def test_digest_file(tmp_path): """Test that a config file can be digested programatically.""" with tempconfig({}): tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) tmp_cfg.write(""" [CLI] media_dir = this_is_my_favorite_path video_dir = {media_dir}/videos """) tmp_cfg.close() config.digest_file(tmp_cfg.name) assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") assert config.get_dir("video_dir") == Path( "this_is_my_favorite_path/videos")
def main(): console.print(f"Manim Community [green]v{__version__}[/green]") args = parse_args(sys.argv) if hasattr(args, "cmd"): if args.cmd == "cfg": if args.subcmd: from manim._config import cfg_subcmds if args.subcmd == "write": cfg_subcmds.write(args.level, args.open) elif args.subcmd == "show": cfg_subcmds.show() elif args.subcmd == "export": cfg_subcmds.export(args.dir) else: logger.error("No subcommand provided; Exiting...") elif args.cmd == "plugins": from manim.plugins import plugins_flags if args.list: plugins_flags.list_plugins() elif not args.list: logger.error("No flag provided; Exiting...") # elif args.cmd == "some_other_cmd": # something_else_here() else: config.digest_args(args) input_file = config.get_dir("input_file") if config["use_webgl_renderer"]: try: from manim.grpc.impl import frame_server_impl server = frame_server_impl.get(input_file) server.start() server.wait_for_termination() except ModuleNotFoundError as e: print("\n\n") print("Dependencies for the WebGL render are missing. Run " "pip install manim[webgl_renderer] to install them.") print(e) print("\n\n") else: for SceneClass in scene_classes_from_file(input_file): try: scene = SceneClass() scene.render() open_file_if_needed(scene.renderer.file_writer) except Exception: print("\n\n") traceback.print_exc() print("\n\n")
def main(): args = parse_args(sys.argv) if hasattr(args, "cmd"): if args.cmd == "cfg": if args.subcmd: from manim._config import cfg_subcmds if args.subcmd == "write": cfg_subcmds.write(args.level, args.open) elif args.subcmd == "show": cfg_subcmds.show() elif args.subcmd == "export": cfg_subcmds.export(args.dir) else: logger.error("No subcommand provided; Exiting...") elif args.cmd == "plugins": from manim.plugins import plugins_flags if args.list: plugins_flags.list_plugins() elif not args.list: logger.error("No flag provided; Exiting...") # elif args.cmd == "some_other_cmd": # something_else_here() else: config.digest_args(args) input_file = config.get_dir("input_file") if config["use_js_renderer"]: try: if frame_server_impl is None: raise ImportError( "Dependencies for JS renderer is not installed.") server = frame_server_impl.get(input_file) server.start() server.wait_for_termination() except Exception: print("\n\n") traceback.print_exc() print("\n\n") else: for SceneClass in scene_classes_from_file(input_file): try: scene = SceneClass() scene.render() open_file_if_needed(scene.renderer.file_writer) except Exception: print("\n\n") traceback.print_exc() print("\n\n")
def test_digest_file(tmp_path): """Test that a config file can be digested programmatically.""" with tempconfig({}): tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) tmp_cfg.write( """ [CLI] media_dir = this_is_my_favorite_path video_dir = {media_dir}/videos sections_dir = {media_dir}/{scene_name}/prepare_for_unforeseen_consequences frame_height = 10 """, ) tmp_cfg.close() config.digest_file(tmp_cfg.name) assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") assert config.get_dir("video_dir") == Path( "this_is_my_favorite_path/videos") assert config.get_dir("sections_dir", scene_name="test") == Path( "this_is_my_favorite_path/test/prepare_for_unforeseen_consequences" )
def main(): args = parse_args(sys.argv) if hasattr(args, "cmd"): if args.cmd == "cfg": if args.subcmd: from manim.config import cfg_subcmds if args.subcmd == "write": cfg_subcmds.write(args.level, args.open) elif args.subcmd == "show": cfg_subcmds.show() elif args.subcmd == "export": cfg_subcmds.export(args.dir) else: logger.error("No subcommand provided; Exiting...") # elif args.cmd == "some_other_cmd": # something_else_here() else: config.digest_args(args) module = get_module(config.get_dir("input_file")) all_scene_classes = get_scene_classes_from_module(module) scene_classes_to_render = get_scenes_to_render(all_scene_classes) for SceneClass in scene_classes_to_render: try: if config["use_js_renderer"]: if frame_server_impl is None: raise ImportError( "Dependencies for JS renderer is not installed.") frame_server_impl.get(SceneClass).start() else: scene = SceneClass() scene.render() open_file_if_needed(scene.renderer.file_writer) except Exception: print("\n\n") traceback.print_exc() print("\n\n")
def run(self): # Render is skipped if the tag skip-manim is present should_skip = ( "skip-manim" in self.state.document.settings.env.app.builder.tags.tags) # Or if we are making the pot-files should_skip = (should_skip or self.state.document.settings.env.app.builder.name == "gettext") if should_skip: node = skip_manim_node() self.state.nested_parse( StringList(self.content[0]), self.content_offset, node, ) return [node] from manim import config, tempconfig global classnamedict clsname = self.arguments[0] if clsname not in classnamedict: classnamedict[clsname] = 1 else: classnamedict[clsname] += 1 hide_source = "hide_source" in self.options save_as_gif = "save_as_gif" in self.options save_last_frame = "save_last_frame" in self.options assert not (save_as_gif and save_last_frame) ref_content = (self.options.get("ref_modules", []) + self.options.get("ref_classes", []) + self.options.get("ref_functions", []) + self.options.get("ref_methods", [])) if ref_content: ref_block = "References: " + " ".join(ref_content) else: ref_block = "" if "quality" in self.options: quality = f'{self.options["quality"]}_quality' else: quality = "example_quality" frame_rate = QUALITIES[quality]["frame_rate"] pixel_height = QUALITIES[quality]["pixel_height"] pixel_width = QUALITIES[quality]["pixel_width"] state_machine = self.state_machine document = state_machine.document source_file_name = Path(document.attributes["source"]) source_rel_name = source_file_name.relative_to(setup.confdir) source_rel_dir = source_rel_name.parents[0] dest_dir = Path(setup.app.builder.outdir, source_rel_dir).absolute() if not dest_dir.exists(): dest_dir.mkdir(parents=True, exist_ok=True) source_block = [ ".. code-block:: python", "", " from manim import *\n", *(" " + line for line in self.content), ] source_block = "\n".join(source_block) config.media_dir = (Path(setup.confdir) / "media").absolute() config.images_dir = "{media_dir}/images" config.video_dir = "{media_dir}/videos/{quality}" output_file = f"{clsname}-{classnamedict[clsname]}" config.assets_dir = Path("_static") config.progress_bar = "none" config.verbosity = "WARNING" example_config = { "frame_rate": frame_rate, "pixel_height": pixel_height, "pixel_width": pixel_width, "save_last_frame": save_last_frame, "write_to_movie": not save_last_frame, "output_file": output_file, } if save_last_frame: example_config["format"] = None if save_as_gif: example_config["format"] = "gif" user_code = self.content if user_code[0].startswith( ">>> "): # check whether block comes from doctest user_code = [ line[4:] for line in user_code if line.startswith((">>> ", "... ")) ] code = [ "from manim import *", *user_code, f"{clsname}().render()", ] with tempconfig(example_config): run_time = timeit(lambda: exec("\n".join(code), globals()), number=1) video_dir = config.get_dir("video_dir") images_dir = config.get_dir("images_dir") _write_rendering_stats( clsname, run_time, self.state.document.settings.env.docname, ) # copy video file to output directory if not (save_as_gif or save_last_frame): filename = f"{output_file}.mp4" filesrc = video_dir / filename destfile = Path(dest_dir, filename) shutil.copyfile(filesrc, destfile) elif save_as_gif: filename = f"{output_file}.gif" filesrc = video_dir / filename elif save_last_frame: filename = f"{output_file}.png" filesrc = images_dir / filename else: raise ValueError("Invalid combination of render flags received.") rendered_template = jinja2.Template(TEMPLATE).render( clsname=clsname, clsname_lowercase=clsname.lower(), hide_source=hide_source, filesrc_rel=Path(filesrc).relative_to(setup.confdir).as_posix(), output_file=output_file, save_last_frame=save_last_frame, save_as_gif=save_as_gif, source_block=source_block, ref_block=ref_block, ) state_machine.insert_input( rendered_template.split("\n"), source=document.attributes["source"], ) return []
def run(self): if "skip-manim" in self.state.document.settings.env.app.builder.tags.tags: node = skip_manim_node() self.state.nested_parse(StringList(self.content[0]), self.content_offset, node) return [node] from manim import config global classnamedict clsname = self.arguments[0] if clsname not in classnamedict: classnamedict[clsname] = 1 else: classnamedict[clsname] += 1 hide_source = "hide_source" in self.options save_as_gif = "save_as_gif" in self.options save_last_frame = "save_last_frame" in self.options assert not (save_as_gif and save_last_frame) ref_content = (self.options.get("ref_modules", []) + self.options.get("ref_classes", []) + self.options.get("ref_functions", []) + self.options.get("ref_methods", [])) if ref_content: ref_block = "References: " + " ".join(ref_content) else: ref_block = "" if "quality" in self.options: quality = f'{self.options["quality"]}_quality' else: quality = "example_quality" frame_rate = QUALITIES[quality]["frame_rate"] pixel_height = QUALITIES[quality]["pixel_height"] pixel_width = QUALITIES[quality]["pixel_width"] qualitydir = f"{pixel_height}p{frame_rate}" state_machine = self.state_machine document = state_machine.document source_file_name = document.attributes["source"] source_rel_name = relpath(source_file_name, setup.confdir) source_rel_dir = os.path.dirname(source_rel_name) while source_rel_dir.startswith(os.path.sep): source_rel_dir = source_rel_dir[1:] dest_dir = os.path.abspath( os.path.join(setup.app.builder.outdir, source_rel_dir)) if not os.path.exists(dest_dir): os.makedirs(dest_dir) source_block = [ ".. code-block:: python", "", " from manim import *\n", *[" " + line for line in self.content], ] source_block = "\n".join(source_block) config.media_dir = Path(setup.confdir) / "media" config.images_dir = "{media_dir}/images" config.video_dir = "{media_dir}/videos/{quality}" output_file = f"{clsname}-{classnamedict[clsname]}" config.assets_dir = Path("_static") config_code = [ f'config["frame_rate"] = {frame_rate}', f'config["pixel_height"] = {pixel_height}', f'config["pixel_width"] = {pixel_width}', f'config["save_last_frame"] = {save_last_frame}', f'config["save_as_gif"] = {save_as_gif}', f'config["write_to_movie"] = {not save_last_frame}', f'config["output_file"] = r"{output_file}"', ] user_code = self.content if user_code[0].startswith( ">>> "): # check whether block comes from doctest user_code = [ line[4:] for line in user_code if line.startswith((">>> ", "... ")) ] code = [ "from manim import *", *config_code, *user_code, f"{clsname}().render()", ] exec("\n".join(code), globals()) # copy video file to output directory if not (save_as_gif or save_last_frame): filename = f"{output_file}.mp4" filesrc = config.get_dir("video_dir") / filename elif save_as_gif: filename = f"{output_file}.gif" filesrc = config.get_dir("video_dir") / filename elif save_last_frame: filename = f"{output_file}.png" filesrc = config.get_dir("images_dir") / filename else: raise ValueError("Invalid combination of render flags received.") rendered_template = jinja2.Template(TEMPLATE).render( clsname=clsname, clsname_lowercase=clsname.lower(), hide_source=hide_source, filename=filename, filesrc_rel=os.path.relpath(filesrc, setup.confdir), output_file=output_file, save_last_frame=save_last_frame, save_as_gif=save_as_gif, source_block=source_block, ref_block=ref_block, ) state_machine.insert_input(rendered_template.split("\n"), source=document.attributes["source"]) return []
def run(self): from manim import config global classnamedict clsname = self.arguments[0] if clsname not in classnamedict: classnamedict[clsname] = 1 else: classnamedict[clsname] += 1 hide_source = "hide_source" in self.options save_as_gif = "save_as_gif" in self.options save_last_frame = "save_last_frame" in self.options assert not (save_as_gif and save_last_frame) if "ref_classes" in self.options or "ref_functions" in self.options: ref_classes = self.options.get("ref_classes", []) ref_functions = self.options.get("ref_functions", []) ref_content = ref_classes + ref_functions ref_block = f""" .. admonition:: Example References :class: example-reference {' '.join(ref_content)}""" else: ref_block = "" frame_rate = 30 pixel_height = 480 pixel_width = 854 if "quality" in self.options: quality = self.options["quality"] if quality == "low": pixel_height = 480 pixel_width = 854 frame_rate = 15 elif quality == "medium": pixel_height = 720 pixel_width = 1280 frame_rate = 30 elif quality == "high": pixel_height = 1440 pixel_width = 2560 frame_rate = 60 elif quality == "fourk": pixel_height = 2160 pixel_width = 3840 frame_rate = 60 qualitydir = f"{pixel_height}p{frame_rate}" state_machine = self.state_machine document = state_machine.document source_file_name = document.attributes["source"] source_rel_name = relpath(source_file_name, setup.confdir) source_rel_dir = os.path.dirname(source_rel_name) while source_rel_dir.startswith(os.path.sep): source_rel_dir = source_rel_dir[1:] dest_dir = os.path.abspath( os.path.join(setup.app.builder.outdir, source_rel_dir)) if not os.path.exists(dest_dir): os.makedirs(dest_dir) source_block = [ ".. code-block:: python", "", *[" " + line for line in self.content], ] source_block = "\n".join(source_block) config.media_dir = Path(setup.confdir) / "media" config.images_dir = "{media_dir}/images" config.video_dir = "{media_dir}/videos/{quality}" output_file = f"{clsname}-{classnamedict[clsname]}" config.assets_dir = Path("_static") config_code = [ f'config["frame_rate"] = {frame_rate}', f'config["pixel_height"] = {pixel_height}', f'config["pixel_width"] = {pixel_width}', f'config["save_last_frame"] = {save_last_frame}', f'config["save_as_gif"] = {save_as_gif}', f'config["output_file"] = r"{output_file}"', ] user_code = self.content if user_code[0].startswith( ">>> "): # check whether block comes from doctest user_code = [ line[4:] for line in user_code if line.startswith((">>> ", "... ")) ] code = [ "from manim import *", *config_code, *user_code, f"{clsname}().render()", ] exec("\n".join(code), globals()) # copy video file to output directory if not (save_as_gif or save_last_frame): filename = f"{output_file}.mp4" filesrc = config.get_dir("video_dir") / filename destfile = os.path.join(dest_dir, filename) shutil.copyfile(filesrc, destfile) elif save_as_gif: filename = f"{output_file}.gif" filesrc = config.get_dir("video_dir") / filename elif save_last_frame: filename = f"{output_file}.png" filesrc = config.get_dir("images_dir") / filename else: raise ValueError("Invalid combination of render flags received.") rendered_template = jinja2.Template(TEMPLATE).render( clsname=clsname, clsname_lowercase=clsname.lower(), hide_source=hide_source, filesrc_rel=os.path.relpath(filesrc, setup.confdir), output_file=output_file, save_last_frame=save_last_frame, save_as_gif=save_as_gif, source_block=source_block, ref_block=ref_block, ) state_machine.insert_input(rendered_template.split("\n"), source=document.attributes["source"]) return []