mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 09:59:47 -06:00
Place: Word 97-2003 .doc files place as area type with their formatting
File > Place reads a Word 97-2003 document (a compound file named .doc, or one that holds a WordDocument stream) and sets its main text as area type, as it does for .rtf and .docx files. The text comes from the piece table, in 16-bit Unicode or compressed 8-bit pieces. Formatting is resolved from the style sheet's default font, the paragraph style, the character style and the direct character and paragraph properties, and keeps the same properties the .docx reader maps. Table cells are separated by tabs and each row is a paragraph, and a field places as its result. Hidden and deleted text, pictures, headers, footers, notes, comments and text boxes are left out, and the reply's warnings name each kind of content left out or changed once. Word 6.0 and Word 95 documents, encrypted documents and documents last saved with fast save are refused, and so are structures that lie outside their streams. The compound file is read with the cfb crate (MIT), which adds one package to Cargo.lock.
This commit is contained in:
@@ -124,8 +124,9 @@ pub(crate) use export_names::{default_name, merge, unique_file_names, with_black
|
||||
use export_names::{distinct_names, write_encoded};
|
||||
use formats::{ARTBOARD, ARTBOARDS, RANGE, USE_ARTBOARDS, writable};
|
||||
pub use formats::{
|
||||
DOCX_EXTS, FORMATS, Format, FormatOption, OPEN_EXTS, PLACE_EXTS, RTF_EXTS, TEXT_EXTS, UNASSOCIATED_EXTS, export_extensions, extension, file_stem,
|
||||
format, format_for_name, has_own_title, library_open_filters, open_filters, place_filters, plugin_formats, titled_for_export, writable_format,
|
||||
DOC_EXTS, DOCX_EXTS, FORMATS, Format, FormatOption, OPEN_EXTS, PLACE_EXTS, RTF_EXTS, TEXT_EXTS, UNASSOCIATED_EXTS, export_extensions, extension,
|
||||
file_stem, format, format_for_name, has_own_title, library_open_filters, open_filters, place_filters, plugin_formats, titled_for_export,
|
||||
writable_format,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -566,8 +566,14 @@ pub const RTF_EXTS: &[&str] = &["rtf"];
|
||||
/// Word documents: File → Place sets them as area type with their formatting.
|
||||
pub const DOCX_EXTS: &[&str] = &["docx"];
|
||||
|
||||
/// Every extension File → Place reads: [`OPEN_EXTS`], [`TEXT_EXTS`], [`RTF_EXTS`] and
|
||||
/// [`DOCX_EXTS`].
|
||||
/// Word 97-2003 documents: File → Place sets them as area type with their formatting.
|
||||
pub const DOC_EXTS: &[&str] = &["doc"];
|
||||
|
||||
/// The Place dialog's Word filter: Word documents and Word 97-2003 documents.
|
||||
const WORD_EXTS: &[&str] = &["docx", "doc"];
|
||||
|
||||
/// Every extension File → Place reads: [`OPEN_EXTS`], [`TEXT_EXTS`], [`RTF_EXTS`],
|
||||
/// [`DOCX_EXTS`] and [`DOC_EXTS`].
|
||||
pub const PLACE_EXTS: &[&str] = &[
|
||||
"vectorcraft",
|
||||
"drawcraft",
|
||||
@@ -610,6 +616,7 @@ pub const PLACE_EXTS: &[&str] = &[
|
||||
"txt",
|
||||
"rtf",
|
||||
"docx",
|
||||
"doc",
|
||||
];
|
||||
|
||||
/// One dialog filter per readable format.
|
||||
@@ -645,13 +652,13 @@ pub fn library_open_filters(
|
||||
}
|
||||
|
||||
/// File → Place dialog filters: "All placeable files", then one per placeable format, then text,
|
||||
/// RTF and Word.
|
||||
/// RTF and Word (`.docx` and `.doc`).
|
||||
pub fn place_filters() -> impl Iterator<Item = (&'static str, &'static [&'static str])> {
|
||||
std::iter::once(("All placeable files", PLACE_EXTS))
|
||||
.chain(format_filters().filter(|(_, exts)| exts.iter().all(|ext| PLACE_EXTS.contains(ext))))
|
||||
.chain(std::iter::once(("Text", TEXT_EXTS)))
|
||||
.chain(std::iter::once(("RTF", RTF_EXTS)))
|
||||
.chain(std::iter::once(("Word", DOCX_EXTS)))
|
||||
.chain(std::iter::once(("Word", WORD_EXTS)))
|
||||
}
|
||||
|
||||
/// A format by id or extension (any case, leading dot allowed; `jpeg` finds `jpg`): a built-in
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
//! - An RTF file becomes area type with its character and paragraph formatting ([`rtf`]).
|
||||
//! - A Word document (`.docx`) becomes area type with the character and paragraph formatting its
|
||||
//! styles and direct formatting give ([`docx`]).
|
||||
//! - A Word 97-2003 document (`.doc`) becomes area type the same way, its main text read from its
|
||||
//! compound file, with a warning for each kind of content left out ([`doc`]).
|
||||
//! - A VectorCraft document placed from a file with Link (the default) becomes a placed document:
|
||||
//! one locked object showing the artboard `page`, linked to the file and read again when it
|
||||
//! changes ([`document`]); without Link, an editable copy of its art.
|
||||
@@ -30,6 +32,7 @@
|
||||
//! `place` tool) with several files, which emits one `file.place` per click or drag.
|
||||
|
||||
pub(crate) mod adopt;
|
||||
mod doc;
|
||||
pub(crate) mod document;
|
||||
pub(crate) mod docx;
|
||||
mod rtf;
|
||||
@@ -169,6 +172,15 @@ fn load(p: &Value, cmd: &str, board: Option<Rect>, link_pdf: bool) -> Result<Loa
|
||||
}
|
||||
return Ok(Loaded { name, format: &docx::FORMAT, art: Art::Text(story), natural: TEXT_FRAME, warnings: vec![], link: None, board: None });
|
||||
}
|
||||
// A Word 97-2003 document is recognized by its name or by its compound file's WordDocument
|
||||
// stream.
|
||||
if doc::is_doc(src.name, &src.bytes) {
|
||||
let (story, warnings) = doc::import(&src.bytes, cmd)?;
|
||||
if story.plain_text().trim().is_empty() {
|
||||
return Err(bad(cmd, format!("`{name}` has no text to place")));
|
||||
}
|
||||
return Ok(Loaded { name, format: &doc::FORMAT, art: Art::Text(story), natural: TEXT_FRAME, warnings, link: None, board: None });
|
||||
}
|
||||
let format = fileio::detect(src.name, &src.bytes)
|
||||
.ok_or_else(|| bad(cmd, format!("can't place `{name}`: not a format VectorCraft reads (see document.formats)")))?;
|
||||
let page = match p.get("page") {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user