feat(export): handler with custom error type

This commit is contained in:
PoiScript 2019-03-13 16:16:57 +08:00
parent 355ea8b46e
commit 0b22db1f0f
4 changed files with 256 additions and 237 deletions

View file

@ -1,103 +1,104 @@
#![allow(unused_variables)]
use std::fmt;
use std::io::{Result, Write};
use jetscii::ascii_chars;
use crate::elements::Key;
use crate::headline::Headline;
use crate::objects::Cookie;
use crate::parser::Parser;
use jetscii::ascii_chars;
use std::convert::From;
use std::fmt;
use std::io::{Error, Write};
use std::marker::PhantomData;
pub trait HtmlHandler<W: Write> {
fn handle_headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<()> {
pub trait HtmlHandler<W: Write, E: From<Error>> {
fn handle_headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<(), E> {
let level = if hdl.level <= 6 { hdl.level } else { 6 };
write!(w, "<h{0}>{1}</h{0}>", level, Escape(hdl.title))
Ok(write!(w, "<h{0}>{1}</h{0}>", level, Escape(hdl.title))?)
}
fn handle_headline_end(&mut self, w: &mut W) -> Result<()> {
fn handle_headline_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_section_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<section>")
fn handle_section_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<section>")?)
}
fn handle_section_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</section>")
fn handle_section_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</section>")?)
}
fn handle_paragraph_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<p>")
fn handle_paragraph_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<p>")?)
}
fn handle_paragraph_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</p>")
fn handle_paragraph_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</p>")?)
}
fn handle_ctr_block_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, r#"<div style="text-align: center">"#)
fn handle_ctr_block_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, r#"<div style="text-align: center">"#)?)
}
fn handle_ctr_block_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</div>")
fn handle_ctr_block_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</div>")?)
}
fn handle_qte_block_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<blockquote>")
fn handle_qte_block_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<blockquote>")?)
}
fn handle_qte_block_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</blockquote>")
fn handle_qte_block_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</blockquote>")?)
}
fn handle_spl_block_beg(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<()> {
write!(w, "<div>")
fn handle_spl_block_beg(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<(), E> {
Ok(write!(w, "<div>")?)
}
fn handle_spl_block_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</div>")
fn handle_spl_block_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</div>")?)
}
fn handle_comment_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<()> {
fn handle_comment_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<(), E> {
Ok(())
}
fn handle_example_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<()> {
write!(w, "<pre><code>{}</code></pre>", Escape(cont))
fn handle_example_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<(), E> {
Ok(write!(w, "<pre><code>{}</code></pre>", Escape(cont))?)
}
fn handle_export_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<()> {
fn handle_export_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<(), E> {
Ok(())
}
fn handle_src_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<()> {
write!(w, "<pre><code>{}</code></pre>", Escape(cont))
fn handle_src_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<(), E> {
Ok(write!(w, "<pre><code>{}</code></pre>", Escape(cont))?)
}
fn handle_verse_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<()> {
fn handle_verse_block(&mut self, w: &mut W, cont: &str, args: Option<&str>) -> Result<(), E> {
Ok(())
}
fn handle_dyn_block_beg(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<()> {
fn handle_dyn_block_beg(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<(), E> {
Ok(())
}
fn handle_dyn_block_end(&mut self, w: &mut W) -> Result<()> {
fn handle_dyn_block_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_list_beg(&mut self, w: &mut W, ordered: bool) -> Result<()> {
fn handle_list_beg(&mut self, w: &mut W, ordered: bool) -> Result<(), E> {
if ordered {
write!(w, "<ol>")
Ok(write!(w, "<ol>")?)
} else {
write!(w, "<ul>")
Ok(write!(w, "<ul>")?)
}
}
fn handle_list_end(&mut self, w: &mut W, ordered: bool) -> Result<()> {
fn handle_list_end(&mut self, w: &mut W, ordered: bool) -> Result<(), E> {
if ordered {
write!(w, "</ol>")
Ok(write!(w, "</ol>")?)
} else {
write!(w, "</ul>")
Ok(write!(w, "</ul>")?)
}
}
fn handle_list_beg_item(&mut self, w: &mut W, bullet: &str) -> Result<()> {
write!(w, "<li>")
fn handle_list_beg_item(&mut self, w: &mut W, bullet: &str) -> Result<(), E> {
Ok(write!(w, "<li>")?)
}
fn handle_list_end_item(&mut self, w: &mut W) -> Result<()> {
write!(w, "</li>")
fn handle_list_end_item(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</li>")?)
}
fn handle_call(&mut self, w: &mut W, value: &str) -> Result<()> {
fn handle_call(&mut self, w: &mut W, value: &str) -> Result<(), E> {
Ok(())
}
fn handle_clock(&mut self, w: &mut W) -> Result<()> {
fn handle_clock(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_comment(&mut self, w: &mut W, cont: &str) -> Result<()> {
fn handle_comment(&mut self, w: &mut W, cont: &str) -> Result<(), E> {
Ok(())
}
fn handle_fixed_width(&mut self, w: &mut W, cont: &str) -> Result<()> {
fn handle_fixed_width(&mut self, w: &mut W, cont: &str) -> Result<(), E> {
for line in cont.lines() {
// remove leading colon
write!(w, "<pre>{}</pre>", Escape(&line[1..]))?;
@ -105,31 +106,36 @@ pub trait HtmlHandler<W: Write> {
Ok(())
}
fn handle_table_start(&mut self, w: &mut W) -> Result<()> {
fn handle_table_start(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_table_end(&mut self, w: &mut W) -> Result<()> {
fn handle_table_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_table_cell(&mut self, w: &mut W) -> Result<()> {
fn handle_table_cell(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_latex_env(&mut self, w: &mut W) -> Result<()> {
fn handle_latex_env(&mut self, w: &mut W) -> Result<(), E> {
Ok(())
}
fn handle_fn_def(&mut self, w: &mut W, label: &str, cont: &str) -> Result<()> {
fn handle_fn_def(&mut self, w: &mut W, label: &str, cont: &str) -> Result<(), E> {
Ok(())
}
fn handle_keyword(&mut self, w: &mut W, key: Key<'_>, value: &str) -> Result<()> {
fn handle_keyword(&mut self, w: &mut W, key: Key<'_>, value: &str) -> Result<(), E> {
Ok(())
}
fn handle_rule(&mut self, w: &mut W) -> Result<()> {
write!(w, "<hr>")
fn handle_rule(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<hr>")?)
}
fn handle_cookie(&mut self, w: &mut W, cookie: Cookie) -> Result<()> {
fn handle_cookie(&mut self, w: &mut W, cookie: Cookie) -> Result<(), E> {
Ok(())
}
fn handle_fn_ref(&mut self, w: &mut W, label: Option<&str>, def: Option<&str>) -> Result<()> {
fn handle_fn_ref(
&mut self,
w: &mut W,
label: Option<&str>,
def: Option<&str>,
) -> Result<(), E> {
Ok(())
}
fn handle_inline_call(
@ -139,7 +145,7 @@ pub trait HtmlHandler<W: Write> {
args: &str,
inside_header: Option<&str>,
end_header: Option<&str>,
) -> Result<()> {
) -> Result<(), E> {
Ok(())
}
fn handle_inline_src(
@ -148,64 +154,105 @@ pub trait HtmlHandler<W: Write> {
lang: &str,
option: Option<&str>,
body: &str,
) -> Result<()> {
write!(w, "<code>{}</code>", Escape(body))
) -> Result<(), E> {
Ok(write!(w, "<code>{}</code>", Escape(body))?)
}
fn handle_link(&mut self, w: &mut W, path: &str, desc: Option<&str>) -> Result<()> {
fn handle_link(&mut self, w: &mut W, path: &str, desc: Option<&str>) -> Result<(), E> {
if let Some(desc) = desc {
write!(w, r#"<a href="{}">{}</a>"#, Escape(path), Escape(desc))
Ok(write!(
w,
r#"<a href="{}">{}</a>"#,
Escape(path),
Escape(desc)
)?)
} else {
write!(w, r#"<a href="{0}">{0}</a>"#, Escape(path))
Ok(write!(w, r#"<a href="{0}">{0}</a>"#, Escape(path))?)
}
}
fn handle_macros(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<()> {
fn handle_macros(&mut self, w: &mut W, name: &str, args: Option<&str>) -> Result<(), E> {
Ok(())
}
fn handle_radio_target(&mut self, w: &mut W, target: &str) -> Result<()> {
fn handle_radio_target(&mut self, w: &mut W, target: &str) -> Result<(), E> {
Ok(())
}
fn handle_snippet(&mut self, w: &mut W, name: &str, value: &str) -> Result<()> {
fn handle_snippet(&mut self, w: &mut W, name: &str, value: &str) -> Result<(), E> {
if name.eq_ignore_ascii_case("HTML") {
write!(w, "{}", value)
Ok(write!(w, "{}", value)?)
} else {
Ok(())
}
}
fn handle_target(&mut self, w: &mut W, target: &str) -> Result<()> {
fn handle_target(&mut self, w: &mut W, target: &str) -> Result<(), E> {
Ok(())
}
fn handle_bold_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<b>")
fn handle_bold_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<b>")?)
}
fn handle_bold_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</b>")
fn handle_bold_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</b>")?)
}
fn handle_italic_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<i>")
fn handle_italic_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<i>")?)
}
fn handle_italic_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</i>")
fn handle_italic_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</i>")?)
}
fn handle_strike_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<s>")
fn handle_strike_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<s>")?)
}
fn handle_strike_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</s>")
fn handle_strike_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</s>")?)
}
fn handle_underline_beg(&mut self, w: &mut W) -> Result<()> {
write!(w, "<u>")
fn handle_underline_beg(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "<u>")?)
}
fn handle_underline_end(&mut self, w: &mut W) -> Result<()> {
write!(w, "</u>")
fn handle_underline_end(&mut self, w: &mut W) -> Result<(), E> {
Ok(write!(w, "</u>")?)
}
fn handle_verbatim(&mut self, w: &mut W, cont: &str) -> Result<()> {
write!(w, "<code>{}</code>", Escape(cont))
fn handle_verbatim(&mut self, w: &mut W, cont: &str) -> Result<(), E> {
Ok(write!(w, "<code>{}</code>", Escape(cont))?)
}
fn handle_code(&mut self, w: &mut W, cont: &str) -> Result<()> {
write!(w, "<code>{}</code>", Escape(cont))
fn handle_code(&mut self, w: &mut W, cont: &str) -> Result<(), E> {
Ok(write!(w, "<code>{}</code>", Escape(cont))?)
}
fn handle_text(&mut self, w: &mut W, cont: &str) -> Result<()> {
write!(w, "{}", Escape(cont))
fn handle_text(&mut self, w: &mut W, cont: &str) -> Result<(), E> {
Ok(write!(w, "{}", Escape(cont))?)
}
}
pub struct DefaultHtmlHandler;
impl<W: Write> HtmlHandler<W, Error> for DefaultHtmlHandler {}
pub struct HtmlRender<'a, W: Write, E: From<Error>, H: HtmlHandler<W, E>> {
pub parser: Parser<'a>,
pub writer: &'a mut W,
handler: H,
error_type: PhantomData<E>,
}
impl<'a, W: Write> HtmlRender<'a, W, Error, DefaultHtmlHandler> {
pub fn default(writer: &'a mut W, text: &'a str) -> Self {
HtmlRender::new(DefaultHtmlHandler, writer, text)
}
}
impl<'a, W: Write, E: From<Error>, H: HtmlHandler<W, E>> HtmlRender<'a, W, E, H> {
pub fn new(handler: H, writer: &'a mut W, text: &'a str) -> Self {
HtmlRender {
parser: Parser::new(text),
handler,
writer,
error_type: PhantomData,
}
}
pub fn render(&mut self) -> Result<(), E> {
for event in &mut self.parser {
handle_event!(event, &mut self.handler, &mut self.writer);
}
Ok(())
}
}