@docen/docx 0.3.1 → 0.3.2
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/dist/converters/docx.d.mts +199 -1
- package/dist/converters/docx.mjs +1273 -1
- package/dist/converters/html.d.mts +28 -1
- package/dist/converters/html.mjs +103 -1
- package/dist/converters/markdown.d.mts +12 -1
- package/dist/converters/markdown.mjs +17 -1
- package/dist/converters/patch.d.mts +52 -1
- package/dist/converters/patch.mjs +35 -1
- package/dist/converters/prepare.d.mts +62 -1
- package/dist/converters/prepare.mjs +121 -1
- package/dist/converters/styles.d.mts +84 -1
- package/dist/converters/styles.mjs +284 -1
- package/dist/core-C9VunJ8o.d.mts +174 -0
- package/dist/core-DT9IrTzN.mjs +670 -0
- package/dist/core.d.mts +1 -1
- package/dist/core.mjs +1 -1
- package/dist/editor.d.mts +20 -1
- package/dist/editor.mjs +20 -1
- package/dist/extensions/blockquote.d.mts +1 -1
- package/dist/extensions/blockquote.mjs +30 -2
- package/dist/extensions/code-block.d.mts +1 -1
- package/dist/extensions/code-block.mjs +22 -1
- package/dist/extensions/column-break.d.mts +1 -1
- package/dist/extensions/column-break.mjs +1 -1
- package/dist/extensions/details.d.mts +1 -1
- package/dist/extensions/details.mjs +17 -2
- package/dist/extensions/document.mjs +49 -1
- package/dist/extensions/extensions.d.mts +3 -4
- package/dist/extensions/extensions.mjs +13 -14
- package/dist/extensions/formatting-marks.d.mts +7 -1
- package/dist/extensions/formatting-marks.mjs +1 -1
- package/dist/extensions/heading.mjs +165 -1
- package/dist/extensions/image.d.mts +1 -1
- package/dist/extensions/image.mjs +395 -1
- package/dist/extensions/index.d.mts +3 -2
- package/dist/extensions/index.mjs +4 -3
- package/dist/extensions/mention.d.mts +1 -1
- package/dist/extensions/mention.mjs +43 -2
- package/dist/extensions/ordered-list.d.mts +1 -1
- package/dist/extensions/ordered-list.mjs +40 -2
- package/dist/extensions/page-break.d.mts +1 -33
- package/dist/extensions/page-break.mjs +1 -1
- package/dist/extensions/paragraph.mjs +150 -1
- package/dist/extensions/passthrough.d.mts +1 -1
- package/dist/extensions/passthrough.mjs +1 -1
- package/dist/extensions/section-break.d.mts +19 -2
- package/dist/extensions/section-break.mjs +1 -1
- package/dist/extensions/strike.mjs +49 -1
- package/dist/extensions/table-cell.mjs +111 -1
- package/dist/extensions/table-header.mjs +111 -1
- package/dist/extensions/table-row.mjs +83 -1
- package/dist/extensions/table.mjs +159 -1
- package/dist/extensions/task-item.d.mts +1 -1
- package/dist/extensions/task-item.mjs +36 -2
- package/dist/extensions/text-style.mjs +150 -1
- package/dist/extensions/tiptap.d.mts +2 -2
- package/dist/extensions/tiptap.mjs +31 -2
- package/dist/extensions/utils.d.mts +2 -62
- package/dist/extensions/utils.mjs +499 -2
- package/dist/extensions/wpg-group.d.mts +2 -0
- package/dist/extensions/wpg-group.mjs +2 -0
- package/dist/extensions/wps-shape.d.mts +2 -0
- package/dist/extensions/wps-shape.mjs +2 -0
- package/dist/index.d.mts +86 -27
- package/dist/index.mjs +13 -10
- package/dist/{tiptap-TErPjuNJ.d.mts → tiptap-pZsNPsvV.d.mts} +1 -3
- package/dist/utils-D87vukzp.d.mts +128 -0
- package/package.json +39 -40
- package/dist/blockquote-Ky9xD_Q-.mjs +0 -31
- package/dist/code-block-BgNjhADy.mjs +0 -23
- package/dist/core-DEqBHRzE.mjs +0 -406
- package/dist/core-fBMCCj4D.d.mts +0 -97
- package/dist/details-Dh8luWb2.mjs +0 -18
- package/dist/dist-B6B3HnVZ.mjs +0 -1838
- package/dist/document-CvTym-FM.mjs +0 -50
- package/dist/docx-C5wyjI-0.d.mts +0 -200
- package/dist/docx-CONyAedl.mjs +0 -1231
- package/dist/editor-Bf3CxQnY.mjs +0 -21
- package/dist/editor-DReY3Rb9.d.mts +0 -21
- package/dist/emoji-BZ1dJD7d.d.mts +0 -17
- package/dist/emoji-C2OsTWR7.mjs +0 -27
- package/dist/extensions/emoji.d.mts +0 -2
- package/dist/extensions/emoji.mjs +0 -2
- package/dist/extensions/image-group.d.mts +0 -6
- package/dist/extensions/image-group.mjs +0 -2
- package/dist/heading-DAubgJJN.mjs +0 -166
- package/dist/html-DCC_DSHv.d.mts +0 -18
- package/dist/html-DedDWPoO.mjs +0 -66
- package/dist/image-CuEIXoZl.mjs +0 -334
- package/dist/markdown-BzJmRsBs.mjs +0 -18
- package/dist/markdown-D0k0sRYS.d.mts +0 -13
- package/dist/mention-C-dTR6MK.mjs +0 -44
- package/dist/ordered-list-V-3xFQmV.mjs +0 -41
- package/dist/paragraph-BrWH-BOV.mjs +0 -147
- package/dist/patch-Cdp5WKJz.d.mts +0 -53
- package/dist/patch-IZ13tXTu.mjs +0 -36
- package/dist/prepare-Bdk8Cjkf.mjs +0 -122
- package/dist/prepare-CPAvcv6q.d.mts +0 -63
- package/dist/strike-hWxShOgb.mjs +0 -50
- package/dist/styles-QSX3RhxK.mjs +0 -285
- package/dist/styles-ugspkrxz.d.mts +0 -85
- package/dist/table-DrA12lxX.mjs +0 -159
- package/dist/table-cell-DmkfYwDc.mjs +0 -112
- package/dist/table-header-Bwr5GKWg.mjs +0 -112
- package/dist/table-row-vew1y7WH.mjs +0 -84
- package/dist/task-item-BnlXGrIG.mjs +0 -37
- package/dist/text-style-tMeBq5XQ.mjs +0 -151
- package/dist/tiptap-D7pl4I5U.mjs +0 -33
- package/dist/utils-BPT4tjcn.mjs +0 -333
package/dist/image-CuEIXoZl.mjs
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { _ as Image$1 } from "./tiptap-D7pl4I5U.mjs";
|
|
2
|
-
//#region src/extensions/image.ts
|
|
3
|
-
/**
|
|
4
|
-
* Custom Image extension with node-level renderHTML + renderDocx/parseDocx.
|
|
5
|
-
*
|
|
6
|
-
* Attrs:
|
|
7
|
-
* - src/alt/title/width/height: Tiptap structural names (kept verbatim so base
|
|
8
|
-
* image commands work).
|
|
9
|
-
* - rotation: editor display only (CSS transform) but also carried through DOCX
|
|
10
|
-
* via transformation.rotation (MediaTransformation.rotation).
|
|
11
|
-
* - floating/outline: nested office-open objects (Floating / OutlineOptions).
|
|
12
|
-
* - crop: nested office-open SourceRectangleOptions (srcRect).
|
|
13
|
-
* - display: editor-only display hint, no OOXML equivalent.
|
|
14
|
-
*
|
|
15
|
-
* DOCX round-trip is near-identity: renderDocx packs attrs into CoreImageOptions;
|
|
16
|
-
* parseDocx unpacks them back. src is a data URL ↔ { type, data } base64.
|
|
17
|
-
* Node-level renderHTML solves the style merge problem (rotation + floating).
|
|
18
|
-
*/
|
|
19
|
-
/** Attribute spec for a nested office-open value stored as JSON in a data-* attr. */
|
|
20
|
-
const attrDataJson = (name) => ({
|
|
21
|
-
default: null,
|
|
22
|
-
rendered: false,
|
|
23
|
-
parseHTML: (element) => {
|
|
24
|
-
const raw = element.getAttribute(name);
|
|
25
|
-
if (!raw) return null;
|
|
26
|
-
try {
|
|
27
|
-
return JSON.parse(raw);
|
|
28
|
-
} catch {
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
/**
|
|
34
|
-
* Tiptap JSON image node → CoreImageOptions-shaped object.
|
|
35
|
-
*
|
|
36
|
-
* Returns `{ image: ImageOptions }` (structural wrapper) or null when no
|
|
37
|
-
* embedded image data is available (external URLs need pre-fetching).
|
|
38
|
-
* rotation is carried via transformation.rotation (not dropped).
|
|
39
|
-
*/
|
|
40
|
-
function renderDocx(node) {
|
|
41
|
-
const attrs = node.attrs ?? {};
|
|
42
|
-
const imageOpts = {};
|
|
43
|
-
const src = attrs.src;
|
|
44
|
-
if (src?.startsWith("data:image/")) {
|
|
45
|
-
const match = src.match(/^data:image\/([\w.+-]+);base64,(.+)$/);
|
|
46
|
-
if (match) {
|
|
47
|
-
imageOpts.type = match[1] === "jpeg" ? "jpg" : match[1];
|
|
48
|
-
const binary = atob(match[2]);
|
|
49
|
-
const bytes = new Uint8Array(binary.length);
|
|
50
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
51
|
-
imageOpts.data = bytes;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if (!imageOpts.data) return null;
|
|
55
|
-
const transformation = {
|
|
56
|
-
width: attrs.width ?? 600,
|
|
57
|
-
height: attrs.height ?? 400
|
|
58
|
-
};
|
|
59
|
-
const rotation = attrs.rotation;
|
|
60
|
-
if (rotation != null) transformation.rotation = rotation;
|
|
61
|
-
imageOpts.transformation = transformation;
|
|
62
|
-
const altText = {};
|
|
63
|
-
if (attrs.alt) altText.name = attrs.alt;
|
|
64
|
-
if (attrs.title) altText.description = attrs.title;
|
|
65
|
-
if (Object.keys(altText).length > 0) imageOpts.altText = altText;
|
|
66
|
-
if (attrs.floating) imageOpts.floating = attrs.floating;
|
|
67
|
-
if (attrs.crop) imageOpts.sourceRectangle = attrs.crop;
|
|
68
|
-
if (attrs.outline) imageOpts.outline = attrs.outline;
|
|
69
|
-
if (attrs.nonVisualProperties) imageOpts.nonVisualProperties = attrs.nonVisualProperties;
|
|
70
|
-
if (attrs.effectExtent) transformation.effectExtent = attrs.effectExtent;
|
|
71
|
-
if (attrs.graphicFrameLocks) imageOpts.graphicFrameLocks = attrs.graphicFrameLocks;
|
|
72
|
-
if (attrs.blipEffects) imageOpts.blipEffects = attrs.blipEffects;
|
|
73
|
-
if (attrs.useLocalDpi !== null && attrs.useLocalDpi !== void 0) imageOpts.useLocalDpi = attrs.useLocalDpi;
|
|
74
|
-
if (attrs.fill) imageOpts.fill = attrs.fill;
|
|
75
|
-
if (attrs.effects) imageOpts.effects = attrs.effects;
|
|
76
|
-
if (attrs.tile) imageOpts.tile = attrs.tile;
|
|
77
|
-
if (attrs.runPropertiesRawXml) imageOpts.runPropertiesRawXml = attrs.runPropertiesRawXml;
|
|
78
|
-
return { image: imageOpts };
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* ImageOptions-shaped object → Tiptap attrs.
|
|
82
|
-
*
|
|
83
|
-
* Near-identity unpack: transformation → width/height/rotation, altText → alt/title,
|
|
84
|
-
* floating/srcRect(→crop)/outline passed through verbatim. src is reconstructed by
|
|
85
|
-
* DocxManager from the image data bytes (kept out of parseDocx).
|
|
86
|
-
*/
|
|
87
|
-
function parseDocx(imageOpts) {
|
|
88
|
-
const opts = imageOpts ?? {};
|
|
89
|
-
const attrs = {};
|
|
90
|
-
const transformation = opts.transformation;
|
|
91
|
-
if (transformation) {
|
|
92
|
-
if (typeof transformation.width === "number") attrs.width = transformation.width;
|
|
93
|
-
if (typeof transformation.height === "number") attrs.height = transformation.height;
|
|
94
|
-
if (typeof transformation.rotation === "number") attrs.rotation = transformation.rotation;
|
|
95
|
-
}
|
|
96
|
-
const altText = opts.altText;
|
|
97
|
-
if (altText) {
|
|
98
|
-
if (altText.name) attrs.alt = altText.name;
|
|
99
|
-
if (altText.description) attrs.title = altText.description;
|
|
100
|
-
}
|
|
101
|
-
if (opts.floating) attrs.floating = opts.floating;
|
|
102
|
-
if (opts.sourceRectangle) attrs.crop = opts.sourceRectangle;
|
|
103
|
-
if (opts.outline) attrs.outline = opts.outline;
|
|
104
|
-
if (opts.nonVisualProperties) attrs.nonVisualProperties = opts.nonVisualProperties;
|
|
105
|
-
const effectExtent = opts.transformation?.effectExtent;
|
|
106
|
-
if (effectExtent) attrs.effectExtent = effectExtent;
|
|
107
|
-
if (opts.graphicFrameLocks) attrs.graphicFrameLocks = opts.graphicFrameLocks;
|
|
108
|
-
if (opts.blipEffects) attrs.blipEffects = opts.blipEffects;
|
|
109
|
-
if (opts.useLocalDpi !== void 0) attrs.useLocalDpi = opts.useLocalDpi;
|
|
110
|
-
if (opts.fill) attrs.fill = opts.fill;
|
|
111
|
-
if (opts.effects) attrs.effects = opts.effects;
|
|
112
|
-
if (opts.tile) attrs.tile = opts.tile;
|
|
113
|
-
if (opts.runPropertiesRawXml) attrs.runPropertiesRawXml = opts.runPropertiesRawXml;
|
|
114
|
-
return attrs;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Render crop as background-image styles for byte-accurate four-sided srcRect.
|
|
118
|
-
*
|
|
119
|
-
* object-fit:cover scales uniformly, so it only matches single-axis crops; for
|
|
120
|
-
* two-sided crops it shrinks the whole image and shows too much. background-size
|
|
121
|
-
* scales each axis independently (W/visibleW × H/visibleH), so the visible
|
|
122
|
-
* srcRect region always maps exactly onto the extent box. background-position
|
|
123
|
-
* then shifts the original so the cropped-left/top region falls outside the box.
|
|
124
|
-
*
|
|
125
|
-
* Requires a div[role=img] host (see Image.renderHTML) — an <img> cannot
|
|
126
|
-
* background-crop itself, since its src is always painted in the foreground.
|
|
127
|
-
*/
|
|
128
|
-
function renderCropAttrs(crop, ctx = {}) {
|
|
129
|
-
const c = crop;
|
|
130
|
-
const leftPct = (c.left || 0) / 1e5;
|
|
131
|
-
const topPct = (c.top || 0) / 1e5;
|
|
132
|
-
const rightPct = (c.right || 0) / 1e5;
|
|
133
|
-
const bottomPct = (c.bottom || 0) / 1e5;
|
|
134
|
-
const visibleW = 1 - leftPct - rightPct;
|
|
135
|
-
const visibleH = 1 - topPct - bottomPct;
|
|
136
|
-
const w = ctx.width ?? 0;
|
|
137
|
-
const h = ctx.height ?? 0;
|
|
138
|
-
const bgW = visibleW > 0 ? w / visibleW : w;
|
|
139
|
-
const bgH = visibleH > 0 ? h / visibleH : h;
|
|
140
|
-
const posX = leftPct + rightPct > 0 ? leftPct / (leftPct + rightPct) * 100 : 50;
|
|
141
|
-
const posY = topPct + bottomPct > 0 ? topPct / (topPct + bottomPct) * 100 : 50;
|
|
142
|
-
return { style: [
|
|
143
|
-
`background-image:url(${ctx.src ?? ""})`,
|
|
144
|
-
`background-size:${bgW.toFixed(2)}px ${bgH.toFixed(2)}px`,
|
|
145
|
-
`background-position:${posX.toFixed(2)}% ${posY.toFixed(2)}%`,
|
|
146
|
-
"background-repeat:no-repeat"
|
|
147
|
-
].join(";") };
|
|
148
|
-
}
|
|
149
|
-
function renderImageStyles(attrs) {
|
|
150
|
-
const styles = [];
|
|
151
|
-
if (attrs.display) styles.push(`display:${attrs.display}`);
|
|
152
|
-
if (attrs.rotation) styles.push(`transform:rotate(${attrs.rotation}deg)`);
|
|
153
|
-
const f = attrs.floating;
|
|
154
|
-
if (f) {
|
|
155
|
-
styles.push(f.behindDocument ? "z-index:-1" : "z-index:1");
|
|
156
|
-
const wrapType = f.wrap?.type ?? 0;
|
|
157
|
-
if (wrapType === 0) styles.push("position:absolute");
|
|
158
|
-
else if (wrapType === 1) {
|
|
159
|
-
const align = f.horizontalPosition?.align;
|
|
160
|
-
if (align === "left" || align === "inside") styles.push("float:left");
|
|
161
|
-
else if (align === "right" || align === "outside") styles.push("float:right");
|
|
162
|
-
else styles.push("float:left");
|
|
163
|
-
} else if (wrapType === 2) {
|
|
164
|
-
styles.push("float:left");
|
|
165
|
-
styles.push("shape-outside:margin-box");
|
|
166
|
-
} else if (wrapType === 3) {
|
|
167
|
-
styles.push("display:block");
|
|
168
|
-
styles.push("clear:both");
|
|
169
|
-
} else styles.push("display:inline-block");
|
|
170
|
-
const m = f.margins;
|
|
171
|
-
if (m) {
|
|
172
|
-
if (m.top) styles.push(`margin-top:${(m.top * 96 / 1440).toFixed(1)}pt`);
|
|
173
|
-
if (m.bottom) styles.push(`margin-bottom:${(m.bottom * 96 / 1440).toFixed(1)}pt`);
|
|
174
|
-
if (m.left) styles.push(`margin-left:${(m.left * 96 / 1440).toFixed(1)}pt`);
|
|
175
|
-
if (m.right) styles.push(`margin-right:${(m.right * 96 / 1440).toFixed(1)}pt`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
return styles;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Stamp the nested office-open attrs onto an HTML attribute map as JSON
|
|
182
|
-
* data-* pairs. Shared by the cropped-div and plain-img render branches so the
|
|
183
|
-
* fidelity fields (floating/outline/nonVisualProperties/…) round-trip through
|
|
184
|
-
* HTML identically. `crop` is handled separately (crop branch only).
|
|
185
|
-
*/
|
|
186
|
-
const RAW_ATTR_DATA = [
|
|
187
|
-
["floating", "data-floating"],
|
|
188
|
-
["outline", "data-outline"],
|
|
189
|
-
["nonVisualProperties", "data-non-visual"],
|
|
190
|
-
["effectExtent", "data-effect-extent"],
|
|
191
|
-
["graphicFrameLocks", "data-graphic-frame-locks"],
|
|
192
|
-
["blipEffects", "data-blip-effects"],
|
|
193
|
-
["useLocalDpi", "data-use-local-dpi"],
|
|
194
|
-
["fill", "data-fill"],
|
|
195
|
-
["effects", "data-effects"],
|
|
196
|
-
["tile", "data-tile"],
|
|
197
|
-
["runPropertiesRawXml", "data-run-properties-raw-xml"]
|
|
198
|
-
];
|
|
199
|
-
function attachRawAttrs(target, attrs) {
|
|
200
|
-
for (const [attr, data] of RAW_ATTR_DATA) {
|
|
201
|
-
const value = attrs[attr];
|
|
202
|
-
if (value !== null && value !== void 0) target[data] = JSON.stringify(value);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
const Image = Image$1.extend({
|
|
206
|
-
addAttributes() {
|
|
207
|
-
return {
|
|
208
|
-
...this.parent?.(),
|
|
209
|
-
display: {
|
|
210
|
-
default: null,
|
|
211
|
-
rendered: false,
|
|
212
|
-
parseHTML: () => this.options.inline ? "inline-block" : null
|
|
213
|
-
},
|
|
214
|
-
rotation: {
|
|
215
|
-
default: null,
|
|
216
|
-
rendered: false,
|
|
217
|
-
parseHTML: (element) => {
|
|
218
|
-
const match = (element.getAttribute("style") || "").match(/transform:\s*rotate\(([\d.]+)deg\)/);
|
|
219
|
-
return match ? parseFloat(match[1]) : null;
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
floating: {
|
|
223
|
-
default: null,
|
|
224
|
-
rendered: false,
|
|
225
|
-
parseHTML: (element) => {
|
|
226
|
-
const raw = element.getAttribute("data-floating");
|
|
227
|
-
if (!raw) return null;
|
|
228
|
-
try {
|
|
229
|
-
return JSON.parse(raw);
|
|
230
|
-
} catch {
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
outline: {
|
|
236
|
-
default: null,
|
|
237
|
-
rendered: false,
|
|
238
|
-
parseHTML: (element) => {
|
|
239
|
-
const raw = element.getAttribute("data-outline");
|
|
240
|
-
if (!raw) return null;
|
|
241
|
-
try {
|
|
242
|
-
return JSON.parse(raw);
|
|
243
|
-
} catch {
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
},
|
|
248
|
-
crop: {
|
|
249
|
-
default: null,
|
|
250
|
-
rendered: false,
|
|
251
|
-
parseHTML: (element) => {
|
|
252
|
-
const raw = element.getAttribute("data-crop");
|
|
253
|
-
if (!raw) return null;
|
|
254
|
-
try {
|
|
255
|
-
return JSON.parse(raw);
|
|
256
|
-
} catch {
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
nonVisualProperties: attrDataJson("data-non-visual"),
|
|
262
|
-
effectExtent: attrDataJson("data-effect-extent"),
|
|
263
|
-
graphicFrameLocks: attrDataJson("data-graphic-frame-locks"),
|
|
264
|
-
blipEffects: attrDataJson("data-blip-effects"),
|
|
265
|
-
useLocalDpi: attrDataJson("data-use-local-dpi"),
|
|
266
|
-
fill: attrDataJson("data-fill"),
|
|
267
|
-
effects: attrDataJson("data-effects"),
|
|
268
|
-
tile: attrDataJson("data-tile"),
|
|
269
|
-
runPropertiesRawXml: attrDataJson("data-run-properties-raw-xml")
|
|
270
|
-
};
|
|
271
|
-
},
|
|
272
|
-
renderHTML({ node, HTMLAttributes }) {
|
|
273
|
-
const attrs = node.attrs;
|
|
274
|
-
if (attrs.crop) {
|
|
275
|
-
const width = attrs.width;
|
|
276
|
-
const height = attrs.height;
|
|
277
|
-
const styles = renderImageStyles(attrs);
|
|
278
|
-
const crop = renderCropAttrs(attrs.crop, {
|
|
279
|
-
width,
|
|
280
|
-
height,
|
|
281
|
-
src: attrs.src
|
|
282
|
-
});
|
|
283
|
-
styles.push(crop.style, `width:${width}px`, `height:${height}px`);
|
|
284
|
-
const divAttrs = {
|
|
285
|
-
"data-image": "crop",
|
|
286
|
-
role: "img",
|
|
287
|
-
style: styles.join(";")
|
|
288
|
-
};
|
|
289
|
-
if (attrs.alt) divAttrs["aria-label"] = attrs.alt;
|
|
290
|
-
if (attrs.title) divAttrs["title"] = attrs.title;
|
|
291
|
-
attachRawAttrs(divAttrs, attrs);
|
|
292
|
-
divAttrs["data-crop"] = JSON.stringify(attrs.crop);
|
|
293
|
-
return ["div", divAttrs];
|
|
294
|
-
}
|
|
295
|
-
const htmlAttrs = { ...HTMLAttributes };
|
|
296
|
-
const styles = renderImageStyles(attrs);
|
|
297
|
-
if (styles.length > 0) htmlAttrs.style = styles.join(";");
|
|
298
|
-
attachRawAttrs(htmlAttrs, attrs);
|
|
299
|
-
return ["img", htmlAttrs];
|
|
300
|
-
},
|
|
301
|
-
parseHTML() {
|
|
302
|
-
return [{
|
|
303
|
-
tag: "div[data-image=crop]",
|
|
304
|
-
getAttrs: (el) => parseCropDiv(el)
|
|
305
|
-
}, { tag: "img[src]" }];
|
|
306
|
-
},
|
|
307
|
-
renderDocx,
|
|
308
|
-
parseDocx
|
|
309
|
-
});
|
|
310
|
-
/**
|
|
311
|
-
* Reverse-parse a cropped div[role=img] back into image attrs.
|
|
312
|
-
*
|
|
313
|
-
* Covers only what the attribute-level parseHTML rules cannot recover from a
|
|
314
|
-
* div: src (background-image), width/height (inline style extent box), and
|
|
315
|
-
* alt/title (aria-label/title). rotation/crop/floating/outline are left to
|
|
316
|
-
* their attribute parseHTML rules, which read the style/data-* the div carries.
|
|
317
|
-
*/
|
|
318
|
-
function parseCropDiv(el) {
|
|
319
|
-
const style = el.getAttribute("style") || "";
|
|
320
|
-
const attrs = {};
|
|
321
|
-
const bgMatch = style.match(/background-image:\s*url\(\s*([^)]+?)\s*\)/);
|
|
322
|
-
if (bgMatch) attrs.src = bgMatch[1].replace(/^['"]|['"]$/g, "");
|
|
323
|
-
const wMatch = style.match(/(?:^|;)\s*width:\s*([\d.]+)px/);
|
|
324
|
-
const hMatch = style.match(/(?:^|;)\s*height:\s*([\d.]+)px/);
|
|
325
|
-
if (wMatch) attrs.width = parseFloat(wMatch[1]);
|
|
326
|
-
if (hMatch) attrs.height = parseFloat(hMatch[1]);
|
|
327
|
-
const ariaLabel = el.getAttribute("aria-label");
|
|
328
|
-
if (ariaLabel) attrs.alt = ariaLabel;
|
|
329
|
-
const title = el.getAttribute("title");
|
|
330
|
-
if (title) attrs.title = title;
|
|
331
|
-
return attrs;
|
|
332
|
-
}
|
|
333
|
-
//#endregion
|
|
334
|
-
export { renderDocx as i, parseDocx as n, renderCropAttrs as r, Image as t };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { s as docxExtensions } from "./core-DEqBHRzE.mjs";
|
|
2
|
-
import { Markdown, MarkdownManager } from "@tiptap/markdown";
|
|
3
|
-
//#region src/converters/markdown.ts
|
|
4
|
-
const markdownManager = new MarkdownManager({ extensions: [...docxExtensions, Markdown] });
|
|
5
|
-
/**
|
|
6
|
-
* Parse Markdown string to Tiptap JSON.
|
|
7
|
-
*/
|
|
8
|
-
function parseMarkdown(markdown) {
|
|
9
|
-
return markdownManager.parse(markdown);
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Generate Markdown string from Tiptap JSON.
|
|
13
|
-
*/
|
|
14
|
-
function generateMarkdown(doc) {
|
|
15
|
-
return markdownManager.serialize(doc);
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { parseMarkdown as n, generateMarkdown as t };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { a as JSONContent } from "./core-fBMCCj4D.mjs";
|
|
2
|
-
|
|
3
|
-
//#region src/converters/markdown.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Parse Markdown string to Tiptap JSON.
|
|
6
|
-
*/
|
|
7
|
-
declare function parseMarkdown(markdown: string): JSONContent;
|
|
8
|
-
/**
|
|
9
|
-
* Generate Markdown string from Tiptap JSON.
|
|
10
|
-
*/
|
|
11
|
-
declare function generateMarkdown(doc: JSONContent): string;
|
|
12
|
-
//#endregion
|
|
13
|
-
export { parseMarkdown as n, generateMarkdown as t };
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import "./tiptap-D7pl4I5U.mjs";
|
|
2
|
-
//#region src/extensions/mention.ts
|
|
3
|
-
/**
|
|
4
|
-
* Mention extension — owns the DOCX expression of an inline mention.
|
|
5
|
-
*
|
|
6
|
-
* A mention is an atom node carrying `{ id, label }`. DOCX has no mention
|
|
7
|
-
* element, but an inline text-SDT (CT_SdtRun) is a reversible carrier: the
|
|
8
|
-
* `id` rides in the SDT alias, the `label` as the SDT's run text, and a fixed
|
|
9
|
-
* tag marks the type so resolve can recover the mention. (customXml would also
|
|
10
|
-
* carry the id but triggers Word's i4i patent warning; SDT does not.)
|
|
11
|
-
*/
|
|
12
|
-
/** SDT tag marking a mention content control. */
|
|
13
|
-
const MENTION_TAG = "docen-mention";
|
|
14
|
-
/** Inline text-SDT carrying a mention (id in alias, label as run text). */
|
|
15
|
-
function createMention(id, label) {
|
|
16
|
-
return { sdt: {
|
|
17
|
-
properties: {
|
|
18
|
-
tag: MENTION_TAG,
|
|
19
|
-
alias: id,
|
|
20
|
-
text: {}
|
|
21
|
-
},
|
|
22
|
-
children: [{ text: label }]
|
|
23
|
-
} };
|
|
24
|
-
}
|
|
25
|
-
/** True if an inline SDT child carries a mention. */
|
|
26
|
-
function isMention(child) {
|
|
27
|
-
if (typeof child !== "object" || child === null || !("sdt" in child)) return false;
|
|
28
|
-
return child.sdt?.properties?.tag === MENTION_TAG;
|
|
29
|
-
}
|
|
30
|
-
/** Read a mention SDT → `{ id, label }`. */
|
|
31
|
-
function readMention(child) {
|
|
32
|
-
const sdt = child.sdt;
|
|
33
|
-
const id = sdt?.properties?.alias ?? "";
|
|
34
|
-
let label = "";
|
|
35
|
-
const first = sdt?.children?.[0];
|
|
36
|
-
if (typeof first === "string") label = first;
|
|
37
|
-
else if (first && typeof first === "object" && "text" in first) label = String(first.text ?? "");
|
|
38
|
-
return {
|
|
39
|
-
id,
|
|
40
|
-
label
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
export { readMention as i, createMention as n, isMention as r, MENTION_TAG as t };
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import "./tiptap-D7pl4I5U.mjs";
|
|
2
|
-
import { LevelFormat } from "@office-open/docx";
|
|
3
|
-
//#region src/extensions/ordered-list.ts
|
|
4
|
-
/**
|
|
5
|
-
* OrderedList extension — owns the DOCX expression of an ordered list.
|
|
6
|
-
*
|
|
7
|
-
* A Tiptap orderedList maps to a sequence of paragraphs referencing one
|
|
8
|
-
* abstractNum (decimal). The reference is keyed by `start` so lists with the
|
|
9
|
-
* same start share a definition; DocxManager gives each list its own instance
|
|
10
|
-
* for independent counting. This module owns that abstractNum shape; DocxManager
|
|
11
|
-
* owns the cross-paragraph tree walk, start recovery, and numbering-instance
|
|
12
|
-
* bookkeeping.
|
|
13
|
-
*/
|
|
14
|
-
/** Reference prefix for generated ordered-list abstractNum definitions. */
|
|
15
|
-
const ORDERED_REFERENCE_PREFIX = "docen-ordered";
|
|
16
|
-
/** lvlText per nesting depth (level 0 → "%1.", … level 8 → "%9."). */
|
|
17
|
-
const ORDERED_LEVEL_TEXT = [
|
|
18
|
-
"%1.",
|
|
19
|
-
"%2.",
|
|
20
|
-
"%3.",
|
|
21
|
-
"%4.",
|
|
22
|
-
"%5.",
|
|
23
|
-
"%6.",
|
|
24
|
-
"%7.",
|
|
25
|
-
"%8.",
|
|
26
|
-
"%9."
|
|
27
|
-
];
|
|
28
|
-
/**
|
|
29
|
-
* Build nine decimal numbering levels for an ordered list. Level 0 carries
|
|
30
|
-
* `start`; deeper levels restart at 1 (Word convention).
|
|
31
|
-
*/
|
|
32
|
-
function buildOrderedLevels(start) {
|
|
33
|
-
return Array.from({ length: 9 }, (_, level) => ({
|
|
34
|
-
level,
|
|
35
|
-
format: LevelFormat.DECIMAL,
|
|
36
|
-
start: level === 0 ? start : 1,
|
|
37
|
-
text: ORDERED_LEVEL_TEXT[level]
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
export { ORDERED_REFERENCE_PREFIX as n, buildOrderedLevels as r, ORDERED_LEVEL_TEXT as t };
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { T as Paragraph$1 } from "./tiptap-D7pl4I5U.mjs";
|
|
2
|
-
import { _ as shadingFromElement, c as indentFromElement, f as renderParagraphStyles, i as bordersFromElement, n as alignmentFromElement, x as spacingFromElement } from "./utils-BPT4tjcn.mjs";
|
|
3
|
-
//#region src/extensions/paragraph.ts
|
|
4
|
-
/**
|
|
5
|
-
* Paragraph extension with nested office-open attrs.
|
|
6
|
-
*
|
|
7
|
-
* Attrs mirror ParagraphPropertiesOptionsBase (alignment/indent/spacing/border/
|
|
8
|
-
* shading/frame as nested objects + scalar OOXML properties). DOCX round-trip is
|
|
9
|
-
* near-identity: renderDocx/parseDocx pass attrs through; CSS conversion happens
|
|
10
|
-
* only in renderHTML via utils mappers.
|
|
11
|
-
*/
|
|
12
|
-
const SECTION_ATTR_KEYS = new Set([
|
|
13
|
-
"sectionProperties",
|
|
14
|
-
"sectionHeaders",
|
|
15
|
-
"sectionFooters"
|
|
16
|
-
]);
|
|
17
|
-
function renderDocx(node) {
|
|
18
|
-
const attrs = node.attrs ?? {};
|
|
19
|
-
const opts = {};
|
|
20
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
21
|
-
if (value === null || value === void 0) continue;
|
|
22
|
-
if (SECTION_ATTR_KEYS.has(key)) continue;
|
|
23
|
-
if (key === "styleId") {
|
|
24
|
-
opts.style = value;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
opts[key] = value;
|
|
28
|
-
}
|
|
29
|
-
return opts;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Structural/semantic keys handled elsewhere (heading ext, list handling, run/text
|
|
33
|
-
* children). NOTE: `run` is intentionally NOT skipped — ParagraphOptions.run (the
|
|
34
|
-
* paragraph's default run properties: font/size/color) is kept as an attr for
|
|
35
|
-
* lossless round-trip (e.g. header/footer paragraphs whose styling lives there).
|
|
36
|
-
*/
|
|
37
|
-
const SKIP_KEYS = new Set([
|
|
38
|
-
"heading",
|
|
39
|
-
"style",
|
|
40
|
-
"bullet",
|
|
41
|
-
"numbering",
|
|
42
|
-
"children",
|
|
43
|
-
"text",
|
|
44
|
-
"thematicBreak"
|
|
45
|
-
]);
|
|
46
|
-
function parseDocx(opts) {
|
|
47
|
-
const resolved = typeof opts === "string" ? { text: opts } : opts;
|
|
48
|
-
const attrs = {};
|
|
49
|
-
if (resolved.style) attrs.styleId = resolved.style;
|
|
50
|
-
for (const [key, value] of Object.entries(resolved)) {
|
|
51
|
-
if (SKIP_KEYS.has(key)) continue;
|
|
52
|
-
attrs[key] = value ?? null;
|
|
53
|
-
}
|
|
54
|
-
return attrs;
|
|
55
|
-
}
|
|
56
|
-
const attrNative = () => ({
|
|
57
|
-
default: null,
|
|
58
|
-
parseHTML: () => null,
|
|
59
|
-
rendered: false
|
|
60
|
-
});
|
|
61
|
-
const Paragraph = Paragraph$1.extend({
|
|
62
|
-
addAttributes() {
|
|
63
|
-
return {
|
|
64
|
-
...this.parent?.(),
|
|
65
|
-
styleId: {
|
|
66
|
-
default: null,
|
|
67
|
-
parseHTML: (el) => {
|
|
68
|
-
const m = (el.getAttribute("class") || "").match(/(?:^|\s)docx-style-(\S+)/);
|
|
69
|
-
return m ? m[1] : null;
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
alignment: {
|
|
73
|
-
default: null,
|
|
74
|
-
rendered: false,
|
|
75
|
-
parseHTML: (el) => alignmentFromElement(el)
|
|
76
|
-
},
|
|
77
|
-
indent: {
|
|
78
|
-
default: null,
|
|
79
|
-
rendered: false,
|
|
80
|
-
parseHTML: (el) => indentFromElement(el)
|
|
81
|
-
},
|
|
82
|
-
spacing: {
|
|
83
|
-
default: null,
|
|
84
|
-
rendered: false,
|
|
85
|
-
parseHTML: (el) => spacingFromElement(el)
|
|
86
|
-
},
|
|
87
|
-
shading: {
|
|
88
|
-
default: null,
|
|
89
|
-
rendered: false,
|
|
90
|
-
parseHTML: (el) => shadingFromElement(el)
|
|
91
|
-
},
|
|
92
|
-
border: {
|
|
93
|
-
default: null,
|
|
94
|
-
rendered: false,
|
|
95
|
-
parseHTML: (el) => bordersFromElement(el)
|
|
96
|
-
},
|
|
97
|
-
frame: attrNative(),
|
|
98
|
-
run: attrNative(),
|
|
99
|
-
sectionProperties: attrNative(),
|
|
100
|
-
sectionHeaders: attrNative(),
|
|
101
|
-
sectionFooters: attrNative(),
|
|
102
|
-
keepNext: attrNative(),
|
|
103
|
-
keepLines: attrNative(),
|
|
104
|
-
pageBreakBefore: attrNative(),
|
|
105
|
-
widowControl: attrNative(),
|
|
106
|
-
contextualSpacing: attrNative(),
|
|
107
|
-
bidirectional: attrNative(),
|
|
108
|
-
outlineLevel: attrNative(),
|
|
109
|
-
textDirection: attrNative(),
|
|
110
|
-
textAlignment: attrNative(),
|
|
111
|
-
suppressLineNumbers: attrNative(),
|
|
112
|
-
wordWrap: attrNative(),
|
|
113
|
-
overflowPunctuation: attrNative(),
|
|
114
|
-
autoSpaceEastAsianText: attrNative(),
|
|
115
|
-
suppressOverlap: attrNative(),
|
|
116
|
-
suppressAutoHyphens: attrNative(),
|
|
117
|
-
adjustRightInd: attrNative(),
|
|
118
|
-
snapToGrid: attrNative(),
|
|
119
|
-
mirrorIndents: attrNative(),
|
|
120
|
-
kinsoku: attrNative(),
|
|
121
|
-
topLinePunct: attrNative(),
|
|
122
|
-
autoSpaceDE: attrNative(),
|
|
123
|
-
textboxTightWrap: attrNative(),
|
|
124
|
-
rightTabStop: attrNative(),
|
|
125
|
-
leftTabStop: attrNative(),
|
|
126
|
-
divId: attrNative(),
|
|
127
|
-
tabStops: attrNative(),
|
|
128
|
-
cnfStyle: attrNative()
|
|
129
|
-
};
|
|
130
|
-
},
|
|
131
|
-
renderHTML({ node, HTMLAttributes }) {
|
|
132
|
-
const styles = renderParagraphStyles(node.attrs);
|
|
133
|
-
const attrs = { ...HTMLAttributes };
|
|
134
|
-
const styleId = node.attrs.styleId;
|
|
135
|
-
attrs.class = styleId ? `docx-style-${styleId}` : "docx-default";
|
|
136
|
-
if (styles.length > 0) attrs.style = styles.join(";");
|
|
137
|
-
return [
|
|
138
|
-
"p",
|
|
139
|
-
attrs,
|
|
140
|
-
0
|
|
141
|
-
];
|
|
142
|
-
},
|
|
143
|
-
renderDocx,
|
|
144
|
-
parseDocx
|
|
145
|
-
});
|
|
146
|
-
//#endregion
|
|
147
|
-
export { parseDocx as n, renderDocx as r, Paragraph as t };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { a as JSONContent } from "./core-fBMCCj4D.mjs";
|
|
2
|
-
import { n as PrepareStep } from "./prepare-CPAvcv6q.mjs";
|
|
3
|
-
import { OutputByType, OutputType, patchDocument } from "@office-open/docx";
|
|
4
|
-
|
|
5
|
-
//#region src/converters/patch.d.ts
|
|
6
|
-
/**
|
|
7
|
-
* A patch's replacement content, expressed as Tiptap JSON. `compileDocument`
|
|
8
|
-
* converts it to office-open `SectionChild[]` before applying.
|
|
9
|
-
*/
|
|
10
|
-
interface DocxPatchContent {
|
|
11
|
-
content: JSONContent;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Options for patching a DOCX template.
|
|
15
|
-
*
|
|
16
|
-
* Mirrors the legacy `@docen/export-docx` DocxPatchOptions minus `exportOptions`
|
|
17
|
-
* — `compileDocument` already derives all styling from the Tiptap attrs, so no
|
|
18
|
-
* separate export configuration is needed.
|
|
19
|
-
*/
|
|
20
|
-
interface DocxPatchOptions<T extends OutputType = OutputType> {
|
|
21
|
-
/** Template DOCX to patch. */
|
|
22
|
-
template: Parameters<typeof patchDocument>[0]["data"];
|
|
23
|
-
/** Placeholder name → replacement content. */
|
|
24
|
-
patches: Record<string, DocxPatchContent>;
|
|
25
|
-
/**
|
|
26
|
-
* Pre-compilation steps run on each patch's content in place (default:
|
|
27
|
-
* `prepareImages()`). `false` skips; `PrepareStep[]` runs custom steps.
|
|
28
|
-
* Required when patch content references http image URLs.
|
|
29
|
-
*/
|
|
30
|
-
prepare?: boolean | PrepareStep[];
|
|
31
|
-
/** Custom placeholder delimiters (default `{{` / `}}`). */
|
|
32
|
-
placeholderDelimiters?: {
|
|
33
|
-
start?: string;
|
|
34
|
-
end?: string;
|
|
35
|
-
};
|
|
36
|
-
/** Keep the template's paragraph styles on patched content. */
|
|
37
|
-
keepOriginalStyles?: boolean;
|
|
38
|
-
/** Recurse into nested patches. */
|
|
39
|
-
recursive?: boolean;
|
|
40
|
-
/** Output container type. */
|
|
41
|
-
outputType: T;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Patch a DOCX template by replacing placeholders with Tiptap-JSON content.
|
|
45
|
-
*
|
|
46
|
-
* Each patch's `content` is prepared (default: `prepareImages`, in place) then
|
|
47
|
-
* compiled (`compileDocument` → `DocumentOptions`); its first section's
|
|
48
|
-
* `children` become the replacement. Patching is delegated to
|
|
49
|
-
* `@office-open/docx`'s `patchDocument`.
|
|
50
|
-
*/
|
|
51
|
-
declare function patchDOCX<T extends OutputType>(options: DocxPatchOptions<T>): Promise<OutputByType[T]>;
|
|
52
|
-
//#endregion
|
|
53
|
-
export { DocxPatchOptions as n, patchDOCX as r, DocxPatchContent as t };
|
package/dist/patch-IZ13tXTu.mjs
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { n as prepareDocument } from "./prepare-Bdk8Cjkf.mjs";
|
|
2
|
-
import { n as compileDocument } from "./docx-CONyAedl.mjs";
|
|
3
|
-
import { patchDocument } from "@office-open/docx";
|
|
4
|
-
//#region src/converters/patch.ts
|
|
5
|
-
/**
|
|
6
|
-
* Patch a DOCX template by replacing placeholders with Tiptap-JSON content.
|
|
7
|
-
*
|
|
8
|
-
* Each patch's `content` is prepared (default: `prepareImages`, in place) then
|
|
9
|
-
* compiled (`compileDocument` → `DocumentOptions`); its first section's
|
|
10
|
-
* `children` become the replacement. Patching is delegated to
|
|
11
|
-
* `@office-open/docx`'s `patchDocument`.
|
|
12
|
-
*/
|
|
13
|
-
async function patchDOCX(options) {
|
|
14
|
-
const { template, patches, prepare = true, placeholderDelimiters, keepOriginalStyles, recursive, outputType } = options;
|
|
15
|
-
const patchesObject = {};
|
|
16
|
-
for (const [key, patchContent] of Object.entries(patches)) {
|
|
17
|
-
if (prepare !== false) await prepareDocument(patchContent.content, prepare === true ? void 0 : prepare);
|
|
18
|
-
patchesObject[key] = {
|
|
19
|
-
type: "document",
|
|
20
|
-
children: compileDocument(patchContent.content).sections?.[0]?.children ?? []
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
return patchDocument({
|
|
24
|
-
outputType,
|
|
25
|
-
data: template,
|
|
26
|
-
placeholders: patchesObject,
|
|
27
|
-
...keepOriginalStyles !== void 0 && { keepOriginalStyles },
|
|
28
|
-
...recursive !== void 0 && { recursive },
|
|
29
|
-
...placeholderDelimiters && { placeholderDelimiters: {
|
|
30
|
-
start: placeholderDelimiters.start ?? "{{",
|
|
31
|
-
end: placeholderDelimiters.end ?? "}}"
|
|
32
|
-
} }
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
//#endregion
|
|
36
|
-
export { patchDOCX as t };
|