feat: support hRule (#234)

* feat: support hRule

* 0.0.141

* 0.0.143

* fix
main
bokuweb 2021-03-02 12:31:46 +09:00 committed by GitHub
parent ef3f2cbb3e
commit 23039556ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 140 additions and 15 deletions

View File

@ -49,7 +49,7 @@ pub fn hello() -> Result<(), DocxError> {
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
// // Note that a dynamic `import` statement here is required due to webpack/webpack#6615, // // Note that a dynamic `import` statement here is required due to webpack/webpack#6615,
import("docx-wasm").then(w => { import("docx-wasm").then((w) => {
const { buffer } = new w.Docx() const { buffer } = new w.Docx()
.addParagraph( .addParagraph(
new w.Paragraph().addRun(new w.Run().addText("Hello world!!")) new w.Paragraph().addRun(new w.Run().addText("Hello world!!"))
@ -100,7 +100,7 @@ writeFileSync("hello.docx", buffer);
- [x] vanish - [x] vanish
- [x] Italic - [x] Italic
- [x] Break - [x] Break
- [ ] Header - [x] Header
- [ ] Footer - [ ] Footer
- [x] Comment - [x] Comment
- [x] Image - [x] Image

View File

@ -1,8 +1,8 @@
use serde::Serialize; use serde::Serialize;
use super::{TableCell, TableRowProperty}; use super::{TableCell, TableRowProperty};
use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
use crate::{documents::BuildXML, HeightRule};
#[derive(Debug, Clone, PartialEq, Serialize)] #[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -37,6 +37,11 @@ impl TableRow {
self.property = self.property.row_height(h); self.property = self.property.row_height(h);
self self
} }
pub fn height_rule(mut self, r: HeightRule) -> TableRow {
self.property = self.property.height_rule(r);
self
}
} }
impl BuildXML for TableRow { impl BuildXML for TableRow {
@ -71,7 +76,7 @@ mod tests {
let r = TableRow::new(vec![TableCell::new()]); let r = TableRow::new(vec![TableCell::new()]);
assert_eq!( assert_eq!(
serde_json::to_string(&r).unwrap(), serde_json::to_string(&r).unwrap(),
r#"{"cells":[{"children":[],"property":{"width":null,"borders":null,"gridSpan":null,"verticalMerge":null,"verticalAlign":null},"hasNumbering":false}],"hasNumbering":false,"property":{"gridAfter":null,"widthAfter":null,"rowHeight":null}}"# r#"{"cells":[{"children":[],"property":{"width":null,"borders":null,"gridSpan":null,"verticalMerge":null,"verticalAlign":null},"hasNumbering":false}],"hasNumbering":false,"property":{"gridAfter":null,"widthAfter":null,"rowHeight":null,"heightRule":null}}"#
); );
} }
} }

View File

@ -1,7 +1,7 @@
use serde::Serialize; use serde::Serialize;
use crate::documents::BuildXML;
use crate::xml_builder::*; use crate::xml_builder::*;
use crate::{documents::BuildXML, HeightRule};
#[derive(Debug, Clone, PartialEq, Serialize)] #[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -9,6 +9,7 @@ pub struct TableRowProperty {
grid_after: Option<u32>, grid_after: Option<u32>,
width_after: Option<f32>, width_after: Option<f32>,
row_height: Option<f32>, row_height: Option<f32>,
height_rule: Option<HeightRule>,
} }
impl TableRowProperty { impl TableRowProperty {
@ -30,6 +31,11 @@ impl TableRowProperty {
self.row_height = Some(h); self.row_height = Some(h);
self self
} }
pub fn height_rule(mut self, r: HeightRule) -> Self {
self.height_rule = Some(r);
self
}
} }
impl Default for TableRowProperty { impl Default for TableRowProperty {
@ -38,6 +44,7 @@ impl Default for TableRowProperty {
grid_after: None, grid_after: None,
width_after: None, width_after: None,
row_height: None, row_height: None,
height_rule: None,
} }
} }
} }
@ -46,7 +53,10 @@ impl BuildXML for TableRowProperty {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new().open_table_row_property(); let mut b = XMLBuilder::new().open_table_row_property();
if let Some(h) = self.row_height { if let Some(h) = self.row_height {
b = b.table_row_height(&format!("{}", h), "auto") b = b.table_row_height(
&format!("{}", h),
&self.height_rule.unwrap_or_default().to_string(),
)
} }
b.close().build() b.close().build()
} }

View File

