feat: Add cell borders
parent
5378c07a35
commit
e387c29edf
|
@ -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::*;
|
||||
|
|
|
@ -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<String>) -> TableCellBorder {
|
||||
self.color = color.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl BuildXML for TableCellBorder {
|
||||
fn build(&self) -> Vec<u8> {
|
||||
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<TableCellBorder>,
|
||||
left: Option<TableCellBorder>,
|
||||
bottom: Option<TableCellBorder>,
|
||||
right: Option<TableCellBorder>,
|
||||
inside_h: Option<TableCellBorder>,
|
||||
inside_v: Option<TableCellBorder>,
|
||||
}
|
||||
|
||||
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<u8> {
|
||||
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#"<w:tcBorders><w:top w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:left w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:bottom w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:insideH w:val="single" w:sz="2" w:space="0" w:color="000000" /></w:tcBorders>"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<u8> {
|
||||
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#"<w:tcPr><w:tcW w:w="200" w:type="dxa" /><w:tcBorders><w:top w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:left w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:bottom w:val="single" w:sz="2" w:space="0" w:color="000000" /><w:insideH w:val="single" w:sz="2" w:space="0" w:color="000000" /></w:tcBorders></w:tcPr>"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<u8> {
|
||||
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#"<w:tcW w:w="20" w:type="dxa" />"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue