@docen/docx 0.3.5 → 0.4.0
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/{blockquote-DY80QC06.d.mts → blockquote-D-1aSxEn.d.mts} +5 -1
- package/dist/converters/docx.d.mts +40 -66
- package/dist/converters/docx.mjs +248 -665
- package/dist/converters/html.d.mts +1 -1
- package/dist/converters/html.mjs +3 -4
- package/dist/converters/markdown.d.mts +1 -1
- package/dist/converters/markdown.mjs +1 -1
- package/dist/converters/patch.d.mts +1 -1
- package/dist/converters/prepare.d.mts +1 -1
- package/dist/converters/styles.d.mts +58 -14
- package/dist/converters/styles.mjs +124 -16
- package/dist/{core-DC0_-WcE.d.mts → core-BqyLL84S.d.mts} +34 -13
- package/dist/{core-BnF8XhVE.mjs → core-wNNPJiKr.mjs} +357 -25
- package/dist/core.d.mts +1 -1
- package/dist/core.mjs +1 -1
- package/dist/details-DsJhDP5K.d.mts +31 -0
- package/dist/editor.d.mts +1 -1
- package/dist/editor.mjs +1 -1
- package/dist/extensions/blockquote.d.mts +2 -3
- package/dist/extensions/blockquote.mjs +50 -2
- package/dist/extensions/bullet-list.mjs +1 -1
- package/dist/extensions/code-block.d.mts +2 -2
- package/dist/extensions/code-block.mjs +51 -5
- package/dist/extensions/column-break.d.mts +2 -2
- package/dist/extensions/column-break.mjs +2 -2
- package/dist/extensions/details.d.mts +2 -3
- package/dist/extensions/details.mjs +48 -2
- package/dist/extensions/document.mjs +1 -1
- package/dist/extensions/extensions.d.mts +13 -9
- package/dist/extensions/extensions.mjs +7 -3
- package/dist/extensions/formatting-marks.d.mts +1 -1
- package/dist/extensions/formatting-marks.mjs +1 -1
- package/dist/extensions/heading.d.mts +2 -2
- package/dist/extensions/heading.mjs +61 -5
- package/dist/extensions/image.d.mts +2 -2
- package/dist/extensions/image.mjs +23 -4
- package/dist/extensions/index.d.mts +14 -10
- package/dist/extensions/index.mjs +8 -4
- package/dist/extensions/link.d.mts +2 -2
- package/dist/extensions/link.mjs +30 -2
- package/dist/extensions/list-aggregator.d.mts +8 -0
- package/dist/extensions/list-aggregator.mjs +2 -0
- package/dist/extensions/marks.d.mts +2 -0
- package/dist/extensions/marks.mjs +41 -0
- package/dist/extensions/mention.d.mts +2 -3
- package/dist/extensions/mention.mjs +16 -2
- package/dist/extensions/ordered-list.mjs +1 -1
- package/dist/extensions/page-break.d.mts +2 -2
- package/dist/extensions/page-break.mjs +2 -2
- package/dist/extensions/paragraph.mjs +3 -3
- package/dist/extensions/passthrough.d.mts +1 -1
- package/dist/extensions/passthrough.mjs +1 -1
- package/dist/extensions/scroll.d.mts +1 -1
- package/dist/extensions/scroll.mjs +30 -5
- package/dist/extensions/section-break.d.mts +1 -1
- package/dist/extensions/section-break.mjs +1 -1
- package/dist/extensions/strike.d.mts +2 -2
- package/dist/extensions/strike.mjs +5 -24
- package/dist/extensions/tab.d.mts +2 -2
- package/dist/extensions/tab.mjs +2 -2
- package/dist/extensions/table-cell.mjs +2 -2
- package/dist/extensions/table-header.mjs +2 -2
- package/dist/extensions/table-row.mjs +2 -2
- package/dist/extensions/table.d.mts +2 -2
- package/dist/extensions/table.mjs +122 -11
- package/dist/extensions/task-item.d.mts +2 -3
- package/dist/extensions/task-item.mjs +2 -2
- package/dist/extensions/text-style.d.mts +2 -2
- package/dist/extensions/text-style.mjs +27 -28
- package/dist/extensions/toc-field.d.mts +2 -2
- package/dist/extensions/toc-field.mjs +2 -2
- package/dist/extensions/track-change.d.mts +2 -0
- package/dist/extensions/track-change.mjs +2 -0
- package/dist/extensions/types.d.mts +127 -8
- package/dist/extensions/utils.d.mts +2 -2
- package/dist/extensions/utils.mjs +74 -1
- package/dist/extensions/wpg-group.d.mts +2 -2
- package/dist/extensions/wpg-group.mjs +2 -2
- package/dist/extensions/wps-shape.d.mts +2 -2
- package/dist/extensions/wps-shape.mjs +2 -2
- package/dist/heading-Bwpa8iZY.d.mts +24 -0
- package/dist/index.d.mts +29 -11
- package/dist/index.mjs +9 -5
- package/dist/{link-BawPjQZR.d.mts → link-gUqW45mE.d.mts} +3 -1
- package/dist/marks-Dz9Vb22Q.d.mts +10 -0
- package/dist/{mention-BGLzLVYw.d.mts → mention-CkONDrw9.d.mts} +5 -1
- package/dist/{scroll-ZNeThJsJ.d.mts → scroll-BARiZ5Gm.d.mts} +9 -3
- package/dist/strike-Brn9sWFy.d.mts +16 -0
- package/dist/table-CdcjR6HD.d.mts +18 -0
- package/dist/{task-item-B0ntvQ1Y.d.mts → task-item-CCAC4QLi.d.mts} +3 -1
- package/dist/text-style-BzfcbufI.d.mts +4 -0
- package/dist/{utils-BJwDQts7.d.mts → utils-CfwwOowz.d.mts} +25 -1
- package/package.json +1 -1
- package/dist/details-Dd5MqqmR.d.mts +0 -17
- package/dist/extensions/tiptap.d.mts +0 -2
- package/dist/extensions/tiptap.mjs +0 -31
- package/dist/heading-BvqBD2zX.d.mts +0 -8
- package/dist/strike-BgWGvjKr.d.mts +0 -33
- package/dist/table-BFkfeRp9.d.mts +0 -9
- package/dist/text-style-BHdtXkMb.d.mts +0 -8
- package/dist/tiptap-BKqn41uT.d.mts +0 -31
package/dist/converters/html.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { o as docxExtensions } from "../core-BnF8XhVE.mjs";
|
|
2
1
|
import { sectionLinePitchCss, sectionMarginCss } from "../extensions/utils.mjs";
|
|
2
|
+
import { h as docxExtensions } from "../core-wNNPJiKr.mjs";
|
|
3
3
|
import { getSchema } from "@tiptap/core";
|
|
4
4
|
import { encodeBase64 } from "@office-open/core";
|
|
5
5
|
import { DOMParser, DOMSerializer, Node } from "@tiptap/pm/model";
|
|
6
6
|
import { parseHTML as parseHTML$1 } from "linkedom";
|
|
7
7
|
//#region src/converters/html.ts
|
|
8
|
-
const defaultExtensions = docxExtensions;
|
|
9
8
|
/** JSON round-trips byte arrays as plain objects ({0:byte,…}); rebuild here. */
|
|
10
9
|
function toBytes(data) {
|
|
11
10
|
if (!data) return null;
|
|
@@ -61,7 +60,7 @@ function splitJsonSections(doc) {
|
|
|
61
60
|
* document: happy-dom drops calc(var(…)) when re-serializing the style
|
|
62
61
|
* attribute, so DOCX line-spacing survives only with linkedom.
|
|
63
62
|
*/
|
|
64
|
-
function generateHTML(doc, extensions =
|
|
63
|
+
function generateHTML(doc, extensions = docxExtensions) {
|
|
65
64
|
const schema = getSchema(extensions);
|
|
66
65
|
const { document } = parseHTML$1("<!DOCTYPE html><html><body></body></html>");
|
|
67
66
|
const serializer = DOMSerializer.fromSchema(schema);
|
|
@@ -95,7 +94,7 @@ function generateHTML(doc, extensions = defaultExtensions) {
|
|
|
95
94
|
* (linePitch/margins) and the page background are section/doc-level metadata,
|
|
96
95
|
* not content — they round-trip losslessly via DOCX, not HTML.
|
|
97
96
|
*/
|
|
98
|
-
function parseHTML(html, extensions =
|
|
97
|
+
function parseHTML(html, extensions = docxExtensions, options) {
|
|
99
98
|
const schema = getSchema(extensions);
|
|
100
99
|
const { document } = parseHTML$1(`<!DOCTYPE html><html><body>${html}</body></html>`);
|
|
101
100
|
return DOMParser.fromSchema(schema).parse(document.body, options).toJSON();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { h as docxExtensions } from "../core-wNNPJiKr.mjs";
|
|
2
2
|
import { Markdown, MarkdownManager } from "@tiptap/markdown";
|
|
3
3
|
//#region src/converters/markdown.ts
|
|
4
4
|
const markdownManager = new MarkdownManager({ extensions: [...docxExtensions, Markdown] });
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { ResolveContext } from "../extensions/types.mjs";
|
|
1
2
|
import { JSONContent } from "@tiptap/core";
|
|
2
|
-
import { StylesOptions } from "@office-open/docx";
|
|
3
|
+
import { ParagraphOptions, StylesOptions } from "@office-open/docx";
|
|
3
4
|
|
|
4
5
|
//#region src/converters/styles.d.ts
|
|
5
6
|
/** A named style entry as office-open models it: BaseParagraphStyleOptions or
|
|
@@ -35,6 +36,17 @@ declare function defaultParagraphStyleId(styles: StylesOptions | null | undefine
|
|
|
35
36
|
*/
|
|
36
37
|
declare function stylesToCss(styles: StylesOptions | null | undefined, scope: string): string;
|
|
37
38
|
declare function indexParagraphStyles(styles: StylesOptions): Map<string, StyleEntry>;
|
|
39
|
+
/** Resolve a table style's effective table-level properties (tblBorders,
|
|
40
|
+
* tblCellMar) by walking its basedOn chain (root first, child overrides) —
|
|
41
|
+
* the table-style counterpart of mergeStyleChain. office-open's parseDocument
|
|
42
|
+
* does NOT merge the referenced <w:tblStyle> into table.borders/cellMargin
|
|
43
|
+
* (they reflect only the table's own <w:tblPr>), so a "Table Grid" table whose
|
|
44
|
+
* borders live in the style needs this to render its grid. Returns empty when
|
|
45
|
+
* the style is absent or unknown. */
|
|
46
|
+
declare function mergeTableStyleProps(tableStyles: unknown, styleId: string | null | undefined): {
|
|
47
|
+
borders?: Record<string, unknown>;
|
|
48
|
+
cellMargin?: Record<string, unknown>;
|
|
49
|
+
};
|
|
38
50
|
/** A gallery-ready paragraph-style entry for the Styles combobox. */
|
|
39
51
|
interface QuickStyleEntry {
|
|
40
52
|
id: string;
|
|
@@ -71,21 +83,53 @@ declare function effectiveRunProps(styles: StylesOptions | null | undefined, sty
|
|
|
71
83
|
size: number | null;
|
|
72
84
|
};
|
|
73
85
|
/**
|
|
74
|
-
*
|
|
75
|
-
* JSONContent
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
86
|
+
* Bake a document's named styles into each node's attrs so a snippet of
|
|
87
|
+
* JSONContent can be lifted into ANOTHER document (DB storage → extract →
|
|
88
|
+
* recombine) without its source styles.xml. The use case is fragment
|
|
89
|
+
* recombination, not editor rendering — the editor never calls this (it
|
|
90
|
+
* renders via stylesToCss global CSS); this is an offline util for
|
|
91
|
+
* self-contained JSON.
|
|
92
|
+
*
|
|
93
|
+
* Baking is intentionally PARTIAL:
|
|
94
|
+
* - A paragraph/heading or textStyle mark WITH a styleId absorbs its basedOn
|
|
95
|
+
* chain, so a "Heading 1" stays styled across documents even when the
|
|
96
|
+
* target lacks that style. styleId is kept as the semantic reference; the
|
|
97
|
+
* baked props are the rendering fallback.
|
|
98
|
+
* - A node WITHOUT a styleId (body text, a default table) is LEFT AS-IS so it
|
|
99
|
+
* follows the TARGET document's body style after recombination. Baking
|
|
100
|
+
* docDefaults here would freeze font/size onto every body paragraph and
|
|
101
|
+
* defeat "change one body style to restyle them all".
|
|
102
|
+
* - Tables are NOT baked here: resolveTable already merged the table style
|
|
103
|
+
* (borders/cellMargin) and pushed insideH/V onto cells at parse time, so a
|
|
104
|
+
* table's JSON is already self-contained. stylesToCss cannot render the
|
|
105
|
+
* interior grid (CSS border-collapse puts it on cells), so that bake MUST
|
|
106
|
+
* stay in resolveDocument — moving it here would regress the editor.
|
|
81
107
|
*
|
|
108
|
+
* Explicit attrs/marks always override the baked values; the style definitions
|
|
109
|
+
* themselves are untouched. Pure JSON — no DOM, no marks pushed onto text.
|
|
82
110
|
* Styles default to the document's own `attrs.styles` (the round-tripped
|
|
83
|
-
* styles.xml model
|
|
84
|
-
*
|
|
85
|
-
* cross-document paste (the snippet carries its styling) and self-contained
|
|
86
|
-
* export. The editor still renders via global styles — this only merges JSON
|
|
87
|
-
* properties.
|
|
111
|
+
* styles.xml model on the doc node), so `inlineStyles(doc)` needs no second
|
|
112
|
+
* argument; pass `styles` to override.
|
|
88
113
|
*/
|
|
89
114
|
declare function inlineStyles(json: JSONContent, styles?: StylesOptions | null): JSONContent;
|
|
115
|
+
/** Remove keys with null/undefined values. */
|
|
116
|
+
declare function cleanAttrs(attrs: Record<string, unknown>): Record<string, unknown>;
|
|
117
|
+
/** Build a text-block node (paragraph/heading) from a resolved ParagraphOptions:
|
|
118
|
+
* reflective attrs parse, optional heading-level stamp, inline content, and
|
|
119
|
+
* null-stripped attrs. Shared by resolveParagraph's heading rule + plain
|
|
120
|
+
* fallback (and the list-item paragraph path) so the build stays DRY.
|
|
121
|
+
* `contentPara` overrides the content source — a list item strips its task
|
|
122
|
+
* checkbox before resolving content, but attrs still come from the original. */
|
|
123
|
+
declare function buildTextBlock(type: string, resolved: ParagraphOptions, ctx: ResolveContext, level?: number, contentPara?: ParagraphOptions): JSONContent;
|
|
124
|
+
/** True when a tblBorders object carries no REAL edge — every side is absent,
|
|
125
|
+
* none, or nil. office-open fills table.borders with all-`none` when the
|
|
126
|
+
* table's own <w:tblPr> defines no <w:tblBorders>, so this detects "the table
|
|
127
|
+
* has no borders of its own" to decide whether a referenced table style's
|
|
128
|
+
* borders should fill the gap. */
|
|
129
|
+
declare function allBordersNone(borders: unknown): boolean;
|
|
130
|
+
/** Merge consecutive text nodes with the same marks. Used by inline container
|
|
131
|
+
* resolution (hyperlink, track-change) so a link/revision range spanning
|
|
132
|
+
* multiple runs becomes a single text node carrying the container mark. */
|
|
133
|
+
declare function mergeTextNodes(nodes: JSONContent[]): JSONContent[];
|
|
90
134
|
//#endregion
|
|
91
|
-
export { QuickStyleEntry, StyleEntry, type StylesOptions, defaultParagraphStyleId, effectiveRunProps, indexParagraphStyles, inlineStyles, quickStyles, stylesToCss };
|
|
135
|
+
export { QuickStyleEntry, StyleEntry, type StylesOptions, allBordersNone, buildTextBlock, cleanAttrs, defaultParagraphStyleId, effectiveRunProps, indexParagraphStyles, inlineStyles, mergeTableStyleProps, mergeTextNodes, quickStyles, stylesToCss };
|
|
@@ -147,11 +147,44 @@ function mergeStyleChain(byId, styleId) {
|
|
|
147
147
|
paragraph
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
|
+
/** Resolve a table style's effective table-level properties (tblBorders,
|
|
151
|
+
* tblCellMar) by walking its basedOn chain (root first, child overrides) —
|
|
152
|
+
* the table-style counterpart of mergeStyleChain. office-open's parseDocument
|
|
153
|
+
* does NOT merge the referenced <w:tblStyle> into table.borders/cellMargin
|
|
154
|
+
* (they reflect only the table's own <w:tblPr>), so a "Table Grid" table whose
|
|
155
|
+
* borders live in the style needs this to render its grid. Returns empty when
|
|
156
|
+
* the style is absent or unknown. */
|
|
157
|
+
function mergeTableStyleProps(tableStyles, styleId) {
|
|
158
|
+
if (!styleId || !tableStyles) return {};
|
|
159
|
+
const byId = new Map(tableStyles.map((t) => [t.id ?? "", t]));
|
|
160
|
+
const chain = [];
|
|
161
|
+
const visited = /* @__PURE__ */ new Set();
|
|
162
|
+
let cur = styleId ?? void 0;
|
|
163
|
+
while (cur && !visited.has(cur)) {
|
|
164
|
+
visited.add(cur);
|
|
165
|
+
const s = byId.get(cur);
|
|
166
|
+
if (!s) break;
|
|
167
|
+
chain.unshift(s);
|
|
168
|
+
cur = s.basedOn;
|
|
169
|
+
}
|
|
170
|
+
let borders;
|
|
171
|
+
let cellMargin;
|
|
172
|
+
for (const s of chain) {
|
|
173
|
+
const t = s.table;
|
|
174
|
+
if (!t) continue;
|
|
175
|
+
if (t.borders) borders = t.borders;
|
|
176
|
+
if (t.cellMargin) cellMargin = t.cellMargin;
|
|
177
|
+
}
|
|
178
|
+
const out = {};
|
|
179
|
+
if (borders) out.borders = borders;
|
|
180
|
+
if (cellMargin) out.cellMargin = cellMargin;
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
150
183
|
/** The `DefaultStylesOptions` keys whose values are character styles, not
|
|
151
184
|
* paragraph styles. The Quick Styles gallery is paragraph-only, so these are
|
|
152
185
|
* excluded even when flagged `quickFormat` (the authoritative source is
|
|
153
186
|
* office-open's DefaultStylesOptions interface). */
|
|
154
|
-
const CHARACTER_DEFAULT_KEYS = new Set([
|
|
187
|
+
const CHARACTER_DEFAULT_KEYS = /* @__PURE__ */ new Set([
|
|
155
188
|
"hyperlink",
|
|
156
189
|
"footnoteReference",
|
|
157
190
|
"footnoteTextChar",
|
|
@@ -247,9 +280,12 @@ function indexCharacterRunStyles(styles) {
|
|
|
247
280
|
}
|
|
248
281
|
return byId;
|
|
249
282
|
}
|
|
250
|
-
/** Resolve one node's style inheritance
|
|
283
|
+
/** Resolve one node's style inheritance. A paragraph/heading absorbs its
|
|
251
284
|
* styleId's basedOn chain (paragraph properties + the default `run`); a
|
|
252
|
-
* textStyle mark absorbs its character style's run.
|
|
285
|
+
* textStyle mark absorbs its character style's run. Other nodes (table,
|
|
286
|
+
* tableRow, tableCell, image, …) are NOT baked here — they only recurse into
|
|
287
|
+
* `content`, so a cell's paragraphs still get baked (see inlineStyles for why
|
|
288
|
+
* tables and docDefaults are intentionally out of scope). Explicit attrs/marks
|
|
253
289
|
* override the inherited values; styleId is preserved. Pure JSON — no DOM, no
|
|
254
290
|
* marks pushed onto text. */
|
|
255
291
|
function resolveNode(node, paraById, charRunById) {
|
|
@@ -284,25 +320,97 @@ function resolveNode(node, paraById, charRunById) {
|
|
|
284
320
|
return out;
|
|
285
321
|
}
|
|
286
322
|
/**
|
|
287
|
-
*
|
|
288
|
-
* JSONContent
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
* themselves are untouched — only properties are copied onto nodes.
|
|
323
|
+
* Bake a document's named styles into each node's attrs so a snippet of
|
|
324
|
+
* JSONContent can be lifted into ANOTHER document (DB storage → extract →
|
|
325
|
+
* recombine) without its source styles.xml. The use case is fragment
|
|
326
|
+
* recombination, not editor rendering — the editor never calls this (it
|
|
327
|
+
* renders via stylesToCss global CSS); this is an offline util for
|
|
328
|
+
* self-contained JSON.
|
|
294
329
|
*
|
|
330
|
+
* Baking is intentionally PARTIAL:
|
|
331
|
+
* - A paragraph/heading or textStyle mark WITH a styleId absorbs its basedOn
|
|
332
|
+
* chain, so a "Heading 1" stays styled across documents even when the
|
|
333
|
+
* target lacks that style. styleId is kept as the semantic reference; the
|
|
334
|
+
* baked props are the rendering fallback.
|
|
335
|
+
* - A node WITHOUT a styleId (body text, a default table) is LEFT AS-IS so it
|
|
336
|
+
* follows the TARGET document's body style after recombination. Baking
|
|
337
|
+
* docDefaults here would freeze font/size onto every body paragraph and
|
|
338
|
+
* defeat "change one body style to restyle them all".
|
|
339
|
+
* - Tables are NOT baked here: resolveTable already merged the table style
|
|
340
|
+
* (borders/cellMargin) and pushed insideH/V onto cells at parse time, so a
|
|
341
|
+
* table's JSON is already self-contained. stylesToCss cannot render the
|
|
342
|
+
* interior grid (CSS border-collapse puts it on cells), so that bake MUST
|
|
343
|
+
* stay in resolveDocument — moving it here would regress the editor.
|
|
344
|
+
*
|
|
345
|
+
* Explicit attrs/marks always override the baked values; the style definitions
|
|
346
|
+
* themselves are untouched. Pure JSON — no DOM, no marks pushed onto text.
|
|
295
347
|
* Styles default to the document's own `attrs.styles` (the round-tripped
|
|
296
|
-
* styles.xml model
|
|
297
|
-
*
|
|
298
|
-
* cross-document paste (the snippet carries its styling) and self-contained
|
|
299
|
-
* export. The editor still renders via global styles — this only merges JSON
|
|
300
|
-
* properties.
|
|
348
|
+
* styles.xml model on the doc node), so `inlineStyles(doc)` needs no second
|
|
349
|
+
* argument; pass `styles` to override.
|
|
301
350
|
*/
|
|
302
351
|
function inlineStyles(json, styles) {
|
|
303
352
|
const docStyles = styles ?? json.attrs?.styles;
|
|
304
353
|
if (!docStyles) return json;
|
|
305
354
|
return resolveNode(json, indexParagraphStyles(docStyles), indexCharacterRunStyles(docStyles));
|
|
306
355
|
}
|
|
356
|
+
/** Remove keys with null/undefined values. */
|
|
357
|
+
function cleanAttrs(attrs) {
|
|
358
|
+
const result = {};
|
|
359
|
+
for (const [key, value] of Object.entries(attrs)) if (value !== null && value !== void 0) result[key] = value;
|
|
360
|
+
return result;
|
|
361
|
+
}
|
|
362
|
+
/** Build a text-block node (paragraph/heading) from a resolved ParagraphOptions:
|
|
363
|
+
* reflective attrs parse, optional heading-level stamp, inline content, and
|
|
364
|
+
* null-stripped attrs. Shared by resolveParagraph's heading rule + plain
|
|
365
|
+
* fallback (and the list-item paragraph path) so the build stays DRY.
|
|
366
|
+
* `contentPara` overrides the content source — a list item strips its task
|
|
367
|
+
* checkbox before resolving content, but attrs still come from the original. */
|
|
368
|
+
function buildTextBlock(type, resolved, ctx, level, contentPara) {
|
|
369
|
+
const attrs = ctx.parseNodeAttrs(type, resolved);
|
|
370
|
+
if (level != null && attrs.level == null) attrs.level = level;
|
|
371
|
+
const content = ctx.resolveInlineContent(contentPara ?? resolved);
|
|
372
|
+
const cleaned = cleanAttrs(attrs);
|
|
373
|
+
const node = { type };
|
|
374
|
+
if (Object.keys(cleaned).length > 0) node.attrs = cleaned;
|
|
375
|
+
if (content.length > 0) node.content = content;
|
|
376
|
+
return node;
|
|
377
|
+
}
|
|
378
|
+
/** True when a tblBorders object carries no REAL edge — every side is absent,
|
|
379
|
+
* none, or nil. office-open fills table.borders with all-`none` when the
|
|
380
|
+
* table's own <w:tblPr> defines no <w:tblBorders>, so this detects "the table
|
|
381
|
+
* has no borders of its own" to decide whether a referenced table style's
|
|
382
|
+
* borders should fill the gap. */
|
|
383
|
+
function allBordersNone(borders) {
|
|
384
|
+
if (!borders || typeof borders !== "object") return true;
|
|
385
|
+
const b = borders;
|
|
386
|
+
return [
|
|
387
|
+
"top",
|
|
388
|
+
"bottom",
|
|
389
|
+
"left",
|
|
390
|
+
"right",
|
|
391
|
+
"insideHorizontal",
|
|
392
|
+
"insideVertical"
|
|
393
|
+
].every((k) => {
|
|
394
|
+
const v = b[k];
|
|
395
|
+
return !v || v.style === "none" || v.style === "nil";
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
/** Merge consecutive text nodes with the same marks. Used by inline container
|
|
399
|
+
* resolution (hyperlink, track-change) so a link/revision range spanning
|
|
400
|
+
* multiple runs becomes a single text node carrying the container mark. */
|
|
401
|
+
function mergeTextNodes(nodes) {
|
|
402
|
+
const result = [];
|
|
403
|
+
for (const node of nodes) {
|
|
404
|
+
if (node.type === "text" && result.length > 0 && result[result.length - 1].type === "text") {
|
|
405
|
+
const prev = result[result.length - 1];
|
|
406
|
+
if (JSON.stringify(prev.marks) === JSON.stringify(node.marks)) {
|
|
407
|
+
prev.text = (prev.text ?? "") + (node.text ?? "");
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
result.push({ ...node });
|
|
412
|
+
}
|
|
413
|
+
return result;
|
|
414
|
+
}
|
|
307
415
|
//#endregion
|
|
308
|
-
export { defaultParagraphStyleId, effectiveRunProps, indexParagraphStyles, inlineStyles, quickStyles, stylesToCss };
|
|
416
|
+
export { allBordersNone, buildTextBlock, cleanAttrs, defaultParagraphStyleId, effectiveRunProps, indexParagraphStyles, inlineStyles, mergeTableStyleProps, mergeTextNodes, quickStyles, stylesToCss };
|
|
@@ -1,19 +1,31 @@
|
|
|
1
|
+
import { ParseBlockRule, ParseInlineRule, ParseParagraphRule } from "./extensions/types.mjs";
|
|
1
2
|
import { AnyExtension, Editor, Extension, Extensions, JSONContent as JSONContent$1, Mark, Node } from "@tiptap/core";
|
|
3
|
+
import { CodeBlockLowlight as CodeBlockLowlight$1 } from "@tiptap/extension-code-block-lowlight";
|
|
4
|
+
import { Emoji as Emoji$1 } from "@tiptap/extension-emoji";
|
|
5
|
+
import { HardBreak as HardBreak$1 } from "@tiptap/extension-hard-break";
|
|
6
|
+
import { HorizontalRule as HorizontalRule$1 } from "@tiptap/extension-horizontal-rule";
|
|
7
|
+
import { ListItem as ListItem$1 } from "@tiptap/extension-list-item";
|
|
8
|
+
import { Mathematics as Mathematics$1 } from "@tiptap/extension-mathematics";
|
|
9
|
+
import { TaskList as TaskList$1 } from "@tiptap/extension-task-list";
|
|
10
|
+
import { Text as Text$1 } from "@tiptap/extension-text";
|
|
11
|
+
import { TextAlign as TextAlign$1 } from "@tiptap/extension-text-align";
|
|
2
12
|
|
|
3
13
|
//#region src/extensions/code-block.d.ts
|
|
4
14
|
/**
|
|
5
|
-
* CodeBlock extension — CodeBlockLowlight with a DOCX renderDocx.
|
|
15
|
+
* CodeBlock extension — CodeBlockLowlight with a DOCX renderDocx + parse rule.
|
|
6
16
|
*
|
|
7
17
|
* DOCX has no dedicated code-block element. A code block maps to a single
|
|
8
18
|
* paragraph styled "Code" with a monospace run font. Inline marks (syntax-
|
|
9
19
|
* highlight tokens) and line breaks (`\n` → `<w:br/>`) are handled by
|
|
10
20
|
* DocxManager's shared inline-content compilation; resolveCodeBlock reassembles
|
|
11
|
-
* the text. This module owns
|
|
21
|
+
* the text. This module owns the paragraph-level style + the parse rule that
|
|
22
|
+
* recognizes a "Code"-styled paragraph.
|
|
12
23
|
*
|
|
13
24
|
* `language` has no OOXML carrier and is intentionally dropped (known lossy).
|
|
14
25
|
*/
|
|
15
26
|
/** codeBlock node → paragraph properties (style "Code" + monospace font). */
|
|
16
27
|
declare function renderDocx$1(_node: JSONContent$1): Record<string, unknown>;
|
|
28
|
+
declare const parseDocxParagraph: ParseParagraphRule;
|
|
17
29
|
declare const CodeBlock: import("@tiptap/core").Node<import("@tiptap/extension-code-block-lowlight").CodeBlockLowlightOptions, any>;
|
|
18
30
|
//#endregion
|
|
19
31
|
//#region src/extensions/column-break.d.ts
|
|
@@ -26,13 +38,11 @@ declare const CodeBlock: import("@tiptap/core").Node<import("@tiptap/extension-c
|
|
|
26
38
|
* layout (paged.js multi-column) is a future concern; the node preserves the
|
|
27
39
|
* break losslessly regardless.
|
|
28
40
|
*
|
|
29
|
-
* The DOCX payload (`{ columnBreak: true }`) is inlined in DocxManager — a
|
|
30
|
-
* one-liner with no per-node variance, so no extension helper for it.
|
|
31
|
-
*
|
|
32
41
|
* `setColumnBreak` only inserts the atom (no paragraph split): a column break
|
|
33
42
|
* does not start a new page, and there is no column layout to reflow yet, so
|
|
34
43
|
* the node is purely for round-trip fidelity until multi-column lands.
|
|
35
44
|
*/
|
|
45
|
+
declare const parseDocxInline$5: ParseInlineRule;
|
|
36
46
|
declare const ColumnBreak: Node<any, any>;
|
|
37
47
|
declare module "@tiptap/core" {
|
|
38
48
|
interface Commands<ReturnType> {
|
|
@@ -108,6 +118,7 @@ declare function renderDocx(node: JSONContent$1): Record<string, unknown> | null
|
|
|
108
118
|
* DocxManager from the image data bytes (kept out of parseDocx).
|
|
109
119
|
*/
|
|
110
120
|
declare function parseDocx(imageOpts: Record<string, unknown>): Record<string, unknown>;
|
|
121
|
+
declare const parseDocxInline$4: ParseInlineRule;
|
|
111
122
|
/** Extent-box dimensions needed to size the inner <img> for a cropped image. */
|
|
112
123
|
interface CropRenderContext {
|
|
113
124
|
width?: number;
|
|
@@ -129,6 +140,10 @@ declare function renderCropAttrs(crop: Record<string, unknown> | CropRect, ctx?:
|
|
|
129
140
|
};
|
|
130
141
|
declare const Image: import("@tiptap/core").Node<import("@tiptap/extension-image").ImageOptions, any>;
|
|
131
142
|
//#endregion
|
|
143
|
+
//#region src/extensions/track-change.d.ts
|
|
144
|
+
declare const Insertion: Mark<any, any>;
|
|
145
|
+
declare const Deletion: Mark<any, any>;
|
|
146
|
+
//#endregion
|
|
132
147
|
//#region src/extensions/formatting-marks.d.ts
|
|
133
148
|
/**
|
|
134
149
|
* FormattingMarks — paints the non-printing paragraph mark via ProseMirror
|
|
@@ -184,6 +199,7 @@ declare module "@tiptap/core" {
|
|
|
184
199
|
* the paginator's `forcesPageBreakAfter` moves it to the next page (matching
|
|
185
200
|
* Word's Ctrl+Enter behavior).
|
|
186
201
|
*/
|
|
202
|
+
declare const parseDocxInline$3: ParseInlineRule;
|
|
187
203
|
declare const PageBreak: Node<any, any>;
|
|
188
204
|
declare module "@tiptap/core" {
|
|
189
205
|
interface Commands<ReturnType> {
|
|
@@ -284,9 +300,11 @@ interface WpsShapeStyles {
|
|
|
284
300
|
* editor's NodeView and generateHTML render identically without re-deriving
|
|
285
301
|
* the engine's EMU/floating math. */
|
|
286
302
|
declare function wpsShapeStyles(ws: WpsShapeStandalone): WpsShapeStyles;
|
|
303
|
+
declare const parseDocxInline$2: ParseInlineRule;
|
|
287
304
|
declare const WpgGroup: Node<any, any>;
|
|
288
305
|
//#endregion
|
|
289
306
|
//#region src/extensions/wps-shape.d.ts
|
|
307
|
+
declare const parseDocxInline$1: ParseInlineRule;
|
|
290
308
|
declare const WpsShape: Node<any, any>;
|
|
291
309
|
//#endregion
|
|
292
310
|
//#region src/extensions/passthrough.d.ts
|
|
@@ -334,14 +352,16 @@ declare const InlinePassthrough: Node<any, any>;
|
|
|
334
352
|
* whose content-less runs (fldChar begin/separate/end) office-open parses as
|
|
335
353
|
* `null`. As opaque passthrough those nulls survived verbatim to
|
|
336
354
|
* `generateDocument`, where office-open's `stringifyRunInline(null).break`
|
|
337
|
-
* crashed.
|
|
338
|
-
* nulls (the
|
|
339
|
-
* and the generate path never sees a null — no
|
|
340
|
-
*
|
|
341
|
-
* DOCX serialization is inlined in DocxManager (resolve/compile read/write
|
|
342
|
-
* `attrs.options` + the entry content directly), so no renderDocx/parseDocx is
|
|
343
|
-
* needed here — the same pattern as the details extension.
|
|
355
|
+
* crashed. The `parseDocxBlock` rule resolves the entries through the shared
|
|
356
|
+
* block-stream path, which drops the nulls (the `child !== null` guard), so
|
|
357
|
+
* compile rebuilds clean entries and the generate path never sees a null — no
|
|
358
|
+
* office-open change required.
|
|
344
359
|
*/
|
|
360
|
+
/**
|
|
361
|
+
* Declarative block parse rule: recognize a table of contents SectionChild and
|
|
362
|
+
* rebuild it as an editable `tocField` container. DocxManager dispatches every
|
|
363
|
+
* SectionChild through this rule before the paragraph/passthrough fallbacks. */
|
|
364
|
+
declare const parseDocxBlock: ParseBlockRule;
|
|
345
365
|
declare const TocField: Node<any, any>;
|
|
346
366
|
//#endregion
|
|
347
367
|
//#region src/extensions/tab.d.ts
|
|
@@ -357,6 +377,7 @@ declare const TocField: Node<any, any>;
|
|
|
357
377
|
* marks where a tab leader (e.g. a TOC's dotted leader) renders. compile turns it
|
|
358
378
|
* back into `{ tab: true }`.
|
|
359
379
|
*/
|
|
380
|
+
declare const parseDocxInline: ParseInlineRule;
|
|
360
381
|
declare const Tab: Node<any, any>;
|
|
361
382
|
//#endregion
|
|
362
383
|
//#region src/extensions/extensions.d.ts
|
|
@@ -384,4 +405,4 @@ interface DocxKitOptions {
|
|
|
384
405
|
}
|
|
385
406
|
declare const DocxKit: Extension<DocxKitOptions, any>;
|
|
386
407
|
//#endregion
|
|
387
|
-
export {
|
|
408
|
+
export { parseDocxInline$5 as $, WpgGroup as A, PageBreak as B, parseDocxInline as C, Passthrough as D, InlinePassthrough as E, renderWpsInterior as F, CropRenderContext as G, FormattingMarks as H, renderWpsText as I, parseDocxInline$4 as J, Image as K, wpsInnerStyle as L, WpsShapeStandalone as M, WpsShapeStyles as N, WpsShape as O, parseDocxInline$2 as P, ColumnBreak as Q, wpsRotationVert as R, Tab as S, parseDocxBlock as T, Deletion as U, parseDocxInline$3 as V, Insertion as W, renderDocx as X, renderCropAttrs as Y, SectionBreak as Z, Text$1 as _, JSONContent$1 as a, tiptapMarkExtensions as b, CodeBlockLowlight$1 as c, Emoji$1 as d, CodeBlock as et, HardBreak$1 as f, TaskList$1 as g, Mathematics$1 as h, Extensions as i, WpsData as j, parseDocxInline$1 as k, DocxKit as l, ListItem$1 as m, Editor as n, renderDocx$1 as nt, Mark as o, HorizontalRule$1 as p, parseDocx as q, Extension as r, Node as s, AnyExtension as t, parseDocxParagraph as tt, DocxKitOptions as u, TextAlign$1 as v, TocField as w, tiptapNodeExtensions as x, docxExtensions as y, wpsShapeStyles as z };
|