Skip to content

Commit

Permalink
Added yaml implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
waylan committed Mar 9, 2015
1 parent 0627342 commit fe16514
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 5 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ point you can forward the document on to your lightweight markup processor of
choice. You might even want to use some the meta-data to configure the behavior
of your lightweight markup processor.

YAML Meta-Data (not yet implemented)
YAML Meta-Data
--------------

Given a document that contains YAML style meta-data, simply pass it to
Expand All @@ -32,9 +32,13 @@ doc, data = get_data(doc)

The `docdata.yamldata.get_data` function will return a tuple which contains the
document with the meta-data removed and the meta-data as returned by the YAML
parser. As YAML provides for and recognizes various types out-of-the-box,
no additional features need to be provided. The document can now be passed to
your lightweight markup processor of choice.
parser. Note that if the YAML root data structure parsed by YAML is not a
dictionary, it is assumed that no data is defined, the YAML block is not
removed from the document, and an empty dict is returned as data.

As YAML provides for and recognizes various types out-of-the-box, no additional
features need to be provided. The document can now be passed to your lightweight
markup processor of choice.

MultiMarkdown Meta-Data
-----------------------
Expand Down
21 changes: 20 additions & 1 deletion docdata/yamldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@
"""


import re
import yaml
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader


BLOCK_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n', re.UNICODE|re.DOTALL)


def get_data(doc):
Expand All @@ -15,4 +23,15 @@ def get_data(doc):
Returns a tuple of document and data.
"""
pass # TODO: implement this
data = {}
m = BLOCK_RE.match(doc)
if m:
try:
data = yaml.load(m.group(1), SafeLoader)
if isinstance(data, dict):
doc = doc[m.end():].lstrip('\n')
else:
data = {}
except:
pass
return doc, data
90 changes: 90 additions & 0 deletions tests/test_yamldata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import unittest
import datetime
from docdata import yamldata

class TestYamlData(unittest.TestCase):
def test_yaml_data(self):
doc = '''---
Author: John Doe
Date: 2015-05-08 14:15:16
Integer: 0x2A
---
Document content.
'''
self.assertEqual(
yamldata.get_data(doc),
(
'Document content.\n',
{
'Author': 'John Doe',
'Date': datetime.datetime(2015, 5, 8, 14, 15, 16),
'Integer': 42
}
)
)

def test_end_deliminator(self):
doc = '''---
Author: John Doe
Date: 2015-05-08
Integer: 42
...
Document content.
'''
self.assertEqual(
yamldata.get_data(doc),
(
'Document content.\n',
{
'Author': 'John Doe',
'Date': datetime.date(2015, 5, 8),
'Integer': 42
}
)
)

def test_bad_deliminator(self):
doc = '''---
Author: John Doe
Date: 2015-05-08
Integer: 42
-.-
Document content.
'''
self.assertEqual(
yamldata.get_data(doc),
(doc, {})
)

def test_blank_first_line(self):
doc = '''
---
Author: John Doe
Date: 2015-05-08
Integer: 42
---
Document content.
'''
self.assertEqual(
yamldata.get_data(doc),
(doc, {})
)

def test_bad_yaml(self):
doc = '''---
foo
...
Document content.
'''
self.assertEqual(
yamldata.get_data(doc),
(doc, {})
)

def test_no_yaml(self):
doc = 'Document content.'
self.assertEqual(
yamldata.get_data(doc),
(doc, {})
)

0 comments on commit fe16514

Please sign in to comment.