@ -4,6 +4,8 @@ use std::str::FromStr;
use xml::attribute::OwnedAttribute; use xml::attribute::OwnedAttribute;
use xml::reader::{EventReader, XmlEvent}; use xml::reader::{EventReader, XmlEvent};
use crate::HeightRule;
use super::attributes::*; use super::attributes::*;
use super::*; use super::*;
@ -13,6 +15,7 @@ impl ElementReader for TableRow {
let mut grid_after = None; let mut grid_after = None;
let mut width_after = None; let mut width_after = None;
let mut row_height = None; let mut row_height = None;
let mut height_rule = Some(HeightRule::Exact);
loop { loop {
let e = r.next(); let e = r.next();
match e { match e {
@ -38,6 +41,13 @@ impl ElementReader for TableRow {
width_after = Some(v.0 as f32); width_after = Some(v.0 as f32);
} }
} }
XMLElement::HeightRule => {
if let Some(v) = read_val(&attributes) {
if let Ok(r) = HeightRule::from_str(&v) {
height_rule = Some(r);
}
}
}
XMLElement::TableRowHeight => { XMLElement::TableRowHeight => {
if let Some(v) = read_val(&attributes) { if let Some(v) = read_val(&attributes) {
let h = f32::from_str(&v); let h = f32::from_str(&v);
@ -64,6 +74,11 @@ impl ElementReader for TableRow {
if let Some(width_after) = width_after { if let Some(width_after) = width_after {
row = row.width_after(width_after); row = row.width_after(width_after);
} }
if let Some(height_rule) = height_rule {
row = row.height_rule(height_rule);
}
return Ok(row); return Ok(row);
} }
} }

View File

@ -54,6 +54,7 @@ pub enum XMLElement {
TableProperty, TableProperty,
TableRow, TableRow,
TableRowHeight, TableRowHeight,
HeightRule,
TableCell, TableCell,
TableCellProperty, TableCellProperty,
TableCellWidth, TableCellWidth,
@ -215,6 +216,7 @@ impl FromStr for XMLElement {
"tblPr" => Ok(XMLElement::TableProperty), "tblPr" => Ok(XMLElement::TableProperty),
"tr" => Ok(XMLElement::TableRow), "tr" => Ok(XMLElement::TableRow),
"trHeight" => Ok(XMLElement::TableRowHeight), "trHeight" => Ok(XMLElement::TableRowHeight),
"hRule" => Ok(XMLElement::HeightRule),
"tc" => Ok(XMLElement::TableCell), "tc" => Ok(XMLElement::TableCell),
"tcPr" => Ok(XMLElement::TableCellProperty), "tcPr" => Ok(XMLElement::TableCellProperty),
"tcW" => Ok(XMLElement::TableCellWidth), "tcW" => Ok(XMLElement::TableCellWidth),

View File

@ -0,0 +1,44 @@
use std::fmt;
use wasm_bindgen::prelude::*;
use serde::Serialize;
use super::errors;
use std::str::FromStr;
#[wasm_bindgen]
#[derive(Debug, Clone, Copy, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum HeightRule {
Auto,
AtLeast,
Exact,
}
impl Default for HeightRule {
fn default() -> Self {
Self::Exact
}
}
impl fmt::Display for HeightRule {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
HeightRule::Auto => write!(f, "auto"),
HeightRule::AtLeast => write!(f, "atLeast"),
HeightRule::Exact => write!(f, "exact"),
}
}
}
impl FromStr for HeightRule {
type Err = errors::TypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"auto" => Ok(HeightRule::Auto),
"atLeast" => Ok(HeightRule::AtLeast),
"exact" => Ok(HeightRule::Exact),
_ => Ok(HeightRule::Exact),
}
}
}

View File

@ -15,6 +15,7 @@ pub mod table_alignment_type;
pub mod vertical_align_type; pub mod vertical_align_type;
pub mod vertical_merge_type; pub mod vertical_merge_type;
pub mod width_type; pub mod width_type;
pub mod height_rule;
pub use alignment_type::*; pub use alignment_type::*;
pub use border_position::*; pub use border_position::*;
@ -33,3 +34,4 @@ pub use table_alignment_type::*;
pub use vertical_align_type::*; pub use vertical_align_type::*;
pub use vertical_merge_type::*; pub use vertical_merge_type::*;
pub use width_type::*; pub use width_type::*;
pub use height_rule::*;

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

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

View File

