123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- """
- Markdown Extension for Liquid-style Tags
- ----------------------------------------
- A markdown extension to allow user-defined tags of the form::
- {% tag arg1 arg2 ... argn %}
- Where "tag" is associated with some user-defined extension.
- These result in a preprocess step within markdown that produces
- either markdown or html.
- """
- import warnings
- import markdown
- import itertools
- import re
- import os
- from functools import wraps
- # Define some regular expressions
- LIQUID_TAG = re.compile(r'\{%.*?%\}', re.MULTILINE | re.DOTALL)
- EXTRACT_TAG = re.compile(r'(?:\s*)(\S+)(?:\s*)')
- LT_CONFIG = { 'CODE_DIR': 'code',
- 'NOTEBOOK_DIR': 'notebooks',
- 'FLICKR_API_KEY': 'flickr',
- 'GIPHY_API_KEY': 'giphy'
- }
- LT_HELP = { 'CODE_DIR' : 'Code directory for include_code subplugin',
- 'NOTEBOOK_DIR' : 'Notebook directory for notebook subplugin',
- 'FLICKR_API_KEY': 'Flickr key for accessing the API',
- 'GIPHY_API_KEY': 'Giphy key for accessing the API'
- }
- class _LiquidTagsPreprocessor(markdown.preprocessors.Preprocessor):
- _tags = {}
- def __init__(self, configs):
- self.configs = configs
- def run(self, lines):
- page = '\n'.join(lines)
- liquid_tags = LIQUID_TAG.findall(page)
- for i, markup in enumerate(liquid_tags):
- # remove {% %}
- markup = markup[2:-2]
- tag = EXTRACT_TAG.match(markup).groups()[0]
- markup = EXTRACT_TAG.sub('', markup, 1)
- if tag in self._tags:
- liquid_tags[i] = self._tags[tag](self, tag, markup.strip())
- # add an empty string to liquid_tags so that chaining works
- liquid_tags.append('')
- # reconstruct string
- page = ''.join(itertools.chain(*zip(LIQUID_TAG.split(page),
- liquid_tags)))
- # resplit the lines
- return page.split("\n")
- class LiquidTags(markdown.Extension):
- """Wrapper for MDPreprocessor"""
- def __init__(self, config):
- try:
- # Needed for markdown versions >= 2.5
- for key,value in LT_CONFIG.items():
- self.config[key] = [value,LT_HELP[key]]
- super(LiquidTags,self).__init__(**config)
- except AttributeError:
- # Markdown versions < 2.5
- for key,value in LT_CONFIG.items():
- config[key] = [config[key],LT_HELP[key]]
- super(LiquidTags,self).__init__(config)
- @classmethod
- def register(cls, tag):
- """Decorator to register a new include tag"""
- def dec(func):
- if tag in _LiquidTagsPreprocessor._tags:
- warnings.warn("Enhanced Markdown: overriding tag '%s'" % tag)
- _LiquidTagsPreprocessor._tags[tag] = func
- return func
- return dec
- def extendMarkdown(self, md, md_globals):
- self.htmlStash = md.htmlStash
- md.registerExtension(self)
- # for the include_code preprocessor, we need to re-run the
- # fenced code block preprocessor after substituting the code.
- # Because the fenced code processor is run before, {% %} tags
- # within equations will not be parsed as an include.
- md.preprocessors.add('mdincludes',
- _LiquidTagsPreprocessor(self), ">html_block")
- def makeExtension(configs=None):
- """Wrapper for a MarkDown extension"""
- return LiquidTags(configs=configs)
|