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 outputmain
parent
fba23ccb24
commit
ff86d6fa67
|
@ -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(())
|
||||
}
|
|
@ -59,7 +59,7 @@ mod tests {
|
|||
);
|
||||
assert_eq!(
|
||||
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}}]}}]}]}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ mod tests {
|
|||
.num_style_link("style1");
|
||||
assert_eq!(
|
||||
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}]}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ mod number_format;
|
|||
mod numbering;
|
||||
mod numbering_id;
|
||||
mod numbering_property;
|
||||
mod outline_lvl;
|
||||
mod page_margin;
|
||||
mod page_size;
|
||||
mod paragraph;
|
||||
|
@ -137,6 +138,7 @@ pub use number_format::*;
|
|||
pub use numbering::*;
|
||||
pub use numbering_id::*;
|
||||
pub use numbering_property::*;
|
||||
pub use outline_lvl::*;
|
||||
pub use page_margin::*;
|
||||
pub use page_size::*;
|
||||
pub use paragraph::*;
|
||||
|
|
|
@ -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" />"#);
|
||||
}
|
||||
|
||||
}
|
|
@ -177,6 +177,11 @@ impl Paragraph {
|
|||
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 {
|
||||
self.property = self.property.page_break_before(v);
|
||||
self
|
||||
|
@ -325,7 +330,7 @@ mod tests {
|
|||
let p = Paragraph::new().add_run(run);
|
||||
assert_eq!(
|
||||
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);
|
||||
assert_eq!(
|
||||
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}"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ pub struct ParagraphProperty {
|
|||
pub keep_lines: bool,
|
||||
pub page_break_before: bool,
|
||||
pub window_control: bool,
|
||||
pub outline_lvl: Option<OutlineLvl>,
|
||||
// read only
|
||||
pub(crate) div_id: Option<String>,
|
||||
}
|
||||
|
@ -35,6 +36,7 @@ impl Default for ParagraphProperty {
|
|||
keep_lines: false,
|
||||
page_break_before: false,
|
||||
window_control: false,
|
||||
outline_lvl: None,
|
||||
div_id: None,
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +93,11 @@ impl ParagraphProperty {
|
|||
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 {
|
||||
self.page_break_before = v;
|
||||
self
|
||||
|
@ -130,7 +137,8 @@ impl BuildXML for ParagraphProperty {
|
|||
.add_optional_child(&self.numbering_property)
|
||||
.add_optional_child(&self.alignment)
|
||||
.add_optional_child(&self.indent)
|
||||
.add_optional_child(&spacing);
|
||||
.add_optional_child(&spacing)
|
||||
.add_optional_child(&self.outline_lvl);
|
||||
|
||||
if self.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]
|
||||
fn test_indent_json() {
|
||||
let c = ParagraphProperty::new();
|
||||
let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None);
|
||||
assert_eq!(
|
||||
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}"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -185,7 +185,7 @@ mod tests {
|
|||
.grid_span(2);
|
||||
assert_eq!(
|
||||
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}"#,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,8 @@ impl XMLBuilder {
|
|||
open!(open_paragraph, "w:p", "w14:paraId");
|
||||
open!(open_paragraph_property, "w:pPr");
|
||||
open!(open_doc_defaults, "w:docDefaults");
|
||||
// i.e. <w:outlineLvl ...>
|
||||
closed_with_usize!(outline_lvl, "w:outlineLvl");
|
||||
// i.e. <w:name ... >
|
||||
closed_with_str!(name, "w:name");
|
||||
// i.e. <w:jc ... >
|
||||
|
|
Loading…
Reference in New Issue