diff --git a/crates/hwp-convert/src/docx.rs b/crates/hwp-convert/src/docx.rs index bb87858..d3c37e3 100644 --- a/crates/hwp-convert/src/docx.rs +++ b/crates/hwp-convert/src/docx.rs @@ -59,6 +59,7 @@ pub fn to_docx(doc: &Document) -> std::io::Result> { document_xml(&b.body).into_bytes(), ), ("word/styles.xml".into(), styles_xml(doc).into_bytes()), + ("word/settings.xml".into(), SETTINGS_XML.into()), ( "word/_rels/document.xml.rels".into(), b.doc_rels_xml().into_bytes(), @@ -558,6 +559,9 @@ impl Builder<'_> { rels.push_str( "", ); + rels.push_str( + "", + ); if self.uses_numbering(self.doc) { rels.push_str( "", @@ -815,6 +819,17 @@ fn sect_pr_xml(page: Option<&hwp_model::PageDef>) -> String { ) } +/// settings.xml — without a part declaring `compatibilityMode`, Word assumes the 2007 content +/// model and opens the document in Compatibility Mode (observed on Word 16.111.2 for macOS). +/// 15 is the Word 2013+ mode. +const SETTINGS_XML: &str = concat!( + "", + "", + "", + "" +); + fn styles_xml(doc: &Document) -> String { let body_font = doc.header.fonts[0] .first() @@ -947,6 +962,7 @@ fn content_types_xml(b: &Builder) -> String { \ \ \ + \ ", ); if b.uses_numbering(b.doc) { @@ -1276,6 +1292,13 @@ mod tests { .unwrap() .contains("Heading1") ); + // Regression: without this part Word opens the document in Compatibility Mode. + assert!( + unzip(&bytes, "word/settings.xml") + .unwrap() + .contains("w:name=\"compatibilityMode\" w:uri=\"http://schemas.microsoft.com/office/word\" w:val=\"15\""), + "settings.xml compatibilityMode" + ); assert!(unzip(&bytes, "[Content_Types].xml").is_some()); assert!(unzip(&bytes, "_rels/.rels").is_some()); assert!(unzip(&bytes, "word/_rels/document.xml.rels").is_some());