From 54c859ed7636e0e64b481687a60a3ba824bb38b2 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Sat, 18 Dec 2021 09:56:32 +0900 Subject: [PATCH] fix: Some options for toc writer (#387) * fix: Some options for toc writer * fix: spec --- docx-core/src/documents/elements/instr_toc.rs | 100 ++++++++++++++++-- .../test/__snapshots__/index.test.js.snap | 6 -- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/docx-core/src/documents/elements/instr_toc.rs b/docx-core/src/documents/elements/instr_toc.rs index 3a1bb36..fdc9574 100644 --- a/docx-core/src/documents/elements/instr_toc.rs +++ b/docx-core/src/documents/elements/instr_toc.rs @@ -27,6 +27,7 @@ pub struct InstrToC { #[serde(skip_serializing_if = "Option::is_none")] omit_page_numbers_level_range: Option<(usize, usize)>, // \b includes entries only from the portion of the document marked by the bookmark named by text in this switch's field-argument. + #[serde(skip_serializing_if = "Option::is_none")] entry_bookmark_name: Option, // \t Uses paragraphs formatted with styles other than the built-in heading styles. // . text in this switch's field-argument specifies those styles as a set of comma-separated doublets, @@ -34,16 +35,21 @@ pub struct InstrToC { styles_with_levels: Vec, // struct S texWin Lis switch's field-argument specifies a sequence of character // . The default is a tab with leader dots. + #[serde(skip_serializing_if = "Option::is_none")] entry_and_page_number_separator: Option, // \d + #[serde(skip_serializing_if = "Option::is_none")] sequence_and_page_numbers_separator: Option, // \a caption_label: Option, // \c + #[serde(skip_serializing_if = "Option::is_none")] caption_label_including_numbers: Option, // \s + #[serde(skip_serializing_if = "Option::is_none")] seq_field_identifier_for_prefix: Option, // \f + #[serde(skip_serializing_if = "Option::is_none")] tc_field_identifier: Option, // \h hyperlink: bool, @@ -147,21 +153,88 @@ impl BuildXML for InstrToC { fn build(&self) -> Vec { let mut instr = "TOC".to_string(); - if let Some(heading_styles_range) = self.heading_styles_range { - instr = format!( - "{} \\o "{}-{}"", - instr, heading_styles_range.0, heading_styles_range.1 - ); + // \a + if let Some(ref t) = self.caption_label { + instr = format!("{} \\a "{}"", instr, t); } + // \b + if let Some(ref t) = self.entry_bookmark_name { + instr = format!("{} \\b "{}"", instr, t); + } + + // \c + if let Some(ref t) = self.caption_label_including_numbers { + instr = format!("{} \\c "{}"", instr, t); + } + + // \d + if let Some(ref t) = self.sequence_and_page_numbers_separator { + instr = format!("{} \\d "{}"", instr, t); + } + + // \f + if let Some(ref t) = self.tc_field_identifier { + instr = format!("{} \\f "{}"", instr, t); + } + + // \l + if let Some(range) = self.tc_field_level_range { + instr = format!("{} \\l "{}-{}"", instr, range.0, range.1); + } + + // \n + if let Some(range) = self.omit_page_numbers_level_range { + instr = format!("{} \\n "{}-{}"", instr, range.0, range.1); + } + + // \o + if let Some(range) = self.heading_styles_range { + instr = format!("{} \\o "{}-{}"", instr, range.0, range.1); + } + + // \p if let Some(ref t) = self.entry_and_page_number_separator { instr = format!("{} \\p "{}"", instr, t); } + // \s + if let Some(ref t) = self.seq_field_identifier_for_prefix { + instr = format!("{} \\s "{}"", instr, t); + } + + // \t + if !self.styles_with_levels.is_empty() { + let s = self + .styles_with_levels + .iter() + .map(|s| format!("{},{}", (s.0).0, (s.0).1)) + .collect::>() + .join(","); + instr = format!("{} \\t "{}"", instr, s); + } + + // \h if self.hyperlink { instr = format!("{} \\h", instr); } + // \u + if self.use_applied_paragraph_line_level { + instr = format!("{} \\u", instr); + } + + // \w + if self.preserve_tab { + instr = format!("{} \\w", instr); + } + + // \x + if self.preserve_new_line { + instr = format!("{} \\x", instr); + } + + // \z if self.hide_tab_and_page_numbers_in_webview { instr = format!("{} \\z", instr); } @@ -261,12 +334,10 @@ impl std::str::FromStr for InstrToC { "\\t" => { if let Some(r) = s.next() { let r = r.replace(""", "").replace("\"", ""); - dbg!(&r); let mut r = r.split(','); loop { if let Some(style) = r.next() { - if let Some(level) = r - .next() { + if let Some(level) = r.next() { if let Ok(level) = usize::from_str(level) { toc = toc.add_style_with_level(StyleWithLevel(( style.to_string(), @@ -307,6 +378,19 @@ mod tests { assert_eq!(str::from_utf8(&b).unwrap(), r#"TOC \o "1-3""#); } + #[test] + fn test_toc_with_styles() { + let b = InstrToC::new() + .heading_styles_range(1, 3) + .add_style_with_level(StyleWithLevel::new("style1", 2)) + .add_style_with_level(StyleWithLevel::new("style2", 3)) + .build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#"TOC \o "1-3" \t "style1,2,style2,3""# + ); + } + #[test] fn read_toc_with_o_and_h() { let i = r#"TOC \o "1-3" \h"#; diff --git a/docx-wasm/test/__snapshots__/index.test.js.snap b/docx-wasm/test/__snapshots__/index.test.js.snap index 24ddf10..8999902 100644 --- a/docx-wasm/test/__snapshots__/index.test.js.snap +++ b/docx-wasm/test/__snapshots__/index.test.js.snap @@ -23123,9 +23123,6 @@ Object { "data": Object { "data": Object { "caption_label": null, - "caption_label_including_numbers": null, - "entry_and_page_number_separator": null, - "entry_bookmark_name": null, "heading_styles_range": Array [ 1, 3, @@ -23134,10 +23131,7 @@ Object { "hyperlink": true, "preserve_new_line": false, "preserve_tab": false, - "seq_field_identifier_for_prefix": null, - "sequence_and_page_numbers_separator": null, "styles_with_levels": Array [], - "tc_field_identifier": null, "use_applied_paragraph_line_level": true, }, "type": "toc",