#!/usr/bin/python3 import subprocess import sys from docutils import nodes, core from docutils.parsers.rst import directives, Directive class Chroma(Directive): """Source code syntax highlighting.""" required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True option_spec = {} has_content = True def run(self): self.assert_has_content() data = "\n".join(self.content) try: parsed = subprocess.run( ["{{ gitea.lookup.mod_rst.chroma_bin }}", "--html", "--html-only", "-l", self.arguments[0]], text=True, input=data, capture_output=True, check=True, ) except subprocess.CalledProcessError: parsed = subprocess.run( ["{{ gitea.lookup.mod_rst.chroma_bin }}", "--html", "--html-only"], text=True, input=data, capture_output=True, check=True, ) return [nodes.raw("", parsed.stdout, format="html")] def html_parts( input_string, source_path=None, destination_path=None, input_encoding="utf8", doctitle=True, initial_header_level=1, ): """ Given an input string, returns a dictionary of HTML document parts. Dictionary keys are the names of parts, and values are Unicode strings; encoding is up to the client. Parameters: - `input_string`: A multi-line text string; required. - `source_path`: Path to the source file or object. Optional, but useful for diagnostic output (system messages). - `destination_path`: Path to the file or object which will receive the output; optional. Used for determining relative paths (stylesheets, source links, etc.). - `input_encoding`: The encoding of `input_string`. If it is an encoded 8-bit string, provide the correct encoding. If it is a Unicode string, use "unicode", the default. - `doctitle`: Disable the promotion of a lone top-level section title to document title (and subsequent section title to document subtitle promotion); enabled by default. - `initial_header_level`: The initial level for header elements (e.g. 1 for "

"). """ overrides = { "input_encoding": input_encoding, "doctitle_xform": doctitle, "initial_header_level": initial_header_level, "report_level": 4, } parts = core.publish_parts( source=input_string, source_path=source_path, destination_path=destination_path, writer_name="html", settings_overrides=overrides, ) return parts def html_body( input_string, source_path=None, destination_path=None, input_encoding="utf8", output_encoding="unicode", doctitle=True, initial_header_level=1, ): """ Given an input string, returns an HTML fragment as a string. The return value is the contents of the element. Parameters (see `html_parts()` for the remainder): - `output_encoding`: The desired encoding of the output. If a Unicode string is desired, use the default value of "unicode" . """ parts = html_parts( input_string=input_string, source_path=source_path, destination_path=destination_path, input_encoding=input_encoding, doctitle=doctitle, initial_header_level=initial_header_level, ) fragment = parts["html_body"] if output_encoding != "unicode": fragment = fragment.encode(output_encoding) return fragment if __name__ == "__main__": directives.register_directive("code-block", Chroma) with open(sys.argv[1], "r") as f: source = "".join(f.readlines()) print(html_body(source.encode()))