From 9a1b92f04676693d2d33db93aa6e77c99dd8459e Mon Sep 17 00:00:00 2001 From: bokuweb Date: Fri, 6 Dec 2019 19:18:48 +0900 Subject: [PATCH 1/2] feat: Add numberings --- docx-core/src/documents/elements/level.rs | 93 ++++ docx-core/src/documents/elements/level_jc.rs | 36 ++ .../src/documents/elements/level_text.rs | 36 ++ docx-core/src/documents/elements/mod.rs | 12 + .../src/documents/elements/number_format.rs | 39 ++ docx-core/src/documents/elements/numbering.rs | 64 +++ docx-core/src/documents/elements/start.rs | 36 ++ docx-core/src/documents/mod.rs | 2 + docx-core/src/documents/numberings.rs | 52 ++ docx-core/src/xml_builder/elements.rs | 13 + docx-core/src/xml_builder/mod.rs | 1 + docx-core/src/xml_builder/numbering.rs | 27 + docx-core/tests/output/word/styles.xml | 23 +- fixtures/numbering/word/numbering.xml | 466 +++++++++++++++++- fixtures/word_default/[Content_Types].xml | 2 + fixtures/word_default/_rels/.rels | 2 + fixtures/word_default/docProps/app.xml | 2 + fixtures/word_default/docProps/core.xml | 2 + .../word_default/word/_rels/document.xml.rels | 2 + fixtures/word_default/word/document.xml | 60 +++ fixtures/word_default/word/fontTable.xml | 2 + fixtures/word_default/word/numbering.xml | 120 +++++ fixtures/word_default/word/settings.xml | 69 +++ fixtures/word_default/word/styles.xml | 444 +++++++++++++++++ fixtures/word_default/word/theme/theme1.xml | 2 + fixtures/word_default/word/webSettings.xml | 2 + fixtures/word_default/word_default.docx | Bin 0 -> 13149 bytes 27 files changed, 1607 insertions(+), 2 deletions(-) create mode 100644 docx-core/src/documents/elements/level.rs create mode 100644 docx-core/src/documents/elements/level_jc.rs create mode 100644 docx-core/src/documents/elements/level_text.rs create mode 100644 docx-core/src/documents/elements/number_format.rs create mode 100644 docx-core/src/documents/elements/numbering.rs create mode 100644 docx-core/src/documents/elements/start.rs create mode 100644 docx-core/src/documents/numberings.rs create mode 100644 docx-core/src/xml_builder/numbering.rs create mode 100644 fixtures/word_default/[Content_Types].xml create mode 100644 fixtures/word_default/_rels/.rels create mode 100644 fixtures/word_default/docProps/app.xml create mode 100644 fixtures/word_default/docProps/core.xml create mode 100644 fixtures/word_default/word/_rels/document.xml.rels create mode 100644 fixtures/word_default/word/document.xml create mode 100644 fixtures/word_default/word/fontTable.xml create mode 100644 fixtures/word_default/word/numbering.xml create mode 100644 fixtures/word_default/word/settings.xml create mode 100644 fixtures/word_default/word/styles.xml create mode 100644 fixtures/word_default/word/theme/theme1.xml create mode 100644 fixtures/word_default/word/webSettings.xml create mode 100644 fixtures/word_default/word_default.docx diff --git a/docx-core/src/documents/elements/level.rs b/docx-core/src/documents/elements/level.rs new file mode 100644 index 000000000..414fbdf00 --- /dev/null +++ b/docx-core/src/documents/elements/level.rs @@ -0,0 +1,93 @@ +use crate::documents::{BuildXML, LevelJc, LevelText, NumberFormat, ParagraphProperty, Start}; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Level<'a> { + level: usize, + start: Start, + format: NumberFormat<'a>, + text: LevelText<'a>, + jc: LevelJc<'a>, + paragraph_property: ParagraphProperty, +} + +impl<'a> Level<'a> { + pub fn new( + level: usize, + start: Start, + format: NumberFormat<'a>, + text: LevelText<'a>, + jc: LevelJc<'a>, + ) -> Level<'a> { + Self { + level, + start, + format, + text, + jc, + paragraph_property: ParagraphProperty::new(), + } + } + + pub fn indent(mut self, left: usize, special_indent: Option) -> Self { + self.paragraph_property = self.paragraph_property.indent(left, special_indent); + self + } +} + +impl<'a> BuildXML for Level<'a> { + fn build(&self) -> Vec { + XMLBuilder::new() + .open_level(&format!("{}", self.level)) + .add_child(&self.start) + .add_child(&self.format) + .add_child(&self.text) + .add_child(&self.jc) + .add_child(&self.paragraph_property) + .close() + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_level() { + let b = Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%4."), + LevelJc::new("left"), + ) + .build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } + + #[test] + fn test_level_indent() { + let b = Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%4."), + LevelJc::new("left"), + ) + .indent(320, Some(SpecialIndentType::Hanging(200))) + .build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } +} diff --git a/docx-core/src/documents/elements/level_jc.rs b/docx-core/src/documents/elements/level_jc.rs new file mode 100644 index 000000000..3de564fd2 --- /dev/null +++ b/docx-core/src/documents/elements/level_jc.rs @@ -0,0 +1,36 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct LevelJc<'a> { + val: &'a str, +} + +impl<'a> LevelJc<'a> { + pub fn new(val: &'a str) -> Self { + Self { val } + } +} + +impl<'a> BuildXML for LevelJc<'a> { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.level_justification(self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_level_jc() { + let c = LevelJc::new("left"); + let b = c.build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } +} diff --git a/docx-core/src/documents/elements/level_text.rs b/docx-core/src/documents/elements/level_text.rs new file mode 100644 index 000000000..425e6d0b3 --- /dev/null +++ b/docx-core/src/documents/elements/level_text.rs @@ -0,0 +1,36 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct LevelText<'a> { + val: &'a str, +} + +impl<'a> LevelText<'a> { + pub fn new(val: &'a str) -> Self { + Self { val } + } +} + +impl<'a> BuildXML for LevelText<'a> { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.level_text(self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_level_text() { + let c = LevelText::new("%4."); + let b = c.build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } +} diff --git a/docx-core/src/documents/elements/mod.rs b/docx-core/src/documents/elements/mod.rs index a9e1848dc..fcf347d57 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -20,8 +20,13 @@ mod insert; mod italic; mod italic_cs; mod justification; +mod level; +mod level_jc; +mod level_text; mod name; mod next; +mod number_format; +mod numbering; mod paragraph; mod paragraph_property; mod paragraph_style; @@ -29,6 +34,7 @@ mod q_format; mod run; mod run_property; mod run_property_default; +mod start; mod style; mod sz; mod sz_cs; @@ -73,8 +79,13 @@ pub use insert::*; pub use italic::*; pub use italic_cs::*; pub use justification::*; +pub use level::*; +pub use level_jc::*; +pub use level_text::*; pub use name::*; pub use next::*; +pub use number_format::*; +pub use numbering::*; pub use paragraph::*; pub use paragraph_property::*; pub use paragraph_style::*; @@ -82,6 +93,7 @@ pub use q_format::*; pub use run::*; pub use run_property::*; pub use run_property_default::*; +pub use start::*; pub use style::*; pub use sz::*; pub use sz_cs::*; diff --git a/docx-core/src/documents/elements/number_format.rs b/docx-core/src/documents/elements/number_format.rs new file mode 100644 index 000000000..e1ebfbc61 --- /dev/null +++ b/docx-core/src/documents/elements/number_format.rs @@ -0,0 +1,39 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct NumberFormat<'a> { + val: &'a str, +} + +impl<'a> NumberFormat<'a> { + pub fn new(val: &'a str) -> Self { + Self { val } + } +} + +impl<'a> BuildXML for NumberFormat<'a> { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.number_format(self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_start() { + let c = NumberFormat::new("decimal"); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } +} diff --git a/docx-core/src/documents/elements/numbering.rs b/docx-core/src/documents/elements/numbering.rs new file mode 100644 index 000000000..29a5c1159 --- /dev/null +++ b/docx-core/src/documents/elements/numbering.rs @@ -0,0 +1,64 @@ +use crate::documents::{BuildXML, Level}; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Numbering<'a> { + id: &'a str, + levels: Vec>, +} + +impl<'a> Numbering<'a> { + pub fn new(id: &'a str) -> Self { + Self { id, levels: vec![] } + } + + pub fn add_level(mut self, level: Level<'a>) -> Self { + self.levels.push(level); + self + } +} + +impl<'a> BuildXML for Numbering<'a> { + fn build(&self) -> Vec { + let mut b = XMLBuilder::new(); + b = b.open_abstract_num(self.id); + for l in &self.levels { + b = b.add_child(l); + } + b.close() + .open_num(self.id) + .abstract_num_id(self.id) + .close() + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use crate::documents::{Level, LevelJc, LevelText, NumberFormat, Start}; + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_numbering() { + let mut c = Numbering::new("0"); + c = c.add_level(Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%4."), + LevelJc::new("left"), + )); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#" + + +"# + ); + } +} diff --git a/docx-core/src/documents/elements/start.rs b/docx-core/src/documents/elements/start.rs new file mode 100644 index 000000000..8f69b1a05 --- /dev/null +++ b/docx-core/src/documents/elements/start.rs @@ -0,0 +1,36 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Start { + val: usize, +} + +impl Start { + pub fn new(val: usize) -> Start { + Start { val } + } +} + +impl BuildXML for Start { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.start(self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_start() { + let c = Start::new(1); + let b = c.build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } +} diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index d5a0453f3..6c029f116 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -7,6 +7,7 @@ mod document_rels; mod elements; mod font_table; mod history_id; +mod numberings; mod rels; mod settings; mod styles; @@ -22,6 +23,7 @@ pub use document::*; pub use document_rels::*; pub use elements::*; pub use font_table::*; +pub use numberings::*; pub use rels::*; pub use settings::*; pub use styles::*; diff --git a/docx-core/src/documents/numberings.rs b/docx-core/src/documents/numberings.rs new file mode 100644 index 000000000..14a26b86d --- /dev/null +++ b/docx-core/src/documents/numberings.rs @@ -0,0 +1,52 @@ +use super::*; +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug)] +pub struct Numberings {} + +impl Numberings { + pub fn new() -> Self { + Default::default() + } +} + +impl Default for Numberings { + fn default() -> Self { + Self {} + } +} + +impl BuildXML for Numberings { + fn build(&self) -> Vec { + let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering(); + b = add_default_numbering(b); + b.close().build() + } +} + +fn add_default_numbering(b: XMLBuilder) -> XMLBuilder { + let mut b = b.open_abstract_num("0"); + b = b.add_child( + &Level::new( + 0, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%1."), + LevelJc::new("left"), + ) + .indent(420, Some(SpecialIndentType::Hanging(420))), + ); + b = b.add_child( + &Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%2."), + LevelJc::new("left"), + ) + .indent(840, Some(SpecialIndentType::Hanging(420))), + ); + b.close() +} diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 05b081151..327b37490 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -141,6 +141,8 @@ impl XMLBuilder { closed_el!(shd, "w:shd", "w:fill", "w:val"); closed_el!(tab, "w:tab"); + closed_el!(tab_with_pos, "w:tab", "w:val", "w:pos"); + closed_el!(br, "w:br", "w:type"); closed_el!(zoom, "w:zoom", "w:percent"); only_usize_val_el!(default_tab_stop, "w:defaultTabStop"); @@ -182,6 +184,17 @@ impl XMLBuilder { "w:date", "w:initials" ); + + opened_el!(open_abstract_num, "w:abstractNum", "w:abstractNumId"); + opened_el!(open_level, "w:lvl", "w:ilvl"); + opened_el!(open_tabs, "w:tabs"); + opened_el!(open_num, "w:num", "w:numId"); + + only_usize_val_el!(start, "w:start"); + only_str_val_el!(number_format, "w:numFmt"); + only_str_val_el!(level_text, "w:lvlText"); + only_str_val_el!(level_justification, "w:lvlJc"); + only_str_val_el!(abstract_num_id, "w:abstractNumId"); } #[cfg(test)] diff --git a/docx-core/src/xml_builder/mod.rs b/docx-core/src/xml_builder/mod.rs index e6a194722..95ab5d769 100644 --- a/docx-core/src/xml_builder/mod.rs +++ b/docx-core/src/xml_builder/mod.rs @@ -7,6 +7,7 @@ mod declaration; mod document; mod elements; mod fonts; +mod numbering; mod properties; mod relationship; mod settings; diff --git a/docx-core/src/xml_builder/numbering.rs b/docx-core/src/xml_builder/numbering.rs new file mode 100644 index 000000000..055c88f63 --- /dev/null +++ b/docx-core/src/xml_builder/numbering.rs @@ -0,0 +1,27 @@ +use super::XMLBuilder; +use super::XmlEvent; + +impl XMLBuilder { + pub(crate) fn open_numbering(mut self) -> Self { + self.writer + .write( + XmlEvent::start_element("w:numbering") + .attr( + "xmlns:r", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + ) + .attr("xmlns:o", "urn:schemas-microsoft-com:office:office") + .attr( + "xmlns:r", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + ) + .attr("xmlns:v", "urn:schemas-microsoft-com:vml") + .attr( + "xmlns:w", + "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + ), + ) + .expect("should write to buf"); + self + } +} diff --git a/docx-core/tests/output/word/styles.xml b/docx-core/tests/output/word/styles.xml index 9cf26fa3e..316fe1263 100755 --- a/docx-core/tests/output/word/styles.xml +++ b/docx-core/tests/output/word/styles.xml @@ -1 +1,22 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/numbering/word/numbering.xml b/fixtures/numbering/word/numbering.xml index 23200153c..4bb77ae7d 100644 --- a/fixtures/numbering/word/numbering.xml +++ b/fixtures/numbering/word/numbering.xml @@ -1,2 +1,466 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/word_default/[Content_Types].xml b/fixtures/word_default/[Content_Types].xml new file mode 100644 index 000000000..d26acf73e --- /dev/null +++ b/fixtures/word_default/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/_rels/.rels b/fixtures/word_default/_rels/.rels new file mode 100644 index 000000000..fdd8c4f37 --- /dev/null +++ b/fixtures/word_default/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/docProps/app.xml b/fixtures/word_default/docProps/app.xml new file mode 100644 index 000000000..ab30cbf0c --- /dev/null +++ b/fixtures/word_default/docProps/app.xml @@ -0,0 +1,2 @@ + +0105Microsoft Office Word011falsefalse5falsefalse16.0000 \ No newline at end of file diff --git a/fixtures/word_default/docProps/core.xml b/fixtures/word_default/docProps/core.xml new file mode 100644 index 000000000..fcd1b3186 --- /dev/null +++ b/fixtures/word_default/docProps/core.xml @@ -0,0 +1,2 @@ + +Ueki SatoshiUeki Satoshi12019-12-06T07:17:00Z2019-12-06T07:17:00Z \ No newline at end of file diff --git a/fixtures/word_default/word/_rels/document.xml.rels b/fixtures/word_default/word/_rels/document.xml.rels new file mode 100644 index 000000000..6c4c76771 --- /dev/null +++ b/fixtures/word_default/word/_rels/document.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/word/document.xml b/fixtures/word_default/word/document.xml new file mode 100644 index 000000000..43b9710f6 --- /dev/null +++ b/fixtures/word_default/word/document.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + H + + + ello + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/word_default/word/fontTable.xml b/fixtures/word_default/word/fontTable.xml new file mode 100644 index 000000000..3b7433e4c --- /dev/null +++ b/fixtures/word_default/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/word/numbering.xml b/fixtures/word_default/word/numbering.xml new file mode 100644 index 000000000..f9ce35c5d --- /dev/null +++ b/fixtures/word_default/word/numbering.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/word_default/word/settings.xml b/fixtures/word_default/word/settings.xml new file mode 100644 index 000000000..31b4908ff --- /dev/null +++ b/fixtures/word_default/word/settings.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/word_default/word/styles.xml b/fixtures/word_default/word/styles.xml new file mode 100644 index 000000000..21ce43db1 --- /dev/null +++ b/fixtures/word_default/word/styles.xml @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/word_default/word/theme/theme1.xml b/fixtures/word_default/word/theme/theme1.xml new file mode 100644 index 000000000..96a423756 --- /dev/null +++ b/fixtures/word_default/word/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/word/webSettings.xml b/fixtures/word_default/word/webSettings.xml new file mode 100644 index 000000000..55b7e9dc7 --- /dev/null +++ b/fixtures/word_default/word/webSettings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/word_default/word_default.docx b/fixtures/word_default/word_default.docx new file mode 100644 index 0000000000000000000000000000000000000000..215ad1048a3c2bb3754a3f02ad04e64accfc6444 GIT binary patch literal 13149 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 bzrcU@xQa4RAoT(O5J6uskcNsg{oMLLfCzMp literal 0 HcmV?d00001 From 4450e758b427f413a7dc7659ee868e0bf3c162d9 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Mon, 9 Dec 2019 03:52:44 +0900 Subject: [PATCH 2/2] feat: Use String for wasm This is because wasm-bindgen does not support 'static for function Pleaase see https://github.com/rustwasm/wasm-bindgen/issues/1187 --- docx-core/src/documents/comments.rs | 12 +- docx-core/src/documents/doc_props/core.rs | 78 ++++++----- docx-core/src/documents/doc_props/mod.rs | 6 +- docx-core/src/documents/document.rs | 22 +-- .../src/documents/elements/bookmark_end.rs | 12 +- .../src/documents/elements/bookmark_start.rs | 17 ++- docx-core/src/documents/elements/comment.rs | 44 +++--- .../documents/elements/comment_range_end.rs | 12 +- .../documents/elements/comment_range_start.rs | 14 +- docx-core/src/documents/elements/delete.rs | 28 ++-- docx-core/src/documents/elements/insert.rs | 28 ++-- docx-core/src/documents/elements/level.rs | 20 +-- docx-core/src/documents/elements/level_jc.rs | 14 +- .../src/documents/elements/level_text.rs | 14 +- .../src/documents/elements/number_format.rs | 14 +- docx-core/src/documents/elements/numbering.rs | 25 ++-- docx-core/src/documents/elements/paragraph.rs | 60 ++++---- .../documents/elements/paragraph_property.rs | 2 +- docx-core/src/documents/elements/run.rs | 36 ++--- .../src/documents/elements/run_property.rs | 6 +- docx-core/src/documents/elements/table.rs | 12 +- .../src/documents/elements/table_cell.rs | 20 +-- docx-core/src/documents/elements/table_row.rs | 10 +- docx-core/src/documents/elements/text.rs | 10 +- docx-core/src/documents/mod.rs | 29 ++-- docx-core/src/documents/numberings.rs | 131 ++++++++++++++---- docx-core/src/documents/xml_docx.rs | 1 + docx-wasm/index.js | 6 +- docx-wasm/src/lib.rs | 47 +++++-- 29 files changed, 429 insertions(+), 301 deletions(-) diff --git a/docx-core/src/documents/comments.rs b/docx-core/src/documents/comments.rs index 2ab8d2197..bc111709a 100644 --- a/docx-core/src/documents/comments.rs +++ b/docx-core/src/documents/comments.rs @@ -3,26 +3,26 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct Comments<'a> { - comments: Vec>, +pub struct Comments { + comments: Vec, } -impl<'a> Comments<'a> { +impl Comments { pub fn new() -> Self { Default::default() } - pub(crate) fn add_comments(&mut self, comments: Vec>) { + pub(crate) fn add_comments(&mut self, comments: Vec) { self.comments = comments; } } -impl<'a> Default for Comments<'a> { +impl Default for Comments { fn default() -> Self { Self { comments: vec![] } } } -impl<'a> BuildXML for Comments<'a> { +impl BuildXML for Comments { fn build(&self) -> Vec { let mut b = XMLBuilder::new().declaration(Some(true)).open_comments(); for c in &self.comments { diff --git a/docx-core/src/documents/doc_props/core.rs b/docx-core/src/documents/doc_props/core.rs index 9dcc6b622..b01258473 100644 --- a/docx-core/src/documents/doc_props/core.rs +++ b/docx-core/src/documents/doc_props/core.rs @@ -2,30 +2,30 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct CoreProps<'a> { - config: CorePropsConfig<'a>, +pub struct CoreProps { + config: CorePropsConfig, } #[derive(Debug)] -pub struct CorePropsConfig<'a> { - created: Option<&'a str>, - creator: Option<&'a str>, - description: Option<&'a str>, - language: Option<&'a str>, - last_modified_by: Option<&'a str>, - modified: Option<&'a str>, +pub struct CorePropsConfig { + created: Option, + creator: Option, + description: Option, + language: Option, + last_modified_by: Option, + modified: Option, revision: Option, - subject: Option<&'a str>, - title: Option<&'a str>, + subject: Option, + title: Option, } -impl<'a> CoreProps<'a> { - pub(crate) fn new(config: CorePropsConfig<'a>) -> CoreProps { +impl CoreProps { + pub(crate) fn new(config: CorePropsConfig) -> CoreProps { CoreProps { config } } } -impl<'a> CorePropsConfig<'a> { +impl CorePropsConfig { pub fn new() -> Self { CorePropsConfig { created: None, @@ -41,7 +41,7 @@ impl<'a> CorePropsConfig<'a> { } } -impl<'a> BuildXML for CoreProps<'a> { +impl BuildXML for CoreProps { fn build(&self) -> Vec { let b = XMLBuilder::new(); let base = b.declaration(Some(true)).open_core_properties( @@ -58,32 +58,40 @@ impl<'a> BuildXML for CoreProps<'a> { "dcterms:W3CDTF", self.config .created - .map_or_else(|| "1970-01-01T00:00:00Z", |v| v), + .as_ref() + .map_or_else(|| "1970-01-01T00:00:00Z", |v| &v), + ) + .dc_creator( + self.config + .creator + .as_ref() + .map_or_else(|| "unknown", |v| &v), ) - .dc_creator(self.config.creator.map_or_else(|| "unknown", |v| v)) .cp_last_modified_by( self.config .last_modified_by - .map_or_else(|| "unknown", |v| v), + .as_ref() + .map_or_else(|| "unknown", |v| &v), ) .dcterms_modified( "dcterms:W3CDTF", self.config .modified - .map_or_else(|| "1970-01-01T00:00:00Z", |v| v), + .as_ref() + .map_or_else(|| "1970-01-01T00:00:00Z", |v| &v), ) .cp_revision(&self.config.revision.map_or_else(|| "1".to_owned(), convert)); - if let Some(v) = self.config.description { - base = base.dc_description(v); + if let Some(v) = self.config.description.as_ref() { + base = base.dc_description(&v); } - if let Some(v) = self.config.language { - base = base.dc_language(v); + if let Some(v) = self.config.language.as_ref() { + base = base.dc_language(&v); } - if let Some(v) = self.config.subject { - base = base.dc_subject(v); + if let Some(v) = self.config.subject.as_ref() { + base = base.dc_subject(&v); } - if let Some(v) = self.config.title { - base = base.dc_title(v); + if let Some(v) = self.config.title.as_ref() { + base = base.dc_title(&v); } base.close().build() } @@ -127,15 +135,15 @@ mod tests { #[test] fn test_configured_doc_props_core_build() { let c = CoreProps::new(CorePropsConfig { - created: Some("2019-01-01"), - creator: Some("foo"), - description: Some("bar"), - language: Some("en"), - last_modified_by: Some("go"), - modified: Some("2019-01-01"), + created: Some("2019-01-01".to_owned()), + creator: Some("foo".to_owned()), + description: Some("bar".to_owned()), + language: Some("en".to_owned()), + last_modified_by: Some("go".to_owned()), + modified: Some("2019-01-01".to_owned()), revision: Some(1), - subject: Some("subject"), - title: Some("title"), + subject: Some("subject".to_owned()), + title: Some("title".to_owned()), }); let b = c.build(); assert_eq!( diff --git a/docx-core/src/documents/doc_props/mod.rs b/docx-core/src/documents/doc_props/mod.rs index cbcd2f581..8301a6ffc 100644 --- a/docx-core/src/documents/doc_props/mod.rs +++ b/docx-core/src/documents/doc_props/mod.rs @@ -6,12 +6,12 @@ pub use self::core::*; use crate::documents::BuildXML; #[derive(Debug)] -pub(crate) struct DocProps<'a> { +pub(crate) struct DocProps { app: AppProps, - core: CoreProps<'a>, + core: CoreProps, } -impl<'a> DocProps<'a> { +impl DocProps { pub(crate) fn new(core_config: CorePropsConfig) -> DocProps { let app = AppProps::new(); let core = CoreProps::new(core_config); diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index e7e13bcce..a79d368a8 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -3,33 +3,33 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug)] -pub struct Document<'a> { - pub(crate) children: Vec>, +pub struct Document { + pub(crate) children: Vec, } #[derive(Debug, Clone)] -pub enum DocumentChild<'a> { - Paragraph(Paragraph<'a>), - Table(Table<'a>), +pub enum DocumentChild { + Paragraph(Paragraph), + Table(Table), } -impl<'a> Document<'a> { - pub fn new() -> Document<'a> { +impl Document { + pub fn new() -> Document { Default::default() } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> Self { + pub fn add_paragraph(mut self, p: Paragraph) -> Self { self.children.push(DocumentChild::Paragraph(p)); self } - pub fn add_table(mut self, t: Table<'a>) -> Self { + pub fn add_table(mut self, t: Table) -> Self { self.children.push(DocumentChild::Table(t)); self } } -impl<'a> Default for Document<'a> { +impl Default for Document { fn default() -> Self { Self { children: Vec::new(), @@ -37,7 +37,7 @@ impl<'a> Default for Document<'a> { } } -impl<'a> BuildXML for Document<'a> { +impl BuildXML for Document { fn build(&self) -> Vec { let mut b = XMLBuilder::new() .declaration(Some(true)) diff --git a/docx-core/src/documents/elements/bookmark_end.rs b/docx-core/src/documents/elements/bookmark_end.rs index d8ddeeb35..ffda2f3b5 100644 --- a/docx-core/src/documents/elements/bookmark_end.rs +++ b/docx-core/src/documents/elements/bookmark_end.rs @@ -2,17 +2,17 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct BookmarkEnd<'a> { - id: &'a str, +pub struct BookmarkEnd { + id: String, } -impl<'a> BookmarkEnd<'a> { - pub fn new(id: &'a str) -> BookmarkEnd<'a> { - BookmarkEnd { id } +impl BookmarkEnd { + pub fn new(id: impl Into) -> BookmarkEnd { + BookmarkEnd { id: id.into() } } } -impl<'a> BuildXML for BookmarkEnd<'a> { +impl BuildXML for BookmarkEnd { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.bookmark_end(&self.id).build() diff --git a/docx-core/src/documents/elements/bookmark_start.rs b/docx-core/src/documents/elements/bookmark_start.rs index dd14b0d55..caac7c0d3 100644 --- a/docx-core/src/documents/elements/bookmark_start.rs +++ b/docx-core/src/documents/elements/bookmark_start.rs @@ -2,18 +2,21 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct BookmarkStart<'a> { - id: &'a str, - name: &'a str, +pub struct BookmarkStart { + id: String, + name: String, } -impl<'a> BookmarkStart<'a> { - pub fn new(id: &'a str, name: &'a str) -> BookmarkStart<'a> { - BookmarkStart { id, name } +impl BookmarkStart { + pub fn new(id: impl Into, name: impl Into) -> BookmarkStart { + BookmarkStart { + id: id.into(), + name: name.into(), + } } } -impl<'a> BuildXML for BookmarkStart<'a> { +impl BuildXML for BookmarkStart { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.bookmark_start(&self.id, &self.name).build() diff --git a/docx-core/src/documents/elements/comment.rs b/docx-core/src/documents/elements/comment.rs index 7703e457c..98c5f9e90 100644 --- a/docx-core/src/documents/elements/comment.rs +++ b/docx-core/src/documents/elements/comment.rs @@ -2,56 +2,56 @@ use crate::documents::{BuildXML, Paragraph}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Comment<'a> { - id: &'a str, - author: &'a str, - date: &'a str, - paragraph: Paragraph<'a>, +pub struct Comment { + id: String, + author: String, + date: String, + paragraph: Paragraph, } -impl<'a> Default for Comment<'a> { - fn default() -> Comment<'a> { +impl Default for Comment { + fn default() -> Comment { Comment { - id: "invalidId", - author: "unnamed", - date: "1970-01-01T00:00:00Z", + id: "invalidId".to_owned(), + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), paragraph: Paragraph::new(), } } } -impl<'a> Comment<'a> { - pub fn new(id: &'a str) -> Comment<'a> { +impl Comment { + pub fn new(id: impl Into) -> Comment { Self { - id, + id: id.into(), ..Default::default() } } - pub fn author(mut self, author: &'a str) -> Comment<'a> { - self.author = author; + pub fn author(mut self, author: impl Into) -> Comment { + self.author = author.into(); self } - pub fn date(mut self, date: &'a str) -> Comment<'a> { - self.date = date; + pub fn date(mut self, date: impl Into) -> Comment { + self.date = date.into(); self } - pub fn paragraph(mut self, p: Paragraph<'a>) -> Comment<'a> { + pub fn paragraph(mut self, p: Paragraph) -> Comment { self.paragraph = p; self } - pub fn id(&self) -> &'a str { - self.id + pub fn id(&self) -> String { + self.id.clone() } } -impl<'a> BuildXML for Comment<'a> { +impl BuildXML for Comment { fn build(&self) -> Vec { XMLBuilder::new() - .open_comment(&self.id, self.author, self.date, "") + .open_comment(&self.id, &self.author, &self.date, "") .add_child(&self.paragraph) .close() .build() diff --git a/docx-core/src/documents/elements/comment_range_end.rs b/docx-core/src/documents/elements/comment_range_end.rs index 554b2beea..597273ccc 100644 --- a/docx-core/src/documents/elements/comment_range_end.rs +++ b/docx-core/src/documents/elements/comment_range_end.rs @@ -2,17 +2,17 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct CommentRangeEnd<'a> { - id: &'a str, +pub struct CommentRangeEnd { + id: String, } -impl<'a> CommentRangeEnd<'a> { - pub fn new(id: &'a str) -> CommentRangeEnd<'a> { - CommentRangeEnd { id } +impl CommentRangeEnd { + pub fn new(id: impl Into) -> CommentRangeEnd { + CommentRangeEnd { id: id.into() } } } -impl<'a> BuildXML for CommentRangeEnd<'a> { +impl BuildXML for CommentRangeEnd { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.open_run() diff --git a/docx-core/src/documents/elements/comment_range_start.rs b/docx-core/src/documents/elements/comment_range_start.rs index 3a37d163b..74020349b 100644 --- a/docx-core/src/documents/elements/comment_range_start.rs +++ b/docx-core/src/documents/elements/comment_range_start.rs @@ -3,25 +3,25 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct CommentRangeStart<'a> { - id: &'a str, - comment: Comment<'a>, +pub struct CommentRangeStart { + id: String, + comment: Comment, } -impl<'a> CommentRangeStart<'a> { - pub fn new(comment: Comment<'a>) -> CommentRangeStart<'a> { +impl CommentRangeStart { + pub fn new(comment: Comment) -> CommentRangeStart { CommentRangeStart { id: comment.id(), comment, } } - pub(crate) fn comment(&self) -> Comment<'a> { + pub(crate) fn comment(&self) -> Comment { self.comment.clone() } } -impl<'a> BuildXML for CommentRangeStart<'a> { +impl BuildXML for CommentRangeStart { fn build(&self) -> Vec { let b = XMLBuilder::new(); b.comment_range_start(&self.id).build() diff --git a/docx-core/src/documents/elements/delete.rs b/docx-core/src/documents/elements/delete.rs index 4f55096c3..5dd75c36f 100644 --- a/docx-core/src/documents/elements/delete.rs +++ b/docx-core/src/documents/elements/delete.rs @@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Delete<'a> { - author: &'a str, - date: &'a str, - run: Run<'a>, +pub struct Delete { + author: String, + date: String, + run: Run, } -impl<'a> Default for Delete<'a> { - fn default() -> Delete<'a> { +impl Default for Delete { + fn default() -> Delete { Delete { - author: "unnamed", - date: "1970-01-01T00:00:00Z", + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), run: Run::new(), } } } -impl<'a> Delete<'a> { - pub fn new() -> Delete<'a> { +impl Delete { + pub fn new() -> Delete { Default::default() } - pub fn run(mut self, run: Run<'a>) -> Delete<'a> { + pub fn run(mut self, run: Run) -> Delete { self.run = run; self } } -impl<'a> HistoryId for Delete<'a> {} +impl HistoryId for Delete {} -impl<'a> BuildXML for Delete<'a> { +impl BuildXML for Delete { fn build(&self) -> Vec { XMLBuilder::new() - .open_delete(&self.generate(), self.author, self.date) + .open_delete(&self.generate(), &self.author, &self.date) .add_child(&self.run) .close() .build() diff --git a/docx-core/src/documents/elements/insert.rs b/docx-core/src/documents/elements/insert.rs index 18480736e..4c3becdbe 100644 --- a/docx-core/src/documents/elements/insert.rs +++ b/docx-core/src/documents/elements/insert.rs @@ -2,39 +2,39 @@ use crate::documents::{BuildXML, HistoryId, Run}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Insert<'a> { - author: &'a str, - date: &'a str, - run: Run<'a>, +pub struct Insert { + author: String, + date: String, + run: Run, } -impl<'a> Default for Insert<'a> { - fn default() -> Insert<'a> { +impl Default for Insert { + fn default() -> Insert { Insert { - author: "unnamed", - date: "1970-01-01T00:00:00Z", + author: "unnamed".to_owned(), + date: "1970-01-01T00:00:00Z".to_owned(), run: Run::new(), } } } -impl<'a> Insert<'a> { - pub fn new() -> Insert<'a> { +impl Insert { + pub fn new() -> Insert { Default::default() } - pub fn run(mut self, run: Run<'a>) -> Insert<'a> { + pub fn run(mut self, run: Run) -> Insert { self.run = run; self } } -impl<'a> HistoryId for Insert<'a> {} +impl HistoryId for Insert {} -impl<'a> BuildXML for Insert<'a> { +impl BuildXML for Insert { fn build(&self) -> Vec { XMLBuilder::new() - .open_insert(&self.generate(), self.author, self.date) + .open_insert(&self.generate(), &self.author, &self.date) .add_child(&self.run) .close() .build() diff --git a/docx-core/src/documents/elements/level.rs b/docx-core/src/documents/elements/level.rs index 414fbdf00..fcb238c76 100644 --- a/docx-core/src/documents/elements/level.rs +++ b/docx-core/src/documents/elements/level.rs @@ -3,23 +3,23 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Level<'a> { +pub struct Level { level: usize, start: Start, - format: NumberFormat<'a>, - text: LevelText<'a>, - jc: LevelJc<'a>, + format: NumberFormat, + text: LevelText, + jc: LevelJc, paragraph_property: ParagraphProperty, } -impl<'a> Level<'a> { +impl Level { pub fn new( level: usize, start: Start, - format: NumberFormat<'a>, - text: LevelText<'a>, - jc: LevelJc<'a>, - ) -> Level<'a> { + format: NumberFormat, + text: LevelText, + jc: LevelJc, + ) -> Level { Self { level, start, @@ -36,7 +36,7 @@ impl<'a> Level<'a> { } } -impl<'a> BuildXML for Level<'a> { +impl BuildXML for Level { fn build(&self) -> Vec { XMLBuilder::new() .open_level(&format!("{}", self.level)) diff --git a/docx-core/src/documents/elements/level_jc.rs b/docx-core/src/documents/elements/level_jc.rs index 3de564fd2..14c20d5dd 100644 --- a/docx-core/src/documents/elements/level_jc.rs +++ b/docx-core/src/documents/elements/level_jc.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct LevelJc<'a> { - val: &'a str, +pub struct LevelJc { + val: String, } -impl<'a> LevelJc<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl LevelJc { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for LevelJc<'a> { +impl BuildXML for LevelJc { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.level_justification(self.val).build() + b.level_justification(&self.val).build() } } diff --git a/docx-core/src/documents/elements/level_text.rs b/docx-core/src/documents/elements/level_text.rs index 425e6d0b3..da40304c3 100644 --- a/docx-core/src/documents/elements/level_text.rs +++ b/docx-core/src/documents/elements/level_text.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct LevelText<'a> { - val: &'a str, +pub struct LevelText { + val: String, } -impl<'a> LevelText<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl LevelText { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for LevelText<'a> { +impl BuildXML for LevelText { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.level_text(self.val).build() + b.level_text(&self.val).build() } } diff --git a/docx-core/src/documents/elements/number_format.rs b/docx-core/src/documents/elements/number_format.rs index e1ebfbc61..53591098a 100644 --- a/docx-core/src/documents/elements/number_format.rs +++ b/docx-core/src/documents/elements/number_format.rs @@ -2,20 +2,20 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct NumberFormat<'a> { - val: &'a str, +pub struct NumberFormat { + val: String, } -impl<'a> NumberFormat<'a> { - pub fn new(val: &'a str) -> Self { - Self { val } +impl NumberFormat { + pub fn new(val: impl Into) -> Self { + Self { val: val.into() } } } -impl<'a> BuildXML for NumberFormat<'a> { +impl BuildXML for NumberFormat { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.number_format(self.val).build() + b.number_format(&self.val).build() } } diff --git a/docx-core/src/documents/elements/numbering.rs b/docx-core/src/documents/elements/numbering.rs index 29a5c1159..415b0e247 100644 --- a/docx-core/src/documents/elements/numbering.rs +++ b/docx-core/src/documents/elements/numbering.rs @@ -2,34 +2,31 @@ use crate::documents::{BuildXML, Level}; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Numbering<'a> { - id: &'a str, - levels: Vec>, +pub struct Numbering { + id: usize, + levels: Vec, } -impl<'a> Numbering<'a> { - pub fn new(id: &'a str) -> Self { +impl Numbering { + pub fn new(id: usize) -> Self { Self { id, levels: vec![] } } - pub fn add_level(mut self, level: Level<'a>) -> Self { + pub fn add_level(mut self, level: Level) -> Self { self.levels.push(level); self } } -impl<'a> BuildXML for Numbering<'a> { +impl BuildXML for Numbering { fn build(&self) -> Vec { + let id = format!("{}", self.id); let mut b = XMLBuilder::new(); - b = b.open_abstract_num(self.id); + b = b.open_abstract_num(&id); for l in &self.levels { b = b.add_child(l); } - b.close() - .open_num(self.id) - .abstract_num_id(self.id) - .close() - .build() + b.close().open_num(&id).abstract_num_id(&id).close().build() } } @@ -44,7 +41,7 @@ mod tests { #[test] fn test_numbering() { - let mut c = Numbering::new("0"); + let mut c = Numbering::new(0); c = c.add_level(Level::new( 1, Start::new(1), diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 41849c0e5..a74cc935a 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -4,13 +4,13 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Paragraph<'a> { - pub(crate) children: Vec>, +pub struct Paragraph { + pub(crate) children: Vec, property: ParagraphProperty, attrs: Vec<(String, String)>, } -impl<'a> Default for Paragraph<'a> { +impl Default for Paragraph { fn default() -> Self { Self { children: Vec::new(), @@ -21,17 +21,17 @@ impl<'a> Default for Paragraph<'a> { } #[derive(Debug, Clone)] -pub enum ParagraphChild<'a> { - Run(Run<'a>), - Insert(Insert<'a>), - Delete(Delete<'a>), - BookmarkStart(BookmarkStart<'a>), - BookmarkEnd(BookmarkEnd<'a>), - CommentStart(CommentRangeStart<'a>), - CommentEnd(CommentRangeEnd<'a>), +pub enum ParagraphChild { + Run(Run), + Insert(Insert), + Delete(Delete), + BookmarkStart(BookmarkStart), + BookmarkEnd(BookmarkEnd), + CommentStart(CommentRangeStart), + CommentEnd(CommentRangeEnd), } -impl<'a> BuildXML for ParagraphChild<'a> { +impl BuildXML for ParagraphChild { fn build(&self) -> Vec { match self { ParagraphChild::Run(v) => v.build(), @@ -45,8 +45,8 @@ impl<'a> BuildXML for ParagraphChild<'a> { } } -impl<'a> Paragraph<'a> { - pub fn new() -> Paragraph<'a> { +impl Paragraph { + pub fn new() -> Paragraph { Default::default() } @@ -54,39 +54,43 @@ impl<'a> Paragraph<'a> { &self.children } - pub fn add_run(mut self, run: Run<'a>) -> Paragraph<'a> { + pub fn add_run(mut self, run: Run) -> Paragraph { self.children.push(ParagraphChild::Run(run)); self } - pub fn add_insert(mut self, insert: Insert<'a>) -> Paragraph<'a> { + pub fn add_insert(mut self, insert: Insert) -> Paragraph { self.children.push(ParagraphChild::Insert(insert)); self } - pub fn add_delete(mut self, delete: Delete<'a>) -> Paragraph<'a> { + pub fn add_delete(mut self, delete: Delete) -> Paragraph { self.children.push(ParagraphChild::Delete(delete)); self } - pub fn add_attr(mut self, key: impl Into, val: impl Into) -> Paragraph<'a> { + pub fn add_attr(mut self, key: impl Into, val: impl Into) -> Paragraph { self.attrs.push((key.into(), val.into())); self } - pub fn add_bookmark_start(mut self, id: &'a str, name: &'a str) -> Paragraph<'a> { + pub fn add_bookmark_start( + mut self, + id: impl Into, + name: impl Into, + ) -> Paragraph { self.children .push(ParagraphChild::BookmarkStart(BookmarkStart::new(id, name))); self } - pub fn add_bookmark_end(mut self, id: &'a str) -> Paragraph<'a> { + pub fn add_bookmark_end(mut self, id: impl Into) -> Paragraph { self.children .push(ParagraphChild::BookmarkEnd(BookmarkEnd::new(id))); self } - pub fn add_comment_start(mut self, comment: Comment<'a>) -> Paragraph<'a> { + pub fn add_comment_start(mut self, comment: Comment) -> Paragraph { self.children .push(ParagraphChild::CommentStart(CommentRangeStart::new( comment, @@ -94,33 +98,29 @@ impl<'a> Paragraph<'a> { self } - pub fn add_comment_end(mut self, id: &'a str) -> Paragraph<'a> { + pub fn add_comment_end(mut self, id: impl Into) -> Paragraph { self.children .push(ParagraphChild::CommentEnd(CommentRangeEnd::new(id))); self } - pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph<'a> { + pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph { self.property = self.property.align(alignment_type); self } - pub fn style(mut self, style_id: &str) -> Paragraph<'a> { + pub fn style(mut self, style_id: &str) -> Paragraph { self.property = self.property.style(style_id); self } - pub fn indent( - mut self, - left: usize, - special_indent: Option, - ) -> Paragraph<'a> { + pub fn indent(mut self, left: usize, special_indent: Option) -> Paragraph { self.property = self.property.indent(left, special_indent); self } } -impl<'a> BuildXML for Paragraph<'a> { +impl BuildXML for Paragraph { fn build(&self) -> Vec { XMLBuilder::new() .open_paragraph(&self.attrs) diff --git a/docx-core/src/documents/elements/paragraph_property.rs b/docx-core/src/documents/elements/paragraph_property.rs index b00b94ab5..502b8a654 100644 --- a/docx-core/src/documents/elements/paragraph_property.rs +++ b/docx-core/src/documents/elements/paragraph_property.rs @@ -1,4 +1,4 @@ -use super::{Indent, Justification, ParagraphStyle, RunProperty}; +use super::*; use crate::documents::BuildXML; use crate::types::{AlignmentType, SpecialIndentType}; use crate::xml_builder::*; diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index 09c4c20e5..38d8277e2 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -4,12 +4,12 @@ use crate::types::BreakType; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Run<'a> { +pub struct Run { run_property: RunProperty, - children: Vec>, + children: Vec, } -impl<'a> Default for Run<'a> { +impl Default for Run { fn default() -> Self { let run_property = RunProperty::new(); Self { @@ -20,72 +20,72 @@ impl<'a> Default for Run<'a> { } #[derive(Debug, Clone)] -pub enum RunChild<'a> { - Text(Text<'a>), +pub enum RunChild { + Text(Text), DeleteText(DeleteText), Tab(Tab), Break(Break), } -impl<'a> Run<'a> { - pub fn new() -> Run<'a> { +impl Run { + pub fn new() -> Run { Run { ..Default::default() } } - pub fn add_text(mut self, text: &'a str) -> Run<'a> { + pub fn add_text(mut self, text: impl Into) -> Run { self.children.push(RunChild::Text(Text::new(text))); self } - pub fn add_delete_text(mut self, text: &'a str) -> Run<'a> { + pub fn add_delete_text(mut self, text: impl Into) -> Run { self.children.push(RunChild::Text(Text::new(text))); self } - pub fn add_tab(mut self) -> Run<'a> { + pub fn add_tab(mut self) -> Run { self.children.push(RunChild::Tab(Tab::new())); self } - pub fn add_break(mut self, break_type: BreakType) -> Run<'a> { + pub fn add_break(mut self, break_type: BreakType) -> Run { self.children.push(RunChild::Break(Break::new(break_type))); self } - pub fn size(mut self, size: usize) -> Run<'a> { + pub fn size(mut self, size: usize) -> Run { self.run_property = self.run_property.size(size); self } - pub fn color(mut self, color: &'a str) -> Run<'a> { + pub fn color(mut self, color: impl Into) -> Run { self.run_property = self.run_property.color(color); self } - pub fn highlight(mut self, color: &'a str) -> Run<'a> { + pub fn highlight(mut self, color: impl Into) -> Run { self.run_property = self.run_property.highlight(color); self } - pub fn bold(mut self) -> Run<'a> { + pub fn bold(mut self) -> Run { self.run_property = self.run_property.bold(); self } - pub fn italic(mut self) -> Run<'a> { + pub fn italic(mut self) -> Run { self.run_property = self.run_property.italic(); self } - pub fn underline(mut self, line_type: &'a str) -> Run<'a> { + pub fn underline(mut self, line_type: impl Into) -> Run { self.run_property = self.run_property.underline(line_type); self } } -impl<'a> BuildXML for Run<'a> { +impl BuildXML for Run { fn build(&self) -> Vec { let b = XMLBuilder::new(); let mut b = b.open_run().add_child(&self.run_property); diff --git a/docx-core/src/documents/elements/run_property.rs b/docx-core/src/documents/elements/run_property.rs index 0c01b8ff4..602ebf9cb 100644 --- a/docx-core/src/documents/elements/run_property.rs +++ b/docx-core/src/documents/elements/run_property.rs @@ -26,12 +26,12 @@ impl RunProperty { self } - pub fn color(mut self, color: &str) -> RunProperty { + pub fn color(mut self, color: impl Into) -> RunProperty { self.color = Some(Color::new(color)); self } - pub fn highlight(mut self, color: &str) -> RunProperty { + pub fn highlight(mut self, color: impl Into) -> RunProperty { self.highlight = Some(Highlight::new(color)); self } @@ -48,7 +48,7 @@ impl RunProperty { self } - pub fn underline(mut self, line_type: &str) -> RunProperty { + pub fn underline(mut self, line_type: impl Into) -> RunProperty { self.underline = Some(Underline::new(line_type)); self } diff --git a/docx-core/src/documents/elements/table.rs b/docx-core/src/documents/elements/table.rs index efd2376d3..54cded0ad 100644 --- a/docx-core/src/documents/elements/table.rs +++ b/docx-core/src/documents/elements/table.rs @@ -3,14 +3,14 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Table<'a> { - pub(crate) rows: Vec>, +pub struct Table { + pub(crate) rows: Vec, property: TableProperty, grid: Vec, } -impl<'a> Table<'a> { - pub fn new(rows: Vec>) -> Table<'a> { +impl Table { + pub fn new(rows: Vec) -> Table { let property = TableProperty::new(); let grid = vec![]; Self { @@ -20,13 +20,13 @@ impl<'a> Table<'a> { } } - pub fn set_grid(mut self, grid: Vec) -> Table<'a> { + pub fn set_grid(mut self, grid: Vec) -> Table { self.grid = grid; self } } -impl<'a> BuildXML for Table<'a> { +impl BuildXML for Table { fn build(&self) -> Vec { let grid = TableGrid::new(self.grid.clone()); let b = XMLBuilder::new() diff --git a/docx-core/src/documents/elements/table_cell.rs b/docx-core/src/documents/elements/table_cell.rs index ccf93b00f..534d5ba30 100644 --- a/docx-core/src/documents/elements/table_cell.rs +++ b/docx-core/src/documents/elements/table_cell.rs @@ -4,40 +4,40 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct TableCell<'a> { - pub(crate) contents: Vec>, +pub struct TableCell { + pub(crate) contents: Vec, property: TableCellProperty, } #[derive(Debug, Clone)] -pub enum TableCellContent<'a> { - Paragraph(Paragraph<'a>), +pub enum TableCellContent { + Paragraph(Paragraph), } -impl<'a> TableCell<'a> { - pub fn new() -> TableCell<'a> { +impl TableCell { + pub fn new() -> TableCell { let property = TableCellProperty::new(); let contents = vec![]; Self { property, contents } } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> TableCell<'a> { + pub fn add_paragraph(mut self, p: Paragraph) -> TableCell { self.contents.push(TableCellContent::Paragraph(p)); self } - pub fn vertical_merge(mut self, t: VMergeType) -> TableCell<'a> { + pub fn vertical_merge(mut self, t: VMergeType) -> TableCell { self.property = self.property.vertical_merge(t); self } - pub fn grid_span(mut self, v: usize) -> TableCell<'a> { + pub fn grid_span(mut self, v: usize) -> TableCell { self.property = self.property.grid_span(v); self } } -impl<'a> BuildXML for TableCell<'a> { +impl BuildXML for TableCell { fn build(&self) -> Vec { let b = XMLBuilder::new(); let mut b = b.open_table_cell().add_child(&self.property); diff --git a/docx-core/src/documents/elements/table_row.rs b/docx-core/src/documents/elements/table_row.rs index 87fde2f82..b3dff7f48 100644 --- a/docx-core/src/documents/elements/table_row.rs +++ b/docx-core/src/documents/elements/table_row.rs @@ -3,19 +3,19 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct TableRow<'a> { - pub(crate) cells: Vec>, +pub struct TableRow { + pub(crate) cells: Vec, property: TableRowProperty, } -impl<'a> TableRow<'a> { - pub fn new(cells: Vec>) -> TableRow<'a> { +impl TableRow { + pub fn new(cells: Vec) -> TableRow { let property = TableRowProperty::new(); Self { property, cells } } } -impl<'a> BuildXML for TableRow<'a> { +impl BuildXML for TableRow { fn build(&self) -> Vec { let b = XMLBuilder::new() .open_table_row() diff --git a/docx-core/src/documents/elements/text.rs b/docx-core/src/documents/elements/text.rs index 4c6ac2d94..65e0ad6b1 100644 --- a/docx-core/src/documents/elements/text.rs +++ b/docx-core/src/documents/elements/text.rs @@ -2,13 +2,13 @@ use crate::documents::BuildXML; use crate::xml_builder::*; #[derive(Debug, Clone)] -pub struct Text<'a> { - text: &'a str, +pub struct Text { + text: String, preserve_space: bool, } -impl<'a> Text<'a> { - pub fn new(text: &'a str) -> Text { +impl Text { + pub fn new(text: impl Into) -> Text { Text { text: text.into(), preserve_space: true, @@ -16,7 +16,7 @@ impl<'a> Text<'a> { } } -impl<'a> BuildXML for Text<'a> { +impl BuildXML for Text { fn build(&self) -> Vec { XMLBuilder::new().text(&self.text, true).build() } diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index 6c029f116..0c6a02db8 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -30,19 +30,20 @@ pub use styles::*; pub use xml_docx::*; #[derive(Debug)] -pub struct Docx<'a> { +pub struct Docx { content_type: ContentTypes, rels: Rels, document_rels: DocumentRels, - doc_props: DocProps<'a>, + doc_props: DocProps, styles: Styles, - document: Document<'a>, - comments: Comments<'a>, + document: Document, + comments: Comments, + numberings: Numberings, settings: Settings, font_table: FontTable, } -impl<'a> Default for Docx<'a> { +impl Default for Docx { fn default() -> Self { let content_type = ContentTypes::new(); let rels = Rels::new(); @@ -53,6 +54,7 @@ impl<'a> Default for Docx<'a> { let settings = Settings::new(); let font_table = FontTable::new(); let comments = Comments::new(); + let numberings = Numberings::new(); Docx { content_type, rels, @@ -63,25 +65,31 @@ impl<'a> Default for Docx<'a> { document_rels, settings, font_table, + numberings, } } } -impl<'a> Docx<'a> { - pub fn new() -> Docx<'a> { +impl Docx { + pub fn new() -> Docx { Default::default() } - pub fn add_paragraph(mut self, p: Paragraph<'a>) -> Docx<'a> { + pub fn add_paragraph(mut self, p: Paragraph) -> Docx { self.document = self.document.add_paragraph(p); self } - pub fn add_table(mut self, t: Table<'a>) -> Docx<'a> { + pub fn add_table(mut self, t: Table) -> Docx { self.document = self.document.add_table(t); self } + pub fn add_numbering(mut self, num: Numbering) -> Docx { + self.numberings = self.numberings.add_numbering(num); + self + } + pub fn build(&mut self) -> XMLDocx { self.update_comments(); XMLDocx { @@ -94,12 +102,13 @@ impl<'a> Docx<'a> { document_rels: self.document_rels.build(), settings: self.settings.build(), font_table: self.font_table.build(), + numberings: self.numberings.build(), } } // Traverse and clone comments from document and add to comments node. fn update_comments(&mut self) { - let mut comments: Vec> = vec![]; + let mut comments: Vec = vec![]; for child in &self.document.children { match child { DocumentChild::Paragraph(paragraph) => { diff --git a/docx-core/src/documents/numberings.rs b/docx-core/src/documents/numberings.rs index 14a26b86d..2485955c8 100644 --- a/docx-core/src/documents/numberings.rs +++ b/docx-core/src/documents/numberings.rs @@ -4,49 +4,128 @@ use crate::types::*; use crate::xml_builder::*; #[derive(Debug)] -pub struct Numberings {} +pub struct Numberings { + numberings: Vec, +} impl Numberings { pub fn new() -> Self { Default::default() } + + pub fn add_numbering(mut self, n: Numbering) -> Self { + self.numberings.push(n); + self + } } impl Default for Numberings { fn default() -> Self { - Self {} + Self { numberings: vec![] } } } impl BuildXML for Numberings { fn build(&self) -> Vec { let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering(); - b = add_default_numbering(b); + b = b.add_child(&create_default_numbering()); + for n in &self.numberings { + b = b.add_child(n); + } b.close().build() } } -fn add_default_numbering(b: XMLBuilder) -> XMLBuilder { - let mut b = b.open_abstract_num("0"); - b = b.add_child( - &Level::new( - 0, - Start::new(1), - NumberFormat::new("decimal"), - LevelText::new("%1."), - LevelJc::new("left"), - ) - .indent(420, Some(SpecialIndentType::Hanging(420))), - ); - b = b.add_child( - &Level::new( - 1, - Start::new(1), - NumberFormat::new("decimal"), - LevelText::new("%2."), - LevelJc::new("left"), - ) - .indent(840, Some(SpecialIndentType::Hanging(420))), - ); - b.close() +fn create_default_numbering() -> Numbering { + Numbering::new(0) + .add_level( + Level::new( + 0, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%1."), + LevelJc::new("left"), + ) + .indent(420, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 1, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%2)"), + LevelJc::new("left"), + ) + .indent(840, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 2, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%3"), + LevelJc::new("left"), + ) + .indent(1260, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 3, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%4."), + LevelJc::new("left"), + ) + .indent(1680, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 4, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%5)"), + LevelJc::new("left"), + ) + .indent(2100, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 5, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%6"), + LevelJc::new("left"), + ) + .indent(2520, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 6, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("%7."), + LevelJc::new("left"), + ) + .indent(2940, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 7, + Start::new(1), + NumberFormat::new("decimal"), + LevelText::new("(%8)"), + LevelJc::new("left"), + ) + .indent(3360, Some(SpecialIndentType::Hanging(420))), + ) + .add_level( + Level::new( + 8, + Start::new(1), + NumberFormat::new("decimalEnclosedCircle"), + LevelText::new("%9"), + LevelJc::new("left"), + ) + .indent(3780, Some(SpecialIndentType::Hanging(420))), + ) } diff --git a/docx-core/src/documents/xml_docx.rs b/docx-core/src/documents/xml_docx.rs index d7fb08279..41e1002ea 100644 --- a/docx-core/src/documents/xml_docx.rs +++ b/docx-core/src/documents/xml_docx.rs @@ -15,6 +15,7 @@ pub struct XMLDocx { pub document_rels: Vec, pub settings: Vec, pub font_table: Vec, + pub numberings: Vec, } impl XMLDocx { diff --git a/docx-wasm/index.js b/docx-wasm/index.js index 1473d5757..e122e3d86 100644 --- a/docx-wasm/index.js +++ b/docx-wasm/index.js @@ -6,7 +6,11 @@ const rust = import("./pkg"); rust .then(m => { - let docx = m.createDocx().add_paragraph(); + const p = m + .createParagraph() + .add_run(m.createRun().add_text("Hello World!!")); + let docx = m.createDocx().add_paragraph(p); saveAs(new Blob([docx.build()]), "example.docx"); + docx.free(); }) .catch(console.error); diff --git a/docx-wasm/src/lib.rs b/docx-wasm/src/lib.rs index d94d491ae..08856596a 100644 --- a/docx-wasm/src/lib.rs +++ b/docx-wasm/src/lib.rs @@ -3,20 +3,17 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] #[derive(Debug)] -pub struct Docx(docx_core::Docx<'static>); +pub struct Docx(docx_core::Docx); -#[wasm_bindgen] -#[allow(non_snake_case)] -pub fn createDocx() -> Docx { +#[wasm_bindgen(js_name = createDocx)] +pub fn create_docx() -> Docx { Docx(docx_core::Docx::new()) } #[wasm_bindgen] impl Docx { - pub fn add_paragraph(mut self) -> Self { - self.0 = self.0.add_paragraph( - docx_core::Paragraph::new().add_run(docx_core::Run::new().add_text("Hello")), - ); + pub fn add_paragraph(mut self, p: Paragraph) -> Self { + self.0 = self.0.add_paragraph(p.0); self } @@ -29,8 +26,38 @@ impl Docx { } Ok(cur.into_inner()) } +} + +#[wasm_bindgen] +#[derive(Debug)] +pub struct Paragraph(docx_core::Paragraph); - pub fn test(&self, t: docx_core::StyleType) { - () +#[wasm_bindgen(js_name = createParagraph)] +pub fn create_paragraph() -> Paragraph { + Paragraph(docx_core::Paragraph::new()) +} + +#[wasm_bindgen] +impl Paragraph { + pub fn add_run(mut self, run: Run) -> Self { + self.0 = self.0.add_run(run.0); + self + } +} + +#[wasm_bindgen] +#[derive(Debug)] +pub struct Run(docx_core::Run); + +#[wasm_bindgen(js_name = createRun)] +pub fn create_run() -> Run { + Run(docx_core::Run::new()) +} + +#[wasm_bindgen] +impl Run { + pub fn add_text(mut self, text: &str) -> Self { + self.0 = self.0.add_text(text); + self } }