@ -386,9 +386,27 @@ export class Docx {
const cell = this.buildCell(c); const cell = this.buildCell(c);
row = row.add_cell(cell); row = row.add_cell(cell);
}); });
if (r.height) { if (r.height) {
row = row.row_height(r.height); row = row.row_height(r.height);
} }
if (r.hRule) {
switch (r.hRule) {
case "auto": {
row = row.height_rule(wasm.HeightRule.Auto);
break;
}
case "atLeast": {
row = row.height_rule(wasm.HeightRule.AtLeast);
break;
}
case "exact": {
row = row.height_rule(wasm.HeightRule.Exact);
break;
}
}
}
table = table.add_row(row); table = table.add_row(row);
}); });
table = table.set_grid(new Uint32Array(t.grid)); table = table.set_grid(new Uint32Array(t.grid));

View File

@ -1,10 +1,13 @@
import { ParagraphJSON } from "./paragraph"; import { ParagraphJSON } from "./paragraph";
import { BorderJSON } from "./border"; import { BorderJSON } from "./border";
import { HeightRule } from "../table-row";
export type TableCellChildJSON = ParagraphJSON; export type TableCellChildJSON = ParagraphJSON;
export type WidthType = "DXA" | "Auto" | "Pct"; export type WidthType = "DXA" | "Auto" | "Pct";
export { HeightRule } from "../table-row";
export type TableCellPropertyJSON = { export type TableCellPropertyJSON = {
width: { width: {
width: number; width: number;
@ -20,6 +23,7 @@ export type TableCellPropertyJSON = {
export type TableRowPropertyJSON = { export type TableRowPropertyJSON = {
gridAfter: number | null; gridAfter: number | null;
rowHeight: number | null; rowHeight: number | null;
heightRule: HeightRule | null;
widthAfter: number | null; widthAfter: number | null;
}; };

View File

@ -1,9 +1,12 @@
import { TableCell } from "./table-cell"; import { TableCell } from "./table-cell";
export type HeightRule = "auto" | "atLeast" | "exact";
export class TableRow { export class TableRow {
cells: TableCell[] = []; cells: TableCell[] = [];
hasNumberings = false; hasNumberings = false;
height: number | null = null; height: number | null = null;
hRule: HeightRule = "exact";
addCell(cell: TableCell) { addCell(cell: TableCell) {
if (cell.hasNumberings) { if (cell.hasNumberings) {
@ -17,4 +20,9 @@ export class TableRow {
this.height = h; this.height = h;
return this; return this;
} }
heightRule(r: HeightRule) {
this.hRule = r;
return this;
}
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "docx-wasm", "name": "docx-wasm",
"version": "0.0.140", "version": "0.0.143",
"main": "dist/node/index.js", "main": "dist/node/index.js",
"browser": "dist/web/index.js", "browser": "dist/web/index.js",
"author": "bokuweb <bokuweb12@gmail.com>", "author": "bokuweb <bokuweb12@gmail.com>",

View File

@ -27,4 +27,9 @@ impl TableRow {
self.0 = self.0.row_height(h as f32); self.0 = self.0.row_height(h as f32);
self self
} }
pub fn height_rule(mut self, r: docx_rs::HeightRule) -> TableRow {
self.0 = self.0.height_rule(r);
self
}
} }

View File

@ -1015,6 +1015,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": null, "gridAfter": null,
"heightRule": "exact",
"rowHeight": 970, "rowHeight": 970,
"widthAfter": null, "widthAfter": null,
}, },
@ -1175,6 +1176,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 1, "gridAfter": 1,
"heightRule": "exact",
"rowHeight": 55, "rowHeight": 55,
"widthAfter": 1065, "widthAfter": 1065,
}, },
@ -1335,6 +1337,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 1, "gridAfter": 1,
"heightRule": "exact",
"rowHeight": 675, "rowHeight": 675,
"widthAfter": 1065, "widthAfter": 1065,
}, },
@ -1495,6 +1498,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -1655,6 +1659,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -1890,6 +1895,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -2125,6 +2131,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -2348,6 +2355,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -2583,6 +2591,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": 2, "gridAfter": 2,
"heightRule": "exact",
"rowHeight": 397, "rowHeight": 397,
"widthAfter": 3717, "widthAfter": 3717,
}, },
@ -9311,6 +9320,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": null, "gridAfter": null,
"heightRule": "exact",
"rowHeight": null, "rowHeight": null,
"widthAfter": null, "widthAfter": null,
}, },
@ -9497,6 +9507,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": null, "gridAfter": null,
"heightRule": "exact",
"rowHeight": null, "rowHeight": null,
"widthAfter": null, "widthAfter": null,
}, },
@ -9683,6 +9694,7 @@ Object {
"hasNumbering": false, "hasNumbering": false,
"property": Object { "property": Object {
"gridAfter": null, "gridAfter": null,
"heightRule": "exact",
"rowHeight": null, "rowHeight": null,
"widthAfter": null, "widthAfter": null,
}, },