15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# markdown is released under the BSD license
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2004 Manfred Stienstra (the original version)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# All rights reserved.
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Redistribution and use in source and binary forms, with or without
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# modification, are permitted provided that the following conditions are met:
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# *   Redistributions of source code must retain the above copyright
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#     notice, this list of conditions and the following disclaimer.
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# *   Redistributions in binary form must reproduce the above copyright
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#     notice, this list of conditions and the following disclaimer in the
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#     documentation and/or other materials provided with the distribution.
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# *   Neither the name of the <organization> nor the
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#     names of its contributors may be used to endorse or promote products
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#     derived from this software without specific prior written permission.
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# POSSIBILITY OF SUCH DAMAGE.
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)"""
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Meta Data Extension for Python-Markdown
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)=======================================
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)This extension adds Meta Data handling to markdown.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Basic Usage:
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> import markdown
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> text = '''Title: A Test Doc.
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... Author: Waylan Limberg
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ...         John Doe
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... Blank_Data:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ...
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... The body. This is paragraph one.
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... '''
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> md = markdown.Markdown(['meta'])
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> print md.convert(text)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    <p>The body. This is paragraph one.</p>
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> print md.Meta
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {u'blank_data': [u''], u'author': [u'Waylan Limberg', u'John Doe'], u'title': [u'A Test Doc.']}
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Make sure text without Meta Data still works (markdown < 1.6b returns a <p>).
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> text = '    Some Code - not extra lines of meta data.'
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> md = markdown.Markdown(['meta'])
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> print md.convert(text)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    <pre><code>Some Code - not extra lines of meta data.
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    </code></pre>
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> md.Meta
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    {}
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Project website: <http://packages.python.org/Markdown/meta_data.html>
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Contact: markdown@freewisdom.org
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)License: BSD (see ../LICENSE.md for details)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)"""
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import absolute_import
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import unicode_literals
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from . import Extension
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from ..preprocessors import Preprocessor
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import re
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Global Vars
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MetaExtension (Extension):
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    """ Meta-Data extension for Python-Markdown. """
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def extendMarkdown(self, md, md_globals):
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        """ Add MetaPreprocessor to Markdown instance. """
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        md.preprocessors.add("meta", MetaPreprocessor(md), "_begin")
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MetaPreprocessor(Preprocessor):
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    """ Get Meta-Data. """
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def run(self, lines):
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        """ Parse Meta-Data and store in Markdown.Meta. """
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        meta = {}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        key = None
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        while 1:
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            line = lines.pop(0)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if line.strip() == '':
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                break # blank line - done
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            m1 = META_RE.match(line)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if m1:
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                key = m1.group('key').lower().strip()
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                value = m1.group('value').strip()
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                try:
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    meta[key].append(value)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                except KeyError:
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    meta[key] = [value]
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            else:
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                m2 = META_MORE_RE.match(line)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                if m2 and key:
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    # Add another line to existing key
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    meta[key].append(m2.group('value').strip())
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                else:
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    lines.insert(0, line)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    break # no meta data - done
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        self.markdown.Meta = meta
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return lines
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def makeExtension(configs={}):
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return MetaExtension(configs=configs)
126