109 lines
3.8 KiB
Rust
109 lines
3.8 KiB
Rust
use std::path::PathBuf;
|
|
use std::fs::read_to_string;
|
|
use std::hash::{Hash, Hasher};
|
|
|
|
use anyhow::{bail, Result};
|
|
use structopt::StructOpt;
|
|
|
|
mod frontmatter;
|
|
mod generate;
|
|
|
|
#[derive(Debug, StructOpt)]
|
|
//#[structopt(name = "brochurise", about = "Produce PDF zines (brochures) from your Markdown files")]
|
|
#[structopt(name = "brochurise")]
|
|
/// Produce PDF from your Markdown documents. Uses pandoc and pdfbook to produce linear A4
|
|
/// or A5 booklets (also called zines, brochures or books).
|
|
/// Multiple documents are generated to find the optimal font size (minimize free space without
|
|
/// requiring an additional A4 sheet, compared to the base size).
|
|
struct Cli {
|
|
// Positional arguments
|
|
#[structopt(parse(from_os_str))]
|
|
/// Path to the Markdown file to be brochurised
|
|
input: PathBuf,
|
|
/// Path to the PDF file to produce. When producing both linear and book output (default
|
|
/// behavior, unless -b or -l is set), `-book` will be appended to the book output path
|
|
/// eg. output.pdf and output-book.pdf
|
|
output: Option<PathBuf>,
|
|
// Additional arguments
|
|
#[structopt(short = "d", long = "debug")]
|
|
/// Enable debug output
|
|
debug: bool,
|
|
|
|
#[structopt(short = "l", long = "linear")]
|
|
/// Only produce a linear A4 output
|
|
linear: bool,
|
|
#[structopt(short = "b", long = "book", conflicts_with = "linear")]
|
|
/// Only produce an A5 booklet (4 pages per A4 sheet)
|
|
book: bool,
|
|
|
|
#[structopt(short = "s", long = "size", default_value = "11")]
|
|
/// The smallest size to generate the PDF with
|
|
size: u8,
|
|
|
|
#[structopt(short = "t", long = "template")]
|
|
/// The lateX template to use
|
|
template: Option<String>,
|
|
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
let cli = Cli::from_args();
|
|
|
|
if !cli.input.is_file() {
|
|
bail!("File does not exist: {:?}", &cli.input);
|
|
}
|
|
|
|
let source = read_to_string(&cli.input)?;
|
|
|
|
let (content, metadata) = frontmatter::extract(&source)?;
|
|
|
|
if cli.debug {
|
|
println!("{}", content);
|
|
}
|
|
|
|
let output = match cli.output {
|
|
Some(path) => path,
|
|
None => {
|
|
let mut path = PathBuf::from(cli.input.parent().unwrap());
|
|
path.push(cli.input.file_stem().unwrap());
|
|
path.set_extension("pdf");
|
|
path
|
|
}
|
|
};
|
|
|
|
match (cli.book, cli.linear) {
|
|
(true, false) => {
|
|
let mut tmp = std::env::temp_dir();
|
|
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
|
cli.input.hash(&mut hasher);
|
|
|
|
tmp.push(hasher.finish().to_string());
|
|
tmp.set_extension("pdf");
|
|
|
|
let pages_count = generate::linear(&content, tmp.clone(), &cli.size, metadata, &cli.template)?;
|
|
println!("Intermediary step: generated linear output to {:?} ({} pages)", &tmp, pages_count);
|
|
generate::book(&tmp, &output)?;
|
|
println!("Generated A5 booklet output to {:?}", output);
|
|
},
|
|
(false, true) => {
|
|
// Only linear output
|
|
let pages_count = generate::linear(&content, output.clone(), &cli.size, metadata, &cli.template)?;
|
|
println!("Generated linear A4 output to {:?} ({} pages)", output, pages_count);
|
|
},
|
|
(false, false) => {
|
|
// Both outputs
|
|
let pages_count = generate::linear(&content, output.clone(), &cli.size, metadata, &cli.template)?;
|
|
println!("Generated linear A4 output to {:?} ({} pages)", output, pages_count);
|
|
let mut book_output = output.clone();
|
|
book_output.set_extension("book.pdf");
|
|
generate::book(&output, &book_output)?;
|
|
println!("Generated A5 booklet output to {:?}", book_output);
|
|
},
|
|
(true, true) => {
|
|
unreachable!("-b conflicts with -l so this branch should never be reached");
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|