use liteparse::config::{ImageMode, LiteParseConfig, OutputFormat};
use liteparse::parser::LiteParse;
pub struct PdfImage {
pub name: String,
pub bytes: Vec<u8>,
}
pub struct PdfConversion {
pub markdown: String,
pub images: Vec<PdfImage>,
pub total_pages: usize,
}
pub fn pdf_to_markdown(
file_path: &str,
embed_images: bool,
) -> Result<PdfConversion, String> {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.map_err(|e| format!("Failed to start async runtime: {e}"))?;
let path = file_path.to_string();
runtime.block_on(async move {
let mut config = LiteParseConfig::default();
config.ocr_enabled = false;
config.output_format = OutputFormat::Markdown;
config.image_mode = if embed_images {
ImageMode::Embed
} else {
ImageMode::Placeholder
};
config.quiet = true;
let parser = LiteParse::new(config);
let result = parser
.parse(&path)
.await
.map_err(|e| format!("liteparse failed to parse PDF: {e}"))?;
let total_pages = result.pages.len();
let markdown = result
.pages
.iter()
.map(|p| p.markdown.trim_end().to_string())
.filter(|m| !m.is_empty())
.collect::<Vec<_>>()
.join("\n\n---\n\n");
let images = if embed_images {
result
.images
.into_iter()
.map(|img| PdfImage {
name: format!("image_{}.png", img.id),
bytes: (*img.bytes).clone(),
})
.collect()
} else {
Vec::new()
};
Ok(PdfConversion {
markdown,
images,
total_pages,
})
})
}