diff --git a/markdown/core.py b/markdown/core.py index 98c925227..f2bd2fbdd 100644 --- a/markdown/core.py +++ b/markdown/core.py @@ -52,6 +52,18 @@ class Markdown(object): 'xhtml': to_xhtml_string, } + block_level_elements = [ + # Elements which are invalid to wrap in a `
` tag.
+ # See http://w3c.github.io/html/grouping-content.html#the-p-element
+ 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl',
+ 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3',
+ 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre',
+ 'section', 'table', 'ul',
+ # Other elements which Markdown should not be mucking up the contents of.
+ 'canvas', 'dd', 'dt', 'group', 'iframe', 'li', 'math', 'noscript', 'output',
+ 'progress', 'script', 'style', 'tbody', 'td', 'th', 'thead', 'tr', 'video'
+ ]
+
def __init__(self, **kwargs):
"""
Creates a new Markdown instance.
@@ -207,6 +219,13 @@ def set_output_format(self, format):
raise
return self
+ def is_block_level(self, tag):
+ """Check if the tag is a block level HTML tag."""
+ if isinstance(tag, util.string_type):
+ return tag.lower().rstrip('/') in self.block_level_elements
+ # Some ElementTree tags are not strings, so return False.
+ return False
+
def convert(self, source):
"""
Convert markdown to serialized XHTML or HTML.
diff --git a/markdown/extensions/attr_list.py b/markdown/extensions/attr_list.py
index 84b852d59..ab7d6b9da 100644
--- a/markdown/extensions/attr_list.py
+++ b/markdown/extensions/attr_list.py
@@ -21,7 +21,6 @@
from __future__ import unicode_literals
from . import Extension
from ..treeprocessors import Treeprocessor
-from ..util import isBlockLevel
import re
@@ -79,7 +78,7 @@ class AttrListTreeprocessor(Treeprocessor):
def run(self, doc):
for elem in doc.iter():
- if isBlockLevel(elem.tag):
+ if self.md.is_block_level(elem.tag):
# Block level: check for attrs on last line of text
RE = self.BLOCK_RE
if isheader(elem) or elem.tag == 'dt':
diff --git a/markdown/postprocessors.py b/markdown/postprocessors.py
index 541da5d94..cecb4ad08 100644
--- a/markdown/postprocessors.py
+++ b/markdown/postprocessors.py
@@ -91,7 +91,7 @@ def isblocklevel(self, html):
if m.group(1)[0] in ('!', '?', '@', '%'):
# Comment, php etc...
return True
- return util.isBlockLevel(m.group(1))
+ return self.md.is_block_level(m.group(1))
return False
diff --git a/markdown/preprocessors.py b/markdown/preprocessors.py
index 50537dd14..89f4baaab 100644
--- a/markdown/preprocessors.py
+++ b/markdown/preprocessors.py
@@ -235,11 +235,11 @@ def run(self, lines):
block)
# keep checking conditions below and maybe just append
- if data_index < len(block) and (util.isBlockLevel(left_tag) or left_tag == '--'):
+ if data_index < len(block) and (self.md.is_block_level(left_tag) or left_tag == '--'):
text.insert(0, block[data_index:])
block = block[:data_index]
- if not (util.isBlockLevel(left_tag) or block[1] in ["!", "?", "@", "%"]):
+ if not (self.md.is_block_level(left_tag) or block[1] in ["!", "?", "@", "%"]):
new_blocks.append(block)
continue
@@ -261,7 +261,7 @@ def run(self, lines):
else:
# if is block level tag and is not complete
if (not self._equal_tags(left_tag, right_tag)) and \
- (util.isBlockLevel(left_tag) or left_tag == "--"):
+ (self.md.is_block_level(left_tag) or left_tag == "--"):
items.append(block.strip())
in_tag = True
else:
diff --git a/markdown/treeprocessors.py b/markdown/treeprocessors.py
index 353826e89..5c2be2d0f 100644
--- a/markdown/treeprocessors.py
+++ b/markdown/treeprocessors.py
@@ -406,12 +406,12 @@ def _prettifyETree(self, elem):
""" Recursively add linebreaks to ElementTree children. """
i = "\n"
- if util.isBlockLevel(elem.tag) and elem.tag not in ['code', 'pre']:
+ if self.md.is_block_level(elem.tag) and elem.tag not in ['code', 'pre']:
if (not elem.text or not elem.text.strip()) \
- and len(elem) and util.isBlockLevel(elem[0].tag):
+ and len(elem) and self.md.is_block_level(elem[0].tag):
elem.text = i
for e in elem:
- if util.isBlockLevel(e.tag):
+ if self.md.is_block_level(e.tag):
self._prettifyETree(e)
if not elem.tail or not elem.tail.strip():
elem.tail = i
diff --git a/markdown/util.py b/markdown/util.py
index b40c01084..262521c88 100644
--- a/markdown/util.py
+++ b/markdown/util.py
@@ -113,6 +113,26 @@
"""
+def deprecated(message):
+ """
+ Raise a DeprecationWarning when wrapped function/method is called.
+
+ Borrowed from https://stackoverflow.com/a/48632082/866026
+ """
+ def deprecated_decorator(func):
+ @wraps(func)
+ def deprecated_func(*args, **kwargs):
+ warnings.warn(
+ "'{}' is deprecated. {}".format(func.__name__, message),
+ category=DeprecationWarning,
+ stacklevel=2
+ )
+ return func(*args, **kwargs)
+ return deprecated_func
+ return deprecated_decorator
+
+
+@deprecated("Use 'Markdown.is_block_level' instead.")
def isBlockLevel(tag):
"""Check if the tag is a block level HTML tag."""
if isinstance(tag, string_type):
@@ -151,25 +171,6 @@ def code_escape(text):
return text
-def deprecated(message):
- """
- Raise a DeprecationWarning when wrapped function/method is called.
-
- Borrowed from https://stackoverflow.com/a/48632082/866026
- """
- def deprecated_decorator(func):
- @wraps(func)
- def deprecated_func(*args, **kwargs):
- warnings.warn(
- "'{}' is deprecated. {}".format(func.__name__, message),
- category=DeprecationWarning,
- stacklevel=2
- )
- return func(*args, **kwargs)
- return deprecated_func
- return deprecated_decorator
-
-
"""
MISC AUXILIARY CLASSES
=============================================================================
diff --git a/tests/test_apis.py b/tests/test_apis.py
index 834299b7c..71a85559b 100644
--- a/tests/test_apis.py
+++ b/tests/test_apis.py
@@ -510,7 +510,8 @@ def testCommentIsComment(self):
def testCommentIsBlockLevel(self):
""" Test that an ElementTree Comment is recognized as BlockLevel. """
- self.assertFalse(markdown.util.isBlockLevel(self.comment.tag))
+ md = markdown.Markdown()
+ self.assertFalse(md.is_block_level(self.comment.tag))
def testCommentSerialization(self):
""" Test that an ElementTree Comment serializes properly. """
@@ -521,7 +522,7 @@ def testCommentSerialization(self):
def testCommentPrettify(self):
""" Test that an ElementTree Comment is prettified properly. """
- pretty = markdown.treeprocessors.PrettifyTreeprocessor()
+ pretty = markdown.treeprocessors.PrettifyTreeprocessor(markdown.Markdown())
pretty.run(self.comment)
self.assertEqual(
markdown.serializers.to_html_string(self.comment),
@@ -532,7 +533,7 @@ def testCommentPrettify(self):
class testElementTailTests(unittest.TestCase):
""" Element Tail Tests """
def setUp(self):
- self.pretty = markdown.treeprocessors.PrettifyTreeprocessor()
+ self.pretty = markdown.treeprocessors.PrettifyTreeprocessor(markdown.Markdown())
def testBrTailNoNewline(self):
""" Test that last
in tree has a new line tail """