def get_graph_hash(node: inheritance_diagram) -> str: encoded = (node['content'] + str(node['parts'])).encode() return md5(encoded).hexdigest()[-10:]
def run(self): # pylint: disable=too-many-locals document = self.state_machine.document env = self.state_machine.document.settings.env config = self.state_machine.document.settings.env.config # set options to default values if not specified self.options.setdefault("show-code", config.gmtplot_show_code) self.options.setdefault("align", config.gmtplot_figure_align) # Get the name of the rst source file we are currently processing rst_file = Path(document["source"]) # current working directory of the rst source file cwd = rst_file.parent if self.arguments: # load codes from a file # Guess language from suffix of the script if "language" not in self.options: self.options["language"] = guess_language(self.arguments[0]) # Get absolute path of the script if config.gmtplot_basedir: # relative to gmtplot_basedir code_file = Path(env.app.srcdir, config.gmtplot_basedir, self.arguments[0]) elif self.arguments[0].startswith( "/"): # relative to source directory code_file = Path(env.app.srcdir, self.arguments[0][1:]) else: # relative to current rst file's path code_file = Path(cwd, self.arguments[0]) code_basedir = code_file.absolute().parent code = code_file.read_text(encoding="utf-8") # If there is content, it will be passed as a caption. caption = "\n".join(self.content) else: # inline codes if "language" not in self.options: self.options["language"] = config.highlight_language code_basedir = cwd code = textwrap.dedent("\n".join(map(str, self.content))) caption = self.options[ "caption"] if "caption" in self.options else "" # use the md5sum value of the code as the basename of script and image files output_base = md5(code.encode()).hexdigest() # determine unique code filename under current working directory suffix = get_suffix_from_language(self.options["language"]) code_file = Path(cwd, f"{output_base}.{suffix}") code_opts = "" if self.options["show-code"]: code_opts = [] for key, val in self.options.items(): if key == "linenos": code_opts.append(f":{key}:") elif key in self.options_code: code_opts.append(f":{key}: {val}") image_opts = [ f":{key}: {val}" for key, val in self.options.items() if key in self.options_figure ] # builddir: where to place output files (temporarily) builddir = Path(env.app.doctreedir).parent / "gmtplot_directive" # determine how to link to files in builddir from the RST file # use os.path.relpath rather than relative_to! builddir_link = Path("/", os.path.relpath(str(builddir), env.app.srcdir)) # copy script to builddir builddir.mkdir(parents=True, exist_ok=True) Path(builddir, code_file.name).write_text(code, encoding="utf-8") # make figures image = render_figure(code, code_basedir, self.options["language"], builddir, output_base, config) gmtplot_block = (jinja2.Template(TEMPLATE).render( label="gmtplot-" + output_base, show_code=self.options["show-code"], code=builddir_link / code_file.name, code_opts=code_opts, image=builddir_link / image, image_opts=image_opts, caption=caption, ).split("\n")) gmtplot_block.extend("\n") self.state_machine.insert_input(gmtplot_block, source=str(rst_file)) return []