diff --git a/crates/mdbook-html/src/html/tree.rs b/crates/mdbook-html/src/html/tree.rs index e4da7ef6..0c7c2e4d 100644 --- a/crates/mdbook-html/src/html/tree.rs +++ b/crates/mdbook-html/src/html/tree.rs @@ -583,8 +583,28 @@ where } fn end_tag(&mut self, tag: TagEnd) { - // TODO: This should validate that the event stack is - // properly synchronized with the tag stack. + // TODO: This should validate that the event stack is properly + // synchronized with the tag stack. That, would likely require keeping + // a parallel "expected end tag" with the tag stack, since mapping a + // pulldown-cmark event tag to an HTML tag isn't always clear. + // + // Check for unclosed HTML tags when exiting a markdown event. + while let Some(node_id) = self.tag_stack.last() { + let node = self.tree.get(*node_id).unwrap().value(); + let Node::Element(el) = node else { + break; + }; + if !el.was_raw { + break; + } + warn!( + "unclosed HTML tag `<{}>` found in `{}` while exiting {tag:?}\n\ + HTML tags must be closed before exiting a markdown element.", + el.name.local, + self.options.path.display(), + ); + self.pop(); + } self.pop(); match tag { TagEnd::TableHead => { diff --git a/tests/testsuite/rendering.rs b/tests/testsuite/rendering.rs index ea75fbd0..421aa5d4 100644 --- a/tests/testsuite/rendering.rs +++ b/tests/testsuite/rendering.rs @@ -290,18 +290,17 @@ fn heading_with_unbalanced_html() { BookTest::init(|_| {}) .change_file("src/chapter_1.md", "### Option") .run("build", |cmd| { - cmd.expect_failure().expect_stderr(str![[r#" + cmd.expect_stderr(str![[r#" INFO Book building has started INFO Running the html backend - -thread 'main' ([..]) panicked at crates/mdbook-html/src/html/tree.rs:[..] -internal error: expected empty tag stack. - - path: `chapter_1.md` -element=Element { name: QualName { prefix: None, ns: Atom('http://www.w3.org/1999/xhtml' type=static), local: Atom('h3' type=inline) }, attrs: {}, self_closing: false, was_raw: false } -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + WARN unclosed HTML tag `` found in `chapter_1.md` while exiting Heading(H3) +HTML tags must be closed before exiting a markdown element. + INFO HTML book written to `[ROOT]/book` "#]]); - }); - // .check_main_file("book/chapter_1.html", str![[""]]); + }) + .check_main_file( + "book/chapter_1.html", + str![[r##"

Option

"##]], + ); }