use std::path::PathBuf;
use anyhow::{Context, Result, bail};
use bookforge_pdf::{ColumnMode, ConvertOptions, convert_pdf};
use clap::Args;
#[derive(Debug, Args)]
pub struct ConvertArgs {
pub input: PathBuf,
#[arg(long)]
pub out: Option<PathBuf>,
#[arg(long, value_enum, default_value_t = ColumnsArg::Auto)]
pub columns: ColumnsArg,
#[arg(long, default_value = "en")]
pub language: String,
#[arg(long)]
pub title: Option<String>,
#[arg(long)]
pub report: Option<PathBuf>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum ColumnsArg {
Auto,
#[value(name = "1")]
Single,
#[value(name = "2")]
Two,
}
impl From<ColumnsArg> for ColumnMode {
fn from(value: ColumnsArg) -> Self {
match value {
ColumnsArg::Auto => ColumnMode::Auto,
ColumnsArg::Single => ColumnMode::Single,
ColumnsArg::Two => ColumnMode::Two,
}
}
}
pub async fn run(args: ConvertArgs) -> Result<()> {
if !args.input.exists() {
bail!("input PDF does not exist: {}", args.input.display());
}
let output = args
.out
.clone()
.unwrap_or_else(|| args.input.with_extension("epub"));
let report_path = args
.report
.clone()
.unwrap_or_else(|| output.with_extension("convert.json"));
let options = ConvertOptions {
columns: args.columns.into(),
language: args.language.clone(),
title: args.title.clone().unwrap_or_default(),
};
let outcome = convert_pdf(&args.input, &output, &options)
.with_context(|| format!("converting {}", args.input.display()))?;
let json = serde_json::to_string_pretty(&outcome.report)?;
std::fs::write(&report_path, json)
.with_context(|| format!("writing report {}", report_path.display()))?;
println!("Input: {}", args.input.display());
println!("Output: {}", outcome.output.display());
print!("{}", outcome.report.summary());
println!("Report: {}", report_path.display());
println!();
println!("Check coverage before translating:");
println!(" bookforge inspect \"{}\"", outcome.output.display());
println!(
" bookforge translate \"{}\" --target <language> ...",
outcome.output.display()
);
Ok(())
}