diff options
Diffstat (limited to 'pysite')
| -rw-r--r-- | pysite/rst/__init__.py | 5 | ||||
| -rw-r--r-- | pysite/rst/roles.py | 37 | 
2 files changed, 40 insertions, 2 deletions
diff --git a/pysite/rst/__init__.py b/pysite/rst/__init__.py index 0e5f6ffe..815ad058 100644 --- a/pysite/rst/__init__.py +++ b/pysite/rst/__init__.py @@ -2,13 +2,14 @@  from docutils.core import publish_parts  from docutils.parsers.rst.roles import register_canonical_role -from pysite.rst.roles import icon_role +from pysite.rst.roles import icon_role, url_for_role  def render(rst: str):      return publish_parts( -        source=rst, writer_name="html5", settings_overrides={"halt_level": 2} +        source=rst, writer_name="html5", settings_overrides={"halt_level": 2, "syntax_highlight": "short"}      )["html_body"]  register_canonical_role("icon", icon_role) +register_canonical_role("url_for", url_for_role) diff --git a/pysite/rst/roles.py b/pysite/rst/roles.py index bff00533..414832df 100644 --- a/pysite/rst/roles.py +++ b/pysite/rst/roles.py @@ -2,6 +2,7 @@  from docutils import nodes  from docutils.parsers.rst.roles import set_classes  from docutils.parsers.rst.states import Inliner +from flask import url_for  from jinja2 import escape @@ -44,3 +45,39 @@ def icon_role(_role: str, rawtext: str, text: str, lineno: int, inliner: Inliner          node = nodes.raw(html, html, format="html", **options)          return [node], [] + + +def url_for_role(_role: str, rawtext: str, text: str, lineno: int, inliner: Inliner, +                 options: dict = None, _content: dict = None): +    if options is None: +        options = {} + +    set_classes(options) + +    if "/" in text: +        parts = [escape(x) for x in text.split("/")] +    else: +        msg = inliner.reporter.error("URL specification must be in the form <page.name>/<text>", line=lineno) +        prb = inliner.problematic(text, rawtext, msg) + +        return [prb], [msg] + +    if len(parts) != 2: +        msg = inliner.reporter.error("URL specification must be in the form <page.name>/<text>", line=lineno) +        prb = inliner.problematic(text, rawtext, msg) + +        return [prb], [msg] +    else: +        try: +            url = url_for(parts[0]) +            name = parts[1] + +            html = f"""<a href="{url}">{name}</a>""" + +            node = nodes.raw(html, html, format="html", **options) +            return [node], [] +        except Exception as e: +            msg = inliner.reporter.error(str(e), line=lineno) +            prb = inliner.problematic(text, rawtext, msg) + +            return [prb], [msg]  |