Make tests pass
diff --git a/src/mdformat/_util.py b/src/mdformat/_util.py index d45c5b3..9024bc5 100644 --- a/src/mdformat/_util.py +++ b/src/mdformat/_util.py
@@ -105,21 +105,26 @@ # TODO: remove empty p tags, remove formatted code def normalize_html_ast(ast: list[dict]) -> list[dict]: - pass + raise NotImplementedError class HTML2AST(HTMLParser): """Parse HTML to a list/dict structure that can be used in comparisons. - HTML2AST.parse() is the only method considered public. + HTML2AST.parse() is the only public interface. """ - def __init__(self): - super().__init__(convert_charrefs=True) + def __init__(self) -> None: + HTMLParser.__init__(self, convert_charrefs=True) + + def reset(self) -> None: + """This is called by HTMLParser.__init__.""" + HTMLParser.reset(self) self.tree: list[dict] = [] self.current: dict | None = None def parse(self, text: str, strip_classes: Iterable[str] = ()) -> list[dict]: + self.reset() self.feed(text) self.close() self.strip_classes(self.tree, set(strip_classes)) @@ -140,7 +145,7 @@ return items - def handle_starttag(self, tag: str, attrs: list[tuple[str, str]]) -> None: + def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: tag_item = {"tag": tag, "attrs": dict(attrs), "parent": self.current} if self.current is None: self.tree.append(tag_item) @@ -161,9 +166,6 @@ # ignore data outside tags if self.current is None: return - assert ( - "data" not in self.current - ), "Oh no, the tag had data in more than one place." if self.current["tag"] == "p": # Strip insignificant paragraph leading/trailing whitespace @@ -171,7 +173,10 @@ # Reduce all collapsable whitespace to a single space data = re.sub(r"[\n\t ]+", " ", data) - self.current["data"] = data + if "data" in self.current: + self.current["data"].append(data) + else: + self.current["data"] = [data] def detect_newline_type(md: str, eol_setting: str) -> Literal["\n", "\r\n"]:
diff --git a/tests/test_html2ast.py b/tests/test_html2ast.py index d79a883..425dce2 100755 --- a/tests/test_html2ast.py +++ b/tests/test_html2ast.py
@@ -22,7 +22,7 @@ def test_html2ast_multiline(): data = HTML2AST().parse("<div>a\nb \nc \n\n</div>") - assert data == [{"tag": "div", "attrs": {}, "data": ["a", "b", "c"]}] + assert data == [{"tag": "div", "attrs": {}, "data": ["a\nb \nc \n\n"]}] def test_html2ast_nested(): @@ -58,7 +58,7 @@ def test_html2ast_multiple_content(): data = HTML2AST().parse( - """' + """ <div> hello @@ -74,26 +74,36 @@ { "tag": "div", "attrs": {}, - "children": [{"tag": "p", "attrs": {"class": "x y"}}], + "children": [ + {"tag": "p", "attrs": {"class": "x y"}, "data": ["a"]}, + {"tag": "p", "attrs": {"class": "a b"}}, + ], + "data": [ + "\nhello\n\n", + "\n", + """ + + another hello in the same div +this one is multiline +""", + ], }, - {"tag": "a", "attrs": {}, "data": ["b"]}, ] -def test_html2ast_multiple_contentssss(): +def test_html2ast_empty_paragraphs(): data = HTML2AST().parse( - """' + """ <p></p> <p>a</p> <p> </p> +<p> </p> """, ) assert data == [ - { - "tag": "div", - "attrs": {}, - "children": [{"tag": "p", "attrs": {"class": "x y"}}], - }, - {"tag": "a", "attrs": {}, "data": ["b"]}, + {"tag": "p", "attrs": {}}, + {"tag": "p", "attrs": {}, "data": ["a"]}, + {"tag": "p", "attrs": {}, "data": [""]}, + {"tag": "p", "attrs": {}, "data": [""]}, ]