From f8dc1ad3bdbe20ec25379427e6afba36c75ec08c Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 23 Jun 2025 14:30:22 +0200 Subject: [PATCH] Handle pre elements that start with a newline --- crates/typst-html/src/encode.rs | 17 +++++++++++++++++ .../html/html-pre-starting-with-newline.html | 17 +++++++++++++++++ tests/suite/html/syntax.typ | 5 +++++ 3 files changed, 39 insertions(+) create mode 100644 tests/ref/html/html-pre-starting-with-newline.html diff --git a/crates/typst-html/src/encode.rs b/crates/typst-html/src/encode.rs index 2bfa78a72..82a5df47c 100644 --- a/crates/typst-html/src/encode.rs +++ b/crates/typst-html/src/encode.rs @@ -97,6 +97,11 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> { let pretty = w.pretty; if !element.children.is_empty() { + // See HTML spec ยง 13.1.2.5. + if element.tag == tag::pre && starts_with_newline(element) { + w.buf.push('\n'); + } + let pretty_inside = allows_pretty_inside(element.tag) && element.children.iter().any(|node| match node { HtmlNode::Element(child) => wants_pretty_around(child.tag), @@ -133,6 +138,18 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> { Ok(()) } +/// Whether the first character in the element is a newline. +fn starts_with_newline(element: &HtmlElement) -> bool { + for child in &element.children { + match child { + HtmlNode::Tag(_) => {} + HtmlNode::Text(text, _) => return text.starts_with(['\n', '\r']), + _ => return false, + } + } + false +} + /// Whether we are allowed to add an extra newline at the start and end of the /// element's contents. /// diff --git a/tests/ref/html/html-pre-starting-with-newline.html b/tests/ref/html/html-pre-starting-with-newline.html new file mode 100644 index 000000000..676d1a803 --- /dev/null +++ b/tests/ref/html/html-pre-starting-with-newline.html @@ -0,0 +1,17 @@ + + + + + + + +
hello
+
+
+hello
+
+
+
+hello
+ + diff --git a/tests/suite/html/syntax.typ b/tests/suite/html/syntax.typ index c95fa06ed..fb5caf3bd 100644 --- a/tests/suite/html/syntax.typ +++ b/tests/suite/html/syntax.typ @@ -5,3 +5,8 @@ --- html-void-element-with-children html --- // Error: 2-27 HTML void elements must not have children #html.elem("img", [Hello]) + +--- html-pre-starting-with-newline html --- +#html.pre("hello") +#html.pre("\nhello") +#html.pre("\n\nhello")