feat: Support size

main
bokuweb 2019-11-11 15:36:26 +09:00
parent d92d111aa6
commit b167bd7f8d
9 changed files with 116 additions and 28 deletions

View File

@ -0,0 +1,15 @@
use docx_core::*;
pub fn main() {
let path = std::path::Path::new("./output/size.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(Paragraph::new().add_run(Run::new("Hello")).size(60))
.add_paragraph(
Paragraph::new()
.add_run(Run::new(" Wor").size(50))
.add_run(Run::new("ld")),
)
.build()
.pack(file);
}

View File

@ -13,6 +13,7 @@ mod run_property;
mod run_property_default; mod run_property_default;
mod style; mod style;
mod sz; mod sz;
mod sz_cs;
mod text; mod text;
pub use based_on::*; pub use based_on::*;
@ -30,4 +31,5 @@ pub use run_property::*;
pub use run_property_default::*; pub use run_property_default::*;
pub use style::*; pub use style::*;
pub use sz::*; pub use sz::*;
pub use sz_cs::*;
pub use text::*; pub use text::*;

View File

@ -1,4 +1,4 @@
use super::{ParagraphProperty, ParagraphStyle, Run}; use super::{ParagraphProperty, Run};
use crate::documents::BuildXML; use crate::documents::BuildXML;
use crate::types::*; use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
@ -7,16 +7,13 @@ use crate::xml_builder::*;
pub struct Paragraph { pub struct Paragraph {
runs: Vec<Run>, runs: Vec<Run>,
property: ParagraphProperty, property: ParagraphProperty,
style: ParagraphStyle,
} }
impl Default for Paragraph { impl Default for Paragraph {
fn default() -> Self { fn default() -> Self {
let s: Option<&str> = None;
Self { Self {
runs: Vec::new(), runs: Vec::new(),
property: ParagraphProperty::new(), property: ParagraphProperty::new(),
style: ParagraphStyle::new(s),
} }
} }
} }
@ -35,6 +32,16 @@ impl Paragraph {
self.property = self.property.align(alignment_type); self.property = self.property.align(alignment_type);
self self
} }
pub fn size(mut self, size: usize) -> Paragraph {
self.runs = self.runs.into_iter().map(|r| r.size(size)).collect();
self
}
pub fn style(mut self, style_id: &str) -> Paragraph {
self.property = self.property.style(style_id);
self
}
} }
impl BuildXML for Paragraph { impl BuildXML for Paragraph {
@ -42,7 +49,6 @@ impl BuildXML for Paragraph {
XMLBuilder::new() XMLBuilder::new()
.open_paragraph() .open_paragraph()
.add_child(&self.property) .add_child(&self.property)
.add_child(&self.style)
.add_children(&self.runs) .add_children(&self.runs)
.close() .close()
.build() .build()
@ -65,4 +71,13 @@ mod tests {
r#"<w:p><w:pPr /><w:pStyle w:val="Normal" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"# r#"<w:p><w:pPr /><w:pStyle w:val="Normal" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
); );
} }
#[test]
fn test_paragraph_size() {
let b = Paragraph::new().add_run(Run::new("Hello")).size(60).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:pPr /><w:r><w:rPr><w:sz w:val="60" /><w:szCs w:val="60" /></w:rPr><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
);
}
} }

View File

@ -1,4 +1,4 @@
use super::{Justification, RunProperty}; use super::{Justification, ParagraphStyle, RunProperty, Sz, SzCs};
use crate::documents::BuildXML; use crate::documents::BuildXML;
use crate::types::AlignmentType; use crate::types::AlignmentType;
use crate::xml_builder::*; use crate::xml_builder::*;
@ -7,13 +7,16 @@ use crate::xml_builder::*;
pub struct ParagraphProperty { pub struct ParagraphProperty {
alignment: Option<Justification>, alignment: Option<Justification>,
run_property: RunProperty, run_property: RunProperty,
style: ParagraphStyle,
} }
impl Default for ParagraphProperty { impl Default for ParagraphProperty {
fn default() -> Self { fn default() -> Self {
let s: Option<&str> = None;
ParagraphProperty { ParagraphProperty {
alignment: None, alignment: None,
run_property: RunProperty::new(), run_property: RunProperty::new(),
style: ParagraphStyle::new(s),
} }
} }
} }
@ -32,15 +35,20 @@ impl ParagraphProperty {
self.alignment = Some(Justification::new(alignment_type.to_string())); self.alignment = Some(Justification::new(alignment_type.to_string()));
self self
} }
pub fn style(mut self, style_id: &str) -> ParagraphProperty {
self.style = ParagraphStyle::new(Some(style_id));
self
}
} }
impl BuildXML for ParagraphProperty { impl BuildXML for ParagraphProperty {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); XMLBuilder::new()
let p = b
.open_paragraph_property() .open_paragraph_property()
.add_optional_child(&self.alignment); .add_optional_child(&self.alignment)
p.close().build() .close()
.build()
} }
} }
@ -53,9 +61,19 @@ mod tests {
use std::str; use std::str;
#[test] #[test]
fn test_build() { fn test_default() {
let c = ParagraphProperty::new(); let c = ParagraphProperty::new();
let b = c.build(); let b = c.build();
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:pPr />"#); assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:pPr />"#);
} }
#[test]
fn test_alignment() {
let c = ParagraphProperty::new();
let b = c.align(AlignmentType::Right).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:pPr><w:jc w:val="right" /></w:pPr>"#
);
}
} }

