Support strike (#390)

* fix: spec

* fix: spec

* fix: strike
main
bokuweb 2021-12-21 11:54:27 +09:00 committed by GitHub
parent 54c859ed76
commit a22abb3b4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1479 additions and 11002 deletions

View File

@ -59,7 +59,7 @@ mod tests {
);
assert_eq!(
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,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":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":{},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#,
);
}
}

View File

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

View File

@ -69,6 +69,7 @@ mod section;
mod section_property;
mod shading;
mod start;
mod strike;
mod structured_data_tag;
mod structured_data_tag_property;
mod style;
@ -176,6 +177,7 @@ pub use section::*;
pub use section_property::*;
pub use shading::*;
pub use start::*;
pub use strike::*;
pub use structured_data_tag::*;
pub use structured_data_tag_property::*;
pub use style::*;

View File

@ -374,7 +374,7 @@ mod tests {
let p = Paragraph::new().add_run(run);
assert_eq!(
serde_json::to_string(&p).unwrap(),
r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#,
r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#,
);
}
@ -385,7 +385,7 @@ mod tests {
let p = Paragraph::new().add_insert(ins);
assert_eq!(
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,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":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,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#
r#"{"id":"12345678","children":[{"type":"insert","data":{"children":[{"type":"run","data":{"runProperty":{},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}"#
);
}
}

View File

@ -221,7 +221,7 @@ mod tests {
let b = c.indent(Some(20), Some(SpecialIndentType::FirstLine(10)), None, None);
assert_eq!(
serde_json::to_string(&b).unwrap(),
r#"{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10},"hangingChars":null,"firstLineChars":null},"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null}"#
r#"{"runProperty":{},"style":null,"numberingProperty":null,"alignment":null,"indent":{"start":20,"startChars":null,"end":null,"specialIndent":{"type":"firstLine","val":10},"hangingChars":null,"firstLineChars":null},"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null}"#
);
}

View File

@ -313,7 +313,7 @@ mod tests {
};
assert_eq!(
serde_json::to_string(&run).unwrap(),
r#"{"runProperty":{"sz":30,"szCs":30,"color":"C9211E","highlight":"yellow","vertAlign":null,"underline":"single","bold":true,"boldCs":true,"italic":true,"italicCs":true,"vanish":true,"characterSpacing":100,"fonts":null,"textBorder":null,"del":null,"ins":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,"characterSpacing":100},"children":[{"type":"tab"},{"type":"text","data":{"preserveSpace":true,"text":"Hello"}},{"type":"break","data":{"breakType":"page"}},{"type":"deleteText","data":{"text":"deleted","preserveSpace":true}}]}"#,
);
}
}

View File

@ -8,22 +8,40 @@ use crate::xml_builder::*;
#[derive(Debug, Clone, Serialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct RunProperty {
#[serde(skip_serializing_if = "Option::is_none")]
pub sz: Option<Sz>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sz_cs: Option<SzCs>,
#[serde(skip_serializing_if = "Option::is_none")]
pub color: Option<Color>,
#[serde(skip_serializing_if = "Option::is_none")]
pub highlight: Option<Highlight>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vert_align: Option<VertAlign>,
#[serde(skip_serializing_if = "Option::is_none")]
pub underline: Option<Underline>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bold: Option<Bold>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bold_cs: Option<BoldCs>,
#[serde(skip_serializing_if = "Option::is_none")]
pub italic: Option<Italic>,
#[serde(skip_serializing_if = "Option::is_none")]
pub italic_cs: Option<ItalicCs>,
#[serde(skip_serializing_if = "Option::is_none")]
pub vanish: Option<Vanish>,
#[serde(skip_serializing_if = "Option::is_none")]
pub character_spacing: Option<CharacterSpacing>,
#[serde(skip_serializing_if = "Option::is_none")]
pub fonts: Option<RunFonts>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_border: Option<TextBorder>,
#[serde(skip_serializing_if = "Option::is_none")]
pub del: Option<Delete>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ins: Option<Insert>,
#[serde(skip_serializing_if = "Option::is_none")]
pub strike: Option<Strike>,
}
impl RunProperty {
@ -75,6 +93,11 @@ impl RunProperty {
self
}
pub fn strike(mut self) -> RunProperty {
self.strike = Some(Strike::new());
self
}
pub fn disable_italic(mut self) -> RunProperty {
self.italic = Some(Italic::new().disable());
self.italic_cs = Some(ItalicCs::new().disable());
@ -131,6 +154,7 @@ impl Default for RunProperty {
text_border: None,
del: None,
ins: None,
strike: None,
}
}
}
@ -146,6 +170,7 @@ impl BuildXML for RunProperty {
.add_optional_child(&self.bold_cs)
.add_optional_child(&self.italic)
.add_optional_child(&self.italic_cs)
.add_optional_child(&self.strike)
.add_optional_child(&self.highlight)
.add_optional_child(&self.underline)
.add_optional_child(&self.vanish)
@ -198,6 +223,16 @@ mod tests {
);
}
#[test]
fn test_strike() {
let c = RunProperty::new().strike();
let b = c.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:rPr><w:strike /></w:rPr>"#
);
}
#[test]
fn test_underline() {
let c = RunProperty::new().underline("single");

View File

@ -0,0 +1,42 @@
use serde::{Deserialize, Serialize, Serializer};
use crate::documents::BuildXML;
use crate::xml_builder::*;
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct Strike {
pub val: bool,
}
impl Strike {
pub fn new() -> Strike {
Default::default()
}
pub fn disable(mut self) -> Strike {
self.val = false;
self
}
}
impl Default for Strike {
fn default() -> Self {
Self { val: true }
}
}
impl Serialize for Strike {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bool(self.val)
}
}
impl BuildXML for Strike {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.strike().build()
}
}

