@@ -27,6 +27,8 @@ use crate::font::{FontData, MapEntry};
2727mod font;
2828mod html;
2929
30+ use html:: Element ;
31+
3032/// An engine that converts SPX to HTML.
3133#[ derive( Default ) ]
3234pub struct Spx2HtmlEngine { }
@@ -693,6 +695,41 @@ impl EmittingState {
693695 }
694696 }
695697
698+ fn create_elem ( & self , name : & str , is_start : bool , common : & mut Common ) -> Element {
699+ // Parsing can never fail since we offer an `Other` element type
700+ let el: html:: Element = name. parse ( ) . unwrap ( ) ;
701+
702+ if el. is_deprecated ( ) {
703+ tt_warning ! (
704+ common. status,
705+ "HTML element `{}` is deprecated; templates should be updated to avoid it" ,
706+ name
707+ ) ;
708+ }
709+
710+ if is_start && el. is_empty ( ) {
711+ tt_warning ! (
712+ common. status,
713+ "HTML element `{}` is an empty element; insert it with `tdux:mfe`, not as a start-tag" ,
714+ name
715+ ) ;
716+ }
717+
718+ if let Some ( cur) = self . cur_elstate ( ) . elem . as_ref ( ) {
719+ if cur. is_autoclosed_by ( & el) {
720+ tt_warning ! (
721+ common. status,
722+ "currently open HTML element `{}` will be implicitly closed by new \
723+ element `{}`; explicit closing tags are strongly encouraged",
724+ cur. name( ) ,
725+ name
726+ ) ;
727+ }
728+ }
729+
730+ el
731+ }
732+
696733 #[ inline( always) ]
697734 fn cur_elstate ( & self ) -> & ElementState {
698735 self . elem_stack . last ( ) . unwrap ( )
@@ -728,11 +765,13 @@ impl EmittingState {
728765 }
729766 }
730767
731- fn push_elem ( & mut self , name : & str , origin : ElementOrigin ) {
768+ fn push_elem ( & mut self , name : & str , origin : ElementOrigin , common : & mut Common ) {
732769 self . close_automatics ( ) ;
733770
771+ let el = self . create_elem ( name, true , common) ;
772+
734773 let new_item = ElementState {
735- elem : Some ( name . parse ( ) . unwrap ( ) ) ,
774+ elem : Some ( el ) ,
736775 origin,
737776 ..* self . cur_elstate ( )
738777 } ;
@@ -856,11 +895,12 @@ impl EmittingState {
856895 if self . content_finished {
857896 self . warn_finished_content ( & format ! ( "auto start tag <{}>" , element) , common) ;
858897 } else if self . cur_elstate ( ) . do_auto_tags {
898+ let el = self . create_elem ( element, true , common) ;
859899 self . push_space_if_needed ( x, None ) ;
860900 self . current_content . push ( '<' ) ;
861- self . current_content . push_str ( element ) ;
901+ self . current_content . push_str ( el . name ( ) ) ;
862902 self . current_content . push ( '>' ) ;
863- self . push_elem ( element, ElementOrigin :: EngineAuto ) ;
903+ self . push_elem ( element, ElementOrigin :: EngineAuto , common ) ;
864904 }
865905 Ok ( ( ) )
866906 } else if let Some ( element) = contents. strip_prefix ( "tdux:ae " ) {
@@ -993,8 +1033,9 @@ impl EmittingState {
9931033 return Ok ( ( ) ) ;
9941034 }
9951035
1036+ let el = self . create_elem ( tagname, true , common) ;
9961037 let mut elstate = ElementState {
997- elem : Some ( tagname . parse ( ) . unwrap ( ) ) ,
1038+ elem : Some ( el ) ,
9981039 origin : ElementOrigin :: Manual ,
9991040 ..* self . cur_elstate ( )
10001041 } ;
@@ -1605,10 +1646,12 @@ impl EmittingState {
16051646 ( "div" , "canvas-block" , "" . to_owned ( ) )
16061647 } ;
16071648
1649+ let element = self . create_elem ( element, true , common) ;
1650+
16081651 write ! (
16091652 self . current_content,
16101653 "<{} class=\" canvas {}\" style=\" width: {}rem; height: {}rem; padding-left: {}rem{}\" >" ,
1611- element,
1654+ element. name ( ) ,
16121655 layout_class,
16131656 ( x_max_tex - x_min_tex) as f32 * self . rems_per_tex,
16141657 ( y_max_tex - y_min_tex) as f32 * self . rems_per_tex,
@@ -1617,7 +1660,7 @@ impl EmittingState {
16171660 )
16181661 . unwrap ( ) ;
16191662 self . current_content . push_str ( & inner_content) ;
1620- write ! ( self . current_content, "</{}>" , element) . unwrap ( ) ;
1663+ write ! ( self . current_content, "</{}>" , element. name ( ) ) . unwrap ( ) ;
16211664 self . update_content_pos ( x_max_tex + canvas. x0 , None ) ;
16221665 Ok ( ( ) )
16231666 }
0 commit comments