diff --git a/README.md b/README.md
index bcfee63..3cfcb84 100644
--- a/README.md
+++ b/README.md
@@ -20,32 +20,38 @@ extern crate orgize;
## Example
+### Using Parser
+
+Orgize parser acts like a event-based parser, which means it returns an
+`Iterator` of `Event` s.
+
```rust
use orgize::Parser;
-let parser = Parser::new(
- r"* Title 1
+let parser = Parser::new(r#"* Title 1
*Section 1*
** Title 2
_Section 2_
* Title 3
/Section 3/
* Title 4
-=Section 4=",
-);
+=Section 4="#);
for event in parser {
// handling the event
}
```
-Alternatively, you can use the built-in render.
+### Using Render
+
+You can use the built-in `HtmlRender` to generate html string directly:
```rust
-use orgize::export::DefaultHtmlRender;
-use std::io::Cursor;
+use orgize::export::HtmlRender;
+use std::io::{Cursor, Result};
-let contents = r"* Title 1
+fn main() -> Result<()> {
+ let contents = r"* Title 1
*Section 1*
** Title 2
_Section 2_
@@ -54,14 +60,96 @@ _Section 2_
* Title 4
=Section 4=";
-let cursor = Cursor::new(Vec::new());
-let mut render = DefaultHtmlRender::new(cursor, &contents);
+ let mut cursor = Cursor::new(Vec::new());
+ let mut render = HtmlRender::default(&mut cursor, &contents);
-render
- .render()
- .expect("something went wrong rendering the file");
-
-let result = String::from_utf8(render.into_writer().into_inner()).expect("invalid utf-8");
+ render.render()?;
+
+ assert_eq!(
+ String::from_utf8(cursor.into_inner()).unwrap(),
+ "
Title 1
\
+ Title 2
\
+ Title 3
\
+ Title 4
"
+ );
+
+ Ok(())
+}
+```
+
+### Custom HtmlHandler
+
+You can create your own handler by implementing `HtmlHandler` trait and passing
+it to the `HtmlRender`.
+
+The following example demonstrates how to add an anchor for every headline and
+use your own error type.
+
+```rust
+use orgize::{export::*, headline::Headline};
+use slugify::slugify;
+use std::io::{Cursor, Error as IOError, Write};
+use std::string::FromUtf8Error;
+
+// custom error type
+#[derive(Debug)]
+enum Error {
+ IO(IOError),
+ Headline,
+ Utf8(FromUtf8Error),
+}
+
+// From trait is required for custom error type
+impl From for Error {
+ fn from(err: IOError) -> Error {
+ Error::IO(err)
+ }
+}
+
+struct CustomHtmlHandler;
+
+impl HtmlHandler for CustomHtmlHandler {
+ fn headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<(), Error> {
+ if hdl.level > 6 {
+ Err(Error::Headline)
+ } else {
+ write!(
+ w,
+ r##""##,
+ hdl.level,
+ slugify!(hdl.title),
+ )?;
+ self.escape(w, hdl.title)?;
+ Ok(write!(w, "", hdl.level)?)
+ }
+ }
+}
+
+fn main() -> Result<(), Error> {
+ let contents = r"* Title 1
+*Section 1*
+** Title 2
+_Section 2_
+* Title 3
+/Section 3/
+* Title 4
+=Section 4=";
+
+ let mut cursor = Cursor::new(Vec::new());
+ let mut render = HtmlRender::new(CustomHtmlHandler, &mut cursor, &contents);
+
+ render.render()?;
+
+ assert_eq!(
+ String::from_utf8(cursor.into_inner()).map_err(Error::Utf8)?,
+ "\
+ \
+ \
+ "
+ );
+
+ Ok(())
+}
```
## License
diff --git a/src/lib.rs b/src/lib.rs
index efb0b59..50d1df7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,33 +1,41 @@
//! A Rust library for parsing orgmode files.
//!
-//! ## Example
+//! # Using Parser
+//!
+//! Orgize parser acts like a event-based parser, which means it
+//! returns an `Iterator` of [`Event`] s.
+//!
+//! [`Event`]: enum.Event.html
//!
//! ```rust
//! use orgize::Parser;
//!
-//! let parser = Parser::new(
-//! r"* Title 1
+//! let parser = Parser::new(r#"* Title 1
//! *Section 1*
//! ** Title 2
//! _Section 2_
//! * Title 3
//! /Section 3/
//! * Title 4
-//! =Section 4=",
-//! );
+//! =Section 4="#);
//!
//! for event in parser {
//! // handling the event
//! }
//! ```
//!
-//! Alternatively, you can use the built-in render directly:
+//! # Using Render
+//!
+//! You can use the built-in [`HtmlRender`] to generate html string directly:
+//!
+//! [`HtmlRender`]: export/struct.HtmlRender.html
//!
//! ```rust
//! use orgize::export::HtmlRender;
-//! use std::io::Cursor;
+//! use std::io::{Cursor, Result};
//!
-//! let contents = r"* Title 1
+//! fn main() -> Result<()> {
+//! let contents = r"* Title 1
//! *Section 1*
//! ** Title 2
//! _Section 2_
@@ -36,41 +44,76 @@
//! * Title 4
//! =Section 4=";
//!
-//! let mut cursor = Cursor::new(Vec::new());
-//! let mut render = HtmlRender::default(&mut cursor, &contents);
+//! let mut cursor = Cursor::new(Vec::new());
+//! let mut render = HtmlRender::default(&mut cursor, &contents);
//!
-//! render
-//! .render()
-//! .expect("something went wrong rendering the file");
+//! render.render()?;
//!
-//! let result = String::from_utf8(cursor.into_inner()).expect("invalid utf-8");
+//! assert_eq!(
+//! String::from_utf8(cursor.into_inner()).unwrap(),
+//! "Title 1
\
+//! Title 2
\
+//! Title 3
\
+//! Title 4
"
+//! );
+//!
+//! Ok(())
+//! }
//! ```
//!
-//! or `impl HtmlHandler` to create your own render. The following example
-//! add an anchor to every headline.
+//! # Custom HtmlHandler
+//!
+//! You can create your own handler by implementing [`HtmlHandler`] trait and passing
+//! it to the [`HtmlRender`].
+//!
+//! The following example demonstrates how to add an anchor for every headline and use
+//! your own error type.
+//!
+//! [`HtmlHandler`]: export/trait.HtmlHandler.html
+//! [`HtmlRender`]: export/struct.HtmlRender.html
//!
//! ```rust
-//! use std::io::{Cursor, Error, Result, Write};
-//!
-//! use orgize::export::*;
-//! use orgize::headline::Headline;
+//! use orgize::{export::*, headline::Headline};
//! use slugify::slugify;
+//! use std::io::{Cursor, Error as IOError, Write};
+//! use std::string::FromUtf8Error;
+//!
+//! // custom error type
+//! #[derive(Debug)]
+//! enum Error {
+//! IO(IOError),
+//! Headline,
+//! Utf8(FromUtf8Error),
+//! }
+//!
+//! // From trait is required for custom error type
+//! impl From for Error {
+//! fn from(err: IOError) -> Error {
+//! Error::IO(err)
+//! }
+//! }
//!
//! struct CustomHtmlHandler;
//!
//! impl HtmlHandler for CustomHtmlHandler {
-//! fn headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<()> {
-//! write!(
-//! w,
-//! r##"{2}"##,
-//! if hdl.level <= 6 { hdl.level } else { 6 },
-//! slugify!(hdl.title),
-//! hdl.title,
-//! )
+//! fn headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<(), Error> {
+//! if hdl.level > 6 {
+//! Err(Error::Headline)
+//! } else {
+//! write!(
+//! w,
+//! r##""##,
+//! hdl.level,
+//! slugify!(hdl.title),
+//! )?;
+//! self.escape(w, hdl.title)?;
+//! Ok(write!(w, "", hdl.level)?)
+//! }
//! }
//! }
//!
-//! let contents = r"* Title 1
+//! fn main() -> Result<(), Error> {
+//! let contents = r"* Title 1
//! *Section 1*
//! ** Title 2
//! _Section 2_
@@ -79,18 +122,23 @@
//! * Title 4
//! =Section 4=";
//!
-//! let mut cursor = Cursor::new(Vec::new());
+//! let mut cursor = Cursor::new(Vec::new());
+//! let mut render = HtmlRender::new(CustomHtmlHandler, &mut cursor, &contents);
//!
-//! let mut render = HtmlRender::new(CustomHtmlHandler, &mut cursor, &contents);
+//! render.render()?;
//!
-//! render
-//! .render()
-//! .expect("something went wrong rendering the file");
+//! assert_eq!(
+//! String::from_utf8(cursor.into_inner()).map_err(Error::Utf8)?,
+//! "\
+//! \
+//! \
+//! "
+//! );
//!
-//! let result = String::from_utf8(cursor.into_inner()).expect("invalid utf-8");
+//! Ok(())
+//! }
//! ```
-#[warn(missing_docs)]
pub mod elements;
pub mod export;
pub mod headline;
diff --git a/tests/html.rs b/tests/html.rs
index ec8484c..c5393bb 100644
--- a/tests/html.rs
+++ b/tests/html.rs
@@ -3,20 +3,22 @@ extern crate orgize;
use orgize::export::HtmlRender;
use std::io::Cursor;
-macro_rules! parse_assert {
- ($content:expr, $expected:expr) => {{
- let mut cursor = Cursor::new(Vec::new());
- let mut render = HtmlRender::default(&mut cursor, $content);
- render.render().expect("render error");
- let s = String::from_utf8(cursor.into_inner()).expect("invalid utf-8");
- assert_eq!(s, $expected);
- }};
+macro_rules! html_test {
+ ($name:ident, $content:expr, $expected:expr) => {
+ #[test]
+ fn $name() {
+ let mut cursor = Cursor::new(Vec::new());
+ let mut render = HtmlRender::default(&mut cursor, $content);
+ render.render().expect("render error");
+ let s = String::from_utf8(cursor.into_inner()).expect("invalid utf-8");
+ assert_eq!(s, $expected);
+ }
+ };
}
-#[test]
-fn emphasis() {
- parse_assert!(
- r#"* Title 1
+html_test!(
+ emphasis,
+ r#"* Title 1
*Section 1*
** Title 2
_Section 2_
@@ -24,19 +26,15 @@ _Section 2_
/Section 3/
* Title 4
=Section 4="#,
- concat!(
- "Title 1
",
- "Title 2
",
- "Title 3
",
- "Title 4
"
- )
- )
-}
+ "Title 1
\
+ Title 2
\
+ Title 3
\
+ Title 4
"
+);
-#[test]
-fn list() {
- parse_assert!(
- r#"+ 1
+html_test!(
+ list,
+ r#"+ 1
+ 2
@@ -45,12 +43,9 @@ fn list() {
- 4
+ 5"#,
- concat!(
- "",
- "1
",
- "2
",
- "5
",
- "
"
- )
- )
-}
+ ""
+);