View File

@ -185,7 +185,7 @@ mod tests {
.grid_span(2);
assert_eq!(
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,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"vertAlign":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"characterSpacing":null,"fonts":null,"textBorder":null,"del":null,"ins":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":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":{},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{},"style":null,"numberingProperty":null,"alignment":null,"indent":null,"lineSpacing":null,"keepNext":false,"keepLines":false,"pageBreakBefore":false,"windowControl":false,"outlineLvl":null,"divId":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null,"textDirection":null,"shading":null},"hasNumbering":false}"#,
);
}
}

View File

@ -30,6 +30,13 @@ impl ElementReader for RunProperty {
rp = rp.bold();
}
XMLElement::Highlight => rp = rp.highlight(attributes[0].value.clone()),
XMLElement::Strike => {
if !read_bool(&attributes) {
rp.strike = Some(Strike::new().disable());
continue;
}
rp = rp.strike();
}
XMLElement::VertAlign => {
if let Ok(v) = VertAlignType::from_str(&attributes[0].value) {
rp = rp.vert_align(v)

View File

@ -69,6 +69,7 @@ pub enum XMLElement {
CommentsExtended,
VAlign,
Shading,
Strike,
TextDirection,
Table,
TableProperty,
@ -320,6 +321,7 @@ impl FromStr for XMLElement {
"pict" => Ok(XMLElement::Pict),
"lvlOverride" => Ok(XMLElement::LvlOverride),
"startOverride" => Ok(XMLElement::StartOverride),
"strike" => Ok(XMLElement::Strike),
"docId" => Ok(XMLElement::DocId),
"docVar" => Ok(XMLElement::DocVar),
"docVars" => Ok(XMLElement::DocVars),

View File

@ -144,6 +144,9 @@ impl XMLBuilder {
closed!(i, "w:i");
closed!(i_cs, "w:iCs");
closed!(strike, "w:strike");
// Build w:style element
// i.e. <w:style ... >
pub(crate) fn open_style(mut self, style_type: StyleType, id: &str) -> Self {

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,21 +12,22 @@ export type TextBorderJSON = {
};
export type RunPropertyJSON = {
sz: number | null;
szCs: number | null;
color: string | null;
highlight: string | null;
vertAlign: VertAlignType | null;
underline: string | null;
bold: boolean | null;
boldCs: boolean | null;
italic: boolean | null;
italicCs: boolean | null;
vanish: boolean | null;
spacing: number | null;
textBorder: TextBorderJSON | null;
ins: InsertJSON | null;
del: DeleteJSON | null;
sz?: number | null;
szCs?: number | null;
color?: string | null;
highlight?: string | null;
vertAlign?: VertAlignType | null;
underline?: string | null;
bold?: boolean | null;
boldCs?: boolean | null;
italic?: boolean | null;
italicCs?: boolean | null;
vanish?: boolean | null;
spacing?: number | null;
textBorder?: TextBorderJSON | null;
ins?: InsertJSON | null;
del?: DeleteJSON | null;
strike?: boolean;
};
export type RunChildJSON =

File diff suppressed because it is too large Load Diff

View File

@ -92,6 +92,12 @@ describe("reader", () => {
const json = w.readDocx(buffer);
expect(json).toMatchSnapshot();
});
test("should read strike docx", () => {
const buffer = readFileSync("../fixtures/strike/strike.docx");
const json = w.readDocx(buffer);
expect(json).toMatchSnapshot();
});
});
describe("writer", () => {

View File

@ -1,2 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>植木 智之</dc:creator><cp:keywords></cp:keywords><dc:description></dc:description><cp:lastModifiedBy>植木 智之</cp:lastModifiedBy><cp:revision>2</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2021-04-07T09:14:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2021-04-08T08:39:00Z</dcterms:modified></cp:coreProperties>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>bokuweb</dc:creator><cp:keywords></cp:keywords><dc:description></dc:description><cp:lastModifiedBy>bokuweb</cp:lastModifiedBy><cp:revision>2</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2021-04-07T09:14:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2021-04-08T08:39:00Z</dcterms:modified></cp:coreProperties>

Binary file not shown.