Support default fonts (#207)
* feat: support default font writer * feat: Support default font by js * fix: update snaps * fix: update snapsmain
parent
1020f4bd04
commit
688632bca2
|
@ -239,9 +239,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.23.11"
|
version = "0.23.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4f0a8345b33b082aedec2f4d7d4a926b845cee184cbe78b703413066564431b"
|
checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -258,9 +258,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "insta"
|
name = "insta"
|
||||||
version = "1.1.0"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e7e7528a20113cf7ca90eddfc2439c608188b6eafc0613964da2bd140c92acec"
|
checksum = "863bf97e7130bf788f29a99bc4073735af6b8ecc3da6a39c23b3a688d2d3109a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console",
|
"console",
|
||||||
"difference",
|
"difference",
|
||||||
|
@ -300,9 +300,9 @@ checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.2"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
|
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
|
@ -530,9 +530,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_yaml"
|
name = "serde_yaml"
|
||||||
version = "0.8.11"
|
version = "0.8.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
|
checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa",
|
"dtoa",
|
||||||
"linked-hash-map",
|
"linked-hash-map",
|
||||||
|
|
|
@ -21,7 +21,7 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
xml-rs = "0.8.3"
|
xml-rs = "0.8.3"
|
||||||
wasm-bindgen = "0.2.50"
|
wasm-bindgen = "0.2.69"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
zip = { version = "0.5.6", default-features = false, features = ["deflate"] }
|
zip = { version = "0.5.6", default-features = false, features = ["deflate"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
@ -30,4 +30,4 @@ image = "0.23.12"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "0.6.1"
|
pretty_assertions = "0.6.1"
|
||||||
insta = "1.1"
|
insta = "1.3"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::documents::BuildXML;
|
|
||||||
use crate::xml_builder::*;
|
use crate::xml_builder::*;
|
||||||
|
use crate::{documents::BuildXML, RunProperty};
|
||||||
|
|
||||||
use super::run_property_default::*;
|
use super::run_property_default::*;
|
||||||
|
use super::RunFonts;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
|
@ -15,6 +16,26 @@ impl DocDefaults {
|
||||||
pub fn new() -> DocDefaults {
|
pub fn new() -> DocDefaults {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(mut self, size: usize) -> Self {
|
||||||
|
self.run_property_default = self.run_property_default.size(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spacing(mut self, spacing: i32) -> Self {
|
||||||
|
self.run_property_default = self.run_property_default.spacing(spacing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fonts(mut self, font: RunFonts) -> Self {
|
||||||
|
self.run_property_default = self.run_property_default.fonts(font);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_property(mut self, p: RunProperty) -> Self {
|
||||||
|
self.run_property_default = self.run_property_default.run_property(p);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DocDefaults {
|
impl Default for DocDefaults {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::RunProperty;
|
use super::*;
|
||||||
use crate::documents::BuildXML;
|
use crate::documents::BuildXML;
|
||||||
use crate::xml_builder::*;
|
use crate::xml_builder::*;
|
||||||
|
|
||||||
|
@ -14,6 +14,26 @@ impl RunPropertyDefault {
|
||||||
pub fn new() -> RunPropertyDefault {
|
pub fn new() -> RunPropertyDefault {
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(mut self, size: usize) -> Self {
|
||||||
|
self.run_property = self.run_property.size(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spacing(mut self, spacing: i32) -> Self {
|
||||||
|
self.run_property = self.run_property.spacing(spacing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fonts(mut self, font: RunFonts) -> Self {
|
||||||
|
self.run_property = self.run_property.fonts(font);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn run_property(mut self, p: RunProperty) -> Self {
|
||||||
|
self.run_property = p;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RunPropertyDefault {
|
impl Default for RunPropertyDefault {
|
||||||
|
|
|
@ -209,6 +209,21 @@ impl Docx {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_size(mut self, size: usize) -> Self {
|
||||||
|
self.styles = self.styles.default_size(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_spacing(mut self, spacing: i32) -> Self {
|
||||||
|
self.styles = self.styles.default_spacing(spacing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_fonts(mut self, font: RunFonts) -> Self {
|
||||||
|
self.styles = self.styles.default_fonts(font);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(&mut self) -> XMLDocx {
|
pub fn build(&mut self) -> XMLDocx {
|
||||||
self.update_comments();
|
self.update_comments();
|
||||||
let (image_ids, images) = self.create_images();
|
let (image_ids, images) = self.create_images();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::{DocDefaults, Style};
|
use super::*;
|
||||||
use crate::documents::BuildXML;
|
use crate::documents::BuildXML;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::xml_builder::*;
|
use crate::xml_builder::*;
|
||||||
|
@ -21,6 +21,26 @@ impl Styles {
|
||||||
self.styles.push(style);
|
self.styles.push(style);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_size(mut self, size: usize) -> Self {
|
||||||
|
self.doc_defaults = self.doc_defaults.size(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_spacing(mut self, spacing: i32) -> Self {
|
||||||
|
self.doc_defaults = self.doc_defaults.spacing(spacing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_fonts(mut self, font: RunFonts) -> Self {
|
||||||
|
self.doc_defaults = self.doc_defaults.fonts(font);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn doc_defaults(mut self, doc_defaults: DocDefaults) -> Self {
|
||||||
|
self.doc_defaults = doc_defaults;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Styles {
|
impl Default for Styles {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
use std::io::Read;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use xml::attribute::OwnedAttribute;
|
||||||
|
use xml::reader::{EventReader, XmlEvent};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl ElementReader for DocDefaults {
|
||||||
|
fn read<R: Read>(
|
||||||
|
r: &mut EventReader<R>,
|
||||||
|
_attrs: &[OwnedAttribute],
|
||||||
|
) -> Result<Self, ReaderError> {
|
||||||
|
let mut doc_defaults = DocDefaults::new();
|
||||||
|
loop {
|
||||||
|
let e = r.next();
|
||||||
|
match e {
|
||||||
|
Ok(XmlEvent::StartElement {
|
||||||
|
attributes, name, ..
|
||||||
|
}) => {
|
||||||
|
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||||
|
if let XMLElement::RunProperty = e {
|
||||||
|
let run_pr = RunProperty::read(r, &attributes)?;
|
||||||
|
doc_defaults = doc_defaults.run_property(run_pr);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(XmlEvent::EndElement { name, .. }) => {
|
||||||
|
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||||
|
if let XMLElement::DocDefaults = e {
|
||||||
|
return Ok(doc_defaults);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => return Err(ReaderError::XMLReadError),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ mod attributes;
|
||||||
mod bookmark_end;
|
mod bookmark_end;
|
||||||
mod bookmark_start;
|
mod bookmark_start;
|
||||||
mod delete;
|
mod delete;
|
||||||
|
mod doc_defaults;
|
||||||
mod document;
|
mod document;
|
||||||
mod document_rels;
|
mod document_rels;
|
||||||
mod drawing;
|
mod drawing;
|
||||||
|
|
|
@ -56,7 +56,6 @@ impl ElementReader for Run {
|
||||||
run = run.size(usize::from_str(&attributes[0].value)?)
|
run = run.size(usize::from_str(&attributes[0].value)?)
|
||||||
}
|
}
|
||||||
XMLElement::Underline => {
|
XMLElement::Underline => {
|
||||||
dbg!(&attributes);
|
|
||||||
run = run.underline(&attributes[0].value.clone())
|
run = run.underline(&attributes[0].value.clone())
|
||||||
}
|
}
|
||||||
XMLElement::Italic => {
|
XMLElement::Italic => {
|
||||||
|
|
|
@ -35,6 +35,8 @@ impl ElementReader for RunProperty {
|
||||||
rp = rp.spacing(v)
|
rp = rp.spacing(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: Implement later
|
||||||
|
XMLElement::RunFonts => {}
|
||||||
XMLElement::Underline => rp = rp.underline(&attributes[0].value.clone()),
|
XMLElement::Underline => rp = rp.underline(&attributes[0].value.clone()),
|
||||||
XMLElement::Italic => {
|
XMLElement::Italic => {
|
||||||
if !read_bool(&attributes) {
|
if !read_bool(&attributes) {
|
||||||
|
@ -43,7 +45,6 @@ impl ElementReader for RunProperty {
|
||||||
rp = rp.italic();
|
rp = rp.italic();
|
||||||
}
|
}
|
||||||
XMLElement::Vanish => rp = rp.vanish(),
|
XMLElement::Vanish => rp = rp.vanish(),
|
||||||
// TODO: Add run fonts reader
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,18 @@ impl FromXML for Styles {
|
||||||
attributes, name, ..
|
attributes, name, ..
|
||||||
}) => {
|
}) => {
|
||||||
let e = XMLElement::from_str(&name.local_name).unwrap();
|
let e = XMLElement::from_str(&name.local_name).unwrap();
|
||||||
if let XMLElement::Style = e {
|
match e {
|
||||||
let s = Style::read(&mut parser, &attributes)?;
|
XMLElement::Style => {
|
||||||
styles = styles.add_style(s);
|
let s = Style::read(&mut parser, &attributes)?;
|
||||||
continue;
|
styles = styles.add_style(s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
XMLElement::DocDefaults => {
|
||||||
|
let d = DocDefaults::read(&mut parser, &attributes)?;
|
||||||
|
styles = styles.doc_defaults(d);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(XmlEvent::EndElement { name, .. }) => {
|
Ok(XmlEvent::EndElement { name, .. }) => {
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub enum XMLElement {
|
||||||
RunProperty,
|
RunProperty,
|
||||||
Color,
|
Color,
|
||||||
Underline,
|
Underline,
|
||||||
|
RunFonts,
|
||||||
Size,
|
Size,
|
||||||
SizeCs,
|
SizeCs,
|
||||||
Spacing,
|
Spacing,
|
||||||
|
@ -100,6 +101,8 @@ pub enum XMLElement {
|
||||||
TxbxContent,
|
TxbxContent,
|
||||||
Pict,
|
Pict,
|
||||||
DocId,
|
DocId,
|
||||||
|
DocDefaults,
|
||||||
|
RunPropertyDefault,
|
||||||
SectionProperty,
|
SectionProperty,
|
||||||
PageSize,
|
PageSize,
|
||||||
PageMargin,
|
PageMargin,
|
||||||
|
@ -257,7 +260,10 @@ impl FromStr for XMLElement {
|
||||||
"docId" => Ok(XMLElement::DocId),
|
"docId" => Ok(XMLElement::DocId),
|
||||||
"sectPr" => Ok(XMLElement::SectionProperty),
|
"sectPr" => Ok(XMLElement::SectionProperty),
|
||||||
"pgSz" => Ok(XMLElement::PageSize),
|
"pgSz" => Ok(XMLElement::PageSize),
|
||||||
|
"rFonts" => Ok(XMLElement::RunFonts),
|
||||||
"pgMar" => Ok(XMLElement::PageMargin),
|
"pgMar" => Ok(XMLElement::PageMargin),
|
||||||
|
"docDefaults" => Ok(XMLElement::DocDefaults),
|
||||||
|
"rPrDefault" => Ok(XMLElement::RunPropertyDefault),
|
||||||
_ => Ok(XMLElement::Unsupported),
|
_ => Ok(XMLElement::Unsupported),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
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
|
@ -0,0 +1,20 @@
|
||||||
|
import { RunProperty, RunFonts } from "./run";
|
||||||
|
|
||||||
|
export class DocDefaults {
|
||||||
|
runProperty: RunProperty;
|
||||||
|
|
||||||
|
size(size: number) {
|
||||||
|
this.runProperty = { ...this.runProperty, size };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
fonts(fonts: RunFonts) {
|
||||||
|
this.runProperty = { ...this.runProperty, fonts };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
spacing(spacing: number) {
|
||||||
|
this.runProperty = { ...this.runProperty, spacing };
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import { DeleteText } from "./delete-text";
|
||||||
import { Table } from "./table";
|
import { Table } from "./table";
|
||||||
import { TableCell } from "./table-cell";
|
import { TableCell } from "./table-cell";
|
||||||
import { BorderType } from "./table-cell-border";
|
import { BorderType } from "./table-cell-border";
|
||||||
import { Run } from "./run";
|
import { Run, RunFonts } from "./run";
|
||||||
import { Text } from "./text";
|
import { Text } from "./text";
|
||||||
import { Tab } from "./tab";
|
import { Tab } from "./tab";
|
||||||
import { Break } from "./break";
|
import { Break } from "./break";
|
||||||
|
@ -16,6 +16,7 @@ import { Numbering } from "./numbering";
|
||||||
import { BookmarkStart } from "./bookmark-start";
|
import { BookmarkStart } from "./bookmark-start";
|
||||||
import { BookmarkEnd } from "./bookmark-end";
|
import { BookmarkEnd } from "./bookmark-end";
|
||||||
import { Settings } from "./settings";
|
import { Settings } from "./settings";
|
||||||
|
import { Styles } from "./styles";
|
||||||
import { SectionProperty, PageMargin } from "./section-property";
|
import { SectionProperty, PageMargin } from "./section-property";
|
||||||
import { DocxJSON } from "./json";
|
import { DocxJSON } from "./json";
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ export class Docx {
|
||||||
numberings: Numbering[] = [];
|
numberings: Numbering[] = [];
|
||||||
settings: Settings = new Settings();
|
settings: Settings = new Settings();
|
||||||
sectionProperty: SectionProperty = new SectionProperty();
|
sectionProperty: SectionProperty = new SectionProperty();
|
||||||
|
styles = new Styles();
|
||||||
|
|
||||||
addParagraph(p: Paragraph) {
|
addParagraph(p: Paragraph) {
|
||||||
if (p.hasNumberings) {
|
if (p.hasNumberings) {
|
||||||
|
@ -108,6 +110,38 @@ export class Docx {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultSize(size: number) {
|
||||||
|
this.styles.defaultSize(size);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultFonts(fonts: RunFonts) {
|
||||||
|
this.styles.defaultFonts(fonts);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultSpacing(spacing: number) {
|
||||||
|
this.styles.defaultSpacing(spacing);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
buildRunFonts = (fonts: RunFonts | undefined) => {
|
||||||
|
let f = wasm.createRunFonts();
|
||||||
|
if (fonts?._ascii) {
|
||||||
|
f = f.ascii(fonts._ascii);
|
||||||
|
}
|
||||||
|
if (fonts?._hiAnsi) {
|
||||||
|
f = f.hi_ansi(fonts._hiAnsi);
|
||||||
|
}
|
||||||
|
if (fonts?._cs) {
|
||||||
|
f = f.cs(fonts._cs);
|
||||||
|
}
|
||||||
|
if (fonts?._eastAsia) {
|
||||||
|
f = f.east_asia(fonts._eastAsia);
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
|
||||||
buildRun(r: Run) {
|
buildRun(r: Run) {
|
||||||
let run = wasm.createRun();
|
let run = wasm.createRun();
|
||||||
r.children.forEach((child) => {
|
r.children.forEach((child) => {
|
||||||
|
@ -160,20 +194,8 @@ export class Docx {
|
||||||
run = run.spacing(r.property.spacing);
|
run = run.spacing(r.property.spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
let f = wasm.createRunFonts();
|
const fonts = this.buildRunFonts(r.property.fonts);
|
||||||
if (r.property.fonts?._ascii) {
|
run = run.fonts(fonts);
|
||||||
f = f.ascii(r.property.fonts._ascii);
|
|
||||||
}
|
|
||||||
if (r.property.fonts?._hiAnsi) {
|
|
||||||
f = f.hi_ansi(r.property.fonts._hiAnsi);
|
|
||||||
}
|
|
||||||
if (r.property.fonts?._cs) {
|
|
||||||
f = f.cs(r.property.fonts._cs);
|
|
||||||
}
|
|
||||||
if (r.property.fonts?._eastAsia) {
|
|
||||||
f = f.east_asia(r.property.fonts._eastAsia);
|
|
||||||
}
|
|
||||||
run = run.fonts(f);
|
|
||||||
|
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
@ -611,6 +633,25 @@ export class Docx {
|
||||||
docx = docx.page_size(w, h);
|
docx = docx.page_size(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.styles?.docDefaults) {
|
||||||
|
if (this.styles.docDefaults.runProperty?.fonts) {
|
||||||
|
const fonts = this.buildRunFonts(
|
||||||
|
this.styles.docDefaults.runProperty.fonts
|
||||||
|
);
|
||||||
|
docx = docx.default_fonts(fonts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.styles.docDefaults.runProperty?.size) {
|
||||||
|
docx = docx.default_size(this.styles.docDefaults.runProperty.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.styles.docDefaults.runProperty?.spacing) {
|
||||||
|
docx = docx.default_spacing(
|
||||||
|
this.styles.docDefaults.runProperty.spacing
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const buf = docx.build(this.hasNumberings);
|
const buf = docx.build(this.hasNumberings);
|
||||||
docx.free();
|
docx.free();
|
||||||
return buf;
|
return buf;
|
||||||
|
@ -631,6 +672,8 @@ export * from "./table-cell-borders";
|
||||||
export * from "./table-row";
|
export * from "./table-row";
|
||||||
export * from "./run";
|
export * from "./run";
|
||||||
export * from "./text";
|
export * from "./text";
|
||||||
|
export * from "./style";
|
||||||
|
export * from "./styles";
|
||||||
export * from "./comment";
|
export * from "./comment";
|
||||||
export * from "./comment-end";
|
export * from "./comment-end";
|
||||||
export * from "./numbering";
|
export * from "./numbering";
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { RunProperty } from "./run";
|
||||||
|
import { ParagraphProperty } from "./paragraph";
|
||||||
|
import { TableProperty } from "./table";
|
||||||
|
|
||||||
|
export type StyleType =
|
||||||
|
| "paragraph"
|
||||||
|
| "character"
|
||||||
|
| "numbering"
|
||||||
|
| "table"
|
||||||
|
| "unsupported";
|
||||||
|
|
||||||
|
export class Style {
|
||||||
|
_styleId: string;
|
||||||
|
_name: string;
|
||||||
|
_styleType: StyleType;
|
||||||
|
_runProperty: RunProperty;
|
||||||
|
_paragraphProperty: ParagraphProperty;
|
||||||
|
_tableProperty: TableProperty;
|
||||||
|
_basedOn: string | null;
|
||||||
|
|
||||||
|
constructor(id: string, type: StyleType) {
|
||||||
|
this._styleId = id;
|
||||||
|
this._styleType = type;
|
||||||
|
this._name = "";
|
||||||
|
this._runProperty = {};
|
||||||
|
this._paragraphProperty = { runProperty: {} };
|
||||||
|
this._tableProperty = {};
|
||||||
|
this._basedOn = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add setter
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { Style } from "./style";
|
||||||
|
import { DocDefaults } from "./doc-defaults";
|
||||||
|
import { RunFonts } from "./run";
|
||||||
|
|
||||||
|
export class Styles {
|
||||||
|
styles: Style[];
|
||||||
|
docDefaults = new DocDefaults();
|
||||||
|
|
||||||
|
defaultSize(size: number) {
|
||||||
|
this.docDefaults.size(size);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultFonts(fonts: RunFonts) {
|
||||||
|
this.docDefaults.fonts(fonts);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultSpacing(spacing: number) {
|
||||||
|
this.docDefaults.spacing(spacing);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
"tsc:web": "tsc -p tsconfig.web.json",
|
"tsc:web": "tsc -p tsconfig.web.json",
|
||||||
"tsc:node": "tsc -p tsconfig.node.json",
|
"tsc:node": "tsc -p tsconfig.node.json",
|
||||||
"tsc": "run-p tsc:*",
|
"tsc": "run-p tsc:*",
|
||||||
"test": "jest",
|
"test": "npm run build && tsc && jest",
|
||||||
"build": "run-s wasm-pack tsc",
|
"build": "run-s wasm-pack tsc",
|
||||||
"serve": "webpack-dev-server --open --config webpack.dev.js",
|
"serve": "webpack-dev-server --open --config webpack.dev.js",
|
||||||
"prepublishOnly": "npm run build"
|
"prepublishOnly": "npm run build"
|
||||||
|
|
|
@ -58,6 +58,21 @@ impl Docx {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn default_size(mut self, size: usize) -> Self {
|
||||||
|
self.0.styles = self.0.styles.default_size(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_spacing(mut self, spacing: i32) -> Self {
|
||||||
|
self.0.styles = self.0.styles.default_spacing(spacing);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_fonts(mut self, font: RunFonts) -> Self {
|
||||||
|
self.0.styles = self.0.styles.default_fonts(font.take());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build(&mut self, has_numberings: bool) -> Result<Vec<u8>, JsValue> {
|
pub fn build(&mut self, has_numberings: bool) -> Result<Vec<u8>, JsValue> {
|
||||||
let buf = Vec::new();
|
let buf = Vec::new();
|
||||||
let mut cur = std::io::Cursor::new(buf);
|
let mut cur = std::io::Cursor::new(buf);
|
||||||
|
|
|
@ -1902,8 +1902,8 @@ Object {
|
||||||
"italic": null,
|
"italic": null,
|
||||||
"italicCs": null,
|
"italicCs": null,
|
||||||
"spacing": null,
|
"spacing": null,
|
||||||
"sz": null,
|
"sz": 21,
|
||||||
"szCs": null,
|
"szCs": 21,
|
||||||
"underline": null,
|
"underline": null,
|
||||||
"vanish": null,
|
"vanish": null,
|
||||||
},
|
},
|
||||||
|
@ -4199,8 +4199,8 @@ Object {
|
||||||
"italic": null,
|
"italic": null,
|
||||||
"italicCs": null,
|
"italicCs": null,
|
||||||
"spacing": null,
|
"spacing": null,
|
||||||
"sz": null,
|
"sz": 21,
|
||||||
"szCs": null,
|
"szCs": 21,
|
||||||
"underline": null,
|
"underline": null,
|
||||||
"vanish": null,
|
"vanish": null,
|
||||||
},
|
},
|
||||||
|
@ -5460,8 +5460,8 @@ Object {
|
||||||
"italic": null,
|
"italic": null,
|
||||||
"italicCs": null,
|
"italicCs": null,
|
||||||
"spacing": null,
|
"spacing": null,
|
||||||
"sz": null,
|
"sz": 21,
|
||||||
"szCs": null,
|
"szCs": 21,
|
||||||
"underline": null,
|
"underline": null,
|
||||||
"vanish": null,
|
"vanish": null,
|
||||||
},
|
},
|
||||||
|
@ -5957,6 +5957,33 @@ Object {
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`writer should write default font 1`] = `
|
||||||
|
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
|
||||||
|
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
|
||||||
|
<Relationship Id=\\"rId1\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\\" Target=\\"styles.xml\\" />
|
||||||
|
<Relationship Id=\\"rId2\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable\\" Target=\\"fontTable.xml\\" />
|
||||||
|
<Relationship Id=\\"rId3\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings\\" Target=\\"settings.xml\\" />
|
||||||
|
<Relationship Id=\\"rId4\\" Type=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header\\" Target=\\"header1.xml\\" />
|
||||||
|
<Relationship Id=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
|
||||||
|
</Relationships>"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`writer should write default font 2`] = `
|
||||||
|
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
|
||||||
|
<w:document xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\" xmlns:w10=\\"urn:schemas-microsoft-com:office:word\\" xmlns:wp=\\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\\" xmlns:wps=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingShape\\" xmlns:wpg=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup\\" xmlns:mc=\\"http://schemas.openxmlformats.org/markup-compatibility/2006\\" xmlns:wp14=\\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\\" xmlns:w14=\\"http://schemas.microsoft.com/office/word/2010/wordml\\" xmlns:w15=\\"http://schemas.microsoft.com/office/word/2012/wordml\\" mc:Ignorable=\\"w14 wp14\\">
|
||||||
|
<w:body><w:p w14:paraId=\\"0000002e\\"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">Hello world!!!!</w:t></w:r></w:p><w:sectPr><w:pgSz w:w=\\"11906\\" w:h=\\"16838\\" /><w:pgMar w:top=\\"1985\\" w:right=\\"1701\\" w:bottom=\\"1701\\" w:left=\\"1701\\" w:header=\\"851\\" w:footer=\\"992\\" w:gutter=\\"0\\" /><w:headerReference w:type=\\"default\\" r:id=\\"rId4\\" /><w:cols w:space=\\"425\\" />
|
||||||
|
<w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" />
|
||||||
|
</w:sectPr></w:body>
|
||||||
|
</w:document>"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`writer should write default font 3`] = `
|
||||||
|
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\" standalone=\\"yes\\"?>
|
||||||
|
<w:numbering xmlns:r=\\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\\" xmlns:o=\\"urn:schemas-microsoft-com:office:office\\" xmlns:v=\\"urn:schemas-microsoft-com:vml\\" xmlns:w=\\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\\"><w:abstractNum w:abstractNumId=\\"1\\"><w:lvl w:ilvl=\\"0\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"%1.\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"420\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"1\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"(%2)\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"840\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"2\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimalEnclosedCircle\\" /><w:lvlText w:val=\\"%3\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"1260\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"3\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"%4.\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"1680\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"4\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"(%5)\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"2100\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"5\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimalEnclosedCircle\\" /><w:lvlText w:val=\\"%6\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"2520\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"6\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"%7.\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"2940\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"7\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimal\\" /><w:lvlText w:val=\\"(%8)\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"3360\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl><w:lvl w:ilvl=\\"8\\"><w:start w:val=\\"1\\" /><w:numFmt w:val=\\"decimalEnclosedCircle\\" /><w:lvlText w:val=\\"%9\\" /><w:lvlJc w:val=\\"left\\" /><w:pPr><w:rPr /><w:ind w:left=\\"3780\\" w:right=\\"0\\" w:hanging=\\"420\\" /></w:pPr><w:rPr /></w:lvl></w:abstractNum><w:num w:numId=\\"1\\">
|
||||||
|
<w:abstractNumId w:val=\\"1\\" />
|
||||||
|
</w:num></w:numbering>"
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`writer should write hello 1`] = `
|
exports[`writer should write hello 1`] = `
|
||||||
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
|
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
|
||||||
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
|
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const w = require("../dist/node");
|
const w = require("../dist/node");
|
||||||
const { readFileSync, writeFileSync } = require("fs");
|
const { readFileSync, writeFileSync } = require("fs");
|
||||||
const path = require("path");
|
|
||||||
const Zip = require("adm-zip");
|
const Zip = require("adm-zip");
|
||||||
|
|
||||||
describe("reader", () => {
|
describe("reader", () => {
|
||||||
|
@ -76,7 +75,26 @@ describe("writer", () => {
|
||||||
.addParagraph(p)
|
.addParagraph(p)
|
||||||
.pageMargin({ top: 1000, left: 2000 })
|
.pageMargin({ top: 1000, left: 2000 })
|
||||||
.build();
|
.build();
|
||||||
writeFileSync("aa.docx", buf);
|
const z = new Zip(Buffer.from(buf));
|
||||||
|
for (const e of z.getEntries()) {
|
||||||
|
if (e.entryName.match(/document.xml|numbering.xml/)) {
|
||||||
|
expect(z.readAsText(e)).toMatchSnapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("should write default font", () => {
|
||||||
|
const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!!!"));
|
||||||
|
const fonts = new w.RunFonts()
|
||||||
|
.eastAsia("Arial")
|
||||||
|
.ascii("Arial")
|
||||||
|
.hiAnsi("Arial");
|
||||||
|
const buf = new w.Docx()
|
||||||
|
.addParagraph(p)
|
||||||
|
.defaultSize(40)
|
||||||
|
.defaultFonts(fonts)
|
||||||
|
.build();
|
||||||
|
writeFileSync("default_font.docx", buf);
|
||||||
const z = new Zip(Buffer.from(buf));
|
const z = new Zip(Buffer.from(buf));
|
||||||
for (const e of z.getEntries()) {
|
for (const e of z.getEntries()) {
|
||||||
if (e.entryName.match(/document.xml|numbering.xml/)) {
|
if (e.entryName.match(/document.xml|numbering.xml/)) {
|
||||||
|
|
Loading…
Reference in New Issue