Files
wordcraft/crates/engine/src/io_ext.rs
T
f7a84fbfb8 Print Markup: comments in PDF, print, images and text copies (#589) (#667)
Rebased onto main as one commit (the branch had merge commits from main).

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-11 23:38:29 -04:00

42 lines
2.3 KiB
Rust

//! Format crates registered with the I/O dispatcher.
use wordcraft_doc::Document;
/// Open a format other than plain text / JSON.
pub fn open(ext: &str, bytes: &[u8]) -> Option<Result<Document, String>> {
match ext {
"docx" | "docm" | "dotx" | "dotm" => Some(wordcraft_docx::read(bytes).map_err(|e| e.to_string())),
"doc" | "dot" => Some(wordcraft_docbin::read(bytes).map_err(|e| e.to_string())),
// Word XML Document (Flat OPC) or Word 2003 XML, told apart by the root element.
"xml" => Some(wordcraft_docx::read_xml(bytes).map_err(|e| e.to_string())),
other => wordcraft_formats::import(other, bytes),
}
}
/// Save to a format other than plain text / JSON.
pub fn save(ext: &str, doc: &Document, opts: &crate::io::ExportOptions) -> Option<Result<Vec<u8>, String>> {
// .docx/.docm/.dotx/.dotm: the extension picks the package flavour Word expects.
if let Some(flavor) = wordcraft_docx::Flavor::from_ext(ext) {
return Some(wordcraft_docx::write_as(doc, flavor).map_err(|e| e.to_string()));
}
match ext {
"xml" => Some(wordcraft_docx::write_flat(doc).map_err(|e| e.to_string())),
"png" => Some(render_png(doc, 0, 2.0, opts)),
"pdf" => {
let pdf = wordcraft_pdf::PdfOptions { include_markup: opts.markup, comments: opts.markup && opts.comments, ..Default::default() };
Some(wordcraft_pdf::export(doc, &pdf).map_err(|e| e.to_string()))
}
other => wordcraft_formats::export_with(other, doc, &wordcraft_formats::ExportOptions { comments: opts.markup && opts.comments }),
}
}
/// Render page `page` as PNG at `scale` px/pt. With Print Markup's comments the page has its
/// markup area with the comments in balloons (page images always show tracked changes).
pub fn render_png(doc: &Document, page: usize, scale: f32, opts: &crate::io::ExportOptions) -> Result<Vec<u8>, String> {
let lo = wordcraft_layout::LayoutOptions { comment_balloons: opts.markup && opts.comments, ..Default::default() };
let l = wordcraft_layout::layout(doc, &mut wordcraft_layout::LayoutCache::new(), &lo);
let p = l.pages.get(page).ok_or_else(|| format!("no page {}", page + 1))?;
let img = wordcraft_render::render_page(doc, p, scale, &Default::default());
Ok(img.to_png())
}