Exemplo n.º 1
0
def get_graph_hash(node: inheritance_diagram) -> str:
    encoded = (node['content'] + str(node['parts'])).encode()
    return md5(encoded).hexdigest()[-10:]
Exemplo n.º 2
0
    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 []