@docen/docx 0.3.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/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/converters/docx.d.mts +110 -0
- package/dist/converters/docx.mjs +624 -0
- package/dist/converters/html.d.mts +14 -0
- package/dist/converters/html.mjs +18 -0
- package/dist/converters/markdown.d.mts +13 -0
- package/dist/converters/markdown.mjs +18 -0
- package/dist/converters/patch.d.mts +53 -0
- package/dist/converters/patch.mjs +37 -0
- package/dist/converters/prepare.d.mts +51 -0
- package/dist/converters/prepare.mjs +76 -0
- package/dist/core-CFIQVRfx.mjs +88 -0
- package/dist/core-omBKMRtl.d.mts +34 -0
- package/dist/core.d.mts +2 -0
- package/dist/core.mjs +2 -0
- package/dist/editor.d.mts +21 -0
- package/dist/editor.mjs +20 -0
- package/dist/extensions/extensions.d.mts +12 -0
- package/dist/extensions/extensions.mjs +12 -0
- package/dist/extensions/heading.d.mts +2 -0
- package/dist/extensions/heading.mjs +145 -0
- package/dist/extensions/image.d.mts +2 -0
- package/dist/extensions/image.mjs +201 -0
- package/dist/extensions/index.d.mts +2 -0
- package/dist/extensions/index.mjs +2 -0
- package/dist/extensions/paragraph.d.mts +2 -0
- package/dist/extensions/paragraph.mjs +116 -0
- package/dist/extensions/strike.d.mts +2 -0
- package/dist/extensions/strike.mjs +50 -0
- package/dist/extensions/table-cell.d.mts +2 -0
- package/dist/extensions/table-cell.mjs +112 -0
- package/dist/extensions/table-header.d.mts +2 -0
- package/dist/extensions/table-header.mjs +112 -0
- package/dist/extensions/table-row.d.mts +2 -0
- package/dist/extensions/table-row.mjs +84 -0
- package/dist/extensions/table.d.mts +2 -0
- package/dist/extensions/table.mjs +134 -0
- package/dist/extensions/text-style.d.mts +2 -0
- package/dist/extensions/text-style.mjs +134 -0
- package/dist/extensions/tiptap.d.mts +2 -0
- package/dist/extensions/tiptap.mjs +33 -0
- package/dist/extensions/types.d.mts +30 -0
- package/dist/extensions/utils.d.mts +49 -0
- package/dist/extensions/utils.mjs +289 -0
- package/dist/heading-BvqBD2zX.d.mts +8 -0
- package/dist/image-Ge1y6uam.d.mts +47 -0
- package/dist/index.d.mts +213 -0
- package/dist/index.mjs +8 -0
- package/dist/paragraph-fhEXtAN2.d.mts +16 -0
- package/dist/strike-BgWGvjKr.d.mts +33 -0
- package/dist/table-BFkfeRp9.d.mts +9 -0
- package/dist/table-cell-D_FV4D2h.d.mts +8 -0
- package/dist/table-header-KGQ2aEkP.d.mts +8 -0
- package/dist/table-row-kgzYkZlW.d.mts +9 -0
- package/dist/text-style-BHdtXkMb.d.mts +8 -0
- package/dist/tiptap-TErPjuNJ.d.mts +33 -0
- package/package.json +106 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { a as JSONContent } from "../core-omBKMRtl.mjs";
|
|
2
|
+
import { PrepareStep } from "./prepare.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 { DocxPatchContent, DocxPatchOptions, patchDOCX };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { prepareDocument } from "./prepare.mjs";
|
|
2
|
+
import { compileDocument } from "./docx.mjs";
|
|
3
|
+
import { PatchType, 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
|
+
const children = compileDocument(patchContent.content).sections?.[0]?.children ?? [];
|
|
19
|
+
patchesObject[key] = {
|
|
20
|
+
type: PatchType.DOCUMENT,
|
|
21
|
+
children
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return patchDocument({
|
|
25
|
+
outputType,
|
|
26
|
+
data: template,
|
|
27
|
+
patches: patchesObject,
|
|
28
|
+
...keepOriginalStyles !== void 0 && { keepOriginalStyles },
|
|
29
|
+
...recursive !== void 0 && { recursive },
|
|
30
|
+
...placeholderDelimiters && { placeholderDelimiters: {
|
|
31
|
+
start: placeholderDelimiters.start ?? "{{",
|
|
32
|
+
end: placeholderDelimiters.end ?? "}}"
|
|
33
|
+
} }
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { patchDOCX };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { a as JSONContent } from "../core-omBKMRtl.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/converters/prepare.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A prepare step that transforms Tiptap JSON in place (e.g. fetch external resources).
|
|
6
|
+
*/
|
|
7
|
+
type PrepareStep = (json: JSONContent) => Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Fetch handler for external image URLs.
|
|
10
|
+
*
|
|
11
|
+
* Receives the URL, returns the image binary data.
|
|
12
|
+
* Override to customize fetching (proxy, auth, caching, etc.).
|
|
13
|
+
*/
|
|
14
|
+
type ImageFetchHandler = (url: string) => Promise<Uint8Array>;
|
|
15
|
+
/**
|
|
16
|
+
* Default fetch handler using the global `fetch` API (Node 18+ and browsers).
|
|
17
|
+
*/
|
|
18
|
+
declare function fetchImageHandler(url: string): Promise<Uint8Array>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a prepare step that fetches external image URLs and converts them to data URLs.
|
|
21
|
+
*
|
|
22
|
+
* @param handler - Custom fetch handler (defaults to `fetchImageHandler`)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```ts
|
|
26
|
+
* // Use with defaults
|
|
27
|
+
* await prepareDocument(json);
|
|
28
|
+
*
|
|
29
|
+
* // Custom handler
|
|
30
|
+
* await prepareDocument(json, [prepareImages(myHandler)]);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare function prepareImages(handler?: ImageFetchHandler): PrepareStep;
|
|
34
|
+
/**
|
|
35
|
+
* Run prepare steps on a Tiptap JSON document before compilation.
|
|
36
|
+
*
|
|
37
|
+
* Each step receives the JSON and may mutate it in place (e.g. replace external
|
|
38
|
+
* URLs with embedded data). Steps run sequentially in order.
|
|
39
|
+
*
|
|
40
|
+
* Defaults to `[prepareImages()]` when no steps are provided.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const json = parseHTML(html);
|
|
45
|
+
* await prepareDocument(json); // default: fetch images
|
|
46
|
+
* const docOpts = compileDocument(json);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
declare function prepareDocument(json: JSONContent, steps?: readonly PrepareStep[]): Promise<void>;
|
|
50
|
+
//#endregion
|
|
51
|
+
export { ImageFetchHandler, PrepareStep, fetchImageHandler, prepareDocument, prepareImages };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
//#region src/converters/prepare.ts
|
|
2
|
+
/**
|
|
3
|
+
* Default fetch handler using the global `fetch` API (Node 18+ and browsers).
|
|
4
|
+
*/
|
|
5
|
+
async function fetchImageHandler(url) {
|
|
6
|
+
const response = await fetch(url);
|
|
7
|
+
if (!response.ok) throw new Error(`Failed to fetch image from ${url}: ${response.status} ${response.statusText}`);
|
|
8
|
+
const buffer = await response.arrayBuffer();
|
|
9
|
+
return new Uint8Array(buffer);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a prepare step that fetches external image URLs and converts them to data URLs.
|
|
13
|
+
*
|
|
14
|
+
* @param handler - Custom fetch handler (defaults to `fetchImageHandler`)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* // Use with defaults
|
|
19
|
+
* await prepareDocument(json);
|
|
20
|
+
*
|
|
21
|
+
* // Custom handler
|
|
22
|
+
* await prepareDocument(json, [prepareImages(myHandler)]);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
function prepareImages(handler = fetchImageHandler) {
|
|
26
|
+
return async (json) => {
|
|
27
|
+
await walkImages(json, handler);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Built-in prepare steps, run when no custom steps are provided. */
|
|
31
|
+
const DEFAULT_STEPS = [prepareImages()];
|
|
32
|
+
/**
|
|
33
|
+
* Run prepare steps on a Tiptap JSON document before compilation.
|
|
34
|
+
*
|
|
35
|
+
* Each step receives the JSON and may mutate it in place (e.g. replace external
|
|
36
|
+
* URLs with embedded data). Steps run sequentially in order.
|
|
37
|
+
*
|
|
38
|
+
* Defaults to `[prepareImages()]` when no steps are provided.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const json = parseHTML(html);
|
|
43
|
+
* await prepareDocument(json); // default: fetch images
|
|
44
|
+
* const docOpts = compileDocument(json);
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
async function prepareDocument(json, steps = DEFAULT_STEPS) {
|
|
48
|
+
for (const step of steps) await step(json);
|
|
49
|
+
}
|
|
50
|
+
async function toDataUrl(src, handler) {
|
|
51
|
+
const data = await handler(src);
|
|
52
|
+
return `data:${{
|
|
53
|
+
jpg: "image/jpeg",
|
|
54
|
+
jpeg: "image/jpeg",
|
|
55
|
+
png: "image/png",
|
|
56
|
+
gif: "image/gif",
|
|
57
|
+
bmp: "image/bmp",
|
|
58
|
+
svg: "image/svg+xml",
|
|
59
|
+
webp: "image/webp"
|
|
60
|
+
}[src.split(".").pop()?.toLowerCase() ?? "png"] ?? "image/png"};base64,${typeof btoa !== "undefined" ? btoa(String.fromCharCode(...data)) : Buffer.from(data).toString("base64")}`;
|
|
61
|
+
}
|
|
62
|
+
async function walkImages(node, handler) {
|
|
63
|
+
if (node.type === "image" && node.attrs) {
|
|
64
|
+
const src = node.attrs.src;
|
|
65
|
+
if (src && (src.startsWith("http://") || src.startsWith("https://"))) try {
|
|
66
|
+
node.attrs.src = await toDataUrl(src, handler);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.warn(`Failed to fetch image: ${src}`, error instanceof Error ? error.message : error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const tasks = [];
|
|
72
|
+
for (const child of node.content ?? []) tasks.push(walkImages(child, handler));
|
|
73
|
+
await Promise.all(tasks);
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { fetchImageHandler, prepareDocument, prepareImages };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Blockquote, Bold, BulletList, Code, CodeBlockLowlight, Details, DetailsContent, DetailsSummary, Document, Dropcursor, Emoji, Gapcursor, HardBreak, Highlight, HorizontalRule, Italic, Link, ListItem, ListKeymap, Mathematics, Mention, OrderedList, Subscript, Superscript, TaskItem, TaskList, Text, TextAlign as TextAlign$1, TrailingNode, Underline, UndoRedo } from "./extensions/tiptap.mjs";
|
|
2
|
+
import { Heading } from "./extensions/heading.mjs";
|
|
3
|
+
import { Image } from "./extensions/image.mjs";
|
|
4
|
+
import { Paragraph } from "./extensions/paragraph.mjs";
|
|
5
|
+
import { Strike } from "./extensions/strike.mjs";
|
|
6
|
+
import { Table } from "./extensions/table.mjs";
|
|
7
|
+
import { TableCell } from "./extensions/table-cell.mjs";
|
|
8
|
+
import { TableHeader } from "./extensions/table-header.mjs";
|
|
9
|
+
import { TableRow } from "./extensions/table-row.mjs";
|
|
10
|
+
import { TextStyle } from "./extensions/text-style.mjs";
|
|
11
|
+
import { Editor, Extension, Mark, Node } from "@tiptap/core";
|
|
12
|
+
import { all, createLowlight } from "lowlight";
|
|
13
|
+
import { TextAlign } from "@tiptap/extension-text-align";
|
|
14
|
+
//#region src/extensions/extensions.ts
|
|
15
|
+
const tiptapNodeExtensions = [
|
|
16
|
+
Document,
|
|
17
|
+
Paragraph,
|
|
18
|
+
Text,
|
|
19
|
+
HardBreak,
|
|
20
|
+
Blockquote,
|
|
21
|
+
OrderedList,
|
|
22
|
+
BulletList,
|
|
23
|
+
ListItem,
|
|
24
|
+
CodeBlockLowlight.configure({ lowlight: createLowlight(all) }),
|
|
25
|
+
Details,
|
|
26
|
+
DetailsSummary,
|
|
27
|
+
DetailsContent,
|
|
28
|
+
Emoji,
|
|
29
|
+
HorizontalRule,
|
|
30
|
+
Image.configure({ inline: true }),
|
|
31
|
+
Mathematics,
|
|
32
|
+
Mention,
|
|
33
|
+
Table,
|
|
34
|
+
TableRow,
|
|
35
|
+
TableCell,
|
|
36
|
+
TableHeader,
|
|
37
|
+
TaskList,
|
|
38
|
+
TaskItem,
|
|
39
|
+
Heading,
|
|
40
|
+
TextAlign$1.configure({ types: ["heading", "paragraph"] })
|
|
41
|
+
];
|
|
42
|
+
const tiptapMarkExtensions = [
|
|
43
|
+
Bold,
|
|
44
|
+
Code,
|
|
45
|
+
Highlight,
|
|
46
|
+
Italic,
|
|
47
|
+
Link,
|
|
48
|
+
Strike,
|
|
49
|
+
Subscript,
|
|
50
|
+
Superscript,
|
|
51
|
+
TextStyle,
|
|
52
|
+
Underline
|
|
53
|
+
];
|
|
54
|
+
const docxExtensions = [...tiptapNodeExtensions, ...tiptapMarkExtensions];
|
|
55
|
+
const StarterKit = Extension.create({
|
|
56
|
+
name: "docenKit",
|
|
57
|
+
addExtensions() {
|
|
58
|
+
const extensions = [];
|
|
59
|
+
if (this.options.bold !== false) extensions.push(Bold.configure(this.options.bold));
|
|
60
|
+
if (this.options.blockquote !== false) extensions.push(Blockquote.configure(this.options.blockquote));
|
|
61
|
+
if (this.options.bulletList !== false) extensions.push(BulletList.configure(this.options.bulletList));
|
|
62
|
+
if (this.options.code !== false) extensions.push(Code.configure(this.options.code));
|
|
63
|
+
if (this.options.codeBlock !== false) extensions.push(CodeBlockLowlight.configure({
|
|
64
|
+
lowlight: createLowlight(all),
|
|
65
|
+
...this.options.codeBlock
|
|
66
|
+
}));
|
|
67
|
+
if (this.options.document !== false) extensions.push(Document);
|
|
68
|
+
if (this.options.dropcursor !== false) extensions.push(Dropcursor.configure(this.options.dropcursor));
|
|
69
|
+
if (this.options.gapcursor !== false) extensions.push(Gapcursor);
|
|
70
|
+
if (this.options.hardBreak !== false) extensions.push(HardBreak.configure(this.options.hardBreak));
|
|
71
|
+
if (this.options.heading !== false) extensions.push(Heading.configure(this.options.heading));
|
|
72
|
+
if (this.options.undoRedo !== false) extensions.push(UndoRedo.configure(this.options.undoRedo));
|
|
73
|
+
if (this.options.horizontalRule !== false) extensions.push(HorizontalRule.configure(this.options.horizontalRule));
|
|
74
|
+
if (this.options.italic !== false) extensions.push(Italic.configure(this.options.italic));
|
|
75
|
+
if (this.options.listItem !== false) extensions.push(ListItem.configure(this.options.listItem));
|
|
76
|
+
if (this.options.listKeymap !== false) extensions.push(ListKeymap.configure(this.options.listKeymap));
|
|
77
|
+
if (this.options.link !== false) extensions.push(Link.configure(this.options.link));
|
|
78
|
+
if (this.options.orderedList !== false) extensions.push(OrderedList.configure(this.options.orderedList));
|
|
79
|
+
if (this.options.paragraph !== false) extensions.push(Paragraph.configure(this.options.paragraph));
|
|
80
|
+
if (this.options.strike !== false) extensions.push(Strike.configure(this.options.strike));
|
|
81
|
+
if (this.options.text !== false) extensions.push(Text);
|
|
82
|
+
if (this.options.underline !== false) extensions.push(Underline.configure(this.options.underline));
|
|
83
|
+
if (this.options.trailingNode !== false) extensions.push(TrailingNode.configure(this.options.trailingNode));
|
|
84
|
+
return extensions;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
//#endregion
|
|
88
|
+
export { StarterKit as a, tiptapMarkExtensions as c, Node as i, tiptapNodeExtensions as l, Extension as n, TextAlign as o, Mark as r, docxExtensions as s, Editor as t };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AnyExtension, Editor, Extension, Extensions, JSONContent as JSONContent$1, Mark, Node } from "@tiptap/core";
|
|
2
|
+
import { TextAlign } from "@tiptap/extension-text-align";
|
|
3
|
+
|
|
4
|
+
//#region src/extensions/extensions.d.ts
|
|
5
|
+
declare const tiptapNodeExtensions: AnyExtension[];
|
|
6
|
+
declare const tiptapMarkExtensions: AnyExtension[];
|
|
7
|
+
declare const docxExtensions: AnyExtension[];
|
|
8
|
+
interface StarterKitOptions {
|
|
9
|
+
bold?: Record<string, any> | false;
|
|
10
|
+
blockquote?: Record<string, any> | false;
|
|
11
|
+
bulletList?: Record<string, any> | false;
|
|
12
|
+
code?: Record<string, any> | false;
|
|
13
|
+
codeBlock?: Record<string, any> | false;
|
|
14
|
+
document?: false;
|
|
15
|
+
dropcursor?: Record<string, any> | false;
|
|
16
|
+
gapcursor?: false;
|
|
17
|
+
hardBreak?: Record<string, any> | false;
|
|
18
|
+
heading?: Record<string, any> | false;
|
|
19
|
+
undoRedo?: Record<string, any> | false;
|
|
20
|
+
horizontalRule?: Record<string, any> | false;
|
|
21
|
+
italic?: Record<string, any> | false;
|
|
22
|
+
listItem?: Record<string, any> | false;
|
|
23
|
+
listKeymap?: Record<string, any> | false;
|
|
24
|
+
link?: Record<string, any> | false;
|
|
25
|
+
orderedList?: Record<string, any> | false;
|
|
26
|
+
paragraph?: Record<string, any> | false;
|
|
27
|
+
strike?: Record<string, any> | false;
|
|
28
|
+
text?: false;
|
|
29
|
+
underline?: Record<string, any> | false;
|
|
30
|
+
trailingNode?: Record<string, any> | false;
|
|
31
|
+
}
|
|
32
|
+
declare const StarterKit: Extension<StarterKitOptions, any>;
|
|
33
|
+
//#endregion
|
|
34
|
+
export { JSONContent$1 as a, StarterKit as c, docxExtensions as d, tiptapMarkExtensions as f, Extensions as i, StarterKitOptions as l, Editor as n, Mark as o, tiptapNodeExtensions as p, Extension as r, Node as s, AnyExtension as t, TextAlign as u };
|
package/dist/core.d.mts
ADDED
package/dist/core.mjs
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { n as Editor, t as AnyExtension } from "./core-omBKMRtl.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/editor.d.ts
|
|
4
|
+
interface DocxEditorOptions {
|
|
5
|
+
/** DOM element to mount the editor */
|
|
6
|
+
element: HTMLElement;
|
|
7
|
+
/** Additional Tiptap extensions */
|
|
8
|
+
extensions?: AnyExtension[];
|
|
9
|
+
/** Initial content (Tiptap JSON or HTML string) */
|
|
10
|
+
content?: Record<string, unknown> | string;
|
|
11
|
+
/** Enable spellcheck (disable for large documents) */
|
|
12
|
+
spellcheck?: boolean;
|
|
13
|
+
/** Editor is editable */
|
|
14
|
+
editable?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a Tiptap editor configured for DOCX editing.
|
|
18
|
+
*/
|
|
19
|
+
declare function createDocxEditor(options: DocxEditorOptions): Editor;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { DocxEditorOptions, createDocxEditor };
|
package/dist/editor.mjs
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { s as docxExtensions, t as Editor } from "./core-CFIQVRfx.mjs";
|
|
2
|
+
//#region src/editor.ts
|
|
3
|
+
/**
|
|
4
|
+
* Create a Tiptap editor configured for DOCX editing.
|
|
5
|
+
*/
|
|
6
|
+
function createDocxEditor(options) {
|
|
7
|
+
const { element, extensions: extraExtensions = [], content, spellcheck = true, editable = true } = options;
|
|
8
|
+
return new Editor({
|
|
9
|
+
element,
|
|
10
|
+
extensions: [...docxExtensions, ...extraExtensions],
|
|
11
|
+
content: content ?? {
|
|
12
|
+
type: "doc",
|
|
13
|
+
content: [{ type: "paragraph" }]
|
|
14
|
+
},
|
|
15
|
+
editable,
|
|
16
|
+
editorProps: { attributes: { spellcheck: spellcheck ? "true" : "false" } }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { createDocxEditor };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { B as UndoRedo, C as Mention, D as Subscript, F as Text, N as TaskItem, O as Superscript, P as TaskList, R as TrailingNode, S as Mathematics, a as CodeBlockLowlight, b as ListItem, c as DetailsSummary, d as Emoji, f as Gapcursor, g as HorizontalRule, h as Highlight, i as Code, l as Document, n as Bold, o as Details, p as HardBreak, r as BulletList, s as DetailsContent, t as Blockquote, u as Dropcursor, v as Italic, w as OrderedList, x as ListKeymap, y as Link, z as Underline } from "../tiptap-TErPjuNJ.mjs";
|
|
2
|
+
import { t as Heading } from "../heading-BvqBD2zX.mjs";
|
|
3
|
+
import { t as Image } from "../image-Ge1y6uam.mjs";
|
|
4
|
+
import { t as Paragraph } from "../paragraph-fhEXtAN2.mjs";
|
|
5
|
+
import { t as TableRow } from "../table-row-kgzYkZlW.mjs";
|
|
6
|
+
import { t as Table } from "../table-BFkfeRp9.mjs";
|
|
7
|
+
import { t as TableCell } from "../table-cell-D_FV4D2h.mjs";
|
|
8
|
+
import { t as TableHeader } from "../table-header-KGQ2aEkP.mjs";
|
|
9
|
+
import { t as Strike } from "../strike-BgWGvjKr.mjs";
|
|
10
|
+
import { t as TextStyle } from "../text-style-BHdtXkMb.mjs";
|
|
11
|
+
import { c as StarterKit, d as docxExtensions, f as tiptapMarkExtensions, l as StarterKitOptions, p as tiptapNodeExtensions, u as TextAlign } from "../core-omBKMRtl.mjs";
|
|
12
|
+
export { Blockquote, Bold, BulletList, Code, CodeBlockLowlight, Details, DetailsContent, DetailsSummary, Document, Dropcursor, Emoji, Gapcursor, HardBreak, Heading, Highlight, HorizontalRule, Image, Italic, Link, ListItem, ListKeymap, Mathematics, Mention, OrderedList, Paragraph, StarterKit, StarterKitOptions, Strike, Subscript, Superscript, Table, TableCell, TableHeader, TableRow, TaskItem, TaskList, Text, TextAlign, TextStyle, TrailingNode, Underline, UndoRedo, docxExtensions, tiptapMarkExtensions, tiptapNodeExtensions };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Blockquote, Bold, BulletList, Code, CodeBlockLowlight, Details, DetailsContent, DetailsSummary, Document, Dropcursor, Emoji, Gapcursor, HardBreak, Highlight, HorizontalRule, Italic, Link, ListItem, ListKeymap, Mathematics, Mention, OrderedList, Subscript, Superscript, TaskItem, TaskList, Text, TrailingNode, Underline, UndoRedo } from "./tiptap.mjs";
|
|
2
|
+
import { Heading } from "./heading.mjs";
|
|
3
|
+
import { Image } from "./image.mjs";
|
|
4
|
+
import { Paragraph } from "./paragraph.mjs";
|
|
5
|
+
import { Strike } from "./strike.mjs";
|
|
6
|
+
import { Table } from "./table.mjs";
|
|
7
|
+
import { TableCell } from "./table-cell.mjs";
|
|
8
|
+
import { TableHeader } from "./table-header.mjs";
|
|
9
|
+
import { TableRow } from "./table-row.mjs";
|
|
10
|
+
import { TextStyle } from "./text-style.mjs";
|
|
11
|
+
import { a as StarterKit, c as tiptapMarkExtensions, l as tiptapNodeExtensions, o as TextAlign, s as docxExtensions } from "../core-CFIQVRfx.mjs";
|
|
12
|
+
export { Blockquote, Bold, BulletList, Code, CodeBlockLowlight, Details, DetailsContent, DetailsSummary, Document, Dropcursor, Emoji, Gapcursor, HardBreak, Heading, Highlight, HorizontalRule, Image, Italic, Link, ListItem, ListKeymap, Mathematics, Mention, OrderedList, Paragraph, StarterKit, Strike, Subscript, Superscript, Table, TableCell, TableHeader, TableRow, TaskItem, TaskList, Text, TextAlign, TextStyle, TrailingNode, Underline, UndoRedo, docxExtensions, tiptapMarkExtensions, tiptapNodeExtensions };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Heading as Heading$1 } from "./tiptap.mjs";
|
|
2
|
+
import { alignmentFromElement, bordersFromElement, indentFromElement, renderParagraphStyles, shadingFromElement, spacingFromElement } from "./utils.mjs";
|
|
3
|
+
//#region src/extensions/heading.ts
|
|
4
|
+
/**
|
|
5
|
+
* Heading extension with nested office-open attrs (mirrors Paragraph).
|
|
6
|
+
*
|
|
7
|
+
* Attrs mirror ParagraphPropertiesOptionsBase (alignment/indent/spacing/border/
|
|
8
|
+
* shading/frame as nested objects + scalar OOXML properties) plus the inherited
|
|
9
|
+
* Tiptap `level` (1-6, rendered: false). DOCX round-trip is near-identity:
|
|
10
|
+
* renderDocx/parseDocx pass attrs through and only map `level` ↔ OOXML
|
|
11
|
+
* `heading` (HeadingLevel literal). CSS conversion happens solely in
|
|
12
|
+
* renderHTML via utils mappers.
|
|
13
|
+
*/
|
|
14
|
+
const HEADING_COMPILE_MAP = {
|
|
15
|
+
1: "Heading1",
|
|
16
|
+
2: "Heading2",
|
|
17
|
+
3: "Heading3",
|
|
18
|
+
4: "Heading4",
|
|
19
|
+
5: "Heading5",
|
|
20
|
+
6: "Heading6"
|
|
21
|
+
};
|
|
22
|
+
const HEADING_PARSE_MAP = {
|
|
23
|
+
Heading1: 1,
|
|
24
|
+
Heading2: 2,
|
|
25
|
+
Heading3: 3,
|
|
26
|
+
Heading4: 4,
|
|
27
|
+
Heading5: 5,
|
|
28
|
+
Heading6: 6,
|
|
29
|
+
Title: 1
|
|
30
|
+
};
|
|
31
|
+
function renderDocx(node) {
|
|
32
|
+
const attrs = node.attrs ?? {};
|
|
33
|
+
const opts = {};
|
|
34
|
+
const level = attrs.level;
|
|
35
|
+
if (level) opts.heading = HEADING_COMPILE_MAP[level] ?? "Heading1";
|
|
36
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
37
|
+
if (key === "level") continue;
|
|
38
|
+
if (value !== null && value !== void 0) opts[key] = value;
|
|
39
|
+
}
|
|
40
|
+
return opts;
|
|
41
|
+
}
|
|
42
|
+
/** Structural/semantic keys expressed elsewhere (heading handled separately, list handling, run children). */
|
|
43
|
+
const SKIP_KEYS = new Set([
|
|
44
|
+
"heading",
|
|
45
|
+
"style",
|
|
46
|
+
"bullet",
|
|
47
|
+
"numbering",
|
|
48
|
+
"run",
|
|
49
|
+
"children",
|
|
50
|
+
"text",
|
|
51
|
+
"thematicBreak"
|
|
52
|
+
]);
|
|
53
|
+
function parseDocx(opts) {
|
|
54
|
+
const resolved = typeof opts === "string" ? { text: opts } : opts;
|
|
55
|
+
const attrs = {};
|
|
56
|
+
if (resolved.heading) {
|
|
57
|
+
const level = HEADING_PARSE_MAP[resolved.heading];
|
|
58
|
+
if (level) attrs.level = level;
|
|
59
|
+
}
|
|
60
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
61
|
+
if (SKIP_KEYS.has(key)) continue;
|
|
62
|
+
attrs[key] = value ?? null;
|
|
63
|
+
}
|
|
64
|
+
return attrs;
|
|
65
|
+
}
|
|
66
|
+
const attrNative = () => ({
|
|
67
|
+
default: null,
|
|
68
|
+
parseHTML: () => null,
|
|
69
|
+
rendered: false
|
|
70
|
+
});
|
|
71
|
+
const Heading = Heading$1.extend({
|
|
72
|
+
addAttributes() {
|
|
73
|
+
return {
|
|
74
|
+
...this.parent?.(),
|
|
75
|
+
alignment: {
|
|
76
|
+
default: null,
|
|
77
|
+
rendered: false,
|
|
78
|
+
parseHTML: (el) => alignmentFromElement(el)
|
|
79
|
+
},
|
|
80
|
+
indent: {
|
|
81
|
+
default: null,
|
|
82
|
+
rendered: false,
|
|
83
|
+
parseHTML: (el) => indentFromElement(el)
|
|
84
|
+
},
|
|
85
|
+
spacing: {
|
|
86
|
+
default: null,
|
|
87
|
+
rendered: false,
|
|
88
|
+
parseHTML: (el) => spacingFromElement(el)
|
|
89
|
+
},
|
|
90
|
+
shading: {
|
|
91
|
+
default: null,
|
|
92
|
+
rendered: false,
|
|
93
|
+
parseHTML: (el) => shadingFromElement(el)
|
|
94
|
+
},
|
|
95
|
+
border: {
|
|
96
|
+
default: null,
|
|
97
|
+
rendered: false,
|
|
98
|
+
parseHTML: (el) => bordersFromElement(el)
|
|
99
|
+
},
|
|
100
|
+
frame: attrNative(),
|
|
101
|
+
keepNext: attrNative(),
|
|
102
|
+
keepLines: attrNative(),
|
|
103
|
+
pageBreakBefore: attrNative(),
|
|
104
|
+
widowControl: attrNative(),
|
|
105
|
+
contextualSpacing: attrNative(),
|
|
106
|
+
bidirectional: attrNative(),
|
|
107
|
+
outlineLevel: attrNative(),
|
|
108
|
+
textDirection: attrNative(),
|
|
109
|
+
textAlignment: attrNative(),
|
|
110
|
+
suppressLineNumbers: attrNative(),
|
|
111
|
+
wordWrap: attrNative(),
|
|
112
|
+
overflowPunctuation: attrNative(),
|
|
113
|
+
autoSpaceEastAsianText: attrNative(),
|
|
114
|
+
suppressOverlap: attrNative(),
|
|
115
|
+
suppressAutoHyphens: attrNative(),
|
|
116
|
+
adjustRightInd: attrNative(),
|
|
117
|
+
snapToGrid: attrNative(),
|
|
118
|
+
mirrorIndents: attrNative(),
|
|
119
|
+
kinsoku: attrNative(),
|
|
120
|
+
topLinePunct: attrNative(),
|
|
121
|
+
autoSpaceDE: attrNative(),
|
|
122
|
+
textboxTightWrap: attrNative(),
|
|
123
|
+
rightTabStop: attrNative(),
|
|
124
|
+
leftTabStop: attrNative(),
|
|
125
|
+
divId: attrNative(),
|
|
126
|
+
tabStops: attrNative(),
|
|
127
|
+
cnfStyle: attrNative()
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
renderHTML({ node, HTMLAttributes }) {
|
|
131
|
+
const styles = renderParagraphStyles(node.attrs);
|
|
132
|
+
const level = node.attrs?.level ?? 1;
|
|
133
|
+
const attrs = { ...HTMLAttributes };
|
|
134
|
+
if (styles.length > 0) attrs.style = styles.join(";");
|
|
135
|
+
return [
|
|
136
|
+
`h${level}`,
|
|
137
|
+
attrs,
|
|
138
|
+
0
|
|
139
|
+
];
|
|
140
|
+
},
|
|
141
|
+
renderDocx,
|
|
142
|
+
parseDocx
|
|
143
|
+
});
|
|
144
|
+
//#endregion
|
|
145
|
+
export { Heading, parseDocx, renderDocx };
|