diff --git a/markdown/postprocessors.py b/markdown/postprocessors.py
index 2d4dcb589..8b311b268 100644
--- a/markdown/postprocessors.py
+++ b/markdown/postprocessors.py
@@ -10,6 +10,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
+from collections import OrderedDict
from . import util
from . import odict
import re
@@ -50,6 +51,7 @@ class RawHtmlPostprocessor(Postprocessor):
def run(self, text):
""" Iterate over html stash and restore "safe" html. """
+ replacements = OrderedDict()
for i in range(self.markdown.htmlStash.html_counter):
html, safe = self.markdown.htmlStash.rawHtmlBlocks[i]
if self.markdown.safeMode and not safe:
@@ -61,14 +63,15 @@ def run(self, text):
html = self.markdown.html_replacement_text
if (self.isblocklevel(html) and
(safe or not self.markdown.safeMode)):
- text = text.replace(
- "
%s
" %
- (self.markdown.htmlStash.get_placeholder(i)),
+ replacements["%s
" %
+ (self.markdown.htmlStash.get_placeholder(i))] = \
html + "\n"
- )
- text = text.replace(
- self.markdown.htmlStash.get_placeholder(i), html
- )
+ replacements[self.markdown.htmlStash.get_placeholder(i)] = html
+
+ if replacements:
+ pattern = re.compile("|".join(re.escape(k) for k in replacements))
+ text = pattern.sub(lambda m: replacements[m.group(0)], text)
+
return text
def escape(self, html):
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
index 72ce21256..30b21bb50 100644
--- a/tests/test_extensions.py
+++ b/tests/test_extensions.py
@@ -12,6 +12,17 @@
import markdown
+class TestCaseWithAssertStartsWith(unittest.TestCase):
+
+ def assertStartsWith(self, expectedPrefix, text, msg=None):
+ if not text.startswith(expectedPrefix):
+ if len(expectedPrefix) + 5 < len(text):
+ text = text[:len(expectedPrefix) + 5] + '...'
+ standardMsg = '%s not found at the start of %s' % (repr(expectedPrefix),
+ repr(text))
+ self.fail(self._formatMessage(msg, standardMsg))
+
+
class TestExtensionClass(unittest.TestCase):
""" Test markdown.extensions.Extension. """
@@ -86,7 +97,7 @@ def testNestedAbbr(self):
)
-class TestCodeHilite(unittest.TestCase):
+class TestCodeHilite(TestCaseWithAssertStartsWith):
""" Test codehilite extension. """
def setUp(self):
@@ -101,7 +112,7 @@ def testBasicCodeHilite(self):
md = markdown.Markdown(extensions=['markdown.extensions.codehilite'])
if self.has_pygments:
# Pygments can use random lexer here as we did not specify the language
- self.assertTrue(md.convert(text).startswith(''))
+ self.assertStartsWith('', md.convert(text))
else:
self.assertEqual(
md.convert(text),
@@ -117,10 +128,9 @@ def testLinenumsTrue(self):
# Different versions of pygments output slightly different markup.
# So we use 'startwith' and test just enough to confirm that
# pygments received and processed linenums.
- self.assertTrue(
- md.convert(text).startswith(
- '
'
- )
+ self.assertStartsWith(
+ '',
+ md.convert(text)
)
else:
self.assertEqual(
@@ -134,7 +144,7 @@ def testLinenumsFalse(self):
md = markdown.Markdown(
extensions=[markdown.extensions.codehilite.CodeHiliteExtension(linenums=False)])
if self.has_pygments:
- self.assertTrue(md.convert(text).startswith(''))
+ self.assertStartsWith('', md.convert(text))
else:
self.assertEqual(
md.convert(text),
@@ -164,10 +174,9 @@ def testLinenumsNoneWithShebang(self):
# Differant versions of pygments output slightly different markup.
# So we use 'startwith' and test just enough to confirm that
# pygments received and processed linenums.
- self.assertTrue(
- md.convert(text).startswith(
- ' '
- )
+ self.assertStartsWith(
+ '',
+ md.convert(text)
)
else:
self.assertEqual(
@@ -182,7 +191,7 @@ def testLinenumsNoneWithColon(self):
extensions=[markdown.extensions.codehilite.CodeHiliteExtension(linenums=None)]
)
if self.has_pygments:
- self.assertTrue(md.convert(text).startswith(' |
|
|
|