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##""##]],
+ );
}