diff --git a/crates/mdbook-html/src/html/tree.rs b/crates/mdbook-html/src/html/tree.rs index 4184740d..383c75b4 100644 --- a/crates/mdbook-html/src/html/tree.rs +++ b/crates/mdbook-html/src/html/tree.rs @@ -378,6 +378,7 @@ where } } } + self.finish_stack(); self.collect_footnote_defs(); } @@ -736,6 +737,40 @@ where output } + /// Deals with any unclosed elements on the stack. + fn finish_stack(&mut self) { + while let Some(node_id) = self.tag_stack.pop() { + let node = self.tree.get(node_id).unwrap().value(); + match node { + Node::Fragment => {} + Node::Element(el) => { + if el.was_raw { + warn!( + "unclosed HTML tag `<{}>` found in `{}`", + el.name.local, + self.options.path.display() + ); + } else { + panic!( + "internal error: expected empty tag stack.\n + path: `{}`\n\ + element={el:?}", + self.options.path.display() + ); + } + } + node => { + panic!( + "internal error: expected empty tag stack.\n + path: `{}`\n\ + node={node:?}", + self.options.path.display() + ); + } + } + } + } + /// Appends a new footnote reference. fn footnote_reference(&mut self, name: CowStr<'event>) { let len = self.footnote_numbers.len() + 1; diff --git a/tests/testsuite/rendering.rs b/tests/testsuite/rendering.rs index 961710ed..f77f0840 100644 --- a/tests/testsuite/rendering.rs +++ b/tests/testsuite/rendering.rs @@ -252,6 +252,9 @@ fn unclosed_html_tags() { cmd.expect_stderr(str![[r#" INFO Book building has started INFO Running the html backend + WARN unclosed HTML tag `` found in `chapter_1.md` + WARN unclosed HTML tag `` found in `chapter_1.md` + WARN unclosed HTML tag `` found in `chapter_1.md` INFO HTML book written to `[ROOT]/book` "#]]);