diff options
-rw-r--r-- | markdown/blockprocessors.py | 37 | ||||
-rw-r--r-- | markdown/extensions/footnotes.py | 78 | ||||
-rw-r--r-- | tests/extensions/extra/footnote.html | 6 | ||||
-rw-r--r-- | tests/extensions/extra/footnote_placeholder.html | 3 | ||||
-rw-r--r-- | tests/extensions/extra/named_markers.html | 12 | ||||
-rw-r--r-- | tests/misc/para-with-hr.html | 5 | ||||
-rw-r--r-- | tests/misc/para-with-hr.txt | 3 |
7 files changed, 64 insertions, 80 deletions
diff --git a/markdown/blockprocessors.py b/markdown/blockprocessors.py index 7223da4..de3f136 100644 --- a/markdown/blockprocessors.py +++ b/markdown/blockprocessors.py @@ -460,35 +460,36 @@ class SetextHeaderProcessor(BlockProcessor): class HRProcessor(BlockProcessor): """ Process Horizontal Rules. """ - RE = r'[ ]{0,3}((-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,})[ ]*' + RE = r'^[ ]{0,3}((-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,})[ ]*' # Detect hr on any line of a block. - SEARCH_RE = re.compile(r'(^|\n)%s(\n|$)' % RE) - # Match a hr on a single line of text. - MATCH_RE = re.compile(r'^%s$' % RE) + SEARCH_RE = re.compile(RE, re.MULTILINE) def test(self, parent, block): - return bool(self.SEARCH_RE.search(block)) + m = self.SEARCH_RE.search(block) + # No atomic grouping in python so we simulate it here for performance. + # The regex only matches what would be in the atomic group - the HR. + # Then check if we are at end of block or if next char is a newline. + if m and (m.end() == len(block) or block[m.end()] == '\n'): + # Save match object on class instance so we can use it later. + self.match = m + return True + return False def run(self, parent, blocks): - lines = blocks.pop(0).split('\n') - prelines = [] + block = blocks.pop(0) # Check for lines in block before hr. - for line in lines: - m = self.MATCH_RE.match(line) - if m: - break - else: - prelines.append(line) - if len(prelines): + prelines = block[:self.match.start()].rstrip('\n') + if prelines: # Recursively parse lines before hr so they get parsed first. - self.parser.parseBlocks(parent, ['\n'.join(prelines)]) + self.parser.parseBlocks(parent, [prelines]) # create hr hr = util.etree.SubElement(parent, 'hr') # check for lines in block after hr. - lines = lines[len(prelines)+1:] - if len(lines): + postlines = block[self.match.end():].lstrip('\n') + if postlines: # Add lines after hr to master blocks for later parsing. - blocks.insert(0, '\n'.join(lines)) + blocks.insert(0, postlines) + class EmptyBlockProcessor(BlockProcessor): diff --git a/markdown/extensions/footnotes.py b/markdown/extensions/footnotes.py index 644e89f..d05edda 100644 --- a/markdown/extensions/footnotes.py +++ b/markdown/extensions/footnotes.py @@ -29,7 +29,7 @@ from markdown.util import etree FN_BACKLINK_TEXT = "zz1337820767766393qq" NBSP_PLACEHOLDER = "qq3936677670287331zz" -DEF_RE = re.compile(r'(\ ?\ ?\ ?)\[\^([^\]]*)\]:\s*(.*)') +DEF_RE = re.compile(r'[ ]{0,3}\[\^([^\]]*)\]:\s*(.*)') TABBED_RE = re.compile(r'((\t)|( ))(.*)') class FootnoteExtension(markdown.Extension): @@ -152,54 +152,33 @@ class FootnotePreprocessor(markdown.preprocessors.Preprocessor): self.footnotes = footnotes def run(self, lines): - lines = self._handleFootnoteDefinitions(lines) - text = "\n".join(lines) - return text.split("\n") - - def _handleFootnoteDefinitions(self, lines): """ - Recursively find all footnote definitions in lines. + Loop through lines and find, set, and remove footnote definitions. Keywords: * lines: A list of lines of text - - Return: A list of lines with footnote definitions removed. - - """ - i, id, footnote = self._findFootnoteDefinition(lines) - - if id : - plain = lines[:i] - detabbed, theRest = self.detectTabbed(lines[i+1:]) - self.footnotes.setFootnote(id, - footnote + "\n" - + "\n".join(detabbed)) - more_plain = self._handleFootnoteDefinitions(theRest) - return plain + [""] + more_plain - else : - return lines - - def _findFootnoteDefinition(self, lines): - """ - Find the parts of a footnote definition. - - Keywords: - * lines: A list of lines of text. + Return: A list of lines of text with footnote definitions removed. - Return: A three item tuple containing the index of the first line of a - footnote definition, the id of the definition and the body of the - definition. - """ - counter = 0 - for line in lines: - m = DEF_RE.match(line) + newlines = [] + i = 0 + #import pdb; pdb.set_trace() #for i, line in enumerate(lines): + while True: + m = DEF_RE.match(lines[i]) if m: - return counter, m.group(2), m.group(3) - counter += 1 - return counter, None, None + fn, _i = self.detectTabbed(lines[i+1:]) + fn.insert(0, m.group(2)) + i += _i-1 # skip past footnote + self.footnotes.setFootnote(m.group(1), "\n".join(fn)) + else: + newlines.append(lines[i]) + if len(lines) > i+1: + i += 1 + else: + break + return newlines def detectTabbed(self, lines): """ Find indented text and remove indent before further proccesing. @@ -208,12 +187,11 @@ class FootnotePreprocessor(markdown.preprocessors.Preprocessor): * lines: an array of strings - Returns: a list of post processed items and the unused - remainder of the original list + Returns: a list of post processed items and the index of last line. """ items = [] - item = -1 + blank_line = False # have we encountered a blank line yet? i = 0 # to keep track of where we are def detab(line): @@ -223,15 +201,21 @@ class FootnotePreprocessor(markdown.preprocessors.Preprocessor): for line in lines: if line.strip(): # Non-blank line - line = detab(line) - if line: + detabbed_line = detab(line) + if detabbed_line: + items.append(detabbed_line) + i += 1 + continue + elif not blank_line and not DEF_RE.match(line): + # not tabbed but still part of first par. items.append(line) i += 1 continue else: - return items, lines[i:] + return items, i+1 else: # Blank line: _maybe_ we are done. + blank_line = True i += 1 # advance # Find the next non-blank line @@ -250,7 +234,7 @@ class FootnotePreprocessor(markdown.preprocessors.Preprocessor): else: i += 1 - return items, lines[i:] + return items, i class FootnotePattern(markdown.inlinepatterns.Pattern): diff --git a/tests/extensions/extra/footnote.html b/tests/extensions/extra/footnote.html index d7d8b92..962967d 100644 --- a/tests/extensions/extra/footnote.html +++ b/tests/extensions/extra/footnote.html @@ -13,14 +13,12 @@ </li> <li id="fn:2"> <blockquote> -<p>This footnote is a blockquote. -</p> +<p>This footnote is a blockquote.</p> </blockquote> <p><a href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p> </li> <li id="fn:3"> -<p>A simple oneliner. - <a href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p> +<p>A simple oneliner. <a href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p> </li> <li id="fn:4"> <p>A footnote with multiple paragraphs.</p> diff --git a/tests/extensions/extra/footnote_placeholder.html b/tests/extensions/extra/footnote_placeholder.html index 7aaf4b2..9c89391 100644 --- a/tests/extensions/extra/footnote_placeholder.html +++ b/tests/extensions/extra/footnote_placeholder.html @@ -2,8 +2,7 @@ <hr /> <ol> <li id="fn:1"> -<p>A Footnote. - <a href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p> +<p>A Footnote. <a href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p> </li> </ol> </div> diff --git a/tests/extensions/extra/named_markers.html b/tests/extensions/extra/named_markers.html index 6996b5f..f643b7b 100644 --- a/tests/extensions/extra/named_markers.html +++ b/tests/extensions/extra/named_markers.html @@ -5,20 +5,16 @@ oddly<sup id="fnref:56"><a href="#fn:56" rel="footnote">3</a></sup> numbered<su <hr /> <ol> <li id="fn:foo"> -<p>Footnote marked <code>foo</code>. - <a href="#fnref:foo" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p> +<p>Footnote marked <code>foo</code>. <a href="#fnref:foo" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p> </li> <li id="fn:bar"> -<p>This one is marked <em>bar</em>. - <a href="#fnref:bar" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p> +<p>This one is marked <em>bar</em>. <a href="#fnref:bar" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p> </li> <li id="fn:56"> -<p>A <strong>numbered</strong> footnote. - <a href="#fnref:56" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p> +<p>A <strong>numbered</strong> footnote. <a href="#fnref:56" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p> </li> <li id="fn:99"> -<p>The last one. - <a href="#fnref:99" rev="footnote" title="Jump back to footnote 4 in the text">↩</a></p> +<p>The last one. <a href="#fnref:99" rev="footnote" title="Jump back to footnote 4 in the text">↩</a></p> </li> </ol> </div>
\ No newline at end of file diff --git a/tests/misc/para-with-hr.html b/tests/misc/para-with-hr.html index 8569fec..7607449 100644 --- a/tests/misc/para-with-hr.html +++ b/tests/misc/para-with-hr.html @@ -1,3 +1,6 @@ <p>Here is a paragraph, followed by a horizontal rule.</p> <hr /> -<p>Followed by another paragraph.</p>
\ No newline at end of file +<p>Followed by another paragraph.</p> +<p>Here is another paragraph, followed by: +*** not an HR. +Followed by more of the same paragraph.</p>
\ No newline at end of file diff --git a/tests/misc/para-with-hr.txt b/tests/misc/para-with-hr.txt index 20735fb..165bbe3 100644 --- a/tests/misc/para-with-hr.txt +++ b/tests/misc/para-with-hr.txt @@ -2,3 +2,6 @@ Here is a paragraph, followed by a horizontal rule. *** Followed by another paragraph. +Here is another paragraph, followed by: +*** not an HR. +Followed by more of the same paragraph. |