@blocknote/xl-pdf-exporter 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/GeistMono-Regular-D4rKXxwr.js +5 -0
- package/dist/GeistMono-Regular-D4rKXxwr.js.map +1 -0
- package/dist/blocknote-xl-pdf-exporter.js +228 -2293
- package/dist/blocknote-xl-pdf-exporter.js.map +1 -1
- package/dist/blocknote-xl-pdf-exporter.umd.cjs +2 -68
- package/dist/blocknote-xl-pdf-exporter.umd.cjs.map +1 -1
- package/dist/webpack-stats.json +1 -1
- package/package.json +5 -4
- package/src/pdf/__snapshots__/example.jsx +910 -567
- package/src/pdf/__snapshots__/exampleWithHeaderAndFooter.jsx +934 -576
- package/src/pdf/defaultSchema/blocks.tsx +35 -2
- package/src/pdf/defaultSchema/styles.tsx +1 -1
- package/src/pdf/pdfExporter.test.tsx +12 -7
- package/src/pdf/pdfExporter.tsx +14 -4
- package/types/src/pdf/defaultSchema/blocks.d.ts +2 -2
- package/types/src/pdf/defaultSchema/index.d.ts +17 -0
- package/types/src/pdf/pdfExporter.d.ts +0 -1
|
@@ -2,6 +2,8 @@ import {
|
|
|
2
2
|
BlockMapping,
|
|
3
3
|
DefaultBlockSchema,
|
|
4
4
|
DefaultProps,
|
|
5
|
+
pageBreakSchema,
|
|
6
|
+
StyledText,
|
|
5
7
|
} from "@blocknote/core";
|
|
6
8
|
import { Image, Link, Path, Svg, Text, View } from "@react-pdf/renderer";
|
|
7
9
|
import {
|
|
@@ -16,7 +18,7 @@ const PIXELS_PER_POINT = 0.75;
|
|
|
16
18
|
const FONT_SIZE = 16;
|
|
17
19
|
|
|
18
20
|
export const pdfBlockMappingForDefaultSchema: BlockMapping<
|
|
19
|
-
DefaultBlockSchema,
|
|
21
|
+
DefaultBlockSchema & typeof pageBreakSchema.blockSchema,
|
|
20
22
|
any,
|
|
21
23
|
any,
|
|
22
24
|
React.ReactElement<Text>,
|
|
@@ -69,7 +71,38 @@ export const pdfBlockMappingForDefaultSchema: BlockMapping<
|
|
|
69
71
|
);
|
|
70
72
|
},
|
|
71
73
|
codeBlock: (block) => {
|
|
72
|
-
|
|
74
|
+
const textContent = (block.content as StyledText<any>[])[0]?.text || "";
|
|
75
|
+
const lines = textContent.split("\n").map((line, index) => {
|
|
76
|
+
const indent = line.match(/^\s*/)?.[0].length || 0;
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Text
|
|
80
|
+
key={`line_${index}`}
|
|
81
|
+
style={{
|
|
82
|
+
marginLeft: indent * 9.5 * PIXELS_PER_POINT,
|
|
83
|
+
}}>
|
|
84
|
+
{line.trimStart() || <> </>}
|
|
85
|
+
</Text>
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<View
|
|
91
|
+
wrap={false}
|
|
92
|
+
style={{
|
|
93
|
+
padding: 24 * PIXELS_PER_POINT,
|
|
94
|
+
backgroundColor: "#161616",
|
|
95
|
+
color: "#ffffff",
|
|
96
|
+
lineHeight: 1.25,
|
|
97
|
+
fontSize: FONT_SIZE * PIXELS_PER_POINT,
|
|
98
|
+
fontFamily: "GeistMono",
|
|
99
|
+
}}>
|
|
100
|
+
{lines}
|
|
101
|
+
</View>
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
pageBreak: () => {
|
|
105
|
+
return <View break />;
|
|
73
106
|
},
|
|
74
107
|
audio: (block, exporter) => {
|
|
75
108
|
return (
|
|
@@ -6,10 +6,11 @@ import {
|
|
|
6
6
|
defaultBlockSpecs,
|
|
7
7
|
defaultInlineContentSpecs,
|
|
8
8
|
defaultStyleSpecs,
|
|
9
|
+
PageBreak,
|
|
9
10
|
} from "@blocknote/core";
|
|
10
11
|
import { Text } from "@react-pdf/renderer";
|
|
11
12
|
import { testDocument } from "@shared/testDocument.js";
|
|
12
|
-
import
|
|
13
|
+
import reactElementToJSXString from "react-element-to-jsx-string";
|
|
13
14
|
import { describe, expect, it } from "vitest";
|
|
14
15
|
import { pdfDefaultSchemaMappings } from "./defaultSchema/index.js";
|
|
15
16
|
import { PDFExporter } from "./pdfExporter.js";
|
|
@@ -26,6 +27,7 @@ describe("exporter", () => {
|
|
|
26
27
|
const schema = BlockNoteSchema.create({
|
|
27
28
|
blockSpecs: {
|
|
28
29
|
...defaultBlockSpecs,
|
|
30
|
+
pageBreak: PageBreak,
|
|
29
31
|
extraBlock: createBlockSpec(
|
|
30
32
|
{
|
|
31
33
|
content: "none",
|
|
@@ -155,13 +157,15 @@ describe("exporter", () => {
|
|
|
155
157
|
|
|
156
158
|
it("should export a document", async () => {
|
|
157
159
|
const exporter = new PDFExporter(
|
|
158
|
-
BlockNoteSchema.create(
|
|
160
|
+
BlockNoteSchema.create({
|
|
161
|
+
blockSpecs: { ...defaultBlockSpecs, pageBreak: PageBreak },
|
|
162
|
+
}),
|
|
159
163
|
pdfDefaultSchemaMappings
|
|
160
164
|
);
|
|
161
165
|
|
|
162
166
|
const transformed = await exporter.toReactPDFDocument(testDocument);
|
|
163
|
-
const
|
|
164
|
-
|
|
167
|
+
const str = reactElementToJSXString(transformed);
|
|
168
|
+
|
|
165
169
|
expect(str).toMatchFileSnapshot("__snapshots__/example.jsx");
|
|
166
170
|
|
|
167
171
|
// would be nice to compare pdf images, but currently doesn't work on mac os (due to node canvas installation issue)
|
|
@@ -186,7 +190,9 @@ describe("exporter", () => {
|
|
|
186
190
|
|
|
187
191
|
it("should export a document with header and footer", async () => {
|
|
188
192
|
const exporter = new PDFExporter(
|
|
189
|
-
BlockNoteSchema.create(
|
|
193
|
+
BlockNoteSchema.create({
|
|
194
|
+
blockSpecs: { ...defaultBlockSpecs, pageBreak: PageBreak },
|
|
195
|
+
}),
|
|
190
196
|
pdfDefaultSchemaMappings
|
|
191
197
|
);
|
|
192
198
|
|
|
@@ -194,8 +200,7 @@ describe("exporter", () => {
|
|
|
194
200
|
header: <Text>Header</Text>,
|
|
195
201
|
footer: <Text>Footer</Text>,
|
|
196
202
|
});
|
|
197
|
-
const
|
|
198
|
-
const str = prettyDOM(view.container, undefined, { highlight: false });
|
|
203
|
+
const str = reactElementToJSXString(transformed);
|
|
199
204
|
expect(str).toMatchFileSnapshot(
|
|
200
205
|
"__snapshots__/exampleWithHeaderAndFooter.jsx"
|
|
201
206
|
);
|
package/src/pdf/pdfExporter.tsx
CHANGED
|
@@ -63,7 +63,6 @@ export class PDFExporter<
|
|
|
63
63
|
fontSize: FONT_SIZE * PIXELS_PER_POINT, // pixels
|
|
64
64
|
lineHeight: 1.5,
|
|
65
65
|
},
|
|
66
|
-
section: {},
|
|
67
66
|
block: {},
|
|
68
67
|
blockChildren: {},
|
|
69
68
|
header: {},
|
|
@@ -145,6 +144,11 @@ export class PDFExporter<
|
|
|
145
144
|
numberedListIndex
|
|
146
145
|
); // TODO: any
|
|
147
146
|
|
|
147
|
+
if (b.type === "pageBreak") {
|
|
148
|
+
ret.push(self);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
148
152
|
const style = this.blocknoteDefaultPropsToReactPDFStyle(b.props as any);
|
|
149
153
|
ret.push(
|
|
150
154
|
<>
|
|
@@ -216,6 +220,14 @@ export class PDFExporter<
|
|
|
216
220
|
fontWeight: "bold",
|
|
217
221
|
});
|
|
218
222
|
|
|
223
|
+
font = await loadFontDataUrl(
|
|
224
|
+
await import("@shared/assets/fonts/GeistMono-Regular.ttf")
|
|
225
|
+
);
|
|
226
|
+
Font.register({
|
|
227
|
+
family: "GeistMono",
|
|
228
|
+
src: font,
|
|
229
|
+
});
|
|
230
|
+
|
|
219
231
|
this.fontsRegistered = true;
|
|
220
232
|
}
|
|
221
233
|
|
|
@@ -247,9 +259,7 @@ export class PDFExporter<
|
|
|
247
259
|
{options.header}
|
|
248
260
|
</View>
|
|
249
261
|
)}
|
|
250
|
-
|
|
251
|
-
{await this.transformBlocks(blocks)}
|
|
252
|
-
</View>
|
|
262
|
+
{await this.transformBlocks(blocks)}
|
|
253
263
|
{options.footer && (
|
|
254
264
|
<View
|
|
255
265
|
fixed
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { BlockMapping, DefaultBlockSchema } from "@blocknote/core";
|
|
2
|
+
import { BlockMapping, DefaultBlockSchema, pageBreakSchema } from "@blocknote/core";
|
|
3
3
|
import { Link, Text } from "@react-pdf/renderer";
|
|
4
|
-
export declare const pdfBlockMappingForDefaultSchema: BlockMapping<DefaultBlockSchema, any, any, React.ReactElement<Text>, React.ReactElement<Text> | React.ReactElement<Link>>;
|
|
4
|
+
export declare const pdfBlockMappingForDefaultSchema: BlockMapping<DefaultBlockSchema & typeof pageBreakSchema.blockSchema, any, any, React.ReactElement<Text>, React.ReactElement<Text> | React.ReactElement<Link>>;
|
|
@@ -447,6 +447,23 @@ export declare const pdfDefaultSchemaMappings: {
|
|
|
447
447
|
fileBlockAccept: string[];
|
|
448
448
|
}, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
|
|
449
449
|
};
|
|
450
|
+
}> & import("@blocknote/core").BlockSchemaFromSpecs<{
|
|
451
|
+
pageBreak: {
|
|
452
|
+
config: {
|
|
453
|
+
type: "pageBreak";
|
|
454
|
+
propSchema: {};
|
|
455
|
+
content: "none";
|
|
456
|
+
isFileBlock: false;
|
|
457
|
+
isSelectable: false;
|
|
458
|
+
};
|
|
459
|
+
implementation: import("@blocknote/core").TiptapBlockImplementation<{
|
|
460
|
+
type: "pageBreak";
|
|
461
|
+
propSchema: {};
|
|
462
|
+
content: "none";
|
|
463
|
+
isFileBlock: false;
|
|
464
|
+
isSelectable: false;
|
|
465
|
+
}, any, import("@blocknote/core").InlineContentSchema, import("@blocknote/core").StyleSchema>;
|
|
466
|
+
};
|
|
450
467
|
}>, any, any, import("react").ReactElement<import("@react-pdf/renderer").Text, string | import("react").JSXElementConstructor<any>>, import("react").ReactElement<import("@react-pdf/renderer").Text, string | import("react").JSXElementConstructor<any>> | import("react").ReactElement<import("@react-pdf/renderer").Link, string | import("react").JSXElementConstructor<any>>>;
|
|
451
468
|
inlineContentMapping: import("@blocknote/core").InlineContentMapping<import("@blocknote/core").InlineContentSchemaFromSpecs<{
|
|
452
469
|
text: {
|