View File

@ -15,6 +15,11 @@ impl Run {
..Default::default() ..Default::default()
} }
} }
pub fn size(mut self, size: usize) -> Run {
self.run_property = self.run_property.size(size);
self
}
} }
impl Default for Run { impl Default for Run {

View File

@ -1,10 +1,11 @@
use super::{Color, Sz}; use super::{Color, Sz, SzCs};
use crate::documents::BuildXML; use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug)] #[derive(Debug)]
pub struct RunProperty { pub struct RunProperty {
sz: Option<Sz>, sz: Option<Sz>,
sz_cs: Option<SzCs>,
color: Option<Color>, color: Option<Color>,
} }
@ -13,12 +14,13 @@ impl RunProperty {
Default::default() Default::default()
} }
pub fn add_sz(mut self, sz: usize) -> RunProperty { pub fn size(mut self, size: usize) -> RunProperty {
self.sz = Some(Sz::new(sz)); self.sz = Some(Sz::new(size));
self.sz_cs = Some(SzCs::new(size));
self self
} }
pub fn add_color(mut self, color: &str) -> RunProperty { pub fn color(mut self, color: &str) -> RunProperty {
self.color = Some(Color::new(color)); self.color = Some(Color::new(color));
self self
} }
@ -27,8 +29,9 @@ impl RunProperty {
impl Default for RunProperty { impl Default for RunProperty {
fn default() -> Self { fn default() -> Self {
Self { Self {
sz: None,
color: None, color: None,
sz: None,
sz_cs: None,
} }
} }
} }
@ -38,6 +41,7 @@ impl BuildXML for RunProperty {
let b = XMLBuilder::new(); let b = XMLBuilder::new();
b.open_run_property() b.open_run_property()
.add_optional_child(&self.sz) .add_optional_child(&self.sz)
.add_optional_child(&self.sz_cs)
.add_optional_child(&self.color) .add_optional_child(&self.color)
.close() .close()
.build() .build()
@ -54,11 +58,11 @@ mod tests {
#[test] #[test]
fn test_build() { fn test_build() {
let c = RunProperty::new().add_sz(10).add_color("FFFFFF"); let c = RunProperty::new().size(10).color("FFFFFF");
let b = c.build(); let b = c.build();
assert_eq!( assert_eq!(
str::from_utf8(&b).unwrap(), str::from_utf8(&b).unwrap(),
r#"<w:rPr><w:sz w:val="10" /><w:color w:val="FFFFFF" /></w:rPr>"# r#"<w:rPr><w:sz w:val="10" /><w:szCs w:val="10" /><w:color w:val="FFFFFF" /></w:rPr>"#
); );
} }
} }

View File

@ -0,0 +1,35 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
#[derive(Debug)]
pub struct SzCs {
val: usize,
}
impl SzCs {
pub fn new(val: usize) -> SzCs {
SzCs { val }
}
}
impl BuildXML for SzCs {
fn build(&self) -> Vec<u8> {
XMLBuilder::new().sz_cs(self.val).build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_sz_cs() {
let c = SzCs::new(20);
let b = c.build();
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:szCs w:val="20" />"#);
}
}

View File

@ -8,7 +8,6 @@ impl XMLBuilder {
// i.e. <w:basedOn ... > // i.e. <w:basedOn ... >
only_str_val_el!(based_on, "w:basedOn"); only_str_val_el!(based_on, "w:basedOn");
// i.e. <w:t ... > // i.e. <w:t ... >
// i.e. <w:sz ... >
pub(crate) fn text(mut self, text: &str, preserve_space: bool) -> Self { pub(crate) fn text(mut self, text: &str, preserve_space: bool) -> Self {
let space = if preserve_space { let space = if preserve_space {
"preserve" "preserve"
@ -38,12 +37,9 @@ impl XMLBuilder {
// i.e. <w:pStyle ... > // i.e. <w:pStyle ... >
only_str_val_el!(paragraph_style, "w:pStyle"); only_str_val_el!(paragraph_style, "w:pStyle");
// i.e. <w:sz ... > // i.e. <w:sz ... >
pub(crate) fn sz(mut self, val: usize) -> Self { only_usize_val_el!(sz, "w:sz");
self.writer // i.e. <w:szCs ... >
.write(XmlEvent::start_element("w:sz").attr("w:val", &format!("{}", val))) only_usize_val_el!(sz_cs, "w:szCs");
.expect("should write to buf");
self.close()
}
// Build w:style element // Build w:style element
// i.e. <w:style ... > // i.e. <w:style ... >
pub(crate) fn open_style(mut self, style_type: StyleType, id: &str) -> Self { pub(crate) fn open_style(mut self, style_type: StyleType, id: &str) -> Self {

View File

@ -142,15 +142,13 @@ macro_rules! only_str_val_el {
}; };
} }
/*
macro_rules! only_usize_val_el { macro_rules! only_usize_val_el {
($name: ident, $el_name: expr) => { ($name: ident, $el_name: expr) => {
pub(crate) fn $name(mut self, val: usize) -> Self { pub(crate) fn $name(mut self, val: usize) -> Self {
self.writer self.writer
.write(XmlEvent::start_element($el_name).attr("w:val", val)) .write(XmlEvent::start_element($el_name).attr("w:val", &format!("{}", val)))
.expect("should write to buf"); .expect("should write to buf");
self.close() self.close()
} }
}; };
} }
*/