Skip to content

Commit

Permalink
Removed yaml option from meta-data extension.
Browse files Browse the repository at this point in the history
The option was buggy. Rather than try to fix it, it is being removed.
This feeture should exist as a seperate extension. Fixes #390.
  • Loading branch information
waylan committed Mar 9, 2015
1 parent f54cd86 commit 4f9d4ff
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 74 deletions.
24 changes: 5 additions & 19 deletions docs/extensions/meta_data.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ many lines as desired.
The first blank line ends all meta-data for the document. Therefore, the first
line of a document must not be blank.

Alternatively, if the first line in the document is `---`, a YAML document
separator, then the meta-data is searched for between it and the next `---`
(or `...`) line. Even though YAML deliminators are supported, meta-data is
not parsed as YAML unless the `yaml` option is set (see below).
Alternatively, You may use YAML style deliminators to mark the start and/or end
of your meta-data. When doing so, the first line of your document must be `---`.
The meta-data ends at the first blank line or the first line containing an end
deliminator (either `---` or `...`), whichever comes first. Even though YAML
deliminators are supported, meta-data is not parsed as YAML.

All meta-data is stripped from the document prior to any further processing
by Markdown.
Expand All @@ -61,16 +62,6 @@ Usage
See [Extensions](index.html) for general extension usage, specify `markdown.extensions.meta`
as the name of the extension.

The following options are provided to configure the output:

* **`yaml`**: Support meta-data specified in YAML format.

Default: `False`

If `yaml` is set to `True`, the lines between `---` separators are parsed
as a full YAML object. PyYAML is required for this, and a warning is
issued if PyYAML (or equivalent) is not available.

Accessing the Meta-Data
-----------------------

Expand Down Expand Up @@ -100,11 +91,6 @@ line breaks if desired. Or the items could be joined where appropriate. No
assumptions are made regarding the data. It is simply passed as found to the
`Meta` attribute.

Note, if `yaml` option is set, the resulting `Meta` attribute is the object as
returned by `yaml.load()` and may deviate significantly from the above
description (e.g. may be a list of dictionaries, with value objects other than
strings, ...).

Perhaps the meta-data could be passed into a template system, or used by
various Markdown extensions. The possibilities are left to the imagination of
the developer.
Expand Down
6 changes: 5 additions & 1 deletion docs/release-2.6.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,15 @@ meta-data. By default, the YAML deliminators are recognized, however, the
actual data is parsed as previously. This follows the syntax of
[MultiMarkdown], which inspired this extension.

Alternatively, if the `yaml` option is set, then the data is parsed as YAML.
<del>Alternatively, if the `yaml` option is set, then the data is parsed as YAML.</del>
<ins>As the `yaml` option was buggy, it was removed in 2.6.1. It is suggested that a third
party extension be used if you want true YAML support. See [Issue #390][#390] for a full
explanation.</ins>

[MultiMarkdown]: http://fletcherpenney.net/MultiMarkdown_Syntax_Guide#metadata
[Meta-Data]: extensions/meta_data.html
[YAML]: http://yaml.org/
[#390]: https://github.com/waylan/Python-Markdown/issues/390

### Table of Contents Extension Refactored

Expand Down
40 changes: 6 additions & 34 deletions markdown/extensions/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,66 +22,40 @@
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.*)?')
BEGIN_RE = re.compile(r'^-{3}(\s.*)?')
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, self.getConfigs()),
MetaPreprocessor(md),
">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
if lines and BEGIN_RE.match(lines[0]):
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)
m1 = META_RE.match(line)
if line.strip() == '' or have_yaml and YAML_END_RE.match(line):
if line.strip() == '' or 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:
if m1:
key = m1.group('key').lower().strip()
value = m1.group('value').strip()
try:
Expand All @@ -96,8 +70,6 @@ def run(self, lines):
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

Expand Down
20 changes: 0 additions & 20 deletions tests/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"""

from __future__ import unicode_literals
import datetime
import unittest
import markdown

Expand Down Expand Up @@ -510,25 +509,6 @@ def testMetaDataWithoutNewline(self):
self.assertEqual(self.md.convert(text), '')
self.assertEqual(self.md.Meta, {'title': ['No newline']})

def testYamlObjectMetaData(self):
""" Test metadata specified as a complex YAML object. """
md = markdown.Markdown(extensions=[markdown.extensions.meta.MetaExtension(yaml=True)])
text = '''---
Author: John Doe
Date: 2014-11-29 14:15:16
Integer: 0x16
---
Some content.'''
self.assertEqual(md.convert(text), '<p>Some content.</p>')
self.assertEqual(
md.Meta, {
'Author': 'John Doe',
'Date': datetime.datetime(2014, 11, 29, 14, 15, 16),
'Integer': 22
}
)


class TestWikiLinks(unittest.TestCase):
""" Test Wikilinks Extension. """
Expand Down

0 comments on commit 4f9d4ff

Please sign in to comment.