feat: Add cell borders

main
bokuweb 2019-11-12 18:20:50 +09:00
parent 5378c07a35
commit e387c29edf
5 changed files with 257 additions and 0 deletions

View File

@ -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::*;

View File

@ -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>"#
);
}
}

View File

@ -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>"#
);
}
}

View File

@ -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" />"#
);
}
}

View File

@ -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");