Home | History | Annotate | Download | only in extensions
      1 # markdown is released under the BSD license
      2 # Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
      3 # Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
      4 # Copyright 2004 Manfred Stienstra (the original version)
      5 # 
      6 # All rights reserved.
      7 # 
      8 # Redistribution and use in source and binary forms, with or without
      9 # modification, are permitted provided that the following conditions are met:
     10 # 
     11 # *   Redistributions of source code must retain the above copyright
     12 #     notice, this list of conditions and the following disclaimer.
     13 # *   Redistributions in binary form must reproduce the above copyright
     14 #     notice, this list of conditions and the following disclaimer in the
     15 #     documentation and/or other materials provided with the distribution.
     16 # *   Neither the name of the <organization> nor the
     17 #     names of its contributors may be used to endorse or promote products
     18 #     derived from this software without specific prior written permission.
     19 # 
     20 # THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY
     21 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     22 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     23 # DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
     24 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30 # POSSIBILITY OF SUCH DAMAGE.
     31 
     32 
     33 """
     34 Meta Data Extension for Python-Markdown
     35 =======================================
     36 
     37 This extension adds Meta Data handling to markdown.
     38 
     39 Basic Usage:
     40 
     41     >>> import markdown
     42     >>> text = '''Title: A Test Doc.
     43     ... Author: Waylan Limberg
     44     ...         John Doe
     45     ... Blank_Data:
     46     ...
     47     ... The body. This is paragraph one.
     48     ... '''
     49     >>> md = markdown.Markdown(['meta'])
     50     >>> print md.convert(text)
     51     <p>The body. This is paragraph one.</p>
     52     >>> print md.Meta
     53     {u'blank_data': [u''], u'author': [u'Waylan Limberg', u'John Doe'], u'title': [u'A Test Doc.']}
     54 
     55 Make sure text without Meta Data still works (markdown < 1.6b returns a <p>).
     56 
     57     >>> text = '    Some Code - not extra lines of meta data.'
     58     >>> md = markdown.Markdown(['meta'])
     59     >>> print md.convert(text)
     60     <pre><code>Some Code - not extra lines of meta data.
     61     </code></pre>
     62     >>> md.Meta
     63     {}
     64 
     65 Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
     66 
     67 Project website: <http://packages.python.org/Markdown/meta_data.html>
     68 Contact: markdown (at] freewisdom.org
     69 
     70 License: BSD (see ../LICENSE.md for details)
     71 
     72 """
     73 
     74 from __future__ import absolute_import
     75 from __future__ import unicode_literals
     76 from . import Extension
     77 from ..preprocessors import Preprocessor
     78 import re
     79 
     80 # Global Vars
     81 META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)')
     82 META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)')
     83 
     84 class MetaExtension (Extension):
     85     """ Meta-Data extension for Python-Markdown. """
     86 
     87     def extendMarkdown(self, md, md_globals):
     88         """ Add MetaPreprocessor to Markdown instance. """
     89 
     90         md.preprocessors.add("meta", MetaPreprocessor(md), "_begin")
     91 
     92 
     93 class MetaPreprocessor(Preprocessor):
     94     """ Get Meta-Data. """
     95 
     96     def run(self, lines):
     97         """ Parse Meta-Data and store in Markdown.Meta. """
     98         meta = {}
     99         key = None
    100         while 1:
    101             line = lines.pop(0)
    102             if line.strip() == '':
    103                 break # blank line - done
    104             m1 = META_RE.match(line)
    105             if m1:
    106                 key = m1.group('key').lower().strip()
    107                 value = m1.group('value').strip()
    108                 try:
    109                     meta[key].append(value)
    110                 except KeyError:
    111                     meta[key] = [value]
    112             else:
    113                 m2 = META_MORE_RE.match(line)
    114                 if m2 and key:
    115                     # Add another line to existing key
    116                     meta[key].append(m2.group('value').strip())
    117                 else:
    118                     lines.insert(0, line)
    119                     break # no meta data - done
    120         self.markdown.Meta = meta
    121         return lines
    122         
    123 
    124 def makeExtension(configs={}):
    125     return MetaExtension(configs=configs)
    126