aboutsummaryrefslogtreecommitdiffstats
path: root/markdown/extensions
diff options
context:
space:
mode:
authorKernc <kerncece@gmail.com>2014-11-25 00:13:39 +0100
committerWaylan Limberg <waylan.limberg@icloud.com>2014-11-30 22:14:57 -0500
commitef6eb032b2e08f866b900cbc4d130b18200f712e (patch)
tree5a3582cb9b348be9b5842779df44b98b1006a6f7 /markdown/extensions
parent1339e8b87f926745b781139df7a23798ce922197 (diff)
downloadmarkdown-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.py48
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