html: output attributes

This commit is contained in:
Noah Hellman 2023-01-15 20:03:25 +01:00
parent eb6b58f2a9
commit 8024499069

View file

@ -68,69 +68,108 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<I, W> {
fn write(&mut self) -> std::fmt::Result { fn write(&mut self) -> std::fmt::Result {
for e in &mut self.events { for e in &mut self.events {
match e { match e {
Event::Start(c, _attrs) => { Event::Start(c, attrs) => {
if c.is_block() { if c.is_block() {
self.out.write_char('\n')?; self.out.write_char('\n')?;
} }
if self.text_only && !matches!(c, Container::Image(..)) { if self.text_only && !matches!(c, Container::Image(..)) {
continue; continue;
} }
match c { match &c {
Container::Blockquote => self.out.write_str("<blockquote>")?, Container::Blockquote => self.out.write_str("<blockquote")?,
Container::List(..) => todo!(), Container::List(..) => todo!(),
Container::ListItem => self.out.write_str("<li>")?, Container::ListItem => self.out.write_str("<li")?,
Container::DescriptionList => self.out.write_str("<dl>")?, Container::DescriptionList => self.out.write_str("<dl")?,
Container::DescriptionDetails => self.out.write_str("<dd>")?, Container::DescriptionDetails => self.out.write_str("<dd")?,
Container::Footnote { .. } => todo!(), Container::Footnote { .. } => todo!(),
Container::Table => self.out.write_str("<table>")?, Container::Table => self.out.write_str("<table")?,
Container::TableRow => self.out.write_str("<tr>")?, Container::TableRow => self.out.write_str("<tr")?,
Container::Div { class } => { Container::Div { .. } => self.out.write_str("<div")?,
if let Some(c) = class { Container::Paragraph => self.out.write_str("<p")?,
write!(self.out, r#"<div class="{}">"#, c)?; Container::Heading { level } => write!(self.out, "<h{}", level)?,
} else { Container::TableCell => self.out.write_str("<td")?,
self.out.write_str("<div>")?; Container::DescriptionTerm => self.out.write_str("<dt")?,
} Container::CodeBlock { .. } => self.out.write_str("<pre")?,
} Container::Span | Container::Math { .. } => self.out.write_str("<span")?,
Container::Paragraph => self.out.write_str("<p>")?, Container::Link(dst, ..) => write!(self.out, r#"<a href="{}""#, dst)?,
Container::Heading { level } => write!(self.out, "<h{}>", level)?,
Container::TableCell => self.out.write_str("<td>")?,
Container::DescriptionTerm => self.out.write_str("<dt>")?,
Container::CodeBlock { lang } => {
if let Some(l) = lang {
write!(self.out, r#"<pre><code class="language-{}">"#, l)?;
} else {
self.out.write_str("<pre><code>")?;
}
}
Container::Span => self.out.write_str("<span>")?,
Container::Link(dst, ..) => write!(self.out, r#"<a href="{}">"#, dst)?,
Container::Image(..) => { Container::Image(..) => {
self.text_only = true; self.text_only = true;
self.out.write_str("<img")?; self.out.write_str("<img")?;
} }
Container::Verbatim => self.out.write_str("<code>")?, Container::Verbatim => self.out.write_str("<code")?,
Container::Math { display } => self.out.write_str(if display {
r#"<span class="math display">\["#
} else {
r#"<span class="math inline">\("#
})?,
Container::RawBlock { format } | Container::RawInline { format } => { Container::RawBlock { format } | Container::RawInline { format } => {
self.raw = if format == "html" { self.raw = if format == &"html" {
Raw::Html Raw::Html
} else { } else {
Raw::Other Raw::Other
} };
continue;
} }
Container::Subscript => self.out.write_str("<sub>")?, Container::Subscript => self.out.write_str("<sub")?,
Container::Superscript => self.out.write_str("<sup>")?, Container::Superscript => self.out.write_str("<sup")?,
Container::Insert => self.out.write_str("<ins>")?, Container::Insert => self.out.write_str("<ins")?,
Container::Delete => self.out.write_str("<del>")?, Container::Delete => self.out.write_str("<del")?,
Container::Strong => self.out.write_str("<strong>")?, Container::Strong => self.out.write_str("<strong")?,
Container::Emphasis => self.out.write_str("<em>")?, Container::Emphasis => self.out.write_str("<em")?,
Container::Mark => self.out.write_str("<mark>")?, Container::Mark => self.out.write_str("<mark")?,
Container::SingleQuoted => self.out.write_str("&lsquo;")?, Container::SingleQuoted => self.out.write_str("&lsquo;")?,
Container::DoubleQuoted => self.out.write_str("&ldquo;")?, Container::DoubleQuoted => self.out.write_str("&ldquo;")?,
} }
if attrs.iter().any(|(a, _)| a == "class")
|| matches!(
c,
Container::Div { class: Some(_) } | Container::Math { .. }
)
{
self.out.write_str(r#" class=""#)?;
let mut classes = attrs
.iter()
.filter(|(a, _)| a == &"class")
.map(|(_, cls)| cls);
let has_attr = if let Container::Math { display } = c {
self.out.write_str(if display {
"math display"
} else {
"math inline"
})?;
true
} else if let Some(cls) = classes.next() {
self.out.write_str(cls)?;
for cls in classes {
self.out.write_char(' ')?;
self.out.write_str(cls)?;
}
true
} else {
false
};
if let Container::Div { class: Some(cls) } = c {
if has_attr {
self.out.write_char(' ')?;
}
self.out.write_str(cls)?;
}
self.out.write_char('"')?;
}
match c {
Container::CodeBlock { lang } => {
if let Some(l) = lang {
write!(self.out, r#"><code class="language-{}">"#, l)?;
} else {
self.out.write_str("><code>")?;
}
}
Container::Image(..) => {
self.out.write_str(r#" alt=""#)?;
}
Container::Math { display } => {
self.out
.write_str(if display { r#">\["# } else { r#">\("# })?;
}
_ => self.out.write_char('>')?,
}
} }
Event::End(c) => { Event::End(c) => {
if c.is_block_container() && !matches!(c, Container::Footnote { .. }) { if c.is_block_container() && !matches!(c, Container::Footnote { .. }) {
@ -154,9 +193,7 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<I, W> {
Container::TableCell => self.out.write_str("</td>")?, Container::TableCell => self.out.write_str("</td>")?,
Container::DescriptionTerm => self.out.write_str("</dt>")?, Container::DescriptionTerm => self.out.write_str("</dt>")?,
Container::CodeBlock { .. } => self.out.write_str("</code></pre>")?, Container::CodeBlock { .. } => self.out.write_str("</code></pre>")?,
Container::Span | Container::Math { .. } => { Container::Span => self.out.write_str("</span>")?,
self.out.write_str("</span>")?;
}
Container::Link(..) => self.out.write_str("</a>")?, Container::Link(..) => self.out.write_str("</a>")?,
Container::Image(src, ..) => { Container::Image(src, ..) => {
self.text_only = false; self.text_only = false;
@ -167,6 +204,13 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<I, W> {
} }
} }
Container::Verbatim => self.out.write_str("</code>")?, Container::Verbatim => self.out.write_str("</code>")?,
Container::Math { display } => {
self.out.write_str(if display {
r#"\]</span>"#
} else {
r#"\)</span>"#
})?;
}
Container::RawBlock { .. } | Container::RawInline { .. } => { Container::RawBlock { .. } | Container::RawInline { .. } => {
self.raw = Raw::None; self.raw = Raw::None;
} }