@docen/export-docx 0.0.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 +270 -0
- package/dist/docx.cjs +1 -0
- package/dist/docx.d.cts +1 -0
- package/dist/docx.d.mts +1 -0
- package/dist/docx.d.ts +1 -0
- package/dist/docx.mjs +1 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +6798 -0
- package/dist/index.d.mts +6798 -0
- package/dist/index.d.ts +6798 -0
- package/dist/index.mjs +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Demo Macro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# @docen/export-docx
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> Export TipTap/ProseMirror editor content to Microsoft Word DOCX format.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 📝 **Rich Text Support** - Full support for headings, paragraphs, and blockquotes with proper formatting
|
|
12
|
+
- 🖼️ **Image Handling** - Automatic image sizing, positioning, and metadata extraction
|
|
13
|
+
- 📊 **Table Support** - Complete table structure with headers, cells, colspan, and rowspan
|
|
14
|
+
- ✅ **Lists & Tasks** - Bullet lists, numbered lists with custom start numbers, and task lists with checkboxes
|
|
15
|
+
- 🎨 **Text Formatting** - Bold, italic, underline, strikethrough, subscript, and superscript
|
|
16
|
+
- 🎯 **Text Styles** - Comprehensive style support including colors, backgrounds, fonts, sizes, and line heights
|
|
17
|
+
- 🔗 **Links** - Hyperlink support with href preservation
|
|
18
|
+
- 💻 **Code Blocks** - Syntax highlighted code blocks with language attribute support
|
|
19
|
+
- 📁 **Collapsible Content** - Details/summary sections for expandable content
|
|
20
|
+
- 😀 **Emoji Support** - Native emoji rendering in documents
|
|
21
|
+
- 🧮 **Mathematical Content** - LaTeX-style formula support
|
|
22
|
+
- ⚙️ **Configurable Options** - Customizable export options for documents, tables, styles, and horizontal rules
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Install with npm
|
|
28
|
+
$ npm install @docen/export-docx
|
|
29
|
+
|
|
30
|
+
# Install with yarn
|
|
31
|
+
$ yarn add @docen/export-docx
|
|
32
|
+
|
|
33
|
+
# Install with pnpm
|
|
34
|
+
$ pnpm add @docen/export-docx
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { generateDOCX } from "@docen/export-docx";
|
|
41
|
+
import { writeFileSync } from "node:fs";
|
|
42
|
+
|
|
43
|
+
// Your TipTap/ProseMirror editor content
|
|
44
|
+
const content = {
|
|
45
|
+
type: "doc",
|
|
46
|
+
content: [
|
|
47
|
+
{
|
|
48
|
+
type: "paragraph",
|
|
49
|
+
content: [
|
|
50
|
+
{
|
|
51
|
+
type: "text",
|
|
52
|
+
marks: [{ type: "bold" }, { type: "italic" }],
|
|
53
|
+
text: "Hello, world!",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Convert to DOCX and save to file
|
|
61
|
+
const docx = await generateDOCX(content, { outputType: "nodebuffer" });
|
|
62
|
+
writeFileSync("document.docx", docx);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API Reference
|
|
66
|
+
|
|
67
|
+
### `generateDOCX(content, options)`
|
|
68
|
+
|
|
69
|
+
Converts TipTap/ProseMirror content to DOCX format.
|
|
70
|
+
|
|
71
|
+
**Parameters:**
|
|
72
|
+
|
|
73
|
+
- `content: JSONContent` - TipTap/ProseMirror editor content
|
|
74
|
+
- `options: DocxExportOptions` - Export configuration options
|
|
75
|
+
|
|
76
|
+
**Returns:** `Promise<OutputByType[T]>` - DOCX file data with type matching the specified outputType
|
|
77
|
+
|
|
78
|
+
**Available Output Types:**
|
|
79
|
+
|
|
80
|
+
- `"base64"` - Base64 encoded string
|
|
81
|
+
- `"string"` - Text string
|
|
82
|
+
- `"text"` - Plain text
|
|
83
|
+
- `"binarystring"` - Binary string
|
|
84
|
+
- `"array"` - Array of numbers
|
|
85
|
+
- `"uint8array"` - Uint8Array
|
|
86
|
+
- `"arraybuffer"` - ArrayBuffer
|
|
87
|
+
- `"blob"` - Blob object
|
|
88
|
+
- `"nodebuffer"` - Node.js Buffer
|
|
89
|
+
|
|
90
|
+
**Configuration Options:**
|
|
91
|
+
|
|
92
|
+
- `title` - Document title
|
|
93
|
+
- `author` - Document author
|
|
94
|
+
- `description` - Document description
|
|
95
|
+
- `outputType` - Output format (required)
|
|
96
|
+
- `table` - Table styling defaults (alignment, spacing, borders)
|
|
97
|
+
- `styles` - Document default styles (font, line height, spacing)
|
|
98
|
+
- `horizontalRule` - Horizontal rule style
|
|
99
|
+
|
|
100
|
+
## Supported Content Types
|
|
101
|
+
|
|
102
|
+
### Text Formatting
|
|
103
|
+
|
|
104
|
+
- **Bold**, _Italic_, <u>Underline</u>, ~~Strikethrough~~
|
|
105
|
+
- ^Superscript^ and ~Subscript~
|
|
106
|
+
- Text colors and background colors
|
|
107
|
+
- Font families and sizes
|
|
108
|
+
- Line heights
|
|
109
|
+
|
|
110
|
+
### Block Elements
|
|
111
|
+
|
|
112
|
+
- **Headings** (H1-H6) with level attribute
|
|
113
|
+
- **Paragraphs** with text alignment (left, right, center, justify)
|
|
114
|
+
- **Blockquotes** (Note: Exported as indented paragraphs with left border due to DOCX format)
|
|
115
|
+
- **Horizontal Rules** (Exported as page breaks)
|
|
116
|
+
- **Code Blocks** with language support
|
|
117
|
+
|
|
118
|
+
### Lists
|
|
119
|
+
|
|
120
|
+
- **Bullet Lists** - Standard unordered lists
|
|
121
|
+
- **Numbered Lists** - Ordered lists with custom start number
|
|
122
|
+
- **Task Lists** - Checkbox lists with checked/unchecked states
|
|
123
|
+
|
|
124
|
+
### Tables
|
|
125
|
+
|
|
126
|
+
- Complete table structure with rows and cells
|
|
127
|
+
- **Table Headers** with colspan/rowspan support
|
|
128
|
+
- **Table Cells** with colspan/rowspan support
|
|
129
|
+
- Cell alignment and formatting options
|
|
130
|
+
|
|
131
|
+
### Media & Embeds
|
|
132
|
+
|
|
133
|
+
- **Images** with automatic sizing and positioning
|
|
134
|
+
- **Links** (hyperlinks) with href attribute
|
|
135
|
+
- **Emoji** rendering
|
|
136
|
+
- **Mathematics** formulas (LaTeX-style)
|
|
137
|
+
- **Details/Summary** collapsible sections
|
|
138
|
+
|
|
139
|
+
## Examples
|
|
140
|
+
|
|
141
|
+
### Document with Tables and Colspan/Rowspan
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
const content = {
|
|
145
|
+
type: "doc",
|
|
146
|
+
content: [
|
|
147
|
+
{
|
|
148
|
+
type: "table",
|
|
149
|
+
content: [
|
|
150
|
+
{
|
|
151
|
+
type: "tableRow",
|
|
152
|
+
content: [
|
|
153
|
+
{
|
|
154
|
+
type: "tableHeader",
|
|
155
|
+
attrs: { colspan: 2, rowspan: 1 },
|
|
156
|
+
content: [
|
|
157
|
+
{
|
|
158
|
+
type: "paragraph",
|
|
159
|
+
content: [{ type: "text", text: "Spanning Header" }],
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: "tableCell",
|
|
165
|
+
content: [
|
|
166
|
+
{
|
|
167
|
+
type: "paragraph",
|
|
168
|
+
content: [{ type: "text", text: "Regular Cell" }],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Document with Text Styles
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const content = {
|
|
184
|
+
type: "doc",
|
|
185
|
+
content: [
|
|
186
|
+
{
|
|
187
|
+
type: "paragraph",
|
|
188
|
+
content: [
|
|
189
|
+
{
|
|
190
|
+
type: "text",
|
|
191
|
+
marks: [
|
|
192
|
+
{
|
|
193
|
+
type: "textStyle",
|
|
194
|
+
attrs: {
|
|
195
|
+
color: "#FF0000",
|
|
196
|
+
fontSize: "18px",
|
|
197
|
+
fontFamily: "Arial",
|
|
198
|
+
backgroundColor: "#FFFF00",
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
text: "Red, 18px, Arial text on yellow background",
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Document with Lists
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
const content = {
|
|
214
|
+
type: "doc",
|
|
215
|
+
content: [
|
|
216
|
+
{
|
|
217
|
+
type: "bulletList",
|
|
218
|
+
content: [
|
|
219
|
+
{
|
|
220
|
+
type: "listItem",
|
|
221
|
+
content: [
|
|
222
|
+
{
|
|
223
|
+
type: "paragraph",
|
|
224
|
+
content: [{ type: "text", text: "First item" }],
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
type: "listItem",
|
|
230
|
+
content: [
|
|
231
|
+
{
|
|
232
|
+
type: "paragraph",
|
|
233
|
+
content: [{ type: "text", text: "Second item" }],
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
};
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Known Limitations
|
|
244
|
+
|
|
245
|
+
### Blockquote Structure
|
|
246
|
+
|
|
247
|
+
DOCX does not have a semantic blockquote structure. Blockquotes are exported as:
|
|
248
|
+
|
|
249
|
+
- Indented paragraphs (720 twips / 0.5 inch left indentation)
|
|
250
|
+
- Left border (single line)
|
|
251
|
+
|
|
252
|
+
This is a DOCX format limitation, not a bug.
|
|
253
|
+
|
|
254
|
+
### Code Marks
|
|
255
|
+
|
|
256
|
+
The `code` mark is exported as monospace font (Consolas). When re-importing, it will be recognized as `textStyle` with `fontFamily: "Consolas"`, not as a `code` mark.
|
|
257
|
+
|
|
258
|
+
This is intentional - we do not detect code marks from fonts during import to avoid false positives.
|
|
259
|
+
|
|
260
|
+
### Color Name Conversion
|
|
261
|
+
|
|
262
|
+
Color names (like `"red"`, `"green"`, `"blue"`) are automatically converted to hex values (`"#FF0000"`, `"#008000"`, `"#0000FF"`) for DOCX compatibility.
|
|
263
|
+
|
|
264
|
+
## Contributing
|
|
265
|
+
|
|
266
|
+
Contributions are welcome! Please read our [Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/) and submit pull requests to the [main repository](https://github.com/DemoMacro/docen).
|
|
267
|
+
|
|
268
|
+
## License
|
|
269
|
+
|
|
270
|
+
- [MIT](LICENSE) © [Demo Macro](https://imst.xyz/)
|
package/dist/docx.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const docx=require("docx");Object.prototype.hasOwnProperty.call(docx,"__proto__")&&!Object.prototype.hasOwnProperty.call(exports,"__proto__")&&Object.defineProperty(exports,"__proto__",{enumerable:!0,value:docx.__proto__}),Object.keys(docx).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&(exports[t]=docx[t])});
|
package/dist/docx.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'docx';
|
package/dist/docx.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'docx';
|
package/dist/docx.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'docx';
|
package/dist/docx.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export*from"docx";
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const docx=require("docx"),imageMeta=require("image-meta"),ofetch=require("ofetch");function f(t){return t?t.startsWith("#")?t:{red:"#FF0000",green:"#008000",blue:"#0000FF",yellow:"#FFFF00",orange:"#FFA500",purple:"#800080",pink:"#FFC0CB",brown:"#A52A2A",black:"#000000",white:"#FFFFFF",gray:"#808080",grey:"#808080",cyan:"#00FFFF",magenta:"#FF00FF",lime:"#00FF00",navy:"#000080",teal:"#008080",maroon:"#800000",olive:"#808000",silver:"#C0C0C0",gold:"#FFD700",indigo:"#4B0082",violet:"#EE82EE"}[t.toLowerCase()]||t:void 0}function convertText(t){const e=t.marks?.some(s=>s.type==="bold"),n=t.marks?.some(s=>s.type==="italic"),r=t.marks?.some(s=>s.type==="underline"),a=t.marks?.some(s=>s.type==="strike"),o=t.marks?.some(s=>s.type==="code"),i=t.marks?.some(s=>s.type==="subscript"),p=t.marks?.some(s=>s.type==="superscript"),w=t.marks?.find(s=>s.type==="link"),u=t.marks?.find(s=>s.type==="textStyle"),c=t.marks?.some(s=>s.type==="highlight"),g=f(u?.attrs?.color),d=f(u?.attrs?.backgroundColor);let h;if(u?.attrs?.fontSize){const s=u.attrs.fontSize;if(s.endsWith("px")){const v=parseFloat(s);isNaN(v)||(h=Math.round(v*1.5))}}let l;o?l="Consolas":u?.attrs?.fontFamily&&(l=u.attrs.fontFamily);const y={text:t.text||"",bold:e||void 0,italics:n||void 0,underline:r?{}:void 0,strike:a||void 0,font:l,size:h,subScript:i||void 0,superScript:p||void 0,color:g,shading:d?{fill:d}:void 0,highlight:c?"yellow":void 0};return w?.attrs?.href?new docx.ExternalHyperlink({children:[new docx.TextRun({...y,style:"Hyperlink"})],link:w.attrs.href}):new docx.TextRun(y)}function convertHardBreak(t){const e={text:"",break:1};if(t)for(const n of t)switch(n.type){case"bold":e.bold=!0;break;case"italic":e.italics=!0;break;case"underline":e.underline={};break;case"strike":e.strike=!0;break;case"textStyle":n.attrs?.color&&(e.color=n.attrs.color);break}return new docx.TextRun(e)}function convertParagraph(t,e){const n={children:t.content?.flatMap(r=>r.type==="text"?convertText(r):r.type==="hardBreak"?convertHardBreak(r.marks):[])||[],...e};return new docx.Paragraph(n)}function convertHeading(t){const e=t?.attrs?.level,n=t.content?.flatMap(a=>a.type==="text"?convertText(a):a.type==="hardBreak"?convertHardBreak(a.marks):[])||[],r={1:docx.HeadingLevel.HEADING_1,2:docx.HeadingLevel.HEADING_2,3:docx.HeadingLevel.HEADING_3,4:docx.HeadingLevel.HEADING_4,5:docx.HeadingLevel.HEADING_5,6:docx.HeadingLevel.HEADING_6};return new docx.Paragraph({children:n,heading:r[e]})}function convertBlockquote(t){return t.content?t.content.map(e=>{if(e.type==="paragraph"){const n=e.content?.flatMap(r=>r.type==="text"?convertText(r):r.type==="hardBreak"?convertHardBreak(r.marks):[])||[];return new docx.Paragraph({children:n,indent:{left:720},border:{left:{style:"single"}}})}return new docx.Paragraph({})}):[]}function getImageTypeFromSrc(t){if(t.startsWith("data:")){const e=t.match(/data:image\/(\w+);/);if(e)switch(e[1].toLowerCase()){case"jpg":case"jpeg":return"jpeg";case"png":return"png";case"gif":return"gif";case"bmp":return"bmp";case"tiff":return"tiff";default:return"png"}}else switch(t.split(".").pop()?.toLowerCase()){case"jpg":case"jpeg":return"jpeg";case"png":return"png";case"gif":return"gif";case"bmp":return"bmp";case"tiff":return"tiff";default:return"png"}return"png"}function createFloatingOptions(){return{horizontalPosition:{relative:"page",align:"center"},verticalPosition:{relative:"page",align:"top"},lockAnchor:!0,behindDocument:!1,inFrontOfText:!1}}function getImageWidth(t,e,n){return t.attrs?.width?t.attrs.width:e?.run?.transformation?.width?e.run.transformation.width:n?.width?Math.min(n.width,600):400}function getImageHeight(t,e,n,r){return t.attrs?.height?t.attrs.height:n?.run?.transformation?.height?n.run.transformation.height:r?.width&&r?.height?Math.round(e*r.height/r.width):300}async function getImageDataAndMeta(t){try{const e=await(await ofetch.ofetch(t,{responseType:"blob"})).bytes();let n;try{n=imageMeta.imageMeta(e)}catch(r){console.warn("Failed to extract image metadata:",r),n={width:void 0,height:void 0,type:getImageTypeFromSrc(t)||"png",orientation:void 0}}return{data:e,meta:n}}catch(e){throw console.warn(`Failed to fetch image from ${t}:`,e),e}}async function convertImage(t,e){const n=c=>{switch(c){case"jpeg":case"jpg":return"jpg";case"png":return"png";case"gif":return"gif";case"bmp":return"bmp"}switch(getImageTypeFromSrc(t.attrs?.src||"")){case"jpeg":return"jpg";case"png":return"png";case"gif":return"gif";case"bmp":return"bmp";default:return"png"}};let r,a;try{const c=t.attrs?.src||"";if(c.startsWith("http")){const g=await getImageDataAndMeta(c);r=g.data,a=g.meta}else if(c.startsWith("data:")){const g=c.split(",")[1],d=atob(g),h=new Uint8Array(d.length);for(let l=0;l<d.length;l++)h[l]=d.charCodeAt(l);r=h;try{a=imageMeta.imageMeta(r)}catch{a={type:"png",width:void 0,height:void 0,orientation:void 0}}}else throw new Error(`Unsupported image source format: ${c.substring(0,20)}...`)}catch(c){return console.warn("Failed to process image:",c),new docx.Paragraph({children:[new docx.ImageRun({type:"png",data:new Uint8Array(0),transformation:{width:100,height:100},altText:{name:t.attrs?.alt||"Failed to load image"}})]})}const o=getImageWidth(t,e,a),i=getImageHeight(t,o,e,a),p={type:n(a.type),data:r,transformation:{width:o,height:i},altText:{name:t.attrs?.alt||"",description:void 0,title:t.attrs?.title||void 0},...e?.run&&e.run.floating&&{floating:e.run.floating},...e?.run&&e.run.outline&&{outline:e.run.outline}},w=new docx.ImageRun(p),u=e?.paragraph||{};return new docx.Paragraph({children:[w],...u})}function convertTableCell(t,e){const n={children:t.content?.map(r=>convertParagraph(r,e?.cell?.paragraph??e?.row?.paragraph??e?.paragraph))||[],...e?.cell?.run};return t.attrs?.colspan&&t.attrs.colspan>1&&(n.columnSpan=t.attrs.colspan),t.attrs?.rowspan&&t.attrs.rowspan>1&&(n.rowSpan=t.attrs.rowspan),t.attrs?.colwidth!==null&&t.attrs?.colwidth!==void 0&&t.attrs.colwidth.length>0&&(n.width={size:t.attrs.colwidth[0],type:"dxa"}),new docx.TableCell(n)}function convertTableHeader(t,e){const n={children:t.content?.map(r=>convertParagraph(r,e?.header?.paragraph??e?.cell?.paragraph??e?.row?.paragraph??e?.paragraph))||[],...e?.header?.run};return t.attrs?.colspan&&t.attrs.colspan>1&&(n.columnSpan=t.attrs.colspan),t.attrs?.rowspan&&t.attrs.rowspan>1&&(n.rowSpan=t.attrs.rowspan),t.attrs?.colwidth!==null&&t.attrs?.colwidth!==void 0&&t.attrs.colwidth.length>0&&(n.width={size:t.attrs.colwidth[0],type:"dxa"}),new docx.TableCell(n)}function convertTableRow(t,e){const n=e?.row,r=t.content?.flatMap(a=>a.type==="tableCell"?convertTableCell(a,e):a.type==="tableHeader"?convertTableHeader(a,e):[])||[];return new docx.TableRow({children:r,...n})}function convertTable(t,e){const n={rows:t.content?.map(r=>convertTableRow(r,e))||[],...e?.run};return[new docx.Table(n),new docx.Paragraph({})]}function convertCodeBlock(t){const e=t.content?.map(n=>n.text||"").join("")||"";return new docx.Paragraph({children:[new docx.TextRun({text:e,font:"Consolas"})]})}function convertListItem(t,e){if(!t.content||t.content.length===0)return new docx.Paragraph({});const n=t.content[0];return n.type==="paragraph"?convertParagraph(n,e):new docx.Paragraph({})}function convertBulletList(){return{numbering:{reference:"bullet-list",level:0}}}function convertOrderedList(t){const e=t.attrs?.start||1;return{numbering:{reference:"ordered-list",level:0},start:e}}function convertList(t,e){if(!t.content)return[];const n=[],r=e==="bullet"?convertBulletList():convertOrderedList(t);let a=r.numbering.reference;e==="ordered"&&r.start&&r.start!==1&&(a=`ordered-list-start-${r.start}`);for(const o of t.content)if(o.type==="listItem"){const i=convertListItem(o,{numbering:{reference:a,level:0}});n.push(i)}return n}function convertTaskItem(t){if(!t.content||t.content.length===0)return new docx.Paragraph({});const e=t.content[0];if(e.type==="paragraph"){const n=t.attrs?.checked?"\u2611 ":"\u2610 ",r=e.content?.flatMap(o=>o.type==="text"?convertText(o):o.type==="hardBreak"?convertHardBreak(o.marks):[])||[],a=new docx.TextRun({text:n});return new docx.Paragraph({children:[a,...r]})}return new docx.Paragraph({})}function convertTaskList(t){return!t.content||t.content.length===0?[]:t.content.filter(e=>e.type==="taskItem").map(e=>convertTaskItem(e))}function convertHorizontalRule(t,e){return new docx.Paragraph({children:[],border:{bottom:{style:docx.BorderStyle.SINGLE,size:1,color:"auto"}},...e?.paragraph})}async function convertDetails(t,e){if(!t.content)return[];const n=[];let r,a;for(const o of t.content)o.type==="detailsSummary"?r=o:o.type==="detailsContent"&&(a=o);if(r?.content){const o=r.content.flatMap(p=>p.type==="text"?convertText(p):p.type==="hardBreak"?convertHardBreak(p.marks):[]),i=new docx.Paragraph({children:o,...e.details?.summary?.paragraph});n.push(i)}if(a?.content)for(const o of a.content){const i=await convertNode(o,e);Array.isArray(i)?n.push(...i):i&&n.push(i)}return n}async function generateDOCX(t,e){const{title:n,subject:r,creator:a,keywords:o,description:i,lastModifiedBy:p,revision:w,styles:u,tableOfContents:c,sections:g,fonts:d,hyphenation:h,compatibility:l,customProperties:y,evenAndOddHeaderAndFooters:s,defaultTabStop:v,outputType:F}=e,k=await convertDocumentContent(t,e),b=c?new docx.TableOfContents(c.title,{...c.run}):null,I=Q(t),m={sections:g?g.map((L,T)=>{const x=[];return T===0&&b&&x.push(b),T===0&&x.push(...k),{...L,...x.length>0?{children:x}:{}}}):[{children:b?[b,...k]:k}],title:n||"Document",subject:r||"",creator:a||"",keywords:o||"",description:i||"",lastModifiedBy:p||"",revision:w||1,styles:u,numbering:I};d&&d.length>0&&Object.assign(m,{fonts:d}),h&&Object.assign(m,{hyphenation:h}),l&&Object.assign(m,{compatibility:l}),y&&y.length>0&&Object.assign(m,{customProperties:y}),s!==void 0&&Object.assign(m,{evenAndOddHeaderAndFooters:s}),v!==void 0&&Object.assign(m,{defaultTabStop:v});const A=new docx.Document(m);return docx.Packer.pack(A,F||"arraybuffer")}async function convertDocumentContent(t,e){const n=[];if(!t||!Array.isArray(t.content))return n;for(const r of t.content){const a=await convertNode(r,e);Array.isArray(a)?n.push(...a):a&&n.push(a)}return n}async function convertNode(t,e){if(!t||!t.type)return null;switch(t.type){case"paragraph":return convertParagraph(t);case"heading":return convertHeading(t);case"blockquote":return convertBlockquote(t);case"codeBlock":return convertCodeBlock(t);case"image":return await convertImage(t,e.image);case"table":return convertTable(t,e.table);case"bulletList":return convertList(t,"bullet");case"orderedList":return convertList(t,"ordered");case"taskList":return convertTaskList(t);case"listItem":return convertListItem(t);case"taskItem":return convertTaskItem(t);case"hardBreak":return new docx.Paragraph({children:[convertHardBreak()]});case"horizontalRule":return convertHorizontalRule(t,e.horizontalRule);case"details":return await convertDetails(t,e);default:return new docx.Paragraph({children:[new docx.TextRun({text:`[Unsupported: ${t.type}]`})]})}}function Q(t){const e=new Set;function n(o){if(o.type==="orderedList"&&o.attrs?.start&&e.add(o.attrs.start),o.content)for(const i of o.content)n(i)}n(t);const r=[{level:0,format:docx.LevelFormat.BULLET,text:"\u2022",alignment:docx.AlignmentType.START,style:{paragraph:{indent:{left:docx.convertInchesToTwip(.5),hanging:docx.convertInchesToTwip(.25)}}}},{level:0,format:docx.LevelFormat.DECIMAL,text:"%1.",alignment:docx.AlignmentType.START,style:{paragraph:{indent:{left:docx.convertInchesToTwip(.5),hanging:docx.convertInchesToTwip(.25)}}}}],a=[{reference:"bullet-list",levels:[r[0]]},{reference:"ordered-list",levels:[r[1]]}];for(const o of e)o!==1&&a.push({reference:`ordered-list-start-${o}`,levels:[{level:0,format:docx.LevelFormat.DECIMAL,text:"%1.",alignment:docx.AlignmentType.START,start:o,style:{paragraph:{indent:{left:docx.convertInchesToTwip(.5),hanging:docx.convertInchesToTwip(.25)}}}}]});return{config:a}}exports.convertBlockquote=convertBlockquote,exports.convertBulletList=convertBulletList,exports.convertCodeBlock=convertCodeBlock,exports.convertDetails=convertDetails,exports.convertDocumentContent=convertDocumentContent,exports.convertHardBreak=convertHardBreak,exports.convertHeading=convertHeading,exports.convertHorizontalRule=convertHorizontalRule,exports.convertImage=convertImage,exports.convertList=convertList,exports.convertListItem=convertListItem,exports.convertNode=convertNode,exports.convertOrderedList=convertOrderedList,exports.convertParagraph=convertParagraph,exports.convertTable=convertTable,exports.convertTableCell=convertTableCell,exports.convertTableHeader=convertTableHeader,exports.convertTableRow=convertTableRow,exports.convertTaskItem=convertTaskItem,exports.convertTaskList=convertTaskList,exports.convertText=convertText,exports.createFloatingOptions=createFloatingOptions,exports.generateDOCX=generateDOCX,exports.getImageDataAndMeta=getImageDataAndMeta,exports.getImageHeight=getImageHeight,exports.getImageTypeFromSrc=getImageTypeFromSrc,exports.getImageWidth=getImageWidth;
|