1
#!usr/bin/python
2
3
"""
4
Meta Data Extension for Python-Markdown
5
=======================================
6
7
This extension adds Meta Data handling to markdown.
8
9
Basic Usage:
10
11
    >>> import markdown
12
    >>> text = '''Title: A Test Doc.
13
    ... Author: Waylan Limberg
14
    ...         John Doe
15
    ... Blank_Data:
16
    ...
17
    ... The body. This is paragraph one.
18
    ... '''
19
    >>> md = markdown.Markdown(['meta'])
20
    >>> md.convert(text)
21
    u'<p>The body. This is paragraph one.</p>'
22
    >>> md.Meta
23
    {u'blank_data': [u''], u'author': [u'Waylan Limberg', u'John Doe'], u'title': [u'A Test Doc.']}
24
25
Make sure text without Meta Data still works (markdown < 1.6b returns a <p>).
26
27
    >>> text = '    Some Code - not extra lines of meta data.'
28
    >>> md = markdown.Markdown(['meta'])
29
    >>> md.convert(text)
30
    u'<pre><code>Some Code - not extra lines of meta data.\\n</code></pre>'
31
    >>> md.Meta
32
    {}
33
34
Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
35
36
Project website: <http://www.freewisdom.org/project/python-markdown/Meta-Data>
37
Contact: markdown@freewisdom.org
38
39
License: BSD (see ../docs/LICENSE for details)
40
41
"""
42
import re
43
44
import markdown
45
46
# Global Vars
47
META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
48
META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
49
50
class MetaExtension (markdown.Extension):
51
    """ Meta-Data extension for Python-Markdown. """
52
53
    def extendMarkdown(self, md, md_globals):
54
        """ Add MetaPreprocessor to Markdown instance. """
55
56
        md.preprocessors.add("meta", MetaPreprocessor(md), "_begin")
57
58
59
class MetaPreprocessor(markdown.preprocessors.Preprocessor):
60
    """ Get Meta-Data. """
61
62
    def run(self, lines):
63
        """ Parse Meta-Data and store in Markdown.Meta. """
64
        meta = {}
65
        key = None
66
        while 1:
67
            line = lines.pop(0)
68
            if line.strip() == '':
69
                break # blank line - done
70
            m1 = META_RE.match(line)
71
            if m1:
72
                key = m1.group('key').lower().strip()
73
                value = m1.group('value').strip()
74
                try:
75
                    meta[key].append(value)
76
                except KeyError:
77
                    meta[key] = [value]
78
            else:
79
                m2 = META_MORE_RE.match(line)
80
                if m2 and key:
81
                    # Add another line to existing key
82
                    meta[key].append(m2.group('value').strip())
83
                else:
84
                    lines.insert(0, line)
85
                    break # no meta data - done
86
        self.markdown.Meta = meta
87
        return lines
88
        
89
90
def makeExtension(configs={}):
91
    return MetaExtension(configs=configs)
92
93
if __name__ == "__main__":
94
    import doctest
95
    doctest.testmod()