Home Download Direct linkSettings
Aa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
Copy
import flask
from markupsafe import Markup

from pygments import highlight
from pygments.lexers import guess_lexer_for_filename, get_lexer_by_name, guess_lexer
from pygments.lexers.templates import HtmlDjangoLexer
from pygments.lexers.special import TextLexer
from pygments.util import ClassNotFound

from pymdownx import highlight as hlt

from pygments.formatters import HtmlFormatter

from src import constants as const

FORMATTER = HtmlFormatter(nowrap=True)


class TemplateHighlight(hlt.Highlight):

    @staticmethod
    def get_linenos(code: str):
        """
        Generate line numbers for code block.
        """
        return Markup("\n".join(map(str, range(1, code.count("\n") + 2))))

    @staticmethod
    def _get_lexer(code: str, language: str | None, filename: str):
        """
        Choose the best suitable lexer depending on present information about code.
        """
        if language:
            return get_lexer_by_name(language)

        if filename.endswith((".html", ".j2")):
            return HtmlDjangoLexer()

        if filename:
            return guess_lexer_for_filename(filename, code)

        return guess_lexer(code)

    @classmethod
    def highlight_code(cls,
                       code: str,
                       language: str | None = None,
                       filename: str | None = None):
        """
        Highlight block of code.
        This function is used in `source/code.html` template.
        """
        try:
            lexer = cls._get_lexer(code, language, filename or "")
        except ClassNotFound:
            lexer = TextLexer()

        return Markup(
            highlight(Markup(code.rstrip()).unescape(), lexer, FORMATTER))

    def highlight(self, src, language, *_args, **_kwargs):
        return flask.render_template(
            "source/code.html",
            source=src,
            language=language,
        )


class TemplateHighlightExtension(hlt.HighlightExtension):

    def get_pymdownx_highlighter(self):
        return TemplateHighlight


def create_missing_code_style_files():
    for style in const.PYGMENTS_BUILTIN_STYLES:
        style_file = (const.CODE_STYLES_DIR / style).with_suffix(".css")
        if not style_file.exists():
            formatter = HtmlFormatter(style=style)
            bg_defs = formatter.get_background_style_defs(".highlight")
            token_defs = formatter.get_token_style_defs(".highlight")
            with style_file.open("w") as file:
                file.write("\n".join(bg_defs + token_defs))