Impl minimum ToC API for JS (#394)

* feat: Support dirty and disabled toc

* fix: js api

* feat: Add js minimum toc API

* fix:

* fix
main
bokuweb 2022-01-06 16:13:45 +09:00 committed by GitHub
parent c89783e8d8
commit 21386cd1a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 636 additions and 35 deletions

5
.gitignore vendored
View File

@ -8,7 +8,7 @@ node_modules
*.docx
!fixtures/**/*.docx
output/*.docx
output/*.json
output/**/*.json
output/*.xml
vrt/screenshot/actual
vrt/screenshot/diff
@ -16,5 +16,4 @@ vrt/report.html
reg.json
docx-core/tests/output/*.docx
docx-wasm/*.tgz
docx-core/tests/output/*.json
docx-core/tests/output/*.json

View File

@ -1,3 +1,4 @@
use wasm_bindgen::prelude::*;
use serde::Serialize;
use super::*;
@ -5,6 +6,7 @@ use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
#[wasm_bindgen]
#[derive(Serialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct TableCellProperty {

View File

@ -10,9 +10,10 @@ use crate::xml_builder::*;
pub struct TableOfContents {
pub instr: InstrToC,
pub items: Vec<TableOfContentsItem>,
// pub disable_auto_items: bool,
pub auto: bool,
pub dirty: bool,
pub alias: Option<String>,
pub page_ref_placeholder: Option<String>,
}
impl TableOfContents {
@ -45,10 +46,10 @@ impl TableOfContents {
self
}
// pub fn disable_auto_items(mut self) -> Self {
// self.disable_auto_items = true;
// self
// }
pub fn auto(mut self) -> Self {
self.auto = true;
self
}
pub fn dirty(mut self) -> Self {
self.dirty = true;
@ -88,6 +89,9 @@ impl BuildXML for TableOfContents {
let mut item = item.clone();
item.instr = self.instr.clone();
item.dirty = self.dirty;
if item.page_ref.is_none() {
item.page_ref = self.page_ref_placeholder.clone();
}
item
})
.collect();

View File

@ -1,3 +1,4 @@
use wasm_bindgen::prelude::*;
use serde::Serialize;
use super::*;
@ -5,6 +6,7 @@ use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
#[wasm_bindgen]
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TableProperty {

View File

@ -445,7 +445,7 @@ impl Docx {
}
for (i, toc) in tocs {
if toc.items.is_empty() {
if toc.items.is_empty() && toc.auto {
let children = update_document_by_toc(self.document.children, &self.styles, toc, i);
self.document.children = children;
}
@ -894,6 +894,16 @@ fn update_document_by_toc(
paragraph =
paragraph.wrap_by_bookmark(generate_bookmark_id(), &toc_key);
}
} else {
// If no heading range is specified, all heading levels used in the document are listed.
let toc_key = TocKey::generate();
items.push(
TableOfContentsItem::new()
.text(paragraph.raw_text())
.toc_key(&toc_key)
.level(*heading_level),
);
paragraph = paragraph.wrap_by_bookmark(generate_bookmark_id(), &toc_key);
}
if let Some((_min, _max)) = toc.instr.tc_field_level_range {

View File

@ -4,6 +4,7 @@ import { Delete } from "./delete";
import { Hyperlink } from "./hyperlink";
import { DeleteText } from "./delete-text";
import { Table } from "./table";
import { TableOfContents } from "./table-of-contents";
import { TableCell, toTextDirectionWasmType } from "./table-cell";
import { BorderType } from "./border";
import { Run, RunFonts } from "./run";
@ -18,6 +19,7 @@ import { BookmarkStart } from "./bookmark-start";
import { BookmarkEnd } from "./bookmark-end";
import { Settings } from "./settings";
import { DocProps } from "./doc-props";
import { Style } from "./style";
import { Styles } from "./styles";
import { WebExtension } from "./webextension";
import { Footer } from "./footer";
@ -75,7 +77,13 @@ const convertWidthType = (t: WidthType) => {
};
export class Docx {
children: (Paragraph | Table | BookmarkStart | BookmarkEnd)[] = [];
children: (
| Paragraph
| Table
| BookmarkStart
| BookmarkEnd
| TableOfContents
)[] = [];
hasNumberings = false;
abstractNumberings: AbstractNumbering[] = [];
numberings: Numbering[] = [];
@ -87,6 +95,16 @@ export class Docx {
customItems: { id: string; xml: string }[] = [];
styles = new Styles();
addTableOfContents(t: TableOfContents) {
this.children.push(t);
return this;
}
addStyle(s: Style) {
this.styles.styles.push(s);
return this;
}
addParagraph(p: Paragraph) {
if (p.hasNumberings) {
this.hasNumberings = true;
@ -876,6 +894,8 @@ export class Docx {
docx = docx.add_bookmark_start(child.id, child.name);
} else if (child instanceof BookmarkEnd) {
docx = docx.add_bookmark_end(child.id);
} else if (child instanceof TableOfContents) {
docx = docx.add_table_of_contents(child.buildWasmObject());
}
});
@ -1039,6 +1059,10 @@ export class Docx {
docx = docx.doc_grid(type, linePitch, charSpace);
}
for (const s of this.styles?.styles) {
docx = docx.add_style(s.buildWasmObject());
}
if (this.styles?.docDefaults) {
if (this.styles.docDefaults.runProperty?.fonts) {
const fonts = this.buildRunFonts(
@ -1126,6 +1150,8 @@ export * from "./table";
export * from "./table-cell";
export * from "./table-cell-border";
export * from "./table-cell-borders";
export * from "./table-of-contents";
export * from "./table-of-contents-item";
export * from "./table-row";
export * from "./run";
export * from "./text";

View File

@ -1,3 +1,5 @@
import * as wasm from "./pkg";
import { createDefaultTableCellMargins, TableProperty } from "./table";
import { RunProperty, createDefaultRunProperty } from "./run";
import { createDefaultParagraphProperty, ParagraphProperty } from "./paragraph";
@ -31,5 +33,33 @@ export class Style {
this._basedOn = null;
}
// TODO: Add setter
name = (n: string) => {
this._name = n;
return this;
};
buildStyleType = () => {
switch (this._styleType) {
case "character":
return wasm.StyleType.Character;
case "numbering":
return wasm.StyleType.Numbering;
case "paragraph":
return wasm.StyleType.Paragraph;
case "table":
return wasm.StyleType.Table;
}
return wasm.StyleType.Paragraph;
};
buildWasmObject = () => {
const styleType = this.buildStyleType();
let s = wasm.createStyle(this._styleId, styleType);
if (this._name) {
s = s.name(this._name);
}
return s;
};
}

View File

@ -3,7 +3,7 @@ import { DocDefaults } from "./doc-defaults";
import { RunFonts } from "./run";
export class Styles {
styles: Style[];
styles: Style[] = [];
docDefaults = new DocDefaults();
defaultSize(size: number) {

View File

@ -0,0 +1,49 @@
import * as wasm from "./pkg/docx_wasm";
export class TableOfContentsItem {
_text = "";
_tocKey = "";
_level = 1;
_pageRef = "";
text = (text: string) => {
this._text = text;
return this;
};
tocKey = (key: string) => {
this._tocKey = key;
return this;
};
level = (l: number) => {
this._level = l;
return this;
};
pageRef = (r: string) => {
this._pageRef = r;
return this;
};
buildWasmObject = () => {
let item = wasm.createTableOfContentsItem();
if (this._text) {
item = item.text(this._text);
}
if (this._tocKey) {
item = item.toc_key(this._tocKey);
}
if (this._level) {
item = item.level(this._level);
}
if (this._pageRef) {
item = item.page_ref(this._pageRef);
}
return item;
};
}

View File

@ -0,0 +1,84 @@
import * as wasm from "./pkg";
import { TableOfContentsItem } from "./table-of-contents-item";
export class TableOfContents {
_headingStylesRange: [number, number] | null = null;
_hyperlink = false;
_alias = "";
_auto = false;
_dirty = false;
_items: TableOfContentsItem[] = [];
_pageRefPlaceholder = "";
headingStylesRange = (r: [number, number]) => {
this._headingStylesRange = r;
return this;
};
hyperlink = () => {
this._hyperlink = true;
return this;
};
alias = (alias: string) => {
this._alias = alias;
return this;
};
pageRefPlaceholder = (placeholder: string) => {
this._pageRefPlaceholder = placeholder;
return this;
};
auto = () => {
this._auto = true;
return this;
};
dirty = () => {
this._dirty = true;
return this;
};
addItem = (item: TableOfContentsItem) => {
this._items.push(item);
return this;
};
buildWasmObject = () => {
let toc = wasm.createTableOfContents();
if (this._headingStylesRange) {
toc = toc.heading_styles_range(
this._headingStylesRange[0],
this._headingStylesRange[1]
);
}
if (this._hyperlink) {
toc = toc.hyperlink();
}
if (this._alias) {
toc = toc.alias(this._alias);
}
if (this._auto) {
toc = toc.auto();
}
if (this._dirty) {
toc = toc.dirty();
}
if (this._pageRefPlaceholder) {
toc = toc.page_ref_placeholder(this._pageRefPlaceholder);
}
for (const item of this._items) {
toc = toc.add_item(item.buildWasmObject());
}
return toc;
};
}

View File

@ -18,6 +18,11 @@ impl Docx {
self
}
pub fn add_table_of_contents(mut self, t: TableOfContents) -> Self {
self.0 = self.0.add_table_of_contents(t.take());
self
}
pub fn add_bookmark_start(mut self, id: usize, name: &str) -> Self {
self.0 = self.0.add_bookmark_start(id, name);
self
@ -118,6 +123,11 @@ impl Docx {
self
}
pub fn add_style(mut self, s: Style) -> Self {
self.0.styles = self.0.styles.add_style(s.take());
self
}
pub fn default_size(mut self, size: usize) -> Self {
self.0.styles = self.0.styles.default_size(size);
self

View File

@ -16,9 +16,12 @@ mod paragraph;
mod reader;
mod run;
mod run_fonts;
mod style;
mod table;
mod table_cell;
mod table_cell_border;
mod table_of_contents;
mod table_of_contents_item;
mod table_row;
mod web_extension;
@ -40,8 +43,11 @@ pub use paragraph::*;
pub use reader::*;
pub use run::*;
pub use run_fonts::*;
pub use style::*;
pub use table::*;
pub use table_cell::*;
pub use table_cell_border::*;
pub use table_of_contents::*;
pub use table_of_contents_item::*;
pub use table_row::*;
pub use web_extension::*;

View File

@ -0,0 +1,99 @@
use super::*;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct Style(docx_rs::Style);
#[wasm_bindgen(js_name = createStyle)]
pub fn create_style(style_id: &str, style_type: docx_rs::StyleType) -> Style {
Style(docx_rs::Style::new(style_id, style_type))
}
#[wasm_bindgen]
impl Style {
pub fn name(mut self, name: &str) -> Self {
self.0.name = docx_rs::Name::new(name);
self
}
pub fn based_on(mut self, base: &str) -> Self {
self.0.based_on = Some(docx_rs::BasedOn::new(base));
self
}
pub fn size(mut self, size: usize) -> Self {
self.0.run_property = self.0.run_property.size(size);
self
}
pub fn color(mut self, color: &str) -> Self {
self.0.run_property = self.0.run_property.color(color);
self
}
pub fn highlight(mut self, color: &str) -> Self {
self.0.run_property = self.0.run_property.highlight(color);
self
}
pub fn bold(mut self) -> Self {
self.0.run_property = self.0.run_property.bold();
self
}
pub fn italic(mut self) -> Self {
self.0.run_property = self.0.run_property.italic();
self
}
pub fn underline(mut self, line_type: &str) -> Self {
self.0.run_property = self.0.run_property.underline(line_type);
self
}
pub fn vanish(mut self) -> Self {
self.0.run_property = self.0.run_property.vanish();
self
}
pub fn align(mut self, alignment_type: docx_rs::AlignmentType) -> Self {
self.0.paragraph_property = self.0.paragraph_property.align(alignment_type);
self
}
pub fn indent(
mut self,
left: i32,
special_indent_kind: Option<docx_rs::SpecialIndentKind>,
special_indent_size: Option<i32>,
) -> Self {
let special_indent = create_special_indent(special_indent_kind, special_indent_size);
self.0.paragraph_property =
self.0
.paragraph_property
.indent(Some(left), special_indent, None, None);
self
}
pub fn outline_lvl(mut self, l: usize) -> Self {
self.0.paragraph_property = self.0.paragraph_property.outline_lvl(l);
self
}
pub fn table_property(mut self, p: docx_rs::TableProperty) -> Self {
self.0.table_property = p;
self
}
pub fn table_cell_property(mut self, p: docx_rs::TableCellProperty) -> Self {
self.0.table_cell_property = p;
self
}
}
impl Style {
pub fn take(self) -> docx_rs::Style {
self.0
}
}

View File

@ -0,0 +1,56 @@
use wasm_bindgen::prelude::*;
use super::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct TableOfContents(docx_rs::TableOfContents);
#[wasm_bindgen(js_name = createTableOfContents)]
pub fn create_table_of_contents() -> TableOfContents {
TableOfContents(docx_rs::TableOfContents::new())
}
impl TableOfContents {
pub fn take(self) -> docx_rs::TableOfContents {
self.0
}
}
#[wasm_bindgen]
impl TableOfContents {
pub fn heading_styles_range(mut self, start: usize, end: usize) -> Self {
self.0.instr = self.0.instr.heading_styles_range(start, end);
self
}
pub fn hyperlink(mut self) -> Self {
self.0.instr = self.0.instr.hyperlink();
self
}
pub fn alias(mut self, a: &str) -> Self {
self.0.alias = Some(a.into());
self
}
pub fn page_ref_placeholder(mut self, a: &str) -> Self {
self.0.page_ref_placeholder = Some(a.into());
self
}
pub fn add_item(mut self, t: TableOfContentsItem) -> Self {
self.0.items.push(t.take());
self
}
pub fn auto(mut self) -> Self {
self.0.auto = true;
self
}
pub fn dirty(mut self) -> Self {
self.0.dirty = true;
self
}
}

View File

@ -0,0 +1,39 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug)]
pub struct TableOfContentsItem(docx_rs::TableOfContentsItem);
#[wasm_bindgen(js_name = createTableOfContentsItem)]
pub fn create_table_of_contents_item() -> TableOfContentsItem {
TableOfContentsItem(docx_rs::TableOfContentsItem::new())
}
impl TableOfContentsItem {
pub fn take(self) -> docx_rs::TableOfContentsItem {
self.0
}
}
#[wasm_bindgen]
impl TableOfContentsItem {
pub fn text(mut self, a: &str) -> Self {
self.0.text = a.into();
self
}
pub fn toc_key(mut self, a: &str) -> Self {
self.0.toc_key = a.into();
self
}
pub fn level(mut self, l: usize) -> Self {
self.0.level = l;
self
}
pub fn page_ref(mut self, a: &str) -> Self {
self.0.page_ref = Some(a.into());
self
}
}

View File

@ -23628,6 +23628,66 @@ Object {
}
`;
exports[`writer should write ToC with items 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=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
</Relationships>"
`;
exports[`writer should write ToC with items 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:sdt><w:sdtPr><w:rPr /><w:alias w:val=\\"Table of contents\\" />
</w:sdtPr><w:sdtContent><w:sdt>
<w:sdtPr />
<w:sdtContent><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC1\\" /><w:tabs>
<w:tab w:val=\\"right\\" w:leader=\\"dot\\" w:pos=\\"80000\\" />
</w:tabs>
</w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>TOC</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /></w:r><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello!!</w:t></w:r><w:r><w:rPr /><w:tab /></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGEREF _Toc00000000 \\\\h</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">2</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p><w:p w14:paraId=\\"00000003\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC2\\" /><w:tabs>
<w:tab w:val=\\"right\\" w:leader=\\"dot\\" w:pos=\\"80000\\" />
</w:tabs>
</w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">World</w:t></w:r><w:r><w:rPr /><w:tab /></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGEREF _Toc00000001 \\\\h</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">3</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p><w:p w14:paraId=\\"00000004\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC2\\" /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p></w:sdtContent>
</w:sdt></w:sdtContent>
</w:sdt><w:p w14:paraId=\\"00000005\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading1\\" /><w:pageBreakBefore />
</w:pPr><w:bookmarkStart w:id=\\"1\\" w:name=\\"_Toc00000000\\" /><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">Hello!!</w:t></w:r><w:bookmarkEnd w:id=\\"1\\" /></w:p><w:p w14:paraId=\\"00000006\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading2\\" /><w:pageBreakBefore />
</w:pPr><w:bookmarkStart w:id=\\"2\\" w:name=\\"_Toc00000001\\" /><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">World</w:t></w:r><w:bookmarkEnd w:id=\\"2\\" /></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:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write auto items ToC 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=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
</Relationships>"
`;
exports[`writer should write auto items ToC 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:sdt><w:sdtPr><w:rPr /><w:alias w:val=\\"Table of contents\\" />
</w:sdtPr><w:sdtContent><w:sdt>
<w:sdtPr />
<w:sdtContent><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC1\\" /><w:tabs>
<w:tab w:val=\\"right\\" w:leader=\\"dot\\" w:pos=\\"80000\\" />
</w:tabs>
</w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>TOC</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /></w:r><w:r><w:rPr /><w:t xml:space=\\"preserve\\">Hello!!</w:t></w:r><w:r><w:rPr /><w:tab /></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGEREF _Toc00000000 \\\\h</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p><w:p w14:paraId=\\"00000003\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC2\\" /><w:tabs>
<w:tab w:val=\\"right\\" w:leader=\\"dot\\" w:pos=\\"80000\\" />
</w:tabs>
</w:pPr><w:r><w:rPr /><w:t xml:space=\\"preserve\\">World</w:t></w:r><w:r><w:rPr /><w:tab /></w:r><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"false\\" /><w:instrText>PAGEREF _Toc00000001 \\\\h</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /><w:t xml:space=\\"preserve\\">1</w:t><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p><w:p w14:paraId=\\"00000004\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"ToC2\\" /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p></w:sdtContent>
</w:sdt></w:sdtContent>
</w:sdt><w:p w14:paraId=\\"00000003\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading1\\" /><w:pageBreakBefore />
</w:pPr><w:bookmarkStart w:id=\\"1\\" w:name=\\"_Toc00000000\\" /><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">Hello!!</w:t></w:r><w:bookmarkEnd w:id=\\"1\\" /></w:p><w:p w14:paraId=\\"00000004\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading2\\" /><w:pageBreakBefore />
</w:pPr><w:bookmarkStart w:id=\\"2\\" w:name=\\"_Toc00000001\\" /><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">World</w:t></w:r><w:bookmarkEnd w:id=\\"2\\" /></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:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write cell shading 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">
@ -23753,6 +23813,27 @@ exports[`writer should write default font 3`] = `
</w:num></w:numbering>"
`;
exports[`writer should write dirty and disable auto items ToC 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=\\"rId5\\" Type=\\"http://schemas.microsoft.com/office/2011/relationships/commentsExtended\\" Target=\\"commentsExtended.xml\\" />
</Relationships>"
`;
exports[`writer should write dirty and disable auto items ToC 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:sdt><w:sdtPr><w:rPr /><w:alias w:val=\\"Table of contents\\" />
</w:sdtPr><w:sdtContent><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"begin\\" w:dirty=\\"true\\" /><w:instrText>TOC</w:instrText><w:fldChar w:fldCharType=\\"separate\\" w:dirty=\\"false\\" /></w:r></w:p><w:p w14:paraId=\\"00000002\\"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:fldChar w:fldCharType=\\"end\\" w:dirty=\\"false\\" /></w:r></w:p></w:sdtContent>
</w:sdt><w:p w14:paraId=\\"00000001\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading1\\" /><w:pageBreakBefore />
</w:pPr><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">Hello!!</w:t></w:r></w:p><w:p w14:paraId=\\"00000002\\"><w:pPr><w:rPr /><w:pStyle w:val=\\"Heading2\\" /><w:pageBreakBefore />
</w:pPr><w:r><w:rPr><w:rFonts /></w:rPr><w:t xml:space=\\"preserve\\">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:cols w:space=\\"425\\" /><w:docGrid w:type=\\"lines\\" w:linePitch=\\"360\\" /></w:sectPr></w:body>
</w:document>"
`;
exports[`writer should write doc grid 1`] = `
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>
<Relationships xmlns=\\"http://schemas.openxmlformats.org/package/2006/relationships\\">

View File

@ -18,14 +18,14 @@ describe("reader", () => {
test("should read tr2bl docx", () => {
const buffer = readFileSync("../fixtures/tr2bl/tr2bl.docx");
const json = w.readDocx(buffer);
writeFileSync("../output/tr2bl.json", JSON.stringify(json, null, 2));
writeFileSync("../output/js/tr2bl.json", JSON.stringify(json, null, 2));
expect(json).toMatchSnapshot();
});
test("should read custom docx", () => {
const buffer = readFileSync("../fixtures/custom/custom.docx");
const json = w.readDocx(buffer);
writeFileSync("../output/custom.json", JSON.stringify(json, null, 2));
writeFileSync("../output/js/custom.json", JSON.stringify(json, null, 2));
expect(json).toMatchSnapshot();
});
@ -123,7 +123,7 @@ describe("writer", () => {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
writeFileSync("../output/strike.docx", buffer);
writeFileSync("../output/js/strike.docx", buffer);
});
test("should write lvlOverride with level", () => {
@ -176,7 +176,7 @@ describe("writer", () => {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
writeFileSync("../output/nested_table.docx", buffer);
writeFileSync("../output/js/nested_table.docx", buffer);
});
test("should write tl2br and tr2bl cells", () => {
@ -207,7 +207,7 @@ describe("writer", () => {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
writeFileSync("../output/cell_borders.docx", buffer);
writeFileSync("../output/js/cell_borders.docx", buffer);
});
test("should write cell shading", () => {
@ -224,7 +224,7 @@ describe("writer", () => {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
writeFileSync("../output/cell_shading.docx", buffer);
writeFileSync("../output/js/cell_shading.docx", buffer);
});
test("should write page margin", () => {
@ -252,7 +252,7 @@ describe("writer", () => {
.defaultSize(40)
.defaultFonts(fonts)
.build();
writeFileSync("../output/default_font.docx", buffer);
writeFileSync("../output/js/default_font.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -264,7 +264,7 @@ describe("writer", () => {
test("should write doc vars", () => {
const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!!!"));
const buffer = new w.Docx().addParagraph(p).addDocVar("foo", "bar").build();
writeFileSync("../output/doc_vars.docx", buffer);
writeFileSync("../output/js/doc_vars.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -276,7 +276,7 @@ describe("writer", () => {
test("should write doc grid", () => {
const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!!!"));
const buffer = new w.Docx().addParagraph(p).docGrid("default", 360).build();
writeFileSync("../output/doc_grid.docx", buffer);
writeFileSync("../output/js/doc_grid.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -297,7 +297,7 @@ describe("writer", () => {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
writeFileSync("../output/table_layout.docx", buffer);
writeFileSync("../output/js/table_layout.docx", buffer);
});
test("should write text border", () => {
@ -305,7 +305,7 @@ describe("writer", () => {
.addRun(new w.Run().addText("Hello "))
.addRun(new w.Run().addText("World!").textBorder("single", 4, 0, "auto"));
const buffer = new w.Docx().addParagraph(p).build();
writeFileSync("../output/text_border.docx", buffer);
writeFileSync("../output/js/text_border.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -321,7 +321,7 @@ describe("writer", () => {
.pageSize(16838, 11906)
.pageOrientation("landscape")
.build();
writeFileSync("../output/page_orientation.docx", buffer);
writeFileSync("../output/js/page_orientation.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -336,7 +336,7 @@ describe("writer", () => {
.addParagraph(p)
.customProperty("hello", '{"world": 0}')
.build();
writeFileSync("../output/custom.docx", buffer);
writeFileSync("../output/js/custom.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml|custom.xml/)) {
@ -360,7 +360,7 @@ describe("writer", () => {
).property("hello", JSON.stringify({ hello: "world" }))
)
.build();
writeFileSync("../output/webextension.docx", buffer);
writeFileSync("../output/js/webextension.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/webextension1.xml|_rels|taskpanes.xml.rel/)) {
@ -378,7 +378,7 @@ describe("writer", () => {
'<root xmlns="https://example.com"><item name="Cheap Item" price="$193.95"/><item name="Expensive Item" price="$931.88"/></root>'
)
.build();
writeFileSync("../output/custom-item.docx", buffer);
writeFileSync("../output/js/custom-item.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/item1.xml|_rels|item1Props/)) {
@ -394,7 +394,7 @@ describe("writer", () => {
new w.LineSpacing().before(100).after(0).line(100).afterLines(400)
);
const buffer = new w.Docx().addParagraph(p).build();
writeFileSync("../output/line_spacing.docx", buffer);
writeFileSync("../output/js/line_spacing.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|numbering.xml/)) {
@ -408,7 +408,7 @@ describe("writer", () => {
const p2 = new w.Paragraph().addRun(new w.Run().addText("World "));
const footer = new w.Footer().addParagraph(p1);
const buffer = new w.Docx().footer(footer).addParagraph(p2).build();
writeFileSync("../output/footer.docx", buffer);
writeFileSync("../output/js/footer.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|footer1.xml/)) {
@ -422,7 +422,7 @@ describe("writer", () => {
const p2 = new w.Paragraph().addRun(new w.Run().addText("World "));
const header = new w.Header().addParagraph(p1);
const buffer = new w.Docx().header(header).addParagraph(p2).build();
writeFileSync("../output/header.docx", buffer);
writeFileSync("../output/js/header.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|footer1.xml/)) {
@ -438,7 +438,7 @@ describe("writer", () => {
);
const header = new w.Header().addTable(table);
const buffer = new w.Docx().firstHeader(header).build();
writeFileSync("../output/first_header_with_table.docx", buffer);
writeFileSync("../output/js/first_header_with_table.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|header[1-9].xml/)) {
@ -454,7 +454,7 @@ describe("writer", () => {
);
const footer = new w.Footer().addTable(table);
const buffer = new w.Docx().evenFooter(footer).build();
writeFileSync("../output/even_footer_with_table.docx", buffer);
writeFileSync("../output/js/even_footer_with_table.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml|footer[1-9].xml/)) {
@ -474,7 +474,113 @@ describe("writer", () => {
.addBookmarkEnd(1);
const buffer = new w.Docx().addParagraph(p1).addParagraph(p2).build();
writeFileSync("../output/hyperlink.docx", buffer);
writeFileSync("../output/js/hyperlink.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
test("should write dirty and disable auto items ToC", () => {
const p1 = new w.Paragraph()
.addRun(new w.Run().addText("Hello!!"))
.pageBreakBefore(true)
.style("Heading1");
const style1 = new w.Style("Heading1", "paragraph").name("Heading 1");
const p2 = new w.Paragraph()
.addRun(new w.Run().addText("World"))
.pageBreakBefore(true)
.style("Heading2");
const style2 = new w.Style("Heading2", "paragraph").name("Heading 2");
const buffer = new w.Docx()
.addTableOfContents(
new w.TableOfContents().alias("Table of contents").dirty()
)
.addParagraph(p1)
.addParagraph(p2)
.addStyle(style1)
.addStyle(style2)
.build();
writeFileSync("../output/js/toc_dirty_and_disable_auto_items.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
test("should write auto items ToC", () => {
const p1 = new w.Paragraph()
.addRun(new w.Run().addText("Hello!!"))
.pageBreakBefore(true)
.style("Heading1");
const style1 = new w.Style("Heading1", "paragraph").name("Heading 1");
const p2 = new w.Paragraph()
.addRun(new w.Run().addText("World"))
.pageBreakBefore(true)
.style("Heading2");
const style2 = new w.Style("Heading2", "paragraph").name("Heading 2");
const buffer = new w.Docx()
.addTableOfContents(
new w.TableOfContents().alias("Table of contents").auto()
)
.addParagraph(p1)
.addParagraph(p2)
.addStyle(style1)
.addStyle(style2)
.build();
writeFileSync("../output/js/toc_auto_items.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {
expect(z.readAsText(e)).toMatchSnapshot();
}
}
});
test("should write ToC with items", () => {
const p1 = new w.Paragraph()
.addBookmarkStart(1, "_Toc00000000")
.addRun(new w.Run().addText("Hello!!"))
.addBookmarkEnd(1)
.pageBreakBefore(true)
.style("Heading1");
const style1 = new w.Style("Heading1", "paragraph").name("Heading 1");
const p2 = new w.Paragraph()
.addBookmarkStart(2, "_Toc00000001")
.addRun(new w.Run().addText("World"))
.addBookmarkEnd(2)
.pageBreakBefore(true)
.style("Heading2");
const style2 = new w.Style("Heading2", "paragraph").name("Heading 2");
const buffer = new w.Docx()
.addTableOfContents(
new w.TableOfContents()
.alias("Table of contents")
.addItem(
new w.TableOfContentsItem()
.text("Hello!!")
.level(1)
.pageRef("2")
.tocKey("_Toc00000000")
)
.addItem(
new w.TableOfContentsItem()
.text("World")
.level(2)
.pageRef("3")
.tocKey("_Toc00000001")
)
)
.addParagraph(p1)
.addParagraph(p2)
.addStyle(style1)
.addStyle(style2)
.build();
writeFileSync("../output/js/toc_with_items.docx", buffer);
const z = new Zip(Buffer.from(buffer));
for (const e of z.getEntries()) {
if (e.entryName.match(/document.xml/)) {

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/custom-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" />

0
output/js/.keep 100644
View File