Some text with an ABBR and a REF. Ignore REFERENCE and ref.
-All changes Copyright 2008-2014 The Python Markdown Project - -License: [BSD](http://www.opensource.org/licenses/bsd-license.php) +Copyright 2007-2008 +* [Waylan Limberg](http://achinghead.com/) +* [Seemant Kulleen](http://www.kulleen.org/) + ''' @@ -85,5 +92,5 @@ class AbbrPattern(Pattern): abbr.set('title', self.title) return abbr -def makeExtension(*args, **kwargs): - return AbbrExtension(*args, **kwargs) +def makeExtension(configs=None): + return AbbrExtension(configs=configs) diff --git a/awx/lib/site-packages/markdown/extensions/admonition.py b/awx/lib/site-packages/markdown/extensions/admonition.py index 189f2c2dd9..9a45b9249c 100644 --- a/awx/lib/site-packages/markdown/extensions/admonition.py +++ b/awx/lib/site-packages/markdown/extensions/admonition.py @@ -4,16 +4,39 @@ Admonition extension for Python-Markdown Adds rST-style admonitions. Inspired by [rST][] feature with the same name. +The syntax is (followed by an indented block with the contents): + !!! [type] [optional explicit title] + +Where `type` is used as a CSS class name of the div. If not present, `title` +defaults to the capitalized `type`, so "note" -> "Note". + +rST suggests the following `types`, but you're free to use whatever you want: + attention, caution, danger, error, hint, important, note, tip, warning + + +A simple example: + !!! note + This is the first line inside the box. + +Outputs: +Note
+This is the first line inside the box
+Did you know?
+Another line here.
+A paragraph before a fenced code block:
+Fenced code block
+
-Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
+Works with safe_mode also (we check this because we are using the HtmlStash):
+ >>> print markdown.markdown(text, extensions=['fenced_code'], safe_mode='replace')
+ A paragraph before a fenced code block:
+Fenced code block
+
-All changes Copyright 2008-2014 The Python Markdown Project
+Include tilde's in a code block and wrap with blank lines:
+
+ >>> text = '''
+ ... ~~~~~~~~
+ ...
+ ... ~~~~
+ ... ~~~~~~~~'''
+ >>> print markdown.markdown(text, extensions=['fenced_code'])
+
+ ~~~~
+
+
+Language tags:
+
+ >>> text = '''
+ ... ~~~~{.python}
+ ... # Some python code
+ ... ~~~~'''
+ >>> print markdown.markdown(text, extensions=['fenced_code'])
+ # Some python code
+
+
+Optionally backticks instead of tildes as per how github's code block markdown is identified:
+
+ >>> text = '''
+ ... `````
+ ... # Arbitrary code
+ ... ~~~~~ # these tildes will not close the block
+ ... `````'''
+ >>> print markdown.markdown(text, extensions=['fenced_code'])
+ # Arbitrary code
+ ~~~~~ # these tildes will not close the block
+
+
+If the codehighlite extension and Pygments are installed, lines can be highlighted:
+
+ >>> text = '''
+ ... ```hl_lines="1 3"
+ ... line 1
+ ... line 2
+ ... line 3
+ ... ```'''
+ >>> print markdown.markdown(text, extensions=['codehilite', 'fenced_code'])
+ line 1
+ line 2
+ line 3
+
+
+Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/).
+
+Project website: The body. This is paragraph one.
+ >>> print md.Meta + {u'blank_data': [u''], u'author': [u'Waylan Limberg', u'John Doe'], u'title': [u'A Test Doc.']} -All changes Copyright 2008-2014 The Python Markdown Project +Make sure text without Meta Data still works (markdown < 1.6b returns a). -License: [BSD](http://www.opensource.org/licenses/bsd-license.php) + >>> text = ' Some Code - not extra lines of meta data.' + >>> md = markdown.Markdown(['meta']) + >>> print md.convert(text) +
Some Code - not extra lines of meta data.
+
+ >>> md.Meta
+ {}
+
+Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
+
+Project website: line 1
+ line 2
Text with double__underscore__words.
+ >>> print markdown.markdown('__Strong__ still works.', + ... extensions=['smart_strong']) +Strong still works.
+ >>> print markdown.markdown('__this__works__too__.', + ... extensions=['smart_strong']) +this__works__too.
-All changes Copyright 2011-2014 The Python Markdown Project - -License: [BSD](http://www.opensource.org/licenses/bsd-license.php) +Copyright 2011 +[Waylan Limberg](http://achinghead.com) ''' @@ -31,5 +38,5 @@ class SmartEmphasisExtension(Extension): md.inlinePatterns['strong'] = SimpleTagPattern(STRONG_RE, 'strong') md.inlinePatterns.add('strong2', SimpleTagPattern(SMART_STRONG_RE, 'strong'), '>emphasis2') -def makeExtension(*args, **kwargs): - return SmartEmphasisExtension(*args, **kwargs) +def makeExtension(configs={}): + return SmartEmphasisExtension(configs=dict(configs)) diff --git a/awx/lib/site-packages/markdown/extensions/smarty.py b/awx/lib/site-packages/markdown/extensions/smarty.py index 00c330f1f0..2f946f8294 100644 --- a/awx/lib/site-packages/markdown/extensions/smarty.py +++ b/awx/lib/site-packages/markdown/extensions/smarty.py @@ -1,91 +1,73 @@ # -*- coding: utf-8 -*- -''' -Smarty extension for Python-Markdown -==================================== - -Adds conversion of ASCII dashes, quotes and ellipses to their HTML -entity equivalents. - -SeeHe said, "'Quoted' words in a larger quote."
@@ -144,6 +113,8 @@ closingSingleQuotesRegex2 = r"(?<=%s)'(\s|s\b)" % closeClass remainingSingleQuotesRegex = "'" remainingDoubleQuotesRegex = '"' +lsquo, rsquo, ldquo, rdquo = '‘', '’', '“', '”' + class SubstituteTextPattern(HtmlPattern): def __init__(self, pattern, replace, markdown_instance): """ Replaces matches with some text. """ @@ -161,56 +132,35 @@ class SubstituteTextPattern(HtmlPattern): return result class SmartyExtension(Extension): - def __init__(self, *args, **kwargs): + def __init__(self, configs): self.config = { 'smart_quotes': [True, 'Educate quotes'], - 'smart_angled_quotes': [False, 'Educate angled quotes'], 'smart_dashes': [True, 'Educate dashes'], - 'smart_ellipses': [True, 'Educate ellipses'], - 'substitutions' : [{}, 'Overwrite default substitutions'], + 'smart_ellipses': [True, 'Educate ellipses'] } - super(SmartyExtension, self).__init__(*args, **kwargs) - self.substitutions = dict(substitutions) - self.substitutions.update(self.getConfig('substitutions', default={})) + for key, value in configs: + self.setConfig(key, parseBoolValue(value)) def _addPatterns(self, md, patterns, serie): for ind, pattern in enumerate(patterns): pattern += (md,) pattern = SubstituteTextPattern(*pattern) - after = ('>smarty-%s-%d' % (serie, ind - 1) if ind else '_begin') + after = ('>smarty-%s-%d' % (serie, ind - 1) if ind else '>entity') name = 'smarty-%s-%d' % (serie, ind) - self.inlinePatterns.add(name, pattern, after) + md.inlinePatterns.add(name, pattern, after) def educateDashes(self, md): - emDashesPattern = SubstituteTextPattern(r'(?entity') + md.inlinePatterns.add('smarty-en-dashes', enDashesPattern, '>smarty-em-dashes') def educateEllipses(self, md): - ellipsesPattern = SubstituteTextPattern(r'(?\>', - (self.substitutions['right-angle-quote'],), md) - self.inlinePatterns.add('smarty-left-angle-quotes', - leftAngledQuotePattern, '_begin') - self.inlinePatterns.add('smarty-right-angle-quotes', - rightAngledQuotePattern, '>smarty-left-angle-quotes') + ellipsesPattern = SubstituteTextPattern(r'(?entity') def educateQuotes(self, md): - configs = self.getConfigs() - lsquo = self.substitutions['left-single-quote'] - rsquo = self.substitutions['right-single-quote'] - ldquo = self.substitutions['left-double-quote'] - rdquo = self.substitutions['right-double-quote'] patterns = ( (singleQuoteStartRe, (rsquo,)), (doubleQuoteStartRe, (rdquo,)), @@ -229,19 +179,13 @@ class SmartyExtension(Extension): def extendMarkdown(self, md, md_globals): configs = self.getConfigs() - self.inlinePatterns = OrderedDict() - if configs['smart_ellipses']: - self.educateEllipses(md) if configs['smart_quotes']: self.educateQuotes(md) - if configs['smart_angled_quotes']: - self.educateAngledQuotes(md) if configs['smart_dashes']: self.educateDashes(md) - inlineProcessor = InlineProcessor(md) - inlineProcessor.inlinePatterns = self.inlinePatterns - md.treeprocessors.add('smarty', inlineProcessor, '_end') + if configs['smart_ellipses']: + self.educateEllipses(md) md.ESCAPED_CHARS.extend(['"', "'"]) -def makeExtension(*args, **kwargs): - return SmartyExtension(*args, **kwargs) +def makeExtension(configs=None): + return SmartyExtension(configs) diff --git a/awx/lib/site-packages/markdown/extensions/tables.py b/awx/lib/site-packages/markdown/extensions/tables.py index 57507e96d8..ad52ec11c7 100644 --- a/awx/lib/site-packages/markdown/extensions/tables.py +++ b/awx/lib/site-packages/markdown/extensions/tables.py @@ -4,15 +4,14 @@ Tables Extension for Python-Markdown Added parsing of tables to Python-Markdown. -SeeSome text with a WikiLink.
-All changes Copyright The Python Markdown Project +Whitespace behavior: + + >>> print markdown.markdown('[[ foo bar_baz ]]', ['wikilinks']) + + >>> print markdown.markdown('foo [[ ]] bar', ['wikilinks']) +foo bar
+ +To define custom settings the simple way: + + >>> print markdown.markdown(text, + ... ['wikilinks(base_url=/wiki/,end_url=.html,html_class=foo)'] + ... ) +Some text with a WikiLink.
+ +Custom settings the complex way: + + >>> md = markdown.Markdown( + ... extensions = ['wikilinks'], + ... extension_configs = {'wikilinks': [ + ... ('base_url', 'http://example.com/'), + ... ('end_url', '.html'), + ... ('html_class', '') ]}, + ... safe_mode = True) + >>> print md.convert(text) +Some text with a WikiLink.
+ +Use MetaData with mdx_meta.py (Note the blank html_class in MetaData): + + >>> text = """wiki_base_url: http://example.com/ + ... wiki_end_url: .html + ... wiki_html_class: + ... + ... Some text with a [[WikiLink]].""" + >>> md = markdown.Markdown(extensions=['meta', 'wikilinks']) + >>> print md.convert(text) +Some text with a WikiLink.
+ +MetaData should not carry over to next document: + + >>> print md.convert("No [[MetaData]] here.") +No MetaData here.
+ +Define a custom URL builder: + + >>> def my_url_builder(label, base, end): + ... return '/bar/' + >>> md = markdown.Markdown(extensions=['wikilinks'], + ... extension_configs={'wikilinks' : [('build_url', my_url_builder)]}) + >>> print md.convert('[[foo]]') + + +From the command line: + + python markdown.py -x wikilinks(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt + +By [Waylan Limberg](http://achinghead.com/). License: [BSD](http://www.opensource.org/licenses/bsd-license.php) +Dependencies: +* [Python 2.3+](http://python.org) +* [Markdown 2.0+](http://packages.python.org/Markdown/) ''' from __future__ import absolute_import @@ -29,17 +90,19 @@ def build_url(label, base, end): class WikiLinkExtension(Extension): - - def __init__ (self, *args, **kwargs): + def __init__(self, configs): + # set extension defaults self.config = { - 'base_url' : ['/', 'String to append to beginning or URL.'], - 'end_url' : ['/', 'String to append to end of URL.'], - 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'], - 'build_url' : [build_url, 'Callable formats URL from label.'], + 'base_url' : ['/', 'String to append to beginning or URL.'], + 'end_url' : ['/', 'String to append to end of URL.'], + 'html_class' : ['wikilink', 'CSS hook. Leave blank for none.'], + 'build_url' : [build_url, 'Callable formats URL from label.'], } + configs = dict(configs) or {} + # Override defaults with user settings + for key, value in configs.items(): + self.setConfig(key, value) - super(WikiLinkExtension, self).__init__(*args, **kwargs) - def extendMarkdown(self, md, md_globals): self.md = md @@ -84,5 +147,5 @@ class WikiLinks(Pattern): return base_url, end_url, html_class -def makeExtension(*args, **kwargs) : - return WikiLinkExtension(*args, **kwargs) +def makeExtension(configs=None) : + return WikiLinkExtension(configs=configs) diff --git a/awx/lib/site-packages/markdown/inlinepatterns.py b/awx/lib/site-packages/markdown/inlinepatterns.py index c9d82fdc75..9335748730 100644 --- a/awx/lib/site-packages/markdown/inlinepatterns.py +++ b/awx/lib/site-packages/markdown/inlinepatterns.py @@ -46,13 +46,13 @@ from __future__ import unicode_literals from . import util from . import odict import re -try: #pragma: no cover +try: from urllib.parse import urlparse, urlunparse -except ImportError: #pragma: no cover +except ImportError: from urlparse import urlparse, urlunparse -try: #pragma: no cover +try: from html import entities -except ImportError: #pragma: no cover +except ImportError: import htmlentitydefs as entities @@ -75,8 +75,7 @@ def build_inlinepatterns(md_instance, **kwargs): inlinePatterns["html"] = HtmlPattern(HTML_RE, md_instance) inlinePatterns["entity"] = HtmlPattern(ENTITY_RE, md_instance) inlinePatterns["not_strong"] = SimpleTextPattern(NOT_STRONG_RE) - inlinePatterns["em_strong"] = DoubleTagPattern(EM_STRONG_RE, 'strong,em') - inlinePatterns["strong_em"] = DoubleTagPattern(STRONG_EM_RE, 'em,strong') + inlinePatterns["strong_em"] = DoubleTagPattern(STRONG_EM_RE, 'strong,em') inlinePatterns["strong"] = SimpleTagPattern(STRONG_RE, 'strong') inlinePatterns["emphasis"] = SimpleTagPattern(EMPHASIS_RE, 'em') if md_instance.smart_emphasis: @@ -101,8 +100,7 @@ BACKTICK_RE = r'(?" in text: text = text.replace(">", ">") return text - except (TypeError, AttributeError): #pragma: no cover + except (TypeError, AttributeError): _raise_serialization_error(text) @@ -115,7 +115,7 @@ def _escape_attrib(text): if "\n" in text: text = text.replace("\n", " ") return text - except (TypeError, AttributeError): #pragma: no cover + except (TypeError, AttributeError): _raise_serialization_error(text) def _escape_attrib_html(text): @@ -130,7 +130,7 @@ def _escape_attrib_html(text): if "\"" in text: text = text.replace("\"", """) return text - except (TypeError, AttributeError): #pragma: no cover + except (TypeError, AttributeError): _raise_serialization_error(text) @@ -240,7 +240,7 @@ def _namespaces(elem, default_namespace=None): "default_namespace option" ) qnames[qname] = qname - except TypeError: #pragma: no cover + except TypeError: _raise_serialization_error(qname) # populate qname and namespaces table diff --git a/awx/lib/site-packages/markdown/treeprocessors.py b/awx/lib/site-packages/markdown/treeprocessors.py index 303e4600cd..ef0a2aa00c 100644 --- a/awx/lib/site-packages/markdown/treeprocessors.py +++ b/awx/lib/site-packages/markdown/treeprocessors.py @@ -34,11 +34,11 @@ class Treeprocessor(util.Processor): def run(self, root): """ Subclasses of Treeprocessor should implement a `run` method, which - takes a root ElementTree. This method can return another ElementTree - object, and the existing root ElementTree will be replaced, or it can + takes a root ElementTree. This method can return another ElementTree + object, and the existing root ElementTree will be replaced, or it can modify the current tree and return None. """ - pass #pragma: no cover + pass class InlineProcessor(Treeprocessor): @@ -53,7 +53,6 @@ class InlineProcessor(Treeprocessor): + len(self.__placeholder_suffix) self.__placeholder_re = util.INLINE_PLACEHOLDER_RE self.markdown = md - self.inlinePatterns = md.inlinePatterns def __makePlaceholder(self, type): """ Generate a placeholder """ @@ -71,7 +70,7 @@ class InlineProcessor(Treeprocessor): * index: index, from which we start search Returns: placeholder id and string index, after the found placeholder. - + """ m = self.__placeholder_re.search(data, index) if m: @@ -100,9 +99,9 @@ class InlineProcessor(Treeprocessor): """ if not isinstance(data, util.AtomicString): startIndex = 0 - while patternIndex < len(self.inlinePatterns): + while patternIndex < len(self.markdown.inlinePatterns): data, matched, startIndex = self.__applyPattern( - self.inlinePatterns.value_for_index(patternIndex), + self.markdown.inlinePatterns.value_for_index(patternIndex), data, patternIndex, startIndex) if not matched: patternIndex += 1 @@ -129,10 +128,11 @@ class InlineProcessor(Treeprocessor): text = subnode.tail subnode.tail = None - childResult = self.__processPlaceholders(text, subnode, isText) + childResult = self.__processPlaceholders(text, subnode) if not isText and node is not subnode: - pos = list(node).index(subnode) + 1 + pos = list(node).index(subnode) + node.remove(subnode) else: pos = 0 @@ -140,7 +140,7 @@ class InlineProcessor(Treeprocessor): for newChild in childResult: node.insert(pos, newChild) - def __processPlaceholders(self, data, parent, isText=True): + def __processPlaceholders(self, data, parent): """ Process string with placeholders and generate ElementTree tree. @@ -150,7 +150,7 @@ class InlineProcessor(Treeprocessor): * parent: Element, which contains processing inline data Returns: list with ElementTree elements with applied inline patterns. - + """ def linkText(text): if text: @@ -159,11 +159,6 @@ class InlineProcessor(Treeprocessor): result[-1].tail += text else: result[-1].tail = text - elif not isText: - if parent.tail: - parent.tail += text - else: - parent.tail = text else: if parent.text: parent.text += text @@ -187,7 +182,7 @@ class InlineProcessor(Treeprocessor): for child in [node] + list(node): if child.tail: if child.tail.strip(): - self.__processElementText(node, child, False) + self.__processElementText(node, child,False) if child.text: if child.text.strip(): self.__processElementText(child, child) @@ -244,7 +239,7 @@ class InlineProcessor(Treeprocessor): # We need to process current node too for child in [node] + list(node): if not isString(node): - if child.text: + if child.text: child.text = self.__handleInline(child.text, patternIndex + 1) if child.tail: @@ -292,10 +287,11 @@ class InlineProcessor(Treeprocessor): if child.tail: tail = self.__handleInline(child.tail) dumby = util.etree.Element('d') - child.tail = None - tailResult = self.__processPlaceholders(tail, dumby, False) - if dumby.tail: - child.tail = dumby.tail + tailResult = self.__processPlaceholders(tail, dumby) + if dumby.text: + child.tail = dumby.text + else: + child.tail = None pos = list(currElement).index(child) + 1 tailResult.reverse() for newChild in tailResult: @@ -307,7 +303,7 @@ class InlineProcessor(Treeprocessor): if self.markdown.enable_attributes: if element.text and isString(element.text): element.text = \ - inlinepatterns.handleAttributes(element.text, + inlinepatterns.handleAttributes(element.text, element) i = 0 for newChild in lst: @@ -361,4 +357,4 @@ class PrettifyTreeprocessor(Treeprocessor): pres = root.getiterator('pre') for pre in pres: if len(pre) and pre[0].tag == 'code': - pre[0].text = util.AtomicString(pre[0].text.rstrip() + '\n') + pre[0].text = pre[0].text.rstrip() + '\n' diff --git a/awx/lib/site-packages/markdown/util.py b/awx/lib/site-packages/markdown/util.py index 0541e7b409..edb25886ad 100644 --- a/awx/lib/site-packages/markdown/util.py +++ b/awx/lib/site-packages/markdown/util.py @@ -10,11 +10,11 @@ Python 3 Stuff """ PY3 = sys.version_info[0] == 3 -if PY3: #pragma: no cover +if PY3: string_type = str text_type = str int2str = chr -else: #pragma: no cover +else: string_type = basestring text_type = unicode int2str = unichr @@ -58,15 +58,14 @@ RTL_BIDI_RANGES = ( ('\u0590', '\u07FF'), # Extensions should use "markdown.util.etree" instead of "etree" (or do `from # markdown.util import etree`). Do not import it by yourself. -try: #pragma: no cover - # Is the C implementation of ElementTree available? +try: # Is the C implementation of ElementTree available? import xml.etree.cElementTree as etree from xml.etree.ElementTree import Comment # Serializers (including ours) test with non-c Comment etree.test_comment = Comment if etree.VERSION < "1.0.5": raise RuntimeError("cElementTree version 1.0.5 or higher is required.") -except (ImportError, RuntimeError): #pragma: no cover +except (ImportError, RuntimeError): # Use the Python implementation of ElementTree? import xml.etree.ElementTree as etree if etree.VERSION < "1.1": @@ -86,20 +85,15 @@ def isBlockLevel(tag): # Some ElementTree tags are not strings, so return False. return False -def parseBoolValue(value, fail_on_errors=True, preserve_none=False): +def parseBoolValue(value, fail_on_errors=True): """Parses a string representing bool value. If parsing was successful, - returns True or False. If preserve_none=True, returns True, False, - or None. If parsing was not successful, raises ValueError, or, if - fail_on_errors=False, returns None.""" + returns True or False. If parsing was not successful, raises + ValueError, or, if fail_on_errors=False, returns None.""" if not isinstance(value, string_type): - if preserve_none and value is None: - return value return bool(value) - elif preserve_none and value.lower() == 'none': - return None elif value.lower() in ('true', 'yes', 'y', 'on', '1'): return True - elif value.lower() in ('false', 'no', 'n', 'off', '0', 'none'): + elif value.lower() in ('false', 'no', 'n', 'off', '0'): return False elif fail_on_errors: raise ValueError('Cannot parse bool value: %r' % value)