diff --git a/markdown/core.py b/markdown/core.py
index 370cb7ec..5b6c1eea 100644
--- a/markdown/core.py
+++ b/markdown/core.py
@@ -303,12 +303,15 @@ def is_block_level(self, tag: Any) -> bool:
"""
Check if the given `tag` is a block level HTML tag.
- Returns `True` for any string listed in `Markdown.block_level_elements`. A `tag` which is
- not a string always returns `False`.
+ Returns `True` for any string listed in `Markdown.block_level_elements`.
+ Also returns `True` for valid custom element names (tag names that contain
+ a hyphen; see https://html.spec.whatwg.org/#valid-custom-element-name).
+ A `tag` which is not a string always returns `False`.
"""
if isinstance(tag, str):
- return tag.lower().rstrip('/') in self.block_level_elements
+ tag = tag.lower().rstrip('/')
+ return tag in self.block_level_elements or '-' in tag
# Some ElementTree tags are not strings, so return False.
return False
diff --git a/markdown/extensions/md_in_html.py b/markdown/extensions/md_in_html.py
index 32a9c11a..7c36790c 100644
--- a/markdown/extensions/md_in_html.py
+++ b/markdown/extensions/md_in_html.py
@@ -34,6 +34,17 @@
from markdown import Markdown
+class _BlockLevelTagSet(set):
+ """A set of block-level tags that also treats custom element names as members.
+
+ Custom elements are required to contain a hyphen in their names.
+ See https://html.spec.whatwg.org/#valid-custom-element-name.
+ """
+
+ def __contains__(self, item: object) -> bool:
+ return super().__contains__(item) or (isinstance(item, str) and '-' in item)
+
+
class HTMLExtractorExtra(HTMLExtractor):
"""
Override `HTMLExtractor` and create `etree` `Elements` for any elements which should have content parsed as
@@ -52,9 +63,13 @@ def __init__(self, md: Markdown, *args, **kwargs):
super().__init__(md, *args, **kwargs)
- # Block-level tags in which the content gets parsed as blocks
- self.block_tags = set(self.block_level_tags) - (self.span_tags | self.raw_tags | self.empty_tags)
- self.span_and_blocks_tags = self.block_tags | self.span_tags
+ # Block-level tags in which the content gets parsed as blocks.
+ # Custom element names (tags with a hyphen) are treated as block-level.
+ self.block_level_tags = _BlockLevelTagSet(self.block_level_tags)
+ self.block_tags = _BlockLevelTagSet(
+ set(self.block_level_tags) - (self.span_tags | self.raw_tags | self.empty_tags)
+ )
+ self.span_and_blocks_tags = _BlockLevelTagSet(self.block_tags | self.span_tags)
def reset(self):
"""Reset this instance. Loses all unprocessed data."""
diff --git a/tests/test_syntax/blocks/test_html_blocks.py b/tests/test_syntax/blocks/test_html_blocks.py
index ecc10f45..b6745a1d 100644
--- a/tests/test_syntax/blocks/test_html_blocks.py
+++ b/tests/test_syntax/blocks/test_html_blocks.py
@@ -133,6 +133,30 @@ def test_raw_uppercase_multiline(self):
)
)
+ def test_raw_custom_element(self):
+ # Custom element names contain a hyphen and are treated as block-level.
+ # https://github.com/Python-Markdown/markdown/issues/1246
+ self.assertMarkdownRenders(
+ self.dedent(
+ """
+
*foo*
asdf
+foo
+hello