diff --git a/docx-core/src/documents/elements/mod.rs b/docx-core/src/documents/elements/mod.rs index 1feecb9..ab74f73 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -94,6 +94,7 @@ mod shading; mod shape; mod spec_vanish; mod start; +mod stretch; mod strike; mod structured_data_tag; mod structured_data_tag_property; @@ -232,6 +233,7 @@ pub use shading::*; pub use shape::*; pub use spec_vanish::*; pub use start::*; +pub use stretch::*; pub use strike::*; pub use structured_data_tag::*; pub use structured_data_tag_property::*; diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index eef316e..f130f10 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -263,6 +263,11 @@ impl Run { self } + pub fn stretch(mut self, v: i32) -> Run { + self.run_property = self.run_property.stretch(v); + self + } + pub fn color(mut self, color: impl Into) -> Run { self.run_property = self.run_property.color(color); self diff --git a/docx-core/src/documents/elements/run_property.rs b/docx-core/src/documents/elements/run_property.rs index 9529710..3cee94c 100644 --- a/docx-core/src/documents/elements/run_property.rs +++ b/docx-core/src/documents/elements/run_property.rs @@ -40,6 +40,8 @@ pub struct RunProperty { #[serde(skip_serializing_if = "Option::is_none")] pub character_spacing: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub stretch: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub fonts: Option, #[serde(skip_serializing_if = "Option::is_none")] pub text_border: Option, @@ -169,6 +171,11 @@ impl RunProperty { self } + pub fn stretch(mut self, v: i32) -> RunProperty { + self.stretch = Some(Stretch::new(v)); + self + } + pub fn text_border(mut self, b: TextBorder) -> Self { self.text_border = Some(b); self @@ -222,6 +229,7 @@ impl BuildXML for RunProperty { .add_optional_child(&self.del)? .add_optional_child(&self.vert_align)? .add_optional_child(&self.character_spacing)? + .add_optional_child(&self.stretch)? .add_optional_child(&self.style)? .add_optional_child(&self.positional_tab)? .add_optional_child(&self.shading)? @@ -318,6 +326,16 @@ mod tests { ); } + #[test] + fn test_stretch() { + let c = RunProperty::new().stretch(80); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } + #[test] fn test_ptab() { let c = RunProperty::new().ptab(PositionalTab::new( diff --git a/docx-core/src/documents/elements/stretch.rs b/docx-core/src/documents/elements/stretch.rs new file mode 100644 index 0000000..e029050 --- /dev/null +++ b/docx-core/src/documents/elements/stretch.rs @@ -0,0 +1,55 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; +use std::io::Write; + +use serde::*; + +#[derive(Debug, Clone, Deserialize, PartialEq)] +pub struct Stretch { + value: i32, +} + +impl Stretch { + pub fn new(s: i32) -> Stretch { + Self { value: s } + } +} + +impl BuildXML for Stretch { + fn build_to( + &self, + stream: xml::writer::EventWriter, + ) -> xml::writer::Result> { + XMLBuilder::from(stream).w(self.value)?.into_inner() + } +} + +impl Serialize for Stretch { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_i32(self.value) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_stretch() { + let b = Stretch::new(200).build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } + + #[test] + fn test_stretch_json() { + let s = Stretch { value: 100 }; + assert_eq!(serde_json::to_string(&s).unwrap(), r#"100"#); + } +} diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 04ec5cd..250eb67 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -278,6 +278,12 @@ impl XMLBuilder { .close() } + // i.e. + pub(crate) fn w(self, s: i32) -> Result { + self.write(XmlEvent::start_element("w:w").attr("w:val", &format!("{}", s)))? + .close() + } + // i.e. pub(crate) fn line_spacing( self,