add paragraph propertie outlineLvl support (#335)

* add support for outlineLvl of ParagraphPropertiy

* add outline_lvl method to Paragraph

* add outlineLvl example

* update test case about  json serializer output
main
14sxlin 2021-09-10 08:42:08 +08:00 committed by GitHub
parent fba23ccb24
commit ff86d6fa67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 109 additions and 7 deletions

View File

@ -0,0 +1,37 @@
use docx_rs::*;
fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./outlineLvl.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Title1"))
.outline_lvl(1),
)
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Title2"))
.outline_lvl(1),
)
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Title2-1"))
.outline_lvl(2),
)
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Title2-2"))
.outline_lvl(2),
)
.add_paragraph(
Paragraph::new()
.add_run(Run::new().add_text("Title3"))
.outline_lvl(1),
)
.build()
.pack(file)?;
Ok(())
}

View File

@ -59,7 +59,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
serde_json::to_string(&graphic).unwrap(), serde_json::to_string(&graphic).unwrap(),
r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#, r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#,
); );
} }
} }

View File

@ -90,7 +90,7 @@ mod tests {
.num_style_link("style1"); .num_style_link("style1");
assert_eq!( assert_eq!(
serde_json::to_string(&c).unwrap(), serde_json::to_string(&c).unwrap(),
r#"{"id":0,"styleLink":null,"numStyleLink":"style1","levels":[{"level":1,"start":1,"format":"decimal","text":"%4.","jc":"left","paragraphProperty":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null},"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"suffix":"tab","pstyle":null,"levelRestart":null}]}"#, r#"{"id":0,"styleLink":null,"numStyleLink":"style1","levels":[{"level":1,"start":1,"format":"decimal","text":"%4.","jc":"left","paragraphProperty":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"suffix":"tab","pstyle":null,"levelRestart":null}]}"#,
); );
} }
} }

View File

@ -43,6 +43,7 @@ mod number_format;
mod numbering; mod numbering;
mod numbering_id; mod numbering_id;
mod numbering_property; mod numbering_property;
mod outline_lvl;
mod page_margin; mod page_margin;
mod page_size; mod page_size;
mod paragraph; mod paragraph;
@ -137,6 +138,7 @@ pub use number_format::*;
pub use numbering::*; pub use numbering::*;
pub use numbering_id::*; pub use numbering_id::*;
pub use numbering_property::*; pub use numbering_property::*;
pub use outline_lvl::*;
pub use page_margin::*; pub use page_margin::*;
pub use page_size::*; pub use page_size::*;
pub use paragraph::*; pub use paragraph::*;

View File

@ -0,0 +1,38 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
use serde::Serialize;
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct OutlineLvl {
pub v: usize,
}
impl OutlineLvl {
pub fn new(v: usize) -> OutlineLvl {
OutlineLvl { v }
}
}
impl BuildXML for OutlineLvl {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.outline_lvl(self.v)
// .close()
.build()
}
}
#[cfg(test)]
mod tests {
use crate::{BuildXML, OutlineLvl};
#[test]
fn test_outline_lvl_build(){
let bytes = OutlineLvl::new(1).build();
assert_eq!(std::str::from_utf8(&bytes).unwrap(),r#"<w:outlineLvl w:val="1" />"#);
}
}

View File

@ -177,6 +177,11 @@ impl Paragraph {
self self
} }
pub fn outline_lvl(mut self, v: usize) -> Self {
self.property = self.property.outline_lvl(v);
self
}
pub fn page_break_before(mut self, v: bool) -> Self { pub fn page_break_before(mut self, v: bool) -> Self {
self.property = self.property.page_break_before(v); self.property = self.property.page_break_before(v);
self self
@ -325,7 +330,7 @@ mod tests {
let p = Paragraph::new().add_run(run); let p = Paragraph::new().add_run(run);
assert_eq!( assert_eq!(
serde_json::to_string(&p).unwrap(), serde_json::to_string(&p).unwrap(),
r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null},"hasNumbering":false}"#, r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#,
); );
} }
@ -336,7 +341,7 @@ mod tests {
let p = Paragraph::new().add_insert(ins); let p = Paragraph::new().add_insert(ins);
assert_eq!( assert_eq!(
serde_json::to_string(&p).unwrap(), serde_json::to_string(&p).unwrap(),
r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null},"hasNumbering":false}"# r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#
); );
} }
} }

