refactor(iter): use indextree::Traverse for iterating nodes

This commit is contained in:
PoiScript 2019-06-27 20:05:54 +08:00
parent 275fbfad34
commit 21aba13d71
7 changed files with 124 additions and 552 deletions

View file

@ -5,8 +5,8 @@ use std::io::{Error as IOError, Write};
use std::result::Result; use std::result::Result;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use orgize::export::*; use orgize::export::{html::Escape, DefaultHtmlHandler, HtmlHandler};
use orgize::{Container, Org}; use orgize::{Element, Org};
use slugify::slugify; use slugify::slugify;
#[derive(Debug)] #[derive(Debug)]
@ -32,22 +32,25 @@ impl From<FromUtf8Error> for MyError {
struct MyHtmlHandler; struct MyHtmlHandler;
impl HtmlHandler<MyError> for MyHtmlHandler { impl HtmlHandler<MyError> for MyHtmlHandler {
fn start<W: Write>(&mut self, mut w: W, container: Container<'_>) -> Result<(), MyError> { fn start<W: Write>(&mut self, mut w: W, element: &Element<'_>) -> Result<(), MyError> {
let mut default_handler = DefaultHtmlHandler; let mut default_handler = DefaultHtmlHandler;
match container { match element {
Container::Headline(hdl) => { Element::Headline { headline, .. } => {
if hdl.level > 6 { if headline.level > 6 {
return Err(MyError::Heading); return Err(MyError::Heading);
} else { } else {
let slugify = slugify!(hdl.title); let slugify = slugify!(headline.title);
write!( write!(
w, w,
"<h{0}><a id=\"{1}\" href=\"#{1}\">{2}</a></h{0}>", "<h{0}><a id=\"{1}\" href=\"#{1}\">{2}</a></h{0}>",
hdl.level, slugify, hdl.title, headline.level,
slugify,
Escape(headline.title),
)?; )?;
} }
} }
_ => default_handler.start(w, container)?, // fallthrough to default handler
_ => default_handler.start(w, element)?,
} }
Ok(()) Ok(())
} }

View file

@ -52,7 +52,6 @@ use indextree::NodeId;
#[cfg_attr(feature = "serde", serde(tag = "type"))] #[cfg_attr(feature = "serde", serde(tag = "type"))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum Element<'a> { pub enum Element<'a> {
Root,
Block { Block {
#[cfg_attr(feature = "serde", serde(flatten))] #[cfg_attr(feature = "serde", serde(flatten))]
block: Block<'a>, block: Block<'a>,

View file

@ -1,171 +1,127 @@
#![allow(unused_variables)] use crate::elements::Element;
#![allow(unused_mut)]
use crate::elements::*;
use crate::iter::Container;
use jetscii::bytes; use jetscii::bytes;
use std::fmt;
use std::io::{Error, Write}; use std::io::{Error, Write};
pub trait HtmlHandler<E: From<Error>> { pub struct Escape<'a>(pub &'a str);
fn escape<W: Write>(&mut self, mut w: W, text: &str) -> Result<(), E> {
impl fmt::Display for Escape<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut pos = 0; 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..]) { 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; pos += off + 1;
match text.as_bytes()[pos - 1] { match bytes[pos - 1] {
b'<' => w.write_all(b"&lt;")?, b'<' => write!(f, "&lt;")?,
b'>' => w.write_all(b"&gt;")?, b'>' => write!(f, "&gt;")?,
b'&' => w.write_all(b"&amp;")?, b'&' => write!(f, "&amp;")?,
b'\'' => w.write_all(b"&#39;")?, b'\'' => write!(f, "&#39;")?,
b'"' => w.write_all(b"&quot;")?, b'"' => write!(f, "&quot;")?,
_ => unreachable!(), _ => 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>")?, pub trait HtmlHandler<E: From<Error>> {
Container::Bold => write!(w, "<b>")?, fn start<W: Write>(&mut self, mut w: W, element: &Element) -> Result<(), E> {
Container::Document => write!(w, "<main>")?, use Element::*;
Container::DynBlock(_) => (),
Container::Headline(hdl) => { match element {
let level = if hdl.level <= 6 { hdl.level } else { 6 }; // container elements
write!(&mut w, "<h{}>", level)?; Block { .. } => write!(w, "<div>")?,
self.text(&mut w, hdl.title)?; Bold { .. } => write!(w, "<b>")?,
write!(&mut w, "</h{}>", level)?; 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>")?, List { list, .. } => {
Container::List(list) => {
if list.ordered { if list.ordered {
write!(w, "<ol>")?; write!(w, "<ol>")?;
} else { } else {
write!(w, "<ul>")?; write!(w, "<ul>")?;
} }
} }
Container::ListItem(_) => write!(w, "<li>")?, Italic { .. } => write!(w, "<i>")?,
Container::Paragraph => write!(w, "<p>")?, ListItem { .. } => write!(w, "<li>")?,
Container::Section => write!(w, "<section>")?, Paragraph { .. } => write!(w, "<p>")?,
Container::Strike => write!(w, "<s>")?, Section { .. } => write!(w, "<section>")?,
Container::Underline => write!(w, "<u>")?, 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(()) Ok(())
} }
fn end<W: Write>(&mut self, mut w: W, container: Container) -> Result<(), E> { fn end<W: Write>(&mut self, mut w: W, element: &Element) -> Result<(), E> {
match container { use Element::*;
Container::Block(block) => write!(w, "</div>")?,
Container::Bold => write!(w, "</b>")?, match element {
Container::Document => write!(w, "</main>")?, // container elements
Container::DynBlock(_) => (), Block { .. } => write!(w, "</div>")?,
Container::Headline(_) => (), Bold { .. } => write!(w, "</b>")?,
Container::Italic => write!(w, "</i>")?, Document { .. } => write!(w, "</main>")?,
Container::List(list) => { DynBlock { .. } => (),
Headline { .. } => (),
List { list, .. } => {
if list.ordered { if list.ordered {
write!(w, "</ol>")?; write!(w, "</ol>")?;
} else { } else {
write!(w, "</ul>")?; write!(w, "</ul>")?;
} }
} }
Container::ListItem(_) => write!(w, "</li>")?, Italic { .. } => write!(w, "</i>")?,
Container::Paragraph => write!(w, "</p>")?, ListItem { .. } => write!(w, "</li>")?,
Container::Section => write!(w, "</section>")?, Paragraph { .. } => write!(w, "</p>")?,
Container::Strike => write!(w, "</s>")?, Section { .. } => write!(w, "</section>")?,
Container::Underline => write!(w, "</u>")?, 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(()) Ok(())
} }
} }

View file

@ -1,3 +1,3 @@
mod html; pub mod html;
pub use html::*; pub use html::{DefaultHtmlHandler, HtmlHandler};

View file

@ -1,389 +1,25 @@
use indextree::{Arena, NodeId}; use indextree::{Arena, NodeEdge, Traverse};
use crate::elements::*; use crate::elements::Element;
#[derive(Debug)]
pub enum Container<'a> {
Block(&'a Block<'a>),
Bold,
Document,
DynBlock(&'a DynBlock<'a>),
Headline(&'a Headline<'a>),
Italic,
List(&'a List),
ListItem(&'a ListItem<'a>),
Paragraph,
Section,
Strike,
Underline,
}
#[derive(Debug)] #[derive(Debug)]
pub enum Event<'a> { pub enum Event<'a> {
Start(Container<'a>), Start(&'a Element<'a>),
End(Container<'a>), End(&'a Element<'a>),
Rule,
BabelCall(&'a BabelCall<'a>),
Clock(&'a Clock<'a>),
Cookie(&'a Cookie<'a>),
Drawer(&'a Drawer<'a>),
FnDef(&'a FnDef<'a>),
FnRef(&'a FnRef<'a>),
InlineCall(&'a InlineCall<'a>),
InlineSrc(&'a InlineSrc<'a>),
Keyword(&'a Keyword<'a>),
Link(&'a Link<'a>),
Macros(&'a Macros<'a>),
Planning(Planning<'a>),
RadioTarget(&'a RadioTarget<'a>),
Snippet(&'a Snippet<'a>),
Target(&'a Target<'a>),
Timestamp(&'a Timestamp<'a>),
Code(&'a str),
Comment(&'a str),
FixedWidth(&'a str),
Text(&'a str),
Verbatim(&'a str),
}
enum State {
Start,
End,
Empty,
Finished,
} }
pub struct Iter<'a> { pub struct Iter<'a> {
arena: &'a Arena<Element<'a>>, pub(crate) arena: &'a Arena<Element<'a>>,
node: NodeId, pub(crate) traverse: Traverse<'a, Element<'a>>,
state: State,
}
impl<'a> Iter<'a> {
pub(crate) fn new(arena: &'a Arena<Element<'a>>, node: NodeId) -> Self {
Iter {
arena,
node,
state: State::Start,
}
}
fn start_event(&mut self) -> Option<Event<'a>> {
let node = &self.arena[self.node];
match &node.data {
Element::Root => {
self.state = State::Finished;
None
}
Element::BabelCall { call, .. } => {
self.state = State::Start;
Some(Event::BabelCall(call))
}
Element::Verbatim { value, .. } => {
self.state = State::Start;
Some(Event::Verbatim(value))
}
Element::Code { value, .. } => {
self.state = State::Start;
Some(Event::Code(value))
}
Element::Text { value, .. } => {
self.state = State::Start;
Some(Event::Text(value))
}
Element::Block { block, .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Block(block)))
}
Element::Bold { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Bold))
}
Element::Document { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Document))
}
Element::DynBlock { dyn_block, .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::DynBlock(dyn_block)))
}
Element::Headline { headline, .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Headline(headline)))
}
Element::Italic { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Italic))
}
Element::List { list, .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::List(list)))
}
Element::ListItem { list_item, .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::ListItem(list_item)))
}
Element::Paragraph { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Paragraph))
}
Element::Section { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Section))
}
Element::Strike { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Strike))
}
Element::Underline { .. } => {
if node.first_child().is_none() {
self.state = State::Empty;
} else {
self.state = State::Start;
}
Some(Event::Start(Container::Underline))
}
Element::Clock { clock, .. } => {
self.state = State::Start;
Some(Event::Clock(clock))
}
Element::Cookie { cookie, .. } => {
self.state = State::Start;
Some(Event::Cookie(cookie))
}
Element::Drawer { drawer, .. } => {
self.state = State::Start;
Some(Event::Drawer(drawer))
}
Element::FnDef { fn_def, .. } => {
self.state = State::Start;
Some(Event::FnDef(fn_def))
}
Element::FnRef { fn_ref, .. } => {
self.state = State::Start;
Some(Event::FnRef(fn_ref))
}
Element::InlineCall { inline_call, .. } => {
self.state = State::Start;
Some(Event::InlineCall(inline_call))
}
Element::InlineSrc { inline_src, .. } => {
self.state = State::Start;
Some(Event::InlineSrc(inline_src))
}
Element::Keyword { keyword, .. } => {
self.state = State::Start;
Some(Event::Keyword(keyword))
}
Element::Link { link, .. } => {
self.state = State::Start;
Some(Event::Link(link))
}
Element::Macros { macros, .. } => {
self.state = State::Start;
Some(Event::Macros(macros))
}
Element::Planning {
deadline,
scheduled,
closed,
..
} => {
self.state = State::Start;
Some(Event::Planning(Planning {
deadline: deadline.and_then(|id| {
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
Some(timestamp)
} else {
None
}
}),
scheduled: scheduled.and_then(|id| {
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
Some(timestamp)
} else {
None
}
}),
closed: closed.and_then(|id| {
if let Element::Timestamp { timestamp, .. } = &self.arena[id].data {
Some(timestamp)
} else {
None
}
}),
}))
}
Element::RadioTarget { radio_target, .. } => {
self.state = State::Start;
Some(Event::RadioTarget(radio_target))
}
Element::Rule { .. } => {
self.state = State::Start;
Some(Event::Rule)
}
Element::Snippet { snippet, .. } => {
self.state = State::Start;
Some(Event::Snippet(snippet))
}
Element::Target { target, .. } => {
self.state = State::Start;
Some(Event::Target(target))
}
Element::Timestamp { timestamp, .. } => {
self.state = State::Start;
Some(Event::Timestamp(timestamp))
}
Element::FixedWidth { value, .. } => {
self.state = State::Start;
Some(Event::FixedWidth(value))
}
Element::Comment { value, .. } => {
self.state = State::Start;
Some(Event::Comment(value))
}
}
}
fn end_event(&mut self) -> Option<Event<'a>> {
let node = &self.arena[self.node];
match &node.data {
Element::Root => {
self.state = State::Finished;
None
}
Element::Block { block, .. } => {
self.state = State::End;
Some(Event::End(Container::Block(block)))
}
Element::Bold { .. } => {
self.state = State::End;
Some(Event::End(Container::Bold))
}
Element::Document { .. } => {
self.state = State::End;
Some(Event::End(Container::Document))
}
Element::DynBlock { dyn_block, .. } => {
self.state = State::End;
Some(Event::End(Container::DynBlock(dyn_block)))
}
Element::Headline { headline, .. } => {
self.state = State::End;
Some(Event::End(Container::Headline(headline)))
}
Element::Italic { .. } => {
self.state = State::End;
Some(Event::End(Container::Italic))
}
Element::List { list, .. } => {
self.state = State::End;
Some(Event::End(Container::List(list)))
}
Element::ListItem { list_item, .. } => {
self.state = State::End;
Some(Event::End(Container::ListItem(list_item)))
}
Element::Paragraph { .. } => {
self.state = State::End;
Some(Event::End(Container::Paragraph))
}
Element::Section { .. } => {
self.state = State::End;
Some(Event::End(Container::Section))
}
Element::Strike { .. } => {
self.state = State::End;
Some(Event::End(Container::Strike))
}
Element::Underline { .. } => {
self.state = State::End;
Some(Event::End(Container::Underline))
}
_ => unreachable!(),
}
}
} }
impl<'a> Iterator for Iter<'a> { impl<'a> Iterator for Iter<'a> {
type Item = Event<'a>; type Item = Event<'a>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
match self.state { self.traverse.next().map(|edge| match edge {
State::Finished => None, NodeEdge::Start(e) => Event::Start(&self.arena[e].data),
State::End => { NodeEdge::End(e) => Event::End(&self.arena[e].data),
let node = &self.arena[self.node]; })
if let Some(sibling_node) = node.next_sibling() {
self.node = sibling_node;
self.start_event()
} else if let Some(parent_node) = node.parent() {
self.node = parent_node;
self.end_event()
} else {
None
}
}
State::Start => {
let node = &self.arena[self.node];
if let Some(child_node) = node.first_child() {
self.node = child_node;
self.start_event()
} else if let Some(sibling_node) = node.next_sibling() {
self.node = sibling_node;
self.start_event()
} else if let Some(parent_node) = node.parent() {
self.node = parent_node;
self.end_event()
} else {
None
}
}
State::Empty => self.end_event(),
}
} }
} }

