diff --git a/src/help.txt b/src/help.txt new file mode 100644 index 0000000..36e7c05 --- /dev/null +++ b/src/help.txt @@ -0,0 +1,10 @@ +usage: jotdown [option] [file] + +arguments: + file a djot source file. use a dash (`-`) or no argument + to read from stdin + +options: + -h --help show this text + -v --version show the version number + -o --output a file to write the output to. stdout if omitted diff --git a/src/main.rs b/src/main.rs index d8ec06c..45f3e4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,86 @@ +use std::ffi::OsString; +use std::fs::File; +use std::io::BufWriter; use std::io::Read; +use std::process::exit; + +#[derive(Default)] +struct App { + input: Option, + output: Option, +} + +fn parse_args() -> App { + let mut app = App::default(); + + let mut args = std::env::args_os().skip(1).peekable(); + + while let Some(arg) = args.next() { + match (arg.to_string_lossy().as_ref(), args.peek()) { + ("-h" | "--help", _) => { + eprint!("{}", include_str!("./help.txt")); + exit(0); + } + ("-v" | "--version", _) => { + eprintln!("{} v{}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION")); + exit(0); + } + (flag @ ("-o" | "--output"), o) => match o { + Some(o) => { + app.output = Some(o.into()); + args.next(); + } + None => { + eprintln!("please supply an argument to {}", flag); + exit(1); + } + }, + ("-", _) => {} + (file, _) if !file.starts_with('-') => { + if app.input.is_some() { + eprint!("too many arguments\n\n{}", include_str!("./help.txt")); + exit(1) + } + app.input = Some(file.into()); + } + (flag, _) => { + eprint!("unknown flag: {}\n\n{}", flag, include_str!("./help.txt")); + exit(1) + } + } + } + + app +} + +fn run() -> Result<(), std::io::Error> { + let app = parse_args(); + + let content = match app.input { + Some(path) => std::fs::read_to_string(path)?, + None => { + let mut s = String::new(); + std::io::stdin().read_to_string(&mut s)?; + s + } + }; + + let parser = jotdown::Parser::new(&content); + + match app.output { + Some(path) => jotdown::html::write(parser, File::create(path)?)?, + None => jotdown::html::write(parser, BufWriter::new(std::io::stdout()))?, + } + + Ok(()) +} fn main() { - let mut src = String::new(); - std::io::stdin() - .read_to_string(&mut src) - .expect("failed to read utf-8 file"); - - let events = jotdown::Parser::new(&src); - let mut out = std::io::BufWriter::new(std::io::stdout()); - jotdown::html::write(events, &mut out).unwrap(); + match run() { + Ok(()) => {} + Err(e) => { + eprintln!("{}", e); + exit(1); + } + } }