diff --git a/docx-core/src/documents/elements/mod.rs b/docx-core/src/documents/elements/mod.rs index e6905c0..b7a3db1 100644 --- a/docx-core/src/documents/elements/mod.rs +++ b/docx-core/src/documents/elements/mod.rs @@ -16,7 +16,10 @@ mod style; mod sz; mod sz_cs; mod table_borders; +mod table_cell_borders; mod table_cell_margins; +mod table_cell_property; +mod table_cell_width; mod table_grid; mod table_indent; mod table_property; @@ -41,7 +44,10 @@ pub use style::*; pub use sz::*; pub use sz_cs::*; pub use table_borders::*; +pub use table_cell_borders::*; pub use table_cell_margins::*; +pub use table_cell_property::*; +pub use table_cell_width::*; pub use table_grid::*; pub use table_indent::*; pub use table_property::*; diff --git a/docx-core/src/documents/elements/table_cell_borders.rs b/docx-core/src/documents/elements/table_cell_borders.rs new file mode 100644 index 0000000..ca3e167 --- /dev/null +++ b/docx-core/src/documents/elements/table_cell_borders.rs @@ -0,0 +1,155 @@ +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +/* + Please see. L.4.3.2.18 Cell Border Properties + + left – left border + right – right border + top – top border + bottom – bottom border + insideH – inner horizontal borders + insideV – inner vertical borders + tl2br – diagonal border from top left corner to bottom right corner + tr2bl – diagonal border from top right corner to bottom left corner +*/ + +#[derive(Debug, Clone)] +pub struct TableCellBorder { + position: BorderPosition, + border_type: BorderType, + size: usize, + space: usize, + color: String, +} + +impl TableCellBorder { + pub fn new(position: BorderPosition) -> TableCellBorder { + TableCellBorder { + position, + border_type: BorderType::Single, + size: 2, + space: 0, + color: "000000".to_owned(), + } + } + + pub fn color(mut self, color: impl Into) -> TableCellBorder { + self.color = color.into(); + self + } +} + +impl BuildXML for TableCellBorder { + fn build(&self) -> Vec { + let base = XMLBuilder::new(); + let base = match self.position { + BorderPosition::Top => { + base.border_top(self.border_type, self.size, self.space, &self.color) + } + BorderPosition::Left => { + base.border_left(self.border_type, self.size, self.space, &self.color) + } + BorderPosition::Bottom => { + base.border_bottom(self.border_type, self.size, self.space, &self.color) + } + BorderPosition::Right => { + base.border_right(self.border_type, self.size, self.space, &self.color) + } + BorderPosition::IndideH => { + base.border_inside_h(self.border_type, self.size, self.space, &self.color) + } + BorderPosition::IndideV => { + base.border_inside_v(self.border_type, self.size, self.space, &self.color) + } + }; + base.build() + } +} + +#[derive(Debug, Clone)] +pub struct TableCellBorders { + top: Option, + left: Option, + bottom: Option, + right: Option, + inside_h: Option, + inside_v: Option, +} + +impl Default for TableCellBorders { + fn default() -> TableCellBorders { + TableCellBorders { + top: Some(TableCellBorder::new(BorderPosition::Top)), + left: Some(TableCellBorder::new(BorderPosition::Left)), + bottom: Some(TableCellBorder::new(BorderPosition::Bottom)), + right: None, + inside_h: Some(TableCellBorder::new(BorderPosition::IndideH)), + inside_v: None, + } + } +} + +impl TableCellBorders { + pub fn new() -> TableCellBorders { + Default::default() + } + + pub fn set_border(mut self, border: TableCellBorder) -> Self { + match border.position { + BorderPosition::Top => self.top = Some(border), + BorderPosition::Left => self.left = Some(border), + BorderPosition::Bottom => self.bottom = Some(border), + BorderPosition::Right => self.right = Some(border), + BorderPosition::IndideH => self.inside_h = Some(border), + BorderPosition::IndideV => self.inside_v = Some(border), + }; + self + } + + pub fn clear_border(mut self, position: BorderPosition) -> Self { + match position { + BorderPosition::Top => self.top = None, + BorderPosition::Left => self.left = None, + BorderPosition::Bottom => self.bottom = None, + BorderPosition::Right => self.right = None, + BorderPosition::IndideH => self.inside_h = None, + BorderPosition::IndideV => self.inside_v = None, + }; + self + } +} + +impl BuildXML for TableCellBorders { + fn build(&self) -> Vec { + XMLBuilder::new() + .open_table_cell_borders() + .add_optional_child(&self.top) + .add_optional_child(&self.left) + .add_optional_child(&self.bottom) + .add_optional_child(&self.right) + .add_optional_child(&self.inside_h) + .add_optional_child(&self.inside_v) + .close() + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_table_borders() { + let b = TableCellBorders::new().build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } +} diff --git a/docx-core/src/documents/elements/table_cell_property.rs b/docx-core/src/documents/elements/table_cell_property.rs new file mode 100644 index 0000000..e168ec2 --- /dev/null +++ b/docx-core/src/documents/elements/table_cell_property.rs @@ -0,0 +1,54 @@ +use super::{TableCellBorders, TableCellWidth}; +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug)] +pub struct TableCellProperty { + width: TableCellWidth, + borders: TableCellBorders, +} + +impl TableCellProperty { + pub fn new(w: usize) -> TableCellProperty { + TableCellProperty { + width: TableCellWidth::new(w, WidthType::DXA), + borders: TableCellBorders::new(), + } + } + + pub fn width(mut self, v: usize) -> TableCellProperty { + self.width = TableCellWidth::new(v, WidthType::DXA); + self + } +} + +impl BuildXML for TableCellProperty { + fn build(&self) -> Vec { + XMLBuilder::new() + .open_table_cell_property() + .add_child(&self.width) + .add_child(&self.borders) + .close() + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_default() { + let c = TableCellProperty::new(200); + let b = c.build(); + assert_eq!( + str::from_utf8(&b).unwrap(), + r#""# + ); + } +} diff --git a/docx-core/src/documents/elements/table_cell_width.rs b/docx-core/src/documents/elements/table_cell_width.rs new file mode 100644 index 0000000..931f020 --- /dev/null +++ b/docx-core/src/documents/elements/table_cell_width.rs @@ -0,0 +1,41 @@ +use crate::documents::BuildXML; +use crate::types::*; +use crate::xml_builder::*; + +#[derive(Debug, Clone)] +pub struct TableCellWidth { + width: usize, + width_type: WidthType, +} + +impl TableCellWidth { + pub fn new(width: usize, width_type: WidthType) -> TableCellWidth { + TableCellWidth { width, width_type } + } +} + +impl BuildXML for TableCellWidth { + fn build(&self) -> Vec { + XMLBuilder::new() + .table_cell_width(self.width, WidthType::DXA) + .build() + } +} + +#[cfg(test)] +mod tests { + + use super::*; + #[cfg(test)] + use pretty_assertions::assert_eq; + use std::str; + + #[test] + fn test_table_width() { + let b = TableCellWidth::new(20, WidthType::DXA).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 3657ae4..5dd0b7b 100644 --- a/docx-core/src/xml_builder/elements.rs +++ b/docx-core/src/xml_builder/elements.rs @@ -98,6 +98,7 @@ impl XMLBuilder { opened_el!(open_table_row_property, "w:trPr"); opened_el!(open_table_cell, "w:tc"); opened_el!(open_table_cell_property, "w:tcPr"); + opened_el!(open_table_cell_borders, "w:tcBorders"); opened_el!(open_table_borders, "w:tblBorders"); opened_el!(open_table_cell_margins, "w:tblCellMar");