Support text border (#257)

* feat: Add text_border

* feat: Add reader

* feat: Add js if and test

* 0.0.171

* update test
main
bokuweb 2021-03-21 00:16:43 +09:00 committed by GitHub
parent ba0ef0bd48
commit 6f6a399597
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 516 additions and 77 deletions

View File

@ -99,6 +99,7 @@ writeFileSync("hello.docx", buffer);
- [x] Underline - [x] Underline
- [x] vanish - [x] vanish
- [x] Italic - [x] Italic
- [x] TextBorder
- [x] Break - [x] Break
- [x] Header - [x] Header
- [ ] Footer - [ ] Footer

View File

@ -59,7 +59,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
serde_json::to_string(&graphic).unwrap(), serde_json::to_string(&graphic).unwrap(),
r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"# r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#
); );
} }
} }

View File

@ -90,7 +90,7 @@ mod tests {
.num_style_link("style1"); .num_style_link("style1");
assert_eq!( assert_eq!(
serde_json::to_string(&c).unwrap(), serde_json::to_string(&c).unwrap(),
r#"{"id":0,"styleLink":null,"numStyleLink":"style1","levels":[{"level":1,"start":1,"format":"decimal","text":"%4.","jc":"left","pstyle":null,"paragraphProperty":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"suffix":"tab"}]}"# r#"{"id":0,"styleLink":null,"numStyleLink":"style1","levels":[{"level":1,"start":1,"format":"decimal","text":"%4.","jc":"left","pstyle":null,"paragraphProperty":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"suffix":"tab"}]}"#
); );
} }
} }

View File

@ -76,6 +76,7 @@ mod table_row_property;
mod table_style; mod table_style;
mod table_width; mod table_width;
mod text; mod text;
mod text_border;
mod text_box_content; mod text_box_content;
mod text_direction; mod text_direction;
mod underline; mod underline;
@ -165,6 +166,7 @@ pub use table_row_property::*;
pub use table_style::*; pub use table_style::*;
pub use table_width::*; pub use table_width::*;
pub use text::*; pub use text::*;
pub use text_border::*;
pub use text_box_content::*; pub use text_box_content::*;
pub use text_direction::*; pub use text_direction::*;
pub use underline::*; pub use underline::*;

View File

@ -295,7 +295,7 @@ mod tests {
let p = Paragraph::new().add_run(run); let p = Paragraph::new().add_run(run);
assert_eq!( assert_eq!(
serde_json::to_string(&p).unwrap(), serde_json::to_string(&p).unwrap(),
r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}"# r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}"#
); );
} }
@ -306,7 +306,7 @@ mod tests {
let p = Paragraph::new().add_insert(ins); let p = Paragraph::new().add_insert(ins);
assert_eq!( assert_eq!(
serde_json::to_string(&p).unwrap(), serde_json::to_string(&p).unwrap(),
r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}"# r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}"#
); );
} }
} }

View File

@ -132,7 +132,7 @@ mod tests {
let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None); let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None);
assert_eq!( assert_eq!(
serde_json::to_string(&b).unwrap(), serde_json::to_string(&b).unwrap(),
r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10}},"lineHeight":null}"# r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10}},"lineHeight":null}"#
); );
} }
} }

View File

@ -269,11 +269,12 @@ mod tests {
vanish: Some(Vanish::new()), vanish: Some(Vanish::new()),
spacing: Some(100), spacing: Some(100),
fonts: None, fonts: None,
text_border: None,
}, },
}; };
assert_eq!( assert_eq!(
serde_json::to_string(&run).unwrap(), serde_json::to_string(&run).unwrap(),
r#"{"runProperty":{"sz":30,"szCs":30,"color":"C9211E","highlight":"yellow","underline":"single","bold":true,"boldCs":true,"italic":true,"italicCs":true,"vanish":true,"spacing":100,"fonts":null},"children":[{"type":"tab"},{"type":"text","data":{"preserveSpace":true,"text":"Hello"}},{"type":"break","data":{"breakType":"page"}},{"type":"deleteText","data":{"text":"deleted","preserveSpace":true}}]}"# r#"{"runProperty":{"sz":30,"szCs":30,"color":"C9211E","highlight":"yellow","underline":"single","bold":true,"boldCs":true,"italic":true,"italicCs":true,"vanish":true,"spacing":100,"fonts":null,"textBorder":null},"children":[{"type":"tab"},{"type":"text","data":{"preserveSpace":true,"text":"Hello"}},{"type":"break","data":{"breakType":"page"}},{"type":"deleteText","data":{"text":"deleted","preserveSpace":true}}]}"#
); );
} }
} }

View File

@ -19,6 +19,7 @@ pub struct RunProperty {
pub vanish: Option<Vanish>, pub vanish: Option<Vanish>,
pub spacing: Option<i32>, pub spacing: Option<i32>,
pub fonts: Option<RunFonts>, pub fonts: Option<RunFonts>,
pub text_border: Option<TextBorder>,
} }
impl RunProperty { impl RunProperty {
@ -85,6 +86,11 @@ impl RunProperty {
self.fonts = Some(font); self.fonts = Some(font);
self self
} }
pub fn text_border(mut self, b: TextBorder) -> Self {
self.text_border = Some(b);
self
}
} }
impl Default for RunProperty { impl Default for RunProperty {
@ -102,6 +108,7 @@ impl Default for RunProperty {
vanish: None, vanish: None,
fonts: None, fonts: None,
spacing: None, spacing: None,
text_border: None,
} }
} }
} }
@ -126,6 +133,7 @@ impl BuildXML for RunProperty {
.add_optional_child(&self.underline) .add_optional_child(&self.underline)
.add_optional_child(&self.vanish) .add_optional_child(&self.vanish)
.add_optional_child(&self.fonts) .add_optional_child(&self.fonts)
.add_optional_child(&self.text_border)
.add_optional_child(&spacing) .add_optional_child(&spacing)
.close() .close()
.build() .build()

View File

@ -185,7 +185,7 @@ mod tests {
.grid_span(2); .grid_span(2);
assert_eq!( assert_eq!(
serde_json::to_string(&c).unwrap(), serde_json::to_string(&c).unwrap(),
r#"{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null,"textDirection":null,"shading":null},"hasNumbering":false}"# r#"{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"spacing":null,"fonts":null,"textBorder":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineHeight":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null,"textDirection":null,"shading":null},"hasNumbering":false}"#
); );
} }
} }

View File

@ -0,0 +1,59 @@
use serde::{Deserialize, Serialize};
use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TextBorder {
pub border_type: BorderType,
pub size: usize,
pub color: String,
pub space: usize,
}
impl TextBorder {
pub fn new() -> Self {
TextBorder::default()
}
pub fn color(mut self, color: impl Into<String>) -> Self {
self.color = color.into();
self
}
pub fn size(mut self, size: usize) -> Self {
self.size = size;
self
}
pub fn space(mut self, space: usize) -> Self {
self.space = space;
self
}
pub fn border_type(mut self, border_type: BorderType) -> Self {
self.border_type = border_type;
self
}
}
impl Default for TextBorder {
fn default() -> Self {
TextBorder {
border_type: BorderType::Single,
size: 4,
space: 0,
color: "auto".to_owned(),
}
}
}
impl BuildXML for TextBorder {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.text_border(self.border_type, self.size, self.space, &self.color)
.build()
}
}

View File

@ -45,6 +45,18 @@ impl ElementReader for RunProperty {
rp = rp.italic(); rp = rp.italic();
} }
XMLElement::Vanish => rp = rp.vanish(), XMLElement::Vanish => rp = rp.vanish(),
XMLElement::TextBorder => {
if let Ok(attr) = read_border(&attributes) {
let mut border = TextBorder::new()
.border_type(attr.border_type)
.color(attr.color);
if let Some(size) = attr.size {
border = border.size(size as usize);
};
rp = rp.text_border(border);
continue;
}
}
_ => {} _ => {}
} }
} }

View File

@ -19,6 +19,7 @@ pub enum XMLElement {
SizeCs, SizeCs,
Spacing, Spacing,
Vanish, Vanish,
TextBorder,
Italic, Italic,
ItalicCs, ItalicCs,
Text, Text,
@ -254,6 +255,7 @@ impl FromStr for XMLElement {
"gridCol" => Ok(XMLElement::GridCol), "gridCol" => Ok(XMLElement::GridCol),
"style" => Ok(XMLElement::Style), "style" => Ok(XMLElement::Style),
"basedOn" => Ok(XMLElement::BasedOn), "basedOn" => Ok(XMLElement::BasedOn),
"bdr" => Ok(XMLElement::TextBorder),
"next" => Ok(XMLElement::Next), "next" => Ok(XMLElement::Next),
"vertAlign" => Ok(XMLElement::VertAlign), "vertAlign" => Ok(XMLElement::VertAlign),
"spacing" => Ok(XMLElement::Spacing), "spacing" => Ok(XMLElement::Spacing),

View File

@ -1,7 +1,7 @@
// //
// Please see p3813 <xsd:simpleType name="ST_Border"> // Please see p3813 <xsd:simpleType name="ST_Border">
// //
use serde::Serialize; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
@ -9,7 +9,7 @@ use super::errors;
use std::str::FromStr; use std::str::FromStr;
#[wasm_bindgen] #[wasm_bindgen]
#[derive(Copy, Clone, Debug, PartialEq, Serialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub enum BorderType { pub enum BorderType {
Nil, Nil,

View File

@ -210,6 +210,8 @@ impl XMLBuilder {
closed_border_el!(border_tl2br, "w:tl2br"); closed_border_el!(border_tl2br, "w:tl2br");
closed_border_el!(border_tr2bl, "w:tr2bl"); closed_border_el!(border_tr2bl, "w:tr2bl");
closed_border_el!(text_border, "w:bdr");
closed!(shd, "w:shd", "w:val", "w:color", "w:fill"); closed!(shd, "w:shd", "w:val", "w:color", "w:fill");
closed!(tab, "w:tab"); closed!(tab, "w:tab");

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

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

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

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,32 @@
export type BorderType =
| "nil"
| "none"
| "single"
| "thick"
| "double"
| "dotted"
| "dashed"
| "dotDash"
| "dotDotDash"
| "triple"
| "thinThickSmallGap"
| "thickThinSmallGap"
| "thinThickThinSmallGap"
| "thinThickMediumGap"
| "thickThinMediumGap"
| "thinThickThinMediumGap"
| "thinThickLargeGap"
| "thickThinLargeGap"
| "thinThickThinLargeGap"
| "wave"
| "doubleWave"
| "dashSmallGap"
| "dashDotStroked"
| "threeDEmboss"
| "threeDEngrave"
| "outset"
| "inset"
| "apples"
| "archedScallops"
| "babyPacifier"
| "babyRattle";

View File

@ -4,7 +4,7 @@ import { Delete } from "./delete";
import { DeleteText } from "./delete-text"; import { DeleteText } from "./delete-text";
import { Table } from "./table"; import { Table } from "./table";
import { TableCell, toTextDirectionWasmType } from "./table-cell"; import { TableCell, toTextDirectionWasmType } from "./table-cell";
import { BorderType } from "./table-cell-border"; import { BorderType } from "./border";
import { Run, RunFonts } from "./run"; import { Run, RunFonts } from "./run";
import { Text } from "./text"; import { Text } from "./text";
import { Tab } from "./tab"; import { Tab } from "./tab";
@ -216,6 +216,11 @@ export class Docx {
run = run.spacing(r.property.spacing); run = run.spacing(r.property.spacing);
} }
if (r.property.textBorder) {
const { borderType, color, space, size } = r.property.textBorder;
run = run.text_border(convertBorderType(borderType), size, space, color);
}
const fonts = this.buildRunFonts(r.property.fonts); const fonts = this.buildRunFonts(r.property.fonts);
run = run.fonts(fonts); run = run.fonts(fonts);
@ -794,6 +799,7 @@ export const readDocx = (buf: Uint8Array) => {
export * from "./paragraph"; export * from "./paragraph";
export * from "./insert"; export * from "./insert";
export * from "./delete"; export * from "./delete";
export * from "./border";
export * from "./table"; export * from "./table";
export * from "./table-cell"; export * from "./table-cell";
export * from "./table-cell-border"; export * from "./table-cell-border";

View File

@ -1,6 +1,13 @@
import { DrawingJSON } from "./drawing"; import { DrawingJSON } from "./drawing";
import { CommentRangeStartJSON, CommentRangeEndJSON } from ".."; import { CommentRangeStartJSON, CommentRangeEndJSON } from "..";
export type TextBorderJSON = {
borderType: string;
size: number;
space: number;
color: string;
};
export type RunPropertyJSON = { export type RunPropertyJSON = {
sz: number | null; sz: number | null;
szCs: number | null; szCs: number | null;
@ -13,6 +20,7 @@ export type RunPropertyJSON = {
italicCs: boolean | null; italicCs: boolean | null;
vanish: boolean | null; vanish: boolean | null;
spacing: number | null; spacing: number | null;
TextBorder: TextBorderJSON | null;
}; };
export type RunChildJSON = export type RunChildJSON =

View File

@ -2,9 +2,17 @@ import { Text } from "./text";
import { DeleteText } from "./delete-text"; import { DeleteText } from "./delete-text";
import { Tab } from "./tab"; import { Tab } from "./tab";
import { Break, BreakType } from "./break"; import { Break, BreakType } from "./break";
import { BorderType } from "./border";
export type RunChild = Text | DeleteText | Tab | Break; export type RunChild = Text | DeleteText | Tab | Break;
export type TextBorder = {
borderType: BorderType;
color: string;
space: number;
size: number;
};
export type RunProperty = { export type RunProperty = {
size?: number; size?: number;
color?: string; color?: string;
@ -15,6 +23,7 @@ export type RunProperty = {
vanish?: boolean; vanish?: boolean;
fonts?: RunFonts; fonts?: RunFonts;
spacing?: number; spacing?: number;
textBorder?: TextBorder;
}; };
export class RunFonts { export class RunFonts {
@ -112,4 +121,17 @@ export class Run {
this.property = { ...this.property, spacing }; this.property = { ...this.property, spacing };
return this; return this;
} }
textBorder(type: BorderType, size: number, space: number, color: string) {
this.property = {
...this.property,
textBorder: {
borderType: type,
size,
space,
color,
},
};
return this;
}
} }

View File

@ -1,35 +1,4 @@
export type BorderType = import { BorderType } from "./border";
| "nil"
| "none"
| "single"
| "thick"
| "double"
| "dotted"
| "dashed"
| "dotDash"
| "dotDotDash"
| "triple"
| "thinThickSmallGap"
| "thickThinSmallGap"
| "thinThickThinSmallGap"
| "thinThickMediumGap"
| "thickThinMediumGap"
| "thinThickThinMediumGap"
| "thinThickLargeGap"
| "thickThinLargeGap"
| "thinThickThinLargeGap"
| "wave"
| "doubleWave"
| "dashSmallGap"
| "dashDotStroked"
| "threeDEmboss"
| "threeDEngrave"
| "outset"
| "inset"
| "apples"
| "archedScallops"
| "babyPacifier"
| "babyRattle";
export type TableCellBorderPosition = export type TableCellBorderPosition =
| "left" | "left"

View File

@ -1,6 +1,6 @@
{ {
"name": "docx-wasm", "name": "docx-wasm",
"version": "0.0.170", "version": "0.0.171",
"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

@ -1,4 +1,5 @@
use super::*; use super::*;
use docx_rs::{BorderType, TextBorder};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
#[wasm_bindgen] #[wasm_bindgen]
@ -84,6 +85,22 @@ impl Run {
self.0.run_property = self.0.run_property.spacing(spacing); self.0.run_property = self.0.run_property.spacing(spacing);
self self
} }
pub fn text_border(
mut self,
border_type: BorderType,
size: usize,
space: usize,
color: &str,
) -> Run {
let border = TextBorder::new()
.border_type(border_type)
.size(size)
.space(space)
.color(color);
self.0.run_property = self.0.run_property.text_border(border);
self
}
} }
impl Run { impl Run {

File diff suppressed because it is too large Load Diff

View File

@ -208,4 +208,18 @@ describe("writer", () => {
} }
} }
}); });
test("should write text border", () => {
const p = new w.Paragraph()
.addRun(new w.Run().addText("Hello "))
.addRun(new w.Run().addText("World!").textBorder("single", 4, 0, "auto"));
const buffer = new w.Docx().addParagraph(p).build();
writeFileSync("../output/text_border.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
}); });