Skip to content

Commit

Permalink
Move isBlockLevel to class. (Python-Markdown#693)
Browse files Browse the repository at this point in the history
Allows users and/or extensions to alter the list of block level 
elements. The old implementation remains with a DeprecationWarning. 
Fixes Python-Markdown#575.
  • Loading branch information
waylan committed Jul 31, 2018
1 parent 7dad12c commit 1e7fd3f
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 31 deletions.
19 changes: 19 additions & 0 deletions markdown/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ class Markdown(object):
'xhtml': to_xhtml_string,
}

block_level_elements = [
# Elements which are invalid to wrap in a `<p>` tag.
# See http:https://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.
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 1 addition & 2 deletions markdown/extensions/attr_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from __future__ import unicode_literals
from . import Extension
from ..treeprocessors import Treeprocessor
from ..util import isBlockLevel
import re


Expand Down Expand Up @@ -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':
Expand Down
2 changes: 1 addition & 1 deletion markdown/postprocessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
6 changes: 3 additions & 3 deletions markdown/preprocessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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:
Expand Down
6 changes: 3 additions & 3 deletions markdown/treeprocessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 20 additions & 19 deletions markdown/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
=============================================================================
Expand Down
7 changes: 4 additions & 3 deletions tests/test_apis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. """
Expand All @@ -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),
Expand All @@ -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 <br> in tree has a new line tail """
Expand Down

0 comments on commit 1e7fd3f

Please sign in to comment.