Support default fonts (#207)

* feat: support default font writer

* feat: Support default font by js

* fix: update snaps

* fix: update snaps
main
bokuweb 2020-12-14 15:01:23 +09:00 committed by GitHub
parent 1020f4bd04
commit 688632bca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 375 additions and 67 deletions

16
Cargo.lock generated
View File

@ -239,9 +239,9 @@ dependencies = [
[[package]]
name = "image"
version = "0.23.11"
version = "0.23.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f0a8345b33b082aedec2f4d7d4a926b845cee184cbe78b703413066564431b"
checksum = "7ce04077ead78e39ae8610ad26216aed811996b043d47beed5090db674f9e9b5"
dependencies = [
"bytemuck",
"byteorder",
@ -258,9 +258,9 @@ dependencies = [
[[package]]
name = "insta"
version = "1.1.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7e7528a20113cf7ca90eddfc2439c608188b6eafc0613964da2bd140c92acec"
checksum = "863bf97e7130bf788f29a99bc4073735af6b8ecc3da6a39c23b3a688d2d3109a"
dependencies = [
"console",
"difference",
@ -300,9 +300,9 @@ checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
[[package]]
name = "linked-hash-map"
version = "0.5.2"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
[[package]]
name = "log"
@ -530,9 +530,9 @@ dependencies = [
[[package]]
name = "serde_yaml"
version = "0.8.11"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
checksum = "f7baae0a99f1a324984bcdc5f0718384c1f69775f1c7eec8b859b71b443e3fd7"
dependencies = [
"dtoa",
"linked-hash-map",

View File

@ -21,7 +21,7 @@ path = "src/lib.rs"
[dependencies]
xml-rs = "0.8.3"
wasm-bindgen = "0.2.50"
wasm-bindgen = "0.2.69"
thiserror = "1.0"
zip = { version = "0.5.6", default-features = false, features = ["deflate"] }
serde = { version = "1.0", features = ["derive"] }
@ -30,4 +30,4 @@ image = "0.23.12"
[dev-dependencies]
pretty_assertions = "0.6.1"
insta = "1.1"
insta = "1.3"

View File

@ -1,9 +1,10 @@
use serde::Serialize;
use crate::documents::BuildXML;
use crate::xml_builder::*;
use crate::{documents::BuildXML, RunProperty};
use super::run_property_default::*;
use super::RunFonts;
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
@ -15,6 +16,26 @@ impl DocDefaults {
pub fn new() -> DocDefaults {
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 {

View File

@ -1,6 +1,6 @@
use serde::Serialize;
use super::RunProperty;
use super::*;
use crate::documents::BuildXML;
use crate::xml_builder::*;
@ -14,6 +14,26 @@ impl RunPropertyDefault {
pub fn new() -> RunPropertyDefault {
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 {

View File

@ -209,6 +209,21 @@ impl Docx {
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 {
self.update_comments();
let (image_ids, images) = self.create_images();

View File

@ -1,6 +1,6 @@
use serde::Serialize;
use super::{DocDefaults, Style};
use super::*;
use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
@ -21,6 +21,26 @@ impl Styles {
self.styles.push(style);
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 {

View File

@ -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),
_ => {}
}
}
}
}

View File

@ -4,6 +4,7 @@ mod attributes;
mod bookmark_end;
mod bookmark_start;
mod delete;
mod doc_defaults;
mod document;
mod document_rels;
mod drawing;

View File

@ -56,7 +56,6 @@ impl ElementReader for Run {
run = run.size(usize::from_str(&attributes[0].value)?)
}
XMLElement::Underline => {
dbg!(&attributes);
run = run.underline(&attributes[0].value.clone())
}
XMLElement::Italic => {

View File

@ -35,6 +35,8 @@ impl ElementReader for RunProperty {
rp = rp.spacing(v)
}
}
// TODO: Implement later
XMLElement::RunFonts => {}
XMLElement::Underline => rp = rp.underline(&attributes[0].value.clone()),
XMLElement::Italic => {
if !read_bool(&attributes) {
@ -43,7 +45,6 @@ impl ElementReader for RunProperty {
rp = rp.italic();
}
XMLElement::Vanish => rp = rp.vanish(),
// TODO: Add run fonts reader
_ => {}
}
}

View File

@ -17,10 +17,18 @@ impl FromXML for Styles {
attributes, name, ..
}) => {
let e = XMLElement::from_str(&name.local_name).unwrap();
if let XMLElement::Style = e {
let s = Style::read(&mut parser, &attributes)?;
styles = styles.add_style(s);
continue;
match e {
XMLElement::Style => {
let s = Style::read(&mut parser, &attributes)?;
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, .. }) => {

View File

@ -14,6 +14,7 @@ pub enum XMLElement {
RunProperty,
Color,
Underline,
RunFonts,
Size,
SizeCs,
Spacing,
@ -100,6 +101,8 @@ pub enum XMLElement {
TxbxContent,
Pict,
DocId,
DocDefaults,
RunPropertyDefault,
SectionProperty,
PageSize,
PageMargin,
@ -257,7 +260,10 @@ impl FromStr for XMLElement {
"docId" => Ok(XMLElement::DocId),
"sectPr" => Ok(XMLElement::SectionProperty),
"pgSz" => Ok(XMLElement::PageSize),
"rFonts" => Ok(XMLElement::RunFonts),
"pgMar" => Ok(XMLElement::PageMargin),
"docDefaults" => Ok(XMLElement::DocDefaults),
"rPrDefault" => Ok(XMLElement::RunPropertyDefault),
_ => 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

View File

@ -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;
}
}

View File

@ -5,7 +5,7 @@ import { DeleteText } from "./delete-text";
import { Table } from "./table";
import { TableCell } from "./table-cell";
import { BorderType } from "./table-cell-border";
import { Run } from "./run";
import { Run, RunFonts } from "./run";
import { Text } from "./text";
import { Tab } from "./tab";
import { Break } from "./break";
@ -16,6 +16,7 @@ import { Numbering } from "./numbering";
import { BookmarkStart } from "./bookmark-start";
import { BookmarkEnd } from "./bookmark-end";
import { Settings } from "./settings";
import { Styles } from "./styles";
import { SectionProperty, PageMargin } from "./section-property";
import { DocxJSON } from "./json";
@ -56,6 +57,7 @@ export class Docx {
numberings: Numbering[] = [];
settings: Settings = new Settings();
sectionProperty: SectionProperty = new SectionProperty();
styles = new Styles();
addParagraph(p: Paragraph) {
if (p.hasNumberings) {
@ -108,6 +110,38 @@ export class Docx {
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) {
let run = wasm.createRun();
r.children.forEach((child) => {
@ -160,20 +194,8 @@ export class Docx {
run = run.spacing(r.property.spacing);
}
let f = wasm.createRunFonts();
if (r.property.fonts?._ascii) {
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);
const fonts = this.buildRunFonts(r.property.fonts);
run = run.fonts(fonts);
return run;
}
@ -611,6 +633,25 @@ export class Docx {
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);
docx.free();
return buf;
@ -631,6 +672,8 @@ export * from "./table-cell-borders";
export * from "./table-row";
export * from "./run";
export * from "./text";
export * from "./style";
export * from "./styles";
export * from "./comment";
export * from "./comment-end";
export * from "./numbering";

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -13,7 +13,7 @@
"tsc:web": "tsc -p tsconfig.web.json",
"tsc:node": "tsc -p tsconfig.node.json",
"tsc": "run-p tsc:*",
"test": "jest",
"test": "npm run build && tsc && jest",
"build": "run-s wasm-pack tsc",
"serve": "webpack-dev-server --open --config webpack.dev.js",
"prepublishOnly": "npm run build"

View File

@ -58,6 +58,21 @@ impl Docx {
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> {
let buf = Vec::new();
let mut cur = std::io::Cursor::new(buf);

View File

@ -1902,8 +1902,8 @@ Object {
"italic": null,
"italicCs": null,
"spacing": null,
"sz": null,
"szCs": null,
"sz": 21,
"szCs": 21,
"underline": null,
"vanish": null,
},
@ -4199,8 +4199,8 @@ Object {
"italic": null,
"italicCs": null,
"spacing": null,
"sz": null,
"szCs": null,
"sz": 21,
"szCs": 21,
"underline": null,
"vanish": null,
},
@ -5460,8 +5460,8 @@ Object {
"italic": null,
"italicCs": null,
"spacing": null,
"sz": null,
"szCs": null,
"sz": 21,
"szCs": 21,
"underline": 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`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">

View File

@ -1,6 +1,5 @@
const w = require("../dist/node");
const { readFileSync, writeFileSync } = require("fs");
const path = require("path");
const Zip = require("adm-zip");
describe("reader", () => {
@ -76,7 +75,26 @@ describe("writer", () => {
.addParagraph(p)
.pageMargin({ top: 1000, left: 2000 })
.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));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {