use markdown_extract::{Document, Parser, Section};
use std::convert::TryInto;
use std::error::Error;
use std::fs::File;
use std::path::PathBuf;
use structopt::StructOpt;
#[derive(StructOpt)]
#[structopt(name = "markdown-extract")]
struct Opts {
#[structopt(short = "s", long)]
case_sensitive: bool,
#[structopt(short, long)]
ignore_first_heading: bool,
title: String,
#[structopt(parse(from_os_str))]
path: PathBuf,
}
fn print_section(document: &Document, section: &Section, ignore_first_heading: bool) {
if !ignore_first_heading {
println!(
"{} {}",
"#".repeat(section.level.try_into().unwrap()),
section.title
);
}
println!("{}", section.body);
for child in §ion.children {
print_section(&document, &document[*child], false);
}
}
fn run() -> Result<(), Box<dyn Error>> {
let opts = Opts::from_args();
let mut parser = Parser::new();
let file = File::open(&opts.path)?;
let document = parser.parse_file(file)?;
let matches: Document = document
.iter()
.filter(|section| {
if opts.case_sensitive {
section.title.trim() == opts.title.trim()
} else {
section.title.to_lowercase().trim() == opts.title.to_lowercase().trim()
}
})
.cloned()
.collect();
if matches.is_empty() {
println!("No matches.");
return Ok(());
}
for section in matches {
print_section(&document, §ion, opts.ignore_first_heading);
}
Ok(())
}
fn main() {
std::process::exit(match run() {
Ok(_) => 0,
Err(error) => {
println!("Error: {}", error);
1
}
});
}