Compare commits
13 Commits
c492b86aba
...
f5fda75a96
Author | SHA1 | Date |
---|---|---|
|
f5fda75a96 | |
|
52af4afeec | |
|
50e6eddb08 | |
|
d95137cb9f | |
|
fbe87945e0 | |
|
077de5d561 | |
|
4728e080a4 | |
|
6c1d6e89b2 | |
|
a4c38a7b0e | |
|
31c109aacb | |
|
ab837bcba4 | |
|
9fbc75d6b2 | |
|
0f65b00436 |
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Support `dstrike`
|
- Support `dstrike`
|
||||||
- Update Add after for default toc styles #806
|
- Update Add after for default toc styles #806
|
||||||
- Update `Level` styles.
|
- Update `Level` styles.
|
||||||
|
- Support `titlePg`
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## @0.4.17 (26. Apr, 2024)
|
## @0.4.17 (26. Apr, 2024)
|
||||||
|
|
|
@ -28,9 +28,9 @@ checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.13.1"
|
version = "0.22.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
|
|
|
@ -29,7 +29,7 @@ thiserror = "1.0"
|
||||||
zip = { version = "0.6.3", default-features = false, features = ["deflate"] }
|
zip = { version = "0.6.3", default-features = false, features = ["deflate"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = {version = "1.0" }
|
serde_json = {version = "1.0" }
|
||||||
base64 = "0.13.1"
|
base64 = "0.22.1"
|
||||||
image = { version = "0.24.4", default-features = false, features=["gif", "jpeg", "png", "bmp", "tiff"], optional = true }
|
image = { version = "0.24.4", default-features = false, features=["gif", "jpeg", "png", "bmp", "tiff"], optional = true }
|
||||||
wasm-bindgen = { version = "0.2.78", optional = true }
|
wasm-bindgen = { version = "0.2.78", optional = true }
|
||||||
ts-rs = { version = "6.1", optional = true }
|
ts-rs = { version = "6.1", optional = true }
|
||||||
|
|
|
@ -140,6 +140,11 @@ impl Document {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn title_pg(mut self) -> Self {
|
||||||
|
self.section_property = self.section_property.title_pg();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn page_size(mut self, size: PageSize) -> Self {
|
pub fn page_size(mut self, size: PageSize) -> Self {
|
||||||
self.section_property = self.section_property.page_size(size);
|
self.section_property = self.section_property.page_size(size);
|
||||||
self
|
self
|
||||||
|
|
|
@ -40,6 +40,10 @@ impl BuildXML for Bold {
|
||||||
&self,
|
&self,
|
||||||
stream: xml::writer::EventWriter<W>,
|
stream: xml::writer::EventWriter<W>,
|
||||||
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
||||||
XMLBuilder::from(stream).b()?.into_inner()
|
if self.val {
|
||||||
|
XMLBuilder::from(stream).b()?.into_inner()
|
||||||
|
} else {
|
||||||
|
XMLBuilder::from(stream).disable_bold()?.into_inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,10 @@ impl BuildXML for Dstrike {
|
||||||
&self,
|
&self,
|
||||||
stream: xml::writer::EventWriter<W>,
|
stream: xml::writer::EventWriter<W>,
|
||||||
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
||||||
XMLBuilder::from(stream).dstrike()?.into_inner()
|
if self.val {
|
||||||
|
XMLBuilder::from(stream).dstrike()?.into_inner()
|
||||||
|
} else {
|
||||||
|
XMLBuilder::from(stream).disable_dstrike()?.into_inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,10 @@ impl BuildXML for Italic {
|
||||||
&self,
|
&self,
|
||||||
stream: xml::writer::EventWriter<W>,
|
stream: xml::writer::EventWriter<W>,
|
||||||
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
||||||
XMLBuilder::from(stream).i()?.into_inner()
|
if self.val {
|
||||||
|
XMLBuilder::from(stream).i()?.into_inner()
|
||||||
|
} else {
|
||||||
|
XMLBuilder::from(stream).disable_italic()?.into_inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ mod shading;
|
||||||
mod shape;
|
mod shape;
|
||||||
mod spec_vanish;
|
mod spec_vanish;
|
||||||
mod start;
|
mod start;
|
||||||
|
mod stretch;
|
||||||
mod strike;
|
mod strike;
|
||||||
mod structured_data_tag;
|
mod structured_data_tag;
|
||||||
mod structured_data_tag_property;
|
mod structured_data_tag_property;
|
||||||
|
@ -232,6 +233,7 @@ pub use shading::*;
|
||||||
pub use shape::*;
|
pub use shape::*;
|
||||||
pub use spec_vanish::*;
|
pub use spec_vanish::*;
|
||||||
pub use start::*;
|
pub use start::*;
|
||||||
|
pub use stretch::*;
|
||||||
pub use strike::*;
|
pub use strike::*;
|
||||||
pub use structured_data_tag::*;
|
pub use structured_data_tag::*;
|
||||||
pub use structured_data_tag_property::*;
|
pub use structured_data_tag_property::*;
|
||||||
|
|
|
@ -263,6 +263,11 @@ impl Run {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stretch(mut self, v: i32) -> Run {
|
||||||
|
self.run_property = self.run_property.stretch(v);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn color(mut self, color: impl Into<String>) -> Run {
|
pub fn color(mut self, color: impl Into<String>) -> Run {
|
||||||
self.run_property = self.run_property.color(color);
|
self.run_property = self.run_property.color(color);
|
||||||
self
|
self
|
||||||
|
|
|
@ -40,6 +40,8 @@ pub struct RunProperty {
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub character_spacing: Option<CharacterSpacing>,
|
pub character_spacing: Option<CharacterSpacing>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub stretch: Option<Stretch>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub fonts: Option<RunFonts>,
|
pub fonts: Option<RunFonts>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub text_border: Option<TextBorder>,
|
pub text_border: Option<TextBorder>,
|
||||||
|
@ -169,6 +171,11 @@ impl RunProperty {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn stretch(mut self, v: i32) -> RunProperty {
|
||||||
|
self.stretch = Some(Stretch::new(v));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn text_border(mut self, b: TextBorder) -> Self {
|
pub fn text_border(mut self, b: TextBorder) -> Self {
|
||||||
self.text_border = Some(b);
|
self.text_border = Some(b);
|
||||||
self
|
self
|
||||||
|
@ -222,6 +229,7 @@ impl BuildXML for RunProperty {
|
||||||
.add_optional_child(&self.del)?
|
.add_optional_child(&self.del)?
|
||||||
.add_optional_child(&self.vert_align)?
|
.add_optional_child(&self.vert_align)?
|
||||||
.add_optional_child(&self.character_spacing)?
|
.add_optional_child(&self.character_spacing)?
|
||||||
|
.add_optional_child(&self.stretch)?
|
||||||
.add_optional_child(&self.style)?
|
.add_optional_child(&self.style)?
|
||||||
.add_optional_child(&self.positional_tab)?
|
.add_optional_child(&self.positional_tab)?
|
||||||
.add_optional_child(&self.shading)?
|
.add_optional_child(&self.shading)?
|
||||||
|
@ -318,6 +326,16 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stretch() {
|
||||||
|
let c = RunProperty::new().stretch(80);
|
||||||
|
let b = c.build();
|
||||||
|
assert_eq!(
|
||||||
|
str::from_utf8(&b).unwrap(),
|
||||||
|
r#"<w:rPr><w:w w:val="80" /></w:rPr>"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_ptab() {
|
fn test_ptab() {
|
||||||
let c = RunProperty::new().ptab(PositionalTab::new(
|
let c = RunProperty::new().ptab(PositionalTab::new(
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
use crate::documents::BuildXML;
|
||||||
|
use crate::xml_builder::*;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
use serde::*;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
pub struct Stretch {
|
||||||
|
value: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stretch {
|
||||||
|
pub fn new(s: i32) -> Stretch {
|
||||||
|
Self { value: s }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildXML for Stretch {
|
||||||
|
fn build_to<W: Write>(
|
||||||
|
&self,
|
||||||
|
stream: xml::writer::EventWriter<W>,
|
||||||
|
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
||||||
|
XMLBuilder::from(stream).w(self.value)?.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Stretch {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_i32(self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
#[cfg(test)]
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stretch() {
|
||||||
|
let b = Stretch::new(200).build();
|
||||||
|
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:w w:val="200" />"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_stretch_json() {
|
||||||
|
let s = Stretch { value: 100 };
|
||||||
|
assert_eq!(serde_json::to_string(&s).unwrap(), r#"100"#);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,6 +40,10 @@ impl BuildXML for Strike {
|
||||||
&self,
|
&self,
|
||||||
stream: xml::writer::EventWriter<W>,
|
stream: xml::writer::EventWriter<W>,
|
||||||
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
) -> xml::writer::Result<xml::writer::EventWriter<W>> {
|
||||||
XMLBuilder::from(stream).strike()?.into_inner()
|
if self.val {
|
||||||
|
XMLBuilder::from(stream).strike()?.into_inner()
|
||||||
|
} else {
|
||||||
|
XMLBuilder::from(stream).disable_strike()?.into_inner()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ pub use web_settings::*;
|
||||||
pub use webextension::*;
|
pub use webextension::*;
|
||||||
pub use xml_docx::*;
|
pub use xml_docx::*;
|
||||||
|
|
||||||
|
use base64::Engine;
|
||||||
use serde::{ser, Serialize};
|
use serde::{ser, Serialize};
|
||||||
|
|
||||||
use self::image_collector::{collect_images_from_paragraph, collect_images_from_table};
|
use self::image_collector::{collect_images_from_paragraph, collect_images_from_table};
|
||||||
|
@ -96,7 +97,7 @@ impl ser::Serialize for Image {
|
||||||
where
|
where
|
||||||
S: ser::Serializer,
|
S: ser::Serializer,
|
||||||
{
|
{
|
||||||
let base64 = base64::display::Base64Display::with_config(&self.0, base64::STANDARD);
|
let base64 = base64::engine::general_purpose::STANDARD.encode(&self.0);
|
||||||
serializer.collect_str(&base64)
|
serializer.collect_str(&base64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +107,7 @@ impl ser::Serialize for Png {
|
||||||
where
|
where
|
||||||
S: ser::Serializer,
|
S: ser::Serializer,
|
||||||
{
|
{
|
||||||
let base64 = base64::display::Base64Display::with_config(&self.0, base64::STANDARD);
|
let base64 = base64::engine::general_purpose::STANDARD.encode(&self.0);
|
||||||
serializer.collect_str(&base64)
|
serializer.collect_str(&base64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,6 +458,11 @@ impl Docx {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn title_pg(mut self) -> Self {
|
||||||
|
self.document = self.document.title_pg();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn page_size(mut self, w: u32, h: u32) -> Self {
|
pub fn page_size(mut self, w: u32, h: u32) -> Self {
|
||||||
self.document = self.document.page_size(PageSize::new().size(w, h));
|
self.document = self.document.page_size(PageSize::new().size(w, h));
|
||||||
self
|
self
|
||||||
|
|
|
@ -67,7 +67,9 @@ impl ElementReader for Level {
|
||||||
is_lgl = Some(IsLgl::new());
|
is_lgl = Some(IsLgl::new());
|
||||||
}
|
}
|
||||||
XMLElement::LevelText => {
|
XMLElement::LevelText => {
|
||||||
level_text = LevelText::new(attributes[0].value.clone());
|
if !attributes.is_empty() {
|
||||||
|
level_text = LevelText::new(attributes[0].value.clone());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
XMLElement::LevelRestart => {
|
XMLElement::LevelRestart => {
|
||||||
if let Ok(v) = u32::from_str(&attributes[0].value) {
|
if let Ok(v) = u32::from_str(&attributes[0].value) {
|
||||||
|
|
|
@ -418,6 +418,7 @@ pub fn read_docx(buf: &[u8]) -> Result<Docx, ReaderError> {
|
||||||
)?;
|
)?;
|
||||||
let nums = Numberings::from_xml(&data[..])?;
|
let nums = Numberings::from_xml(&data[..])?;
|
||||||
docx = docx.numberings(nums);
|
docx = docx.numberings(nums);
|
||||||
|
docx.document_rels.has_numberings = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,13 @@ impl ElementReader for RunProperty {
|
||||||
}
|
}
|
||||||
rp = rp.strike();
|
rp = rp.strike();
|
||||||
}
|
}
|
||||||
|
XMLElement::Dstrike => {
|
||||||
|
if !read_bool(&attributes) {
|
||||||
|
rp.dstrike = Some(Dstrike::new().disable());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rp = rp.dstrike();
|
||||||
|
}
|
||||||
XMLElement::VertAlign => {
|
XMLElement::VertAlign => {
|
||||||
if let Ok(v) = VertAlignType::from_str(&attributes[0].value) {
|
if let Ok(v) = VertAlignType::from_str(&attributes[0].value) {
|
||||||
rp = rp.vert_align(v)
|
rp = rp.vert_align(v)
|
||||||
|
@ -121,6 +128,11 @@ impl ElementReader for RunProperty {
|
||||||
}
|
}
|
||||||
rp = rp.italic();
|
rp = rp.italic();
|
||||||
}
|
}
|
||||||
|
XMLElement::Shading => {
|
||||||
|
if let Ok(shd) = Shading::read(r, &attributes) {
|
||||||
|
rp = rp.shading(shd);
|
||||||
|
}
|
||||||
|
}
|
||||||
XMLElement::Vanish => rp = rp.vanish(),
|
XMLElement::Vanish => rp = rp.vanish(),
|
||||||
XMLElement::SpecVanish => rp = rp.spec_vanish(),
|
XMLElement::SpecVanish => rp = rp.spec_vanish(),
|
||||||
XMLElement::TextBorder => {
|
XMLElement::TextBorder => {
|
||||||
|
|
|
@ -183,14 +183,39 @@ impl<W: Write> XMLBuilder<W> {
|
||||||
closed!(b, "w:b");
|
closed!(b, "w:b");
|
||||||
closed!(b_cs, "w:bCs");
|
closed!(b_cs, "w:bCs");
|
||||||
|
|
||||||
|
pub(crate) fn disable_bold(self) -> Result<Self> {
|
||||||
|
let f = "false";
|
||||||
|
self.write(XmlEvent::start_element("w:b").attr("w:val", &f))?
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
|
||||||
closed_with_str!(caps, "w:caps");
|
closed_with_str!(caps, "w:caps");
|
||||||
|
|
||||||
closed!(i, "w:i");
|
closed!(i, "w:i");
|
||||||
closed!(i_cs, "w:iCs");
|
closed!(i_cs, "w:iCs");
|
||||||
|
|
||||||
|
pub(crate) fn disable_italic(self) -> Result<Self> {
|
||||||
|
let f = "false";
|
||||||
|
self.write(XmlEvent::start_element("w:i").attr("w:val", &f))?
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
|
||||||
closed!(strike, "w:strike");
|
closed!(strike, "w:strike");
|
||||||
|
|
||||||
|
pub(crate) fn disable_strike(self) -> Result<Self> {
|
||||||
|
let f = "false";
|
||||||
|
self.write(XmlEvent::start_element("w:strike").attr("w:val", &f))?
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
|
||||||
closed!(dstrike, "w:dstrike");
|
closed!(dstrike, "w:dstrike");
|
||||||
|
|
||||||
|
pub(crate) fn disable_dstrike(self) -> Result<Self> {
|
||||||
|
let f = "false";
|
||||||
|
self.write(XmlEvent::start_element("w:dstrike").attr("w:val", &f))?
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
|
||||||
// Build w:style element
|
// Build w:style element
|
||||||
// i.e. <w:style ... >
|
// i.e. <w:style ... >
|
||||||
pub(crate) fn open_style(self, style_type: StyleType, id: &str) -> Result<Self> {
|
pub(crate) fn open_style(self, style_type: StyleType, id: &str) -> Result<Self> {
|
||||||
|
@ -253,6 +278,12 @@ impl<W: Write> XMLBuilder<W> {
|
||||||
.close()
|
.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// i.e. <w:w ... >
|
||||||
|
pub(crate) fn w(self, s: i32) -> Result<Self> {
|
||||||
|
self.write(XmlEvent::start_element("w:w").attr("w:val", &format!("{}", s)))?
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
|
||||||
// i.e. <w:spacing ... >
|
// i.e. <w:spacing ... >
|
||||||
pub(crate) fn line_spacing(
|
pub(crate) fn line_spacing(
|
||||||
self,
|
self,
|
||||||
|
@ -471,7 +502,7 @@ impl<W: Write> XMLBuilder<W> {
|
||||||
closed!(keep_lines, "w:keepLines");
|
closed!(keep_lines, "w:keepLines");
|
||||||
closed!(page_break_before, "w:pageBreakBefore");
|
closed!(page_break_before, "w:pageBreakBefore");
|
||||||
closed!(widow_control, "w:widowControl", "w:val");
|
closed!(widow_control, "w:widowControl", "w:val");
|
||||||
closed!(bidi,"w:bidi");
|
closed!(bidi, "w:bidi");
|
||||||
/*
|
/*
|
||||||
<w:lvlOverride w:ilvl="0">
|
<w:lvlOverride w:ilvl="0">
|
||||||
<w:startOverride w:val="1"/>
|
<w:startOverride w:val="1"/>
|
||||||
|
|
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
|
@ -152,6 +152,11 @@ export class Docx {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
titlePg() {
|
||||||
|
this.sectionProperty.titlePg();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
pageSize(w: number, h: number) {
|
pageSize(w: number, h: number) {
|
||||||
this.sectionProperty.pageSize(w, h);
|
this.sectionProperty.pageSize(w, h);
|
||||||
return this;
|
return this;
|
||||||
|
@ -549,6 +554,10 @@ export class Docx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.sectionProperty._titlePg) {
|
||||||
|
docx = docx.title_pg();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.sectionProperty._pageTypeNum) {
|
if (this.sectionProperty._pageTypeNum) {
|
||||||
const { start, chapStyle } = this.sectionProperty._pageTypeNum;
|
const { start, chapStyle } = this.sectionProperty._pageTypeNum;
|
||||||
const p = wasm.createPageNumType(start, chapStyle);
|
const p = wasm.createPageNumType(start, chapStyle);
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
CommentRangeEndJSON,
|
CommentRangeEndJSON,
|
||||||
InsertJSONData,
|
InsertJSONData,
|
||||||
DeleteJSONData,
|
DeleteJSONData,
|
||||||
|
ShadingJSON,
|
||||||
} from "..";
|
} from "..";
|
||||||
import { BorderType } from "../border";
|
import { BorderType } from "../border";
|
||||||
import { VertAlignType } from "../run-property";
|
import { VertAlignType } from "../run-property";
|
||||||
|
@ -56,6 +57,7 @@ export type RunPropertyJSON = {
|
||||||
del?: DeleteJSONData | null;
|
del?: DeleteJSONData | null;
|
||||||
strike?: boolean;
|
strike?: boolean;
|
||||||
dstrike?: boolean;
|
dstrike?: boolean;
|
||||||
|
shading?: ShadingJSON | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RunChildJSON =
|
export type RunChildJSON =
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import * as wasm from "./pkg/docx_wasm";
|
import * as wasm from "./pkg/docx_wasm";
|
||||||
|
|
||||||
import { BorderType } from "./border";
|
import { BorderType } from "./border";
|
||||||
|
import { Shading } from "./shading";
|
||||||
|
|
||||||
export type TextBorder = {
|
export type TextBorder = {
|
||||||
borderType: BorderType;
|
borderType: BorderType;
|
||||||
|
@ -38,6 +39,7 @@ export class RunProperty {
|
||||||
_textBorder?: TextBorder;
|
_textBorder?: TextBorder;
|
||||||
_ins?: RunPropertyIns;
|
_ins?: RunPropertyIns;
|
||||||
_del?: RunPropertyDel;
|
_del?: RunPropertyDel;
|
||||||
|
_shading?: Shading;
|
||||||
|
|
||||||
style(style: string) {
|
style(style: string) {
|
||||||
this._style = style;
|
this._style = style;
|
||||||
|
@ -143,6 +145,15 @@ export class RunProperty {
|
||||||
};
|
};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shading(type: string, color: string, fill: string) {
|
||||||
|
const s = new Shading();
|
||||||
|
s.color(color);
|
||||||
|
s.fill(fill);
|
||||||
|
s.type(type);
|
||||||
|
this._shading = s;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const convertBorderType = (t: BorderType) => {
|
export const convertBorderType = (t: BorderType) => {
|
||||||
|
@ -340,6 +351,14 @@ export const setRunProperty = <T extends wasm.Run | wasm.Style>(
|
||||||
target = target.fonts(fonts) as T;
|
target = target.fonts(fonts) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (property._shading != null) {
|
||||||
|
target = target.shading(
|
||||||
|
property._shading._type,
|
||||||
|
property._shading._color,
|
||||||
|
property._shading._fill
|
||||||
|
) as T;
|
||||||
|
}
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -429,5 +448,13 @@ export const createRunProperty = (property: RunProperty): wasm.RunProperty => {
|
||||||
target = target.fonts(fonts);
|
target = target.fonts(fonts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (property._shading != null) {
|
||||||
|
target = target.shading(
|
||||||
|
property._shading._type,
|
||||||
|
property._shading._color,
|
||||||
|
property._shading._fill
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
|
@ -160,6 +160,12 @@ export class Run {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shading(type: string, color: string, fill: string) {
|
||||||
|
this.property ??= createDefaultRunProperty();
|
||||||
|
this.property.shading(type, color, fill);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
let run = wasm.createRun();
|
let run = wasm.createRun();
|
||||||
this.children.forEach((child) => {
|
this.children.forEach((child) => {
|
||||||
|
|
|
@ -14,6 +14,7 @@ export class SectionProperty {
|
||||||
w: 11906,
|
w: 11906,
|
||||||
h: 16838,
|
h: 16838,
|
||||||
};
|
};
|
||||||
|
_titlePg: boolean | null = null;
|
||||||
_pageMargin: PageMargin | null = null;
|
_pageMargin: PageMargin | null = null;
|
||||||
_docGrid: DocGrid | null = null;
|
_docGrid: DocGrid | null = null;
|
||||||
_header: Header | null = null;
|
_header: Header | null = null;
|
||||||
|
@ -24,6 +25,11 @@ export class SectionProperty {
|
||||||
_evenFooter: Footer | null = null;
|
_evenFooter: Footer | null = null;
|
||||||
_pageTypeNum: PageNumType | null = null;
|
_pageTypeNum: PageNumType | null = null;
|
||||||
|
|
||||||
|
titlePg() {
|
||||||
|
this._titlePg = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
pageSize(w: number, h: number) {
|
pageSize(w: number, h: number) {
|
||||||
this._pageSize.w = w;
|
this._pageSize.w = w;
|
||||||
this._pageSize.h = h;
|
this._pageSize.h = h;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "docx-wasm",
|
"name": "docx-wasm",
|
||||||
"version": "0.4.18-rc41",
|
"version": "0.4.18-rc48",
|
||||||
"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>",
|
||||||
|
|
|
@ -123,6 +123,11 @@ impl Docx {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn title_pg(mut self) -> Docx {
|
||||||
|
self.0 = self.0.title_pg();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn page_size(mut self, w: u32, h: u32) -> Docx {
|
pub fn page_size(mut self, w: u32, h: u32) -> Docx {
|
||||||
self.0 = self.0.page_size(w, h);
|
self.0 = self.0.page_size(w, h);
|
||||||
self
|
self
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use docx_rs::{BorderType, TextBorder, VertAlignType};
|
use docx_rs::{BorderType, Shading, TextBorder, VertAlignType};
|
||||||
|
use std::str::FromStr;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -137,6 +138,15 @@ impl Run {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shading(mut self, t: &str, color: &str, fill: &str) -> Self {
|
||||||
|
let mut s = Shading::new().color(color).fill(fill);
|
||||||
|
if let Ok(t) = docx_rs::ShdType::from_str(t) {
|
||||||
|
s = s.shd_type(t);
|
||||||
|
}
|
||||||
|
self.0.run_property = self.0.run_property.shading(s);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn text_border(
|
pub fn text_border(
|
||||||
mut self,
|
mut self,
|
||||||
border_type: BorderType,
|
border_type: BorderType,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct RunProperty(docx_rs::RunProperty);
|
pub struct RunProperty(docx_rs::RunProperty);
|
||||||
|
@ -130,6 +132,15 @@ impl RunProperty {
|
||||||
self.0 = self.0.text_border(border);
|
self.0 = self.0.text_border(border);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shading(mut self, t: &str, color: &str, fill: &str) -> Self {
|
||||||
|
let mut s = docx_rs::Shading::new().color(color).fill(fill);
|
||||||
|
if let Ok(t) = docx_rs::ShdType::from_str(t) {
|
||||||
|
s = s.shd_type(t);
|
||||||
|
}
|
||||||
|
self.0 = self.0.shading(s);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunProperty {
|
impl RunProperty {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use docx_rs::{BorderType, TextBorder, VertAlignType, WidthType};
|
use docx_rs::{BorderType, Shading, TextBorder, VertAlignType, WidthType};
|
||||||
|
use std::str::FromStr;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -63,6 +64,15 @@ impl Style {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shading(mut self, t: &str, color: &str, fill: &str) -> Self {
|
||||||
|
let mut s = Shading::new().color(color).fill(fill);
|
||||||
|
if let Ok(t) = docx_rs::ShdType::from_str(t) {
|
||||||
|
s = s.shd_type(t);
|
||||||
|
}
|
||||||
|
self.0.run_property = self.0.run_property.shading(s);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn link(mut self, link: &str) -> Self {
|
pub fn link(mut self, link: &str) -> Self {
|
||||||
self.0 = self.0.link(link);
|
self.0 = self.0.link(link);
|
||||||
self
|
self
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -220,6 +220,12 @@ describe("reader", () => {
|
||||||
const json = w.readDocx(buffer);
|
const json = w.readDocx(buffer);
|
||||||
expect(json).toMatchSnapshot();
|
expect(json).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should read dstrike", () => {
|
||||||
|
const buffer = readFileSync("../fixtures/dstrike/dstrike.docx");
|
||||||
|
const json = w.readDocx(buffer);
|
||||||
|
expect(json).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("writer", () => {
|
describe("writer", () => {
|
||||||
|
@ -464,6 +470,20 @@ describe("writer", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should write shd", () => {
|
||||||
|
const p = new w.Paragraph()
|
||||||
|
.addRun(new w.Run().addText("Hello "))
|
||||||
|
.addRun(new w.Run().addText("World!").shading("clear", "auto", "FFC000"));
|
||||||
|
const buffer = new w.Docx().addParagraph(p).build();
|
||||||
|
writeFileSync("../output/js/shading.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test("should write page orientation", () => {
|
test("should write page orientation", () => {
|
||||||
const p = new w.Paragraph().addRun(new w.Run().addText("Hello "));
|
const p = new w.Paragraph().addRun(new w.Run().addText("Hello "));
|
||||||
const buffer = new w.Docx()
|
const buffer = new w.Docx()
|
||||||
|
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
1.73
|
1.85
|
||||||
|
|
Loading…
Reference in New Issue