From bf43b56d513048c32f529eda5940926798c23e0a Mon Sep 17 00:00:00 2001 From: bokuweb Date: Fri, 22 Nov 2024 00:43:54 +0900 Subject: [PATCH] fix: toc styles --- docx-core/src/documents/document.rs | 2 +- .../documents/elements/table_of_contents.rs | 57 ++++++++++--------- docx-core/src/documents/mod.rs | 23 +++++--- docx-core/src/documents/styles.rs | 4 +- docx-wasm/package.json | 2 +- .../test/__snapshots__/index.test.js.snap | 14 ++--- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index dc370344..7a1967ba 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -297,7 +297,7 @@ mod tests { let b = Document::new().add_table_of_contents(toc).build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"TOC \o "1-3""# + r#"TOC \o "1-3""# ); } diff --git a/docx-core/src/documents/elements/table_of_contents.rs b/docx-core/src/documents/elements/table_of_contents.rs index b85e4cde..c403f245 100644 --- a/docx-core/src/documents/elements/table_of_contents.rs +++ b/docx-core/src/documents/elements/table_of_contents.rs @@ -189,42 +189,47 @@ impl BuildXML for TableOfContents { } } - let mut p1 = if let Some(ref del) = self.delete { + let p1 = if let Some(ref del) = self.delete { Paragraph::new().add_delete( - Delete::new() - .author(&del.author) - .date(&del.date) - .add_run( - Run::new() - .add_field_char(FieldCharType::Begin, true) - .add_delete_instr_text(DeleteInstrText::TOC(self.instr.clone())) - .add_field_char(FieldCharType::Separate, false), - ) - .add_run(Run::new().add_field_char(FieldCharType::End, false)), - ) - } else { - Paragraph::new() - .add_run( + Delete::new().author(&del.author).date(&del.date).add_run( Run::new() .add_field_char(FieldCharType::Begin, true) - .add_instr_text(InstrText::TOC(self.instr.clone())) + .add_delete_instr_text(DeleteInstrText::TOC(self.instr.clone())) .add_field_char(FieldCharType::Separate, false), - ) - .add_run(Run::new().add_field_char(FieldCharType::End, false)) + ), + ) + } else { + Paragraph::new().add_run( + Run::new() + .add_field_char(FieldCharType::Begin, true) + .add_instr_text(InstrText::TOC(self.instr.clone())) + .add_field_char(FieldCharType::Separate, false), + ) }; - if let Some(ref paragraph_property) = self.paragraph_property { - p1.property = paragraph_property.clone(); - } - b = b.add_child(&p1)?; - if !self.after_contents.is_empty() { + let p2 = Paragraph::new().add_run(Run::new().add_field_char(FieldCharType::End, false)); + + if self.after_contents.is_empty() { + b = b.add_child(&p2)?; + } else { for (i, c) in self.after_contents.iter().enumerate() { match c { TocContent::Paragraph(p) => { // Merge paragraph - b = b.add_child(&p)?; + if i == 0 { + let mut new_p = p.clone(); + new_p.children.insert( + 0, + ParagraphChild::Run(Box::new( + Run::new().add_field_char(FieldCharType::End, false), + )), + ); + b = b.add_child(&new_p)? + } else { + b = b.add_child(&p)?; + } } TocContent::Table(t) => { // insert empty line for table @@ -319,7 +324,7 @@ mod tests { let b = TableOfContents::new().heading_styles_range(1, 3).build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"TOC \o "1-3""# + r#"TOC \o "1-3""# ); } @@ -331,7 +336,7 @@ mod tests { .build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"TOC \o "1-3""# + r#"TOC \o "1-3""# ); } diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index 7be938e6..5644f382 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -541,13 +541,7 @@ impl Docx { }) .collect(); - if !tocs.is_empty() { - for i in 1..=9 { - self.styles = self - .styles - .add_style(crate::documents::preset_styles::toc(i)); - } - } + let has_toc = !tocs.is_empty(); for (i, toc) in tocs { if toc.items.is_empty() && toc.auto { @@ -611,6 +605,21 @@ impl Docx { self.document_rels.has_footnotes = true; } + if has_toc { + for i in 1..=9 { + if !self + .styles + .styles + .iter() + .any(|s| s.name == Name::new(format!("toc {}", i))) + { + self.styles = self + .styles + .add_style(crate::documents::preset_styles::toc(i)); + } + } + } + XMLDocx { content_type: self.content_type.build(), rels: self.rels.build(), diff --git a/docx-core/src/documents/styles.rs b/docx-core/src/documents/styles.rs index ee496b0f..1f6d730b 100644 --- a/docx-core/src/documents/styles.rs +++ b/docx-core/src/documents/styles.rs @@ -9,8 +9,8 @@ use crate::xml_builder::*; #[derive(Debug, Clone, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Styles { - doc_defaults: DocDefaults, - styles: Vec