@blocknote/xl-docx-exporter 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +661 -0
  2. package/dist/Inter_18pt-Regular-byxnNS-8.js +5 -0
  3. package/dist/Inter_18pt-Regular-byxnNS-8.js.map +1 -0
  4. package/dist/blocknote-xl-docx-exporter.js +381 -0
  5. package/dist/blocknote-xl-docx-exporter.js.map +1 -0
  6. package/dist/blocknote-xl-docx-exporter.umd.cjs +991 -0
  7. package/dist/blocknote-xl-docx-exporter.umd.cjs.map +1 -0
  8. package/dist/styles-CcdeAskf.js +994 -0
  9. package/dist/styles-CcdeAskf.js.map +1 -0
  10. package/dist/webpack-stats.json +1 -0
  11. package/package.json +80 -0
  12. package/src/docx/__snapshots__/basic/document.xml +685 -0
  13. package/src/docx/__snapshots__/basic/styles.xml +960 -0
  14. package/src/docx/__snapshots__/withCustomOptions/core.xml +14 -0
  15. package/src/docx/__snapshots__/withCustomOptions/document.xml.rels +17 -0
  16. package/src/docx/__snapshots__/withCustomOptions/footer1.xml +8 -0
  17. package/src/docx/__snapshots__/withCustomOptions/header1.xml +8 -0
  18. package/src/docx/defaultSchema/blocks.ts +222 -0
  19. package/src/docx/defaultSchema/index.ts +9 -0
  20. package/src/docx/defaultSchema/inlinecontent.ts +29 -0
  21. package/src/docx/defaultSchema/styles.ts +73 -0
  22. package/src/docx/docxExporter.test.ts +118 -0
  23. package/src/docx/docxExporter.ts +269 -0
  24. package/src/docx/imageUtil.ts +21 -0
  25. package/src/docx/index.ts +2 -0
  26. package/src/docx/template/[Content_Types].xml +22 -0
  27. package/src/docx/template/_rels/.rels +2 -0
  28. package/src/docx/template/docProps/app.xml +35 -0
  29. package/src/docx/template/docProps/core.xml +16 -0
  30. package/src/docx/template/template blocknote.docx +0 -0
  31. package/src/docx/template/word/_rels/document.xml.rels +24 -0
  32. package/src/docx/template/word/document.xml +325 -0
  33. package/src/docx/template/word/fontTable.xml +2 -0
  34. package/src/docx/template/word/media/image1.jpeg +0 -0
  35. package/src/docx/template/word/settings.xml +71 -0
  36. package/src/docx/template/word/styles.xml +990 -0
  37. package/src/docx/template/word/theme/theme1.xml +2 -0
  38. package/src/docx/template/word/webSettings.xml +2 -0
  39. package/src/docx/util/Table.tsx +43 -0
  40. package/src/index.ts +1 -0
  41. package/src/vite-env.d.ts +11 -0
  42. package/types/src/Exporter.d.ts +26 -0
  43. package/types/src/context/BlockNoteContext.d.ts +59 -0
  44. package/types/src/context/BlockNoteContext.test.d.ts +1 -0
  45. package/types/src/context/ServerBlockNoteEditor.d.ts +137 -0
  46. package/types/src/context/ServerBlockNoteEditor.test.d.ts +1 -0
  47. package/types/src/context/react/ReactServer.test.d.ts +2 -0
  48. package/types/src/docx/blocks.d.ts +433 -0
  49. package/types/src/docx/defaultSchema/blocks.d.ts +3 -0
  50. package/types/src/docx/defaultSchema/index.d.ts +559 -0
  51. package/types/src/docx/defaultSchema/inlinecontent.d.ts +3 -0
  52. package/types/src/docx/defaultSchema/styles.d.ts +3 -0
  53. package/types/src/docx/docxExporter.d.ts +53 -0
  54. package/types/src/docx/docxExporter.test.d.ts +1 -0
  55. package/types/src/docx/imageUtil.d.ts +4 -0
  56. package/types/src/docx/index.d.ts +2 -0
  57. package/types/src/docx/inlinecontent.d.ts +12 -0
  58. package/types/src/docx/styles.d.ts +55 -0
  59. package/types/src/docx/util/Table.d.ts +3 -0
  60. package/types/src/docxExporter.d.ts +255 -0
  61. package/types/src/docxExporter.test.d.ts +1 -0
  62. package/types/src/index.d.ts +1 -0
  63. package/types/src/mapping.d.ts +29 -0
  64. package/types/src/pdf/blocks.d.ts +434 -0
  65. package/types/src/pdf/defaultSchema/blocks.d.ts +5 -0
  66. package/types/src/pdf/defaultSchema/index.d.ts +510 -0
  67. package/types/src/pdf/defaultSchema/inlinecontent.d.ts +5 -0
  68. package/types/src/pdf/defaultSchema/styles.d.ts +4 -0
  69. package/types/src/pdf/index.d.ts +2 -0
  70. package/types/src/pdf/inlinecontent.d.ts +13 -0
  71. package/types/src/pdf/pdfExporter.d.ts +35 -0
  72. package/types/src/pdf/pdfExporter.test.d.ts +1 -0
  73. package/types/src/pdf/styles.d.ts +55 -0
  74. package/types/src/pdf/types.d.ts +2 -0
  75. package/types/src/pdf/util/listItem.d.ts +9 -0
  76. package/types/src/pdf/util/loadFontDataUrl.d.ts +3 -0
  77. package/types/src/pdf/util/table/Table.d.ts +6 -0
  78. package/types/src/pdfExporter.d.ts +256 -0
  79. package/types/src/pdfExporter.test.d.ts +1 -0
  80. package/types/src/react-email/defaultSchema/blocks.d.ts +5 -0
  81. package/types/src/react-email/defaultSchema/index.d.ts +560 -0
  82. package/types/src/react-email/defaultSchema/inlinecontent.d.ts +5 -0
  83. package/types/src/react-email/defaultSchema/styles.d.ts +4 -0
  84. package/types/src/react-email/reactEmailExporter.d.ts +13 -0
  85. package/types/src/react-email/reactEmailExporter.test.d.ts +8 -0
  86. package/types/src/testDocument.d.ts +505 -0
  87. package/types/src/transformer.d.ts +20 -0
  88. package/types/src/util/fileUtil.d.ts +22 -0
  89. package/types/src/util/imageUtil.d.ts +4 -0
  90. package/types/src/yjs/index.d.ts +2 -0
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
3
+ <dc:creator>
4
+ John Doe
5
+ </dc:creator>
6
+ <cp:lastModifiedBy>
7
+ Un-named
8
+ </cp:lastModifiedBy>
9
+ <cp:revision>
10
+ 1
11
+ </cp:revision>
12
+ <dcterms:created xsi:type="dcterms:W3CDTF">FAKE-DATE</dcterms:created>
13
+ <dcterms:modified xsi:type="dcterms:W3CDTF">FAKE-DATE</dcterms:modified>
14
+ </cp:coreProperties>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
3
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>
4
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering" Target="numbering.xml"/>
5
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" Target="footnotes.xml"/>
6
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/>
7
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" Target="comments.xml"/>
8
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/header" Target="header1.xml"/>
9
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer" Target="footer1.xml"/>
10
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/>
11
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="" TargetMode="External"/>
12
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.webm" TargetMode="External"/>
13
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3" TargetMode="External"/>
14
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="" TargetMode="External"/>
15
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="https://www.blocknotejs.org" TargetMode="External"/>
16
+ <Relationship Id="FAKE-ID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/e1037269513fbdc121e06bb1bc7cf37b9045c8fc.gif"/>
17
+ </Relationships>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <w:ftr xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
3
+ <w:p>
4
+ <w:r>
5
+ <w:t xml:space="preserve">Footer</w:t>
6
+ </w:r>
7
+ </w:p>
8
+ </w:ftr>
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <w:hdr xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex">
3
+ <w:p>
4
+ <w:r>
5
+ <w:t xml:space="preserve">Header</w:t>
6
+ </w:r>
7
+ </w:p>
8
+ </w:hdr>
@@ -0,0 +1,222 @@
1
+ import {
2
+ BlockMapping,
3
+ COLORS_DEFAULT,
4
+ DefaultBlockSchema,
5
+ DefaultProps,
6
+ UnreachableCaseError,
7
+ } from "@blocknote/core";
8
+ import {
9
+ CheckBox,
10
+ Table as DocxTable,
11
+ ExternalHyperlink,
12
+ IParagraphOptions,
13
+ ImageRun,
14
+ Paragraph,
15
+ ParagraphChild,
16
+ ShadingType,
17
+ TextRun,
18
+ } from "docx";
19
+ import { getImageDimensions } from "../imageUtil.js";
20
+ import { Table } from "../util/Table.js";
21
+
22
+ function blockPropsToStyles(
23
+ props: Partial<DefaultProps>,
24
+ colors: typeof COLORS_DEFAULT
25
+ ): IParagraphOptions {
26
+ return {
27
+ shading:
28
+ props.backgroundColor === "default" || !props.backgroundColor
29
+ ? undefined
30
+ : {
31
+ type: ShadingType.SOLID,
32
+ color:
33
+ colors[
34
+ props.backgroundColor as keyof typeof colors
35
+ ].background.slice(1),
36
+ },
37
+ run:
38
+ props.textColor === "default" || !props.textColor
39
+ ? undefined
40
+ : {
41
+ color: colors[props.textColor as keyof typeof colors].text.slice(1),
42
+ },
43
+ alignment:
44
+ !props.textAlignment || props.textAlignment === "left"
45
+ ? undefined
46
+ : props.textAlignment === "center"
47
+ ? "center"
48
+ : props.textAlignment === "right"
49
+ ? "right"
50
+ : props.textAlignment === "justify"
51
+ ? "distribute"
52
+ : (() => {
53
+ throw new UnreachableCaseError(props.textAlignment);
54
+ })(),
55
+ };
56
+ }
57
+ export const docxBlockMappingForDefaultSchema: BlockMapping<
58
+ DefaultBlockSchema,
59
+ any,
60
+ any,
61
+ | Promise<Paragraph[] | Paragraph | DocxTable>
62
+ | Paragraph[]
63
+ | Paragraph
64
+ | DocxTable,
65
+ ParagraphChild
66
+ > = {
67
+ paragraph: (block, exporter) => {
68
+ return new Paragraph({
69
+ ...blockPropsToStyles(block.props, exporter.options.colors),
70
+ children: exporter.transformInlineContent(block.content),
71
+ style: "Normal",
72
+ run: {
73
+ font: "Inter",
74
+ },
75
+ });
76
+ },
77
+ numberedListItem: (block, exporter, nestingLevel) => {
78
+ return new Paragraph({
79
+ ...blockPropsToStyles(block.props, exporter.options.colors),
80
+ children: exporter.transformInlineContent(block.content),
81
+ numbering: {
82
+ reference: "blocknote-numbered-list",
83
+ level: nestingLevel,
84
+ },
85
+ });
86
+ },
87
+ bulletListItem: (block, exporter, nestingLevel) => {
88
+ return new Paragraph({
89
+ ...blockPropsToStyles(block.props, exporter.options.colors),
90
+ children: exporter.transformInlineContent(block.content),
91
+ numbering: {
92
+ reference: "blocknote-bullet-list",
93
+ level: nestingLevel,
94
+ },
95
+ });
96
+ },
97
+ checkListItem: (block, exporter) => {
98
+ return new Paragraph({
99
+ ...blockPropsToStyles(block.props, exporter.options.colors),
100
+ children: [
101
+ new CheckBox({ checked: block.props.checked }),
102
+ new TextRun({
103
+ children: [" "],
104
+ }),
105
+ ...exporter.transformInlineContent(block.content),
106
+ ],
107
+ });
108
+ },
109
+ heading: (block, exporter) => {
110
+ return new Paragraph({
111
+ ...blockPropsToStyles(block.props, exporter.options.colors),
112
+ children: exporter.transformInlineContent(block.content),
113
+ heading: `Heading${block.props.level}`,
114
+ });
115
+ },
116
+ audio: (block, exporter) => {
117
+ return [
118
+ file(block.props, "Open audio", exporter),
119
+ ...caption(block.props, exporter),
120
+ ];
121
+ },
122
+ video: (block, exporter) => {
123
+ return [
124
+ file(block.props, "Open video", exporter),
125
+ ...caption(block.props, exporter),
126
+ ];
127
+ },
128
+ file: (block, exporter) => {
129
+ return [
130
+ file(block.props, "Open file", exporter),
131
+ ...caption(block.props, exporter),
132
+ ];
133
+ },
134
+ // TODO
135
+ codeBlock: (block, exporter) => {
136
+ return new Paragraph({
137
+ // ...blockPropsToStyles(block.props, exporter.options.colors),
138
+ style: "Codeblock",
139
+ children: exporter.transformInlineContent(block.content),
140
+ // children: [
141
+ // new TextRun({
142
+ // text: block..type + " not implemented",
143
+ // }),
144
+ // ],
145
+ });
146
+ },
147
+ image: async (block, exporter) => {
148
+ const blob = await exporter.resolveFile(block.props.url);
149
+ const { width, height } = await getImageDimensions(blob);
150
+
151
+ return [
152
+ new Paragraph({
153
+ ...blockPropsToStyles(block.props, exporter.options.colors),
154
+ children: [
155
+ new ImageRun({
156
+ data: await blob.arrayBuffer(),
157
+ // it would be nicer to set the actual data type here, but then we'd need to use a mime type / image type
158
+ // detector. atm passing gif does not seem to be causing issues as the "type" is mainly used by docxjs internally
159
+ // (i.e.: to make sure it's not svg)
160
+ type: "gif",
161
+ altText: block.props.caption
162
+ ? {
163
+ description: block.props.caption,
164
+ name: block.props.caption,
165
+ title: block.props.caption,
166
+ }
167
+ : undefined,
168
+ transformation: {
169
+ width: block.props.previewWidth,
170
+ height: (block.props.previewWidth / width) * height,
171
+ },
172
+ }),
173
+ ],
174
+ }),
175
+ ...caption(block.props, exporter),
176
+ ];
177
+ },
178
+ table: (block, exporter) => {
179
+ return Table(block.content, exporter);
180
+ },
181
+ };
182
+
183
+ function file(
184
+ props: Partial<DefaultProps & { name: string; url: string }>,
185
+ defaultText: string,
186
+ exporter: any
187
+ ) {
188
+ return new Paragraph({
189
+ ...blockPropsToStyles(props, exporter.options.colors),
190
+ children: [
191
+ new ExternalHyperlink({
192
+ children: [
193
+ new TextRun({
194
+ text: props.name || defaultText,
195
+ style: "Hyperlink",
196
+ }),
197
+ ],
198
+ link: props.url!,
199
+ }),
200
+ ],
201
+ });
202
+ }
203
+
204
+ function caption(
205
+ props: Partial<DefaultProps & { caption: string }>,
206
+ exporter: any
207
+ ) {
208
+ if (!props.caption) {
209
+ return [];
210
+ }
211
+ return [
212
+ new Paragraph({
213
+ ...blockPropsToStyles(props, exporter.options.colors),
214
+ children: [
215
+ new TextRun({
216
+ text: props.caption,
217
+ }),
218
+ ],
219
+ style: "Caption",
220
+ }),
221
+ ];
222
+ }
@@ -0,0 +1,9 @@
1
+ import { docxBlockMappingForDefaultSchema } from "./blocks.js";
2
+ import { docxInlineContentMappingForDefaultSchema } from "./inlinecontent.js";
3
+ import { docxStyleMappingForDefaultSchema } from "./styles.js";
4
+
5
+ export const docxDefaultSchemaMappings = {
6
+ blockMapping: docxBlockMappingForDefaultSchema,
7
+ inlineContentMapping: docxInlineContentMappingForDefaultSchema,
8
+ styleMapping: docxStyleMappingForDefaultSchema,
9
+ };
@@ -0,0 +1,29 @@
1
+ import {
2
+ DefaultInlineContentSchema,
3
+ DefaultStyleSchema,
4
+ InlineContentMapping,
5
+ } from "@blocknote/core";
6
+ import { ExternalHyperlink, ParagraphChild, TextRun } from "docx";
7
+ import type { DOCXExporter } from "../docxExporter.js";
8
+
9
+ export const docxInlineContentMappingForDefaultSchema: InlineContentMapping<
10
+ DefaultInlineContentSchema,
11
+ DefaultStyleSchema,
12
+ ParagraphChild,
13
+ TextRun
14
+ > = {
15
+ link: (ic, exporter) => {
16
+ return new ExternalHyperlink({
17
+ children: ic.content.map((content) => {
18
+ return (exporter as DOCXExporter<any, any, any>).transformStyledText(
19
+ content,
20
+ true
21
+ );
22
+ }),
23
+ link: ic.href,
24
+ });
25
+ },
26
+ text: (ic, t) => {
27
+ return t.transformStyledText(ic);
28
+ },
29
+ };
@@ -0,0 +1,73 @@
1
+ import { DefaultStyleSchema, StyleMapping } from "@blocknote/core";
2
+ import { IRunPropertiesOptions } from "docx";
3
+
4
+ export const docxStyleMappingForDefaultSchema: StyleMapping<
5
+ DefaultStyleSchema,
6
+ IRunPropertiesOptions
7
+ > = {
8
+ bold: (val) => {
9
+ if (!val) {
10
+ return {};
11
+ }
12
+ return {
13
+ bold: val,
14
+ };
15
+ },
16
+ italic: (val) => {
17
+ if (!val) {
18
+ return {};
19
+ }
20
+ return {
21
+ italics: val,
22
+ };
23
+ },
24
+ underline: (val) => {
25
+ if (!val) {
26
+ return {};
27
+ }
28
+ return {
29
+ underline: {
30
+ type: "single",
31
+ },
32
+ };
33
+ },
34
+ strike: (val) => {
35
+ if (!val) {
36
+ return {};
37
+ }
38
+ return {
39
+ strike: val,
40
+ };
41
+ },
42
+ backgroundColor: (val, exporter) => {
43
+ if (!val) {
44
+ return {};
45
+ }
46
+ return {
47
+ shading: {
48
+ fill: exporter.options.colors[
49
+ val as keyof typeof exporter.options.colors
50
+ ].background.slice(1),
51
+ },
52
+ };
53
+ },
54
+ textColor: (val, exporter) => {
55
+ if (!val) {
56
+ return {};
57
+ }
58
+ return {
59
+ color:
60
+ exporter.options.colors[
61
+ val as keyof typeof exporter.options.colors
62
+ ].text.slice(1),
63
+ };
64
+ },
65
+ code: (val) => {
66
+ if (!val) {
67
+ return {};
68
+ }
69
+ return {
70
+ font: "Courier New",
71
+ };
72
+ },
73
+ };
@@ -0,0 +1,118 @@
1
+ import { BlockNoteSchema } from "@blocknote/core";
2
+ import { testDocument } from "@shared/testDocument.js";
3
+ import AdmZip from "adm-zip";
4
+ import { Packer, Paragraph, TextRun } from "docx";
5
+ import { describe, expect, it } from "vitest";
6
+ import xmlFormat from "xml-formatter";
7
+ import { docxDefaultSchemaMappings } from "./defaultSchema/index.js";
8
+ import { DOCXExporter } from "./docxExporter.js";
9
+
10
+ describe("exporter", () => {
11
+ it("should export a document", { timeout: 10000 }, async () => {
12
+ const exporter = new DOCXExporter(
13
+ BlockNoteSchema.create(),
14
+ docxDefaultSchemaMappings
15
+ );
16
+ const doc = await exporter.toDocxJsDocument(testDocument);
17
+
18
+ const buffer = await Packer.toBuffer(doc);
19
+ const zip = new AdmZip(buffer);
20
+
21
+ expect(
22
+ prettify(zip.getEntry("word/document.xml")!.getData().toString())
23
+ ).toMatchFileSnapshot("__snapshots__/basic/document.xml");
24
+ expect(
25
+ prettify(zip.getEntry("word/styles.xml")!.getData().toString())
26
+ ).toMatchFileSnapshot("__snapshots__/basic/styles.xml");
27
+
28
+ // fs.writeFileSync(__dirname + "/My Document.docx", buffer);
29
+ });
30
+
31
+ it(
32
+ "should export a document with custom document options",
33
+ { timeout: 10000 },
34
+ async () => {
35
+ const exporter = new DOCXExporter(
36
+ BlockNoteSchema.create(),
37
+ docxDefaultSchemaMappings
38
+ );
39
+
40
+ const doc = await exporter.toDocxJsDocument(testDocument, {
41
+ documentOptions: {
42
+ creator: "John Doe",
43
+ },
44
+ sectionOptions: {
45
+ headers: {
46
+ default: {
47
+ options: {
48
+ children: [
49
+ new Paragraph({ children: [new TextRun("Header")] }),
50
+ ],
51
+ },
52
+ },
53
+ },
54
+ footers: {
55
+ default: {
56
+ options: {
57
+ children: [
58
+ new Paragraph({ children: [new TextRun("Footer")] }),
59
+ ],
60
+ },
61
+ },
62
+ },
63
+ },
64
+ });
65
+
66
+ const buffer = await Packer.toBuffer(doc);
67
+
68
+ // fs.writeFileSync(__dirname + "/My Document.docx", buffer);
69
+
70
+ const zip = new AdmZip(buffer);
71
+
72
+ // files related to header / footer
73
+ expect(
74
+ prettify(
75
+ zip.getEntry("word/_rels/document.xml.rels")!.getData().toString()
76
+ )
77
+ ).toMatchFileSnapshot(
78
+ "__snapshots__/withCustomOptions/document.xml.rels"
79
+ );
80
+
81
+ expect(
82
+ prettify(zip.getEntry("word/header1.xml")!.getData().toString())
83
+ ).toMatchFileSnapshot("__snapshots__/withCustomOptions/header1.xml");
84
+
85
+ expect(
86
+ prettify(zip.getEntry("word/footer1.xml")!.getData().toString())
87
+ ).toMatchFileSnapshot("__snapshots__/withCustomOptions/footer1.xml");
88
+
89
+ // has author data
90
+ expect(
91
+ prettify(zip.getEntry("docProps/core.xml")!.getData().toString())
92
+ ).toMatchFileSnapshot("__snapshots__/withCustomOptions/core.xml");
93
+ }
94
+ );
95
+ });
96
+
97
+ function prettify(sourceXml: string) {
98
+ let ret = xmlFormat(sourceXml);
99
+
100
+ // replace random ids like r:id="rIdll8_ocxarmodcwrnsavfb"
101
+ ret = ret.replace(/r:id="[a-zA-Z0-9_-]*"/g, 'r:id="FAKE-ID"');
102
+
103
+ // replace random ids like Id="rIdll8_ocxarmodcwrnsavfb"
104
+ ret = ret.replace(/ Id="[a-zA-Z0-9_-]*"/g, ' Id="FAKE-ID"');
105
+
106
+ // replace created date <dcterms:created xsi:type="dcterms:W3CDTF">...</dcterms:created>
107
+ ret = ret.replace(
108
+ /<dcterms:created xsi:type="dcterms:W3CDTF">[^<]*<\/dcterms:created>/g,
109
+ '<dcterms:created xsi:type="dcterms:W3CDTF">FAKE-DATE</dcterms:created>'
110
+ );
111
+
112
+ // replace modified date <dcterms:modified xsi:type="dcterms:W3CDTF">...</dcterms:modified>
113
+ ret = ret.replace(
114
+ /<dcterms:modified xsi:type="dcterms:W3CDTF">[^<]*<\/dcterms:modified>/g,
115
+ '<dcterms:modified xsi:type="dcterms:W3CDTF">FAKE-DATE</dcterms:modified>'
116
+ );
117
+ return ret;
118
+ }