From 8c657d1d85a7d41aeb32bc80644e1575082f0efb Mon Sep 17 00:00:00 2001 From: bokuweb Date: Wed, 13 Nov 2019 15:00:53 +0900 Subject: [PATCH] feat: Add grid span and vmerge --- docx-core/src/documents/elements/grid_span.rs | 34 +++ docx-core/src/documents/elements/mod.rs | 4 + docx-core/src/documents/elements/table.rs | 2 +- .../src/documents/elements/table_cell.rs | 11 + .../documents/elements/table_cell_property.rs | 38 ++- .../src/documents/elements/table_property.rs | 2 +- .../src/documents/elements/vertical_merge.rs | 40 +++ docx-core/src/types/mod.rs | 2 + docx-core/src/types/vertical_merge_type.rs | 18 ++ docx-core/src/types/width_type.rs | 4 +- docx-core/src/xml_builder/elements.rs | 3 + docx-core/tests/lib.rs | 38 +++ .../[Content_Types].xml | 3 + .../table_merged_libre_office/_rels/.rels | 3 + .../docProps/app.xml | 2 + .../docProps/core.xml | 2 + .../table_merged.docx | Bin 0 -> 4496 bytes .../word/_rels/document.xml.rels | 3 + .../word/document.xml | 241 ++++++++++++++++++ .../word/fontTable.xml | 2 + .../word/settings.xml | 2 + .../table_merged_libre_office/word/styles.xml | 2 + 22 files changed, 451 insertions(+), 5 deletions(-) create mode 100644 docx-core/src/documents/elements/grid_span.rs create mode 100644 docx-core/src/documents/elements/vertical_merge.rs create mode 100644 docx-core/src/types/vertical_merge_type.rs create mode 100644 fixtures/table_merged_libre_office/[Content_Types].xml create mode 100644 fixtures/table_merged_libre_office/_rels/.rels create mode 100644 fixtures/table_merged_libre_office/docProps/app.xml create mode 100644 fixtures/table_merged_libre_office/docProps/core.xml create mode 100644 fixtures/table_merged_libre_office/table_merged.docx create mode 100644 fixtures/table_merged_libre_office/word/_rels/document.xml.rels create mode 100644 fixtures/table_merged_libre_office/word/document.xml create mode 100644 fixtures/table_merged_libre_office/word/fontTable.xml create mode 100644 fixtures/table_merged_libre_office/word/settings.xml create mode 100644 fixtures/table_merged_libre_office/word/styles.xml diff --git a/docx-core/src/documents/elements/grid_span.rs b/docx-core/src/documents/elements/grid_span.rs new file mode 100644 index 0000000..a5d8d35 --- /dev/null +++ b/docx-core/src/documents/elements/grid_span.rs @@ -0,0 +1,34 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct GridSpan { + val: usize, +} + +impl GridSpan { + pub fn new(v: usize) -> GridSpan { + GridSpan { val: v } + } +} + +impl BuildXML for GridSpan { + fn build(&self) -> Vec { + XMLBuilder::new().grid_span(self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_grid_span() { + let b = GridSpan::new(3).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 a3187f0..df6a6d2 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 grid_span; mod indent; mod justification; mod name; @@ -29,10 +30,12 @@ mod table_row; mod table_row_property; mod table_width; mod text; +mod vertical_merge; pub use based_on::*; pub use color::*; pub use doc_defaults::*; +pub use grid_span::*; pub use indent::*; pub use justification::*; pub use name::*; @@ -61,3 +64,4 @@ pub use table_row::*; pub use table_row_property::*; pub use table_width::*; pub use text::*; +pub use vertical_merge::*; diff --git a/docx-core/src/documents/elements/table.rs b/docx-core/src/documents/elements/table.rs index 7b36a11..2ea2123 100644 --- a/docx-core/src/documents/elements/table.rs +++ b/docx-core/src/documents/elements/table.rs @@ -56,7 +56,7 @@ mod tests { -"# +"# ); } diff --git a/docx-core/src/documents/elements/table_cell.rs b/docx-core/src/documents/elements/table_cell.rs index ae60cac..9afc1f0 100644 --- a/docx-core/src/documents/elements/table_cell.rs +++ b/docx-core/src/documents/elements/table_cell.rs @@ -1,5 +1,6 @@ use super::{Paragraph, TableCellProperty}; use crate::documents::BuildXML; +use crate::types::*; use crate::xml_builder::*; #[derive(Debug, Clone)] @@ -24,6 +25,16 @@ impl TableCell { self.contents.push(TableCellContent::Paragraph(p)); self } + + pub fn vertical_merge(mut self, t: VMergeType) -> TableCell { + self.property = self.property.vertical_merge(t); + self + } + + pub fn grid_span(mut self, v: usize) -> TableCell { + self.property = self.property.grid_span(v); + self + } } impl BuildXML for TableCell { diff --git a/docx-core/src/documents/elements/table_cell_property.rs b/docx-core/src/documents/elements/table_cell_property.rs index f5a3e5e..cbc80ea 100644 --- a/docx-core/src/documents/elements/table_cell_property.rs +++ b/docx-core/src/documents/elements/table_cell_property.rs @@ -1,4 +1,4 @@ -use super::{TableCellBorders, TableCellWidth}; +use super::{GridSpan, TableCellBorders, TableCellWidth, VMerge}; use crate::documents::BuildXML; use crate::types::*; use crate::xml_builder::*; @@ -7,6 +7,8 @@ use crate::xml_builder::*; pub struct TableCellProperty { width: Option, borders: Option, + grid_span: Option, + vertical_merge: Option, } impl TableCellProperty { @@ -14,6 +16,8 @@ impl TableCellProperty { TableCellProperty { width: None, borders: None, + grid_span: None, + vertical_merge: None, } } @@ -21,6 +25,16 @@ impl TableCellProperty { self.width = Some(TableCellWidth::new(v, t)); self } + + pub fn vertical_merge(mut self, t: VMergeType) -> TableCellProperty { + self.vertical_merge = Some(VMerge::new(t)); + self + } + + pub fn grid_span(mut self, v: usize) -> TableCellProperty { + self.grid_span = Some(GridSpan::new(v)); + self + } } impl BuildXML for TableCellProperty { @@ -29,6 +43,8 @@ impl BuildXML for TableCellProperty { .open_table_cell_property() .add_optional_child(&self.width) .add_optional_child(&self.borders) + .add_optional_child(&self.grid_span) + .add_optional_child(&self.vertical_merge) .close() .build() } @@ -48,4 +64,24 @@ mod tests { let b = c.build(); assert_eq!(str::from_utf8(&b).unwrap(), r#""#); } + + #[test] + fn test_grid_span() { + let c = TableCellProperty::new().grid_span(3); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } + + #[test] + fn test_vmerge() { + let c = TableCellProperty::new().vertical_merge(VMergeType::Continue); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } } diff --git a/docx-core/src/documents/elements/table_property.rs b/docx-core/src/documents/elements/table_property.rs index a764d19..efd649d 100644 --- a/docx-core/src/documents/elements/table_property.rs +++ b/docx-core/src/documents/elements/table_property.rs @@ -15,7 +15,7 @@ pub struct TableProperty { impl Default for TableProperty { fn default() -> Self { TableProperty { - width: TableWidth::new(0, WidthType::AUTO), + width: TableWidth::new(0, WidthType::Auto), justification: Justification::new("left"), borders: TableBorders::new(), margins: TableCellMargins::new(), diff --git a/docx-core/src/documents/elements/vertical_merge.rs b/docx-core/src/documents/elements/vertical_merge.rs new file mode 100644 index 0000000..6b018ca --- /dev/null +++ b/docx-core/src/documents/elements/vertical_merge.rs @@ -0,0 +1,40 @@ +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct VMerge { + val: VMergeType, +} + +impl VMerge { + pub fn new(v: VMergeType) -> VMerge { + VMerge { val: v } + } +} + +impl BuildXML for VMerge { + fn build(&self) -> Vec { + XMLBuilder::new() + .vertical_merge(&self.val.to_string()) + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_build() { + let b = VMerge::new(VMergeType::Continue).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 0090fa3..2cb0808 100644 --- a/docx-core/src/types/mod.rs +++ b/docx-core/src/types/mod.rs @@ -4,6 +4,7 @@ pub mod border_type; pub mod special_indent_type; pub mod style_type; pub mod table_alignment_type; +pub mod vertical_merge_type; pub mod width_type; pub use alignment_type::*; @@ -12,4 +13,5 @@ pub use border_type::*; pub use special_indent_type::*; pub use style_type::*; pub use table_alignment_type::*; +pub use vertical_merge_type::*; pub use width_type::*; diff --git a/docx-core/src/types/vertical_merge_type.rs b/docx-core/src/types/vertical_merge_type.rs new file mode 100644 index 0000000..68b3156 --- /dev/null +++ b/docx-core/src/types/vertical_merge_type.rs @@ -0,0 +1,18 @@ +use std::fmt; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Copy, Clone, Debug)] +pub enum VMergeType { + Continue, + Restart, +} + +impl fmt::Display for VMergeType { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + VMergeType::Continue => write!(f, "continue"), + VMergeType::Restart => write!(f, "restart"), + } + } +} diff --git a/docx-core/src/types/width_type.rs b/docx-core/src/types/width_type.rs index 10c8c4d..ee0458f 100644 --- a/docx-core/src/types/width_type.rs +++ b/docx-core/src/types/width_type.rs @@ -5,14 +5,14 @@ use wasm_bindgen::prelude::*; #[derive(Copy, Clone, Debug)] pub enum WidthType { DXA, - AUTO, + Auto, } impl fmt::Display for WidthType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { WidthType::DXA => write!(f, "dxa"), - WidthType::AUTO => write!(f, "auto"), + WidthType::Auto => write!(f, "auto"), } } } diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 5dd0b7b..c024ccb 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -107,6 +107,9 @@ impl XMLBuilder { closed_w_with_type_el!(grid_column, "w:gridCol"); closed_w_with_type_el!(table_cell_width, "w:tcW"); + only_usize_val_el!(grid_span, "w:gridSpan"); + only_str_val_el!(vertical_merge, "w:vMerge"); + closed_w_with_type_el!(margin_top, "w:top"); closed_w_with_type_el!(margin_left, "w:left"); closed_w_with_type_el!(margin_bottom, "w:bottom"); diff --git a/docx-core/tests/lib.rs b/docx-core/tests/lib.rs index 074147d..84bfe30 100644 --- a/docx-core/tests/lib.rs +++ b/docx-core/tests/lib.rs @@ -97,3 +97,41 @@ pub fn table_with_grid() -> Result<(), DocxError> { Docx::new().add_table(table).build().pack(file)?; Ok(()) } + +#[test] +pub fn table_merged() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/table_merged.docx"); + let file = std::fs::File::create(&path).unwrap(); + + let table = Table::new(vec![ + TableRow::new(vec![ + TableCell::new() + .add_paragraph(Paragraph::new()) + .grid_span(2), + TableCell::new() + .add_paragraph(Paragraph::new().add_run(Run::new("Hello"))) + .vertical_merge(VMergeType::Restart), + ]), + TableRow::new(vec![ + TableCell::new() + .add_paragraph(Paragraph::new()) + .vertical_merge(VMergeType::Restart), + TableCell::new().add_paragraph(Paragraph::new()), + TableCell::new() + .add_paragraph(Paragraph::new()) + .vertical_merge(VMergeType::Continue), + ]), + TableRow::new(vec![ + TableCell::new() + .add_paragraph(Paragraph::new()) + .vertical_merge(VMergeType::Continue), + TableCell::new().add_paragraph(Paragraph::new()), + TableCell::new() + .add_paragraph(Paragraph::new()) + .vertical_merge(VMergeType::Continue), + ]), + ]) + .set_grid(vec![2000, 2000, 2000]); + Docx::new().add_table(table).build().pack(file)?; + Ok(()) +} diff --git a/fixtures/table_merged_libre_office/[Content_Types].xml b/fixtures/table_merged_libre_office/[Content_Types].xml new file mode 100644 index 0000000..dc111cb --- /dev/null +++ b/fixtures/table_merged_libre_office/[Content_Types].xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/_rels/.rels b/fixtures/table_merged_libre_office/_rels/.rels new file mode 100644 index 0000000..f0b72e7 --- /dev/null +++ b/fixtures/table_merged_libre_office/_rels/.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/docProps/app.xml b/fixtures/table_merged_libre_office/docProps/app.xml new file mode 100644 index 0000000..4071433 --- /dev/null +++ b/fixtures/table_merged_libre_office/docProps/app.xml @@ -0,0 +1,2 @@ + +1LibreOffice/6.0.7.3$Linux_X86_64 LibreOffice_project/00m0$Build-310000 \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/docProps/core.xml b/fixtures/table_merged_libre_office/docProps/core.xml new file mode 100644 index 0000000..6e51d28 --- /dev/null +++ b/fixtures/table_merged_libre_office/docProps/core.xml @@ -0,0 +1,2 @@ + +2019-11-13T14:09:27Zja-JP2019-11-13T14:10:33Z1 \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/table_merged.docx b/fixtures/table_merged_libre_office/table_merged.docx new file mode 100644 index 0000000000000000000000000000000000000000..5fa1bd26f17b567ae1af13d843a88a73073c3511 GIT binary patch literal 4496 zcmai1c|6qp79PgFFJm1P+1ChV8A}M+#$E_nMl^O|Y*A9SG?wgp#xf1rg;8kiL}aHZ zmF(HF<<9ip_vY<$Z}-e+<}-iH^ZU+u&i6UzIZ!>h@xEldZ1U3GrA={4{-X+ zrLxlAC7HZ1Ba=>L2fpfJr1wnSZrW{`yjyp|`Zt>eV&@m+Kuz)1UqPpH8xiB7st z#Gni)W}5Dtnu1BNa6nZSg*C}h8p;Wl)Et$*r_EZhqiNL}) z@6K31qWTd?wmHr040ir9kVDk_G3dqykU*_jlOKSa2mttjfB$c48BbE{=;`B3;5Oc* z*RcI8L-QsJaxMA;8Bu(q8Sx0Pz(gQMZ8{EXaLu8!YG&-+2Yv&qJaP{ur4JLS)!nuh zt*mh@wLOf{4xn%cIkvLCp(O{-+5DG^Wfw4Rqza1RT1oSwj*8B;5zkBI*o9t_&FV}f zFLGhBhDACaW7JH*h>zS(i=p}Ios8cD93yNi?An)Kj((r5&7Xa4SE1=GuObexixgMFZD81~4f8Occj%*d|M`oZ#E5w{$u z>?#Y;%&GH|2`pUkeZ+a4CLhS=V`XJYR0%uIiHnIT(Mi30I56v>hpNosQmErNu2zI| zha{x0Rpw01=K1BWQ%@jd2= ze&w2&6+Z&5Nuh;nZSGRNVdb_TuAK=fk9h9!gy{P?rKNi6YP;%j<##edg%%{QNIT-I zGxf*I&xNm0fTxd>)L%UTuY+6e&K`b*I{nojkOow3XBqD8=J55+qRbhPC=X39v2B2K zc3rDHWw&rpFfhhSc)o4nFmz2?%FgcK;k7|>_xNye-H3eSx;H3BFX8%Ofv2&$EuDrY zHk26u2ppK1q(;*Nhk#1#$ncNmM<-40+nR`nwr86OO`OgxTD)^$LswjfYLN% z!8vV(IpffEUuHW|VG*4`fNyc{Oq>KlT!1Ywhy)}e*R&6-Z_?{tjWb|HQ3PZH=v?1> z=Q~Cwv@fkNUl`JK?9peRqbBt~>i1tEG4E$`q2{0Ayl#QX-j(UQk_d0$r&6hItp|woE$;1+F8?cjPP^KH70ted?)n@HlWOO2J{5ZUk@0G|Wk7E}Tv?0NHM@aJbfRNC z<#MIR5Yg+9`^nEb$jPNc+tq1RMy{=MrYAL4yBUM%dm?xdk15BxzN4f$bFn|Xbi6^7 zH+WIh4RYMQZxyoHFB7L;T#M6S1#`X13{XqYv!;j>GNi9d)Z#Ut1-dM6$k3+eL=0%o z*nWbL0E1(NbmCzz^y{_jcm3bo^uAe9teIYyp&U!zerSZYtnPf&%W6%7>MpncAehgV zog0cSb=tH}U59Wm7?Fa58&w8!V-!^bw@C@)wsuZX5W1l`@c(tgpO@>T%2uve8%>=B zg}tjN`9|kzRgzb5npU<0Si%Gk_U9Jb_>>7RE;`s&GF*e;Lt8bxWE-C?R<86%u8YpF!H%!E!T#RPTmA^8MJ(>3)R3aW>Vgkrr#y}P5I zLDU#v;zGuyxbgRQyqtC};H)^)Cm`Z`S702tSMc(@9v4yF;PPaa z(B8K!wdnwv`Ca0u?G;@gE&cf3*%mS|;Su;yl`EmbhgU8`x`6^P;ybHV?8OF?xz;!| zkah|+X%x1_`p~ztkawDY{HiF_aLpLh1XPt??q|%@jB~1+1r~`RN8OI(6i*-1NVaBU zEKEo#*d)&wwjbtb-gPTr5ac1#6Pz2^MjO#C#I2S?l14ALG^wyep*}8^12&S(`o{#pQS9CghF__<1da5j-O@8+lQbDPnDjLeVmV)D63~4(BYXhyKV97+RqL?`1 zvoMmyONEBmvX;ZcQArNUVzide^7Dlywo4WHW8H_8o-mDCu?}U-&SA!vW^WDV@0hV2 zM{{MHw`08efbTzyIoRq$Kif4Ly^P=53uRsu-AwJ7Za8jUu5D6!+-72&SdI-? zIWnl(rHx!})ERsC&d9m($L#iQz$A6Z?S#xu^l_KZgB<&%Qd)hwmv^S8M0z0J=3xg- zu+T)Vrs9{lhVZ>FHv&O)HfLtgh($VDG+S1T&`Q;53KJgN!6$A4>B)7-k!AQjge!J1 zvr%O4+KO8Tk%~Z?ysno~x~T-%ANC;K>)`Yg>M~v%(ad5HY7N%X#>?m(s2n%Nwmqy$ z(377zE0hthrN?Z4(i8pP&C1sg0eAk{s&VE9p3Kq=*iA8umf}o{BMResb6xY&A}SWw z+u>tN2Gc?AAG|Z7tm$7yoSUa1e^n|ZdHRO|OY3X<9qKo$QFSC=1e$UxJ3VKEm9D;1 z)_W4rBSC>7u4)+M=dsk+zPJta@oN~q!AQ?#&X{7g5gw=Ts6U>3sZhS5^5gqC1nG*g z8reX4-5Lf zN^5(?jayvQ9n~g*A(iP^fhzGw&!zynB@m7bve9!R(NLYa4i5Htfv4Ch%gHxThx!Ni z;r10s*pxC#WAXI0NuafOtohFPP*22pH&gqIBu;jb(+&tsGfzFAU>YY}Bn>$anr5Zo zd{pi~xnxXg>#|l^AMgmq@m>VNFfjG0*lb9p_RjakTA^vtX|K!9YLCA$C?9iNkvzlQ zz>{RQ-OFwnUpQ+H>a0Q9amP^b(rY@_XYy>tMjb85rY)hjq?wRBw;r*hox{dK_lxTf zSfbAP&MkPrp=25oE7opgB01u<;3DPx0-0g$p~zG$XzppJi&Fa6AN>zjtuLX9>YS*cqWya&|~Z>V0wArgw`Czh9N< zC-=t?*J&8I<$xC}Dj_uSmES)1R}zu5ql0k8+*Cia%?xY^dMi}C2UsBHSO=FrLeGDei^r_ zj@paoE-`-+ayR}IK?Fr0y(-8TOVdonSB*z z3K{g`vbLfxZl|xlw2ORYx%9SX`nhcPvE$GgPF|Azilyu#(ESz^n z=Sz<}+ENw!hGGR&B##4>`h@Nd!uC|!TJFDSh?fp%tDsW(Aysysz_yqF(4qu>gxiu3 z*d`(d0e$i*34hQgg@%{rSo_6Ne53broX}+e=Yul{(G + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/word/document.xml b/fixtures/table_merged_libre_office/word/document.xml new file mode 100644 index 0000000..3657372 --- /dev/null +++ b/fixtures/table_merged_libre_office/word/document.xml @@ -0,0 +1,241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/word/fontTable.xml b/fixtures/table_merged_libre_office/word/fontTable.xml new file mode 100644 index 0000000..94f56db --- /dev/null +++ b/fixtures/table_merged_libre_office/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/word/settings.xml b/fixtures/table_merged_libre_office/word/settings.xml new file mode 100644 index 0000000..97dba84 --- /dev/null +++ b/fixtures/table_merged_libre_office/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/table_merged_libre_office/word/styles.xml b/fixtures/table_merged_libre_office/word/styles.xml new file mode 100644 index 0000000..f4a3277 --- /dev/null +++ b/fixtures/table_merged_libre_office/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file