diff --git a/.gitignore b/.gitignore index da8c19b..a4de448 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ dist node_modules pkg *.docx# -test.docx \ No newline at end of file +test.docx +output/*.docx \ No newline at end of file diff --git a/docx-core/examples/alignment.rs b/docx-core/examples/alignment.rs new file mode 100644 index 0000000..ade39aa --- /dev/null +++ b/docx-core/examples/alignment.rs @@ -0,0 +1,15 @@ +use docx_core::*; + +pub fn main() { + 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); +} diff --git a/docx-core/src/documents/elements/justification.rs b/docx-core/src/documents/elements/justification.rs new file mode 100644 index 0000000..47e326e --- /dev/null +++ b/docx-core/src/documents/elements/justification.rs @@ -0,0 +1,44 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +// 22.1.2.51 +// jc (Justification) +// This element specifies justification of the math paragraph (a series of adjacent instances of mathematical text +// within the same paragraph). A math paragraph can be Left Justified, Right Justified, Centered, or Centered as +// Group. If this element is omitted, the math paragraph is Centered as Group. Whether the element is absent or +// present without the val attribute, the default of the val attribute is centerGroup . This means that the instances +// of mathematical text can be aligned with respect to each other, but the entire group of mathematical text is +// centered as a whole. +#[derive(Debug)] +pub struct Justification { + val: String, +} + +impl Justification { + pub fn new(val: impl Into) -> Justification { + Justification { val: val.into() } + } +} + +impl BuildXML for Justification { + fn build(&self) -> Vec { + let b = XMLBuilder::new(); + b.justification(&self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_justification() { + let c = Justification::new("start"); + 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 74d4f71..9682254 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 color; mod doc_defaults; +mod justification; mod name; mod next; mod paragraph; @@ -16,6 +17,7 @@ mod text; pub use based_on::*; pub use color::*; pub use doc_defaults::*; +pub use justification::*; pub use name::*; pub use next::*; pub use paragraph::*; diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 6f79624..4f1d0ca 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -1,15 +1,20 @@ -use super::{Run, RunProperty, Text}; +use super::{ParagraphProperty, Run, RunProperty, Text}; use crate::documents::BuildXML; +use crate::types::*; use crate::xml_builder::*; #[derive(Debug)] pub struct Paragraph { runs: Vec, + property: ParagraphProperty, } impl Default for Paragraph { fn default() -> Self { - Self { runs: Vec::new() } + Self { + runs: Vec::new(), + property: ParagraphProperty::new(), + } } } @@ -22,12 +27,18 @@ impl Paragraph { self.runs.push(run); self } + + pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph { + self.property = self.property.align(alignment_type); + self + } } impl BuildXML for Paragraph { fn build(&self) -> Vec { XMLBuilder::new() .open_paragraph() + .add_child(&self.property) .add_children(&self.runs) .close() .build() diff --git a/docx-core/src/documents/elements/paragraph_property.rs b/docx-core/src/documents/elements/paragraph_property.rs index 519ac12..7f9af3d 100644 --- a/docx-core/src/documents/elements/paragraph_property.rs +++ b/docx-core/src/documents/elements/paragraph_property.rs @@ -1,8 +1,18 @@ +use super::Justification; use crate::documents::BuildXML; +use crate::types::AlignmentType; use crate::xml_builder::*; #[derive(Debug)] -pub struct ParagraphProperty {} +pub struct ParagraphProperty { + alignment: Option, +} + +impl Default for ParagraphProperty { + fn default() -> Self { + ParagraphProperty { alignment: None } + } +} // 17.3.1.26 // pPr (Paragraph Properties) @@ -11,14 +21,22 @@ pub struct ParagraphProperty {} // as direct formatting, since they are directly applied to the paragraph and supersede any formatting from styles. impl ParagraphProperty { pub fn new() -> ParagraphProperty { - ParagraphProperty {} + Default::default() + } + + pub fn align(mut self, alignment_type: AlignmentType) -> ParagraphProperty { + self.alignment = Some(Justification::new(alignment_type.to_string())); + self } } impl BuildXML for ParagraphProperty { fn build(&self) -> Vec { let b = XMLBuilder::new(); - b.open_paragraph_property().close().build() + let p = b + .open_paragraph_property() + .add_optional_child(&self.alignment); + p.close().build() } } diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index 7379a0c..4ff014a 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -49,7 +49,7 @@ mod tests { let b = Run::new("Hello").build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#"Hello"# + r#"Hello"# ); } } diff --git a/docx-core/src/documents/elements/text.rs b/docx-core/src/documents/elements/text.rs index 289d5fc..90f2f98 100644 --- a/docx-core/src/documents/elements/text.rs +++ b/docx-core/src/documents/elements/text.rs @@ -34,6 +34,9 @@ mod tests { #[test] fn test_build() { let b = Text::new("Hello").build(); - assert_eq!(str::from_utf8(&b).unwrap(), r#"Hello"#); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#"Hello"# + ); } } diff --git a/docx-core/src/lib.rs b/docx-core/src/lib.rs index a2e6d33..bf5883d 100644 --- a/docx-core/src/lib.rs +++ b/docx-core/src/lib.rs @@ -11,11 +11,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_run(Run::new(" World")), - ) + .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .add_paragraph(Paragraph::new().add_run(Run::new(" World"))) .build() .pack(file); } diff --git a/docx-core/src/types/alignment_type.rs b/docx-core/src/types/alignment_type.rs new file mode 100644 index 0000000..683e117 --- /dev/null +++ b/docx-core/src/types/alignment_type.rs @@ -0,0 +1,22 @@ +use std::fmt; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Copy, Clone, Debug)] +pub enum AlignmentType { + Center, + Left, + Right, + Justified, +} + +impl fmt::Display for AlignmentType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + AlignmentType::Center => write!(f, "center"), + AlignmentType::Left => write!(f, "left"), + AlignmentType::Right => write!(f, "right"), + AlignmentType::Justified => write!(f, "justified"), + } + } +} diff --git a/docx-core/src/types/mod.rs b/docx-core/src/types/mod.rs index 87172bb..f87533e 100644 --- a/docx-core/src/types/mod.rs +++ b/docx-core/src/types/mod.rs @@ -1,3 +1,5 @@ +pub mod alignment_type; pub mod style_type; +pub use alignment_type::*; pub use style_type::*; diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 740a65a..5f05b6a 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -33,6 +33,10 @@ impl XMLBuilder { opened_el!(open_doc_defaults, "w:docDefaults"); // i.e. only_str_val_el!(name, "w:name"); + // i.e. + only_str_val_el!(justification, "w:jc"); + // i.e. + only_str_val_el!(p_style, "w:pStyle"); // i.e. pub(crate) fn sz(mut self, val: usize) -> Self { self.writer diff --git a/output/.keep b/output/.keep new file mode 100644 index 0000000..e69de29