feat: Support run style (#447)

* feat: Support run style

* update snaps
main
bokuweb 2022-03-16 12:24:12 +09:00 committed by GitHub
parent 935d880839
commit 886113515b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 1530 additions and 36 deletions

View File

@ -9,6 +9,7 @@ mod bookmark_start;
mod br; mod br;
mod character_spacing; mod character_spacing;
mod color; mod color;
mod run_style;
mod comment; mod comment;
mod comment_extended; mod comment_extended;
mod comment_range_end; mod comment_range_end;
@ -136,6 +137,7 @@ pub use doc_var::*;
pub use drawing::*; pub use drawing::*;
pub use fld_char::*; pub use fld_char::*;
pub use font::*; pub use font::*;
pub use run_style::*;
pub use font_scheme::*; pub use font_scheme::*;
pub use footer_reference::*; pub use footer_reference::*;
pub use grid_span::*; pub use grid_span::*;

View File

@ -165,6 +165,11 @@ impl Run {
self self
} }
pub fn style(mut self, style_id: &str) -> Self {
self.run_property = self.run_property.style(style_id);
self
}
pub fn size(mut self, size: usize) -> Run { pub fn size(mut self, size: usize) -> Run {
self.run_property = self.run_property.size(size); self.run_property = self.run_property.size(size);
self self

View File

@ -5,9 +5,11 @@ use crate::documents::BuildXML;
use crate::types::*; use crate::types::*;
use crate::xml_builder::*; use crate::xml_builder::*;
#[derive(Debug, Clone, Serialize, PartialEq)] #[derive(Debug, Clone, Serialize, PartialEq, Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct RunProperty { pub struct RunProperty {
#[serde(skip_serializing_if = "Option::is_none")]
pub style: Option<RunStyle>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub sz: Option<Sz>, pub sz: Option<Sz>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -49,6 +51,11 @@ impl RunProperty {
Default::default() Default::default()
} }
pub fn style(mut self, style_id: &str) -> Self {
self.style = Some(RunStyle::new(style_id));
self
}
pub fn size(mut self, size: usize) -> RunProperty { pub fn size(mut self, size: usize) -> RunProperty {
self.sz = Some(Sz::new(size)); self.sz = Some(Sz::new(size));
self.sz_cs = Some(SzCs::new(size)); self.sz_cs = Some(SzCs::new(size));
@ -135,30 +142,6 @@ impl RunProperty {
} }
} }
impl Default for RunProperty {
fn default() -> Self {
Self {
color: None,
sz: None,
sz_cs: None,
highlight: None,
vert_align: None,
underline: None,
bold: None,
bold_cs: None,
italic: None,
italic_cs: None,
vanish: None,
fonts: None,
character_spacing: None,
text_border: None,
del: None,
ins: None,
strike: None,
}
}
}
impl BuildXML for RunProperty { impl BuildXML for RunProperty {
fn build(&self) -> Vec<u8> { fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new(); let b = XMLBuilder::new();

View File

@ -0,0 +1,57 @@
use serde::{Serialize, Serializer};
use crate::documents::BuildXML;
use crate::xml_builder::*;
#[derive(Debug, Clone, PartialEq)]
pub struct RunStyle {
pub val: String,
}
impl Default for RunStyle {
fn default() -> Self {
RunStyle {
val: "Normal".to_owned(),
}
}
}
impl RunStyle {
pub fn new(val: impl Into<String>) -> RunStyle {
RunStyle { val: val.into() }
}
}
impl BuildXML for RunStyle {
fn build(&self) -> Vec<u8> {
XMLBuilder::new().run_style(&self.val).build()
}
}
impl Serialize for RunStyle {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.val)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_r_style() {
let c = RunStyle::new("Heading");
let b = c.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:rStyle w:val="Heading" />"#
);
}
}

View File

@ -60,6 +60,11 @@ impl ElementReader for RunProperty {
}) => { }) => {
let e = XMLElement::from_str(&name.local_name).unwrap(); let e = XMLElement::from_str(&name.local_name).unwrap();
match e { match e {
XMLElement::RunStyle => {
if let Some(v) = read_val(&attributes) {
rp = rp.style(&v);
}
}
XMLElement::Bold => { XMLElement::Bold => {
if !read_bool(&attributes) { if !read_bool(&attributes) {
rp = rp.disable_bold(); rp = rp.disable_bold();

View File

@ -29,6 +29,7 @@ pub enum XMLElement {
Highlight, Highlight,
VertAlign, VertAlign,
Bold, Bold,
RunStyle,
BoldCs, BoldCs,
Break, Break,
Tab, Tab,
@ -235,6 +236,7 @@ impl FromStr for XMLElement {
"pStyle" => Ok(XMLElement::ParagraphStyle), "pStyle" => Ok(XMLElement::ParagraphStyle),
"pPrChange" => Ok(XMLElement::ParagraphPropertyChange), "pPrChange" => Ok(XMLElement::ParagraphPropertyChange),
"highlight" => Ok(XMLElement::Highlight), "highlight" => Ok(XMLElement::Highlight),
"rStyle" => Ok(XMLElement::RunStyle),
"b" => Ok(XMLElement::Bold), "b" => Ok(XMLElement::Bold),
"bCs" => Ok(XMLElement::BoldCs), "bCs" => Ok(XMLElement::BoldCs),
"i" => Ok(XMLElement::Italic), "i" => Ok(XMLElement::Italic),

View File

@ -149,6 +149,8 @@ impl XMLBuilder {
closed_with_str!(vert_align, "w:vertAlign"); closed_with_str!(vert_align, "w:vertAlign");
// i.e. <w:pStyle ... > // i.e. <w:pStyle ... >
closed_with_str!(paragraph_style, "w:pStyle"); closed_with_str!(paragraph_style, "w:pStyle");
// i.e. <w:rStyle ... >
closed_with_str!(run_style, "w:rStyle");
// i.e. <w:sz ... > // i.e. <w:sz ... >
closed_with_usize!(sz, "w:sz"); closed_with_usize!(sz, "w:sz");
// i.e. <w:szCs ... > // i.e. <w:szCs ... >

File diff suppressed because it is too large Load Diff

View File

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

Binary file not shown.