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)Python Markdown 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)=============== 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Python Markdown converts Markdown to HTML and can be used as a library or 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)called from the command line. 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)## Basic usage as a module: 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) import markdown 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) html = markdown.markdown(your_text_string) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)See <http://packages.python.org/Markdown/> for more 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)information and instructions on how to extend the functionality of 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Python Markdown. Read that before you try modifying this file. 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)## Authors and License 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Started by [Manfred Stienstra](http://www.dwerg.net/). Continued and 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)maintained by [Yuri Takhteyev](http://www.freewisdom.org), [Waylan 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Limberg](http://achinghead.com/) and [Artem Yunusov](http://blog.splyer.com). 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Contact: markdown@freewisdom.org 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 2007-2013 The Python Markdown Project (v. 1.7 and later) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 200? Django Software Foundation (OrderedDict implementation) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Copyright 2004 Manfred Stienstra (the original version) 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)License: BSD (see LICENSE for details). 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import absolute_import 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from __future__ import unicode_literals 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .__version__ import version, version_info 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import re 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import codecs 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import sys 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import logging 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from . import util 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .preprocessors import build_preprocessors 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .blockprocessors import build_block_parser 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .treeprocessors import build_treeprocessors 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .inlinepatterns import build_inlinepatterns 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .postprocessors import build_postprocessors 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .extensions import Extension 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)from .serializers import to_html_string, to_xhtml_string 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)__all__ = ['Markdown', 'markdown', 'markdownFromFile'] 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)logger = logging.getLogger('MARKDOWN') 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class Markdown(object): 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Convert Markdown to HTML.""" 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) doc_tag = "div" # Element used to wrap document - later removed 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) option_defaults = { 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'html_replacement_text' : '[HTML_REMOVED]', 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'tab_length' : 4, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'enable_attributes' : True, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'smart_emphasis' : True, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'lazy_ol' : True, 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_formats = { 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'html' : to_html_string, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'html4' : to_html_string, 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'html5' : to_html_string, 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'xhtml' : to_xhtml_string, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'xhtml1': to_xhtml_string, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'xhtml5': to_xhtml_string, 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ESCAPED_CHARS = ['\\', '`', '*', '_', '{', '}', '[', ']', 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '(', ')', '>', '#', '+', '-', '.', '!'] 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, *args, **kwargs): 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Creates a new Markdown instance. 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * extensions: A list of extensions. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) If they are of type string, the module mdx_name.py will be loaded. 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) If they are a subclass of markdown.Extension, they will be used 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) as-is. 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * extension_configs: Configuration settingis for extensions. 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * output_format: Format of output. Supported formats are: 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "xhtml1": Outputs XHTML 1.x. Default. 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "xhtml5": Outputs XHTML style tags of HTML 5 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "xhtml": Outputs latest supported version of XHTML (currently XHTML 1.1). 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "html4": Outputs HTML 4 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "html5": Outputs HTML style tags of HTML 5 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * "html": Outputs latest supported version of HTML (currently HTML 4). 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Note that it is suggested that the more specific formats ("xhtml1" 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) and "html4") be used as "xhtml" or "html" may change in the future 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if it makes sense at that time. 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * safe_mode: Disallow raw html. One of "remove", "replace" or "escape". 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * html_replacement_text: Text used when safe_mode is set to "replace". 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * tab_length: Length of tabs in the source. Default: 4 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * enable_attributes: Enable the conversion of attributes. Default: True 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * smart_emphasis: Treat `_connected_words_` intelegently Default: True 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * lazy_ol: Ignore number of first item of ordered lists. Default: True 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # For backward compatibility, loop through old positional args 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pos = ['extensions', 'extension_configs', 'safe_mode', 'output_format'] 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) c = 0 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for arg in args: 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if pos[c] not in kwargs: 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kwargs[pos[c]] = arg 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) c += 1 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if c == len(pos): 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # ignore any additional args 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Loop through kwargs and assign defaults 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for option, default in self.option_defaults.items(): 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) setattr(self, option, kwargs.get(option, default)) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.safeMode = kwargs.get('safe_mode', False) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.safeMode and 'enable_attributes' not in kwargs: 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Disable attributes in safeMode when not explicitly set 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.enable_attributes = False 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.registeredExtensions = [] 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.docType = "" 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.stripTopLevelTags = True 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.build_parser() 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.references = {} 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.htmlStash = util.HtmlStash() 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.set_output_format(kwargs.get('output_format', 'xhtml1')) 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.registerExtensions(extensions=kwargs.get('extensions', []), 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configs=kwargs.get('extension_configs', {})) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.reset() 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def build_parser(self): 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ Build the parser from the various parts. """ 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.preprocessors = build_preprocessors(self) 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.parser = build_block_parser(self) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.inlinePatterns = build_inlinepatterns(self) 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.treeprocessors = build_treeprocessors(self) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.postprocessors = build_postprocessors(self) 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def registerExtensions(self, extensions, configs): 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Register extensions with this instance of Markdown. 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * extensions: A list of extensions, which can either 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) be strings or objects. See the docstring on Markdown. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * configs: A dictionary mapping module names to config options. 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for ext in extensions: 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if isinstance(ext, util.string_type): 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext = self.build_extension(ext, configs.get(ext, [])) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if isinstance(ext, Extension): 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext.extendMarkdown(self, globals()) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif ext is not None: 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise TypeError( 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'Extension "%s.%s" must be of type: "markdown.Extension"' 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) % (ext.__class__.__module__, ext.__class__.__name__)) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def build_extension(self, ext_name, configs = []): 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Build extension by name, then return the module. 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) The extension name may contain arguments as part of the string in the 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) following format: "extname(key1=value1,key2=value2)" 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Parse extensions config params (ignore the order) 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configs = dict(configs) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pos = ext_name.find("(") # find the first "(" 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if pos > 0: 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext_args = ext_name[pos+1:-1] 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext_name = ext_name[:pos] 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pairs = [x.split("=") for x in ext_args.split(",")] 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) configs.update([(x.strip(), y.strip()) for (x, y) in pairs]) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Setup the module name 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module_name = ext_name 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if '.' not in ext_name: 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module_name = '.'.join(['third_party.markdown.extensions', ext_name]) 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Try loading the extension first from one place, then another 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: # New style (markdown.extensons.<extension>) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module = __import__(module_name, {}, {}, [module_name.rpartition('.')[0]]) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except ImportError: 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module_name_old_style = '_'.join(['mdx', ext_name]) 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: # Old style (mdx_<extension>) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) module = __import__(module_name_old_style) 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except ImportError as e: 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message = "Failed loading extension '%s' from '%s' or '%s'" \ 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) % (ext_name, module_name, module_name_old_style) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e.args = (message,) + e.args[1:] 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # If the module is loaded successfully, we expect it to define a 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # function called makeExtension() 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return module.makeExtension(configs.items()) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except AttributeError as e: 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message = e.args[0] 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message = "Failed to initiate extension " \ 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "'%s': %s" % (ext_name, message) 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e.args = (message,) + e.args[1:] 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def registerExtension(self, extension): 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ This gets called by the extension """ 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.registeredExtensions.append(extension) 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def reset(self): 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Resets all state variables so that we can start with a new text. 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.htmlStash.reset() 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.references.clear() 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for extension in self.registeredExtensions: 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if hasattr(extension, 'reset'): 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension.reset() 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def set_output_format(self, format): 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ Set the output format for the class instance. """ 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.output_format = format.lower() 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.serializer = self.output_formats[self.output_format] 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except KeyError as e: 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid_formats = list(self.output_formats.keys()) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid_formats.sort() 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) message = 'Invalid Output Format: "%s". Use one of %s.' \ 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) % (self.output_format, 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '"' + '", "'.join(valid_formats) + '"') 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e.args = (message,) + e.args[1:] 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def convert(self, source): 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Convert markdown to serialized XHTML or HTML. 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * source: Source text as a Unicode string. 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Markdown processing takes place in five steps: 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1. A bunch of "preprocessors" munge the input text. 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2. BlockParser() parses the high-level structural elements of the 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pre-processed text into an ElementTree. 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3. A bunch of "treeprocessors" are run against the ElementTree. One 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) such treeprocessor runs InlinePatterns against the ElementTree, 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) detecting inline markup. 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4. Some post-processors are run against the text after the ElementTree 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) has been serialized into text. 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5. The output is written to a string. 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Fixup the source text 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not source.strip(): 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return '' # a blank unicode string 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) source = util.text_type(source) 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except UnicodeDecodeError as e: 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Customise error message while maintaining original trackback 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e.reason += '. -- Note: Markdown only accepts unicode input!' 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Split into lines and run the line preprocessors. 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.lines = source.split("\n") 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for prep in self.preprocessors.values(): 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.lines = prep.run(self.lines) 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Parse the high-level elements. 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root = self.parser.parseDocument(self.lines).getroot() 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Run the tree-processors 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for treeprocessor in self.treeprocessors.values(): 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) newRoot = treeprocessor.run(root) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if newRoot: 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) root = newRoot 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Serialize _properly_. Strip top-level tags. 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output = self.serializer(root) 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.stripTopLevelTags: 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) start = output.index('<%s>'%self.doc_tag)+len(self.doc_tag)+2 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) end = output.rindex('</%s>'%self.doc_tag) 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output = output[start:end].strip() 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except ValueError: 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if output.strip().endswith('<%s />'%self.doc_tag): 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # We have an empty document 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output = '' 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # We have a serious problem 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise ValueError('Markdown failed to strip top-level tags. Document=%r' % output.strip()) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Run the text post-processors 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for pp in self.postprocessors.values(): 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output = pp.run(output) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return output.strip() 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def convertFile(self, input=None, output=None, encoding=None): 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Converts a markdown file and returns the HTML as a unicode string. 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Decodes the file using the provided encoding (defaults to utf-8), 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) passes the file content to markdown, and outputs the html to either 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) the provided stream or the file with provided name, using the same 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) encoding as the source file. The 'xmlcharrefreplace' error handler is 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) used when encoding the output. 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) **Note:** This is the only place that decoding and encoding of unicode 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) takes place in Python-Markdown. (All other code is unicode-in / 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unicode-out.) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * input: File object or path. Reads from stdin if `None`. 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * output: File object or path. Writes to stdout if `None`. 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * encoding: Encoding of input and output files. Defaults to utf-8. 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) encoding = encoding or "utf-8" 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Read the source 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if input: 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if isinstance(input, util.string_type): 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_file = codecs.open(input, mode="r", encoding=encoding) 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_file = codecs.getreader(encoding)(input) 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) text = input_file.read() 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) input_file.close() 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) text = sys.stdin.read() 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not isinstance(text, util.text_type): 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) text = text.decode(encoding) 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) text = text.lstrip('\ufeff') # remove the byte-order mark 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Convert 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) html = self.convert(text) 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Write to file or stdout 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if output: 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if isinstance(output, util.string_type): 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_file = codecs.open(output, "w", 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) encoding=encoding, 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errors="xmlcharrefreplace") 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_file.write(html) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_file.close() 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writer = codecs.getwriter(encoding) 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_file = writer(output, errors="xmlcharrefreplace") 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) output_file.write(html) 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Don't close here. User may want to write more. 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Encode manually and write bytes to stdout. 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) html = html.encode(encoding, "xmlcharrefreplace") 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) try: 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Write bytes directly to buffer (Python 3). 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.stdout.buffer.write(html) 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) except AttributeError: 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Probably Python 2, which works with bytes by default. 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sys.stdout.write(html) 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)EXPORTED FUNCTIONS 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)============================================================================= 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Those are the two functions we really mean to export: markdown() and 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)markdownFromFile(). 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)""" 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def markdown(text, *args, **kwargs): 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Convert a markdown string to HTML and return HTML as a unicode string. 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) This is a shortcut function for `Markdown` class to cover the most 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) basic use case. It initializes an instance of Markdown, loads the 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) necessary extensions and runs the parser on the given text. 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * text: Markdown formatted text as Unicode or ASCII string. 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Any arguments accepted by the Markdown class. 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Returns: An HTML document as a string. 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) md = Markdown(*args, **kwargs) 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return md.convert(text) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)def markdownFromFile(*args, **kwargs): 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """Read markdown code from a file and write it to a file or a stream. 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) This is a shortcut function which initializes an instance of Markdown, 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) and calls the convertFile method rather than convert. 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Keyword arguments: 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * input: a file name or readable object. 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * output: a file name or writable object. 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * encoding: Encoding of input and output. 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Any arguments accepted by the Markdown class. 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # For backward compatibility loop through positional args 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pos = ['input', 'output', 'extensions', 'encoding'] 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) c = 0 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for arg in args: 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if pos[c] not in kwargs: 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kwargs[pos[c]] = arg 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) c += 1 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if c == len(pos): 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) md = Markdown(**kwargs) 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) md.convertFile(kwargs.get('input', None), 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kwargs.get('output', None), 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) kwargs.get('encoding', None)) 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 476