| Index: third_party/Python-Markdown/markdown/preprocessors.py
|
| diff --git a/third_party/markdown/preprocessors.py b/third_party/Python-Markdown/markdown/preprocessors.py
|
| similarity index 62%
|
| copy from third_party/markdown/preprocessors.py
|
| copy to third_party/Python-Markdown/markdown/preprocessors.py
|
| index 3f1cfe7777fbacde0ae2a68ac910e343426e9fb7..7fd38d331fb5685a4c06f23e646c9d4d40e69b8b 100644
|
| --- a/third_party/markdown/preprocessors.py
|
| +++ b/third_party/Python-Markdown/markdown/preprocessors.py
|
| @@ -1,41 +1,9 @@
|
| -# markdown is released under the BSD license
|
| -# Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later)
|
| -# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
|
| -# Copyright 2004 Manfred Stienstra (the original version)
|
| -#
|
| -# All rights reserved.
|
| -#
|
| -# Redistribution and use in source and binary forms, with or without
|
| -# modification, are permitted provided that the following conditions are met:
|
| -#
|
| -# * Redistributions of source code must retain the above copyright
|
| -# notice, this list of conditions and the following disclaimer.
|
| -# * Redistributions in binary form must reproduce the above copyright
|
| -# notice, this list of conditions and the following disclaimer in the
|
| -# documentation and/or other materials provided with the distribution.
|
| -# * Neither the name of the <organization> nor the
|
| -# names of its contributors may be used to endorse or promote products
|
| -# derived from this software without specific prior written permission.
|
| -#
|
| -# THIS SOFTWARE IS PROVIDED BY THE PYTHON MARKDOWN PROJECT ''AS IS'' AND ANY
|
| -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| -# DISCLAIMED. IN NO EVENT SHALL ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT
|
| -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
| -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
| -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
| -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
| -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
| -# POSSIBILITY OF SUCH DAMAGE.
|
| -
|
| -
|
| """
|
| PRE-PROCESSORS
|
| =============================================================================
|
|
|
| Preprocessors work on source text before we start doing anything too
|
| -complicated.
|
| +complicated.
|
| """
|
|
|
| from __future__ import absolute_import
|
| @@ -73,7 +41,7 @@ class Preprocessor(util.Processor):
|
| the (possibly modified) list of lines.
|
|
|
| """
|
| - pass
|
| + pass # pragma: no cover
|
|
|
|
|
| class NormalizeWhitespace(Preprocessor):
|
| @@ -93,13 +61,14 @@ class HtmlBlockPreprocessor(Preprocessor):
|
|
|
| right_tag_patterns = ["</%s>", "%s>"]
|
| attrs_pattern = r"""
|
| - \s+(?P<attr>[^>"'/= ]+)=(?P<q>['"])(?P<value>.*?)(?P=q) # attr="value"
|
| - | # OR
|
| - \s+(?P<attr1>[^>"'/= ]+)=(?P<value1>[^> ]+) # attr=value
|
| - | # OR
|
| - \s+(?P<attr2>[^>"'/= ]+) # attr
|
| + \s+(?P<attr>[^>"'/= ]+)=(?P<q>['"])(?P<value>.*?)(?P=q) # attr="value"
|
| + | # OR
|
| + \s+(?P<attr1>[^>"'/= ]+)=(?P<value1>[^> ]+) # attr=value
|
| + | # OR
|
| + \s+(?P<attr2>[^>"'/= ]+) # attr
|
| """
|
| - left_tag_pattern = r'^\<(?P<tag>[^> ]+)(?P<attrs>(%s)*)\s*\/?\>?' % attrs_pattern
|
| + left_tag_pattern = r'^\<(?P<tag>[^> ]+)(?P<attrs>(%s)*)\s*\/?\>?' % \
|
| + attrs_pattern
|
| attrs_re = re.compile(attrs_pattern, re.VERBOSE)
|
| left_tag_re = re.compile(left_tag_pattern, re.VERBOSE)
|
| markdown_in_raw = False
|
| @@ -119,7 +88,9 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| attrs[ma.group('attr').strip()] = ""
|
| elif ma.group('attr1'):
|
| if ma.group('value1'):
|
| - attrs[ma.group('attr1').strip()] = ma.group('value1')
|
| + attrs[ma.group('attr1').strip()] = ma.group(
|
| + 'value1'
|
| + )
|
| else:
|
| attrs[ma.group('attr1').strip()] = ""
|
| elif ma.group('attr2'):
|
| @@ -134,7 +105,7 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| i = block.find(rtag, start_index)
|
| if i == -1:
|
| return -1
|
| - j = block.find(ltag, start_index)
|
| + j = block.find(ltag, start_index)
|
| # if no ltag, or rtag found before another ltag, return index
|
| if (j > i or j == -1):
|
| return i + len(rtag)
|
| @@ -143,27 +114,28 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| j = block.find('>', j)
|
| start_index = self._recursive_tagfind(ltag, rtag, j + 1, block)
|
| if start_index == -1:
|
| - # HTML potentially malformed- ltag has no corresponding
|
| + # HTML potentially malformed- ltag has no corresponding
|
| # rtag
|
| return -1
|
|
|
| def _get_right_tag(self, left_tag, left_index, block):
|
| for p in self.right_tag_patterns:
|
| tag = p % left_tag
|
| - i = self._recursive_tagfind("<%s" % left_tag, tag, left_index, block)
|
| + i = self._recursive_tagfind(
|
| + "<%s" % left_tag, tag, left_index, block
|
| + )
|
| if i > 2:
|
| return tag.lstrip("<").rstrip(">"), i
|
| return block.rstrip()[-left_index:-1].lower(), len(block)
|
| -
|
| +
|
| def _equal_tags(self, left_tag, right_tag):
|
| - if left_tag[0] in ['?', '@', '%']: # handle PHP, etc.
|
| + if left_tag[0] in ['?', '@', '%']: # handle PHP, etc.
|
| return True
|
| if ("/" + left_tag) == right_tag:
|
| return True
|
| if (right_tag == "--" and left_tag == "--"):
|
| return True
|
| - elif left_tag == right_tag[1:] \
|
| - and right_tag[0] == "/":
|
| + elif left_tag == right_tag[1:] and right_tag[0] == "/":
|
| return True
|
| else:
|
| return False
|
| @@ -171,6 +143,48 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| def _is_oneliner(self, tag):
|
| return (tag in ['hr', 'hr/'])
|
|
|
| + def _stringindex_to_listindex(self, stringindex, items):
|
| + """
|
| + Same effect as concatenating the strings in items,
|
| + finding the character to which stringindex refers in that string,
|
| + and returning the index of the item in which that character resides.
|
| + """
|
| + items.append('dummy')
|
| + i, count = 0, 0
|
| + while count <= stringindex:
|
| + count += len(items[i])
|
| + i += 1
|
| + return i - 1
|
| +
|
| + def _nested_markdown_in_html(self, items):
|
| + """Find and process html child elements of the given element block."""
|
| + for i, item in enumerate(items):
|
| + if self.left_tag_re.match(item):
|
| + left_tag, left_index, attrs = \
|
| + self._get_left_tag(''.join(items[i:]))
|
| + right_tag, data_index = self._get_right_tag(
|
| + left_tag, left_index, ''.join(items[i:]))
|
| + right_listindex = \
|
| + self._stringindex_to_listindex(data_index, items[i:]) + i
|
| + if 'markdown' in attrs.keys():
|
| + items[i] = items[i][left_index:] # remove opening tag
|
| + placeholder = self.markdown.htmlStash.store_tag(
|
| + left_tag, attrs, i + 1, right_listindex + 1)
|
| + items.insert(i, placeholder)
|
| + if len(items) - right_listindex <= 1: # last nest, no tail
|
| + right_listindex -= 1
|
| + items[right_listindex] = items[right_listindex][
|
| + :-len(right_tag) - 2] # remove closing tag
|
| + else: # raw html
|
| + if len(items) - right_listindex <= 1: # last element
|
| + right_listindex -= 1
|
| + offset = 1 if i == right_listindex else 0
|
| + placeholder = self.markdown.htmlStash.store('\n\n'.join(
|
| + items[i:right_listindex + offset]))
|
| + del items[i:right_listindex + offset]
|
| + items.insert(i, placeholder)
|
| + return items
|
| +
|
| def run(self, lines):
|
| text = "\n".join(lines)
|
| new_blocks = []
|
| @@ -178,7 +192,7 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| items = []
|
| left_tag = ''
|
| right_tag = ''
|
| - in_tag = False # flag
|
| + in_tag = False # flag
|
|
|
| while text:
|
| block = text[0]
|
| @@ -192,24 +206,21 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| if not in_tag:
|
| if block.startswith("<") and len(block.strip()) > 1:
|
|
|
| - if block[1] == "!":
|
| + if block[1:4] == "!--":
|
| # is a comment block
|
| - left_tag, left_index, attrs = "--", 2, {}
|
| + left_tag, left_index, attrs = "--", 2, {}
|
| else:
|
| left_tag, left_index, attrs = self._get_left_tag(block)
|
| - right_tag, data_index = self._get_right_tag(left_tag,
|
| + right_tag, data_index = self._get_right_tag(left_tag,
|
| left_index,
|
| block)
|
| # keep checking conditions below and maybe just append
|
| -
|
| - if data_index < len(block) \
|
| - and (util.isBlockLevel(left_tag)
|
| - or left_tag == '--'):
|
| +
|
| + if data_index < len(block) and (util.isBlockLevel(left_tag) or left_tag == '--'):
|
| text.insert(0, block[data_index:])
|
| block = block[:data_index]
|
|
|
| - if not (util.isBlockLevel(left_tag) \
|
| - or block[1] in ["!", "?", "@", "%"]):
|
| + if not (util.isBlockLevel(left_tag) or block[1] in ["!", "?", "@", "%"]):
|
| new_blocks.append(block)
|
| continue
|
|
|
| @@ -218,35 +229,30 @@ class HtmlBlockPreprocessor(Preprocessor):
|
| continue
|
|
|
| if block.rstrip().endswith(">") \
|
| - and self._equal_tags(left_tag, right_tag):
|
| + and self._equal_tags(left_tag, right_tag):
|
| if self.markdown_in_raw and 'markdown' in attrs.keys():
|
| - start = re.sub(r'\smarkdown(=[\'"]?[^> ]*[\'"]?)?',
|
| - '', block[:left_index])
|
| - end = block[-len(right_tag)-2:]
|
| - block = block[left_index:-len(right_tag)-2]
|
| - new_blocks.append(
|
| - self.markdown.htmlStash.store(start))
|
| - new_blocks.append(block)
|
| - new_blocks.append(
|
| - self.markdown.htmlStash.store(end))
|
| + block = block[left_index:-len(right_tag) - 2]
|
| + new_blocks.append(self.markdown.htmlStash.
|
| + store_tag(left_tag, attrs, 0, 2))
|
| + new_blocks.extend([block])
|
| else:
|
| new_blocks.append(
|
| self.markdown.htmlStash.store(block.strip()))
|
| continue
|
| - else:
|
| + else:
|
| # if is block level tag and is not complete
|
| -
|
| - if util.isBlockLevel(left_tag) or left_tag == "--" \
|
| - and not block.rstrip().endswith(">"):
|
| + if (not self._equal_tags(left_tag, right_tag)) and \
|
| + (util.isBlockLevel(left_tag) or left_tag == "--"):
|
| items.append(block.strip())
|
| in_tag = True
|
| else:
|
| new_blocks.append(
|
| - self.markdown.htmlStash.store(block.strip()))
|
| -
|
| + self.markdown.htmlStash.store(block.strip())
|
| + )
|
| continue
|
|
|
| - new_blocks.append(block)
|
| + else:
|
| + new_blocks.append(block)
|
|
|
| else:
|
| items.append(block)
|
| @@ -255,7 +261,7 @@ class HtmlBlockPreprocessor(Preprocessor):
|
|
|
| if self._equal_tags(left_tag, right_tag):
|
| # if find closing tag
|
| -
|
| +
|
| if data_index < len(block):
|
| # we have more text after right_tag
|
| items[-1] = block[:data_index]
|
| @@ -263,16 +269,21 @@ class HtmlBlockPreprocessor(Preprocessor):
|
|
|
| in_tag = False
|
| if self.markdown_in_raw and 'markdown' in attrs.keys():
|
| - start = re.sub(r'\smarkdown(=[\'"]?[^> ]*[\'"]?)?',
|
| - '', items[0][:left_index])
|
| items[0] = items[0][left_index:]
|
| - end = items[-1][-len(right_tag)-2:]
|
| - items[-1] = items[-1][:-len(right_tag)-2]
|
| - new_blocks.append(
|
| - self.markdown.htmlStash.store(start))
|
| - new_blocks.extend(items)
|
| - new_blocks.append(
|
| - self.markdown.htmlStash.store(end))
|
| + items[-1] = items[-1][:-len(right_tag) - 2]
|
| + if items[len(items) - 1]: # not a newline/empty string
|
| + right_index = len(items) + 3
|
| + else:
|
| + right_index = len(items) + 2
|
| + new_blocks.append(self.markdown.htmlStash.store_tag(
|
| + left_tag, attrs, 0, right_index))
|
| + placeholderslen = len(self.markdown.htmlStash.tag_data)
|
| + new_blocks.extend(
|
| + self._nested_markdown_in_html(items))
|
| + nests = len(self.markdown.htmlStash.tag_data) - \
|
| + placeholderslen
|
| + self.markdown.htmlStash.tag_data[-1 - nests][
|
| + 'right_index'] += nests - 2
|
| else:
|
| new_blocks.append(
|
| self.markdown.htmlStash.store('\n\n'.join(items)))
|
| @@ -280,21 +291,23 @@ class HtmlBlockPreprocessor(Preprocessor):
|
|
|
| if items:
|
| if self.markdown_in_raw and 'markdown' in attrs.keys():
|
| - start = re.sub(r'\smarkdown(=[\'"]?[^> ]*[\'"]?)?',
|
| - '', items[0][:left_index])
|
| items[0] = items[0][left_index:]
|
| - end = items[-1][-len(right_tag)-2:]
|
| - items[-1] = items[-1][:-len(right_tag)-2]
|
| + items[-1] = items[-1][:-len(right_tag) - 2]
|
| + if items[len(items) - 1]: # not a newline/empty string
|
| + right_index = len(items) + 3
|
| + else:
|
| + right_index = len(items) + 2
|
| new_blocks.append(
|
| - self.markdown.htmlStash.store(start))
|
| - new_blocks.extend(items)
|
| - if end.strip():
|
| - new_blocks.append(
|
| - self.markdown.htmlStash.store(end))
|
| + self.markdown.htmlStash.store_tag(
|
| + left_tag, attrs, 0, right_index))
|
| + placeholderslen = len(self.markdown.htmlStash.tag_data)
|
| + new_blocks.extend(self._nested_markdown_in_html(items))
|
| + nests = len(self.markdown.htmlStash.tag_data) - placeholderslen
|
| + self.markdown.htmlStash.tag_data[-1 - nests][
|
| + 'right_index'] += nests - 2
|
| else:
|
| new_blocks.append(
|
| self.markdown.htmlStash.store('\n\n'.join(items)))
|
| - #new_blocks.append(self.markdown.htmlStash.store('\n\n'.join(items)))
|
| new_blocks.append('\n')
|
|
|
| new_text = "\n\n".join(new_blocks)
|
| @@ -305,11 +318,13 @@ class ReferencePreprocessor(Preprocessor):
|
| """ Remove reference definitions from text and store for later use. """
|
|
|
| TITLE = r'[ ]*(\"(.*)\"|\'(.*)\'|\((.*)\))[ ]*'
|
| - RE = re.compile(r'^[ ]{0,3}\[([^\]]*)\]:\s*([^ ]*)[ ]*(%s)?$' % TITLE, re.DOTALL)
|
| + RE = re.compile(
|
| + r'^[ ]{0,3}\[([^\]]*)\]:\s*([^ ]*)[ ]*(%s)?$' % TITLE, re.DOTALL
|
| + )
|
| TITLE_RE = re.compile(r'^%s$' % TITLE)
|
|
|
| - def run (self, lines):
|
| - new_text = [];
|
| + def run(self, lines):
|
| + new_text = []
|
| while lines:
|
| line = lines.pop(0)
|
| m = self.RE.match(line)
|
| @@ -327,4 +342,4 @@ class ReferencePreprocessor(Preprocessor):
|
| else:
|
| new_text.append(line)
|
|
|
| - return new_text #+ "\n"
|
| + return new_text # + "\n"
|
|
|