1//! Writes a section's pages, or one titled page, as the PDF Print and Export as PDF make.
2//! `print_pdf SECTION.one NEW.pdf [TITLE] [--a4]`
3
4use canvas::{layout::TextEngine, print};
5use onestore::{RevisionIndex, Store, document::Document, page::Page};
6use std::{env, fs, path::Path};
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let args: Vec<String> = env::args().skip(1).collect();
10 let [section, destination, rest @ ..] = args.as_slice() else {
11 return Err("Expected a section, a new PDF path and optionally a page title".into());
12 };
13 let a4 = rest.iter().any(|arg| arg == "--a4");
14 let title = rest.iter().find(|arg| *arg != "--a4");
15 let bytes = fs::read(section)?;
16 let store = Store::parse(&bytes)?;
17 let index = RevisionIndex::parse(&store)?;
18 let document = Document::parse(&index)?;
19 let mut spaces: Vec<_> = document
20 .pages()?
21 .into_iter()
22 .map(|(space, _)| space)
23 .collect();
24 spaces.dedup();
25 let pages = spaces
26 .into_iter()
27 .map(|space| Page::from_space(&document, space))
28 .collect::<Result<Vec<_>, _>>()?
29 .into_iter()
30 .filter(|page| title.is_none_or(|title| page.title == *title))
31 .collect();
32 let name = Path::new(section)
33 .file_stem()
34 .and_then(|stem| stem.to_str())
35 .unwrap_or_default();
36 let setup = print::Setup {
37 paper: if a4 { print::A4 } else { print::LETTER },
38 fit_width: true,
39 footer: print::Footer::SectionAndPage,
40 };
41 let pdf = print::pdf(
42 vec![(name.to_owned(), pages)],
43 &mut TextEngine::default(),
44 &setup,
45 )?;
46 fs::write(destination, pdf)?;
47 Ok(())
48}