1#!usr/bin/python
2
3"""
4Meta Data Extension for Python-Markdown
5=======================================
6
7This extension adds Meta Data handling to markdown.
8
9Basic 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
25Make 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
34Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
35
36Project website: <http://www.freewisdom.org/project/python-markdown/Meta-Data>
37Contact: markdown@freewisdom.org
38
39License: BSD (see ../docs/LICENSE for details)
40
41"""
42
43import markdown, re
44
45# Global Vars
46META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
47META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
48
49class MetaExtension (markdown.Extension):
50    """ Meta-Data extension for Python-Markdown. """
51
52    def extendMarkdown(self, md, md_globals):
53        """ Add MetaPreprocessor to Markdown instance. """
54
55        md.preprocessors.add("meta", MetaPreprocessor(md), "_begin")
56
57
58class MetaPreprocessor(markdown.preprocessors.Preprocessor):
59    """ Get Meta-Data. """
60
61    def run(self, lines):
62        """ Parse Meta-Data and store in Markdown.Meta. """
63        meta = {}
64        key = None
65        while 1:
66            line = lines.pop(0)
67            if line.strip() == '':
68                break # blank line - done
69            m1 = META_RE.match(line)
70            if m1:
71                key = m1.group('key').lower().strip()
72                meta[key] = [m1.group('value').strip()]
73            else:
74                m2 = META_MORE_RE.match(line)
75                if m2 and key:
76                    # Add another line to existing key
77                    meta[key].append(m2.group('value').strip())
78                else:
79                    lines.insert(0, line)
80                    break # no meta data - done
81        self.markdown.Meta = meta
82        return lines
83
84
85def makeExtension(configs={}):
86    return MetaExtension(configs=configs)
87
88if __name__ == "__main__":
89    import doctest
90    doctest.testmod()
91