refactor(iter): use indextree::Traverse for iterating nodes
This commit is contained in:
parent
275fbfad34
commit
21aba13d71
7 changed files with 124 additions and 552 deletions
|
|
@ -1,171 +1,127 @@
|
|||
#![allow(unused_variables)]
|
||||
#![allow(unused_mut)]
|
||||
|
||||
use crate::elements::*;
|
||||
use crate::iter::Container;
|
||||
use crate::elements::Element;
|
||||
use jetscii::bytes;
|
||||
use std::fmt;
|
||||
use std::io::{Error, Write};
|
||||
|
||||
pub trait HtmlHandler<E: From<Error>> {
|
||||
fn escape<W: Write>(&mut self, mut w: W, text: &str) -> Result<(), E> {
|
||||
pub struct Escape<'a>(pub &'a str);
|
||||
|
||||
impl fmt::Display for Escape<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut pos = 0;
|
||||
let bytes = text.as_bytes();
|
||||
let bytes = self.0.as_bytes();
|
||||
while let Some(off) = bytes!(b'<', b'>', b'&', b'\'', b'"').find(&bytes[pos..]) {
|
||||
w.write_all(&bytes[pos..pos + off])?;
|
||||
write!(f, "{}", &self.0[pos..pos + off])?;
|
||||
|
||||
pos += off + 1;
|
||||
|
||||
match text.as_bytes()[pos - 1] {
|
||||
b'<' => w.write_all(b"<")?,
|
||||
b'>' => w.write_all(b">")?,
|
||||
b'&' => w.write_all(b"&")?,
|
||||
b'\'' => w.write_all(b"'")?,
|
||||
b'"' => w.write_all(b""")?,
|
||||
match bytes[pos - 1] {
|
||||
b'<' => write!(f, "<")?,
|
||||
b'>' => write!(f, ">")?,
|
||||
b'&' => write!(f, "&")?,
|
||||
b'\'' => write!(f, "'")?,
|
||||
b'"' => write!(f, """)?,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(w.write_all(&bytes[pos..])?)
|
||||
write!(f, "{}", &self.0[pos..])
|
||||
}
|
||||
fn start<W: Write>(&mut self, mut w: W, container: Container) -> Result<(), E> {
|
||||
match container {
|
||||
Container::Block(block) => write!(w, "<div>")?,
|
||||
Container::Bold => write!(w, "<b>")?,
|
||||
Container::Document => write!(w, "<main>")?,
|
||||
Container::DynBlock(_) => (),
|
||||
Container::Headline(hdl) => {
|
||||
let level = if hdl.level <= 6 { hdl.level } else { 6 };
|
||||
write!(&mut w, "<h{}>", level)?;
|
||||
self.text(&mut w, hdl.title)?;
|
||||
write!(&mut w, "</h{}>", level)?;
|
||||
}
|
||||
|
||||
pub trait HtmlHandler<E: From<Error>> {
|
||||
fn start<W: Write>(&mut self, mut w: W, element: &Element) -> Result<(), E> {
|
||||
use Element::*;
|
||||
|
||||
match element {
|
||||
// container elements
|
||||
Block { .. } => write!(w, "<div>")?,
|
||||
Bold { .. } => write!(w, "<b>")?,
|
||||
Document { .. } => write!(w, "<main>")?,
|
||||
DynBlock { .. } => (),
|
||||
Headline { headline, .. } => {
|
||||
let level = if headline.level <= 6 {
|
||||
headline.level
|
||||
} else {
|
||||
6
|
||||
};
|
||||
write!(w, "<h{0}>{1}</h{0}>", level, Escape(headline.title))?;
|
||||
}
|
||||
Container::Italic => write!(w, "<i>")?,
|
||||
Container::List(list) => {
|
||||
List { list, .. } => {
|
||||
if list.ordered {
|
||||
write!(w, "<ol>")?;
|
||||
} else {
|
||||
write!(w, "<ul>")?;
|
||||
}
|
||||
}
|
||||
Container::ListItem(_) => write!(w, "<li>")?,
|
||||
Container::Paragraph => write!(w, "<p>")?,
|
||||
Container::Section => write!(w, "<section>")?,
|
||||
Container::Strike => write!(w, "<s>")?,
|
||||
Container::Underline => write!(w, "<u>")?,
|
||||
Italic { .. } => write!(w, "<i>")?,
|
||||
ListItem { .. } => write!(w, "<li>")?,
|
||||
Paragraph { .. } => write!(w, "<p>")?,
|
||||
Section { .. } => write!(w, "<section>")?,
|
||||
Strike { .. } => write!(w, "<s>")?,
|
||||
Underline { .. } => write!(w, "<u>")?,
|
||||
// non-container elements
|
||||
BabelCall { .. } => (),
|
||||
InlineSrc { inline_src, .. } => write!(w, "<code>{}</code>", Escape(inline_src.body))?,
|
||||
Code { value, .. } => write!(w, "<code>{}</code>", Escape(value))?,
|
||||
FnRef { .. } => (),
|
||||
InlineCall { .. } => (),
|
||||
Link { link, .. } => write!(
|
||||
w,
|
||||
"<a href=\"{}\">{}</a>",
|
||||
Escape(link.path),
|
||||
Escape(link.desc.unwrap_or(link.path)),
|
||||
)?,
|
||||
Macros { .. } => (),
|
||||
Planning { .. } => (),
|
||||
RadioTarget { .. } => (),
|
||||
Snippet { snippet, .. } => {
|
||||
if snippet.name.eq_ignore_ascii_case("HTML") {
|
||||
write!(w, "{}", snippet.value)?;
|
||||
}
|
||||
}
|
||||
Target { .. } => (),
|
||||
Text { value, .. } => write!(w, "{}", Escape(value))?,
|
||||
Timestamp { .. } => (),
|
||||
Verbatim { value, .. } => write!(&mut w, "<code>{}</code>", Escape(value))?,
|
||||
FnDef { .. } => (),
|
||||
Clock { .. } => (),
|
||||
Comment { value, .. } => write!(w, "<!--\n{}\n-->", Escape(value))?,
|
||||
FixedWidth { value, .. } => write!(w, "<pre>{}</pre>", Escape(value))?,
|
||||
Keyword { .. } => (),
|
||||
Drawer { .. } => (),
|
||||
Rule { .. } => write!(w, "<hr>")?,
|
||||
Cookie { .. } => (),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn end<W: Write>(&mut self, mut w: W, container: Container) -> Result<(), E> {
|
||||
match container {
|
||||
Container::Block(block) => write!(w, "</div>")?,
|
||||
Container::Bold => write!(w, "</b>")?,
|
||||
Container::Document => write!(w, "</main>")?,
|
||||
Container::DynBlock(_) => (),
|
||||
Container::Headline(_) => (),
|
||||
Container::Italic => write!(w, "</i>")?,
|
||||
Container::List(list) => {
|
||||
fn end<W: Write>(&mut self, mut w: W, element: &Element) -> Result<(), E> {
|
||||
use Element::*;
|
||||
|
||||
match element {
|
||||
// container elements
|
||||
Block { .. } => write!(w, "</div>")?,
|
||||
Bold { .. } => write!(w, "</b>")?,
|
||||
Document { .. } => write!(w, "</main>")?,
|
||||
DynBlock { .. } => (),
|
||||
Headline { .. } => (),
|
||||
List { list, .. } => {
|
||||
if list.ordered {
|
||||
write!(w, "</ol>")?;
|
||||
} else {
|
||||
write!(w, "</ul>")?;
|
||||
}
|
||||
}
|
||||
Container::ListItem(_) => write!(w, "</li>")?,
|
||||
Container::Paragraph => write!(w, "</p>")?,
|
||||
Container::Section => write!(w, "</section>")?,
|
||||
Container::Strike => write!(w, "</s>")?,
|
||||
Container::Underline => write!(w, "</u>")?,
|
||||
Italic { .. } => write!(w, "</i>")?,
|
||||
ListItem { .. } => write!(w, "</li>")?,
|
||||
Paragraph { .. } => write!(w, "</p>")?,
|
||||
Section { .. } => write!(w, "</section>")?,
|
||||
Strike { .. } => write!(w, "</s>")?,
|
||||
Underline { .. } => write!(w, "</u>")?,
|
||||
// non-container elements
|
||||
_ => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn keyword<W: Write>(&mut self, mut w: W, keyword: &Keyword<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn drawer<W: Write>(&mut self, mut w: W, drawer: &Drawer<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn rule<W: Write>(&mut self, mut w: W) -> Result<(), E> {
|
||||
Ok(write!(w, "<hr>")?)
|
||||
}
|
||||
fn cookie<W: Write>(&mut self, mut w: W, cookie: &Cookie) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn fn_ref<W: Write>(&mut self, mut w: W, fn_ref: &FnRef<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn babel_call<W: Write>(&mut self, mut w: W, call: &BabelCall<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn inline_call<W: Write>(&mut self, mut w: W, call: &InlineCall<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn inline_src<W: Write>(&mut self, mut w: W, src: &InlineSrc<'_>) -> Result<(), E> {
|
||||
write!(&mut w, "<code>")?;
|
||||
self.text(&mut w, src.body)?;
|
||||
write!(&mut w, "</code>")?;
|
||||
Ok(())
|
||||
}
|
||||
fn link<W: Write>(&mut self, mut w: W, link: &Link<'_>) -> Result<(), E> {
|
||||
write!(&mut w, r#"<a href=""#)?;
|
||||
self.text(&mut w, link.path)?;
|
||||
write!(&mut w, r#"">"#)?;
|
||||
self.text(&mut w, link.desc.unwrap_or(link.path))?;
|
||||
write!(&mut w, "</a>")?;
|
||||
Ok(())
|
||||
}
|
||||
fn macros<W: Write>(&mut self, mut w: W, macros: &Macros<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn radio_target<W: Write>(&mut self, mut w: W, target: &RadioTarget<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn snippet<W: Write>(&mut self, mut w: W, snippet: &Snippet<'_>) -> Result<(), E> {
|
||||
if snippet.name.eq_ignore_ascii_case("HTML") {
|
||||
write!(w, "{}", snippet.value)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn target<W: Write>(&mut self, mut w: W, target: &Target<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn timestamp<W: Write>(&mut self, mut w: W, timestamp: &Timestamp) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn verbatim<W: Write>(&mut self, mut w: W, cont: &str) -> Result<(), E> {
|
||||
write!(&mut w, "<code>")?;
|
||||
self.text(&mut w, cont)?;
|
||||
write!(&mut w, "</code>")?;
|
||||
Ok(())
|
||||
}
|
||||
fn code<W: Write>(&mut self, mut w: W, cont: &str) -> Result<(), E> {
|
||||
write!(&mut w, "<code>")?;
|
||||
self.text(&mut w, cont)?;
|
||||
write!(&mut w, "</code>")?;
|
||||
Ok(())
|
||||
}
|
||||
fn text<W: Write>(&mut self, mut w: W, cont: &str) -> Result<(), E> {
|
||||
self.escape(w, cont)?;
|
||||
Ok(())
|
||||
}
|
||||
fn planning<W: Write>(&mut self, mut w: W, planning: &Planning) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn clock<W: Write>(&mut self, mut w: W, clock: &Clock<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn fn_def<W: Write>(&mut self, mut w: W, fn_def: &FnDef<'_>) -> Result<(), E> {
|
||||
Ok(())
|
||||
}
|
||||
fn comment<W: Write>(&mut self, mut w: W, value: &str) -> Result<(), E> {
|
||||
write!(&mut w, "<!--\n")?;
|
||||
self.text(&mut w, value)?;
|
||||
write!(&mut w, "\n-->")?;
|
||||
Ok(())
|
||||
}
|
||||
fn fixed_width<W: Write>(&mut self, mut w: W, value: &str) -> Result<(), E> {
|
||||
write!(&mut w, "<pre>")?;
|
||||
self.text(&mut w, value)?;
|
||||
write!(&mut w, "</pre>")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue