Read cel border (#64)

* feat: Read cell border

* feat: update snaps
main
bokuweb 2020-04-27 12:06:19 +09:00 committed by GitHub
parent 5c6d95aaf7
commit e9224f1129
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 216 additions and 12 deletions

View File

@ -73,6 +73,11 @@ impl TableCell {
self
}
pub fn set_borders(mut self, borders: TableCellBorders) -> Self {
self.property = self.property.set_borders(borders);
self
}
pub fn clear_border(mut self, position: BorderPosition) -> Self {
self.property = self.property.clear_border(position);
self

View File

@ -109,6 +109,17 @@ impl TableCellBorders {
Default::default()
}
pub fn with_empty() -> TableCellBorders {
TableCellBorders {
top: None,
left: None,
bottom: None,
right: None,
inside_h: None,
inside_v: None,
}
}
pub fn set(mut self, border: TableCellBorder) -> Self {
match border.position {
BorderPosition::Top => self.top = Some(border),

View File

@ -40,6 +40,11 @@ impl TableCellProperty {
self
}
pub fn set_borders(mut self, borders: TableCellBorders) -> Self {
self.borders = Some(borders);
self
}
pub fn set_border(mut self, border: TableCellBorder) -> Self {
self.borders = Some(self.borders.unwrap_or_default().set(border));
self

View File

@ -0,0 +1,40 @@
use std::str::FromStr;
use xml::attribute::OwnedAttribute;
use crate::types::*;
use super::super::errors::*;
pub struct BorderAttrs {
pub border_type: BorderType,
pub color: String,
pub size: Option<u32>,
pub space: Option<u32>,
}
pub fn read_border(attrs: &[OwnedAttribute]) -> Result<BorderAttrs, ReaderError> {
let mut border_type = BorderType::Single;
let mut color = "000000".to_owned();
let mut size: Option<u32> = None;
let mut space: Option<u32> = None;
for a in attrs {
let local_name = &a.name.local_name;
if local_name == "color" {
color = a.value.to_owned();
} else if local_name == "sz" {
size = Some(u32::from_str(&a.value)?);
} else if local_name == "space" {
space = Some(u32::from_str(&a.value)?);
} else if local_name == "val" {
border_type = BorderType::from_str(&a.value)?;
}
}
Ok(BorderAttrs {
border_type,
color,
size,
space,
})
}

View File

@ -2,8 +2,10 @@ mod bool_value;
mod indent;
mod indent_level;
mod width;
mod border;
pub use bool_value::*;
pub use indent::*;
pub use border::*;
pub use indent_level::*;
pub use width::*;

View File

@ -20,6 +20,7 @@ mod style;
mod styles;
mod table;
mod table_cell;
mod table_cell_borders;
mod table_row;
mod text_box_content;
mod wp_anchor;

View File

@ -67,7 +67,8 @@ impl ElementReader for TableCell {
}
}
XMLElement::TableCellBorders => {
// TODO: Support table cell borders later
let borders = TableCellBorders::read(r, &attributes)?;
cell = cell.set_borders(borders);
}
_ => {}
}
@ -115,9 +116,11 @@ mod tests {
<w:gridSpan w:val="2"/>
<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:left w:val="single" w:sz="3" w:space="0" w:color="000000"/>
<w:right w:val="single" w:sz="2" w:space="0" w:color="000000"/>
<w:bottom w:val="double" w:sz="4" w:space="0" w:color="000000"/>
<w:insideH w:val="single" w:sz="5" w:space="0" w:color="FF0000"/>
<w:insideV w:val="single" w:sz="2" w:space="0" w:color="000000"/>
</w:tcBorders>
<w:shd w:fill="auto" w:val="clear"/>
</w:tcPr>
@ -136,7 +139,19 @@ mod tests {
.add_paragraph(Paragraph::new().add_run(Run::new()))
.width(6425, WidthType::DXA)
.grid_span(2)
.vertical_merge(VMergeType::Restart),
.vertical_merge(VMergeType::Restart)
.set_border(TableCellBorder::new(BorderPosition::Top))
.set_border(TableCellBorder::new(BorderPosition::Left).size(3))
.set_border(
TableCellBorder::new(BorderPosition::Bottom)
.size(4)
.border_type(BorderType::Double)
)
.set_border(
TableCellBorder::new(BorderPosition::InsideH)
.size(5)
.color("FF0000".to_owned())
)
);
}

View File

@ -0,0 +1,101 @@
use std::io::Read;
use std::str::FromStr;
use xml::attribute::OwnedAttribute;
use xml::reader::{EventReader, XmlEvent};
use super::*;
use crate::types::*;
impl ElementReader for TableCellBorders {
fn read<R: Read>(r: &mut EventReader<R>, _: &[OwnedAttribute]) -> Result<Self, ReaderError> {
let mut borders = TableCellBorders::with_empty();
loop {
let e = r.next();
match e {
Ok(XmlEvent::StartElement {
attributes, name, ..
}) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
match e {
XMLElement::Top => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::Top)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
XMLElement::Right => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::Right)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
XMLElement::Bottom => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::Bottom)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
XMLElement::Left => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::Left)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
XMLElement::InsideH => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::InsideH)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
XMLElement::InsideV => {
let attr = read_border(&attributes)?;
let mut border = TableCellBorder::new(BorderPosition::InsideV)
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
borders = borders.set(border);
continue;
}
_ => {}
}
}
Ok(XmlEvent::EndElement { name, .. }) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if e == XMLElement::TableCellBorders {
return Ok(borders);
}
}
Err(_) => return Err(ReaderError::XMLReadError),
_ => {}
}
}
}
}

View File

@ -54,9 +54,11 @@ pub enum XMLElement {
TableIndent,
TableBorders,
Top,
Right,
Left,
Bottom,
InsideH,
InsideV,
TableCellMargin,
TableGrid,
GridCol,
@ -190,9 +192,11 @@ impl FromStr for XMLElement {
"tblInd" => Ok(XMLElement::TableIndent),
"tblBorders" => Ok(XMLElement::TableBorders),
"top" => Ok(XMLElement::Top),
"right" => Ok(XMLElement::Right),
"left" => Ok(XMLElement::Left),
"bottom" => Ok(XMLElement::Bottom),
"insideH" => Ok(XMLElement::InsideH),
"insideV" => Ok(XMLElement::InsideV),
"tblCellMar" => Ok(XMLElement::TableCellMargin),
"tblGrid" => Ok(XMLElement::TableGrid),
"gridCol" => Ok(XMLElement::GridCol),

View File

@ -5,6 +5,9 @@ use serde::Serialize;
use std::fmt;
use wasm_bindgen::prelude::*;
use super::errors;
use std::str::FromStr;
#[wasm_bindgen]
#[derive(Copy, Clone, Debug, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
@ -38,10 +41,27 @@ impl fmt::Display for BorderType {
}
}
impl FromStr for BorderType {
type Err = errors::TypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"nil" => Ok(BorderType::Nil),
"none" => Ok(BorderType::None),
"single" => Ok(BorderType::Single),
"thick" => Ok(BorderType::Thick),
"double" => Ok(BorderType::Double),
"dotted" => Ok(BorderType::Dotted),
"dashed" => Ok(BorderType::Dashed),
"dotDash" => Ok(BorderType::DotDash),
"dotDotDash" => Ok(BorderType::DotDotDash),
"triple" => Ok(BorderType::Triple),
_ => Ok(BorderType::Single),
}
}
}
/*
Unsupported types
"nil"
"none"
Unsupported types
"thinThickSmallGap"
"thickThinSmallGap"
"thinThickThinSmallGap"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long