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

118
README.md
View file

@ -20,32 +20,38 @@ extern crate orgize;
## Example ## Example
### Using Parser
Orgize parser acts like a event-based parser, which means it returns an
`Iterator` of `Event` s.
```rust ```rust
use orgize::Parser; use orgize::Parser;
let parser = Parser::new( let parser = Parser::new(r#"* Title 1
r"* Title 1
*Section 1* *Section 1*
** Title 2 ** Title 2
_Section 2_ _Section 2_
* Title 3 * Title 3
/Section 3/ /Section 3/
* Title 4 * Title 4
=Section 4=", =Section 4="#);
);
for event in parser { for event in parser {
// handling the event // 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 ```rust
use orgize::export::DefaultHtmlRender; 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* *Section 1*
** Title 2 ** Title 2
_Section 2_ _Section 2_
@ -54,14 +60,96 @@ _Section 2_
* Title 4 * Title 4
=Section 4="; =Section 4=";
let cursor = Cursor::new(Vec::new()); let mut cursor = Cursor::new(Vec::new());
let mut render = DefaultHtmlRender::new(cursor, &contents); let mut render = HtmlRender::default(&mut cursor, &contents);
render render.render()?;
.render()
.expect("something went wrong rendering the file"); assert_eq!(
String::from_utf8(cursor.into_inner()).unwrap(),
let result = String::from_utf8(render.into_writer().into_inner()).expect("invalid utf-8"); "<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 ## License

View file

@ -1,33 +1,41 @@
//! A Rust library for parsing orgmode files. //! 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 //! ```rust
//! use orgize::Parser; //! use orgize::Parser;
//! //!
//! let parser = Parser::new( //! let parser = Parser::new(r#"* Title 1
//! r"* Title 1
//! *Section 1* //! *Section 1*
//! ** Title 2 //! ** Title 2
//! _Section 2_ //! _Section 2_
//! * Title 3 //! * Title 3
//! /Section 3/ //! /Section 3/
//! * Title 4 //! * Title 4
//! =Section 4=", //! =Section 4="#);
//! );
//! //!
//! for event in parser { //! for event in parser {
//! // handling the event //! // 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 //! ```rust
//! use orgize::export::HtmlRender; //! 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* //! *Section 1*
//! ** Title 2 //! ** Title 2
//! _Section 2_ //! _Section 2_
@ -36,41 +44,76 @@
//! * Title 4 //! * Title 4
//! =Section 4="; //! =Section 4=";
//! //!
//! let mut cursor = Cursor::new(Vec::new()); //! let mut cursor = Cursor::new(Vec::new());
//! let mut render = HtmlRender::default(&mut cursor, &contents); //! let mut render = HtmlRender::default(&mut cursor, &contents);
//! //!
//! render //! render.render()?;
//! .render()
//! .expect("something went wrong rendering the file");
//! //!
//! 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 //! # Custom HtmlHandler
//! add an anchor to every headline. //!
//! 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 //! ```rust
//! use std::io::{Cursor, Error, Result, Write}; //! use orgize::{export::*, headline::Headline};
//!
//! use orgize::export::*;
//! use orgize::headline::Headline;
//! use slugify::slugify; //! 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; //! struct CustomHtmlHandler;
//! //!
//! impl<W: Write> HtmlHandler<W, Error> for 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> {
//! write!( //! if hdl.level > 6 {
//! w, //! Err(Error::Headline)
//! r##"<h{0}><a class="anchor" href="#{1}">{2}</a></h{0}>"##, //! } else {
//! if hdl.level <= 6 { hdl.level } else { 6 }, //! write!(
//! slugify!(hdl.title), //! w,
//! hdl.title, //! r##"<h{}><a class="anchor" href="#{}">"##,
//! ) //! hdl.level,
//! slugify!(hdl.title),
//! )?;
//! self.escape(w, hdl.title)?;
//! Ok(write!(w, "</a></h{}>", hdl.level)?)
//! }
//! } //! }
//! } //! }
//! //!
//! let contents = r"* Title 1 //! fn main() -> Result<(), Error> {
//! let contents = r"* Title 1
//! *Section 1* //! *Section 1*
//! ** Title 2 //! ** Title 2
//! _Section 2_ //! _Section 2_
@ -79,18 +122,23 @@
//! * Title 4 //! * Title 4
//! =Section 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 //! assert_eq!(
//! .render() //! String::from_utf8(cursor.into_inner()).map_err(Error::Utf8)?,
//! .expect("something went wrong rendering the file"); //! "<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>"
//! );
//! //!
//! let result = String::from_utf8(cursor.into_inner()).expect("invalid utf-8"); //! Ok(())
//! }
//! ``` //! ```
#[warn(missing_docs)]
pub mod elements; pub mod elements;
pub mod export; pub mod export;
pub mod headline; pub mod headline;

View file

@ -3,20 +3,22 @@ extern crate orgize;
use orgize::export::HtmlRender; use orgize::export::HtmlRender;
use std::io::Cursor; use std::io::Cursor;
macro_rules! parse_assert { macro_rules! html_test {
($content:expr, $expected:expr) => {{ ($name:ident, $content:expr, $expected:expr) => {
let mut cursor = Cursor::new(Vec::new()); #[test]
let mut render = HtmlRender::default(&mut cursor, $content); fn $name() {
render.render().expect("render error"); let mut cursor = Cursor::new(Vec::new());
let s = String::from_utf8(cursor.into_inner()).expect("invalid utf-8"); let mut render = HtmlRender::default(&mut cursor, $content);
assert_eq!(s, $expected); render.render().expect("render error");
}}; let s = String::from_utf8(cursor.into_inner()).expect("invalid utf-8");
assert_eq!(s, $expected);
}
};
} }
#[test] html_test!(
fn emphasis() { emphasis,
parse_assert!( r#"* Title 1
r#"* Title 1
*Section 1* *Section 1*
** Title 2 ** Title 2
_Section 2_ _Section 2_
@ -24,19 +26,15 @@ _Section 2_
/Section 3/ /Section 3/
* Title 4 * Title 4
=Section 4="#, =Section 4="#,
concat!( "<h1>Title 1</h1><section><p><b>Section 1</b></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>\
"<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 3</h1><section><p><i>Section 3</i></p></section>", <h1>Title 4</h1><section><p><code>Section 4</code></p></section>"
"<h1>Title 4</h1><section><p><code>Section 4</code></p></section>" );
)
)
}
#[test] html_test!(
fn list() { list,
parse_assert!( r#"+ 1
r#"+ 1
+ 2 + 2
@ -45,12 +43,9 @@ fn list() {
- 4 - 4
+ 5"#, + 5"#,
concat!( "<section><ul>\
"<section><ul>", <li><p>1</p></li>\
"<li><p>1</p></li>", <li><p>2</p><ul><li><p>3</p></li><li><p>4</p></li></ul></li>\
"<li><p>2</p><ul><li><p>3</p></li><li><p>4</p></li></ul></li>", <li><p>5</p></li>\
"<li><p>5</p></li>", </ul></section>"
"</ul></section>" );
)
)
}