View File

@ -18,6 +18,7 @@ pub struct ParagraphProperty {
pub keep_lines: bool, pub keep_lines: bool,
pub page_break_before: bool, pub page_break_before: bool,
pub window_control: bool, pub window_control: bool,
pub outline_lvl: Option<OutlineLvl>,
// read only // read only
pub(crate) div_id: Option<String>, pub(crate) div_id: Option<String>,
} }
@ -35,6 +36,7 @@ impl Default for ParagraphProperty {
keep_lines: false, keep_lines: false,
page_break_before: false, page_break_before: false,
window_control: false, window_control: false,
outline_lvl: None,
div_id: None, div_id: None,
} }
} }
@ -91,6 +93,11 @@ impl ParagraphProperty {
self self
} }
pub fn outline_lvl(mut self, v: usize) -> Self {
self.outline_lvl = Some(OutlineLvl::new(v));
self
}
pub fn page_break_before(mut self, v: bool) -> Self { pub fn page_break_before(mut self, v: bool) -> Self {
self.page_break_before = v; self.page_break_before = v;
self self
@ -130,7 +137,8 @@ impl BuildXML for ParagraphProperty {
.add_optional_child(&self.numbering_property) .add_optional_child(&self.numbering_property)
.add_optional_child(&self.alignment) .add_optional_child(&self.alignment)
.add_optional_child(&self.indent) .add_optional_child(&self.indent)
.add_optional_child(&spacing); .add_optional_child(&spacing)
.add_optional_child(&self.outline_lvl);
if self.keep_next { if self.keep_next {
b = b.keep_next() b = b.keep_next()
@ -198,13 +206,23 @@ mod tests {
); );
} }
#[test]
fn test_outline_lvl() {
let props = ParagraphProperty::new();
let bytes = props.outline_lvl(1).build();
assert_eq!(
str::from_utf8(&bytes).unwrap(),
r#"<w:pPr><w:rPr /><w:outlineLvl w:val="1" /></w:pPr>"#
)
}
#[test] #[test]
fn test_indent_json() { fn test_indent_json() {
let c = ParagraphProperty::new(); let c = ParagraphProperty::new();
let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None); let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None);
assert_eq!( assert_eq!(
serde_json::to_string(&b).unwrap(), serde_json::to_string(&b).unwrap(),
r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10},"hangingChars":null,"firstLineChars":null},"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null}"# r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10},"hangingChars":null,"firstLineChars":null},"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null}"#
); );
} }
} }

View File

@ -185,7 +185,7 @@ mod tests {
.grid_span(2); .grid_span(2);
assert_eq!( assert_eq!(
serde_json::to_string(&c).unwrap(), serde_json::to_string(&c).unwrap(),
r#"{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"divId":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null,"textDirection":null,"shading":null},"hasNumbering":false}"#, r#"{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null,"textDirection":null,"shading":null},"hasNumbering":false}"#,
); );
} }
} }

View File

@ -71,6 +71,8 @@ impl XMLBuilder {
open!(open_paragraph, "w:p", "w14:paraId"); open!(open_paragraph, "w:p", "w14:paraId");
open!(open_paragraph_property, "w:pPr"); open!(open_paragraph_property, "w:pPr");
open!(open_doc_defaults, "w:docDefaults"); open!(open_doc_defaults, "w:docDefaults");
// i.e. <w:outlineLvl ...>
closed_with_usize!(outline_lvl, "w:outlineLvl");
// i.e. <w:name ... > // i.e. <w:name ... >
closed_with_str!(name, "w:name"); closed_with_str!(name, "w:name");
// i.e. <w:jc ... > // i.e. <w:jc ... >