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 WikiLinks Extension for Python-Markdown 35 ====================================== 36 37 Converts [[WikiLinks]] to relative links. Requires Python-Markdown 2.0+ 38 39 Basic 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 47 Whitespace 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 54 To 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 61 Custom 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 73 Use 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 84 MetaData 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 89 Define 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 98 From the command line: 99 100 python markdown.py -x wikilinks(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt 101 102 By [Waylan Limberg](http://achinghead.com/). 103 104 License: [BSD](http://www.opensource.org/licenses/bsd-license.php) 105 106 Dependencies: 107 * [Python 2.3+](http://python.org) 108 * [Markdown 2.0+](http://packages.python.org/Markdown/) 109 ''' 110 111 from __future__ import absolute_import 112 from __future__ import unicode_literals 113 from . import Extension 114 from ..inlinepatterns import Pattern 115 from ..util import etree 116 import re 117 118 def 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 124 class 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 148 class 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 182 def makeExtension(configs=None) : 183 return WikiLinkExtension(configs=configs) 184