2019-03-13 08:16:57 +00:00
|
|
|
use std::convert::From;
|
|
|
|
use std::env::args;
|
2019-06-26 18:53:50 +01:00
|
|
|
use std::fs;
|
|
|
|
use std::io::{Error as IOError, Write};
|
|
|
|
use std::result::Result;
|
2019-03-13 08:16:57 +00:00
|
|
|
use std::string::FromUtf8Error;
|
2019-02-14 05:38:48 +00:00
|
|
|
|
2019-06-27 13:05:54 +01:00
|
|
|
use orgize::export::{html::Escape, DefaultHtmlHandler, HtmlHandler};
|
|
|
|
use orgize::{Element, Org};
|
2019-06-26 18:53:50 +01:00
|
|
|
use slugify::slugify;
|
2019-02-14 05:38:48 +00:00
|
|
|
|
2019-03-13 08:16:57 +00:00
|
|
|
#[derive(Debug)]
|
2019-06-26 18:53:50 +01:00
|
|
|
enum MyError {
|
2019-03-13 08:16:57 +00:00
|
|
|
IO(IOError),
|
|
|
|
Heading,
|
|
|
|
Utf8(FromUtf8Error),
|
|
|
|
}
|
|
|
|
|
2019-06-26 18:53:50 +01:00
|
|
|
// From<std::io::Error> trait is required for custom error type
|
|
|
|
impl From<IOError> for MyError {
|
|
|
|
fn from(err: IOError) -> Self {
|
|
|
|
MyError::IO(err)
|
2019-03-13 08:16:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-26 18:53:50 +01:00
|
|
|
impl From<FromUtf8Error> for MyError {
|
|
|
|
fn from(err: FromUtf8Error) -> Self {
|
|
|
|
MyError::Utf8(err)
|
2019-03-13 08:16:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-27 07:03:42 +01:00
|
|
|
struct MyHtmlHandler;
|
2019-03-13 08:16:57 +00:00
|
|
|
|
2019-06-27 07:03:42 +01:00
|
|
|
impl HtmlHandler<MyError> for MyHtmlHandler {
|
2019-06-27 13:05:54 +01:00
|
|
|
fn start<W: Write>(&mut self, mut w: W, element: &Element<'_>) -> Result<(), MyError> {
|
2019-06-26 18:53:50 +01:00
|
|
|
let mut default_handler = DefaultHtmlHandler;
|
2019-06-27 13:05:54 +01:00
|
|
|
match element {
|
|
|
|
Element::Headline { headline, .. } => {
|
|
|
|
if headline.level > 6 {
|
2019-06-26 18:53:50 +01:00
|
|
|
return Err(MyError::Heading);
|
|
|
|
} else {
|
2019-06-27 13:05:54 +01:00
|
|
|
let slugify = slugify!(headline.title);
|
2019-06-26 18:53:50 +01:00
|
|
|
write!(
|
|
|
|
w,
|
|
|
|
"<h{0}><a id=\"{1}\" href=\"#{1}\">{2}</a></h{0}>",
|
2019-06-27 13:05:54 +01:00
|
|
|
headline.level,
|
|
|
|
slugify,
|
|
|
|
Escape(headline.title),
|
2019-06-26 18:53:50 +01:00
|
|
|
)?;
|
|
|
|
}
|
|
|
|
}
|
2019-06-27 13:05:54 +01:00
|
|
|
// fallthrough to default handler
|
|
|
|
_ => default_handler.start(w, element)?,
|
2019-03-13 08:16:57 +00:00
|
|
|
}
|
2019-06-26 18:53:50 +01:00
|
|
|
Ok(())
|
2019-02-14 05:38:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-26 18:53:50 +01:00
|
|
|
fn main() -> Result<(), MyError> {
|
2019-02-14 05:38:48 +00:00
|
|
|
let args: Vec<_> = args().collect();
|
|
|
|
|
|
|
|
if args.len() < 2 {
|
2019-06-26 18:53:50 +01:00
|
|
|
eprintln!("Usage: {} <org-file>", args[0]);
|
2019-02-14 05:38:48 +00:00
|
|
|
} else {
|
2019-06-26 18:53:50 +01:00
|
|
|
let contents = String::from_utf8(fs::read(&args[1])?)?;
|
2019-02-14 05:38:48 +00:00
|
|
|
|
2019-06-27 06:20:21 +01:00
|
|
|
let mut writer = Vec::new();
|
2019-06-27 07:03:42 +01:00
|
|
|
Org::parse(&contents).html(&mut writer, MyHtmlHandler)?;
|
2019-02-14 05:38:48 +00:00
|
|
|
|
2019-06-26 18:53:50 +01:00
|
|
|
println!("{}", String::from_utf8(writer)?);
|
2019-02-14 05:38:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|