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