Skip to content

Commit

Permalink
add cell merge (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuntara authored Sep 1, 2021
1 parent 991c3b0 commit b7d5e7e
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 27 deletions.
7 changes: 2 additions & 5 deletions src/rtf/destination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,8 @@ impl Destination {
return;
}
if let Destination::Text(text) = self {
if !in_table {
text.last_or_new_paragraph(stylesheet, para_style, in_table);
} else {
/* NOP */
}
text.last_or_new_paragraph(stylesheet, para_style, in_table);

{
let base_encoding = text.encoding;
let line = text.last_or_new_line(font, style, Some(encoding));
Expand Down
53 changes: 42 additions & 11 deletions src/rtf/docx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ impl Docx for Rtf {
}
}
}
impl std::convert::Into<docx_rs::VAlignType> for CellVerticalAlignment {
fn into(self) -> docx_rs::VAlignType {
match self {
Self::Top => VAlignType::Top,
Self::Center => VAlignType::Center,
Self::Bottom => VAlignType::Bottom,
}
}
}
impl std::convert::Into<docx_rs::BorderType> for table_border::BorderType {
fn into(self) -> docx_rs::BorderType {
match self {
Expand Down Expand Up @@ -132,6 +141,7 @@ impl Docx for Rtf {
_ => crate::rtf::Text::decode_line(encoding, &line),
};
let run_font = RunFonts::new().east_asia(font.font_name.clone());

run = run.fonts(run_font);
// println!("{} {:?} {:?}", text, encoding, font.charset);
text
Expand Down Expand Up @@ -216,7 +226,7 @@ impl Docx for Rtf {
let mut rows: Vec<docx_rs::TableRow> = vec![];
let mut border = None;
let mut grid: Vec<usize> = vec![];
let mut make_grid = true;
let mut make_grid = false;

for rtf_row in table.rows {
if rtf_row.border.is_some() {
Expand All @@ -228,6 +238,7 @@ impl Docx for Rtf {
}
let mut cells: Vec<docx_rs::TableCell> = vec![];
let cell_len = rtf_row.cells.len();

for (cell_index, rtf_cell) in rtf_row.cells.into_iter().enumerate()
{
if cell_index == cell_len - 1 && rtf_cell.is_empty() {
Expand All @@ -250,9 +261,33 @@ impl Docx for Rtf {
} else {
}

if rtf_cell.opts.vert_merge_root {
cell = cell.vertical_merge(VMergeType::Restart);
} else if rtf_cell.opts.vert_merged_cell {
cell = cell.vertical_merge(VMergeType::Continue);
} else {
}
cell = cell.vertical_align(rtf_cell.opts.vert_align.into());

for para in rtf_cell.paras {
let para_style =
para.style.as_ref().unwrap_or(&stylesheet_para);
let align = para_style
.align
.as_ref()
.or_else(|| stylesheet_para.align.as_ref());

let first_indent = para_style
.first_indent
.as_ref()
.or_else(|| stylesheet_para.first_indent.as_ref());
let special_indent = first_indent.map(|indent| {
SpecialIndentType::FirstLine(indent.clone())
});

let make_paragrah = || {
let mut p = Paragraph::new();

if let Some(align) = align {
p = p.align(align.clone().into());
}
Expand All @@ -271,15 +306,10 @@ impl Docx for Rtf {
let mut runs: VecDeque<Run> = VecDeque::new();
let process_run =
|cell: TableCell, runs: &mut VecDeque<Run>| {
if runs.len() > 0 {
if !runs.is_empty() {
let mut p = make_paragrah();
loop {
if let Some(run) = runs.pop_front() {
// println!("cell run {:?}", run);
p = p.add_run(run.clone());
} else {
break;
}
while let Some(run) = runs.pop_front() {
p = p.add_run(run.clone());
}
cell.add_paragraph(p)
} else {
Expand Down Expand Up @@ -307,7 +337,7 @@ impl Docx for Rtf {
cell = process_run(cell, &mut runs);
}
if let Some(width) = width {
cell = cell.width(width, WidthType::Auto);
cell = cell.width(width, WidthType::DXA);
if make_grid {
grid.push(Twips::from_px(width).into());
}
Expand All @@ -316,10 +346,11 @@ impl Docx for Rtf {
grid = vec![];
make_grid = false;
}
// println!("{:?}", cell);

cells.push(cell);
}
let row = docx_rs::TableRow::new(cells);

rows.push(row);
make_grid = false;
}
Expand Down
109 changes: 108 additions & 1 deletion src/rtf/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,14 @@ impl GroupState {
} else {
let last_paragraph = text.last_paragraph(false);
if let Some(table) = last_paragraph.table.as_mut() {
table.add_row();
if table.last_row().is_last {
let mut p = Paragraph::new();
p.table = Some(Table::new());
text.last_section().paras.push(Paragraph::new());
text.last_section().paras.push(p);
} else {
table.add_row();
}
} else {
last_paragraph.table = Some(Table::new());
}
Expand Down Expand Up @@ -407,6 +414,32 @@ impl GroupState {
text.set_border_width(self.border_select.clone(), border_width);
}
}
pub fn set_row_last(&mut self) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_row_last();
}
}
pub fn fit_text(&mut self, twips: i32) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.fit_text(twips);
}
}
pub fn set_cell_right(&mut self, right: Twips) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
Expand All @@ -420,6 +453,71 @@ impl GroupState {
text.set_cell_right(right);
}
}
pub fn set_cell_vert_merge_root(&mut self) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_cell_vert_merge_root();
}
}
pub fn set_cell_vert_align(&mut self, align: CellVerticalAlignment) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_cell_vert_align(align);
}
}
pub fn set_cell_vert_merged_cell(&mut self) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_cell_vert_merged_cell();
}
}
pub fn set_cell_horiz_merge_root(&mut self) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_cell_horiz_merge_root();
}
}
pub fn set_cell_horiz_merged_cell(&mut self) {
let dest_name = match self.get_destination_name() {
Some(name) => name.clone(),
None => {
warn!("Document format error: Document text found outside of any document group",);
return;
}
};
if let Some(Destination::Text(text)) = (*self.destinations).borrow_mut().get_mut(&dest_name)
{
text.set_cell_horiz_merged_cell();
}
}
pub fn set_value(&mut self, name: &str, value: Option<i32>) {
match name {
"f" => {
Expand All @@ -433,6 +531,9 @@ impl GroupState {
self.set_row();
}
"intbl" => {}
"lastrow" => {
self.set_row_last();
}
"trbrdrt" => self.border_select = BorderSelect::RowTop,
"trbrdrl" => self.border_select = BorderSelect::RowLeft,
"trbrdrb" => self.border_select = BorderSelect::RowBottom,
Expand All @@ -452,6 +553,12 @@ impl GroupState {
"brdrhair" => self.set_border_type(BorderType::Hairline),
"brdrnone" => self.set_border_type(BorderType::None),
"brdrw" => self.set_border_width(value.unwrap_or(0) as usize),
"clvmgf" => self.set_cell_vert_merge_root(),
"clvmrg" => self.set_cell_vert_merged_cell(),
"clvertalt" => self.set_cell_vert_align(CellVerticalAlignment::Top),
"clvertalc" => self.set_cell_vert_align(CellVerticalAlignment::Center),
"clvertalb" => self.set_cell_vert_align(CellVerticalAlignment::Bottom),
"fittext" => self.fit_text(value.unwrap_or(-1)),
"cellx" => {
if let Some(value) = value {
self.set_cell_right((value as usize).into())
Expand Down
18 changes: 18 additions & 0 deletions src/rtf/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,28 @@ pub use super::*;
pub struct TableCellOption {
pub border: Option<CellBorder>,
pub right: Option<Twips>,
pub vert_align: CellVerticalAlignment,
pub vert_merge_root: bool,
pub vert_merged_cell: bool,
pub horiz_merge_root: bool,
pub horiz_merged_cell: bool,
}
#[derive(Clone, Debug)]
pub enum CellVerticalAlignment {
Top,
Center,
Bottom,
}
impl TableCellOption {
pub fn new() -> Self {
Self {
border: None,
right: None,
vert_merge_root: false,
vert_merged_cell: false,
horiz_merge_root: false,
horiz_merged_cell: false,
vert_align: CellVerticalAlignment::Top,
}
}
}
Expand All @@ -36,6 +52,7 @@ pub struct TableRow {
pub border: Option<RowBorder>,
pub cell_opt_pos: usize,
pub cell_opts: Vec<TableCellOption>,
pub is_last: bool,
}
impl TableRow {
pub fn new() -> TableRow {
Expand All @@ -44,6 +61,7 @@ impl TableRow {
border: None,
cell_opt_pos: 0,
cell_opts: vec![TableCellOption::new()],
is_last: false,
}
}
pub fn add_cell(&mut self) {
Expand Down
Loading

0 comments on commit b7d5e7e

Please sign in to comment.