From 73380b26bc26d29a9d73ce29b276e69d5811b38c Mon Sep 17 00:00:00 2001 From: PoiScript Date: Wed, 31 Jul 2019 16:00:46 +0800 Subject: [PATCH] feat(export): export Org struct as org --- src/elements/mod.rs | 2 +- src/export/mod.rs | 6 +- src/export/org.rs | 219 ++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 2 +- src/org.rs | 20 ++++ 5 files changed, 245 insertions(+), 4 deletions(-) create mode 100644 src/export/org.rs diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 2ef29ca..2dfe523 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -1,4 +1,4 @@ -//! Org-mode elements module +//! Org-mode elements mod block; mod clock; diff --git a/src/export/mod.rs b/src/export/mod.rs index 80dfa41..9254548 100644 --- a/src/export/mod.rs +++ b/src/export/mod.rs @@ -1,5 +1,7 @@ +//! Export `Org` struct to various formats. + pub mod html; -// pub mod org; +pub mod org; pub use html::{DefaultHtmlHandler, HtmlHandler}; -// pub use org::{DefaultOrgHandler, OrgHandler}; +pub use org::{DefaultOrgHandler, OrgHandler}; diff --git a/src/export/org.rs b/src/export/org.rs new file mode 100644 index 0000000..9e3e082 --- /dev/null +++ b/src/export/org.rs @@ -0,0 +1,219 @@ +use crate::elements::Element; +use std::io::{Error, Write}; + +pub trait OrgHandler> { + fn start(&mut self, mut w: W, element: &Element) -> Result<(), E> { + use Element::*; + + match element { + // container elements + Block(block) => { + write!(&mut w, "#+BEGIN_{}", block.name)?; + if let Some(parameters) = block.args { + write!(&mut w, " {}", parameters)?; + } + writeln!(&mut w)?; + } + Bold => write!(w, "*")?, + Document => (), + DynBlock(dyn_block) => { + write!(&mut w, "#+BEGIN: {}", dyn_block.block_name)?; + if let Some(parameters) = dyn_block.arguments { + write!(&mut w, " {}", parameters)?; + } + writeln!(&mut w)?; + } + Headline => (), + List(_list) => (), + Italic => write!(w, "/")?, + ListItem(list_item) => write!(w, "{}", list_item.bullet)?, + Paragraph => (), + Section => (), + Strike => write!(w, "+")?, + Underline => write!(w, "_")?, + Drawer(drawer) => writeln!(w, ":{}:", drawer.name)?, + // non-container elements + BabelCall(_babel_call) => (), + InlineSrc(inline_src) => { + write!(&mut w, "src_{}", inline_src.lang)?; + if let Some(options) = inline_src.options { + write!(&mut w, "[{}]", options)?; + } + write!(&mut w, "{{{}}}", inline_src.body)?; + } + Code { value } => write!(w, "~{}~", value)?, + FnRef(fn_ref) => { + write!(&mut w, "[fn:")?; + if let Some(label) = fn_ref.label { + write!(&mut w, "{}", label)?; + } + if let Some(definition) = fn_ref.definition { + write!(&mut w, ":{}", definition)?; + } + write!(&mut w, "]")?; + } + InlineCall(inline_call) => { + write!(&mut w, "call_{}", inline_call.name)?; + if let Some(header) = inline_call.inside_header { + write!(&mut w, "[{}]", header)?; + } + write!(&mut w, "({})", inline_call.arguments)?; + if let Some(header) = inline_call.end_header { + write!(&mut w, "[{}]", header)?; + } + } + Link(link) => { + write!(&mut w, "[[{}]", link.path)?; + if let Some(desc) = link.desc { + write!(&mut w, "[{}]", desc)?; + } + write!(&mut w, "]")?; + } + Macros(_macros) => (), + Planning(_planning) => (), + RadioTarget(_radio_target) => (), + Snippet(snippet) => write!(w, "@@{}:{}@@", snippet.name, snippet.value)?, + Target(_target) => (), + Text { value } => write!(w, "{}", value)?, + Timestamp(timestamp) => { + use crate::elements::{Date, Time, Timestamp::*}; + + fn write_date(mut w: W, date: &Date) -> Result<(), Error> { + write!( + w, + "{}-{}-{} {}", + date.year, date.month, date.day, date.dayname + ) + } + + fn write_time(mut w: W, time: &Option