diff --git a/docx-core/examples/numbering.rs b/docx-core/examples/numbering.rs index 0a303ad..030b4d1 100644 --- a/docx-core/examples/numbering.rs +++ b/docx-core/examples/numbering.rs @@ -9,8 +9,8 @@ pub fn main() -> Result<(), DocxError> { .add_run(Run::new().add_text("Hello")) .numbering(NumberingId::new(2), IndentLevel::new(0)), ) - .add_numbering( - Numbering::new(2).add_level( + .add_abstract_numbering( + AbstractNumbering::new(2).add_level( Level::new( 0, Start::new(1), @@ -21,6 +21,7 @@ pub fn main() -> Result<(), DocxError> { .indent(1620, Some(SpecialIndentType::Hanging(320)), None), ), ) + .add_numbering(Numbering::new(2, 2)) .build() .pack(file)?; Ok(()) diff --git a/docx-core/src/documents/elements/abstract_numbering.rs b/docx-core/src/documents/elements/abstract_numbering.rs new file mode 100644 index 0000000..f817b1b --- /dev/null +++ b/docx-core/src/documents/elements/abstract_numbering.rs @@ -0,0 +1,61 @@ +use crate::documents::{BuildXML, Level}; +use crate::xml_builder::*; + +use serde::Serialize; + +#[derive(Debug, Clone, PartialEq, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AbstractNumbering { + id: usize, + levels: Vec, +} + +impl AbstractNumbering { + pub fn new(id: usize) -> Self { + Self { id, levels: vec![] } + } + + pub fn add_level(mut self, level: Level) -> Self { + self.levels.push(level); + self + } +} + +impl BuildXML for AbstractNumbering { + fn build(&self) -> Vec { + let id = format!("{}", self.id); + let mut b = XMLBuilder::new(); + b = b.open_abstract_num(&id); + for l in &self.levels { + b = b.add_child(l); + } + b.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 = AbstractNumbering::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/mod.rs b/docx-core/src/documents/elements/mod.rs index 54090d0..947980d 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -1,3 +1,4 @@ +mod abstract_numbering; mod based_on; mod bold; mod bold_cs; @@ -64,6 +65,7 @@ mod vanish; mod vertical_merge; mod zoom; +pub use abstract_numbering::*; pub use based_on::*; pub use bold::*; pub use bold_cs::*; diff --git a/docx-core/src/documents/elements/numbering.rs b/docx-core/src/documents/elements/numbering.rs index 159bb35..4b67114 100644 --- a/docx-core/src/documents/elements/numbering.rs +++ b/docx-core/src/documents/elements/numbering.rs @@ -1,4 +1,4 @@ -use crate::documents::{BuildXML, Level}; +use crate::documents::BuildXML; use crate::xml_builder::*; use serde::Serialize; @@ -7,29 +7,24 @@ use serde::Serialize; #[serde(rename_all = "camelCase")] pub struct Numbering { id: usize, - levels: Vec, + abstract_num_id: usize, } impl Numbering { - pub fn new(id: usize) -> Self { - Self { id, levels: vec![] } - } - - pub fn add_level(mut self, level: Level) -> Self { - self.levels.push(level); - self + pub fn new(id: usize, abstract_num_id: usize) -> Self { + Self { + id, + abstract_num_id, + } } } impl BuildXML for Numbering { fn build(&self) -> Vec { + let b = XMLBuilder::new(); let id = format!("{}", self.id); - let mut b = XMLBuilder::new(); - b = b.open_abstract_num(&id); - for l in &self.levels { - b = b.add_child(l); - } - b.close().open_num(&id).abstract_num_id(&id).close().build() + let abs_id = format!("{}", self.abstract_num_id); + b.open_num(&id).abstract_num_id(&abs_id).close().build() } } @@ -38,26 +33,17 @@ 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 c = Numbering::new(0, 2); let b = c.build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#" - - + r#" + "# ); } diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index 94889ae..7ca826e 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -103,6 +103,11 @@ impl Docx { self } + pub fn add_abstract_numbering(mut self, num: AbstractNumbering) -> Docx { + self.numberings = self.numberings.add_abstract_numbering(num); + self + } + pub fn add_numbering(mut self, num: Numbering) -> Docx { self.numberings = self.numberings.add_numbering(num); self diff --git a/docx-core/src/documents/numberings.rs b/docx-core/src/documents/numberings.rs index eb19326..ac46790 100644 --- a/docx-core/src/documents/numberings.rs +++ b/docx-core/src/documents/numberings.rs @@ -8,6 +8,7 @@ use serde::Serialize; #[derive(Debug, Clone, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Numberings { + abstract_nums: Vec, numberings: Vec, } @@ -16,6 +17,11 @@ impl Numberings { Default::default() } + pub fn add_abstract_numbering(mut self, n: AbstractNumbering) -> Self { + self.abstract_nums.push(n); + self + } + pub fn add_numbering(mut self, n: Numbering) -> Self { self.numberings.push(n); self @@ -24,7 +30,10 @@ impl Numberings { impl Default for Numberings { fn default() -> Self { - Self { numberings: vec![] } + Self { + abstract_nums: vec![], + numberings: vec![], + } } } @@ -32,6 +41,10 @@ impl BuildXML for Numberings { fn build(&self) -> Vec { let mut b = XMLBuilder::new().declaration(Some(true)).open_numbering(); b = b.add_child(&create_default_numbering()); + for n in &self.abstract_nums { + b = b.add_child(n); + } + b = b.add_child(&Numbering::new(1, 1)); for n in &self.numberings { b = b.add_child(n); } @@ -39,8 +52,8 @@ impl BuildXML for Numberings { } } -fn create_default_numbering() -> Numbering { - Numbering::new(1) +fn create_default_numbering() -> AbstractNumbering { + AbstractNumbering::new(1) .add_level( Level::new( 0, diff --git a/docx-core/tests/lib.rs b/docx-core/tests/lib.rs index d4c2416..1d58ef9 100644 --- a/docx-core/tests/lib.rs +++ b/docx-core/tests/lib.rs @@ -359,8 +359,8 @@ pub fn user_numbering() -> Result<(), DocxError> { .add_run(Run::new().add_text("Hello")) .numbering(NumberingId::new(2), IndentLevel::new(0)), ) - .add_numbering( - Numbering::new(2).add_level( + .add_abstract_numbering( + AbstractNumbering::new(2).add_level( Level::new( 0, Start::new(1), @@ -371,6 +371,7 @@ pub fn user_numbering() -> Result<(), DocxError> { .indent(1620, Some(SpecialIndentType::Hanging(320)), None), ), ) + .add_numbering(Numbering::new(2, 2)) .build() .pack(file)?; Ok(()) diff --git a/docx-wasm/js/abstract-numbering.ts b/docx-wasm/js/abstract-numbering.ts new file mode 100644 index 0000000..3db5f35 --- /dev/null +++ b/docx-wasm/js/abstract-numbering.ts @@ -0,0 +1,13 @@ +import { Level } from "./level"; + +export class AbstractNumbering { + id: number; + levels: Level[]; + constructor(id: number) { + this.id = id; + } + addLevel(level: Level) { + this.levels.push(level); + return this; + } +} diff --git a/docx-wasm/js/index.ts b/docx-wasm/js/index.ts index fe9492d..4584c2d 100644 --- a/docx-wasm/js/index.ts +++ b/docx-wasm/js/index.ts @@ -10,6 +10,7 @@ import { Tab } from "./tab"; import { Break } from "./break"; import { Comment } from "./comment"; import { CommentEnd } from "./comment-end"; +import { AbstractNumbering } from "./abstract-numbering"; import { Numbering } from "./numbering"; import { BookmarkStart } from "./bookmark-start"; import { BookmarkEnd } from "./bookmark-end"; @@ -18,6 +19,7 @@ import * as wasm from "../pkg"; export class Docx { children: (Paragraph | Table)[] = []; + abstractNumberings: AbstractNumbering[] = []; numberings: Numbering[] = []; addParagraph(p: Paragraph) { @@ -30,6 +32,11 @@ export class Docx { return this; } + addAbstractNumbering(num: AbstractNumbering) { + this.abstractNumberings.push(num); + return this; + } + addNumbering(num: Numbering) { this.numberings.push(num); return this; @@ -259,14 +266,20 @@ export class Docx { } }); - this.numberings.forEach(n => { - let num = wasm.createNumbering(n.id); + this.abstractNumberings.forEach(n => { + let num = wasm.createAbstractNumbering(n.id); n.levels.forEach(l => { const level = wasm.createLevel(l.id, l.start, l.format, l.text, l.jc); num = num.add_level(level); }); + docx = docx.add_abstract_numbering(num); + }); + + this.numberings.forEach(n => { + let num = wasm.createNumbering(n.id, n.abstractNumId); docx = docx.add_numbering(num); }); + const buf = docx.build(); docx.free(); return buf; diff --git a/docx-wasm/js/numbering.ts b/docx-wasm/js/numbering.ts index 580d712..f6889af 100644 --- a/docx-wasm/js/numbering.ts +++ b/docx-wasm/js/numbering.ts @@ -1,13 +1,8 @@ -import { Level } from "./level"; - export class Numbering { id: number; - levels: Level[]; - constructor(id: number) { + abstractNumId: number; + constructor(id: number, abstractNumId: number) { this.id = id; - } - addLevel(level: Level) { - this.levels.push(level); - return this; + this.abstractNumId = abstractNumId; } } diff --git a/docx-wasm/src/abstract_numbering.rs b/docx-wasm/src/abstract_numbering.rs new file mode 100644 index 0000000..035dcec --- /dev/null +++ b/docx-wasm/src/abstract_numbering.rs @@ -0,0 +1,26 @@ +use super::*; +use docx_rs; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Debug)] +pub struct AbstractNumbering(docx_rs::AbstractNumbering); + +#[wasm_bindgen(js_name = createAbstractNumbering)] +pub fn create_abstract_numbering(id: usize) -> AbstractNumbering { + AbstractNumbering(docx_rs::AbstractNumbering::new(id)) +} + +impl AbstractNumbering { + pub fn take(self) -> docx_rs::AbstractNumbering { + self.0 + } +} + +#[wasm_bindgen] +impl AbstractNumbering { + pub fn add_level(mut self, level: Level) -> Self { + self.0 = self.0.add_level(level.take()); + self + } +} diff --git a/docx-wasm/src/doc.rs b/docx-wasm/src/doc.rs index 9e194f6..faf4511 100644 --- a/docx-wasm/src/doc.rs +++ b/docx-wasm/src/doc.rs @@ -24,6 +24,11 @@ impl Docx { self } + pub fn add_abstract_numbering(mut self, num: AbstractNumbering) -> Docx { + self.0.numberings = self.0.numberings.add_abstract_numbering(num.take()); + self + } + pub fn add_numbering(mut self, num: Numbering) -> Docx { self.0.numberings = self.0.numberings.add_numbering(num.take()); self diff --git a/docx-wasm/src/lib.rs b/docx-wasm/src/lib.rs index 04b1f10..3281119 100644 --- a/docx-wasm/src/lib.rs +++ b/docx-wasm/src/lib.rs @@ -1,3 +1,4 @@ +mod abstract_numbering; mod adaptors; mod comment; mod delete; @@ -12,6 +13,7 @@ mod table; mod table_cell; mod table_row; +pub use abstract_numbering::*; pub use adaptors::*; pub use comment::*; pub use delete::*; diff --git a/docx-wasm/src/numbering.rs b/docx-wasm/src/numbering.rs index 296bc9f..a9b20be 100644 --- a/docx-wasm/src/numbering.rs +++ b/docx-wasm/src/numbering.rs @@ -1,4 +1,3 @@ -use super::*; use docx_rs; use wasm_bindgen::prelude::*; @@ -7,8 +6,8 @@ use wasm_bindgen::prelude::*; pub struct Numbering(docx_rs::Numbering); #[wasm_bindgen(js_name = createNumbering)] -pub fn create_numbering(id: usize) -> Numbering { - Numbering(docx_rs::Numbering::new(id)) +pub fn create_numbering(id: usize, abstract_num_id: usize) -> Numbering { + Numbering(docx_rs::Numbering::new(id, abstract_num_id)) } impl Numbering { @@ -16,11 +15,3 @@ impl Numbering { self.0 } } - -#[wasm_bindgen] -impl Numbering { - pub fn add_level(mut self, level: Level) -> Self { - self.0 = self.0.add_level(level.take()); - self - } -} diff --git a/fixtures/paragraph/word/numbering.xml b/fixtures/paragraph/word/numbering.xml index 8f2ea96..c400dad 100644 --- a/fixtures/paragraph/word/numbering.xml +++ b/fixtures/paragraph/word/numbering.xml @@ -1,2 +1,214 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file