From 119efb80e421faa29b0ffa3a3e7f32e6a284c889 Mon Sep 17 00:00:00 2001 From: Gareth Coles Date: Tue, 10 Apr 2018 13:26:46 +0100 Subject: [Wiki] Add url_for text role --- pysite/rst/__init__.py | 3 ++- pysite/rst/roles.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/pysite/rst/__init__.py b/pysite/rst/__init__.py index 9b2ef23c..815ad058 100644 --- a/pysite/rst/__init__.py +++ b/pysite/rst/__init__.py @@ -2,7 +2,7 @@ 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): @@ -12,3 +12,4 @@ def render(rst: str): 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..09c4d373 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 /", 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 /", line=lineno) + prb = inliner.problematic(text, rawtext, msg) + + return [prb], [msg] + else: + try: + url = url_for(parts[0]) + name = parts[1] + + html = f"""{name}""" + + 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] -- cgit v1.2.3