aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--markdown/blockprocessors.py37
-rw-r--r--markdown/extensions/footnotes.py78
-rw-r--r--tests/extensions/extra/footnote.html6
-rw-r--r--tests/extensions/extra/footnote_placeholder.html3
-rw-r--r--tests/extensions/extra/named_markers.html12
-rw-r--r--tests/misc/para-with-hr.html5
-rw-r--r--tests/misc/para-with-hr.txt3
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">&#8617;</a></p>
</li>
<li id="fn:3">
-<p>A simple oneliner.
-&#160;<a href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">&#8617;</a></p>
+<p>A simple oneliner.&#160;<a href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">&#8617;</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.
-&#160;<a href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
+<p>A Footnote.&#160;<a href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</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>.
-&#160;<a href="#fnref:foo" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
+<p>Footnote marked <code>foo</code>.&#160;<a href="#fnref:foo" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:bar">
-<p>This one is marked <em>bar</em>.
-&#160;<a href="#fnref:bar" rev="footnote" title="Jump back to footnote 2 in the text">&#8617;</a></p>
+<p>This one is marked <em>bar</em>.&#160;<a href="#fnref:bar" rev="footnote" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
<li id="fn:56">
-<p>A <strong>numbered</strong> footnote.
-&#160;<a href="#fnref:56" rev="footnote" title="Jump back to footnote 3 in the text">&#8617;</a></p>
+<p>A <strong>numbered</strong> footnote.&#160;<a href="#fnref:56" rev="footnote" title="Jump back to footnote 3 in the text">&#8617;</a></p>
</li>
<li id="fn:99">
-<p>The last one.
-&#160;<a href="#fnref:99" rev="footnote" title="Jump back to footnote 4 in the text">&#8617;</a></p>
+<p>The last one.&#160;<a href="#fnref:99" rev="footnote" title="Jump back to footnote 4 in the text">&#8617;</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.