diff options
author | Kernc <kerncece@gmail.com> | 2014-11-25 00:13:39 +0100 |
---|---|---|
committer | Waylan Limberg <waylan.limberg@icloud.com> | 2014-11-30 22:14:57 -0500 |
commit | ef6eb032b2e08f866b900cbc4d130b18200f712e (patch) | |
tree | 5a3582cb9b348be9b5842779df44b98b1006a6f7 /markdown/extensions | |
parent | 1339e8b87f926745b781139df7a23798ce922197 (diff) | |
download | markdown-ef6eb032b2e08f866b900cbc4d130b18200f712e.tar.gz markdown-ef6eb032b2e08f866b900cbc4d130b18200f712e.tar.bz2 markdown-ef6eb032b2e08f866b900cbc4d130b18200f712e.zip |
Add YAML support to Meta extension
By default, this only supports YAML deliminators (`---`) and adds no
additional behavior. In other words, parsing is unchanged. However, with
the `yaml` option set, PyYAML will parse the metadata.
Thanks to @kernc for suggesting the idea and doing the work on this.
Diffstat (limited to 'markdown/extensions')
-rw-r--r-- | markdown/extensions/meta.py | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/markdown/extensions/meta.py b/markdown/extensions/meta.py index a733a8a..cf8074f 100644 --- a/markdown/extensions/meta.py +++ b/markdown/extensions/meta.py @@ -20,36 +20,68 @@ from __future__ import unicode_literals from . import Extension from ..preprocessors import Preprocessor import re +import logging + +try: # pragma: no cover + import yaml + try: + from yaml import CSafeLoader as SafeLoader + except ImportError: + from yaml import SafeLoader +except ImportError: + yaml = None + +log = logging.getLogger('MARKDOWN') # Global Vars META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)') META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)') +YAML_BEGIN_RE = re.compile(r'^-{3}(\s.*)?') +YAML_END_RE = re.compile(r'^(-{3}|\.{3})(\s.*)?') class MetaExtension (Extension): """ Meta-Data extension for Python-Markdown. """ + def __init__(self, *args, **kwargs): + self.config = { + 'yaml': [False, "Parse meta data specified as a " + "'---' delimited YAML front matter"], + } + super(MetaExtension, self).__init__(*args, **kwargs) def extendMarkdown(self, md, md_globals): """ Add MetaPreprocessor to Markdown instance. """ - - md.preprocessors.add( - "meta", MetaPreprocessor(md), ">normalize_whitespace" - ) + md.preprocessors.add("meta", + MetaPreprocessor(md, self.getConfigs()), + ">normalize_whitespace") class MetaPreprocessor(Preprocessor): """ Get Meta-Data. """ + def __init__(self, md, config): + self.config = config + super(MetaPreprocessor, self).__init__(md) + def run(self, lines): """ Parse Meta-Data and store in Markdown.Meta. """ meta = {} key = None + yaml_block = [] + have_yaml = False + if lines and YAML_BEGIN_RE.match(lines[0]): + have_yaml = True + lines.pop(0) + if self.config['yaml'] and not yaml: # pragma: no cover + log.warning('Document with YAML header, but PyYAML unavailable') while lines: line = lines.pop(0) - if line.strip() == '': - break # blank line - done m1 = META_RE.match(line) - if m1: + if line.strip() == '' or have_yaml and YAML_END_RE.match(line): + break # blank line or end of YAML header - done + elif have_yaml and self.config['yaml'] and yaml: + yaml_block.append(line) + elif m1: key = m1.group('key').lower().strip() value = m1.group('value').strip() try: @@ -64,6 +96,8 @@ class MetaPreprocessor(Preprocessor): else: lines.insert(0, line) break # no meta data - done + if yaml_block: + meta = yaml.load('\n'.join(yaml_block), SafeLoader) self.markdown.Meta = meta return lines |