129 lines
3.8 KiB
Python
129 lines
3.8 KiB
Python
#!/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 "<h1>").
|
|
"""
|
|
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 <body> 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()))
|