js.documents 7.10.4 → 7.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/edit/docx/content.cjs +32 -4
- package/dist/edit/docx/content.js +32 -4
- package/dist/edit/docx/editor.cjs +10 -0
- package/dist/edit/docx/editor.d.cts +2 -0
- package/dist/edit/docx/editor.d.ts +2 -0
- package/dist/edit/docx/editor.js +10 -0
- package/dist/edit/odt/content.cjs +29 -4
- package/dist/edit/odt/content.js +29 -4
- package/dist/edit/odt/editor.cjs +23 -0
- package/dist/edit/odt/editor.d.cts +2 -0
- package/dist/edit/odt/editor.d.ts +2 -0
- package/dist/edit/odt/editor.js +23 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -270,7 +270,7 @@ const pdfBytes = docxToPdf(docxBytes, {
|
|
|
270
270
|
|
|
271
271
|
The tree and the flat `ContentDocument` are one format in two encodings, related by three laws (stated on [document-schema.js#20](https://github.com/ExaDev/document-schema.js/issues/20), proven over this package's real corpus by the bijection suite in `src/convert/bijection.test.ts`): (i) `flattenTree(assembleTree(c))` reproduces `c` exactly, up to one declared normalisation (a present-but-empty sheet `embeddedObjects` array normalises to the field absent); (ii) effective-property equality holds universally — a factored and an unfactored serialisation of one document resolve to the same properties; (iii) minting is idempotent — factoring a second time produces the identical styles table.
|
|
272
272
|
|
|
273
|
-
Three flat-form signals drive the grouping, and all three are reproduced exactly on the way back: `headingLevel`, `list.level`, and — since document-schema.js 4.2.0 — the `constructStart`/`constructEnd` block pair that delimits a fidelity construct (a docx SDT, an ODF field, a tracked-change span, a bookmark, a hyperlink region, a division). `decompose` promotes each marker pair to a construct group carrying the `ConstructDescriptor` and holding the delimited region as its children, decomposed on its own; `flattenTree` writes the pair back around that region. A construct is a semantic wrapper rather than a container, so it neither disturbs the enclosing heading/list nesting it sits inside nor resets the style chain resolving onto it — content inside a construct still inherits the ambient heading's or section's factored properties, exactly as if the construct were not there. Markers must pair up within one container's block flow: an unmatched `constructEnd`, or a `constructStart` a container never closes, throws document-schema.js's `ConstructMarkerImbalanceError` (carrying its `ConstructMarkerImbalance` payload, so the offending block index is available without parsing the message) rather than being repaired into a plausible tree. The format codecs
|
|
273
|
+
Three flat-form signals drive the grouping, and all three are reproduced exactly on the way back: `headingLevel`, `list.level`, and — since document-schema.js 4.2.0 — the `constructStart`/`constructEnd` block pair that delimits a fidelity construct (a docx SDT, an ODF field, a tracked-change span, a bookmark, a hyperlink region, a division). `decompose` promotes each marker pair to a construct group carrying the `ConstructDescriptor` and holding the delimited region as its children, decomposed on its own; `flattenTree` writes the pair back around that region. A construct is a semantic wrapper rather than a container, so it neither disturbs the enclosing heading/list nesting it sits inside nor resets the style chain resolving onto it — content inside a construct still inherits the ambient heading's or section's factored properties, exactly as if the construct were not there. Markers must pair up within one container's block flow: an unmatched `constructEnd`, or a `constructStart` a container never closes, throws document-schema.js's `ConstructMarkerImbalanceError` (carrying its `ConstructMarkerImbalance` payload, so the offending block index is available without parsing the message) rather than being repaired into a plausible tree. The format codecs emit and consume these markers on both sides today — ooxml.js's docx pair (SDTs, bookmarks, tracked changes, block-scoped fields), odf.js's odt reader for divisions, index wrappers, and cross-paragraph bookmarks with its writer covering the construct kinds it models and refusing the rest by name, markdown-codec, rtf-codec, and epub-codec in both directions, and this package's own PDF reconstruction emitting division and anchor pairs — so the marker machinery has real producers and consumers, not just the boundary transform. Reaching further than the codecs is still a mixed picture, not a blanket guarantee: `buildMarkdownText` passes markers through to markdown-codec's own bracket-resolving writer, which renders each construct it has a markdown spelling for (a footnote definition, a blockquote division, a titled image's link wrapper) and renders the rest transparently with a diagnostic — markdown-codec's own read side emits those pairs, so this package's editor and conversion round trips depend on it; building docx bytes from marker-carrying flat content writes a bookmark anchor's pair as real `w:bookmarkStart`/`w:bookmarkEnd` around the blocks it spans, and the odt builder does the same through `text:bookmark-start`/`-end` — the one construct family expressible append-only in either format's body flow — while the wrapper-shaped kinds (an SDT, a tracked change, a division) are dropped rather than written, since neither editor model has a surface for them; and the layout engines (`convertWordprocessingToLayout`, `convertShape`) silently skip a marker block during pagination — harmless there, since a marker carries no content of its own to render.
|
|
274
274
|
|
|
275
275
|
`assembleTree` is the one constructor behind every construction site — decompose, then `factorStyles`, the minting pass that hoists property tuples occurring two or more times onto a group-wrapper ref plus a `styles` table entry (deterministic order; `frames`/`sourcePath`/`styleId` are per-node facts and never factor). The transform belongs to `document-schema.js`, which owns both encodings and publishes `assembleTree`, `decompose`, `flattenTree`, `factorStyles`, `ConstructMarkerImbalanceError`, and the `TreeChildren` type for any caller composing its own boundary — import them from there, not from this package. documents.js consumes that transform at its own boundary and re-exports none of it; the readers, builders, layout engines, and editors here keep producing and consuming the flat form, so the tree exists only where a `DocumentTree` is constructed or consumed:
|
|
276
276
|
|
|
@@ -13,6 +13,31 @@ const require_edit_docx_numbering = require("./numbering.cjs");
|
|
|
13
13
|
let ooxml_js = require("ooxml.js");
|
|
14
14
|
let document_schema_js = require("document-schema.js");
|
|
15
15
|
//#region src/edit/docx/content.ts
|
|
16
|
+
var ConstructMarkerState = class {
|
|
17
|
+
nextBookmarkId = 1;
|
|
18
|
+
open = [];
|
|
19
|
+
openConstruct(body, marker) {
|
|
20
|
+
const detail = marker.descriptor;
|
|
21
|
+
if (detail.kind === "anchor" && detail.anchorType === "bookmark") {
|
|
22
|
+
const id = this.nextBookmarkId;
|
|
23
|
+
this.nextBookmarkId += 1;
|
|
24
|
+
this.open.push({
|
|
25
|
+
isBookmark: true,
|
|
26
|
+
id
|
|
27
|
+
});
|
|
28
|
+
body.appendBookmarkStart(id, detail.name);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.open.push({
|
|
32
|
+
isBookmark: false,
|
|
33
|
+
id: -1
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
closeConstruct(body) {
|
|
37
|
+
const entry = this.open.pop();
|
|
38
|
+
if (entry?.isBookmark) body.appendBookmarkEnd(entry.id);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
16
41
|
function buildDocxPackage(content, options) {
|
|
17
42
|
if (content.kind !== "wordprocessing") throw new Error("buildDocxPackage requires a wordprocessing ContentDocument");
|
|
18
43
|
const clock = options?.clock ?? require_ports_clock.systemClock;
|
|
@@ -49,12 +74,13 @@ function buildDocxPackage(content, options) {
|
|
|
49
74
|
});
|
|
50
75
|
}
|
|
51
76
|
const editor = new require_edit_docx_editor.DocxEditor(pkg);
|
|
77
|
+
const markers = new ConstructMarkerState();
|
|
52
78
|
(numIdLevels.size > 0 ? content.sections.map((section) => ({
|
|
53
79
|
...section,
|
|
54
80
|
blocks: remapListNumIds(section.blocks, remap)
|
|
55
81
|
})) : content.sections).forEach((section, sectionIndex) => {
|
|
56
82
|
if (sectionIndex > 0) editor.body.appendPageBreak();
|
|
57
|
-
appendBlocks(editor.body, section.blocks, options);
|
|
83
|
+
appendBlocks(editor.body, section.blocks, options, markers);
|
|
58
84
|
});
|
|
59
85
|
return editor.toPackage();
|
|
60
86
|
}
|
|
@@ -97,7 +123,7 @@ function remapListNumIds(blocks, numIdMap) {
|
|
|
97
123
|
return block;
|
|
98
124
|
});
|
|
99
125
|
}
|
|
100
|
-
function appendBlocks(body, blocks, options) {
|
|
126
|
+
function appendBlocks(body, blocks, options, markers) {
|
|
101
127
|
let index = 0;
|
|
102
128
|
while (index < blocks.length) {
|
|
103
129
|
const block = blocks[index];
|
|
@@ -118,7 +144,7 @@ function appendBlocks(body, blocks, options) {
|
|
|
118
144
|
index += 2;
|
|
119
145
|
continue;
|
|
120
146
|
}
|
|
121
|
-
if (block !== void 0) appendBlock(body, block, options);
|
|
147
|
+
if (block !== void 0) appendBlock(body, block, options, markers);
|
|
122
148
|
index += 1;
|
|
123
149
|
}
|
|
124
150
|
}
|
|
@@ -202,7 +228,7 @@ function appendTable(body, block) {
|
|
|
202
228
|
function appendCellBlock(cell, block) {
|
|
203
229
|
if (block.kind === "paragraph") populateParagraph(cell.appendParagraph(), block);
|
|
204
230
|
}
|
|
205
|
-
function appendBlock(body, block, options) {
|
|
231
|
+
function appendBlock(body, block, options, markers) {
|
|
206
232
|
if (block.kind === "paragraph") populateParagraph(body.appendParagraph(), block);
|
|
207
233
|
else if (block.kind === "image") {
|
|
208
234
|
const paragraph = body.appendParagraph();
|
|
@@ -217,6 +243,8 @@ function appendBlock(body, block, options) {
|
|
|
217
243
|
} else if (block.kind === "pageBreak") body.appendPageBreak();
|
|
218
244
|
else if (block.kind === "table") appendTable(body, block);
|
|
219
245
|
else if (block.kind === "embeddedObject") appendEmbeddedObject(body, block, options);
|
|
246
|
+
else if (block.kind === "constructStart") markers.openConstruct(body, block);
|
|
247
|
+
else markers.closeConstruct(body);
|
|
220
248
|
}
|
|
221
249
|
function appendEmbeddedObject(body, block, options) {
|
|
222
250
|
if (require_model_embedded_drawing.drawingOfBlock(block) !== void 0) {
|
|
@@ -12,6 +12,31 @@ import { NUMBERING_CONTENT_TYPE, NUMBERING_PART_PATH, NUMBERING_REL_TYPE, buildN
|
|
|
12
12
|
import { base64ToBytes } from "ooxml.js";
|
|
13
13
|
import { resolveCellFillColor } from "document-schema.js";
|
|
14
14
|
//#region src/edit/docx/content.ts
|
|
15
|
+
var ConstructMarkerState = class {
|
|
16
|
+
nextBookmarkId = 1;
|
|
17
|
+
open = [];
|
|
18
|
+
openConstruct(body, marker) {
|
|
19
|
+
const detail = marker.descriptor;
|
|
20
|
+
if (detail.kind === "anchor" && detail.anchorType === "bookmark") {
|
|
21
|
+
const id = this.nextBookmarkId;
|
|
22
|
+
this.nextBookmarkId += 1;
|
|
23
|
+
this.open.push({
|
|
24
|
+
isBookmark: true,
|
|
25
|
+
id
|
|
26
|
+
});
|
|
27
|
+
body.appendBookmarkStart(id, detail.name);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.open.push({
|
|
31
|
+
isBookmark: false,
|
|
32
|
+
id: -1
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
closeConstruct(body) {
|
|
36
|
+
const entry = this.open.pop();
|
|
37
|
+
if (entry?.isBookmark) body.appendBookmarkEnd(entry.id);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
15
40
|
function buildDocxPackage(content, options) {
|
|
16
41
|
if (content.kind !== "wordprocessing") throw new Error("buildDocxPackage requires a wordprocessing ContentDocument");
|
|
17
42
|
const clock = options?.clock ?? systemClock;
|
|
@@ -48,12 +73,13 @@ function buildDocxPackage(content, options) {
|
|
|
48
73
|
});
|
|
49
74
|
}
|
|
50
75
|
const editor = new DocxEditor(pkg);
|
|
76
|
+
const markers = new ConstructMarkerState();
|
|
51
77
|
(numIdLevels.size > 0 ? content.sections.map((section) => ({
|
|
52
78
|
...section,
|
|
53
79
|
blocks: remapListNumIds(section.blocks, remap)
|
|
54
80
|
})) : content.sections).forEach((section, sectionIndex) => {
|
|
55
81
|
if (sectionIndex > 0) editor.body.appendPageBreak();
|
|
56
|
-
appendBlocks(editor.body, section.blocks, options);
|
|
82
|
+
appendBlocks(editor.body, section.blocks, options, markers);
|
|
57
83
|
});
|
|
58
84
|
return editor.toPackage();
|
|
59
85
|
}
|
|
@@ -96,7 +122,7 @@ function remapListNumIds(blocks, numIdMap) {
|
|
|
96
122
|
return block;
|
|
97
123
|
});
|
|
98
124
|
}
|
|
99
|
-
function appendBlocks(body, blocks, options) {
|
|
125
|
+
function appendBlocks(body, blocks, options, markers) {
|
|
100
126
|
let index = 0;
|
|
101
127
|
while (index < blocks.length) {
|
|
102
128
|
const block = blocks[index];
|
|
@@ -117,7 +143,7 @@ function appendBlocks(body, blocks, options) {
|
|
|
117
143
|
index += 2;
|
|
118
144
|
continue;
|
|
119
145
|
}
|
|
120
|
-
if (block !== void 0) appendBlock(body, block, options);
|
|
146
|
+
if (block !== void 0) appendBlock(body, block, options, markers);
|
|
121
147
|
index += 1;
|
|
122
148
|
}
|
|
123
149
|
}
|
|
@@ -201,7 +227,7 @@ function appendTable(body, block) {
|
|
|
201
227
|
function appendCellBlock(cell, block) {
|
|
202
228
|
if (block.kind === "paragraph") populateParagraph(cell.appendParagraph(), block);
|
|
203
229
|
}
|
|
204
|
-
function appendBlock(body, block, options) {
|
|
230
|
+
function appendBlock(body, block, options, markers) {
|
|
205
231
|
if (block.kind === "paragraph") populateParagraph(body.appendParagraph(), block);
|
|
206
232
|
else if (block.kind === "image") {
|
|
207
233
|
const paragraph = body.appendParagraph();
|
|
@@ -216,6 +242,8 @@ function appendBlock(body, block, options) {
|
|
|
216
242
|
} else if (block.kind === "pageBreak") body.appendPageBreak();
|
|
217
243
|
else if (block.kind === "table") appendTable(body, block);
|
|
218
244
|
else if (block.kind === "embeddedObject") appendEmbeddedObject(body, block, options);
|
|
245
|
+
else if (block.kind === "constructStart") markers.openConstruct(body, block);
|
|
246
|
+
else markers.closeConstruct(body);
|
|
219
247
|
}
|
|
220
248
|
function appendEmbeddedObject(body, block, options) {
|
|
221
249
|
if (drawingOfBlock(block) !== void 0) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_xml_entities = require("../../xml/entities.cjs");
|
|
2
3
|
const require_xml_fragment = require("../../xml/fragment.cjs");
|
|
3
4
|
const require_metadata_core_patch = require("../../metadata/core-patch.cjs");
|
|
4
5
|
const require_model_metadata = require("../../model/metadata.cjs");
|
|
@@ -61,6 +62,15 @@ var DocxBodyImpl = class {
|
|
|
61
62
|
const paragraph = require_xml_fragment.el("w:p", {}, [run]);
|
|
62
63
|
this.body.children.splice(bodyInsertionPoint(this.body), 0, paragraph);
|
|
63
64
|
}
|
|
65
|
+
appendBookmarkStart(id, name) {
|
|
66
|
+
this.body.children.splice(bodyInsertionPoint(this.body), 0, require_xml_fragment.el("w:bookmarkStart", {
|
|
67
|
+
"w:id": String(id),
|
|
68
|
+
"w:name": require_xml_entities.encodeXmlText(name)
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
appendBookmarkEnd(id) {
|
|
72
|
+
this.body.children.splice(bodyInsertionPoint(this.body), 0, require_xml_fragment.el("w:bookmarkEnd", { "w:id": String(id) }));
|
|
73
|
+
}
|
|
64
74
|
};
|
|
65
75
|
var DocxEditor = class {
|
|
66
76
|
body;
|
|
@@ -9,6 +9,8 @@ interface DocxBody {
|
|
|
9
9
|
appendParagraph(init?: ParagraphInit): DocxParagraph;
|
|
10
10
|
appendTable(init: TableInit): DocxTable;
|
|
11
11
|
appendPageBreak(): void;
|
|
12
|
+
appendBookmarkStart(id: number, name: string): void;
|
|
13
|
+
appendBookmarkEnd(id: number): void;
|
|
12
14
|
}
|
|
13
15
|
declare class DocxEditor {
|
|
14
16
|
readonly body: DocxBody;
|
|
@@ -9,6 +9,8 @@ interface DocxBody {
|
|
|
9
9
|
appendParagraph(init?: ParagraphInit): DocxParagraph;
|
|
10
10
|
appendTable(init: TableInit): DocxTable;
|
|
11
11
|
appendPageBreak(): void;
|
|
12
|
+
appendBookmarkStart(id: number, name: string): void;
|
|
13
|
+
appendBookmarkEnd(id: number): void;
|
|
12
14
|
}
|
|
13
15
|
declare class DocxEditor {
|
|
14
16
|
readonly body: DocxBody;
|
package/dist/edit/docx/editor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encodeXmlText } from "../../xml/entities.js";
|
|
1
2
|
import { el } from "../../xml/fragment.js";
|
|
2
3
|
import { patchOoxmlCorePropertiesOnPackage } from "../../metadata/core-patch.js";
|
|
3
4
|
import { resolveMetadataTimestamps } from "../../model/metadata.js";
|
|
@@ -60,6 +61,15 @@ var DocxBodyImpl = class {
|
|
|
60
61
|
const paragraph = el("w:p", {}, [run]);
|
|
61
62
|
this.body.children.splice(bodyInsertionPoint(this.body), 0, paragraph);
|
|
62
63
|
}
|
|
64
|
+
appendBookmarkStart(id, name) {
|
|
65
|
+
this.body.children.splice(bodyInsertionPoint(this.body), 0, el("w:bookmarkStart", {
|
|
66
|
+
"w:id": String(id),
|
|
67
|
+
"w:name": encodeXmlText(name)
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
appendBookmarkEnd(id) {
|
|
71
|
+
this.body.children.splice(bodyInsertionPoint(this.body), 0, el("w:bookmarkEnd", { "w:id": String(id) }));
|
|
72
|
+
}
|
|
63
73
|
};
|
|
64
74
|
var DocxEditor = class {
|
|
65
75
|
body;
|
|
@@ -14,9 +14,10 @@ function buildOdtPackage(content, options) {
|
|
|
14
14
|
const clock = options?.clock ?? require_ports_clock.systemClock;
|
|
15
15
|
const metadata = require_model_metadata.resolveMetadataTimestamps(content.metadata, clock);
|
|
16
16
|
const editor = new require_edit_odt_editor.OdtEditor(require_edit_odt_scaffold.createEmptyOdtPackage({ metadata }));
|
|
17
|
+
const markers = new ConstructMarkerState();
|
|
17
18
|
content.sections.forEach((section, sectionIndex) => {
|
|
18
19
|
if (sectionIndex > 0) editor.body.appendPageBreak();
|
|
19
|
-
appendBlocks(editor.body, section.blocks);
|
|
20
|
+
appendBlocks(editor.body, section.blocks, markers);
|
|
20
21
|
});
|
|
21
22
|
return editor.toPackage();
|
|
22
23
|
}
|
|
@@ -36,7 +37,7 @@ function appendMergedImageParagraph(body, paragraphBlock, imageBlock) {
|
|
|
36
37
|
altText: imageBlock.altText
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
|
-
function appendBlocks(body, blocks) {
|
|
40
|
+
function appendBlocks(body, blocks, markers) {
|
|
40
41
|
let i = 0;
|
|
41
42
|
while (i < blocks.length) {
|
|
42
43
|
const block = blocks[i];
|
|
@@ -61,7 +62,7 @@ function appendBlocks(body, blocks) {
|
|
|
61
62
|
appendListRun(body, run);
|
|
62
63
|
continue;
|
|
63
64
|
}
|
|
64
|
-
appendBlock(body, block);
|
|
65
|
+
appendBlock(body, block, markers);
|
|
65
66
|
i++;
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -187,7 +188,29 @@ function appendCellBlock(cell, block) {
|
|
|
187
188
|
altText: block.altText
|
|
188
189
|
});
|
|
189
190
|
}
|
|
190
|
-
|
|
191
|
+
var ConstructMarkerState = class {
|
|
192
|
+
open = [];
|
|
193
|
+
openConstruct(body, marker) {
|
|
194
|
+
const detail = marker.descriptor;
|
|
195
|
+
if (detail.kind === "anchor" && detail.anchorType === "bookmark") {
|
|
196
|
+
this.open.push({
|
|
197
|
+
isBookmark: true,
|
|
198
|
+
name: detail.name
|
|
199
|
+
});
|
|
200
|
+
body.appendBookmarkStart(detail.name);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.open.push({
|
|
204
|
+
isBookmark: false,
|
|
205
|
+
name: ""
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
closeConstruct(body) {
|
|
209
|
+
const entry = this.open.pop();
|
|
210
|
+
if (entry?.isBookmark) body.appendBookmarkEnd(entry.name);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
function appendBlock(body, block, markers) {
|
|
191
214
|
if (block.kind === "paragraph") populateParagraph(body.appendParagraph(), block, { headings: "element" });
|
|
192
215
|
else if (block.kind === "image") body.appendParagraph().insertImageAfter({
|
|
193
216
|
format: block.format,
|
|
@@ -199,6 +222,8 @@ function appendBlock(body, block) {
|
|
|
199
222
|
else if (block.kind === "pageBreak") body.appendPageBreak();
|
|
200
223
|
else if (block.kind === "table") appendTable(body, block);
|
|
201
224
|
else if (block.kind === "embeddedObject") appendEmbeddedObject(body, block);
|
|
225
|
+
else if (block.kind === "constructStart") markers.openConstruct(body, block);
|
|
226
|
+
else markers.closeConstruct(body);
|
|
202
227
|
}
|
|
203
228
|
function appendEmbeddedObject(body, block) {
|
|
204
229
|
if (require_model_embedded_drawing.drawingOfBlock(block) !== void 0) {
|
package/dist/edit/odt/content.js
CHANGED
|
@@ -13,9 +13,10 @@ function buildOdtPackage(content, options) {
|
|
|
13
13
|
const clock = options?.clock ?? systemClock;
|
|
14
14
|
const metadata = resolveMetadataTimestamps(content.metadata, clock);
|
|
15
15
|
const editor = new OdtEditor(createEmptyOdtPackage({ metadata }));
|
|
16
|
+
const markers = new ConstructMarkerState();
|
|
16
17
|
content.sections.forEach((section, sectionIndex) => {
|
|
17
18
|
if (sectionIndex > 0) editor.body.appendPageBreak();
|
|
18
|
-
appendBlocks(editor.body, section.blocks);
|
|
19
|
+
appendBlocks(editor.body, section.blocks, markers);
|
|
19
20
|
});
|
|
20
21
|
return editor.toPackage();
|
|
21
22
|
}
|
|
@@ -35,7 +36,7 @@ function appendMergedImageParagraph(body, paragraphBlock, imageBlock) {
|
|
|
35
36
|
altText: imageBlock.altText
|
|
36
37
|
});
|
|
37
38
|
}
|
|
38
|
-
function appendBlocks(body, blocks) {
|
|
39
|
+
function appendBlocks(body, blocks, markers) {
|
|
39
40
|
let i = 0;
|
|
40
41
|
while (i < blocks.length) {
|
|
41
42
|
const block = blocks[i];
|
|
@@ -60,7 +61,7 @@ function appendBlocks(body, blocks) {
|
|
|
60
61
|
appendListRun(body, run);
|
|
61
62
|
continue;
|
|
62
63
|
}
|
|
63
|
-
appendBlock(body, block);
|
|
64
|
+
appendBlock(body, block, markers);
|
|
64
65
|
i++;
|
|
65
66
|
}
|
|
66
67
|
}
|
|
@@ -186,7 +187,29 @@ function appendCellBlock(cell, block) {
|
|
|
186
187
|
altText: block.altText
|
|
187
188
|
});
|
|
188
189
|
}
|
|
189
|
-
|
|
190
|
+
var ConstructMarkerState = class {
|
|
191
|
+
open = [];
|
|
192
|
+
openConstruct(body, marker) {
|
|
193
|
+
const detail = marker.descriptor;
|
|
194
|
+
if (detail.kind === "anchor" && detail.anchorType === "bookmark") {
|
|
195
|
+
this.open.push({
|
|
196
|
+
isBookmark: true,
|
|
197
|
+
name: detail.name
|
|
198
|
+
});
|
|
199
|
+
body.appendBookmarkStart(detail.name);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
this.open.push({
|
|
203
|
+
isBookmark: false,
|
|
204
|
+
name: ""
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
closeConstruct(body) {
|
|
208
|
+
const entry = this.open.pop();
|
|
209
|
+
if (entry?.isBookmark) body.appendBookmarkEnd(entry.name);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
function appendBlock(body, block, markers) {
|
|
190
213
|
if (block.kind === "paragraph") populateParagraph(body.appendParagraph(), block, { headings: "element" });
|
|
191
214
|
else if (block.kind === "image") body.appendParagraph().insertImageAfter({
|
|
192
215
|
format: block.format,
|
|
@@ -198,6 +221,8 @@ function appendBlock(body, block) {
|
|
|
198
221
|
else if (block.kind === "pageBreak") body.appendPageBreak();
|
|
199
222
|
else if (block.kind === "table") appendTable(body, block);
|
|
200
223
|
else if (block.kind === "embeddedObject") appendEmbeddedObject(body, block);
|
|
224
|
+
else if (block.kind === "constructStart") markers.openConstruct(body, block);
|
|
225
|
+
else markers.closeConstruct(body);
|
|
201
226
|
}
|
|
202
227
|
function appendEmbeddedObject(body, block) {
|
|
203
228
|
if (drawingOfBlock(block) !== void 0) {
|
package/dist/edit/odt/editor.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_xml_entities = require("../../xml/entities.cjs");
|
|
2
3
|
const require_metadata_core_patch = require("../../metadata/core-patch.cjs");
|
|
3
4
|
const require_model_metadata = require("../../model/metadata.cjs");
|
|
4
5
|
const require_ports_clock = require("../../ports/clock.cjs");
|
|
@@ -69,6 +70,28 @@ var OdtBodyImpl = class {
|
|
|
69
70
|
});
|
|
70
71
|
this.officeText.children.push(paragraphElement);
|
|
71
72
|
}
|
|
73
|
+
appendBookmarkStart(name) {
|
|
74
|
+
this.officeText.children.push({
|
|
75
|
+
type: "element",
|
|
76
|
+
tag: "text:bookmark-start",
|
|
77
|
+
attributes: [{
|
|
78
|
+
name: "text:name",
|
|
79
|
+
value: require_xml_entities.encodeXmlText(name)
|
|
80
|
+
}],
|
|
81
|
+
children: []
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
appendBookmarkEnd(name) {
|
|
85
|
+
this.officeText.children.push({
|
|
86
|
+
type: "element",
|
|
87
|
+
tag: "text:bookmark-end",
|
|
88
|
+
attributes: [{
|
|
89
|
+
name: "text:name",
|
|
90
|
+
value: require_xml_entities.encodeXmlText(name)
|
|
91
|
+
}],
|
|
92
|
+
children: []
|
|
93
|
+
});
|
|
94
|
+
}
|
|
72
95
|
};
|
|
73
96
|
var OdtEditor = class {
|
|
74
97
|
body;
|
|
@@ -12,6 +12,8 @@ interface OdtBody {
|
|
|
12
12
|
appendPageBreak(): void;
|
|
13
13
|
appendFormula(formula: ContentFormula, frame: Box): OdtParagraph;
|
|
14
14
|
appendVectors(vectors: readonly ContentVector[]): OdtParagraph;
|
|
15
|
+
appendBookmarkStart(name: string): void;
|
|
16
|
+
appendBookmarkEnd(name: string): void;
|
|
15
17
|
}
|
|
16
18
|
declare class OdtEditor {
|
|
17
19
|
readonly body: OdtBody;
|
|
@@ -12,6 +12,8 @@ interface OdtBody {
|
|
|
12
12
|
appendPageBreak(): void;
|
|
13
13
|
appendFormula(formula: ContentFormula, frame: Box): OdtParagraph;
|
|
14
14
|
appendVectors(vectors: readonly ContentVector[]): OdtParagraph;
|
|
15
|
+
appendBookmarkStart(name: string): void;
|
|
16
|
+
appendBookmarkEnd(name: string): void;
|
|
15
17
|
}
|
|
16
18
|
declare class OdtEditor {
|
|
17
19
|
readonly body: OdtBody;
|
package/dist/edit/odt/editor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { encodeXmlText as encodeXmlText$1 } from "../../xml/entities.js";
|
|
1
2
|
import { patchOdfMetadataOnPackage } from "../../metadata/core-patch.js";
|
|
2
3
|
import { resolveMetadataTimestamps } from "../../model/metadata.js";
|
|
3
4
|
import { systemClock } from "../../ports/clock.js";
|
|
@@ -68,6 +69,28 @@ var OdtBodyImpl = class {
|
|
|
68
69
|
});
|
|
69
70
|
this.officeText.children.push(paragraphElement);
|
|
70
71
|
}
|
|
72
|
+
appendBookmarkStart(name) {
|
|
73
|
+
this.officeText.children.push({
|
|
74
|
+
type: "element",
|
|
75
|
+
tag: "text:bookmark-start",
|
|
76
|
+
attributes: [{
|
|
77
|
+
name: "text:name",
|
|
78
|
+
value: encodeXmlText$1(name)
|
|
79
|
+
}],
|
|
80
|
+
children: []
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
appendBookmarkEnd(name) {
|
|
84
|
+
this.officeText.children.push({
|
|
85
|
+
type: "element",
|
|
86
|
+
tag: "text:bookmark-end",
|
|
87
|
+
attributes: [{
|
|
88
|
+
name: "text:name",
|
|
89
|
+
value: encodeXmlText$1(name)
|
|
90
|
+
}],
|
|
91
|
+
children: []
|
|
92
|
+
});
|
|
93
|
+
}
|
|
71
94
|
};
|
|
72
95
|
var OdtEditor = class {
|
|
73
96
|
body;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js.documents",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.11.1",
|
|
4
4
|
"description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"epub-codec": "1.3.3",
|
|
85
85
|
"fflate": "0.8.3",
|
|
86
86
|
"markdown-codec": "6.6.0",
|
|
87
|
-
"odf.js": "7.
|
|
87
|
+
"odf.js": "7.12.0",
|
|
88
88
|
"ooxml.js": "8.8.0",
|
|
89
89
|
"pdf-codec": "4.1.0",
|
|
90
90
|
"ppt-codec": "1.4.4",
|