From 23f9a5de79b467adb4d2ddecb4461b03792becdc Mon Sep 17 00:00:00 2001 From: bokuweb Date: Wed, 4 Dec 2019 16:28:11 +0900 Subject: [PATCH] feat: Support underline --- docx-core/src/documents/elements/mod.rs | 2 + docx-core/src/documents/elements/run.rs | 14 ++++++ .../src/documents/elements/run_property.rs | 20 +++++++- docx-core/src/documents/elements/underline.rs | 35 ++++++++++++++ docx-core/src/xml_builder/elements.rs | 3 ++ docx-core/tests/lib.rs | 26 ++++++++++ .../[Content_Types].xml | 3 ++ fixtures/highlight_and_underline/_rels/.rels | 3 ++ .../highlight_and_underline/docProps/app.xml | 2 + .../highlight_and_underline/docProps/core.xml | 2 + .../highlight_and_underline.docx | Bin 0 -> 4215 bytes .../word/_rels/document.xml.rels | 3 ++ .../highlight_and_underline/word/document.xml | 45 ++++++++++++++++++ .../word/fontTable.xml | 2 + .../highlight_and_underline/word/settings.xml | 2 + .../highlight_and_underline/word/styles.xml | 2 + 16 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 docx-core/src/documents/elements/underline.rs create mode 100644 fixtures/highlight_and_underline/[Content_Types].xml create mode 100644 fixtures/highlight_and_underline/_rels/.rels create mode 100644 fixtures/highlight_and_underline/docProps/app.xml create mode 100644 fixtures/highlight_and_underline/docProps/core.xml create mode 100644 fixtures/highlight_and_underline/highlight_and_underline.docx create mode 100644 fixtures/highlight_and_underline/word/_rels/document.xml.rels create mode 100644 fixtures/highlight_and_underline/word/document.xml create mode 100644 fixtures/highlight_and_underline/word/fontTable.xml create mode 100644 fixtures/highlight_and_underline/word/settings.xml create mode 100644 fixtures/highlight_and_underline/word/styles.xml diff --git a/docx-core/src/documents/elements/mod.rs b/docx-core/src/documents/elements/mod.rs index 51e05cd..a62847f 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -42,6 +42,7 @@ mod table_row; mod table_row_property; mod table_width; mod text; +mod underline; mod vertical_merge; mod zoom; @@ -89,5 +90,6 @@ pub use table_row::*; pub use table_row_property::*; pub use table_width::*; pub use text::*; +pub use underline::*; pub use vertical_merge::*; pub use zoom::*; diff --git a/docx-core/src/documents/elements/run.rs b/docx-core/src/documents/elements/run.rs index dc7a58a..47b2b99 100644 --- a/docx-core/src/documents/elements/run.rs +++ b/docx-core/src/documents/elements/run.rs @@ -78,6 +78,11 @@ impl Run { self.run_property = self.run_property.italic(); self } + + pub fn underline(mut self, line_type: &str) -> Run { + self.run_property = self.run_property.underline(line_type); + self + } } impl BuildXML for Run { @@ -112,4 +117,13 @@ mod tests { r#"Hello"# ); } + + #[test] + fn test_underline() { + let b = Run::new().add_text("Hello").underline("single").build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#"Hello"# + ); + } } diff --git a/docx-core/src/documents/elements/run_property.rs b/docx-core/src/documents/elements/run_property.rs index 86c6101..0c01b8f 100644 --- a/docx-core/src/documents/elements/run_property.rs +++ b/docx-core/src/documents/elements/run_property.rs @@ -1,4 +1,4 @@ -use super::{Bold, BoldCs, Color, Highlight, Italic, ItalicCs, Sz, SzCs}; +use super::{Bold, BoldCs, Color, Highlight, Italic, ItalicCs, Sz, SzCs, Underline}; use crate::documents::BuildXML; use crate::xml_builder::*; @@ -8,6 +8,7 @@ pub struct RunProperty { sz_cs: Option, color: Option, highlight: Option, + underline: Option, bold: Option, bold_cs: Option, italic: Option, @@ -46,6 +47,11 @@ impl RunProperty { self.italic_cs = Some(ItalicCs::new()); self } + + pub fn underline(mut self, line_type: &str) -> RunProperty { + self.underline = Some(Underline::new(line_type)); + self + } } impl Default for RunProperty { @@ -55,6 +61,7 @@ impl Default for RunProperty { sz: None, sz_cs: None, highlight: None, + underline: None, bold: None, bold_cs: None, italic: None, @@ -75,6 +82,7 @@ impl BuildXML for RunProperty { .add_optional_child(&self.italic) .add_optional_child(&self.italic_cs) .add_optional_child(&self.highlight) + .add_optional_child(&self.underline) .close() .build() } @@ -117,4 +125,14 @@ mod tests { r#""# ); } + + #[test] + fn test_underline() { + let c = RunProperty::new().underline("single"); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } } diff --git a/docx-core/src/documents/elements/underline.rs b/docx-core/src/documents/elements/underline.rs new file mode 100644 index 0000000..ba555f5 --- /dev/null +++ b/docx-core/src/documents/elements/underline.rs @@ -0,0 +1,35 @@ +use crate::documents::BuildXML; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct Underline { + val: String, +} + +impl Underline { + pub fn new(val: impl Into) -> Underline { + Underline { val: val.into() } + } +} + +impl BuildXML for Underline { + fn build(&self) -> Vec { + XMLBuilder::new().underline(&self.val).build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_underline() { + let c = Underline::new("single"); + let b = c.build(); + assert_eq!(str::from_utf8(&b).unwrap(), r#""#); + } +} diff --git a/docx-core/src/xml_builder/elements.rs b/docx-core/src/xml_builder/elements.rs index 74518a4..a5b552f 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -83,6 +83,9 @@ impl XMLBuilder { // i.e. only_str_val_el!(highlight, "w:highlight"); + // i.e. + only_str_val_el!(underline, "w:u"); + // i.e. pub(crate) fn indent(mut self, left: usize, special_indent: Option) -> Self { let left = &format!("{}", left); diff --git a/docx-core/tests/lib.rs b/docx-core/tests/lib.rs index 73eb01d..7a1cc50 100644 --- a/docx-core/tests/lib.rs +++ b/docx-core/tests/lib.rs @@ -230,3 +230,29 @@ pub fn history() -> Result<(), DocxError> { .pack(file)?; Ok(()) } + +#[test] +pub fn underline() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/underline.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello").underline("single"))) + .build() + .pack(file)?; + Ok(()) +} + +#[test] +pub fn highlight() -> Result<(), DocxError> { + let path = std::path::Path::new("./tests/output/highlight.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_paragraph( + Paragraph::new() + .add_run(Run::new().add_text("Hello").highlight("cyan")) + .add_run(Run::new().add_text(" World!").highlight("yellow")), + ) + .build() + .pack(file)?; + Ok(()) +} diff --git a/fixtures/highlight_and_underline/[Content_Types].xml b/fixtures/highlight_and_underline/[Content_Types].xml new file mode 100644 index 0000000..dc111cb --- /dev/null +++ b/fixtures/highlight_and_underline/[Content_Types].xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/_rels/.rels b/fixtures/highlight_and_underline/_rels/.rels new file mode 100644 index 0000000..f0b72e7 --- /dev/null +++ b/fixtures/highlight_and_underline/_rels/.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/docProps/app.xml b/fixtures/highlight_and_underline/docProps/app.xml new file mode 100644 index 0000000..f55b421 --- /dev/null +++ b/fixtures/highlight_and_underline/docProps/app.xml @@ -0,0 +1,2 @@ + +36LibreOffice/6.0.7.3$Linux_X86_64 LibreOffice_project/00m0$Build-316681 \ No newline at end of file diff --git a/fixtures/highlight_and_underline/docProps/core.xml b/fixtures/highlight_and_underline/docProps/core.xml new file mode 100644 index 0000000..8601f04 --- /dev/null +++ b/fixtures/highlight_and_underline/docProps/core.xml @@ -0,0 +1,2 @@ + +2019-11-22T13:53:22Zja-JP2019-11-22T15:50:33Z1 \ No newline at end of file diff --git a/fixtures/highlight_and_underline/highlight_and_underline.docx b/fixtures/highlight_and_underline/highlight_and_underline.docx new file mode 100644 index 0000000000000000000000000000000000000000..5fe43126a0ddba06d990a885ef727d4f7f53584b GIT binary patch literal 4215 zcmai11z6Ml7N$2OrKA)XHJT~ilaL%RQfVpak_L$ntO3#?-KBuU$kE*)NLq-5C?GKq zkh}SP-<8jMulMZPp6z+|{{R2;p7WmHdvrAL321PDKp>8en2$Ejxgf!OxA3%e_7W1r zem;-a(!ht3-rqW1UiB1iDiX|LVZ{S`Etugr6b=ckc50))S5PuJ$x#s*b2yz(!GLv##DxqdLx7qEsotK zaBIJB4g$i?ESGf;qF=CnG?)SOZe3rCj!!iL&3wGpxvLF$u5S1`d3RvG;nd^!MG10R z3&J@2Q9LN@`e3SU!ZB)n|L*9zM2wpaiQ2FP3g`Qmd>9CAffKT3lXzkGK}OF-CdnyW!c1K%a}W{=(8AlOF($`rR<^4m~8RtJ<;@g z(*{-e*0%YcN_q5zIezQ~yk2|N8Ij`Psu-S*G8JeHx#dJ{!(c;E3#3XonrNA0ww;Mb zqj7X%UQ!E!3?dV)i8BIgS1{^bTg~NpVRw>{6q+E>+AAu-m1^A}O1i)HFeW+tNpgTw z*{Fg$DecRgj2;fqVS%@$W8e<7FN4Qvot#ln9pI@Sa#QjG`Z%~&Te@^B`)&Qvl$W?8 z*r1u0yre%STE{h1k}^y@C%7@pUu%mc`I+r6IKf5@E~VxW-(r9G>UgH=36oy! zCh?(h=!%Nts@rUWJk=E=%_Nhy?b}_QeahSndY^gt?3NZ;f;pj!ms|QG7sqvjhflo< zh%>uIw8m5zNt*_Ve5y|a3D+OTRDGUzl^1I_lb-|zZ5EX0Xj8n)J~Ix&$JWSBv9QJ# zQ=f(33V<0?BVRX98=*hv0!9noF1D_Bv6cFBM#O1d=oF@mL}!79Ul$or#ud3Lx%2Jg zKr)dXV#EXBfI$4mx4`c^S5AVrAVL-v$1!H(0GH@cezmY%UF2lZMR#!h6z4O9T5BH+ zZc6;zC#;8wnxIz6wZ~sa;NU99OzxwE`ETZM{@|`meeOBd?85c%V{IZDe69rpypxK- z&?NB(ZB;I2PLWLIqq2;Qac{$1FW*;9Y=u&7mn8J#$_dIJ7YDhJC4HTJx6o0(Khk|t zDX);1y0UsHE3-IKZ4~g1&KFC^k&tkE4<=da-_n6?*&lRx+1|bD;A-!MB|Yw z5(Q>;=4Z|7YJ2!wB(i@Tr ze31DTjnQ>Gp`e3X)om2-I#OyW_r#7yOc&=3oblst!GLc=Iv(mt*~%7-p*%%bGCU*t zwoje_1Vz`g``w-ir8ssR`={+)-hbK85mI+jhdRT>=8v%du+o9a4(GR$rTRO6J2%(6 z`c}7{e`xl(4iwfUOxdz~VaRu*77&qFL`(HPA|Pi4*TjCxxcXJxD~>&M1B{QYKR4&~ zX69Vl+|3I4Oj=nYu`FK6Y+5+0g9Ve6{?}l%=NXvrMh@dM?q?q^-mEb49m;izz$ff8jcTI~MdHv8opUfCP6z$>d&|Z8N4NG}Soj(ohVBvH2$xzv@3Mf-q*I zzPqb>&=B8YDc%(Fag#? zrE0-EJ`<(tmL z#*>pa-fV4fP0*}XQEvHIdn}ElOCKh}_49Z5iL@rM;>k#XqlWV%jA9(g$5A+D1 z$jhC5`@RB}-;<-aoO$5wD3W(SusM%#&#>h7>BWmOi5@3|0@BEsH%16V59M}@A-K5!Y95f2pBvR5a~s6)b(t!39VmPBt)X^ap~+P9Z^Oe`YJ z93%x*VU0Ul#?I@=$yq^jb^OtNyH6vGQNRb$RIvKhuj1G~8-jnX;K2;AaKhj98O7fs z_PXouZ2Mz`^%#u678EF3(LB#k0Pcs`;7(S?2m)mu$G5m#2NHADAxk%@Crz|v-75mN za<#|xrt3>}j_H@YH^pL=6#nSuJQ&>^zPB5kEiN5s1XoJA^T;WwYUWmgatS=sLsWD2 zXwE8s1mu}>mGYKVCzqHd6~-@oGd;WmwEx z$;^mdGb~p9u%L0VQas({1wn=JQc)e`mFm}*j+2ch8g)_LS-UhthOI5r{BH_MnELnF z6gXxPogzW<_%Rd>Z(ZTxR&korHxvs6NF%ammaUra&1e<_QWe>lBMW8grmJryJyCql zth`LFGw9z5JH&bJR%!6^#*o)Xz5HNh4LI<_!6U`afcf>a9NH7P686J_Puu>uA$R>{4!lI=n3!5Rhj>dgDqNB(4x-F5tduzC3G9NCw zG4EfuG9_bvQ`oU+7TK3-AF#OJZ7fjKQ^cFKbY%=;`gDlp3s>)uWqap%I0K=K?FN`c z#$Q>v^ag+rQ|*%8}++Ll%~?>ww%LgX^G(GFgb;@9&6SDhS=+0#=nuc zq6V&%H>J2gS~K_NQ^hnoR%_Ty?~**|wM$^lhOKU?E$+Go7{k=~cauxV)U~Wi#z}q2Ho?&M>|a0HjN> z4@toEvjXw&`k5Nj&nAkP0|{eHEcE@|ZN1E}$1*BWTRTFSvS;g4)GP5aDc-eD?c-|Jr>uCWZ^_bZ*~%m*pfRDwTCPxH zhldQ$c)t*@)`i=!2Q^URCq~H!ti{>y48*7VD%vD#O1yI7!P{Rp$(Ng$d_Rwf{Ja6cdZ?cPBKiyd4@dPY{`_G7=j}rPf8o!YhF{_5b%dS%KVuc6 qtUsUr-)F(E;PY*PmDI{q-+NKg)Ii literal 0 HcmV?d00001 diff --git a/fixtures/highlight_and_underline/word/_rels/document.xml.rels b/fixtures/highlight_and_underline/word/_rels/document.xml.rels new file mode 100644 index 0000000..8a2db8a --- /dev/null +++ b/fixtures/highlight_and_underline/word/_rels/document.xml.rels @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/word/document.xml b/fixtures/highlight_and_underline/word/document.xml new file mode 100644 index 0000000..e7eb215 --- /dev/null +++ b/fixtures/highlight_and_underline/word/document.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + マーカー + + + + + + + + + + 下線 + + + + + + + + + + + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/word/fontTable.xml b/fixtures/highlight_and_underline/word/fontTable.xml new file mode 100644 index 0000000..94f56db --- /dev/null +++ b/fixtures/highlight_and_underline/word/fontTable.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/word/settings.xml b/fixtures/highlight_and_underline/word/settings.xml new file mode 100644 index 0000000..97dba84 --- /dev/null +++ b/fixtures/highlight_and_underline/word/settings.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/fixtures/highlight_and_underline/word/styles.xml b/fixtures/highlight_and_underline/word/styles.xml new file mode 100644 index 0000000..72e6f53 --- /dev/null +++ b/fixtures/highlight_and_underline/word/styles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file