use argh::FromArgs;
use c2pdf::code_to_pdf::CodeToPdf;
use c2pdf::dimensions::Dimensions;
use c2pdf::font_loader::load_font;
use c2pdf::logging::Logger;
use core::f32;
use log::{error, info};
use printpdf::*;
use std::fs::File;
use std::num::NonZeroU8;
use std::path::PathBuf;
use std::time::Instant;
type StringVec = Vec<String>;
fn vec_from_string(s: &str) -> Result<StringVec, String> {
Ok(s.split(",").map(str::to_string).collect())
}
#[derive(FromArgs)]
struct Arguments {
#[argh(positional)]
walk_path: String,
#[argh(option, default = "String::from(\"output.pdf\")")]
out: String,
#[argh(
option,
from_str_fn(vec_from_string),
default = "vec![\"pnpm-lock.yaml\".into(), \"Cargo.lock\".into()]"
)]
exclude: StringVec,
#[argh(option, default = "true")]
include_path: bool,
#[argh(option, default = "String::from(\"Project Code\")")]
name: String,
#[argh(option)]
font: Option<String>,
#[argh(option, default = "12.0")]
font_size: f32,
#[argh(option, default = "20.0")]
margin_top: f32,
#[argh(option, default = "5.0")]
margin_bottom: f32,
#[argh(option, default = "10.0")]
margin_left: f32,
#[argh(option, default = "10.0")]
margin_right: f32,
#[argh(option)]
page_text: Option<String>,
#[argh(option)]
threads: Option<NonZeroU8>,
#[argh(switch)]
no_log: bool,
#[argh(option, default = "0.85")]
image_quality: f32,
}
fn main() {
let args: Arguments = argh::from_env();
let logger = Box::leak(Box::new(Logger::new(crossbeam_channel::unbounded())));
log::set_logger(logger)
.map(|()| {
if !args.no_log {
log::set_max_level(log::LevelFilter::Trace)
}
})
.expect("should be able to set logger");
let path = args.walk_path;
let page_dimensions = Dimensions::new(
Mm(210.0),
Mm(297.0),
Mm(args.margin_top),
Mm(args.margin_bottom),
Mm(args.margin_left),
Mm(args.margin_right),
);
let mut doc = PdfDocument::new(&args.name);
let (font_bytes, font_loaded) = load_font(args.font);
if let c2pdf::font_loader::FontLoaded::FailProvided = font_loaded {
error!("Unable to load provided font")
}
let font_bytes = &*font_bytes;
let font = ParsedFont::from_bytes(font_bytes, 0, &mut vec![]).unwrap();
let font_id = doc.add_font(&font);
let start = Instant::now();
let (doc_subset, processed_file_count) = CodeToPdf::run_parallel(
font_id,
font_bytes,
PathBuf::from(path),
args.exclude,
page_dimensions,
args.font_size,
args.page_text,
args.include_path,
args.threads,
);
doc_subset.lock().unwrap().to_document(&mut doc);
let num_pages = doc.pages.len();
let f = File::create(args.out).unwrap();
let mut f = std::io::BufWriter::new(f);
doc.save_writer(
&mut f,
&PdfSaveOptions {
image_optimization: Some(ImageOptimizationOptions {
quality: Some(args.image_quality),
max_image_size: None,
..Default::default()
}),
..Default::default()
},
&mut vec![],
);
info!("Done!");
info!(
"Processed {} files and generated {} pages in {} seconds",
processed_file_count,
num_pages,
start.elapsed().as_secs_f32()
)
}