Skip to content

Commit 317a5e0

Browse files
committed
engine_spx2html: add some HTML validity diagnostics
1 parent f3601dd commit 317a5e0

2 files changed

Lines changed: 50 additions & 11 deletions

File tree

crates/engine_spx2html/src/html.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ macro_rules! emit_element_data {
5252
}
5353
}
5454

55-
pub fn is_other(&self) -> bool {
56-
matches!(self, Element::Other(_))
57-
}
58-
5955
pub fn is_autoclosed_by(&self, other: &Element) -> bool {
6056
match self {
6157
$(

crates/engine_spx2html/src/lib.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ use crate::font::{FontData, MapEntry};
2727
mod font;
2828
mod html;
2929

30+
use html::Element;
31+
3032
/// An engine that converts SPX to HTML.
3133
#[derive(Default)]
3234
pub 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

Comments
 (0)