diff --git a/docx-core/examples/indent.rs b/docx-core/examples/indent.rs new file mode 100644 index 0000000..e0e4aa0 --- /dev/null +++ b/docx-core/examples/indent.rs @@ -0,0 +1,24 @@ +use docx_core::*; + +pub const DUMMY: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + +pub fn main() { + 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_paragraph( + Paragraph::new() + .add_run(Run::new(DUMMY)) + .indent(840, Some(SpecialIndentType::FirstLine(720))), + ) + .add_paragraph(Paragraph::new()) + .add_paragraph( + Paragraph::new() + .add_run(Run::new(DUMMY)) + .indent(1560, Some(SpecialIndentType::Hanging(720))), + ) + .build() + .pack(file); +} diff --git a/docx-core/src/documents/elements/indent.rs b/docx-core/src/documents/elements/indent.rs new file mode 100644 index 0000000..d1c34ea --- /dev/null +++ b/docx-core/src/documents/elements/indent.rs @@ -0,0 +1,59 @@ +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug)] +pub struct Indent { + left: usize, + special_indent: Option, +} + +impl Indent { + pub fn new(left: usize, special_indent: Option) -> Indent { + Indent { + left, + special_indent, + } + } +} + +impl BuildXML for Indent { + fn build(&self) -> Vec { + XMLBuilder::new() + .indent(self.left, self.special_indent) + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_left() { + let b = Indent::new(20, None).build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } + + #[test] + fn test_first_line() { + let b = Indent::new(20, Some(SpecialIndentType::FirstLine(40))).build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } + + #[test] + fn test_hanging() { + let b = Indent::new(20, Some(SpecialIndentType::Hanging(50))).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 70fab11..dd2fcd4 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 indent; mod justification; mod name; mod next; @@ -19,6 +20,7 @@ mod text; pub use based_on::*; pub use color::*; pub use doc_defaults::*; +pub use indent::*; pub use justification::*; pub use name::*; pub use next::*; diff --git a/docx-core/src/documents/elements/paragraph.rs b/docx-core/src/documents/elements/paragraph.rs index 771cba1..8e43fc6 100644 --- a/docx-core/src/documents/elements/paragraph.rs +++ b/docx-core/src/documents/elements/paragraph.rs @@ -42,6 +42,11 @@ impl Paragraph { self.property = self.property.style(style_id); self } + + pub fn indent(mut self, left: usize, special_indent: Option) -> Paragraph { + self.property = self.property.indent(left, special_indent); + self + } } impl BuildXML for Paragraph { diff --git a/docx-core/src/documents/elements/paragraph_property.rs b/docx-core/src/documents/elements/paragraph_property.rs index e7210b1..60d4a84 100644 --- a/docx-core/src/documents/elements/paragraph_property.rs +++ b/docx-core/src/documents/elements/paragraph_property.rs @@ -1,22 +1,24 @@ -use super::{Justification, ParagraphStyle, RunProperty, Sz, SzCs}; +use super::{Indent, Justification, ParagraphStyle, RunProperty}; use crate::documents::BuildXML; -use crate::types::AlignmentType; +use crate::types::{AlignmentType, SpecialIndentType}; use crate::xml_builder::*; #[derive(Debug)] pub struct ParagraphProperty { - alignment: Option, run_property: RunProperty, style: ParagraphStyle, + alignment: Option, + indent: Option, } impl Default for ParagraphProperty { fn default() -> Self { let s: Option<&str> = None; ParagraphProperty { - alignment: None, run_property: RunProperty::new(), style: ParagraphStyle::new(s), + alignment: None, + indent: None, } } } @@ -40,13 +42,25 @@ impl ParagraphProperty { self.style = ParagraphStyle::new(Some(style_id)); self } + + pub fn indent( + mut self, + left: usize, + special_indent: Option, + ) -> ParagraphProperty { + self.indent = Some(Indent::new(left, special_indent)); + self + } } impl BuildXML for ParagraphProperty { fn build(&self) -> Vec { XMLBuilder::new() .open_paragraph_property() + .add_child(&self.style) + .add_child(&self.run_property) .add_optional_child(&self.alignment) + .add_optional_child(&self.indent) .close() .build() } @@ -64,7 +78,10 @@ mod tests { fn test_default() { let c = ParagraphProperty::new(); let b = c.build(); - assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); } #[test] @@ -73,7 +90,17 @@ mod tests { let b = c.align(AlignmentType::Right).build(); assert_eq!( str::from_utf8(&b).unwrap(), - r#""# + r#""# + ); + } + + #[test] + fn test_indent() { + let c = ParagraphProperty::new(); + let b = c.indent(20, None).build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# ); } } diff --git a/docx-core/src/types/mod.rs b/docx-core/src/types/mod.rs index f87533e..243f6c6 100644 --- a/docx-core/src/types/mod.rs +++ b/docx-core/src/types/mod.rs @@ -1,5 +1,7 @@ pub mod alignment_type; +pub mod special_indent_type; pub mod style_type; pub use alignment_type::*; +pub use special_indent_type::*; pub use style_type::*; diff --git a/docx-core/src/types/special_indent_type.rs b/docx-core/src/types/special_indent_type.rs new file mode 100644 index 0000000..60c0675 --- /dev/null +++ b/docx-core/src/types/special_indent_type.rs @@ -0,0 +1,7 @@ +// INFO: wasm-bindgen allow c-style enum for now +// Please convert typescript type to following type. +#[derive(Copy, Clone, Debug)] +pub enum SpecialIndentType { + FirstLine(usize), + Hanging(usize), +} diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 14e3493..34bb5e9 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -2,6 +2,8 @@ use super::XMLBuilder; use super::XmlEvent; use crate::types::*; +const EXPECT_MESSAGE: &str = "should write buf"; + impl XMLBuilder { // i.e. opened_el!(open_body, "w:body"); @@ -16,8 +18,8 @@ impl XMLBuilder { }; self.writer .write(XmlEvent::start_element("w:t").attr("xml:space", space)) - .expect("should write to buf"); - self.writer.write(text).expect("should write to buf"); + .expect(EXPECT_MESSAGE); + self.writer.write(text).expect(EXPECT_MESSAGE); self.close() } // i.e. @@ -49,14 +51,14 @@ impl XMLBuilder { .attr("w:type", &style_type.to_string()) .attr("w:styleId", id), ) - .expect("should write to buf"); + .expect(EXPECT_MESSAGE); self } // i.e. pub(crate) fn next(mut self, val: &str) -> Self { self.writer .write(XmlEvent::start_element("w:next").attr("w:val", val)) - .expect("should write to buf"); + .expect(EXPECT_MESSAGE); self.close() } @@ -64,7 +66,25 @@ impl XMLBuilder { pub(crate) fn color(mut self, val: &str) -> Self { self.writer .write(XmlEvent::start_element("w:color").attr("w:val", val)) - .expect("should write to buf"); + .expect(EXPECT_MESSAGE); + self.close() + } + + // i.e. + pub(crate) fn indent(mut self, left: usize, special_indent: Option) -> Self { + let left = &format!("{}", left); + let base = XmlEvent::start_element("w:ind").attr("w:left", left); + match special_indent { + Some(SpecialIndentType::FirstLine(v)) => self + .writer + .write(base.attr("w:firstLine", &format!("{}", v))) + .expect(EXPECT_MESSAGE), + Some(SpecialIndentType::Hanging(v)) => self + .writer + .write(base.attr("w:hanging", &format!("{}", v))) + .expect(EXPECT_MESSAGE), + _ => self.writer.write(base).expect(EXPECT_MESSAGE), + }; self.close() } } diff --git a/fixtures/indent_word_online/[Content_Types].xml b/fixtures/indent_word_online/[Content_Types].xml new file mode 100644 index 0000000..4d5931e --- /dev/null +++ b/fixtures/indent_word_online/[Content_Types].xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fixtures/indent_word_online/_rels/.rels b/fixtures/indent_word_online/_rels/.rels new file mode 100644 index 0000000..0afe5c3 --- /dev/null +++ b/fixtures/indent_word_online/_rels/.rels @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fixtures/indent_word_online/docProps/app.xml b/fixtures/indent_word_online/docProps/app.xml new file mode 100644 index 0000000..5af8832 --- /dev/null +++ b/fixtures/indent_word_online/docProps/app.xml @@ -0,0 +1 @@ +Microsoft Office Word0falsefalsefalse00.0001Normal.dotmfalse \ No newline at end of file diff --git a/fixtures/indent_word_online/docProps/core.xml b/fixtures/indent_word_online/docProps/core.xml new file mode 100644 index 0000000..a751965 --- /dev/null +++ b/fixtures/indent_word_online/docProps/core.xml @@ -0,0 +1 @@ +2019-11-11T06:45:09.0517060Z2019-11-11T06:48:02.2167547ZSatoshi UekiSatoshi Ueki \ No newline at end of file diff --git a/fixtures/indent_word_online/indent.docx b/fixtures/indent_word_online/indent.docx new file mode 100644 index 0000000..0ed341c Binary files /dev/null and b/fixtures/indent_word_online/indent.docx differ diff --git a/fixtures/indent_word_online/word/_rels/document.xml.rels b/fixtures/indent_word_online/word/_rels/document.xml.rels new file mode 100644 index 0000000..8a2db8a --- /dev/null +++ b/fixtures/indent_word_online/word/_rels/document.xml.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/_rels/document2.xml.rels b/fixtures/indent_word_online/word/_rels/document2.xml.rels new file mode 100644 index 0000000..d9d3612 --- /dev/null +++ b/fixtures/indent_word_online/word/_rels/document2.xml.rels @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/document.xml b/fixtures/indent_word_online/word/document.xml new file mode 100644 index 0000000..8d00c87 --- /dev/null +++ b/fixtures/indent_word_online/word/document.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/fontTable.xml b/fixtures/indent_word_online/word/fontTable.xml new file mode 100644 index 0000000..4d95c7e --- /dev/null +++ b/fixtures/indent_word_online/word/fontTable.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/settings.xml b/fixtures/indent_word_online/word/settings.xml new file mode 100644 index 0000000..dc93b1a --- /dev/null +++ b/fixtures/indent_word_online/word/settings.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/styles.xml b/fixtures/indent_word_online/word/styles.xml new file mode 100644 index 0000000..c391f5a --- /dev/null +++ b/fixtures/indent_word_online/word/styles.xml @@ -0,0 +1,428 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/theme/theme1.xml b/fixtures/indent_word_online/word/theme/theme1.xml new file mode 100644 index 0000000..31e6197 --- /dev/null +++ b/fixtures/indent_word_online/word/theme/theme1.xml @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/indent_word_online/word/webSettings.xml b/fixtures/indent_word_online/word/webSettings.xml new file mode 100644 index 0000000..b5d824d --- /dev/null +++ b/fixtures/indent_word_online/word/webSettings.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file