orgize/README.md
2019-04-24 21:54:51 +08:00

158 lines
3.5 KiB
Markdown

# Orgize
Orgize is a Emacs Org-mode parser written by pure Rust. It behaves like a pull
parser (returning an iterator of events) but not exactly.
Besides, orgize also provides some mechanism for exporting org-mode files to
various formats, e.g. HTML.
## Usage
```toml
[dependencies]
orgize = "0.1.0"
```
```rust
// Rust 2015 only
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
*Section 1*
** Title 2
_Section 2_
* Title 3
/Section 3/
* Title 4
=Section 4="#);
for event in parser {
// handling the event
}
```
### Using Render
You can use the built-in `HtmlRender` to generate html string directly:
```rust
use orgize::export::HtmlRender;
use std::io::{Cursor, Result};
fn main() -> Result<()> {
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::default(&mut cursor, &contents);
render.render()?;
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
MIT