# Orgize [![Build Status](https://travis-ci.org/PoiScript/orgize.svg?branch=master)](https://travis-ci.org/PoiScript/orgize) [![Crates.io](https://img.shields.io/crates/v/orgize.svg)](https://crates.io/crates/orgize) [![Document](https://docs.rs/orgize/badge.svg)](https://docs.rs/orgize) A Rust library for parsing orgmode files. ## Parse To parse a orgmode string, simply invoking the `Org::parse` function: ```rust use orgize::Org; Org::parse("* DONE Title :tag:"); ``` or `Org::parse_with_config`: ``` rust use orgize::{Org, ParseConfig}; Org::parse_with_config( "* TASK Title 1", &ParseConfig { // custom todo keywords todo_keywords: vec!["TASK".to_string()], ..Default::default() }, ); ``` ## Iter `Org::iter` function will returns an iteractor of `Event`s, which is a simple wrapper of `Element`. ```rust use orgize::Org; for event in Org::parse("* DONE Title :tag:").iter() { // handling the event } ``` **Note**: whether an element is container or not, it will appears twice in one loop. One as `Event::Start(element)`, one as `Event::End(element)`. ## Render html You can call the `Org::html` function to generate html directly, which uses the `DefaultHtmlHandler` internally: ```rust use orgize::Org; let mut writer = Vec::new(); Org::parse("* title\n*section*").html(&mut writer).unwrap(); assert_eq!( String::from_utf8(writer).unwrap(), "

title

section

" ); ``` ## Render html with custom `HtmlHandler` To customize html rendering, simply implementing `HtmlHandler` trait and passing it to the `Org::html_with_handler` function. The following code demonstrates how to add a id for every headline and return own error type while rendering. ```rust use std::convert::From; use std::io::{Error as IOError, Write}; use std::string::FromUtf8Error; use orgize::export::{html::Escape, DefaultHtmlHandler, HtmlHandler}; use orgize::{Element, Org}; use slugify::slugify; #[derive(Debug)] enum MyError { IO(IOError), Heading, Utf8(FromUtf8Error), } // From trait is required for custom error type impl From for MyError { fn from(err: IOError) -> Self { MyError::IO(err) } } impl From for MyError { fn from(err: FromUtf8Error) -> Self { MyError::Utf8(err) } } struct MyHtmlHandler(DefaultHtmlHandler); impl HtmlHandler for MyHtmlHandler { fn start(&mut self, mut w: W, element: &Element<'_>) -> Result<(), MyError> { match element { Element::Headline(headline) => { if headline.level > 6 { return Err(MyError::Heading); } else { write!( w, "{2}", headline.level, slugify!(headline.title), Escape(headline.title), )?; } } // fallthrough to default handler _ => self.0.start(w, element)?, } Ok(()) } } fn main() -> Result<(), MyError> { let mut writer = Vec::new(); Org::parse("* title\n*section*").html_with_handler(&mut writer, MyHtmlHandler(DefaultHtmlHandler))?; assert_eq!( String::from_utf8(writer)?, "

title

\

section

" ); Ok(()) } ``` **Note**: as I mentioned above, each element will appears two times while iterating. And handler will silently ignores all end events from non-container elements. So if you want to change how a non-container element renders, just redefine the `start` function and leave the `end` function unchanged. # Serde `Org` struct have already implemented serde's `Serialize` trait. It means you can serialize it into any format supported by serde, such as json: ```rust use orgize::Org; use serde_json::{json, to_string}; let org = Org::parse("I 'm *bold*."); println!("{}", to_string(&org).unwrap()); // { // "type": "document", // "children": [{ // "type": "section", // "children": [{ // "type": "paragraph", // "children":[{ // "type": "text", // "value":"I 'm " // }, { // "type": "bold", // "children":[{ // "type": "text", // "value": "bold" // }] // }, { // "type":"text", // "value":"." // }] // }] // }] // } ``` ## Features By now, orgize provides two features: + `serde`: adds the ability to serialize `Org` and other elements using `serde`, enabled by default. + `chrono`: adds the ability to convert `Datetime` into `chrono` structs, disabled by default. ## License MIT