summaryrefslogtreecommitdiff
path: root/crates/typst-html/src/encode.rs
diff options
context:
space:
mode:
authorMichael Färber <01mf02@gmail.com>2024-12-10 10:57:22 +0100
committerGitHub <noreply@github.com>2024-12-10 09:57:22 +0000
commit17f20c6944d569d5f0bb57caee37d9f208d87d0d (patch)
tree9e48c3a6525adb876d06711bc48ef82eb64e59ff /crates/typst-html/src/encode.rs
parentbb0c8140950b3eec020a4f0147bbc4ea65f3952a (diff)
Basic HTML pretty-printing (#5533)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
Diffstat (limited to 'crates/typst-html/src/encode.rs')
-rw-r--r--crates/typst-html/src/encode.rs48
1 files changed, 45 insertions, 3 deletions
diff --git a/crates/typst-html/src/encode.rs b/crates/typst-html/src/encode.rs
index d4ff83d6..b87b0e1d 100644
--- a/crates/typst-html/src/encode.rs
+++ b/crates/typst-html/src/encode.rs
@@ -8,14 +8,30 @@ use typst_syntax::Span;
/// Encodes an HTML document into a string.
pub fn html(document: &HtmlDocument) -> SourceResult<String> {
- let mut w = Writer { buf: String::new() };
+ let mut w = Writer { pretty: true, ..Writer::default() };
w.buf.push_str("<!DOCTYPE html>");
+ write_indent(&mut w);
write_element(&mut w, &document.root)?;
Ok(w.buf)
}
+#[derive(Default)]
struct Writer {
buf: String,
+ /// current indentation level
+ level: usize,
+ /// pretty printing enabled?
+ pretty: bool,
+}
+
+/// Write a newline and indent, if pretty printing is enabled.
+fn write_indent(w: &mut Writer) {
+ if w.pretty {
+ w.buf.push('\n');
+ for _ in 0..w.level {
+ w.buf.push_str(" ");
+ }
+ }
}
/// Encode an HTML node into the writer.
@@ -67,9 +83,30 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> {
return Ok(());
}
- for node in &element.children {
- write_node(w, node)?;
+ let pretty = w.pretty;
+ if !element.children.is_empty() {
+ w.pretty &= is_pretty(element);
+ let mut indent = w.pretty;
+
+ w.level += 1;
+ for c in &element.children {
+ let pretty_child = match c {
+ HtmlNode::Tag(_) => continue,
+ HtmlNode::Element(element) => is_pretty(element),
+ HtmlNode::Text(..) | HtmlNode::Frame(_) => false,
+ };
+
+ if core::mem::take(&mut indent) || pretty_child {
+ write_indent(w);
+ }
+ write_node(w, c)?;
+ indent = pretty_child;
+ }
+ w.level -= 1;
+
+ write_indent(w)
}
+ w.pretty = pretty;
w.buf.push_str("</");
w.buf.push_str(&element.tag.resolve());
@@ -78,6 +115,11 @@ fn write_element(w: &mut Writer, element: &HtmlElement) -> SourceResult<()> {
Ok(())
}
+/// Whether the element should be pretty-printed.
+fn is_pretty(element: &HtmlElement) -> bool {
+ tag::is_block_by_default(element.tag) || matches!(element.tag, tag::meta)
+}
+
/// Escape a character.
fn write_escape(w: &mut Writer, c: char) -> StrResult<()> {
// See <https://html.spec.whatwg.org/multipage/syntax.html#syntax-charref>