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''' 34WikiLinks Extension for Python-Markdown 35====================================== 36 37Converts [[WikiLinks]] to relative links. Requires Python-Markdown 2.0+ 38 39Basic usage: 40 41 >>> import markdown 42 >>> text = "Some text with a [[WikiLink]]." 43 >>> html = markdown.markdown(text, ['wikilinks']) 44 >>> print html 45 <p>Some text with a <a class="wikilink" href="/WikiLink/">WikiLink</a>.</p> 46 47Whitespace behavior: 48 49 >>> print markdown.markdown('[[ foo bar_baz ]]', ['wikilinks']) 50 <p><a class="wikilink" href="/foo_bar_baz/">foo bar_baz</a></p> 51 >>> print markdown.markdown('foo [[ ]] bar', ['wikilinks']) 52 <p>foo bar</p> 53 54To define custom settings the simple way: 55 56 >>> print markdown.markdown(text, 57 ... ['wikilinks(base_url=/wiki/,end_url=.html,html_class=foo)'] 58 ... ) 59 <p>Some text with a <a class="foo" href="/wiki/WikiLink.html">WikiLink</a>.</p> 60 61Custom settings the complex way: 62 63 >>> md = markdown.Markdown( 64 ... extensions = ['wikilinks'], 65 ... extension_configs = {'wikilinks': [ 66 ... ('base_url', 'http://example.com/'), 67 ... ('end_url', '.html'), 68 ... ('html_class', '') ]}, 69 ... safe_mode = True) 70 >>> print md.convert(text) 71 <p>Some text with a <a href="http://example.com/WikiLink.html">WikiLink</a>.</p> 72 73Use MetaData with mdx_meta.py (Note the blank html_class in MetaData): 74 75 >>> text = """wiki_base_url: http://example.com/ 76 ... wiki_end_url: .html 77 ... wiki_html_class: 78 ... 79 ... Some text with a [[WikiLink]].""" 80 >>> md = markdown.Markdown(extensions=['meta', 'wikilinks']) 81 >>> print md.convert(text) 82 <p>Some text with a <a href="http://example.com/WikiLink.html">WikiLink</a>.</p> 83 84MetaData should not carry over to next document: 85 86 >>> print md.convert("No [[MetaData]] here.") 87 <p>No <a class="wikilink" href="/MetaData/">MetaData</a> here.</p> 88 89Define a custom URL builder: 90 91 >>> def my_url_builder(label, base, end): 92 ... return '/bar/' 93 >>> md = markdown.Markdown(extensions=['wikilinks'], 94 ... extension_configs={'wikilinks' : [('build_url', my_url_builder)]}) 95 >>> print md.convert('[[foo]]') 96 <p><a class="wikilink" href="/bar/">foo</a></p> 97 98From the command line: 99 100 python markdown.py -x wikilinks(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt 101 102By [Waylan Limberg](http://achinghead.com/). 103 104License: [BSD](http://www.opensource.org/licenses/bsd-license.php) 105 106Dependencies: 107* [Python 2.3+](http://python.org) 108* [Markdown 2.0+](http://packages.python.org/Markdown/) 109''' 110 111from __future__ import absolute_import 112from __future__ import unicode_literals 113from . import Extension 114from ..inlinepatterns import Pattern 115from ..util import etree 116import re 117 118def build_url(label, base, end): 119 """ Build a url from the label, a base, and an end. """ 120 clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label) 121 return '%s%s%s'% (base, clean_label, end) 122 123 124class WikiLinkExtension(Extension): 125 def __init__(self, configs): 126 # set extension defaults 127 self.config = { 128 'base_url' : ['/', 'String to append to beginning or URL.'], 129 'end_url' : ['/', 'String to append to end of URL.'], 130 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'], 131 'build_url' : [build_url, 'Callable formats URL from label.'], 132 } 133 134 # Override defaults with user settings 135 for key, value in configs : 136 self.setConfig(key, value) 137 138 def extendMarkdown(self, md, md_globals): 139 self.md = md 140 141 # append to end of inline patterns 142 WIKILINK_RE = r'\[\[([\w0-9_ -]+)\]\]' 143 wikilinkPattern = WikiLinks(WIKILINK_RE, self.getConfigs()) 144 wikilinkPattern.md = md 145 md.inlinePatterns.add('wikilink', wikilinkPattern, "<not_strong") 146 147 148class WikiLinks(Pattern): 149 def __init__(self, pattern, config): 150 super(WikiLinks, self).__init__(pattern) 151 self.config = config 152 153 def handleMatch(self, m): 154 if m.group(2).strip(): 155 base_url, end_url, html_class = self._getMeta() 156 label = m.group(2).strip() 157 url = self.config['build_url'](label, base_url, end_url) 158 a = etree.Element('a') 159 a.text = label 160 a.set('href', url) 161 if html_class: 162 a.set('class', html_class) 163 else: 164 a = '' 165 return a 166 167 def _getMeta(self): 168 """ Return meta data or config data. """ 169 base_url = self.config['base_url'] 170 end_url = self.config['end_url'] 171 html_class = self.config['html_class'] 172 if hasattr(self.md, 'Meta'): 173 if 'wiki_base_url' in self.md.Meta: 174 base_url = self.md.Meta['wiki_base_url'][0] 175 if 'wiki_end_url' in self.md.Meta: 176 end_url = self.md.Meta['wiki_end_url'][0] 177 if 'wiki_html_class' in self.md.Meta: 178 html_class = self.md.Meta['wiki_html_class'][0] 179 return base_url, end_url, html_class 180 181 182def makeExtension(configs=None) : 183 return WikiLinkExtension(configs=configs) 184