@docen/export-docx 0.0.12 → 0.0.13
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 +271 -271
- package/dist/index.d.mts +252 -30
- package/dist/index.mjs +67 -59
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,271 +1,271 @@
|
|
|
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
|
-
- `creator` - Document author
|
|
94
|
-
- `description` - Document description
|
|
95
|
-
- `outputType` - Output format (required)
|
|
96
|
-
- `table` - Table styling defaults (alignment, spacing, borders)
|
|
97
|
-
- `image` - Image handling options
|
|
98
|
-
- `styles` - Document default styles (font, line height, spacing)
|
|
99
|
-
- `horizontalRule` - Horizontal rule style
|
|
100
|
-
|
|
101
|
-
## Supported Content Types
|
|
102
|
-
|
|
103
|
-
### Text Formatting
|
|
104
|
-
|
|
105
|
-
- **Bold**, _Italic_, <u>Underline</u>, ~~Strikethrough~~
|
|
106
|
-
- ^Superscript^ and ~Subscript~
|
|
107
|
-
- Text colors and background colors
|
|
108
|
-
- Font families and sizes
|
|
109
|
-
- Line heights
|
|
110
|
-
|
|
111
|
-
### Block Elements
|
|
112
|
-
|
|
113
|
-
- **Headings** (H1-H6) with level attribute
|
|
114
|
-
- **Paragraphs** with text alignment (left, right, center, justify)
|
|
115
|
-
- **Blockquotes** (Note: Exported as indented paragraphs with left border due to DOCX format)
|
|
116
|
-
- **Horizontal Rules** (Exported as page breaks by default)
|
|
117
|
-
- **Code Blocks** with language support
|
|
118
|
-
|
|
119
|
-
### Lists
|
|
120
|
-
|
|
121
|
-
- **Bullet Lists** - Standard unordered lists
|
|
122
|
-
- **Numbered Lists** - Ordered lists with custom start number
|
|
123
|
-
- **Task Lists** - Checkbox lists with checked/unchecked states
|
|
124
|
-
|
|
125
|
-
### Tables
|
|
126
|
-
|
|
127
|
-
- Complete table structure with rows and cells
|
|
128
|
-
- **Table Headers** with colspan/rowspan support
|
|
129
|
-
- **Table Cells** with colspan/rowspan support
|
|
130
|
-
- Cell alignment and formatting options
|
|
131
|
-
|
|
132
|
-
### Media & Embeds
|
|
133
|
-
|
|
134
|
-
- **Images** with automatic sizing and positioning
|
|
135
|
-
- **Links** (hyperlinks) with href attribute
|
|
136
|
-
- **Emoji** rendering
|
|
137
|
-
- **Mathematics** formulas (LaTeX-style)
|
|
138
|
-
- **Details/Summary** collapsible sections
|
|
139
|
-
|
|
140
|
-
## Examples
|
|
141
|
-
|
|
142
|
-
### Document with Tables and Colspan/Rowspan
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
const content = {
|
|
146
|
-
type: "doc",
|
|
147
|
-
content: [
|
|
148
|
-
{
|
|
149
|
-
type: "table",
|
|
150
|
-
content: [
|
|
151
|
-
{
|
|
152
|
-
type: "tableRow",
|
|
153
|
-
content: [
|
|
154
|
-
{
|
|
155
|
-
type: "tableHeader",
|
|
156
|
-
attrs: { colspan: 2, rowspan: 1 },
|
|
157
|
-
content: [
|
|
158
|
-
{
|
|
159
|
-
type: "paragraph",
|
|
160
|
-
content: [{ type: "text", text: "Spanning Header" }],
|
|
161
|
-
},
|
|
162
|
-
],
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
type: "tableCell",
|
|
166
|
-
content: [
|
|
167
|
-
{
|
|
168
|
-
type: "paragraph",
|
|
169
|
-
content: [{ type: "text", text: "Regular Cell" }],
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
},
|
|
177
|
-
],
|
|
178
|
-
};
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Document with Text Styles
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
const content = {
|
|
185
|
-
type: "doc",
|
|
186
|
-
content: [
|
|
187
|
-
{
|
|
188
|
-
type: "paragraph",
|
|
189
|
-
content: [
|
|
190
|
-
{
|
|
191
|
-
type: "text",
|
|
192
|
-
marks: [
|
|
193
|
-
{
|
|
194
|
-
type: "textStyle",
|
|
195
|
-
attrs: {
|
|
196
|
-
color: "#FF0000",
|
|
197
|
-
fontSize: "18px",
|
|
198
|
-
fontFamily: "Arial",
|
|
199
|
-
backgroundColor: "#FFFF00",
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
],
|
|
203
|
-
text: "Red, 18px, Arial text on yellow background",
|
|
204
|
-
},
|
|
205
|
-
],
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
};
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Document with Lists
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
const content = {
|
|
215
|
-
type: "doc",
|
|
216
|
-
content: [
|
|
217
|
-
{
|
|
218
|
-
type: "bulletList",
|
|
219
|
-
content: [
|
|
220
|
-
{
|
|
221
|
-
type: "listItem",
|
|
222
|
-
content: [
|
|
223
|
-
{
|
|
224
|
-
type: "paragraph",
|
|
225
|
-
content: [{ type: "text", text: "First item" }],
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
type: "listItem",
|
|
231
|
-
content: [
|
|
232
|
-
{
|
|
233
|
-
type: "paragraph",
|
|
234
|
-
content: [{ type: "text", text: "Second item" }],
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
},
|
|
238
|
-
],
|
|
239
|
-
},
|
|
240
|
-
],
|
|
241
|
-
};
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
## Known Limitations
|
|
245
|
-
|
|
246
|
-
### Blockquote Structure
|
|
247
|
-
|
|
248
|
-
DOCX does not have a semantic blockquote structure. Blockquotes are exported as:
|
|
249
|
-
|
|
250
|
-
- Indented paragraphs (720 twips / 0.5 inch left indentation)
|
|
251
|
-
- Left border (single line)
|
|
252
|
-
|
|
253
|
-
This is a DOCX format limitation, not a bug.
|
|
254
|
-
|
|
255
|
-
### Code Marks
|
|
256
|
-
|
|
257
|
-
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.
|
|
258
|
-
|
|
259
|
-
This is intentional - we do not detect code marks from fonts during import to avoid false positives.
|
|
260
|
-
|
|
261
|
-
### Color Name Conversion
|
|
262
|
-
|
|
263
|
-
Color names (like `"red"`, `"green"`, `"blue"`) are automatically converted to hex values (`"#FF0000"`, `"#008000"`, `"#0000FF"`) for DOCX compatibility.
|
|
264
|
-
|
|
265
|
-
## Contributing
|
|
266
|
-
|
|
267
|
-
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).
|
|
268
|
-
|
|
269
|
-
## License
|
|
270
|
-
|
|
271
|
-
- [MIT](LICENSE) © [Demo Macro](https://imst.xyz/)
|
|
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
|
+
- `creator` - Document author
|
|
94
|
+
- `description` - Document description
|
|
95
|
+
- `outputType` - Output format (required)
|
|
96
|
+
- `table` - Table styling defaults (alignment, spacing, borders)
|
|
97
|
+
- `image` - Image handling options
|
|
98
|
+
- `styles` - Document default styles (font, line height, spacing)
|
|
99
|
+
- `horizontalRule` - Horizontal rule style
|
|
100
|
+
|
|
101
|
+
## Supported Content Types
|
|
102
|
+
|
|
103
|
+
### Text Formatting
|
|
104
|
+
|
|
105
|
+
- **Bold**, _Italic_, <u>Underline</u>, ~~Strikethrough~~
|
|
106
|
+
- ^Superscript^ and ~Subscript~
|
|
107
|
+
- Text colors and background colors
|
|
108
|
+
- Font families and sizes
|
|
109
|
+
- Line heights
|
|
110
|
+
|
|
111
|
+
### Block Elements
|
|
112
|
+
|
|
113
|
+
- **Headings** (H1-H6) with level attribute
|
|
114
|
+
- **Paragraphs** with text alignment (left, right, center, justify)
|
|
115
|
+
- **Blockquotes** (Note: Exported as indented paragraphs with left border due to DOCX format)
|
|
116
|
+
- **Horizontal Rules** (Exported as page breaks by default)
|
|
117
|
+
- **Code Blocks** with language support
|
|
118
|
+
|
|
119
|
+
### Lists
|
|
120
|
+
|
|
121
|
+
- **Bullet Lists** - Standard unordered lists
|
|
122
|
+
- **Numbered Lists** - Ordered lists with custom start number
|
|
123
|
+
- **Task Lists** - Checkbox lists with checked/unchecked states
|
|
124
|
+
|
|
125
|
+
### Tables
|
|
126
|
+
|
|
127
|
+
- Complete table structure with rows and cells
|
|
128
|
+
- **Table Headers** with colspan/rowspan support
|
|
129
|
+
- **Table Cells** with colspan/rowspan support
|
|
130
|
+
- Cell alignment and formatting options
|
|
131
|
+
|
|
132
|
+
### Media & Embeds
|
|
133
|
+
|
|
134
|
+
- **Images** with automatic sizing and positioning
|
|
135
|
+
- **Links** (hyperlinks) with href attribute
|
|
136
|
+
- **Emoji** rendering
|
|
137
|
+
- **Mathematics** formulas (LaTeX-style)
|
|
138
|
+
- **Details/Summary** collapsible sections
|
|
139
|
+
|
|
140
|
+
## Examples
|
|
141
|
+
|
|
142
|
+
### Document with Tables and Colspan/Rowspan
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
const content = {
|
|
146
|
+
type: "doc",
|
|
147
|
+
content: [
|
|
148
|
+
{
|
|
149
|
+
type: "table",
|
|
150
|
+
content: [
|
|
151
|
+
{
|
|
152
|
+
type: "tableRow",
|
|
153
|
+
content: [
|
|
154
|
+
{
|
|
155
|
+
type: "tableHeader",
|
|
156
|
+
attrs: { colspan: 2, rowspan: 1 },
|
|
157
|
+
content: [
|
|
158
|
+
{
|
|
159
|
+
type: "paragraph",
|
|
160
|
+
content: [{ type: "text", text: "Spanning Header" }],
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
type: "tableCell",
|
|
166
|
+
content: [
|
|
167
|
+
{
|
|
168
|
+
type: "paragraph",
|
|
169
|
+
content: [{ type: "text", text: "Regular Cell" }],
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
};
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Document with Text Styles
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const content = {
|
|
185
|
+
type: "doc",
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: "paragraph",
|
|
189
|
+
content: [
|
|
190
|
+
{
|
|
191
|
+
type: "text",
|
|
192
|
+
marks: [
|
|
193
|
+
{
|
|
194
|
+
type: "textStyle",
|
|
195
|
+
attrs: {
|
|
196
|
+
color: "#FF0000",
|
|
197
|
+
fontSize: "18px",
|
|
198
|
+
fontFamily: "Arial",
|
|
199
|
+
backgroundColor: "#FFFF00",
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
],
|
|
203
|
+
text: "Red, 18px, Arial text on yellow background",
|
|
204
|
+
},
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Document with Lists
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const content = {
|
|
215
|
+
type: "doc",
|
|
216
|
+
content: [
|
|
217
|
+
{
|
|
218
|
+
type: "bulletList",
|
|
219
|
+
content: [
|
|
220
|
+
{
|
|
221
|
+
type: "listItem",
|
|
222
|
+
content: [
|
|
223
|
+
{
|
|
224
|
+
type: "paragraph",
|
|
225
|
+
content: [{ type: "text", text: "First item" }],
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
type: "listItem",
|
|
231
|
+
content: [
|
|
232
|
+
{
|
|
233
|
+
type: "paragraph",
|
|
234
|
+
content: [{ type: "text", text: "Second item" }],
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
},
|
|
238
|
+
],
|
|
239
|
+
},
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Known Limitations
|
|
245
|
+
|
|
246
|
+
### Blockquote Structure
|
|
247
|
+
|
|
248
|
+
DOCX does not have a semantic blockquote structure. Blockquotes are exported as:
|
|
249
|
+
|
|
250
|
+
- Indented paragraphs (720 twips / 0.5 inch left indentation)
|
|
251
|
+
- Left border (single line)
|
|
252
|
+
|
|
253
|
+
This is a DOCX format limitation, not a bug.
|
|
254
|
+
|
|
255
|
+
### Code Marks
|
|
256
|
+
|
|
257
|
+
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.
|
|
258
|
+
|
|
259
|
+
This is intentional - we do not detect code marks from fonts during import to avoid false positives.
|
|
260
|
+
|
|
261
|
+
### Color Name Conversion
|
|
262
|
+
|
|
263
|
+
Color names (like `"red"`, `"green"`, `"blue"`) are automatically converted to hex values (`"#FF0000"`, `"#008000"`, `"#0000FF"`) for DOCX compatibility.
|
|
264
|
+
|
|
265
|
+
## Contributing
|
|
266
|
+
|
|
267
|
+
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).
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
|
|
271
|
+
- [MIT](LICENSE) © [Demo Macro](https://imst.xyz/)
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ExternalHyperlink, FileChild,
|
|
1
|
+
import { ExternalHyperlink, FileChild, IImageOptions, IParagraphOptions, IParagraphStyleOptions, IPropertiesOptions, ISectionOptions, ITableCellOptions, ITableOfContentsOptions, ITableOptions, ITableRowOptions, ImageRun, OutputByType, OutputType, PositiveUniversalMeasure as PositiveUniversalMeasure$1, Table, TableCell, TableRow, TextRun } from "docx";
|
|
2
2
|
import { ImageMeta } from "image-meta";
|
|
3
3
|
|
|
4
4
|
//#region ../../node_modules/.pnpm/orderedmap@2.1.1/node_modules/orderedmap/dist/index.d.ts
|
|
@@ -3672,7 +3672,7 @@ point into textblock nodes. It can be empty (a regular cursor
|
|
|
3672
3672
|
position).
|
|
3673
3673
|
*/
|
|
3674
3674
|
//#endregion
|
|
3675
|
-
//#region ../../node_modules/.pnpm/@tiptap+core@3.20.
|
|
3675
|
+
//#region ../../node_modules/.pnpm/@tiptap+core@3.20.0_@tiptap+pm@3.20.0/node_modules/@tiptap/core/dist/index.d.ts
|
|
3676
3676
|
type StringKeyOf<T> = Extract<keyof T, string>;
|
|
3677
3677
|
type CallbackType<T extends Record<string, any>, EventName extends StringKeyOf<T>> = T[EventName] extends any[] ? T[EventName] : [T[EventName]];
|
|
3678
3678
|
type CallbackFunction<T extends Record<string, any>, EventName extends StringKeyOf<T>> = (...props: CallbackType<T, EventName>) => any;
|
|
@@ -6763,12 +6763,225 @@ declare function convertDocument(node: JSONContent, params: {
|
|
|
6763
6763
|
declare function convertNode(node: JSONContent, options: DocxExportOptions, effectiveContentWidth: number): Promise<FileChild | FileChild[] | null>;
|
|
6764
6764
|
//#endregion
|
|
6765
6765
|
//#region ../extensions/dist/types.d.mts
|
|
6766
|
+
//#region ../../node_modules/.pnpm/docx@9.6.1/node_modules/docx/dist/index.d.ts
|
|
6767
|
+
declare const CompoundLine: {
|
|
6768
|
+
readonly SINGLE: "sng";
|
|
6769
|
+
readonly DOUBLE: "dbl";
|
|
6770
|
+
readonly THICK_THIN: "thickThin";
|
|
6771
|
+
readonly THIN_THICK: "thinThick";
|
|
6772
|
+
readonly TRI: "tri";
|
|
6773
|
+
};
|
|
6774
|
+
declare type CoreImageOptions = {
|
|
6775
|
+
readonly transformation: IMediaTransformation;
|
|
6776
|
+
readonly floating?: IFloating;
|
|
6777
|
+
readonly altText?: DocPropertiesOptions;
|
|
6778
|
+
readonly outline?: OutlineOptions;
|
|
6779
|
+
readonly solidFill?: SolidFillOptions;
|
|
6780
|
+
};
|
|
6781
|
+
declare type DocPropertiesOptions = {
|
|
6782
|
+
readonly name: string;
|
|
6783
|
+
readonly description?: string;
|
|
6784
|
+
readonly title?: string;
|
|
6785
|
+
readonly id?: string;
|
|
6786
|
+
};
|
|
6787
|
+
declare const HorizontalPositionAlign: {
|
|
6788
|
+
readonly CENTER: "center";
|
|
6789
|
+
readonly INSIDE: "inside";
|
|
6790
|
+
readonly LEFT: "left";
|
|
6791
|
+
readonly OUTSIDE: "outside";
|
|
6792
|
+
readonly RIGHT: "right";
|
|
6793
|
+
};
|
|
6794
|
+
declare const HorizontalPositionRelativeFrom: {
|
|
6795
|
+
readonly CHARACTER: "character";
|
|
6796
|
+
readonly COLUMN: "column";
|
|
6797
|
+
readonly INSIDE_MARGIN: "insideMargin";
|
|
6798
|
+
readonly LEFT_MARGIN: "leftMargin";
|
|
6799
|
+
readonly MARGIN: "margin";
|
|
6800
|
+
readonly OUTSIDE_MARGIN: "outsideMargin";
|
|
6801
|
+
readonly PAGE: "page";
|
|
6802
|
+
readonly RIGHT_MARGIN: "rightMargin";
|
|
6803
|
+
};
|
|
6804
|
+
declare type IDistance = {
|
|
6805
|
+
readonly distT?: number;
|
|
6806
|
+
readonly distB?: number;
|
|
6807
|
+
readonly distL?: number;
|
|
6808
|
+
readonly distR?: number;
|
|
6809
|
+
};
|
|
6810
|
+
declare type IFloating = {
|
|
6811
|
+
readonly horizontalPosition: IHorizontalPositionOptions;
|
|
6812
|
+
readonly verticalPosition: IVerticalPositionOptions;
|
|
6813
|
+
readonly allowOverlap?: boolean;
|
|
6814
|
+
readonly lockAnchor?: boolean;
|
|
6815
|
+
readonly behindDocument?: boolean;
|
|
6816
|
+
readonly layoutInCell?: boolean;
|
|
6817
|
+
readonly margins?: IMargins;
|
|
6818
|
+
readonly wrap?: ITextWrapping;
|
|
6819
|
+
readonly zIndex?: number;
|
|
6820
|
+
};
|
|
6821
|
+
declare type IHorizontalPositionOptions = {
|
|
6822
|
+
readonly relative?: (typeof HorizontalPositionRelativeFrom)[keyof typeof HorizontalPositionRelativeFrom];
|
|
6823
|
+
readonly align?: (typeof HorizontalPositionAlign)[keyof typeof HorizontalPositionAlign];
|
|
6824
|
+
readonly offset?: number;
|
|
6825
|
+
};
|
|
6826
|
+
declare type IImageOptions$1 = (RegularImageOptions | SvgMediaOptions) & CoreImageOptions;
|
|
6827
|
+
declare type IMargins = {
|
|
6828
|
+
readonly left?: number;
|
|
6829
|
+
readonly bottom?: number;
|
|
6830
|
+
readonly top?: number;
|
|
6831
|
+
readonly right?: number;
|
|
6832
|
+
};
|
|
6833
|
+
declare type IMediaTransformation = {
|
|
6834
|
+
readonly offset?: {
|
|
6835
|
+
readonly top?: number;
|
|
6836
|
+
readonly left?: number;
|
|
6837
|
+
};
|
|
6838
|
+
readonly width: number;
|
|
6839
|
+
readonly height: number;
|
|
6840
|
+
readonly flip?: {
|
|
6841
|
+
readonly vertical?: boolean;
|
|
6842
|
+
readonly horizontal?: boolean;
|
|
6843
|
+
};
|
|
6844
|
+
readonly rotation?: number;
|
|
6845
|
+
};
|
|
6846
|
+
declare type ITextWrapping = {
|
|
6847
|
+
readonly type: (typeof TextWrappingType)[keyof typeof TextWrappingType];
|
|
6848
|
+
readonly side?: (typeof TextWrappingSide)[keyof typeof TextWrappingSide];
|
|
6849
|
+
readonly margins?: IDistance;
|
|
6850
|
+
};
|
|
6851
|
+
declare type IVerticalPositionOptions = {
|
|
6852
|
+
readonly relative?: (typeof VerticalPositionRelativeFrom)[keyof typeof VerticalPositionRelativeFrom];
|
|
6853
|
+
readonly align?: (typeof VerticalPositionAlign)[keyof typeof VerticalPositionAlign];
|
|
6854
|
+
readonly offset?: number;
|
|
6855
|
+
};
|
|
6856
|
+
declare const LineCap: {
|
|
6857
|
+
readonly ROUND: "rnd";
|
|
6858
|
+
readonly SQUARE: "sq";
|
|
6859
|
+
readonly FLAT: "flat";
|
|
6860
|
+
};
|
|
6861
|
+
declare type OutlineAttributes = {
|
|
6862
|
+
readonly width?: number;
|
|
6863
|
+
readonly cap?: keyof typeof LineCap;
|
|
6864
|
+
readonly compoundLine?: keyof typeof CompoundLine;
|
|
6865
|
+
readonly align?: keyof typeof PenAlignment;
|
|
6866
|
+
};
|
|
6867
|
+
declare type OutlineFillProperties = OutlineNoFill | OutlineSolidFill;
|
|
6868
|
+
declare type OutlineNoFill = {
|
|
6869
|
+
readonly type: "noFill";
|
|
6870
|
+
};
|
|
6871
|
+
declare type OutlineOptions = OutlineAttributes & OutlineFillProperties;
|
|
6872
|
+
declare type OutlineRgbSolidFill = {
|
|
6873
|
+
readonly type: "solidFill";
|
|
6874
|
+
readonly solidFillType: "rgb";
|
|
6875
|
+
readonly value: string;
|
|
6876
|
+
};
|
|
6877
|
+
declare type OutlineSchemeSolidFill = {
|
|
6878
|
+
readonly type: "solidFill";
|
|
6879
|
+
readonly solidFillType: "scheme";
|
|
6880
|
+
readonly value: (typeof SchemeColor)[keyof typeof SchemeColor];
|
|
6881
|
+
};
|
|
6882
|
+
declare type OutlineSolidFill = OutlineRgbSolidFill | OutlineSchemeSolidFill;
|
|
6883
|
+
declare const PenAlignment: {
|
|
6884
|
+
readonly CENTER: "ctr";
|
|
6885
|
+
readonly INSET: "in";
|
|
6886
|
+
};
|
|
6887
|
+
declare type RegularImageOptions = {
|
|
6888
|
+
readonly type: "jpg" | "png" | "gif" | "bmp";
|
|
6889
|
+
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
|
6890
|
+
};
|
|
6891
|
+
declare type RgbColorOptions = {
|
|
6892
|
+
readonly type: "rgb";
|
|
6893
|
+
readonly value: string;
|
|
6894
|
+
};
|
|
6895
|
+
declare const SchemeColor: {
|
|
6896
|
+
readonly BG1: "bg1";
|
|
6897
|
+
readonly TX1: "tx1";
|
|
6898
|
+
readonly BG2: "bg2";
|
|
6899
|
+
readonly TX2: "tx2";
|
|
6900
|
+
readonly ACCENT1: "accent1";
|
|
6901
|
+
readonly ACCENT2: "accent2";
|
|
6902
|
+
readonly ACCENT3: "accent3";
|
|
6903
|
+
readonly ACCENT4: "accent4";
|
|
6904
|
+
readonly ACCENT5: "accent5";
|
|
6905
|
+
readonly ACCENT6: "accent6";
|
|
6906
|
+
readonly HLINK: "hlink";
|
|
6907
|
+
readonly FOLHLINK: "folHlink";
|
|
6908
|
+
readonly DK1: "dk1";
|
|
6909
|
+
readonly LT1: "lt1";
|
|
6910
|
+
readonly DK2: "dk2";
|
|
6911
|
+
readonly LT2: "lt2";
|
|
6912
|
+
readonly PHCLR: "phClr";
|
|
6913
|
+
};
|
|
6914
|
+
declare type SchemeColorOptions = {
|
|
6915
|
+
readonly type: "scheme";
|
|
6916
|
+
readonly value: (typeof SchemeColor)[keyof typeof SchemeColor];
|
|
6917
|
+
};
|
|
6918
|
+
declare type SolidFillOptions = RgbColorOptions | SchemeColorOptions;
|
|
6919
|
+
declare type SvgMediaOptions = {
|
|
6920
|
+
readonly type: "svg";
|
|
6921
|
+
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
|
6922
|
+
readonly fallback: RegularImageOptions;
|
|
6923
|
+
};
|
|
6924
|
+
declare const TextWrappingSide: {
|
|
6925
|
+
readonly BOTH_SIDES: "bothSides";
|
|
6926
|
+
readonly LEFT: "left";
|
|
6927
|
+
readonly RIGHT: "right";
|
|
6928
|
+
readonly LARGEST: "largest";
|
|
6929
|
+
};
|
|
6930
|
+
declare const TextWrappingType: {
|
|
6931
|
+
readonly NONE: 0;
|
|
6932
|
+
readonly SQUARE: 1;
|
|
6933
|
+
readonly TIGHT: 2;
|
|
6934
|
+
readonly TOP_AND_BOTTOM: 3;
|
|
6935
|
+
};
|
|
6936
|
+
declare const VerticalPositionAlign: {
|
|
6937
|
+
readonly BOTTOM: "bottom";
|
|
6938
|
+
readonly CENTER: "center";
|
|
6939
|
+
readonly INSIDE: "inside";
|
|
6940
|
+
readonly OUTSIDE: "outside";
|
|
6941
|
+
readonly TOP: "top";
|
|
6942
|
+
};
|
|
6943
|
+
declare const VerticalPositionRelativeFrom: {
|
|
6944
|
+
readonly BOTTOM_MARGIN: "bottomMargin";
|
|
6945
|
+
readonly INSIDE_MARGIN: "insideMargin";
|
|
6946
|
+
readonly LINE: "line";
|
|
6947
|
+
readonly MARGIN: "margin";
|
|
6948
|
+
readonly OUTSIDE_MARGIN: "outsideMargin";
|
|
6949
|
+
readonly PAGE: "page";
|
|
6950
|
+
readonly PARAGRAPH: "paragraph";
|
|
6951
|
+
readonly TOP_MARGIN: "topMargin";
|
|
6952
|
+
}; //#endregion
|
|
6766
6953
|
//#region src/types.d.ts
|
|
6954
|
+
/**
|
|
6955
|
+
* Border definition (compatible with docx.js BorderOptions)
|
|
6956
|
+
* Used by paragraphs, table cells, and blockquotes
|
|
6957
|
+
*/
|
|
6958
|
+
interface Border {
|
|
6959
|
+
/** Border color (hex without #, e.g., "FF0000" or "auto") */
|
|
6960
|
+
color?: string;
|
|
6961
|
+
/** Border size (eighth-points, 1/8 pt) */
|
|
6962
|
+
size?: number;
|
|
6963
|
+
/** Border style */
|
|
6964
|
+
style?: "single" | "dashed" | "dotted" | "double" | "dotDash" | "dotDotDash" | "none";
|
|
6965
|
+
/** Space between border and content (points) */
|
|
6966
|
+
space?: number;
|
|
6967
|
+
}
|
|
6968
|
+
/**
|
|
6969
|
+
* Shading definition (compatible with docx.js ShadingOptions)
|
|
6970
|
+
* Used for paragraph and table cell background colors
|
|
6971
|
+
*/
|
|
6972
|
+
interface Shading {
|
|
6973
|
+
/** Fill color (hex without #, e.g., "FF0000") */
|
|
6974
|
+
fill?: string;
|
|
6975
|
+
/** Pattern color (hex without #) */
|
|
6976
|
+
color?: string;
|
|
6977
|
+
/** Shading pattern type (e.g., "clear", "percent-10") */
|
|
6978
|
+
type?: string;
|
|
6979
|
+
}
|
|
6767
6980
|
type ImageFloatingOptions = {
|
|
6768
6981
|
horizontalPosition: IHorizontalPositionOptions;
|
|
6769
6982
|
verticalPosition: IVerticalPositionOptions;
|
|
6770
6983
|
} & Partial<Omit<IFloating, "horizontalPosition" | "verticalPosition">>;
|
|
6771
|
-
type ImageOutlineOptions = IImageOptions["outline"];
|
|
6984
|
+
type ImageOutlineOptions = IImageOptions$1["outline"];
|
|
6772
6985
|
interface TextNode {
|
|
6773
6986
|
type: "text";
|
|
6774
6987
|
text: string;
|
|
@@ -6806,6 +7019,11 @@ interface ParagraphNode extends JSONContent {
|
|
|
6806
7019
|
indentFirstLine?: string;
|
|
6807
7020
|
spacingBefore?: string;
|
|
6808
7021
|
spacingAfter?: string;
|
|
7022
|
+
shading?: Shading;
|
|
7023
|
+
borderTop?: Border;
|
|
7024
|
+
borderBottom?: Border;
|
|
7025
|
+
borderLeft?: Border;
|
|
7026
|
+
borderRight?: Border;
|
|
6809
7027
|
};
|
|
6810
7028
|
content?: Array<TextNode | HardBreakNode | ImageNode>;
|
|
6811
7029
|
}
|
|
@@ -6819,6 +7037,11 @@ interface HeadingNode extends JSONContent {
|
|
|
6819
7037
|
spacingBefore?: string;
|
|
6820
7038
|
spacingAfter?: string;
|
|
6821
7039
|
textAlign?: "left" | "right" | "center" | "justify";
|
|
7040
|
+
shading?: Shading;
|
|
7041
|
+
borderTop?: Border;
|
|
7042
|
+
borderBottom?: Border;
|
|
7043
|
+
borderLeft?: Border;
|
|
7044
|
+
borderRight?: Border;
|
|
6822
7045
|
};
|
|
6823
7046
|
content?: Array<TextNode | HardBreakNode>;
|
|
6824
7047
|
}
|
|
@@ -6864,11 +7087,6 @@ interface TaskItemNode extends JSONContent {
|
|
|
6864
7087
|
};
|
|
6865
7088
|
content?: Array<ParagraphNode>;
|
|
6866
7089
|
}
|
|
6867
|
-
interface TableCellBorder {
|
|
6868
|
-
color?: string;
|
|
6869
|
-
width?: number;
|
|
6870
|
-
style?: "solid" | "dashed" | "dotted" | "double" | "none";
|
|
6871
|
-
}
|
|
6872
7090
|
interface TableNode extends JSONContent {
|
|
6873
7091
|
type: "table";
|
|
6874
7092
|
attrs?: {
|
|
@@ -6894,10 +7112,10 @@ interface TableCellNode extends JSONContent {
|
|
|
6894
7112
|
colwidth?: number[] | null;
|
|
6895
7113
|
backgroundColor?: string | null;
|
|
6896
7114
|
verticalAlign?: "top" | "middle" | "bottom" | null;
|
|
6897
|
-
borderTop?:
|
|
6898
|
-
borderBottom?:
|
|
6899
|
-
borderLeft?:
|
|
6900
|
-
borderRight?:
|
|
7115
|
+
borderTop?: Border;
|
|
7116
|
+
borderBottom?: Border;
|
|
7117
|
+
borderLeft?: Border;
|
|
7118
|
+
borderRight?: Border;
|
|
6901
7119
|
};
|
|
6902
7120
|
content?: Array<ParagraphNode>;
|
|
6903
7121
|
}
|
|
@@ -6909,10 +7127,10 @@ interface TableHeaderNode extends JSONContent {
|
|
|
6909
7127
|
colwidth?: number[] | null;
|
|
6910
7128
|
backgroundColor?: string | null;
|
|
6911
7129
|
verticalAlign?: "top" | "middle" | "bottom" | null;
|
|
6912
|
-
borderTop?:
|
|
6913
|
-
borderBottom?:
|
|
6914
|
-
borderLeft?:
|
|
6915
|
-
borderRight?:
|
|
7130
|
+
borderTop?: Border;
|
|
7131
|
+
borderBottom?: Border;
|
|
7132
|
+
borderLeft?: Border;
|
|
7133
|
+
borderRight?: Border;
|
|
6916
7134
|
};
|
|
6917
7135
|
content?: Array<ParagraphNode>;
|
|
6918
7136
|
}
|
|
@@ -7632,26 +7850,30 @@ declare function createStringValidator<T extends string>(validValues: readonly T
|
|
|
7632
7850
|
* Calculate effective content width from document options
|
|
7633
7851
|
*/
|
|
7634
7852
|
declare function calculateEffectiveContentWidth(options?: DocxExportOptions): number;
|
|
7635
|
-
//#endregion
|
|
7636
|
-
//#region src/utils/paragraph.d.ts
|
|
7637
7853
|
/**
|
|
7638
|
-
*
|
|
7854
|
+
* Convert Border to docx.js format
|
|
7639
7855
|
*/
|
|
7640
|
-
declare
|
|
7641
|
-
|
|
7642
|
-
|
|
7856
|
+
declare function convertBorder(border?: Border): {
|
|
7857
|
+
color?: string;
|
|
7858
|
+
size?: number;
|
|
7859
|
+
style?: string;
|
|
7860
|
+
space?: number;
|
|
7861
|
+
} | undefined;
|
|
7643
7862
|
/**
|
|
7644
|
-
* Convert
|
|
7645
|
-
*
|
|
7646
|
-
* @param border - TipTap table cell border definition
|
|
7647
|
-
* @returns DOCX border options or undefined if no border
|
|
7863
|
+
* Convert Shading to docx.js format
|
|
7648
7864
|
*/
|
|
7649
|
-
declare function
|
|
7865
|
+
declare function convertShading(shading?: Shading): {
|
|
7866
|
+
fill?: string;
|
|
7650
7867
|
color?: string;
|
|
7651
|
-
|
|
7652
|
-
style: "single" | "dashed" | "dotted" | "double" | "none";
|
|
7868
|
+
val?: string;
|
|
7653
7869
|
} | undefined;
|
|
7654
7870
|
//#endregion
|
|
7871
|
+
//#region src/utils/paragraph.d.ts
|
|
7872
|
+
/**
|
|
7873
|
+
* Apply paragraph style attributes to options
|
|
7874
|
+
*/
|
|
7875
|
+
declare const applyParagraphStyleAttributes: <T extends Record<string, unknown>>(options: T, attrs?: ParagraphNode["attrs"]) => T;
|
|
7876
|
+
//#endregion
|
|
7655
7877
|
//#region src/converters/image.d.ts
|
|
7656
7878
|
/**
|
|
7657
7879
|
* Convert TipTap image node to DOCX ImageRun
|
|
@@ -7825,4 +8047,4 @@ declare function convertDetailsSummary(node: DetailsSummaryNode, params: {
|
|
|
7825
8047
|
/** Export options for details styling */options?: DocxExportOptions["details"];
|
|
7826
8048
|
}): IParagraphOptions;
|
|
7827
8049
|
//#endregion
|
|
7828
|
-
export { BlockNode, BlockquoteNode, BulletListNode, CHECKBOX_SYMBOLS, COLOR_NAME_TO_HEX, CodeBlockNode, DEFAULT_CODE_FONT, DOCX_DPI, DOCX_STYLE_NAMES, DetailsContentNode, DetailsNode, DetailsSummaryNode, DocumentNode, DocxExportOptions, DocxImageExportHandler, EMUS_PER_INCH, HALF_POINTS_PER_PIXEL, HardBreakNode, HeadingNode, HorizontalRuleNode, ImageFloatingOptions, ImageNode, ImageOutlineOptions, type JSONContent, ListItemNode, ListOptions, Mark, OrderedListNode, PAGE_DIMENSIONS, PIXELS_PER_HALF_POINT, ParagraphNode, PositiveUniversalMeasure, TEXT_ALIGN_MAP, TWIPS_PER_INCH,
|
|
8050
|
+
export { BlockNode, BlockquoteNode, Border, BulletListNode, CHECKBOX_SYMBOLS, COLOR_NAME_TO_HEX, CodeBlockNode, DEFAULT_CODE_FONT, DOCX_DPI, DOCX_STYLE_NAMES, DetailsContentNode, DetailsNode, DetailsSummaryNode, DocumentNode, DocxExportOptions, DocxImageExportHandler, EMUS_PER_INCH, HALF_POINTS_PER_PIXEL, HardBreakNode, HeadingNode, HorizontalRuleNode, ImageFloatingOptions, ImageNode, ImageOutlineOptions, type JSONContent, ListItemNode, ListOptions, Mark, OrderedListNode, PAGE_DIMENSIONS, PIXELS_PER_HALF_POINT, ParagraphNode, PositiveUniversalMeasure, Shading, TEXT_ALIGN_MAP, TWIPS_PER_INCH, TableCellNode, TableHeaderNode, TableNode, TableRowNode, TaskItemNode, TaskListNode, TextContent, TextNode, applyParagraphStyleAttributes, applyTableMargins, calculateEffectiveContentWidth, convertBlockquote, convertBorder, convertBulletList, convertCodeBlock, convertColorToHex, convertCssLengthToPixels, convertDetailsSummary, convertDocument, convertEmuStringToPixels, convertEmuToPixels, convertHardBreak, convertHeading, convertHorizontalRule, convertImage, convertList, convertListItem, convertMeasureToInches, convertMeasureToPixels, convertNode, convertOrderedList, convertParagraph, convertPixelsToEmu, convertPixelsToTwip, convertShading, convertTable, convertTableCell, convertTableHeader, convertTableRow, convertTaskItem, convertTaskList, convertText, convertTextNodes, convertToDocxImageType, convertTwipToCssString, convertTwipToPixels, createFloatingOptions, createStringValidator, findChild, findDeepChild, findDeepChildren, generateDOCX, getImageDataAndMeta, getImageHeight, getImageTypeFromSrc, getImageWidth, normalizeHexColor, parseTwipAttr };
|
package/dist/index.mjs
CHANGED
|
@@ -438,6 +438,29 @@ function calculateEffectiveContentWidth(options) {
|
|
|
438
438
|
const effectiveWidth = pageWidth - marginLeft - marginRight;
|
|
439
439
|
return Math.max(convertTwipToPixels(effectiveWidth), 96);
|
|
440
440
|
}
|
|
441
|
+
/**
|
|
442
|
+
* Convert Border to docx.js format
|
|
443
|
+
*/
|
|
444
|
+
function convertBorder(border) {
|
|
445
|
+
if (!border) return void 0;
|
|
446
|
+
const docxBorder = {};
|
|
447
|
+
if (border.color) docxBorder.color = border.color.replace("#", "");
|
|
448
|
+
if (border.size !== void 0) docxBorder.size = border.size;
|
|
449
|
+
if (border.style) docxBorder.style = border.style;
|
|
450
|
+
if (border.space !== void 0) docxBorder.space = border.space;
|
|
451
|
+
return Object.keys(docxBorder).length > 0 ? docxBorder : void 0;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Convert Shading to docx.js format
|
|
455
|
+
*/
|
|
456
|
+
function convertShading(shading) {
|
|
457
|
+
if (!shading || !shading.fill) return void 0;
|
|
458
|
+
const docxShading = {};
|
|
459
|
+
if (shading.fill) docxShading.fill = shading.fill.replace("#", "");
|
|
460
|
+
if (shading.color) docxShading.color = shading.color.replace("#", "");
|
|
461
|
+
docxShading.val = shading.type || "clear";
|
|
462
|
+
return docxShading;
|
|
463
|
+
}
|
|
441
464
|
//#endregion
|
|
442
465
|
//#region src/utils/image.ts
|
|
443
466
|
const DEFAULT_MAX_IMAGE_WIDTH_PIXELS = 6.5 * 96;
|
|
@@ -600,52 +623,27 @@ async function getImageDataAndMeta(url) {
|
|
|
600
623
|
*/
|
|
601
624
|
const applyParagraphStyleAttributes = (options, attrs) => {
|
|
602
625
|
if (!attrs) return options;
|
|
603
|
-
|
|
604
|
-
if (attrs.indentLeft || attrs.indentRight || attrs.indentFirstLine) result = {
|
|
605
|
-
...
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
...attrs.indentRight && { right: convertPixelsToTwip(convertCssLengthToPixels(attrs.indentRight)) },
|
|
609
|
-
...attrs.indentFirstLine && { firstLine: convertPixelsToTwip(convertCssLengthToPixels(attrs.indentFirstLine)) }
|
|
610
|
-
}
|
|
626
|
+
const result = { ...options };
|
|
627
|
+
if (attrs.indentLeft || attrs.indentRight || attrs.indentFirstLine) result.indent = {
|
|
628
|
+
...attrs.indentLeft && { left: convertPixelsToTwip(convertCssLengthToPixels(attrs.indentLeft)) },
|
|
629
|
+
...attrs.indentRight && { right: convertPixelsToTwip(convertCssLengthToPixels(attrs.indentRight)) },
|
|
630
|
+
...attrs.indentFirstLine && { firstLine: convertPixelsToTwip(convertCssLengthToPixels(attrs.indentFirstLine)) }
|
|
611
631
|
};
|
|
612
|
-
if (attrs.spacingBefore || attrs.spacingAfter) result = {
|
|
613
|
-
...
|
|
614
|
-
|
|
615
|
-
...attrs.spacingBefore && { before: convertPixelsToTwip(convertCssLengthToPixels(attrs.spacingBefore)) },
|
|
616
|
-
...attrs.spacingAfter && { after: convertPixelsToTwip(convertCssLengthToPixels(attrs.spacingAfter)) }
|
|
617
|
-
}
|
|
632
|
+
if (attrs.spacingBefore || attrs.spacingAfter) result.spacing = {
|
|
633
|
+
...attrs.spacingBefore && { before: convertPixelsToTwip(convertCssLengthToPixels(attrs.spacingBefore)) },
|
|
634
|
+
...attrs.spacingAfter && { after: convertPixelsToTwip(convertCssLengthToPixels(attrs.spacingAfter)) }
|
|
618
635
|
};
|
|
619
|
-
if (attrs.textAlign) result =
|
|
620
|
-
|
|
621
|
-
|
|
636
|
+
if (attrs.textAlign) result.alignment = TEXT_ALIGN_MAP.tiptapToDocx[attrs.textAlign];
|
|
637
|
+
if (attrs.shading) result.shading = convertShading(attrs.shading);
|
|
638
|
+
if (attrs.borderTop || attrs.borderBottom || attrs.borderLeft || attrs.borderRight) result.border = {
|
|
639
|
+
...attrs.borderTop && { top: convertBorder(attrs.borderTop) },
|
|
640
|
+
...attrs.borderBottom && { bottom: convertBorder(attrs.borderBottom) },
|
|
641
|
+
...attrs.borderLeft && { left: convertBorder(attrs.borderLeft) },
|
|
642
|
+
...attrs.borderRight && { right: convertBorder(attrs.borderRight) }
|
|
622
643
|
};
|
|
623
644
|
return result;
|
|
624
645
|
};
|
|
625
646
|
//#endregion
|
|
626
|
-
//#region src/utils/table.ts
|
|
627
|
-
/**
|
|
628
|
-
* Convert TipTap border to DOCX border format
|
|
629
|
-
*
|
|
630
|
-
* @param border - TipTap table cell border definition
|
|
631
|
-
* @returns DOCX border options or undefined if no border
|
|
632
|
-
*/
|
|
633
|
-
function convertBorder(border) {
|
|
634
|
-
if (!border) return void 0;
|
|
635
|
-
const docxStyle = border.style ? {
|
|
636
|
-
solid: "single",
|
|
637
|
-
dashed: "dashed",
|
|
638
|
-
dotted: "dotted",
|
|
639
|
-
double: "double",
|
|
640
|
-
none: "none"
|
|
641
|
-
}[border.style] || "single" : "single";
|
|
642
|
-
return {
|
|
643
|
-
color: border.color?.replace("#", "") || "auto",
|
|
644
|
-
size: border.width ? border.width * 6 : 4,
|
|
645
|
-
style: docxStyle
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
//#endregion
|
|
649
647
|
//#region src/converters/text.ts
|
|
650
648
|
/**
|
|
651
649
|
* Convert TipTap text node to DOCX TextRun or ExternalHyperlink
|
|
@@ -933,13 +931,16 @@ async function convertTableCell(node, params) {
|
|
|
933
931
|
}
|
|
934
932
|
if (node.attrs?.backgroundColor) cellOptions.shading = { fill: node.attrs.backgroundColor.replace("#", "") };
|
|
935
933
|
if (node.attrs?.verticalAlign) cellOptions.verticalAlign = node.attrs.verticalAlign === "middle" ? "center" : node.attrs.verticalAlign;
|
|
936
|
-
const borders = {
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
if (
|
|
934
|
+
const borders = {};
|
|
935
|
+
const top = convertBorder(node.attrs?.borderTop);
|
|
936
|
+
if (top) borders.top = top;
|
|
937
|
+
const bottom = convertBorder(node.attrs?.borderBottom);
|
|
938
|
+
if (bottom) borders.bottom = bottom;
|
|
939
|
+
const left = convertBorder(node.attrs?.borderLeft);
|
|
940
|
+
if (left) borders.left = left;
|
|
941
|
+
const right = convertBorder(node.attrs?.borderRight);
|
|
942
|
+
if (right) borders.right = right;
|
|
943
|
+
if (Object.keys(borders).length > 0) cellOptions.borders = borders;
|
|
943
944
|
return new TableCell(cellOptions);
|
|
944
945
|
}
|
|
945
946
|
//#endregion
|
|
@@ -973,13 +974,16 @@ async function convertTableHeader(node, params) {
|
|
|
973
974
|
}
|
|
974
975
|
if (node.attrs?.backgroundColor) headerCellOptions.shading = { fill: node.attrs.backgroundColor.replace("#", "") };
|
|
975
976
|
if (node.attrs?.verticalAlign) headerCellOptions.verticalAlign = node.attrs.verticalAlign === "middle" ? "center" : node.attrs.verticalAlign;
|
|
976
|
-
const borders = {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
if (
|
|
977
|
+
const borders = {};
|
|
978
|
+
const top = convertBorder(node.attrs?.borderTop);
|
|
979
|
+
if (top) borders.top = top;
|
|
980
|
+
const bottom = convertBorder(node.attrs?.borderBottom);
|
|
981
|
+
if (bottom) borders.bottom = bottom;
|
|
982
|
+
const left = convertBorder(node.attrs?.borderLeft);
|
|
983
|
+
if (left) borders.left = left;
|
|
984
|
+
const right = convertBorder(node.attrs?.borderRight);
|
|
985
|
+
if (right) borders.right = right;
|
|
986
|
+
if (Object.keys(borders).length > 0) headerCellOptions.borders = borders;
|
|
983
987
|
return new TableCell(headerCellOptions);
|
|
984
988
|
}
|
|
985
989
|
//#endregion
|
|
@@ -1264,11 +1268,13 @@ async function generateDOCX(docJson, options) {
|
|
|
1264
1268
|
* Convert document content to DOCX elements
|
|
1265
1269
|
*/
|
|
1266
1270
|
async function convertDocument(node, params) {
|
|
1267
|
-
|
|
1268
|
-
if (!node || !Array.isArray(node.content)) return elements;
|
|
1271
|
+
if (!node || !Array.isArray(node.content)) return [];
|
|
1269
1272
|
const effectiveContentWidth = calculateEffectiveContentWidth(params.options);
|
|
1270
|
-
|
|
1271
|
-
|
|
1273
|
+
const convertedElements = await Promise.all(node.content.map((childNode) => convertNode(childNode, params.options, effectiveContentWidth)));
|
|
1274
|
+
const elements = [];
|
|
1275
|
+
for (let i = 0; i < convertedElements.length; i++) {
|
|
1276
|
+
const element = convertedElements[i];
|
|
1277
|
+
const childNode = node.content[i];
|
|
1272
1278
|
if (Array.isArray(element)) elements.push(...element);
|
|
1273
1279
|
else if (element) {
|
|
1274
1280
|
elements.push(element);
|
|
@@ -1292,6 +1298,7 @@ async function convertNode(node, options, effectiveContentWidth) {
|
|
|
1292
1298
|
if (Array.isArray(dataResult)) {
|
|
1293
1299
|
const styleId = getStyleIdByNodeType(node.type, options);
|
|
1294
1300
|
return dataResult.map((paragraphOptions) => {
|
|
1301
|
+
if (!styleId) return new Paragraph(paragraphOptions);
|
|
1295
1302
|
return new Paragraph(applyStyleReference(paragraphOptions, styleId));
|
|
1296
1303
|
});
|
|
1297
1304
|
}
|
|
@@ -1299,6 +1306,7 @@ async function convertNode(node, options, effectiveContentWidth) {
|
|
|
1299
1306
|
if (!styleId && node.type === "paragraph" && node.content) {
|
|
1300
1307
|
if (node.content.length > 0 && node.content.every((child) => child.type === "image")) styleId = options.image?.style?.id;
|
|
1301
1308
|
}
|
|
1309
|
+
if (!styleId) return createDOCXObject(dataResult);
|
|
1302
1310
|
return createDOCXObject(applyStyleReference(dataResult, styleId));
|
|
1303
1311
|
}
|
|
1304
1312
|
/**
|
|
@@ -1443,4 +1451,4 @@ function createDOCXObject(options) {
|
|
|
1443
1451
|
return new Paragraph(options);
|
|
1444
1452
|
}
|
|
1445
1453
|
//#endregion
|
|
1446
|
-
export { CHECKBOX_SYMBOLS, COLOR_NAME_TO_HEX, DEFAULT_CODE_FONT, DOCX_DPI, DOCX_STYLE_NAMES, EMUS_PER_INCH, HALF_POINTS_PER_PIXEL, PAGE_DIMENSIONS, PIXELS_PER_HALF_POINT, TEXT_ALIGN_MAP, TWIPS_PER_INCH, applyParagraphStyleAttributes, applyTableMargins, calculateEffectiveContentWidth, convertBlockquote, convertBorder, convertBulletList, convertCodeBlock, convertColorToHex, convertCssLengthToPixels, convertDetailsSummary, convertDocument, convertEmuStringToPixels, convertEmuToPixels, convertHardBreak, convertHeading, convertHorizontalRule, convertImage, convertList, convertListItem, convertMeasureToInches, convertMeasureToPixels, convertNode, convertOrderedList, convertParagraph, convertPixelsToEmu, convertPixelsToTwip, convertTable, convertTableCell, convertTableHeader, convertTableRow, convertTaskItem, convertTaskList, convertText, convertTextNodes, convertToDocxImageType, convertTwipToCssString, convertTwipToPixels, createFloatingOptions, createStringValidator, findChild, findDeepChild, findDeepChildren, generateDOCX, getImageDataAndMeta, getImageHeight, getImageTypeFromSrc, getImageWidth, normalizeHexColor, parseTwipAttr };
|
|
1454
|
+
export { CHECKBOX_SYMBOLS, COLOR_NAME_TO_HEX, DEFAULT_CODE_FONT, DOCX_DPI, DOCX_STYLE_NAMES, EMUS_PER_INCH, HALF_POINTS_PER_PIXEL, PAGE_DIMENSIONS, PIXELS_PER_HALF_POINT, TEXT_ALIGN_MAP, TWIPS_PER_INCH, applyParagraphStyleAttributes, applyTableMargins, calculateEffectiveContentWidth, convertBlockquote, convertBorder, convertBulletList, convertCodeBlock, convertColorToHex, convertCssLengthToPixels, convertDetailsSummary, convertDocument, convertEmuStringToPixels, convertEmuToPixels, convertHardBreak, convertHeading, convertHorizontalRule, convertImage, convertList, convertListItem, convertMeasureToInches, convertMeasureToPixels, convertNode, convertOrderedList, convertParagraph, convertPixelsToEmu, convertPixelsToTwip, convertShading, convertTable, convertTableCell, convertTableHeader, convertTableRow, convertTaskItem, convertTaskList, convertText, convertTextNodes, convertToDocxImageType, convertTwipToCssString, convertTwipToPixels, createFloatingOptions, createStringValidator, findChild, findDeepChild, findDeepChildren, generateDOCX, getImageDataAndMeta, getImageHeight, getImageTypeFromSrc, getImageWidth, normalizeHexColor, parseTwipAttr };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docen/export-docx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.13",
|
|
4
4
|
"description": "A powerful TipTap/ProseMirror extension that converts editor content to Microsoft Word DOCX format",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"converter",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"ofetch": "1.5.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@tiptap/core": "3.20.
|
|
58
|
-
"@docen/
|
|
59
|
-
"@docen/
|
|
57
|
+
"@tiptap/core": "3.20.0",
|
|
58
|
+
"@docen/extensions": "0.0.13",
|
|
59
|
+
"@docen/utils": "0.0.13"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"dev": "basis build --stub",
|