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('
Header 1\n'
             '

Header 2

' ) - self.assertTrue(md.toc.startswith('
')) + self.assertStartsWith('
', md.toc) def testReset(self): """ Test TOC Reset. """ self.assertEqual(self.md.toc, '') self.md.convert('# Header 1\n\n## Header 2') - self.assertTrue(self.md.toc.startswith('
')) + self.assertStartsWith('
', self.md.toc) self.md.reset() self.assertEqual(self.md.toc, '') @@ -771,7 +781,10 @@ def testTitle(self): extensions=[markdown.extensions.toc.TocExtension(title='Table of Contents')] ) md.convert('# Header 1\n\n## Header 2') - self.assertTrue(md.toc.startswith('
Table of Contents
    ')) + self.assertStartsWith( + '
    Table of Contents
      ', + md.toc + ) def testWithAttrList(self): """ Test TOC with attr_list Extension. """