Source code for docdown.note_blocks

# -*- coding: utf-8 -*-

"""
note_blocks
----------------------------------

docdown.note_blocks Markdown extension module
"""

from __future__ import absolute_import, unicode_literals, print_function

from markdown.extensions import Extension
from markdown.preprocessors import Preprocessor
import re

from .docdown import TemplateRenderMixin


DEFAULT_ADAPTER = 'docdown.template_adapters.StringFormatAdapter'


[docs]class NoteBlockPreprocessor(TemplateRenderMixin, Preprocessor): RE = re.compile(r''' (?P<fence>^(?:!{3,}))\W(?P<type>\w+)\W*\n (?P<content>.*?)(?<=\n) (?P=fence)[ ]*$''', re.MULTILINE | re.DOTALL | re.VERBOSE) def __init__(self, prefix='', postfix='', tags=None, template_adapter=DEFAULT_ADAPTER, default_tag='', **kwargs): if tags is None: tags = {} self.prefix = prefix self.postfix = postfix self.tags = tags self.default_tag = default_tag super(NoteBlockPreprocessor, self).__init__(template_adapter=template_adapter, **kwargs)
[docs] def run(self, lines): text = "\n".join(lines) renderer = self.get_template_adapter() while 1: m = self.RE.search(text) if m: fence_type = m.group('type') css_class = fence_type.lower() content = m.group('content') try: context = self.tags[css_class] except KeyError: css_class = self.default_tag context = self.tags.get(css_class, {}) context.update({'tag': css_class}) prefix_template = context.get('prefix', self.prefix) postfix_template = context.get('postfix', self.postfix) prefix = renderer.render(template=prefix_template, context=context) postfix = renderer.render(template=postfix_template, context=context) start_tag = self.markdown.htmlStash.store(prefix, safe=True) end_tag = self.markdown.htmlStash.store(postfix, safe=True) text = '%s\n%s\n\n%s\n%s\n%s' % (text[:m.start()], start_tag, content, end_tag, text[m.end():]) else: break return text.split("\n")
[docs]class NoteExtension(Extension): """ Renders a block of HTML with a title, svg image, and content to be displayed as a note. The svg image is rendered using. Configuration Example: { 'template_adapter': 'docdown.template_adapters.StringFormatAdapter', 'prefix': ('<div class="{ tag }">' ' <div class="icon">' ' {% svg "{ svg }" %}' ' <img class="icon--pdf" src="{% static "{ svg_path }" %}"' ' </div>' ' <h5>{ title }</h5>' '</div>'), 'postfix': '</div>', 'tags': { 'tag_name': { 'svg': 'standard/icon-must', 'svg_path': 'svg/standard/icon-must.svg', 'title': 'Must' }, } } """ def __init__(self, **kwargs): self.config = { 'prefix': ['<div>', 'Opening tag(s) which wrap the content'], 'postfix': ['</div>', 'Closing tag(s) which wrap the content'], 'tags': [{}, 'Template context passed into template rendering'], 'template_adapter': ['docdown.template_adapters.StringFormatAdapter', ('Adapter for rendering prefix and postfix templates' ' using your template language of choice.')], 'default_tag': ['', 'Default tag to use if the specified tag is not in the tags dict'], } super(NoteExtension, self).__init__(**kwargs)
[docs] def extendMarkdown(self, md, md_globals): """ Add NoteBlockPreprocessor to the Markdown instance. """ md.registerExtension(self) prefix = self.getConfig('prefix') postfix = self.getConfig('postfix') tags = self.getConfig('tags') template_adapter = self.getConfig('template_adapter') default_tag = self.getConfig('default_tag') md.preprocessors.add('note_blocks', NoteBlockPreprocessor(prefix=prefix, postfix=postfix, tags=tags, template_adapter=template_adapter, default_tag=default_tag, markdown_instance=md), ">normalize_whitespace")
[docs]def makeExtension(*args, **kwargs): return NoteExtension(*args, **kwargs)
# TODO: put this in a different module