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)Abbreviation Extension for Python-Markdown
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)==========================================
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)This extension adds abbreviation handling to Python-Markdown.
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Simple Usage:
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> import markdown
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> text = """
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... Some text with an ABBR and a REF. Ignore REFERENCE and ref.
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ...
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... *[ABBR]: Abbreviation
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... *[REF]: Abbreviation Reference
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ... """
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    >>> print markdown.markdown(text, ['abbr'])
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    <p>Some text with an <abbr title="Abbreviation">ABBR</abbr> and a <abbr title="Abbreviation Reference">REF</abbr>. Ignore REFERENCE and ref.</p>
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 2007-2008
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)* [Waylan Limberg](http://achinghead.com/)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)* [Seemant Kulleen](http://www.kulleen.org/)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)'''
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import absolute_import
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import unicode_literals
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from . import Extension
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from ..preprocessors import Preprocessor
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from ..inlinepatterns import Pattern
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from ..util import etree
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import re
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Global Vars
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ABBR_REF_RE = re.compile(r'[*]\[(?P<abbr>[^\]]*)\][ ]?:\s*(?P<title>.*)')
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AbbrExtension(Extension):
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    """ Abbreviation Extension for Python-Markdown. """
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def extendMarkdown(self, md, md_globals):
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        """ Insert AbbrPreprocessor before ReferencePreprocessor. """
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        md.preprocessors.add('abbr', AbbrPreprocessor(md), '<reference')
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AbbrPreprocessor(Preprocessor):
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    """ Abbreviation Preprocessor - parse text for abbr references. """
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def run(self, lines):
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        '''
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Find and remove all Abbreviation references from the text.
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Each reference is set as a new AbbrPattern in the markdown instance.
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        '''
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new_text = []
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        for line in lines:
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            m = ABBR_REF_RE.match(line)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            if m:
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                abbr = m.group('abbr').strip()
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                title = m.group('title').strip()
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                self.markdown.inlinePatterns['abbr-%s'%abbr] = \
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    AbbrPattern(self._generate_pattern(abbr), title)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            else:
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                new_text.append(line)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return new_text
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def _generate_pattern(self, text):
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        '''
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Given a string, returns an regex pattern to match that string.
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        'HTML' -> r'(?P<abbr>[H][T][M][L])'
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        Note: we force each char as a literal match (in brackets) as we don't
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        know what they will be beforehand.
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        '''
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        chars = list(text)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        for i in range(len(chars)):
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            chars[i] = r'[%s]' % chars[i]
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return r'(?P<abbr>\b%s\b)' % (r''.join(chars))
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AbbrPattern(Pattern):
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    """ Abbreviation inline pattern. """
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def __init__(self, pattern, title):
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        super(AbbrPattern, self).__init__(pattern)
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        self.title = title
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    def handleMatch(self, m):
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        abbr = etree.Element('abbr')
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        abbr.text = m.group('abbr')
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        abbr.set('title', self.title)
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        return abbr
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def makeExtension(configs=None):
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return AbbrExtension(configs=configs)
129