diff --git a/docx-core/examples/alignment.rs b/docx-core/examples/alignment.rs deleted file mode 100644 index be34a2e..0000000 --- a/docx-core/examples/alignment.rs +++ /dev/null @@ -1,16 +0,0 @@ -use docx_core::*; - -pub fn main() -> Result<(), DocxError> { - let path = std::path::Path::new("./output/alignment.docx"); - let file = std::fs::File::create(&path).unwrap(); - Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) - .add_paragraph( - Paragraph::new() - .add_run(Run::new(" World")) - .align(AlignmentType::Right), - ) - .build() - .pack(file)?; - Ok(()) -} diff --git a/docx-core/examples/indent.rs b/docx-core/examples/indent.rs index 1cfa8e6..dcc1627 100644 --- a/docx-core/examples/indent.rs +++ b/docx-core/examples/indent.rs @@ -6,17 +6,21 @@ pub fn main() -> Result<(), DocxError> { let path = std::path::Path::new("./output/indent.docx"); let file = std::fs::File::create(&path).unwrap(); Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new(DUMMY)).indent(840, None)) + .add_paragraph( + Paragraph::new() + .add_run(Run::new().add_text(DUMMY)) + .indent(840, None), + ) .add_paragraph(Paragraph::new()) .add_paragraph( Paragraph::new() - .add_run(Run::new(DUMMY)) + .add_run(Run::new().add_text(DUMMY)) .indent(840, Some(SpecialIndentType::FirstLine(720))), ) .add_paragraph(Paragraph::new()) .add_paragraph( Paragraph::new() - .add_run(Run::new(DUMMY)) + .add_run(Run::new().add_text(DUMMY)) .indent(1560, Some(SpecialIndentType::Hanging(720))), ) .build() diff --git a/docx-core/examples/size.rs b/docx-core/examples/size.rs deleted file mode 100644 index 40f39f6..0000000 --- a/docx-core/examples/size.rs +++ /dev/null @@ -1,16 +0,0 @@ -use docx_core::*; - -pub fn main() -> Result<(), DocxError> { - let path = std::path::Path::new("./output/size.docx"); - let file = std::fs::File::create(&path).unwrap(); - Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello")).size(60)) - .add_paragraph( - Paragraph::new() - .add_run(Run::new(" Wor").size(50)) - .add_run(Run::new("ld")), - ) - .build() - .pack(file)?; - Ok(()) -} diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index 3bda466..b852ef8 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -4,11 +4,11 @@ use crate::xml_builder::*; #[derive(Debug)] pub struct Document { - children: Vec, + children: Vec, } #[derive(Debug, Clone)] -pub enum DocumentContent { +pub enum DocumentChild { Paragraph(Paragraph), Table(Table), } @@ -19,12 +19,12 @@ impl Document { } pub fn add_paragraph(mut self, p: Paragraph) -> Self { - self.children.push(DocumentContent::Paragraph(p)); + self.children.push(DocumentChild::Paragraph(p)); self } pub fn add_table(mut self, t: Table) -> Self { - self.children.push(DocumentContent::Table(t)); + self.children.push(DocumentChild::Table(t)); self } } @@ -45,8 +45,8 @@ impl BuildXML for Document { .open_body(); for c in &self.children { match c { - DocumentContent::Paragraph(p) => b = b.add_child(p), - DocumentContent::Table(t) => b = b.add_child(t), + DocumentChild::Paragraph(p) => b = b.add_child(p), + DocumentChild::Table(t) => b = b.add_child(t), } } b.close().close().build() @@ -65,7 +65,7 @@ mod tests { #[test] fn test_document() { let b = Document::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) .build(); assert_eq!( str::from_utf8(&b).unwrap(), diff --git a/docx-core/src/documents/elements/br.rs b/docx-core/src/documents/elements/br.rs new file mode 100644 index 0000000..8624b9e --- /dev/null +++ b/docx-core/src/documents/elements/br.rs @@ -0,0 +1,21 @@ +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Break { + break_type: BreakType, +} + +impl Break { + pub fn new(t: BreakType) -> Break { + Break { break_type: t } + } +} + +impl BuildXML for Break { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.br(&self.break_type.to_string()).build() + } +} diff --git a/docx-core/src/documents/elements/mod.rs b/docx-core/src/documents/elements/mod.rs index 4fc42af..4596a20 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -1,6 +1,7 @@ mod based_on; mod bold; mod bold_cs; +mod br; mod color; mod doc_defaults; mod grid_span; @@ -21,6 +22,7 @@ mod run_property_default; mod style; mod sz; mod sz_cs; +mod tab; mod table; mod table_borders; mod table_cell; @@ -40,6 +42,7 @@ mod vertical_merge; pub use based_on::*; pub use bold::*; pub use bold_cs::*; +pub use br::*; pub use color::*; pub use doc_defaults::*; pub use grid_span::*; @@ -60,6 +63,7 @@ pub use run_property_default::*; pub use style::*; pub use sz::*; pub use sz_cs::*; +pub use tab::*; pub use table::*; pub use table_borders::*; pub use table_cell::*; diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 83f5eb5..4006cc8 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -70,7 +70,9 @@ mod tests { #[test] fn test_paragraph() { - let b = Paragraph::new().add_run(Run::new("Hello")).build(); + let b = Paragraph::new() + .add_run(Run::new().add_text("Hello")) + .build(); assert_eq!( str::from_utf8(&b).unwrap(), r#"Hello"# @@ -79,7 +81,10 @@ mod tests { #[test] fn test_paragraph_size() { - let b = Paragraph::new().add_run(Run::new("Hello")).size(60).build(); + let b = Paragraph::new() + .add_run(Run::new().add_text("Hello")) + .size(60) + .build(); assert_eq!( str::from_utf8(&b).unwrap(), r#"Hello"# diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index 958e62d..08a1bad 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -1,21 +1,53 @@ -use super::{RunProperty, Text}; +use super::{Break, RunProperty, Tab, Text}; use crate::documents::BuildXML; +use crate::types::BreakType; use crate::xml_builder::*; #[derive(Debug, Clone)] pub struct Run { run_property: RunProperty, - text: Text, + children: Vec, +} + +impl Default for Run { + fn default() -> Self { + let run_property = RunProperty::new(); + Self { + run_property, + children: vec![], + } + } +} + +#[derive(Debug, Clone)] +pub enum RunChild { + Text(Text), + Tab(Tab), + Break(Break), } impl Run { - pub fn new(text: impl Into) -> Run { + pub fn new() -> Run { Run { - text: Text::new(text), ..Default::default() } } + pub fn add_text(mut self, text: &str) -> Run { + self.children.push(RunChild::Text(Text::new(text))); + self + } + + 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 { + self.children.push(RunChild::Break(Break::new(break_type))); + self + } + pub fn size(mut self, size: usize) -> Run { self.run_property = self.run_property.size(size); self @@ -42,22 +74,18 @@ impl Run { } } -impl Default for Run { - fn default() -> Self { - let run_property = RunProperty::new(); - let text = Text::new(""); - Self { run_property, text } - } -} - impl BuildXML for Run { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.open_run() - .add_child(&self.run_property) - .add_child(&self.text) - .close() - .build() + let mut b = b.open_run().add_child(&self.run_property); + for c in &self.children { + match c { + RunChild::Text(t) => b = b.add_child(t), + RunChild::Tab(t) => b = b.add_child(t), + RunChild::Break(t) => b = b.add_child(t), + } + } + b.close().build() } } @@ -71,7 +99,7 @@ mod tests { #[test] fn test_build() { - let b = Run::new("Hello").build(); + let b = Run::new().add_text("Hello").build(); assert_eq!( str::from_utf8(&b).unwrap(), r#"Hello"# diff --git a/docx-core/src/documents/elements/tab.rs b/docx-core/src/documents/elements/tab.rs new file mode 100644 index 0000000..bf3b33d --- /dev/null +++ b/docx-core/src/documents/elements/tab.rs @@ -0,0 +1,18 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Tab {} + +impl Tab { + pub fn new() -> Tab { + Tab {} + } +} + +impl BuildXML for Tab { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.tab().build() + } +} diff --git a/docx-core/src/documents/elements/table_cell.rs b/docx-core/src/documents/elements/table_cell.rs index 9afc1f0..b580a95 100644 --- a/docx-core/src/documents/elements/table_cell.rs +++ b/docx-core/src/documents/elements/table_cell.rs @@ -68,7 +68,7 @@ mod tests { #[test] fn test_cell_add_p() { let b = TableCell::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) .build(); assert_eq!( str::from_utf8(&b).unwrap(), diff --git a/docx-core/src/lib.rs b/docx-core/src/lib.rs index 9bdd3fe..693d70b 100644 --- a/docx-core/src/lib.rs +++ b/docx-core/src/lib.rs @@ -12,8 +12,8 @@ pub fn simple() { let path = std::path::Path::new("./test.docx"); let file = std::fs::File::create(&path).unwrap(); Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) - .add_paragraph(Paragraph::new().add_run(Run::new(" World"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text(" World"))) .build() .pack(file); } diff --git a/docx-core/src/types/break_type.rs b/docx-core/src/types/break_type.rs new file mode 100644 index 0000000..56adb2b --- /dev/null +++ b/docx-core/src/types/break_type.rs @@ -0,0 +1,24 @@ +// +// Please see +// + +use std::fmt; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Copy, Clone, Debug)] +pub enum BreakType { + Page, + Column, + TextWrapping, +} + +impl fmt::Display for BreakType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + BreakType::Page => write!(f, "page"), + BreakType::Column => write!(f, "column"), + BreakType::TextWrapping => write!(f, "textWrapping"), + } + } +} diff --git a/docx-core/src/types/mod.rs b/docx-core/src/types/mod.rs index 2cb0808..48bec73 100644 --- a/docx-core/src/types/mod.rs +++ b/docx-core/src/types/mod.rs @@ -1,6 +1,7 @@ pub mod alignment_type; pub mod border_position; pub mod border_type; +pub mod break_type; pub mod special_indent_type; pub mod style_type; pub mod table_alignment_type; @@ -10,6 +11,7 @@ pub mod width_type; pub use alignment_type::*; pub use border_position::*; pub use border_type::*; +pub use break_type::*; pub use special_indent_type::*; pub use style_type::*; pub use table_alignment_type::*; diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index c212f2d..03abcef 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -122,6 +122,9 @@ impl XMLBuilder { closed_border_el!(border_inside_v, "w:insideV"); closed_el!(shd, "w:shd", "w:fill", "w:val"); + + closed_el!(tab, "w:tab"); + closed_el!(br, "w:br", "w:type"); } #[cfg(test)] diff --git a/docx-core/tests/lib.rs b/docx-core/tests/lib.rs index a926382..3156267 100644 --- a/docx-core/tests/lib.rs +++ b/docx-core/tests/lib.rs @@ -9,17 +9,21 @@ pub fn indent() -> Result<(), DocxError> { let path = std::path::Path::new("./tests/output/indent.docx"); let file = std::fs::File::create(&path).unwrap(); Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new(DUMMY)).indent(840, None)) + .add_paragraph( + Paragraph::new() + .add_run(Run::new().add_text(DUMMY)) + .indent(840, None), + ) .add_paragraph(Paragraph::new()) .add_paragraph( Paragraph::new() - .add_run(Run::new(DUMMY)) + .add_run(Run::new().add_text(DUMMY)) .indent(840, Some(SpecialIndentType::FirstLine(720))), ) .add_paragraph(Paragraph::new()) .add_paragraph( Paragraph::new() - .add_run(Run::new(DUMMY)) + .add_run(Run::new().add_text(DUMMY)) .indent(1560, Some(SpecialIndentType::Hanging(720))), ) .build() @@ -32,11 +36,15 @@ pub fn size() -> Result<(), DocxError> { let path = std::path::Path::new("./tests/output/size.docx"); let file = std::fs::File::create(&path).unwrap(); Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello")).size(60)) .add_paragraph( Paragraph::new() - .add_run(Run::new(" Wor").size(50)) - .add_run(Run::new("ld")), + .add_run(Run::new().add_text("Hello")) + .size(60), + ) + .add_paragraph( + Paragraph::new() + .add_run(Run::new().add_text(" Wor").size(50)) + .add_run(Run::new().add_text("ld")), ) .build() .pack(file)?; @@ -48,10 +56,10 @@ pub fn alignment() -> Result<(), DocxError> { let path = std::path::Path::new("./tests/output/alignment.docx"); let file = std::fs::File::create(&path).unwrap(); Docx::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) .add_paragraph( Paragraph::new() - .add_run(Run::new(" World")) + .add_run(Run::new().add_text(" World")) .align(AlignmentType::Right), ) .build() @@ -66,12 +74,12 @@ pub fn table() -> Result<(), DocxError> { let table = Table::new(vec![ TableRow::new(vec![ - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Hello"))), - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("World"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("World"))), ]), TableRow::new(vec![ - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Foo"))), - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Bar"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Foo"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Bar"))), ]), ]); Docx::new().add_table(table).build().pack(file)?; @@ -85,12 +93,12 @@ pub fn table_with_grid() -> Result<(), DocxError> { let table = Table::new(vec![ TableRow::new(vec![ - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Hello"))), - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("World"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("World"))), ]), TableRow::new(vec![ - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Foo"))), - TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new("Bar"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Foo"))), + TableCell::new().add_paragraph(Paragraph::new().add_run(Run::new().add_text("Bar"))), ]), ]) .set_grid(vec![3000, 3000]); @@ -109,7 +117,7 @@ pub fn table_merged() -> Result<(), DocxError> { .add_paragraph(Paragraph::new()) .grid_span(2), TableCell::new() - .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) .vertical_merge(VMergeType::Restart), ]), TableRow::new(vec![ @@ -143,23 +151,43 @@ pub fn decoration() -> Result<(), DocxError> { Docx::new() .add_paragraph( Paragraph::new() - .add_run(Run::new("Hello")) - .add_run(Run::new(" World").bold()), + .add_run(Run::new().add_text("Hello")) + .add_run(Run::new().add_text(" World").bold()), ) .add_paragraph( Paragraph::new() - .add_run(Run::new("Hello")) - .add_run(Run::new(" World").highlight("yellow")), + .add_run(Run::new().add_text("Hello")) + .add_run(Run::new().add_text(" World").highlight("yellow")), ) .add_paragraph( Paragraph::new() - .add_run(Run::new("Hello")) - .add_run(Run::new(" World").italic()), + .add_run(Run::new().add_text("Hello")) + .add_run(Run::new().add_text(" World").italic()), ) .add_paragraph( Paragraph::new() - .add_run(Run::new("Hello")) - .add_run(Run::new(" World").color("FF0000")), + .add_run(Run::new().add_text("Hello")) + .add_run(Run::new().add_text(" World").color("FF0000")), + ) + .build() + .pack(file)?; + Ok(()) +} + +#[test] +pub fn tab_and_break() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/tab_and_break.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph( + Paragraph::new().add_run( + Run::new() + .add_text("Hello") + .add_tab() + .add_text("World") + .add_break(BreakType::Page) + .add_text("Foo"), + ), ) .build() .pack(file)?; diff --git a/docx-core/tests/output/word/document.xml b/docx-core/tests/output/word/document.xml index 1de8501..af02188 100755 --- a/docx-core/tests/output/word/document.xml +++ b/docx-core/tests/output/word/document.xml @@ -19,62 +19,10 @@ Hello - - - - - - - World - - - - - - - - - - Hello - - - - - - World - - - - - - - - - - Hello - - - - - - - World - - - - - - - - - - Hello - - - - - - World + + World + + Foo diff --git a/docx-wasm/src/lib.rs b/docx-wasm/src/lib.rs index e4aa435..2c6c7ee 100644 --- a/docx-wasm/src/lib.rs +++ b/docx-wasm/src/lib.rs @@ -14,9 +14,9 @@ pub fn createDocx() -> Docx { #[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("Hello"))); + self.0 = self.0.add_paragraph( + docx_core::Paragraph::new().add_run(docx_core::Run::new().add_text("Hello")), + ); self } diff --git a/fixtures/tab_and_break/[Content_Types].xml b/fixtures/tab_and_break/[Content_Types].xml new file mode 100644 index 0000000..dc111cb --- /dev/null +++ b/fixtures/tab_and_break/[Content_Types].xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/tab_and_break/_rels/.rels b/fixtures/tab_and_break/_rels/.rels new file mode 100644 index 0000000..f0b72e7 --- /dev/null +++ b/fixtures/tab_and_break/_rels/.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/tab_and_break/docProps/app.xml b/fixtures/tab_and_break/docProps/app.xml new file mode 100644 index 0000000..b3d57c7 --- /dev/null +++ b/fixtures/tab_and_break/docProps/app.xml @@ -0,0 +1,2 @@ + +0LibreOffice/6.0.7.3$Linux_X86_64 LibreOffice_project/00m0$Build-32421232 \ No newline at end of file diff --git a/fixtures/tab_and_break/docProps/core.xml b/fixtures/tab_and_break/docProps/core.xml new file mode 100644 index 0000000..ac5ae74 --- /dev/null +++ b/fixtures/tab_and_break/docProps/core.xml @@ -0,0 +1,2 @@ + +2019-11-13T16:09:41Zja-JP2019-11-13T16:10:19Z1 \ No newline at end of file diff --git a/fixtures/tab_and_break/tab_and_break.docx b/fixtures/tab_and_break/tab_and_break.docx new file mode 100644 index 0000000..23c6efa Binary files /dev/null and b/fixtures/tab_and_break/tab_and_break.docx differ diff --git a/fixtures/tab_and_break/word/_rels/document.xml.rels b/fixtures/tab_and_break/word/_rels/document.xml.rels new file mode 100644 index 0000000..8a2db8a --- /dev/null +++ b/fixtures/tab_and_break/word/_rels/document.xml.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/tab_and_break/word/document.xml b/fixtures/tab_and_break/word/document.xml new file mode 100644 index 0000000..34d0fc9 --- /dev/null +++ b/fixtures/tab_and_break/word/document.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + Start + + + + + + + + + + + + + Break + + Tabaaa + + aaaaa + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/tab_and_break/word/fontTable.xml b/fixtures/tab_and_break/word/fontTable.xml new file mode 100644 index 0000000..94f56db --- /dev/null +++ b/fixtures/tab_and_break/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/tab_and_break/word/settings.xml b/fixtures/tab_and_break/word/settings.xml new file mode 100644 index 0000000..97dba84 --- /dev/null +++ b/fixtures/tab_and_break/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/tab_and_break/word/styles.xml b/fixtures/tab_and_break/word/styles.xml new file mode 100644 index 0000000..72e6f53 --- /dev/null +++ b/fixtures/tab_and_break/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file