114 lines
3.6 KiB
Rust
114 lines
3.6 KiB
Rust
use std::path::{PathBuf, Path};
|
|
use std::process::Command;
|
|
|
|
use anyhow::{bail, Result};
|
|
use regex::Regex;
|
|
|
|
pub fn linear(content: &str, output: PathBuf, basesize: &u8, metadata: Vec<(String, String)>, template: &Option<String>) -> Result<u8> {
|
|
let mut pandoc = pandoc::new();
|
|
pandoc.set_input(pandoc::InputKind::Pipe(content.to_string()));
|
|
pandoc.set_input_format(pandoc::InputFormat::Commonmark, Vec::new());
|
|
pandoc.set_output_format(pandoc::OutputFormat::Latex, Vec::new());
|
|
pandoc.add_option(pandoc::PandocOption::PdfEngine("pdflatex".into()));
|
|
for (key, value) in metadata {
|
|
pandoc.set_variable(&key, &value);
|
|
}
|
|
|
|
if template.is_some() {
|
|
pandoc.set_latex_template(&template.as_ref().unwrap());
|
|
}
|
|
|
|
let mut current_size = basesize.clone();
|
|
let mut sheets: Option<u8> = None;
|
|
while current_size <= basesize + 10 {
|
|
println!("DOING SIZE {}", current_size);
|
|
pandoc.set_variable("fontsize", &format!("{}pt", current_size));
|
|
let current_output = sized_output(&output, ¤t_size);
|
|
let pages = make_linear(&mut pandoc, ¤t_output)?;
|
|
let current_sheets = match pages % 4 {
|
|
0 => pages / 4 + 1,
|
|
_ => pages / 4
|
|
};
|
|
|
|
match sheets {
|
|
None => {
|
|
sheets = Some(current_sheets);
|
|
},
|
|
Some(s) => {
|
|
if s != current_sheets {
|
|
// We have grown too big, remove current iteration
|
|
// and place the previous one to output
|
|
std::fs::remove_file(current_output)?;
|
|
current_size = current_size - 1;
|
|
let current_output = sized_output(&output, ¤t_size);
|
|
std::fs::rename(¤t_output, &output)?;
|
|
return count_pages(&output);
|
|
} else {
|
|
// We haven't grown too big, remove the previous iteration output
|
|
let previous_size = current_size - 1;
|
|
std::fs::remove_file(sized_output(&output, &previous_size))?;
|
|
}
|
|
}
|
|
}
|
|
|
|
current_size = current_size + 1;
|
|
}
|
|
|
|
Ok(0)
|
|
/*
|
|
pandoc.execute()?;
|
|
|
|
let pages_count = count_pages(&output)?;
|
|
|
|
Ok(pages_count)
|
|
*/
|
|
}
|
|
|
|
fn make_linear(pandoc: &mut pandoc::Pandoc, output: &Path) -> Result<u8> {
|
|
pandoc.set_output(pandoc::OutputKind::File(output.to_path_buf()));
|
|
pandoc.clone().execute()?;
|
|
Ok(count_pages(&output)?)
|
|
}
|
|
|
|
pub fn book(input: &Path, output: &Path) -> Result<()> {
|
|
let status = Command::new("pdfbook")
|
|
.arg("--short-edge")
|
|
.arg("--outfile")
|
|
.arg(output)
|
|
.arg(input)
|
|
.status()?;
|
|
if !status.success() {
|
|
bail!("Running pdfjam failed!")
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn count_pages(pdf_file: &Path) -> Result<u8> {
|
|
let output = Command::new("pdfinfo")
|
|
.arg(pdf_file)
|
|
.output()?;
|
|
|
|
let stdout = std::str::from_utf8(&output.stdout)?;
|
|
let stderr = std::str::from_utf8(&output.stderr)?;
|
|
|
|
if !output.status.success() {
|
|
bail!("Running pdfinfo failed! STDERR:\n{}", stderr);
|
|
}
|
|
|
|
let regex: Regex = Regex::new(r"Pages:\s*(\d+)").unwrap();
|
|
if !regex.is_match(stdout) {
|
|
bail!("Could not extract pages count for {}", pdf_file.display());
|
|
}
|
|
|
|
let caps = regex.captures(&stdout).unwrap();
|
|
let count: u8 = caps[1].parse()?;
|
|
|
|
Ok(count)
|
|
}
|
|
|
|
fn sized_output(output: &Path, size: &u8) -> PathBuf {
|
|
let mut sized_output = output.to_path_buf();
|
|
sized_output.set_extension(&format!("{}.pdf", size));
|
|
sized_output
|
|
}
|