@docen/export-docx 0.0.12 → 0.0.14
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 +279 -33
- 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
|
|
@@ -2166,7 +2166,7 @@ can be lifted. Will not go across
|
|
|
2166
2166
|
[isolating](https://prosemirror.net/docs/ref/#model.NodeSpec.isolating) parent nodes.
|
|
2167
2167
|
*/
|
|
2168
2168
|
//#endregion
|
|
2169
|
-
//#region ../../node_modules/.pnpm/prosemirror-view@1.41.
|
|
2169
|
+
//#region ../../node_modules/.pnpm/prosemirror-view@1.41.7/node_modules/prosemirror-view/dist/index.d.ts
|
|
2170
2170
|
type DOMNode = InstanceType<typeof window.Node>;
|
|
2171
2171
|
type WidgetConstructor = ((view: EditorView, getPos: () => number | undefined) => DOMNode) | DOMNode;
|
|
2172
2172
|
/**
|
|
@@ -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.4_@tiptap+pm@3.20.4/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;
|
|
@@ -4436,6 +4436,27 @@ interface ExtendableConfig<Options = any, Storage = any, Config extends Extensio
|
|
|
4436
4436
|
* Defines if this markdown element should indent it's child elements
|
|
4437
4437
|
*/
|
|
4438
4438
|
indentsContent?: boolean;
|
|
4439
|
+
/**
|
|
4440
|
+
* Lets a mark tell the Markdown serializer which inline HTML tags it can
|
|
4441
|
+
* safely use when plain markdown delimiters would become ambiguous.
|
|
4442
|
+
*
|
|
4443
|
+
* This is mainly useful for overlapping marks. For example, bold followed
|
|
4444
|
+
* by bold+italic followed by italic cannot always be written back with only
|
|
4445
|
+
* `*` and `**` in a way that still parses correctly. In that case, the
|
|
4446
|
+
* serializer can close the overlapping section with markdown and reopen the
|
|
4447
|
+
* remaining tail with HTML instead.
|
|
4448
|
+
*
|
|
4449
|
+
* Example:
|
|
4450
|
+
* - desired formatting: `**123` + `*456*` + `789 italic`
|
|
4451
|
+
* - serialized result: `**123*456***<em>789</em>`
|
|
4452
|
+
*
|
|
4453
|
+
* If your extension defines custom mark names, set `htmlReopen` on that
|
|
4454
|
+
* extension so the serializer can reuse its HTML form for overlap cases.
|
|
4455
|
+
*/
|
|
4456
|
+
htmlReopen?: {
|
|
4457
|
+
open: string;
|
|
4458
|
+
close: string;
|
|
4459
|
+
};
|
|
4439
4460
|
};
|
|
4440
4461
|
/**
|
|
4441
4462
|
* This function extends the schema of the node.
|
|
@@ -5279,7 +5300,8 @@ type MarkdownToken = {
|
|
|
5279
5300
|
*/
|
|
5280
5301
|
type MarkdownParseHelpers = {
|
|
5281
5302
|
/** Parse an array of inline tokens into text nodes with marks */parseInline: (tokens: MarkdownToken[]) => JSONContent[]; /** Parse an array of block-level tokens */
|
|
5282
|
-
parseChildren: (tokens: MarkdownToken[]) => JSONContent[]; /**
|
|
5303
|
+
parseChildren: (tokens: MarkdownToken[]) => JSONContent[]; /** Parse block-level tokens while preserving implicit empty paragraphs from blank lines */
|
|
5304
|
+
parseBlockChildren?: (tokens: MarkdownToken[]) => JSONContent[]; /** Create a text node with optional marks */
|
|
5283
5305
|
createTextNode: (text: string, marks?: Array<{
|
|
5284
5306
|
type: string;
|
|
5285
5307
|
attrs?: any;
|
|
@@ -5312,6 +5334,7 @@ type RenderContext = {
|
|
|
5312
5334
|
level: number;
|
|
5313
5335
|
meta?: Record<string, any>;
|
|
5314
5336
|
parentType?: string | null;
|
|
5337
|
+
previousNode?: JSONContent | null;
|
|
5315
5338
|
};
|
|
5316
5339
|
/** Extension contract for markdown parsing/serialization. */
|
|
5317
5340
|
/**
|
|
@@ -5345,7 +5368,8 @@ type MarkdownRendererHelpers = {
|
|
|
5345
5368
|
* @param separator An optional separator string (legacy) or RenderContext
|
|
5346
5369
|
* @returns The rendered markdown string
|
|
5347
5370
|
*/
|
|
5348
|
-
renderChildren: (nodes: JSONContent | JSONContent[], separator?: string) => string;
|
|
5371
|
+
renderChildren: (nodes: JSONContent | JSONContent[], separator?: string) => string; /** Render a single child node with its sibling index preserved */
|
|
5372
|
+
renderChild?: (node: JSONContent, index: number) => string;
|
|
5349
5373
|
/**
|
|
5350
5374
|
* Render a text token to a markdown string
|
|
5351
5375
|
* @param prefix The prefix to add before the content
|
|
@@ -6763,12 +6787,225 @@ declare function convertDocument(node: JSONContent, params: {
|
|
|
6763
6787
|
declare function convertNode(node: JSONContent, options: DocxExportOptions, effectiveContentWidth: number): Promise<FileChild | FileChild[] | null>;
|
|
6764
6788
|
//#endregion
|
|
6765
6789
|
//#region ../extensions/dist/types.d.mts
|
|
6790
|
+
//#region ../../node_modules/.pnpm/docx@9.6.1/node_modules/docx/dist/index.d.ts
|
|
6791
|
+
declare const CompoundLine: {
|
|
6792
|
+
readonly SINGLE: "sng";
|
|
6793
|
+
readonly DOUBLE: "dbl";
|
|
6794
|
+
readonly THICK_THIN: "thickThin";
|
|
6795
|
+
readonly THIN_THICK: "thinThick";
|
|
6796
|
+
readonly TRI: "tri";
|
|
6797
|
+
};
|
|
6798
|
+
declare type CoreImageOptions = {
|
|
6799
|
+
readonly transformation: IMediaTransformation;
|
|
6800
|
+
readonly floating?: IFloating;
|
|
6801
|
+
readonly altText?: DocPropertiesOptions;
|
|
6802
|
+
readonly outline?: OutlineOptions;
|
|
6803
|
+
readonly solidFill?: SolidFillOptions;
|
|
6804
|
+
};
|
|
6805
|
+
declare type DocPropertiesOptions = {
|
|
6806
|
+
readonly name: string;
|
|
6807
|
+
readonly description?: string;
|
|
6808
|
+
readonly title?: string;
|
|
6809
|
+
readonly id?: string;
|
|
6810
|
+
};
|
|
6811
|
+
declare const HorizontalPositionAlign: {
|
|
6812
|
+
readonly CENTER: "center";
|
|
6813
|
+
readonly INSIDE: "inside";
|
|
6814
|
+
readonly LEFT: "left";
|
|
6815
|
+
readonly OUTSIDE: "outside";
|
|
6816
|
+
readonly RIGHT: "right";
|
|
6817
|
+
};
|
|
6818
|
+
declare const HorizontalPositionRelativeFrom: {
|
|
6819
|
+
readonly CHARACTER: "character";
|
|
6820
|
+
readonly COLUMN: "column";
|
|
6821
|
+
readonly INSIDE_MARGIN: "insideMargin";
|
|
6822
|
+
readonly LEFT_MARGIN: "leftMargin";
|
|
6823
|
+
readonly MARGIN: "margin";
|
|
6824
|
+
readonly OUTSIDE_MARGIN: "outsideMargin";
|
|
6825
|
+
readonly PAGE: "page";
|
|
6826
|
+
readonly RIGHT_MARGIN: "rightMargin";
|
|
6827
|
+
};
|
|
6828
|
+
declare type IDistance = {
|
|
6829
|
+
readonly distT?: number;
|
|
6830
|
+
readonly distB?: number;
|
|
6831
|
+
readonly distL?: number;
|
|
6832
|
+
readonly distR?: number;
|
|
6833
|
+
};
|
|
6834
|
+
declare type IFloating = {
|
|
6835
|
+
readonly horizontalPosition: IHorizontalPositionOptions;
|
|
6836
|
+
readonly verticalPosition: IVerticalPositionOptions;
|
|
6837
|
+
readonly allowOverlap?: boolean;
|
|
6838
|
+
readonly lockAnchor?: boolean;
|
|
6839
|
+
readonly behindDocument?: boolean;
|
|
6840
|
+
readonly layoutInCell?: boolean;
|
|
6841
|
+
readonly margins?: IMargins;
|
|
6842
|
+
readonly wrap?: ITextWrapping;
|
|
6843
|
+
readonly zIndex?: number;
|
|
6844
|
+
};
|
|
6845
|
+
declare type IHorizontalPositionOptions = {
|
|
6846
|
+
readonly relative?: (typeof HorizontalPositionRelativeFrom)[keyof typeof HorizontalPositionRelativeFrom];
|
|
6847
|
+
readonly align?: (typeof HorizontalPositionAlign)[keyof typeof HorizontalPositionAlign];
|
|
6848
|
+
readonly offset?: number;
|
|
6849
|
+
};
|
|
6850
|
+
declare type IImageOptions$1 = (RegularImageOptions | SvgMediaOptions) & CoreImageOptions;
|
|
6851
|
+
declare type IMargins = {
|
|
6852
|
+
readonly left?: number;
|
|
6853
|
+
readonly bottom?: number;
|
|
6854
|
+
readonly top?: number;
|
|
6855
|
+
readonly right?: number;
|
|
6856
|
+
};
|
|
6857
|
+
declare type IMediaTransformation = {
|
|
6858
|
+
readonly offset?: {
|
|
6859
|
+
readonly top?: number;
|
|
6860
|
+
readonly left?: number;
|
|
6861
|
+
};
|
|
6862
|
+
readonly width: number;
|
|
6863
|
+
readonly height: number;
|
|
6864
|
+
readonly flip?: {
|
|
6865
|
+
readonly vertical?: boolean;
|
|
6866
|
+
readonly horizontal?: boolean;
|
|
6867
|
+
};
|
|
6868
|
+
readonly rotation?: number;
|
|
6869
|
+
};
|
|
6870
|
+
declare type ITextWrapping = {
|
|
6871
|
+
readonly type: (typeof TextWrappingType)[keyof typeof TextWrappingType];
|
|
6872
|
+
readonly side?: (typeof TextWrappingSide)[keyof typeof TextWrappingSide];
|
|
6873
|
+
readonly margins?: IDistance;
|
|
6874
|
+
};
|
|
6875
|
+
declare type IVerticalPositionOptions = {
|
|
6876
|
+
readonly relative?: (typeof VerticalPositionRelativeFrom)[keyof typeof VerticalPositionRelativeFrom];
|
|
6877
|
+
readonly align?: (typeof VerticalPositionAlign)[keyof typeof VerticalPositionAlign];
|
|
6878
|
+
readonly offset?: number;
|
|
6879
|
+
};
|
|
6880
|
+
declare const LineCap: {
|
|
6881
|
+
readonly ROUND: "rnd";
|
|
6882
|
+
readonly SQUARE: "sq";
|
|
6883
|
+
readonly FLAT: "flat";
|
|
6884
|
+
};
|
|
6885
|
+
declare type OutlineAttributes = {
|
|
6886
|
+
readonly width?: number;
|
|
6887
|
+
readonly cap?: keyof typeof LineCap;
|
|
6888
|
+
readonly compoundLine?: keyof typeof CompoundLine;
|
|
6889
|
+
readonly align?: keyof typeof PenAlignment;
|
|
6890
|
+
};
|
|
6891
|
+
declare type OutlineFillProperties = OutlineNoFill | OutlineSolidFill;
|
|
6892
|
+
declare type OutlineNoFill = {
|
|
6893
|
+
readonly type: "noFill";
|
|
6894
|
+
};
|
|
6895
|
+
declare type OutlineOptions = OutlineAttributes & OutlineFillProperties;
|
|
6896
|
+
declare type OutlineRgbSolidFill = {
|
|
6897
|
+
readonly type: "solidFill";
|
|
6898
|
+
readonly solidFillType: "rgb";
|
|
6899
|
+
readonly value: string;
|
|
6900
|
+
};
|
|
6901
|
+
declare type OutlineSchemeSolidFill = {
|
|
6902
|
+
readonly type: "solidFill";
|
|
6903
|
+
readonly solidFillType: "scheme";
|
|
6904
|
+
readonly value: (typeof SchemeColor)[keyof typeof SchemeColor];
|
|
6905
|
+
};
|
|
6906
|
+
declare type OutlineSolidFill = OutlineRgbSolidFill | OutlineSchemeSolidFill;
|
|
6907
|
+
declare const PenAlignment: {
|
|
6908
|
+
readonly CENTER: "ctr";
|
|
6909
|
+
readonly INSET: "in";
|
|
6910
|
+
};
|
|
6911
|
+
declare type RegularImageOptions = {
|
|
6912
|
+
readonly type: "jpg" | "png" | "gif" | "bmp";
|
|
6913
|
+
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
|
6914
|
+
};
|
|
6915
|
+
declare type RgbColorOptions = {
|
|
6916
|
+
readonly type: "rgb";
|
|
6917
|
+
readonly value: string;
|
|
6918
|
+
};
|
|
6919
|
+
declare const SchemeColor: {
|
|
6920
|
+
readonly BG1: "bg1";
|
|
6921
|
+
readonly TX1: "tx1";
|
|
6922
|
+
readonly BG2: "bg2";
|
|
6923
|
+
readonly TX2: "tx2";
|
|
6924
|
+
readonly ACCENT1: "accent1";
|
|
6925
|
+
readonly ACCENT2: "accent2";
|
|
6926
|
+
readonly ACCENT3: "accent3";
|
|
6927
|
+
readonly ACCENT4: "accent4";
|
|
6928
|
+
readonly ACCENT5: "accent5";
|
|
6929
|
+
readonly ACCENT6: "accent6";
|
|
6930
|
+
readonly HLINK: "hlink";
|
|
6931
|
+
readonly FOLHLINK: "folHlink";
|
|
6932
|
+
readonly DK1: "dk1";
|
|
6933
|
+
readonly LT1: "lt1";
|
|
6934
|
+
readonly DK2: "dk2";
|
|
6935
|
+
readonly LT2: "lt2";
|
|
6936
|
+
readonly PHCLR: "phClr";
|
|
6937
|
+
};
|
|
6938
|
+
declare type SchemeColorOptions = {
|
|
6939
|
+
readonly type: "scheme";
|
|
6940
|
+
readonly value: (typeof SchemeColor)[keyof typeof SchemeColor];
|
|
6941
|
+
};
|
|
6942
|
+
declare type SolidFillOptions = RgbColorOptions | SchemeColorOptions;
|
|
6943
|
+
declare type SvgMediaOptions = {
|
|
6944
|
+
readonly type: "svg";
|
|
6945
|
+
readonly data: Buffer | string | Uint8Array | ArrayBuffer;
|
|
6946
|
+
readonly fallback: RegularImageOptions;
|
|
6947
|
+
};
|
|
6948
|
+
declare const TextWrappingSide: {
|
|
6949
|
+
readonly BOTH_SIDES: "bothSides";
|
|
6950
|
+
readonly LEFT: "left";
|
|
6951
|
+
readonly RIGHT: "right";
|
|
6952
|
+
readonly LARGEST: "largest";
|
|
6953
|
+
};
|
|
6954
|
+
declare const TextWrappingType: {
|
|
6955
|
+
readonly NONE: 0;
|
|
6956
|
+
readonly SQUARE: 1;
|
|
6957
|
+
readonly TIGHT: 2;
|
|
6958
|
+
readonly TOP_AND_BOTTOM: 3;
|
|
6959
|
+
};
|
|
6960
|
+
declare const VerticalPositionAlign: {
|
|
6961
|
+
readonly BOTTOM: "bottom";
|
|
6962
|
+
readonly CENTER: "center";
|
|
6963
|
+
readonly INSIDE: "inside";
|
|
6964
|
+
readonly OUTSIDE: "outside";
|
|
6965
|
+
readonly TOP: "top";
|
|
6966
|
+
};
|
|
6967
|
+
declare const VerticalPositionRelativeFrom: {
|
|
6968
|
+
readonly BOTTOM_MARGIN: "bottomMargin";
|
|
6969
|
+
readonly INSIDE_MARGIN: "insideMargin";
|
|
6970
|
+
readonly LINE: "line";
|
|
6971
|
+
readonly MARGIN: "margin";
|
|
6972
|
+
readonly OUTSIDE_MARGIN: "outsideMargin";
|
|
6973
|
+
readonly PAGE: "page";
|
|
6974
|
+
readonly PARAGRAPH: "paragraph";
|
|
6975
|
+
readonly TOP_MARGIN: "topMargin";
|
|
6976
|
+
}; //#endregion
|
|
6766
6977
|
//#region src/types.d.ts
|
|
6978
|
+
/**
|
|
6979
|
+
* Border definition (compatible with docx.js BorderOptions)
|
|
6980
|
+
* Used by paragraphs, table cells, and blockquotes
|
|
6981
|
+
*/
|
|
6982
|
+
interface Border {
|
|
6983
|
+
/** Border color (hex without #, e.g., "FF0000" or "auto") */
|
|
6984
|
+
color?: string;
|
|
6985
|
+
/** Border size (eighth-points, 1/8 pt) */
|
|
6986
|
+
size?: number;
|
|
6987
|
+
/** Border style */
|
|
6988
|
+
style?: "single" | "dashed" | "dotted" | "double" | "dotDash" | "dotDotDash" | "none";
|
|
6989
|
+
/** Space between border and content (points) */
|
|
6990
|
+
space?: number;
|
|
6991
|
+
}
|
|
6992
|
+
/**
|
|
6993
|
+
* Shading definition (compatible with docx.js ShadingOptions)
|
|
6994
|
+
* Used for paragraph and table cell background colors
|
|
6995
|
+
*/
|
|
6996
|
+
interface Shading {
|
|
6997
|
+
/** Fill color (hex without #, e.g., "FF0000") */
|
|
6998
|
+
fill?: string;
|
|
6999
|
+
/** Pattern color (hex without #) */
|
|
7000
|
+
color?: string;
|
|
7001
|
+
/** Shading pattern type (e.g., "clear", "percent-10") */
|
|
7002
|
+
type?: string;
|
|
7003
|
+
}
|
|
6767
7004
|
type ImageFloatingOptions = {
|
|
6768
7005
|
horizontalPosition: IHorizontalPositionOptions;
|
|
6769
7006
|
verticalPosition: IVerticalPositionOptions;
|
|
6770
7007
|
} & Partial<Omit<IFloating, "horizontalPosition" | "verticalPosition">>;
|
|
6771
|
-
type ImageOutlineOptions = IImageOptions["outline"];
|
|
7008
|
+
type ImageOutlineOptions = IImageOptions$1["outline"];
|
|
6772
7009
|
interface TextNode {
|
|
6773
7010
|
type: "text";
|
|
6774
7011
|
text: string;
|
|
@@ -6806,6 +7043,11 @@ interface ParagraphNode extends JSONContent {
|
|
|
6806
7043
|
indentFirstLine?: string;
|
|
6807
7044
|
spacingBefore?: string;
|
|
6808
7045
|
spacingAfter?: string;
|
|
7046
|
+
shading?: Shading;
|
|
7047
|
+
borderTop?: Border;
|
|
7048
|
+
borderBottom?: Border;
|
|
7049
|
+
borderLeft?: Border;
|
|
7050
|
+
borderRight?: Border;
|
|
6809
7051
|
};
|
|
6810
7052
|
content?: Array<TextNode | HardBreakNode | ImageNode>;
|
|
6811
7053
|
}
|
|
@@ -6819,6 +7061,11 @@ interface HeadingNode extends JSONContent {
|
|
|
6819
7061
|
spacingBefore?: string;
|
|
6820
7062
|
spacingAfter?: string;
|
|
6821
7063
|
textAlign?: "left" | "right" | "center" | "justify";
|
|
7064
|
+
shading?: Shading;
|
|
7065
|
+
borderTop?: Border;
|
|
7066
|
+
borderBottom?: Border;
|
|
7067
|
+
borderLeft?: Border;
|
|
7068
|
+
borderRight?: Border;
|
|
6822
7069
|
};
|
|
6823
7070
|
content?: Array<TextNode | HardBreakNode>;
|
|
6824
7071
|
}
|
|
@@ -6864,11 +7111,6 @@ interface TaskItemNode extends JSONContent {
|
|
|
6864
7111
|
};
|
|
6865
7112
|
content?: Array<ParagraphNode>;
|
|
6866
7113
|
}
|
|
6867
|
-
interface TableCellBorder {
|
|
6868
|
-
color?: string;
|
|
6869
|
-
width?: number;
|
|
6870
|
-
style?: "solid" | "dashed" | "dotted" | "double" | "none";
|
|
6871
|
-
}
|
|
6872
7114
|
interface TableNode extends JSONContent {
|
|
6873
7115
|
type: "table";
|
|
6874
7116
|
attrs?: {
|
|
@@ -6894,10 +7136,10 @@ interface TableCellNode extends JSONContent {
|
|
|
6894
7136
|
colwidth?: number[] | null;
|
|
6895
7137
|
backgroundColor?: string | null;
|
|
6896
7138
|
verticalAlign?: "top" | "middle" | "bottom" | null;
|
|
6897
|
-
borderTop?:
|
|
6898
|
-
borderBottom?:
|
|
6899
|
-
borderLeft?:
|
|
6900
|
-
borderRight?:
|
|
7139
|
+
borderTop?: Border;
|
|
7140
|
+
borderBottom?: Border;
|
|
7141
|
+
borderLeft?: Border;
|
|
7142
|
+
borderRight?: Border;
|
|
6901
7143
|
};
|
|
6902
7144
|
content?: Array<ParagraphNode>;
|
|
6903
7145
|
}
|
|
@@ -6909,10 +7151,10 @@ interface TableHeaderNode extends JSONContent {
|
|
|
6909
7151
|
colwidth?: number[] | null;
|
|
6910
7152
|
backgroundColor?: string | null;
|
|
6911
7153
|
verticalAlign?: "top" | "middle" | "bottom" | null;
|
|
6912
|
-
borderTop?:
|
|
6913
|
-
borderBottom?:
|
|
6914
|
-
borderLeft?:
|
|
6915
|
-
borderRight?:
|
|
7154
|
+
borderTop?: Border;
|
|
7155
|
+
borderBottom?: Border;
|
|
7156
|
+
borderLeft?: Border;
|
|
7157
|
+
borderRight?: Border;
|
|
6916
7158
|
};
|
|
6917
7159
|
content?: Array<ParagraphNode>;
|
|
6918
7160
|
}
|
|
@@ -7632,26 +7874,30 @@ declare function createStringValidator<T extends string>(validValues: readonly T
|
|
|
7632
7874
|
* Calculate effective content width from document options
|
|
7633
7875
|
*/
|
|
7634
7876
|
declare function calculateEffectiveContentWidth(options?: DocxExportOptions): number;
|
|
7635
|
-
//#endregion
|
|
7636
|
-
//#region src/utils/paragraph.d.ts
|
|
7637
7877
|
/**
|
|
7638
|
-
*
|
|
7878
|
+
* Convert Border to docx.js format
|
|
7639
7879
|
*/
|
|
7640
|
-
declare
|
|
7641
|
-
|
|
7642
|
-
|
|
7880
|
+
declare function convertBorder(border?: Border): {
|
|
7881
|
+
color?: string;
|
|
7882
|
+
size?: number;
|
|
7883
|
+
style?: string;
|
|
7884
|
+
space?: number;
|
|
7885
|
+
} | undefined;
|
|
7643
7886
|
/**
|
|
7644
|
-
* Convert
|
|
7645
|
-
*
|
|
7646
|
-
* @param border - TipTap table cell border definition
|
|
7647
|
-
* @returns DOCX border options or undefined if no border
|
|
7887
|
+
* Convert Shading to docx.js format
|
|
7648
7888
|
*/
|
|
7649
|
-
declare function
|
|
7889
|
+
declare function convertShading(shading?: Shading): {
|
|
7890
|
+
fill?: string;
|
|
7650
7891
|
color?: string;
|
|
7651
|
-
|
|
7652
|
-
style: "single" | "dashed" | "dotted" | "double" | "none";
|
|
7892
|
+
val?: string;
|
|
7653
7893
|
} | undefined;
|
|
7654
7894
|
//#endregion
|
|
7895
|
+
//#region src/utils/paragraph.d.ts
|
|
7896
|
+
/**
|
|
7897
|
+
* Apply paragraph style attributes to options
|
|
7898
|
+
*/
|
|
7899
|
+
declare const applyParagraphStyleAttributes: <T extends Record<string, unknown>>(options: T, attrs?: ParagraphNode["attrs"]) => T;
|
|
7900
|
+
//#endregion
|
|
7655
7901
|
//#region src/converters/image.d.ts
|
|
7656
7902
|
/**
|
|
7657
7903
|
* Convert TipTap image node to DOCX ImageRun
|
|
@@ -7825,4 +8071,4 @@ declare function convertDetailsSummary(node: DetailsSummaryNode, params: {
|
|
|
7825
8071
|
/** Export options for details styling */options?: DocxExportOptions["details"];
|
|
7826
8072
|
}): IParagraphOptions;
|
|
7827
8073
|
//#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,
|
|
8074
|
+
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.14",
|
|
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.4",
|
|
58
|
+
"@docen/extensions": "0.0.14",
|
|
59
|
+
"@docen/utils": "0.0.14"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"dev": "basis build --stub",
|