@@ -306,25 +306,7 @@ where
306306 trace ! ( "event={event:?}" ) ;
307307 match event {
308308 Event :: Start ( tag) => self . start_tag ( tag) ,
309- Event :: End ( tag) => {
310- // TODO: This should validate that the event stack is
311- // properly synchronized with the tag stack.
312- self . pop ( ) ;
313- match tag {
314- TagEnd :: TableHead => {
315- self . table_state = TableState :: Body ;
316- self . push ( Node :: Element ( Element :: new ( "tbody" ) ) ) ;
317- }
318- TagEnd :: TableCell => {
319- self . table_cell_index += 1 ;
320- }
321- TagEnd :: Table => {
322- // Pop tbody or thead
323- self . pop ( ) ;
324- }
325- _ => { }
326- }
327- }
309+ Event :: End ( tag) => self . end_tag ( tag) ,
328310 Event :: Text ( text) => {
329311 self . append_text ( text. into_tendril ( ) ) ;
330312 }
@@ -600,6 +582,46 @@ where
600582 self . push ( Node :: Element ( element) ) ;
601583 }
602584
585+ fn end_tag ( & mut self , tag : TagEnd ) {
586+ // TODO: This should validate that the event stack is properly
587+ // synchronized with the tag stack. That, would likely require keeping
588+ // a parallel "expected end tag" with the tag stack, since mapping a
589+ // pulldown-cmark event tag to an HTML tag isn't always clear.
590+ //
591+ // Check for unclosed HTML tags when exiting a markdown event.
592+ while let Some ( node_id) = self . tag_stack . last ( ) {
593+ let node = self . tree . get ( * node_id) . unwrap ( ) . value ( ) ;
594+ let Node :: Element ( el) = node else {
595+ break ;
596+ } ;
597+ if !el. was_raw {
598+ break ;
599+ }
600+ warn ! (
601+ "unclosed HTML tag `<{}>` found in `{}` while exiting {tag:?}\n \
602+ HTML tags must be closed before exiting a markdown element.",
603+ el. name. local,
604+ self . options. path. display( ) ,
605+ ) ;
606+ self . pop ( ) ;
607+ }
608+ self . pop ( ) ;
609+ match tag {
610+ TagEnd :: TableHead => {
611+ self . table_state = TableState :: Body ;
612+ self . push ( Node :: Element ( Element :: new ( "tbody" ) ) ) ;
613+ }
614+ TagEnd :: TableCell => {
615+ self . table_cell_index += 1 ;
616+ }
617+ TagEnd :: Table => {
618+ // Pop tbody or thead
619+ self . pop ( ) ;
620+ }
621+ _ => { }
622+ }
623+ }
624+
603625 /// Given some HTML, parse it into [`Node`] elements and append them to
604626 /// the current node.
605627 fn append_html ( & mut self , html : & str ) {
0 commit comments