@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,269 @@
1
+ import {
2
+ Block,
3
+ BlockNoteSchema,
4
+ BlockSchema,
5
+ COLORS_DEFAULT,
6
+ InlineContentSchema,
7
+ StyleSchema,
8
+ StyledText,
9
+ } from "@blocknote/core";
10
+ import {
11
+ AlignmentType,
12
+ Document,
13
+ IRunPropertiesOptions,
14
+ ISectionOptions,
15
+ LevelFormat,
16
+ Packer,
17
+ Paragraph,
18
+ ParagraphChild,
19
+ Tab,
20
+ Table,
21
+ TextRun,
22
+ } from "docx";
23
+
24
+ import { Exporter, ExporterOptions } from "@blocknote/core";
25
+ import { corsProxyResolveFileUrl } from "@shared/api/corsProxy.js";
26
+ import { loadFileBuffer } from "@shared/util/fileUtil.js";
27
+
28
+ // get constructor arg type from Document
29
+ type DocumentOptions = Partial<ConstructorParameters<typeof Document>[0]>;
30
+
31
+ const DEFAULT_TAB_STOP =
32
+ /* default font size */ 16 *
33
+ /* 1 pixel is 0.75 points */ 0.75 *
34
+ /* 1.5em*/ 1.5 *
35
+ /* 1 point is 20 twips */ 20;
36
+
37
+ /**
38
+ * Exports a BlockNote document to a .docx file using the docxjs library.
39
+ */
40
+ export class DOCXExporter<
41
+ B extends BlockSchema,
42
+ S extends StyleSchema,
43
+ I extends InlineContentSchema
44
+ > extends Exporter<
45
+ B,
46
+ I,
47
+ S,
48
+ Promise<Paragraph[] | Paragraph | Table> | Paragraph[] | Paragraph | Table,
49
+ ParagraphChild,
50
+ IRunPropertiesOptions,
51
+ TextRun
52
+ > {
53
+ public constructor(
54
+ /**
55
+ * The schema of your editor. The mappings are automatically typed checked against this schema.
56
+ */
57
+ protected readonly schema: BlockNoteSchema<B, I, S>,
58
+ /**
59
+ * The mappings that map the BlockNote schema to the docxjs content.
60
+ * Pass {@link docxDefaultSchemaMappings} for the default schema.
61
+ */
62
+ protected readonly mappings: Exporter<
63
+ NoInfer<B>,
64
+ NoInfer<I>,
65
+ NoInfer<S>,
66
+ | Promise<Paragraph[] | Paragraph | Table>
67
+ | Paragraph[]
68
+ | Paragraph
69
+ | Table,
70
+ ParagraphChild,
71
+ IRunPropertiesOptions,
72
+ TextRun
73
+ >["mappings"],
74
+ options?: Partial<ExporterOptions>
75
+ ) {
76
+ const defaults = {
77
+ colors: COLORS_DEFAULT,
78
+ resolveFileUrl: corsProxyResolveFileUrl,
79
+ } satisfies Partial<ExporterOptions>;
80
+
81
+ const newOptions = {
82
+ ...defaults,
83
+ ...options,
84
+ };
85
+ super(schema, mappings, newOptions);
86
+ }
87
+
88
+ /**
89
+ * Mostly for internal use, you probably want to use `toBlob` or `toDocxJsDocument` instead.
90
+ */
91
+ public transformStyledText(styledText: StyledText<S>, hyperlink?: boolean) {
92
+ const stylesArray = this.mapStyles(styledText.styles);
93
+
94
+ const styles: IRunPropertiesOptions = Object.assign(
95
+ {} as IRunPropertiesOptions,
96
+ ...stylesArray
97
+ );
98
+
99
+ return new TextRun({
100
+ ...styles,
101
+ style: hyperlink ? "Hyperlink" : undefined,
102
+ text: styledText.text,
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Mostly for internal use, you probably want to use `toBlob` or `toDocxJsDocument` instead.
108
+ */
109
+ public async transformBlocks(
110
+ blocks: Block<B, I, S>[],
111
+ nestingLevel = 0
112
+ ): Promise<Array<Paragraph | Table>> {
113
+ const ret: Array<Paragraph | Table> = [];
114
+
115
+ for (const b of blocks) {
116
+ let children = await this.transformBlocks(b.children, nestingLevel + 1);
117
+ children = children.map((c, _i) => {
118
+ // NOTE: nested tables not supported (we can't insert the new Tab before a table)
119
+ if (
120
+ c instanceof Paragraph &&
121
+ !(c as any).properties.numberingReferences.length
122
+ ) {
123
+ c.addRunToFront(
124
+ new TextRun({
125
+ children: [new Tab()],
126
+ })
127
+ );
128
+ }
129
+ return c;
130
+ });
131
+ const self = await this.mapBlock(b as any, nestingLevel, 0 /*unused*/); // TODO: any
132
+ if (Array.isArray(self)) {
133
+ ret.push(...self, ...children);
134
+ } else {
135
+ ret.push(self, ...children);
136
+ }
137
+ }
138
+ return ret;
139
+ }
140
+
141
+ protected async getFonts(): Promise<DocumentOptions["fonts"]> {
142
+ // Unfortunately, loading the variable font doesn't work
143
+ // "./src/fonts/Inter-VariableFont_opsz,wght.ttf",
144
+
145
+ let font = await loadFileBuffer(
146
+ await import("@shared/assets/fonts/inter/Inter_18pt-Regular.ttf")
147
+ );
148
+
149
+ if (font instanceof ArrayBuffer) {
150
+ // conversionw with Polyfill needed because docxjs requires Buffer
151
+ const Buffer = (await import("buffer")).Buffer;
152
+ font = Buffer.from(font);
153
+ }
154
+
155
+ return [{ name: "Inter", data: font as Buffer }];
156
+ }
157
+
158
+ protected async createDefaultDocumentOptions(): Promise<DocumentOptions> {
159
+ const externalStyles = (await import("./template/word/styles.xml?raw"))
160
+ .default;
161
+
162
+ const bullets = ["•"]; //, "◦", "▪"]; (these don't look great, just use solid bullet for now)
163
+ return {
164
+ numbering: {
165
+ config: [
166
+ {
167
+ reference: "blocknote-numbered-list",
168
+ levels: Array.from({ length: 9 }, (_, i) => ({
169
+ start: 1,
170
+ level: i,
171
+ format: LevelFormat.DECIMAL,
172
+ text: `%${i + 1}.`,
173
+ alignment: AlignmentType.LEFT,
174
+ style: {
175
+ paragraph: {
176
+ indent: {
177
+ left: DEFAULT_TAB_STOP * (i + 1),
178
+ hanging: DEFAULT_TAB_STOP,
179
+ },
180
+ },
181
+ },
182
+ })),
183
+ },
184
+ {
185
+ reference: "blocknote-bullet-list",
186
+ levels: Array.from({ length: 9 }, (_, i) => ({
187
+ start: 1,
188
+ level: i,
189
+ format: LevelFormat.BULLET,
190
+ text: bullets[i % bullets.length],
191
+ alignment: AlignmentType.LEFT,
192
+ style: {
193
+ paragraph: {
194
+ indent: {
195
+ left: DEFAULT_TAB_STOP * (i + 1),
196
+ hanging: DEFAULT_TAB_STOP,
197
+ },
198
+ },
199
+ },
200
+ })),
201
+ },
202
+ ],
203
+ },
204
+ fonts: await this.getFonts(),
205
+ defaultTabStop: 200,
206
+ externalStyles,
207
+ };
208
+ }
209
+
210
+ /**
211
+ * Convert a document (array of Blocks to a Blob representing a .docx file)
212
+ */
213
+ public async toBlob(
214
+ blocks: Block<B, I, S>[],
215
+ options: {
216
+ sectionOptions: Omit<ISectionOptions, "children">;
217
+ documentOptions: DocumentOptions;
218
+ } = {
219
+ sectionOptions: {},
220
+ documentOptions: {},
221
+ }
222
+ ) {
223
+ const doc = await this.toDocxJsDocument(blocks, options);
224
+ const prevBuffer = globalThis.Buffer;
225
+ try {
226
+ if (!globalThis.Buffer) {
227
+ // load Buffer polyfill because docxjs requires this
228
+ globalThis.Buffer = (await import("buffer")).Buffer;
229
+ }
230
+ return Packer.toBlob(doc);
231
+ } finally {
232
+ globalThis.Buffer = prevBuffer;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Convert a document (array of Blocks to a docxjs Document)
238
+ */
239
+ public async toDocxJsDocument(
240
+ blocks: Block<B, I, S>[],
241
+ options: {
242
+ sectionOptions: Omit<ISectionOptions, "children">;
243
+ documentOptions: DocumentOptions;
244
+ } = {
245
+ sectionOptions: {},
246
+ documentOptions: {},
247
+ }
248
+ ) {
249
+ const doc = new Document({
250
+ ...(await this.createDefaultDocumentOptions()),
251
+ ...options.documentOptions,
252
+ sections: [
253
+ {
254
+ children: await this.transformBlocks(blocks),
255
+ ...options.sectionOptions,
256
+ },
257
+ ],
258
+ });
259
+
260
+ // fix https://github.com/dolanmiu/docx/pull/2800/files
261
+ doc.Document.Relationships.createRelationship(
262
+ doc.Document.Relationships.RelationshipCount + 1,
263
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
264
+ "fontTable.xml"
265
+ );
266
+
267
+ return doc;
268
+ }
269
+ }
@@ -0,0 +1,21 @@
1
+ import type Sharp from "sharp";
2
+
3
+ export async function getImageDimensions(blob: Blob) {
4
+ if (typeof window !== "undefined" && import.meta.env.NODE_ENV !== "test") {
5
+ const bmp = await createImageBitmap(blob);
6
+ const { width, height } = bmp;
7
+ bmp.close(); // free memory
8
+ return { width, height };
9
+ } else {
10
+ // node or vitest
11
+ const sharp = (await require("sharp")) as typeof Sharp;
12
+ const buffer = await blob.arrayBuffer();
13
+
14
+ // const buffer2 = Buffer.from(buffer); for jsdom, currently disabled
15
+ const metadata = await sharp(buffer).metadata();
16
+ if (!metadata.width || !metadata.height) {
17
+ throw new Error("Image has no width or height");
18
+ }
19
+ return { width: metadata.width, height: metadata.height };
20
+ }
21
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./defaultSchema/index.js";
2
+ export * from "./docxExporter.js";
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
3
+ <Default Extension="jpeg" ContentType="image/jpeg" />
4
+ <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
5
+ <Default Extension="xml" ContentType="application/xml" />
6
+ <Override PartName="/word/document.xml"
7
+ ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" />
8
+ <Override PartName="/word/styles.xml"
9
+ ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" />
10
+ <Override PartName="/word/settings.xml"
11
+ ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml" />
12
+ <Override PartName="/word/webSettings.xml"
13
+ ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml" />
14
+ <Override PartName="/word/fontTable.xml"
15
+ ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml" />
16
+ <Override PartName="/word/theme/theme1.xml"
17
+ ContentType="application/vnd.openxmlformats-officedocument.theme+xml" />
18
+ <Override PartName="/docProps/core.xml"
19
+ ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
20
+ <Override PartName="/docProps/app.xml"
21
+ ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />
22
+ </Types>
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
@@ -0,0 +1,35 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
3
+ xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
4
+ <Template>Normal.dotm</Template>
5
+ <TotalTime>23</TotalTime>
6
+ <Pages>1</Pages>
7
+ <Words>37</Words>
8
+ <Characters>216</Characters>
9
+ <Application>Microsoft Office Word</Application>
10
+ <DocSecurity>0</DocSecurity>
11
+ <Lines>1</Lines>
12
+ <Paragraphs>1</Paragraphs>
13
+ <ScaleCrop>false</ScaleCrop>
14
+ <HeadingPairs>
15
+ <vt:vector size="2" baseType="variant">
16
+ <vt:variant>
17
+ <vt:lpstr>Title</vt:lpstr>
18
+ </vt:variant>
19
+ <vt:variant>
20
+ <vt:i4>1</vt:i4>
21
+ </vt:variant>
22
+ </vt:vector>
23
+ </HeadingPairs>
24
+ <TitlesOfParts>
25
+ <vt:vector size="1" baseType="lpstr">
26
+ <vt:lpstr></vt:lpstr>
27
+ </vt:vector>
28
+ </TitlesOfParts>
29
+ <Company></Company>
30
+ <LinksUpToDate>false</LinksUpToDate>
31
+ <CharactersWithSpaces>252</CharactersWithSpaces>
32
+ <SharedDoc>false</SharedDoc>
33
+ <HyperlinksChanged>false</HyperlinksChanged>
34
+ <AppVersion>16.0000</AppVersion>
35
+ </Properties>
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <cp:coreProperties
3
+ xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
4
+ xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/"
5
+ xmlns:dcmitype="http://purl.org/dc/dcmitype/"
6
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
7
+ <dc:title></dc:title>
8
+ <dc:subject></dc:subject>
9
+ <dc:creator>BlockNote</dc:creator>
10
+ <cp:keywords></cp:keywords>
11
+ <dc:description></dc:description>
12
+ <cp:lastModifiedBy>BlockNote</cp:lastModifiedBy>
13
+ <cp:revision>3</cp:revision>
14
+ <dcterms:created xsi:type="dcterms:W3CDTF">2024-10-19T14:19:00Z</dcterms:created>
15
+ <dcterms:modified xsi:type="dcterms:W3CDTF">2024-11-01T04:50:00Z</dcterms:modified>
16
+ </cp:coreProperties>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
3
+ <Relationship Id="rId3"
4
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"
5
+ Target="webSettings.xml" />
6
+ <Relationship Id="rId7"
7
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"
8
+ Target="theme/theme1.xml" />
9
+ <Relationship Id="rId2"
10
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"
11
+ Target="settings.xml" />
12
+ <Relationship Id="rId1"
13
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
14
+ Target="styles.xml" />
15
+ <Relationship Id="rId6"
16
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"
17
+ Target="fontTable.xml" />
18
+ <Relationship Id="rId5"
19
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
20
+ Target="media/image1.jpeg" />
21
+ <Relationship Id="rId4"
22
+ Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink"
23
+ Target="https://www.blocknotejs.org/" TargetMode="External" />
24
+ </Relationships>