View file

@ -146,5 +146,6 @@ pub mod org;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
mod serde; mod serde;
pub use iter::{Container, Event}; pub use elements::Element;
pub use iter::{Event, Iter};
pub use org::Org; pub use org::Org;

View file

@ -10,25 +10,21 @@ use crate::iter::Iter;
pub struct Org<'a> { pub struct Org<'a> {
pub(crate) arena: Arena<Element<'a>>, pub(crate) arena: Arena<Element<'a>>,
pub(crate) document: NodeId, pub(crate) document: NodeId,
root: NodeId,
text: &'a str, text: &'a str,
} }
impl<'a> Org<'a> { impl<'a> Org<'a> {
pub fn parse(text: &'a str) -> Self { pub fn parse(text: &'a str) -> Self {
let mut arena = Arena::new(); let mut arena = Arena::new();
let root = arena.new_node(Element::Root);
let document = arena.new_node(Element::Document { let document = arena.new_node(Element::Document {
begin: 0, begin: 0,
end: text.len(), end: text.len(),
contents_begin: 0, contents_begin: 0,
contents_end: text.len(), contents_end: text.len(),
}); });
root.append(document, &mut arena).unwrap();
let mut org = Org { let mut org = Org {
arena, arena,
root,
document, document,
text, text,
}; };
@ -38,7 +34,10 @@ impl<'a> Org<'a> {
} }
pub fn iter(&'a self) -> Iter<'a> { pub fn iter(&'a self) -> Iter<'a> {
Iter::new(&self.arena, self.root) Iter {
arena: &self.arena,
traverse: self.document.traverse(&self.arena),
}
} }
pub fn html<W, H, E>(&self, mut writer: W, mut handler: H) -> Result<(), E> pub fn html<W, H, E>(&self, mut writer: W, mut handler: H) -> Result<(), E>
@ -53,28 +52,6 @@ impl<'a> Org<'a> {
match event { match event {
Start(e) => handler.start(&mut writer, e)?, Start(e) => handler.start(&mut writer, e)?,
End(e) => handler.end(&mut writer, e)?, End(e) => handler.end(&mut writer, e)?,
Clock(e) => handler.clock(&mut writer, e)?,
Cookie(e) => handler.cookie(&mut writer, e)?,
Drawer(e) => handler.drawer(&mut writer, e)?,
FnDef(e) => handler.fn_def(&mut writer, e)?,
FnRef(e) => handler.fn_ref(&mut writer, e)?,
InlineCall(e) => handler.inline_call(&mut writer, e)?,
InlineSrc(e) => handler.inline_src(&mut writer, e)?,
Keyword(e) => handler.keyword(&mut writer, e)?,
Link(e) => handler.link(&mut writer, e)?,
Macros(e) => handler.macros(&mut writer, e)?,
Planning(e) => handler.planning(&mut writer, &e)?,
RadioTarget(e) => handler.radio_target(&mut writer, e)?,
Snippet(e) => handler.snippet(&mut writer, e)?,
Target(e) => handler.target(&mut writer, e)?,
Timestamp(e) => handler.timestamp(&mut writer, e)?,
Text(e) => handler.text(&mut writer, e)?,
Code(e) => handler.code(&mut writer, e)?,
Verbatim(e) => handler.verbatim(&mut writer, e)?,
BabelCall(e) => handler.babel_call(&mut writer, e)?,
Rule => handler.rule(&mut writer)?,
Comment(e) => handler.comment(&mut writer, e)?,
FixedWidth(e) => handler.fixed_width(&mut writer, e)?,
} }
} }