~homeworkprod/byceps

ref: 4237b3ec9496efe95dcce82bea3207ab9de4d520 byceps/byceps/services/text_markup/service.py -rw-r--r-- 2.0 KiB
4237b3ec — Jochen Kupperschmidt Move ticketing blueprint into `site` subpackage 1 year, 11 months ago
                                                                                
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
"""
byceps.services.text_markup.service
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2006-2020 Jochen Kupperschmidt
:License: Modified BSD, see LICENSE for details.
"""

from html import escape

from bbcode import Parser

try:
    from .smileys import get_smileys
except ModuleNotFoundError:
    def get_smileys():
        return []


try:
    from .smileys import replace_smileys as _replace_smileys
except ModuleNotFoundError:
    def _replace_smileys(text):
        return text


def _create_parser() -> Parser:
    """Create a customized BBcode parser."""
    parser = Parser(replace_cosmetic=False)

    _add_code_formatter(parser)
    _add_image_formatter(parser)
    _add_quote_formatter(parser)

    return parser


def _add_code_formatter(parser: Parser) -> None:
    """Replace code tags."""

    def render_code(name, value, options, parent, context):
        return f'<pre><code class="block">{value}</code></pre>'

    parser.add_formatter(
        'code', render_code, replace_cosmetic=False, replace_links=False
    )


def _add_image_formatter(parser: Parser) -> None:
    """Replace image tags."""

    def render_image(name, value, options, parent, context):
        return f'<img src="{value}">'

    parser.add_formatter(
        'img', render_image, replace_cosmetic=False, replace_links=False
    )


def _add_quote_formatter(parser: Parser) -> None:
    """Render quotes with optional author."""

    def render_quote(name, value, options, parent, context):
        intro = ''
        if 'author' in options:
            author = escape(options['author'])
            intro = (
                f'<p class="quote-intro"><cite>{author}</cite> schrieb:</p>\n'
            )
        return f'{intro}<blockquote>{value}</blockquote>'

    parser.add_formatter('quote', render_quote, strip=True)


_PARSER = _create_parser()


def render_html(value: str) -> str:
    """Render text as HTML, interpreting BBcode."""
    html = _PARSER.format(value)
    html = _replace_smileys(html)
    return html