#!python3 import manimlib if __name__ == "__main__": manimlib.main()
def manim(self, line, cell): # execute the code - won't generate any video, however it will introduce # the variables into the notebook's namespace (enabling autocompletion etc); # this also allows users to get feedback on some code errors early on get_ipython().ex(cell) user_args = line.split(' ') # path of the output video path = None settings = self.defaults.copy() # disable the switches as indicated by the user for key, arg in self.magic_off_switches.items(): if '--' + key in user_args: user_args.remove('--' + key) settings[arg] = False resolution_index = (user_args.index('--resolution') if '--resolution' in user_args else None) if resolution_index is not None: # the resolution is passed as "height,width" try: h, w = user_args[resolution_index + 1].split(',') settings['height'] = h settings['width'] = w except (IndexError, KeyError): warn( 'Unable to retrieve dimensions from your resolution setting, falling back to the defaults' ) remote_index = ( user_args.index('-b') if '-b' in user_args else user_args.index('--base64') if '--base64' in user_args else None) if remote_index is not None: settings['remote'] = True if '-b' in user_args: user_args.remove('-b') if '--base64' in user_args: user_args.remove('--base64') silent = settings['silent'] def catch_path_and_forward(lines): nonlocal path for line in lines.split('\n'): if not silent: print(line, file=std_out) if line.startswith(self.path_line_start): path = line[len(self.path_line_start):].strip() # Using a workaround for Windows permissions issue as in this questions: # https://stackoverflow.com/q/15169101 f = NamedTemporaryFile('w', suffix='.py', delete=False) try: with ExitStack() as stack: enter = stack.enter_context if settings['export_variables']: # TODO test this with pytest pickle_path = enter(self.export_globals()) if pickle_path: unpickle_script = UNPICKLE_SCRIPT.format( pickle_path=pickle_path) cell = unpickle_script + cell f.write(cell) f.close() args = ['manim', f.name, *user_args] stdout = StringIOWithCallback(catch_path_and_forward) enter(patch.object(sys, 'argv', args)) enter(suppress(SystemExit)) enter(redirect_stdout(stdout)) if silent: stderr = StringIO() enter(redirect_stderr(stderr)) manimlib.main() finally: os.remove(f.name) if path: path = Path(path) assert path.exists() # To display a video in Jupyter, we need to have access to it # so it has to be within the working tree. The absolute paths # are usually outside of the accessible range. relative_path = path.relative_to(Path.cwd()) video_settings = { k: v for k, v in settings.items() if k in self.video_settings } # If in remote mode, we send with a data: url if settings['remote']: data = base64.b64encode(path.read_bytes()).decode() data_url = "data:video/mp4;base64," + data return video(data_url, **video_settings) # otherwise a relative path is fine else: return video(relative_path, **video_settings) else: just_show_help = '-h' in user_args or '--help' in user_args if not just_show_help: warn('Could not find path in the manim output') # If we were silent, some errors could have been silenced too. if silent: # Let's break the silence: print(stdout.getvalue()) print(stderr.getvalue(), file=sys.stderr)
def manim(self, line, cell): # execute the code - won't generate any video, however it will introduce # the variables into the notebook's namespace (enabling autocompletion etc); # this also allows users to get feedback on some code errors early on get_ipython().ex(cell) # path of the output video path = None settings, user_args = self.parse_arguments(line) silent = settings['silent'] def catch_path_and_forward(lines): nonlocal path for line in lines.split('\n'): if not silent: print(line, file=std_out) if line.startswith(self.path_line_start): path = line[len(self.path_line_start):].strip() # Using a workaround for Windows permissions issue as in this questions: # https://stackoverflow.com/q/15169101 f = NamedTemporaryFile('w', suffix='.py', delete=False) try: with ExitStack() as stack: enter = stack.enter_context if settings['export_variables']: pickle_path = enter(self.export_globals()) if pickle_path: unpickle_script = UNPICKLE_SCRIPT.format(pickle_path=pickle_path) cell = unpickle_script + cell try: cell = self.extract_imports() + '\n' + cell except Exception as e: warn('Assembling imports failed: ' + str(e)) f.write(cell) f.close() args = ['manim', f.name, *user_args] stdout = StringIOWithCallback(catch_path_and_forward) enter(patch.object(sys, 'argv', args)) enter(suppress(SystemExit)) enter(redirect_stdout(stdout)) if silent: stderr = StringIO() enter(redirect_stderr(stderr)) manimlib.main() finally: os.remove(f.name) if path: path = Path(path) assert path.exists() # To display a video in Jupyter, we need to have access to it # so it has to be within the working tree. The absolute paths # are usually outside of the accessible range. relative_path = path.relative_to(Path.cwd()) video_settings = { k: v for k, v in settings.items() if k in self.video_settings } display_method = gif if settings['is_gif'] else video file_type = 'image/gif' if settings['is_gif'] else 'video/mp4' if settings['remote']: data = base64.b64encode(path.read_bytes()).decode() to_display = 'data:' + file_type + ';base64,' + data else: to_display = relative_path return display_method(to_display, **video_settings) else: just_show_help = '-h' in user_args or '--help' in user_args if not just_show_help: warn('Could not find path in the manim output') # If we were silent, some errors could have been silenced too. if silent: # Let's break the silence: print(stdout.getvalue()) print(stderr.getvalue(), file=sys.stderr)
#!/usr/bin/env python import manimlib if __name__ == "__main__": manimlib.main() else: manimlib.stream_starter.start_livestream()