docs: update README.md and doc-tests

This commit is contained in:
PoiScript 2019-04-24 21:54:51 +08:00
parent d9053d992d
commit 0083425872
3 changed files with 215 additions and 84 deletions

116
README.md
View file

@ -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");
render.render()?;
let result = String::from_utf8(render.into_writer().into_inner()).expect("invalid utf-8");
assert_eq!(
String::from_utf8(cursor.into_inner()).unwrap(),
"<h1>Title 1</h1><section><p><b>Section 1</b></p></section>\
<h2>Title 2</h2><section><p><u>Section 2</u></p></section>\
<h1>Title 3</h1><section><p><i>Section 3</i></p></section>\
<h1>Title 4</h1><section><p><code>Section 4</code></p></section>"
);
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<std::io::Error> trait is required for custom error type
impl From<IOError> for Error {
fn from(err: IOError) -> Error {
Error::IO(err)
}
}
struct CustomHtmlHandler;
impl<W: Write> HtmlHandler<W, Error> 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##"<h{}><a class="anchor" href="#{}">"##,
hdl.level,
slugify!(hdl.title),
)?;
self.escape(w, hdl.title)?;
Ok(write!(w, "</a></h{}>", 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)?,
"<h1><a class=\"anchor\" href=\"#title-1\">Title 1</a></h1><section><p><b>Section 1</b></p></section>\
<h2><a class=\"anchor\" href=\"#title-2\">Title 2</a></h2><section><p><u>Section 2</u></p></section>\
<h1><a class=\"anchor\" href=\"#title-3\">Title 3</a></h1><section><p><i>Section 3</i></p></section>\
<h1><a class=\"anchor\" href=\"#title-4\">Title 4</a></h1><section><p><code>Section 4</code></p></section>"
);
Ok(())
}
```
## License

View file

@ -1,32 +1,40 @@
//! 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};
//!
//! fn main() -> Result<()> {
//! let contents = r"* Title 1
//! *Section 1*
//! ** Title 2
@ -39,37 +47,72 @@
//! 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(),
//! "<h1>Title 1</h1><section><p><b>Section 1</b></p></section>\
//! <h2>Title 2</h2><section><p><u>Section 2</u></p></section>\
//! <h1>Title 3</h1><section><p><i>Section 3</i></p></section>\
//! <h1>Title 4</h1><section><p><code>Section 4</code></p></section>"
//! );
//!
//! 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<std::io::Error> trait is required for custom error type
//! impl From<IOError> for Error {
//! fn from(err: IOError) -> Error {
//! Error::IO(err)
//! }
//! }
//!
//! struct CustomHtmlHandler;
//!
//! impl<W: Write> HtmlHandler<W, Error> for CustomHtmlHandler {
//! fn headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<()> {
//! fn headline_beg(&mut self, w: &mut W, hdl: Headline) -> Result<(), Error> {
//! if hdl.level > 6 {
//! Err(Error::Headline)
//! } else {
//! write!(
//! w,
//! r##"<h{0}><a class="anchor" href="#{1}">{2}</a></h{0}>"##,
//! if hdl.level <= 6 { hdl.level } else { 6 },
//! r##"<h{}><a class="anchor" href="#{}">"##,
//! hdl.level,
//! slugify!(hdl.title),
//! hdl.title,
//! )
//! )?;
//! self.escape(w, hdl.title)?;
//! Ok(write!(w, "</a></h{}>", hdl.level)?)
//! }
//! }
//! }
//!
//! fn main() -> Result<(), Error> {
//! let contents = r"* Title 1
//! *Section 1*
//! ** Title 2
@ -80,17 +123,22 @@
//! =Section 4=";
//!
//! let mut cursor = Cursor::new(Vec::new());
//!
//! let mut render = HtmlRender::new(CustomHtmlHandler, &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()).map_err(Error::Utf8)?,
//! "<h1><a class=\"anchor\" href=\"#title-1\">Title 1</a></h1><section><p><b>Section 1</b></p></section>\
//! <h2><a class=\"anchor\" href=\"#title-2\">Title 2</a></h2><section><p><u>Section 2</u></p></section>\
//! <h1><a class=\"anchor\" href=\"#title-3\">Title 3</a></h1><section><p><i>Section 3</i></p></section>\
//! <h1><a class=\"anchor\" href=\"#title-4\">Title 4</a></h1><section><p><code>Section 4</code></p></section>"
//! );
//!
//! Ok(())
//! }
//! ```
#[warn(missing_docs)]
pub mod elements;
pub mod export;
pub mod headline;

View file

@ -3,19 +3,21 @@ extern crate orgize;
use orgize::export::HtmlRender;
use std::io::Cursor;
macro_rules! parse_assert {
($content:expr, $expected:expr) => {{
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!(
html_test!(
emphasis,
r#"* Title 1
*Section 1*
** Title 2
@ -24,18 +26,14 @@ _Section 2_
/Section 3/
* Title 4
=Section 4="#,
concat!(
"<h1>Title 1</h1><section><p><b>Section 1</b></p></section>",
"<h2>Title 2</h2><section><p><u>Section 2</u></p></section>",
"<h1>Title 3</h1><section><p><i>Section 3</i></p></section>",
"<h1>Title 4</h1><section><p><code>Section 4</code></p></section>"
)
)
}
"<h1>Title 1</h1><section><p><b>Section 1</b></p></section>\
<h2>Title 2</h2><section><p><u>Section 2</u></p></section>\
<h1>Title 3</h1><section><p><i>Section 3</i></p></section>\
<h1>Title 4</h1><section><p><code>Section 4</code></p></section>"
);
#[test]
fn list() {
parse_assert!(
html_test!(
list,
r#"+ 1
+ 2
@ -45,12 +43,9 @@ fn list() {
- 4
+ 5"#,
concat!(
"<section><ul>",
"<li><p>1</p></li>",
"<li><p>2</p><ul><li><p>3</p></li><li><p>4</p></li></ul></li>",
"<li><p>5</p></li>",
"</ul></section>"
)
)
}
"<section><ul>\
<li><p>1</p></li>\
<li><p>2</p><ul><li><p>3</p></li><li><p>4</p></li></ul></li>\
<li><p>5</p></li>\
</ul></section>"
);