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" |