|
- from jinja2 import contextfilter, environmentfilter
- from jinja2.ext import Extension
-
- from io import StringIO
- from lxml import etree
-
- @contextfilter
- def rellinktoabs(context, value):
- env = context.environment
-
- # get the path for this context
- rel_path = context['resource'].relative_path
- content_url = env.globals['content_url'](context, rel_path)
-
- html = etree.HTML(value)
-
- # get all the fragment urls
- r = html.xpath("//a[@href[starts-with(.,'#')]]")
-
- for i in r:
- # prefix them w/ the content_url
- i.attrib['href'] = content_url + i.attrib['href']
-
- return etree.tostring(html, encoding='unicode', method='html')
-
- # mostly copied from hyde.ext.templates.jinja.py Markdown
- # and using docs from:
- # https://jinja.palletsprojects.com/en/2.10.x/extensions/#example-extension
- # to get the filter installed
-
- class RelLinktoAbs(Extension):
- """
- A wrapper around the rellinktoabs filter for syntactic sugar.
- """
- tags = { 'rellinktoabs' }
-
- def __init__(self, env):
- super(RelLinktoAbs, self).__init__(env)
-
- env.filters['rellinktoabs'] = rellinktoabs
-
- def parse(self, parser):
- """
- Parses the statements and defers to the callback
- for rellinktoabs processing.
- """
-
- lineno = next(parser.stream).lineno
- body = parser.parse_statements(['name:endrellinktoabs'], drop_needle=True)
-
- return nodes.CallBlock(
- self.call_method('_render_rellinktoabs'),
- [], [], body).set_lineno(lineno)
-
- def _render_rellinktoabs(self, caller=None):
- """
- Calls the rellinktoabs filter to transform the output.
- """
- if not caller:
- return ''
- output = caller().strip()
- return rellinktoabs(self.environment, output)
|