diff options
-rw-r--r-- | markdown/extensions/md_in_html.py | 12 | ||||
-rw-r--r-- | markdown/postprocessors.py | 6 | ||||
-rw-r--r-- | tests/test_syntax/extensions/test_md_in_html.py | 17 |
3 files changed, 33 insertions, 2 deletions
diff --git a/markdown/extensions/md_in_html.py b/markdown/extensions/md_in_html.py index 3518d05..174224a 100644 --- a/markdown/extensions/md_in_html.py +++ b/markdown/extensions/md_in_html.py @@ -17,6 +17,7 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) from . import Extension from ..blockprocessors import BlockProcessor from ..preprocessors import Preprocessor +from ..postprocessors import RawHtmlPostprocessor from .. import util from ..htmlparser import HTMLExtractor import xml.etree.ElementTree as etree @@ -263,6 +264,15 @@ class MarkdownInHtmlProcessor(BlockProcessor): return False +class MarkdownInHTMLPostprocessor(RawHtmlPostprocessor): + def stash_to_string(self, text): + """ Override default to handle any etree elements still in the stash. """ + if isinstance(text, etree.Element): + return self.md.serializer(text) + else: + return str(text) + + class MarkdownInHtmlExtension(Extension): """Add Markdown parsing in HTML to Markdown class.""" @@ -275,6 +285,8 @@ class MarkdownInHtmlExtension(Extension): md.parser.blockprocessors.register( MarkdownInHtmlProcessor(md.parser), 'markdown_block', 105 ) + # Replace raw HTML postprocessor + md.postprocessors.register(MarkdownInHTMLPostprocessor(md), 'raw_html', 30) def makeExtension(**kwargs): # pragma: no cover diff --git a/markdown/postprocessors.py b/markdown/postprocessors.py index cd32687..2e68cd9 100644 --- a/markdown/postprocessors.py +++ b/markdown/postprocessors.py @@ -69,7 +69,7 @@ class RawHtmlPostprocessor(Postprocessor): """ Iterate over html stash and restore html. """ replacements = OrderedDict() for i in range(self.md.htmlStash.html_counter): - html = self.md.htmlStash.rawHtmlBlocks[i] + html = self.stash_to_string(self.md.htmlStash.rawHtmlBlocks[i]) if self.isblocklevel(html): replacements["<p>{}</p>".format( self.md.htmlStash.get_placeholder(i))] = html @@ -95,6 +95,10 @@ class RawHtmlPostprocessor(Postprocessor): return self.md.is_block_level(m.group(1)) return False + def stash_to_string(self, text): + """ Convert a stashed object to a string. """ + return str(text) + class AndSubstitutePostprocessor(Postprocessor): """ Restore valid entities """ diff --git a/tests/test_syntax/extensions/test_md_in_html.py b/tests/test_syntax/extensions/test_md_in_html.py index b68412c..433cdd5 100644 --- a/tests/test_syntax/extensions/test_md_in_html.py +++ b/tests/test_syntax/extensions/test_md_in_html.py @@ -23,6 +23,21 @@ License: BSD (see LICENSE.md for details). from unittest import TestSuite from markdown.test_tools import TestCase from ..blocks.test_html_blocks import TestHTMLBlocks +from markdown import Markdown +from xml.etree.ElementTree import Element + + +class TestMarkdownInHTMLPostProcessor(TestCase): + """ Ensure any remaining elements in HTML stash are properly serialized. """ + + def test_stash_to_string(self): + # There should be no known cases where this actually happens so we need to + # forcefully pass an etree Element to the method to ensure proper behavior. + element = Element('div') + element.text = 'Foo bar.' + md = Markdown(extensions=['md_in_html']) + result = md.postprocessors['raw_html'].stash_to_string(element) + self.assertEqual(result, '<div>Foo bar.</div>') class TestDefaultwMdInHTML(TestHTMLBlocks): @@ -758,7 +773,7 @@ class TestMdInHTML(TestCase): def load_tests(loader, tests, pattern): ''' Ensure TestHTMLBlocks doesn't get run twice by excluding it here. ''' suite = TestSuite() - for test_class in [TestDefaultwMdInHTML, TestMdInHTML]: + for test_class in [TestDefaultwMdInHTML, TestMdInHTML, TestMarkdownInHTMLPostProcessor]: tests = loader.loadTestsFromTestCase(test_class) suite.addTests(tests) return suite |