jspdf-md-renderer 3.1.0 → 3.3.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/README.md +34 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +2 -2
- package/dist/index.mjs +824 -570
- package/dist/index.umd.js +2 -2
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,90 @@
|
|
|
1
|
-
import { marked as
|
|
2
|
-
import
|
|
1
|
+
import { marked as j } from "marked";
|
|
2
|
+
import O from "jspdf-autotable";
|
|
3
3
|
var u = /* @__PURE__ */ ((t) => (t.Heading = "heading", t.Paragraph = "paragraph", t.List = "list", t.ListItem = "list_item", t.Blockquote = "blockquote", t.Code = "code", t.CodeSpan = "codespan", t.Table = "table", t.Html = "html", t.Hr = "hr", t.Image = "image", t.Link = "link", t.Strong = "strong", t.Em = "em", t.TableHeader = "table_header", t.TableCell = "table_cell", t.Raw = "raw", t.Text = "text", t))(u || {});
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
return
|
|
4
|
+
const D = "__jmr_", q = /(!\[[^\]]*\]\()([^)]+)(\))\s*\{([^}]+)\}/g, U = /(\w+)\s*=\s*(\w+)/g, R = ["left", "center", "right"], Q = (t) => {
|
|
5
|
+
const e = [];
|
|
6
|
+
return t.width !== void 0 && e.push(`w=${t.width}`), t.height !== void 0 && e.push(`h=${t.height}`), t.align && e.push(`a=${t.align}`), e.length > 0 ? `#${D}${e.join("&")}` : "";
|
|
7
|
+
}, V = (t) => {
|
|
8
|
+
const e = {};
|
|
9
|
+
let i;
|
|
10
|
+
for (; (i = U.exec(t)) !== null; ) {
|
|
11
|
+
const r = i[1].toLowerCase(), h = i[2];
|
|
12
|
+
switch (r) {
|
|
13
|
+
case "width":
|
|
14
|
+
case "w": {
|
|
15
|
+
const o = parseInt(h, 10);
|
|
16
|
+
!isNaN(o) && o > 0 && (e.width = o);
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
case "height":
|
|
20
|
+
case "h": {
|
|
21
|
+
const o = parseInt(h, 10);
|
|
22
|
+
!isNaN(o) && o > 0 && (e.height = o);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case "align": {
|
|
26
|
+
const o = h.toLowerCase();
|
|
27
|
+
R.includes(
|
|
28
|
+
o
|
|
29
|
+
) && (e.align = o);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return e;
|
|
35
|
+
}, Z = (t) => t.replace(
|
|
36
|
+
q,
|
|
37
|
+
(e, i, r, h, o) => {
|
|
38
|
+
const l = V(o), a = Q(l);
|
|
39
|
+
return `${i}${r}${a}${h}`;
|
|
40
|
+
}
|
|
41
|
+
), K = (t) => {
|
|
42
|
+
const e = t.indexOf(`#${D}`);
|
|
43
|
+
if (e === -1)
|
|
44
|
+
return { cleanHref: t, attrs: {} };
|
|
45
|
+
const i = t.substring(0, e), r = t.substring(e + 1 + D.length), h = {}, o = r.split("&");
|
|
46
|
+
for (const l of o) {
|
|
47
|
+
const [a, s] = l.split("=");
|
|
48
|
+
switch (a) {
|
|
49
|
+
case "w": {
|
|
50
|
+
const g = parseInt(s, 10);
|
|
51
|
+
!isNaN(g) && g > 0 && (h.width = g);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case "h": {
|
|
55
|
+
const g = parseInt(s, 10);
|
|
56
|
+
!isNaN(g) && g > 0 && (h.height = g);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "a": {
|
|
60
|
+
R.includes(
|
|
61
|
+
s
|
|
62
|
+
) && (h.align = s);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { cleanHref: i, attrs: h };
|
|
68
|
+
}, M = async (t) => {
|
|
69
|
+
const e = Z(t), i = await j.lexer(e, {
|
|
70
|
+
async: !0,
|
|
71
|
+
gfm: !0
|
|
72
|
+
});
|
|
73
|
+
return W(i);
|
|
7
74
|
}, W = (t) => {
|
|
8
|
-
const
|
|
9
|
-
return t.forEach((
|
|
75
|
+
const e = [];
|
|
76
|
+
return t.forEach((i) => {
|
|
10
77
|
try {
|
|
11
|
-
const
|
|
12
|
-
|
|
78
|
+
const r = tt[i.type];
|
|
79
|
+
r ? e.push(r(i)) : e.push({
|
|
13
80
|
type: u.Raw,
|
|
14
|
-
content:
|
|
81
|
+
content: i.raw
|
|
15
82
|
});
|
|
16
|
-
} catch (
|
|
17
|
-
console.error("Failed to handle token ==>",
|
|
83
|
+
} catch (r) {
|
|
84
|
+
console.error("Failed to handle token ==>", i, r);
|
|
18
85
|
}
|
|
19
|
-
}),
|
|
20
|
-
},
|
|
86
|
+
}), e;
|
|
87
|
+
}, tt = {
|
|
21
88
|
[u.Heading]: (t) => ({
|
|
22
89
|
type: u.Heading,
|
|
23
90
|
depth: t.depth,
|
|
@@ -47,22 +114,28 @@ const j = async (t) => {
|
|
|
47
114
|
}),
|
|
48
115
|
[u.Table]: (t) => ({
|
|
49
116
|
type: u.Table,
|
|
50
|
-
header: t.header.map((
|
|
117
|
+
header: t.header.map((e) => ({
|
|
51
118
|
type: u.TableHeader,
|
|
52
|
-
content:
|
|
119
|
+
content: e.text
|
|
53
120
|
})),
|
|
54
121
|
rows: t.rows.map(
|
|
55
|
-
(
|
|
122
|
+
(e) => e.map((i) => ({
|
|
56
123
|
type: u.TableCell,
|
|
57
|
-
content:
|
|
124
|
+
content: i.text
|
|
58
125
|
}))
|
|
59
126
|
)
|
|
60
127
|
}),
|
|
61
|
-
[u.Image]: (t) =>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
128
|
+
[u.Image]: (t) => {
|
|
129
|
+
const { cleanHref: e, attrs: i } = K(t.href);
|
|
130
|
+
return {
|
|
131
|
+
type: u.Image,
|
|
132
|
+
src: e,
|
|
133
|
+
alt: t.text,
|
|
134
|
+
width: i.width,
|
|
135
|
+
height: i.height,
|
|
136
|
+
align: i.align
|
|
137
|
+
};
|
|
138
|
+
},
|
|
66
139
|
[u.Link]: (t) => ({
|
|
67
140
|
type: u.Link,
|
|
68
141
|
href: t.href,
|
|
@@ -99,15 +172,15 @@ const j = async (t) => {
|
|
|
99
172
|
content: t.text,
|
|
100
173
|
items: t.tokens ? W(t.tokens) : []
|
|
101
174
|
})
|
|
102
|
-
},
|
|
103
|
-
static initialize(
|
|
104
|
-
this.options_ =
|
|
175
|
+
}, I = class I {
|
|
176
|
+
static initialize(e) {
|
|
177
|
+
this.options_ = e, this.cursor = { x: e.cursor.x, y: e.cursor.y }, this.lastContentY_ = e.cursor.y;
|
|
105
178
|
}
|
|
106
179
|
static getCursor() {
|
|
107
180
|
return this.cursor;
|
|
108
181
|
}
|
|
109
|
-
static setCursor(
|
|
110
|
-
this.cursor =
|
|
182
|
+
static setCursor(e) {
|
|
183
|
+
this.cursor = e;
|
|
111
184
|
}
|
|
112
185
|
static get options() {
|
|
113
186
|
return this.options_;
|
|
@@ -127,8 +200,8 @@ const j = async (t) => {
|
|
|
127
200
|
* @param operation 'set' to assign a new value, 'add' to increment the current value.
|
|
128
201
|
* @default operation = 'set'
|
|
129
202
|
*/
|
|
130
|
-
static updateX(
|
|
131
|
-
|
|
203
|
+
static updateX(e, i = "set") {
|
|
204
|
+
i === "set" ? this.cursor.x = e : i === "add" && (this.cursor.x += e);
|
|
132
205
|
}
|
|
133
206
|
/**
|
|
134
207
|
* Updates the y pointer of the cursor.
|
|
@@ -136,8 +209,8 @@ const j = async (t) => {
|
|
|
136
209
|
* @param operation 'set' to assign a new value, 'add' to increment the current value.
|
|
137
210
|
* @default operation = 'set'
|
|
138
211
|
*/
|
|
139
|
-
static updateY(
|
|
140
|
-
|
|
212
|
+
static updateY(e, i = "set") {
|
|
213
|
+
i === "set" ? this.cursor.y = e : i === "add" && (this.cursor.y += e);
|
|
141
214
|
}
|
|
142
215
|
/**
|
|
143
216
|
* Records a Y position as the bottom of rendered content.
|
|
@@ -145,8 +218,8 @@ const j = async (t) => {
|
|
|
145
218
|
* where their actual text content ends, ignoring any trailing margins.
|
|
146
219
|
* @param specificY Optional Y value to record. Defaults to current cursor Y.
|
|
147
220
|
*/
|
|
148
|
-
static recordContentY(
|
|
149
|
-
this.lastContentY_ =
|
|
221
|
+
static recordContentY(e) {
|
|
222
|
+
this.lastContentY_ = e !== void 0 ? e : this.cursor.y;
|
|
150
223
|
}
|
|
151
224
|
/**
|
|
152
225
|
* Gets the last Y position recorded as content bottom.
|
|
@@ -162,75 +235,192 @@ const j = async (t) => {
|
|
|
162
235
|
return this.cursor.y;
|
|
163
236
|
}
|
|
164
237
|
};
|
|
165
|
-
|
|
166
|
-
let
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
if (t.setFontSize(
|
|
170
|
-
for (const
|
|
171
|
-
|
|
238
|
+
I.cursor = { x: 0, y: 0 }, I.lastContentY_ = 0, I.inlineLock = !1;
|
|
239
|
+
let n = I;
|
|
240
|
+
const C = (t) => t.getTextDimensions("H").h * n.options.page.defaultLineHeightFactor, y = (t) => t.getTextDimensions("H").w * n.options.page.defaultLineHeightFactor, et = (t, e, i, r) => {
|
|
241
|
+
const h = 6 - (e?.depth ?? 0) > 0 ? 6 - (e?.depth ?? 0) : 1;
|
|
242
|
+
if (t.setFontSize(n.options.page.defaultFontSize + h), e?.items && e?.items.length > 0)
|
|
243
|
+
for (const o of e?.items ?? [])
|
|
244
|
+
r(o, i, !1);
|
|
172
245
|
else {
|
|
173
|
-
const
|
|
246
|
+
const o = C(t);
|
|
174
247
|
t.text(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
248
|
+
e?.content ?? "",
|
|
249
|
+
n.X + i,
|
|
250
|
+
n.Y,
|
|
178
251
|
{
|
|
179
252
|
align: "left",
|
|
180
|
-
maxWidth:
|
|
253
|
+
maxWidth: n.options.page.maxContentWidth - i,
|
|
181
254
|
baseline: "top"
|
|
182
255
|
}
|
|
183
|
-
),
|
|
256
|
+
), n.recordContentY(n.Y + o), n.updateY(o, "add");
|
|
257
|
+
}
|
|
258
|
+
t.setFontSize(n.options.page.defaultFontSize), n.updateX(n.options.page.xpading, "set");
|
|
259
|
+
}, Y = (t) => {
|
|
260
|
+
typeof n.options.pageBreakHandler == "function" ? n.options.pageBreakHandler(t) : t.addPage(
|
|
261
|
+
n.options.page?.format,
|
|
262
|
+
n.options.page?.orientation
|
|
263
|
+
), n.updateY(n.options.page.topmargin), n.updateX(n.options.page.xpading);
|
|
264
|
+
}, z = 96, k = (t, e = "mm") => {
|
|
265
|
+
switch (e) {
|
|
266
|
+
case "pt":
|
|
267
|
+
return t * 72 / z;
|
|
268
|
+
case "in":
|
|
269
|
+
return t / z;
|
|
270
|
+
case "px":
|
|
271
|
+
return t;
|
|
272
|
+
default:
|
|
273
|
+
return t * 25.4 / z;
|
|
274
|
+
}
|
|
275
|
+
}, G = (t) => {
|
|
276
|
+
try {
|
|
277
|
+
let e = "";
|
|
278
|
+
if (t.includes("base64,")) {
|
|
279
|
+
const a = t.split("base64,")[1];
|
|
280
|
+
typeof window < "u" && typeof window.atob == "function" ? e = decodeURIComponent(escape(window.atob(a))) : typeof Buffer < "u" ? e = Buffer.from(a, "base64").toString("utf-8") : e = decodeURIComponent(escape(atob(a)));
|
|
281
|
+
} else
|
|
282
|
+
e = decodeURIComponent(t.split(",")[1] || "");
|
|
283
|
+
const i = e.match(
|
|
284
|
+
/<svg[^>]*\swidth=(?:'|")([0-9.]+)[a-zA-Z]*(?:'|")/i
|
|
285
|
+
), r = e.match(
|
|
286
|
+
/<svg[^>]*\sheight=(?:'|")([0-9.]+)[a-zA-Z]*(?:'|")/i
|
|
287
|
+
), h = e.match(
|
|
288
|
+
/<svg[^>]*\sviewBox=(?:'|")[^'"]*(?:'|")/i
|
|
289
|
+
);
|
|
290
|
+
let o = i ? parseFloat(i[1]) : 0, l = r ? parseFloat(r[1]) : 0;
|
|
291
|
+
if ((!o || !l) && h) {
|
|
292
|
+
const a = h[0].match(
|
|
293
|
+
/viewBox=(?:'|")([^'"]+)(?:'|")/i
|
|
294
|
+
);
|
|
295
|
+
if (a) {
|
|
296
|
+
const s = a[1].split(/[ ,]+/).filter(Boolean).map(parseFloat);
|
|
297
|
+
s.length >= 4 && (o = o || s[2], l = l || s[3]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (o > 0 && l > 0) return { width: o, height: l };
|
|
301
|
+
} catch (e) {
|
|
302
|
+
console.warn("Failed to extract SVG dimensions:", e);
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}, _ = (t, e, i, r, h = "mm") => {
|
|
306
|
+
if (!e.data)
|
|
307
|
+
return { finalWidth: 0, finalHeight: 0 };
|
|
308
|
+
let o = e.naturalWidth || 0, l = e.naturalHeight || 0;
|
|
309
|
+
if (!o || !l)
|
|
310
|
+
if (e.data.startsWith("data:image/svg")) {
|
|
311
|
+
const c = G(e.data);
|
|
312
|
+
c && (o = c.width, l = c.height);
|
|
313
|
+
} else
|
|
314
|
+
try {
|
|
315
|
+
const c = t.getImageProperties(e.data);
|
|
316
|
+
o = c.width, l = c.height;
|
|
317
|
+
} catch (c) {
|
|
318
|
+
console.warn(
|
|
319
|
+
"Failed to get image properties for intrinsic sizing:",
|
|
320
|
+
c
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
const a = l > 0 ? o / l : 1;
|
|
324
|
+
let s, g;
|
|
325
|
+
if (e.width && e.height ? (s = k(e.width, h), g = k(e.height, h)) : e.width ? (s = k(e.width, h), g = s / a) : e.height ? (g = k(e.height, h), s = g * a) : (s = k(o, h), g = k(l, h)), s > i) {
|
|
326
|
+
const c = i / s;
|
|
327
|
+
s = i, g = g * c;
|
|
328
|
+
}
|
|
329
|
+
if (g > r) {
|
|
330
|
+
const c = r / g;
|
|
331
|
+
g = r, s = s * c;
|
|
332
|
+
}
|
|
333
|
+
return { finalWidth: s, finalHeight: g };
|
|
334
|
+
}, $ = async (t) => {
|
|
335
|
+
for (const e of t) {
|
|
336
|
+
if (e.type === u.Image && e.src)
|
|
337
|
+
try {
|
|
338
|
+
if (e.src.startsWith("data:"))
|
|
339
|
+
e.data = e.src;
|
|
340
|
+
else {
|
|
341
|
+
const i = await fetch(e.src);
|
|
342
|
+
if (!i.ok)
|
|
343
|
+
throw new Error(
|
|
344
|
+
`Failed to fetch image: ${i.statusText}`
|
|
345
|
+
);
|
|
346
|
+
const r = await i.blob(), h = await new Promise(
|
|
347
|
+
(o, l) => {
|
|
348
|
+
const a = new FileReader();
|
|
349
|
+
a.onloadend = () => {
|
|
350
|
+
typeof a.result == "string" ? o(a.result) : l(
|
|
351
|
+
new Error(
|
|
352
|
+
"Failed to convert image to base64 string"
|
|
353
|
+
)
|
|
354
|
+
);
|
|
355
|
+
}, a.onerror = l, a.readAsDataURL(r);
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
e.data = h;
|
|
359
|
+
}
|
|
360
|
+
e.data && e.data.startsWith("data:image/svg") && typeof window < "u" && typeof document < "u" && (e.data = await new Promise((i) => {
|
|
361
|
+
const r = new Image();
|
|
362
|
+
r.onload = () => {
|
|
363
|
+
const h = document.createElement("canvas"), o = G(
|
|
364
|
+
e.data
|
|
365
|
+
), l = o ? o.width : r.width || 300, a = o ? o.height : r.height || 150;
|
|
366
|
+
e.naturalWidth = l, e.naturalHeight = a;
|
|
367
|
+
const s = 4;
|
|
368
|
+
h.width = l * s, h.height = a * s;
|
|
369
|
+
const g = h.getContext("2d");
|
|
370
|
+
g ? (g.scale(s, s), g.drawImage(r, 0, 0, l, a), i(h.toDataURL("image/png"))) : i(e.data);
|
|
371
|
+
}, r.onerror = () => i(e.data), r.src = e.data;
|
|
372
|
+
}));
|
|
373
|
+
} catch (i) {
|
|
374
|
+
console.warn(
|
|
375
|
+
`[jspdf-md-renderer] Warning: Failed to load image at ${e.src}. It will be skipped.`,
|
|
376
|
+
i
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
e.items && e.items.length > 0 && await $(e.items);
|
|
184
380
|
}
|
|
185
|
-
t.setFontSize(e.options.page.defaultFontSize), e.updateX(e.options.page.xpading, "set");
|
|
186
|
-
}, w = (t) => {
|
|
187
|
-
typeof e.options.pageBreakHandler == "function" ? e.options.pageBreakHandler(t) : t.addPage(
|
|
188
|
-
e.options.page?.format,
|
|
189
|
-
e.options.page?.orientation
|
|
190
|
-
), e.updateY(e.options.page.topmargin), e.updateX(e.options.page.xpading);
|
|
191
381
|
};
|
|
192
|
-
class
|
|
382
|
+
class A {
|
|
193
383
|
// Default codespan styling (can be overridden via RenderStore.options.codespan)
|
|
194
384
|
static getCodespanOptions() {
|
|
195
|
-
const
|
|
385
|
+
const e = n.options.codespan ?? {};
|
|
196
386
|
return {
|
|
197
|
-
backgroundColor:
|
|
198
|
-
padding:
|
|
199
|
-
showBackground:
|
|
200
|
-
fontSizeScale:
|
|
387
|
+
backgroundColor: e.backgroundColor ?? "#EEEEEE",
|
|
388
|
+
padding: e.padding ?? 0.5,
|
|
389
|
+
showBackground: e.showBackground !== !1,
|
|
390
|
+
fontSizeScale: e.fontSizeScale ?? 0.9
|
|
201
391
|
};
|
|
202
392
|
}
|
|
203
393
|
/**
|
|
204
394
|
* Apply font style to the jsPDF document.
|
|
205
395
|
*/
|
|
206
|
-
static applyStyle(
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
return
|
|
210
|
-
},
|
|
211
|
-
const
|
|
212
|
-
return
|
|
396
|
+
static applyStyle(e, i) {
|
|
397
|
+
const r = e.getFont().fontName, h = e.getFontSize(), o = () => {
|
|
398
|
+
const a = n.options.font.bold?.name;
|
|
399
|
+
return a && a !== "" ? a : r;
|
|
400
|
+
}, l = () => {
|
|
401
|
+
const a = n.options.font.regular?.name;
|
|
402
|
+
return a && a !== "" ? a : r;
|
|
213
403
|
};
|
|
214
|
-
switch (
|
|
404
|
+
switch (i) {
|
|
215
405
|
case "bold":
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
406
|
+
e.setFont(
|
|
407
|
+
o(),
|
|
408
|
+
n.options.font.bold?.style || "bold"
|
|
219
409
|
);
|
|
220
410
|
break;
|
|
221
411
|
case "italic":
|
|
222
|
-
|
|
412
|
+
e.setFont(l(), "italic");
|
|
223
413
|
break;
|
|
224
414
|
case "bolditalic":
|
|
225
|
-
|
|
415
|
+
e.setFont(o(), "bolditalic");
|
|
226
416
|
break;
|
|
227
417
|
case "codespan":
|
|
228
|
-
|
|
229
|
-
|
|
418
|
+
e.setFont("courier", "normal"), e.setFontSize(
|
|
419
|
+
h * this.getCodespanOptions().fontSizeScale
|
|
230
420
|
);
|
|
231
421
|
break;
|
|
232
422
|
default:
|
|
233
|
-
|
|
423
|
+
e.setFont(l(), e.getFont().fontStyle);
|
|
234
424
|
break;
|
|
235
425
|
}
|
|
236
426
|
}
|
|
@@ -239,60 +429,79 @@ class E {
|
|
|
239
429
|
* NOTE: jsPDF's getTextWidth() does NOT include charSpace in its calculation,
|
|
240
430
|
* so we must manually add it: effectiveWidth = getTextWidth(text) + (text.length * charSpace)
|
|
241
431
|
*/
|
|
242
|
-
static measureWordWidth(
|
|
243
|
-
const
|
|
244
|
-
this.applyStyle(
|
|
245
|
-
const
|
|
246
|
-
return
|
|
432
|
+
static measureWordWidth(e, i, r) {
|
|
433
|
+
const h = e.getFont(), o = e.getFontSize();
|
|
434
|
+
this.applyStyle(e, r);
|
|
435
|
+
const l = e.getTextWidth(i), a = e.getCharSpace?.() ?? 0, s = l + i.length * a;
|
|
436
|
+
return e.setFont(h.fontName, h.fontStyle), e.setFontSize(o), s;
|
|
247
437
|
}
|
|
248
438
|
/**
|
|
249
439
|
* Extract style from element type string.
|
|
250
440
|
*/
|
|
251
|
-
static getStyleFromType(
|
|
252
|
-
switch (
|
|
441
|
+
static getStyleFromType(e, i) {
|
|
442
|
+
switch (e) {
|
|
253
443
|
case "strong":
|
|
254
|
-
return
|
|
444
|
+
return i === "italic" ? "bolditalic" : "bold";
|
|
255
445
|
case "em":
|
|
256
|
-
return
|
|
446
|
+
return i === "bold" ? "bolditalic" : "italic";
|
|
257
447
|
case "codespan":
|
|
258
448
|
return "codespan";
|
|
259
449
|
default:
|
|
260
|
-
return
|
|
450
|
+
return i || "normal";
|
|
261
451
|
}
|
|
262
452
|
}
|
|
263
453
|
/**
|
|
264
454
|
* Flatten ParsedElement tree into an array of StyledWordInfo.
|
|
265
455
|
* Handles nested inline elements.
|
|
266
456
|
*/
|
|
267
|
-
static flattenToWords(
|
|
268
|
-
const
|
|
269
|
-
for (const
|
|
270
|
-
const
|
|
271
|
-
if (
|
|
457
|
+
static flattenToWords(e, i, r = "normal", h = !1, o) {
|
|
458
|
+
const l = [];
|
|
459
|
+
for (const a of i) {
|
|
460
|
+
const s = this.getStyleFromType(a.type, r), g = a.type === "link" || h, c = a.href || o;
|
|
461
|
+
if (a.items && a.items.length > 0) {
|
|
272
462
|
const f = this.flattenToWords(
|
|
273
|
-
|
|
274
|
-
|
|
463
|
+
e,
|
|
464
|
+
a.items,
|
|
465
|
+
s,
|
|
466
|
+
g,
|
|
467
|
+
c
|
|
468
|
+
);
|
|
469
|
+
l.push(...f);
|
|
470
|
+
} else if (a.type === "image") {
|
|
471
|
+
const f = n.options.page.maxContentHeight - n.options.page.topmargin, d = n.options.page.maxContentWidth - n.options.page.indent * 0, p = n.options.page.unit || "mm", { finalWidth: m, finalHeight: x } = _(
|
|
472
|
+
e,
|
|
275
473
|
a,
|
|
276
|
-
|
|
474
|
+
d,
|
|
475
|
+
f,
|
|
277
476
|
p
|
|
278
477
|
);
|
|
279
|
-
|
|
478
|
+
l.push({
|
|
479
|
+
text: "",
|
|
480
|
+
width: m,
|
|
481
|
+
style: s,
|
|
482
|
+
isLink: g,
|
|
483
|
+
href: c,
|
|
484
|
+
linkColor: g ? n.options.link?.linkColor || [0, 0, 255] : void 0,
|
|
485
|
+
isImage: !0,
|
|
486
|
+
imageElement: a,
|
|
487
|
+
imageHeight: x
|
|
488
|
+
});
|
|
280
489
|
} else {
|
|
281
|
-
const f =
|
|
490
|
+
const f = a.content || a.text || "";
|
|
282
491
|
if (!f) continue;
|
|
283
|
-
if (
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
text:
|
|
492
|
+
if (s === "codespan") {
|
|
493
|
+
const p = f.trim();
|
|
494
|
+
p && l.push({
|
|
495
|
+
text: p,
|
|
287
496
|
width: this.measureWordWidth(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
497
|
+
e,
|
|
498
|
+
p,
|
|
499
|
+
s
|
|
291
500
|
),
|
|
292
|
-
style:
|
|
293
|
-
isLink:
|
|
294
|
-
href:
|
|
295
|
-
linkColor:
|
|
501
|
+
style: s,
|
|
502
|
+
isLink: g,
|
|
503
|
+
href: c,
|
|
504
|
+
linkColor: g ? n.options.link?.linkColor || [
|
|
296
505
|
0,
|
|
297
506
|
0,
|
|
298
507
|
255
|
|
@@ -300,93 +509,130 @@ class E {
|
|
|
300
509
|
});
|
|
301
510
|
continue;
|
|
302
511
|
}
|
|
303
|
-
const d = f.split(/\s+/).filter((
|
|
512
|
+
const d = f.split(/\s+/).filter((p) => p.length > 0);
|
|
304
513
|
if (d.length === 0)
|
|
305
514
|
continue;
|
|
306
|
-
for (let
|
|
307
|
-
const m = d[
|
|
308
|
-
|
|
515
|
+
for (let p = 0; p < d.length; p++) {
|
|
516
|
+
const m = d[p];
|
|
517
|
+
l.push({
|
|
309
518
|
text: m,
|
|
310
|
-
width: this.measureWordWidth(
|
|
311
|
-
style:
|
|
312
|
-
isLink:
|
|
313
|
-
href:
|
|
314
|
-
linkColor:
|
|
519
|
+
width: this.measureWordWidth(e, m, s),
|
|
520
|
+
style: s,
|
|
521
|
+
isLink: g,
|
|
522
|
+
href: c,
|
|
523
|
+
linkColor: g ? n.options.link?.linkColor || [0, 0, 255] : void 0
|
|
315
524
|
});
|
|
316
525
|
}
|
|
317
526
|
}
|
|
318
527
|
}
|
|
319
|
-
return
|
|
528
|
+
return l;
|
|
320
529
|
}
|
|
321
530
|
/**
|
|
322
531
|
* Break a flat list of words into lines that fit within maxWidth.
|
|
323
532
|
* Correctly tracks totalTextWidth (sum of word widths only) for justification.
|
|
324
533
|
*/
|
|
325
|
-
static breakIntoLines(
|
|
326
|
-
const
|
|
327
|
-
let
|
|
328
|
-
const
|
|
329
|
-
for (let
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
words:
|
|
333
|
-
totalTextWidth:
|
|
334
|
-
isLastLine: !1
|
|
335
|
-
|
|
534
|
+
static breakIntoLines(e, i, r) {
|
|
535
|
+
const h = [];
|
|
536
|
+
let o = [], l = 0, a = 0, s = C(e) * n.options.page.defaultLineHeightFactor;
|
|
537
|
+
const g = e.getTextWidth(" ");
|
|
538
|
+
for (let c = 0; c < i.length; c++) {
|
|
539
|
+
const f = i[c], d = o.length > 0 ? g + f.width : f.width, p = f.isImage && f.imageHeight ? f.imageHeight : C(e) * n.options.page.defaultLineHeightFactor;
|
|
540
|
+
a + d > r && o.length > 0 ? (h.push({
|
|
541
|
+
words: o,
|
|
542
|
+
totalTextWidth: l,
|
|
543
|
+
isLastLine: !1,
|
|
544
|
+
lineHeight: s
|
|
545
|
+
}), o = [f], l = f.width, a = f.width, s = p) : (o.push(f), l += f.width, a += d, s = Math.max(s, p));
|
|
336
546
|
}
|
|
337
|
-
return
|
|
338
|
-
words:
|
|
339
|
-
totalTextWidth:
|
|
340
|
-
isLastLine: !0
|
|
341
|
-
|
|
547
|
+
return o.length > 0 && h.push({
|
|
548
|
+
words: o,
|
|
549
|
+
totalTextWidth: l,
|
|
550
|
+
isLastLine: !0,
|
|
551
|
+
lineHeight: s
|
|
552
|
+
}), h;
|
|
342
553
|
}
|
|
343
554
|
/**
|
|
344
555
|
* Render a single word with its style applied.
|
|
345
556
|
*/
|
|
346
|
-
static renderWord(
|
|
347
|
-
const
|
|
348
|
-
if (this.applyStyle(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
557
|
+
static renderWord(e, i, r, h) {
|
|
558
|
+
const o = e.getFont(), l = e.getFontSize(), a = e.getTextColor();
|
|
559
|
+
if (this.applyStyle(e, i.style), i.isLink && i.linkColor && e.setTextColor(...i.linkColor), i.isImage && i.imageElement && i.imageElement.data)
|
|
560
|
+
try {
|
|
561
|
+
let s = "JPEG";
|
|
562
|
+
if (i.imageElement.data.startsWith("data:image/png"))
|
|
563
|
+
s = "PNG";
|
|
564
|
+
else if (i.imageElement.data.startsWith("data:image/webp"))
|
|
565
|
+
s = "WEBP";
|
|
566
|
+
else if (i.imageElement.data.startsWith("data:image/gif"))
|
|
567
|
+
s = "GIF";
|
|
568
|
+
else if (i.imageElement.src) {
|
|
569
|
+
const c = i.imageElement.src.split("?")[0].split("#")[0].split(".").pop()?.toUpperCase();
|
|
570
|
+
c && ["PNG", "JPEG", "JPG", "WEBP", "GIF"].includes(c) && (s = c === "JPG" ? "JPEG" : c);
|
|
571
|
+
}
|
|
572
|
+
if (i.width > 0 && (i.imageHeight || 0) > 0) {
|
|
573
|
+
const g = i.imageHeight || 0, c = h - g;
|
|
574
|
+
e.addImage(
|
|
575
|
+
i.imageElement.data,
|
|
576
|
+
s,
|
|
577
|
+
r,
|
|
578
|
+
c,
|
|
579
|
+
i.width,
|
|
580
|
+
g
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
} catch (s) {
|
|
584
|
+
console.warn("Failed to render inline image", s);
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
if (i.style === "codespan") {
|
|
588
|
+
const s = this.getCodespanOptions();
|
|
589
|
+
if (s.showBackground) {
|
|
590
|
+
const g = C(e), c = s.padding;
|
|
591
|
+
e.setFillColor(s.backgroundColor), e.rect(
|
|
592
|
+
r - c,
|
|
593
|
+
h - c,
|
|
594
|
+
i.width + c * 2,
|
|
595
|
+
g + c * 2,
|
|
596
|
+
"F"
|
|
597
|
+
), e.setFillColor("#000000");
|
|
598
|
+
}
|
|
359
599
|
}
|
|
600
|
+
e.text(i.text, r, h, { baseline: "top" });
|
|
360
601
|
}
|
|
361
|
-
if (
|
|
362
|
-
const
|
|
363
|
-
|
|
602
|
+
if (i.isLink && i.href) {
|
|
603
|
+
const s = i.isImage && i.imageHeight ? i.imageHeight : C(e);
|
|
604
|
+
e.link(r, h, i.width, s, { url: i.href });
|
|
364
605
|
}
|
|
365
|
-
|
|
606
|
+
e.setFont(o.fontName, o.fontStyle), e.setFontSize(l), e.setTextColor(a);
|
|
366
607
|
}
|
|
367
608
|
/**
|
|
368
609
|
* Render a single line with specified alignment.
|
|
369
610
|
*/
|
|
370
|
-
static renderAlignedLine(
|
|
371
|
-
const { words:
|
|
372
|
-
if (
|
|
373
|
-
const
|
|
374
|
-
let f =
|
|
375
|
-
const
|
|
376
|
-
switch (
|
|
611
|
+
static renderAlignedLine(e, i, r, h, o, l = "left") {
|
|
612
|
+
const { words: a, totalTextWidth: s, isLastLine: g } = i;
|
|
613
|
+
if (a.length === 0) return;
|
|
614
|
+
const c = e.getTextWidth(" ");
|
|
615
|
+
let f = r, d = c;
|
|
616
|
+
const p = s + (a.length - 1) * c;
|
|
617
|
+
switch (l) {
|
|
377
618
|
case "right":
|
|
378
|
-
f =
|
|
619
|
+
f = r + o - p;
|
|
379
620
|
break;
|
|
380
621
|
case "center":
|
|
381
|
-
f =
|
|
622
|
+
f = r + (o - p) / 2;
|
|
382
623
|
break;
|
|
383
624
|
case "justify":
|
|
384
|
-
!
|
|
625
|
+
!g && a.length > 1 && (d = (o - s) / (a.length - 1));
|
|
385
626
|
break;
|
|
386
627
|
}
|
|
387
628
|
let m = f;
|
|
388
|
-
|
|
389
|
-
|
|
629
|
+
const x = C(e) * n.options.page.defaultLineHeightFactor;
|
|
630
|
+
for (let F = 0; F < a.length; F++) {
|
|
631
|
+
const b = a[F];
|
|
632
|
+
let H = h;
|
|
633
|
+
const w = b.isImage && b.imageHeight ? b.imageHeight : x;
|
|
634
|
+
w < i.lineHeight && (H = h + (i.lineHeight - w)), this.renderWord(e, b, m, H), m += b.width, F < a.length - 1 && (m += d);
|
|
635
|
+
}
|
|
390
636
|
}
|
|
391
637
|
/**
|
|
392
638
|
* Main entry point: Render a paragraph with mixed inline elements.
|
|
@@ -399,34 +645,34 @@ class E {
|
|
|
399
645
|
* @param maxWidth Maximum width for text wrapping
|
|
400
646
|
* @param alignment Optional alignment override (defaults to RenderStore option)
|
|
401
647
|
*/
|
|
402
|
-
static renderStyledParagraph(
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
const
|
|
406
|
-
let
|
|
407
|
-
for (const
|
|
408
|
-
|
|
409
|
-
|
|
648
|
+
static renderStyledParagraph(e, i, r, h, o, l) {
|
|
649
|
+
const a = l ?? n.options.content?.textAlignment ?? "left", s = this.flattenToWords(e, i);
|
|
650
|
+
if (s.length === 0) return;
|
|
651
|
+
const g = this.breakIntoLines(e, s, o);
|
|
652
|
+
let c = h;
|
|
653
|
+
for (const d of g)
|
|
654
|
+
c + d.lineHeight > n.options.page.maxContentHeight && (Y(e), c = n.Y), this.renderAlignedLine(
|
|
655
|
+
e,
|
|
656
|
+
d,
|
|
657
|
+
r,
|
|
658
|
+
c,
|
|
410
659
|
o,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (d) {
|
|
418
|
-
const o = d.totalTextWidth + (d.words.length - 1) * n.getTextWidth(" ");
|
|
419
|
-
e.updateX(g + o, "set");
|
|
660
|
+
a
|
|
661
|
+
), n.recordContentY(c + d.lineHeight), c += d.lineHeight, n.updateY(d.lineHeight, "add");
|
|
662
|
+
const f = g[g.length - 1];
|
|
663
|
+
if (f) {
|
|
664
|
+
const d = f.totalTextWidth + (f.words.length - 1) * e.getTextWidth(" ");
|
|
665
|
+
n.updateX(r + d, "set");
|
|
420
666
|
}
|
|
421
667
|
}
|
|
422
668
|
/**
|
|
423
669
|
* @deprecated Use renderStyledParagraph instead
|
|
424
670
|
*/
|
|
425
|
-
static renderJustifiedParagraph(
|
|
426
|
-
this.renderStyledParagraph(
|
|
671
|
+
static renderJustifiedParagraph(e, i, r, h, o) {
|
|
672
|
+
this.renderStyledParagraph(e, i, r, h, o);
|
|
427
673
|
}
|
|
428
674
|
}
|
|
429
|
-
class
|
|
675
|
+
class T {
|
|
430
676
|
/**
|
|
431
677
|
* Renders text with automatic line wrapping and page breaking.
|
|
432
678
|
* @param doc jsPDF instance
|
|
@@ -436,228 +682,236 @@ class X {
|
|
|
436
682
|
* @param maxWidth Max width for text wrapping
|
|
437
683
|
* @param justify Whether to justify the text
|
|
438
684
|
*/
|
|
439
|
-
static renderText(
|
|
440
|
-
const
|
|
441
|
-
let
|
|
442
|
-
for (let f = 0; f <
|
|
443
|
-
const d =
|
|
444
|
-
|
|
445
|
-
maxWidth:
|
|
685
|
+
static renderText(e, i, r = n.X, h = n.Y, o, l = !1) {
|
|
686
|
+
const a = e.splitTextToSize(i, o), s = C(e), g = s * n.options.page.defaultLineHeightFactor;
|
|
687
|
+
let c = h;
|
|
688
|
+
for (let f = 0; f < a.length; f++) {
|
|
689
|
+
const d = a[f];
|
|
690
|
+
c + g > n.options.page.maxContentHeight && (Y(e), c = n.Y), l ? f === a.length - 1 ? e.text(d, r, c, { baseline: "top" }) : e.text(d, r, c, {
|
|
691
|
+
maxWidth: o,
|
|
446
692
|
align: "justify",
|
|
447
693
|
baseline: "top"
|
|
448
|
-
}) :
|
|
694
|
+
}) : e.text(d, r, c, { baseline: "top" }), n.recordContentY(c + s), c += g, n.updateY(g, "add");
|
|
449
695
|
}
|
|
450
|
-
return
|
|
696
|
+
return c;
|
|
451
697
|
}
|
|
452
698
|
}
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
const
|
|
456
|
-
if (
|
|
457
|
-
if (
|
|
458
|
-
(
|
|
459
|
-
|
|
460
|
-
|
|
699
|
+
const nt = (t, e, i, r) => {
|
|
700
|
+
n.activateInlineLock(), t.setFontSize(n.options.page.defaultFontSize);
|
|
701
|
+
const h = n.options.page.maxContentWidth - i;
|
|
702
|
+
if (e?.items && e?.items.length > 0) {
|
|
703
|
+
if (e.items.length === 1 && e.items[0].type === "image") {
|
|
704
|
+
r(e.items[0], i, !1), n.updateX(n.options.page.xpading), n.deactivateInlineLock();
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const o = [
|
|
708
|
+
"strong",
|
|
709
|
+
"em",
|
|
710
|
+
"text",
|
|
711
|
+
"codespan",
|
|
712
|
+
"link",
|
|
713
|
+
"image"
|
|
714
|
+
];
|
|
715
|
+
if (e.items.some(
|
|
716
|
+
(a) => !o.includes(a.type)
|
|
461
717
|
)) {
|
|
462
|
-
const
|
|
463
|
-
|
|
718
|
+
const a = [], s = () => {
|
|
719
|
+
a.length > 0 && (A.renderStyledParagraph(
|
|
464
720
|
t,
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
),
|
|
721
|
+
a,
|
|
722
|
+
n.X + i,
|
|
723
|
+
n.Y,
|
|
724
|
+
h
|
|
725
|
+
), a.length = 0);
|
|
470
726
|
};
|
|
471
|
-
for (const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
) ? r.push(a) : (i(), g(a, s, !1));
|
|
475
|
-
i();
|
|
727
|
+
for (const g of e.items)
|
|
728
|
+
o.includes(g.type) ? a.push(g) : (s(), r(g, i, !1));
|
|
729
|
+
s();
|
|
476
730
|
} else
|
|
477
|
-
|
|
731
|
+
A.renderStyledParagraph(
|
|
478
732
|
t,
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
733
|
+
e.items,
|
|
734
|
+
n.X + i,
|
|
735
|
+
n.Y,
|
|
736
|
+
h
|
|
483
737
|
);
|
|
484
|
-
else {
|
|
485
|
-
const
|
|
486
|
-
|
|
738
|
+
} else {
|
|
739
|
+
const o = e.content ?? "", l = n.options.content?.textAlignment ?? "left";
|
|
740
|
+
o.trim() && T.renderText(
|
|
487
741
|
t,
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
742
|
+
o,
|
|
743
|
+
n.X + i,
|
|
744
|
+
n.Y,
|
|
745
|
+
h,
|
|
746
|
+
l === "justify"
|
|
493
747
|
);
|
|
494
748
|
}
|
|
495
|
-
|
|
496
|
-
},
|
|
497
|
-
t.setFontSize(
|
|
498
|
-
for (const [
|
|
499
|
-
const
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
749
|
+
n.updateX(n.options.page.xpading), n.deactivateInlineLock();
|
|
750
|
+
}, it = (t, e, i, r) => {
|
|
751
|
+
t.setFontSize(n.options.page.defaultFontSize);
|
|
752
|
+
for (const [h, o] of e?.items?.entries() ?? []) {
|
|
753
|
+
const l = e.ordered ? (e.start ?? 0) + h : e.start;
|
|
754
|
+
r(
|
|
755
|
+
o,
|
|
756
|
+
i + 1,
|
|
503
757
|
!0,
|
|
504
|
-
|
|
505
|
-
|
|
758
|
+
l,
|
|
759
|
+
e.ordered
|
|
506
760
|
);
|
|
507
761
|
}
|
|
508
|
-
},
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
const
|
|
513
|
-
if (
|
|
514
|
-
const
|
|
515
|
-
|
|
762
|
+
}, st = (t, e, i, r, h, o) => {
|
|
763
|
+
n.Y + C(t) >= n.options.page.maxContentHeight && Y(t);
|
|
764
|
+
const l = n.options, a = i * l.page.indent, s = o ? `${h}. ` : "• ", g = l.page.xpading;
|
|
765
|
+
n.updateX(g, "set"), t.setFont(l.font.regular.name, l.font.regular.style), t.text(s, g + a, n.Y, { baseline: "top" });
|
|
766
|
+
const c = t.getTextWidth(s), f = g + a + c, d = l.page.maxContentWidth - a - c;
|
|
767
|
+
if (e.items && e.items.length > 0) {
|
|
768
|
+
const p = [], m = () => {
|
|
769
|
+
p.length > 0 && (A.renderStyledParagraph(
|
|
516
770
|
t,
|
|
517
|
-
|
|
771
|
+
p,
|
|
518
772
|
f,
|
|
519
|
-
|
|
773
|
+
n.Y,
|
|
520
774
|
d
|
|
521
|
-
),
|
|
775
|
+
), p.length = 0, n.updateX(g, "set"));
|
|
522
776
|
};
|
|
523
|
-
for (const x of
|
|
524
|
-
x.type === u.List ? (m(),
|
|
777
|
+
for (const x of e.items)
|
|
778
|
+
x.type === u.List ? (m(), r(
|
|
525
779
|
x,
|
|
526
|
-
|
|
780
|
+
i,
|
|
527
781
|
!0,
|
|
528
|
-
|
|
782
|
+
h,
|
|
529
783
|
x.ordered ?? !1
|
|
530
|
-
)) : x.type === u.ListItem ? (m(),
|
|
784
|
+
)) : x.type === u.ListItem ? (m(), r(
|
|
531
785
|
x,
|
|
532
|
-
|
|
786
|
+
i,
|
|
533
787
|
!0,
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
)) :
|
|
788
|
+
h,
|
|
789
|
+
o
|
|
790
|
+
)) : p.push(x);
|
|
537
791
|
m();
|
|
538
|
-
} else if (
|
|
539
|
-
const
|
|
540
|
-
|
|
792
|
+
} else if (e.content) {
|
|
793
|
+
const p = l.content?.textAlignment ?? "left";
|
|
794
|
+
T.renderText(
|
|
541
795
|
t,
|
|
542
|
-
|
|
796
|
+
e.content,
|
|
543
797
|
f,
|
|
544
|
-
|
|
798
|
+
n.Y,
|
|
545
799
|
d,
|
|
546
|
-
|
|
800
|
+
p === "justify"
|
|
547
801
|
);
|
|
548
802
|
}
|
|
549
|
-
},
|
|
550
|
-
if (
|
|
551
|
-
for (const
|
|
552
|
-
|
|
553
|
-
a,
|
|
803
|
+
}, at = (t, e, i, r, h, o, l, a = !0) => {
|
|
804
|
+
if (e?.items && e?.items.length > 0)
|
|
805
|
+
for (const s of e?.items ?? [])
|
|
806
|
+
h(
|
|
554
807
|
s,
|
|
555
|
-
|
|
556
|
-
l,
|
|
808
|
+
i,
|
|
557
809
|
r,
|
|
558
|
-
|
|
810
|
+
o,
|
|
811
|
+
l,
|
|
812
|
+
a
|
|
559
813
|
);
|
|
560
814
|
else {
|
|
561
|
-
const
|
|
562
|
-
if (!f && !
|
|
563
|
-
if (!f.trim() && !
|
|
564
|
-
const
|
|
565
|
-
if (
|
|
566
|
-
const m =
|
|
567
|
-
|
|
815
|
+
const s = n.options, g = i * s.page.indent, c = r ? l ? `${o}. ` : "• " : "", f = e.content || "", d = s.page.xpading;
|
|
816
|
+
if (!f && !c) return;
|
|
817
|
+
if (!f.trim() && !c) {
|
|
818
|
+
const p = (f.match(/\n/g) || []).length;
|
|
819
|
+
if (p > 1) {
|
|
820
|
+
const m = p - 1, x = t.getTextDimensions("A").h * s.page.defaultLineHeightFactor, F = m * x;
|
|
821
|
+
n.Y + F > s.page.maxContentHeight ? Y(t) : (n.updateY(F, "add"), n.recordContentY(n.Y));
|
|
568
822
|
}
|
|
569
823
|
return;
|
|
570
824
|
}
|
|
571
|
-
if (
|
|
572
|
-
const
|
|
573
|
-
t.setFont(
|
|
825
|
+
if (n.updateX(d, "set"), r && c) {
|
|
826
|
+
const p = t.getTextWidth(c), m = s.page.maxContentWidth - g - p;
|
|
827
|
+
t.setFont(s.font.regular.name, s.font.regular.style), t.text(c, d + g, n.Y, {
|
|
574
828
|
baseline: "top"
|
|
575
|
-
}),
|
|
829
|
+
}), T.renderText(
|
|
576
830
|
t,
|
|
577
831
|
f,
|
|
578
|
-
d +
|
|
579
|
-
|
|
832
|
+
d + g + p,
|
|
833
|
+
n.Y,
|
|
580
834
|
m,
|
|
581
|
-
|
|
835
|
+
a
|
|
582
836
|
);
|
|
583
837
|
} else {
|
|
584
|
-
const
|
|
585
|
-
|
|
838
|
+
const p = s.page.maxContentWidth - g;
|
|
839
|
+
T.renderText(
|
|
586
840
|
t,
|
|
587
841
|
f,
|
|
588
|
-
d +
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
842
|
+
d + g,
|
|
843
|
+
n.Y,
|
|
844
|
+
p,
|
|
845
|
+
a
|
|
592
846
|
);
|
|
593
847
|
}
|
|
594
|
-
|
|
848
|
+
n.updateX(d, "set");
|
|
595
849
|
}
|
|
596
|
-
},
|
|
597
|
-
const
|
|
850
|
+
}, ot = (t) => {
|
|
851
|
+
const e = t.internal.pageSize.getWidth();
|
|
598
852
|
t.setLineDashPattern([1, 1], 0), t.setLineWidth(0.1), t.line(
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
), t.setLineWidth(0.1), t.setLineDashPattern([], 0),
|
|
604
|
-
},
|
|
605
|
-
const
|
|
853
|
+
n.options.page.xpading,
|
|
854
|
+
n.Y,
|
|
855
|
+
e - n.options.page.xpading,
|
|
856
|
+
n.Y
|
|
857
|
+
), t.setLineWidth(0.1), t.setLineDashPattern([], 0), n.updateY(C(t), "add");
|
|
858
|
+
}, rt = (t, e, i, r) => {
|
|
859
|
+
const h = t.getFont(), o = t.getFontSize();
|
|
606
860
|
t.setFont("courier", "normal");
|
|
607
|
-
const
|
|
608
|
-
t.setFontSize(
|
|
609
|
-
const
|
|
861
|
+
const l = n.options.page.defaultFontSize * 0.9;
|
|
862
|
+
t.setFontSize(l);
|
|
863
|
+
const a = i * n.options.page.indent, s = n.options.page.maxContentWidth - a - 8, g = t.getLineHeightFactor(), c = l / t.internal.scaleFactor * g, d = (e.code ?? "").replace(/[\r\n\s]+$/, "");
|
|
610
864
|
if (!d) {
|
|
611
|
-
t.setFont(
|
|
865
|
+
t.setFont(h.fontName, h.fontStyle), t.setFontSize(o);
|
|
612
866
|
return;
|
|
613
867
|
}
|
|
614
|
-
const
|
|
615
|
-
for (;
|
|
616
|
-
|
|
617
|
-
if (
|
|
618
|
-
t.setFont(
|
|
868
|
+
const p = t.splitTextToSize(d, s);
|
|
869
|
+
for (; p.length > 0 && p[p.length - 1].trim() === ""; )
|
|
870
|
+
p.pop();
|
|
871
|
+
if (p.length === 0) {
|
|
872
|
+
t.setFont(h.fontName, h.fontStyle), t.setFontSize(o);
|
|
619
873
|
return;
|
|
620
874
|
}
|
|
621
|
-
const m = 4, x = "#EEEEEE",
|
|
622
|
-
let
|
|
623
|
-
for (;
|
|
624
|
-
const
|
|
625
|
-
let
|
|
626
|
-
if (
|
|
627
|
-
|
|
875
|
+
const m = 4, x = "#EEEEEE", F = "#DDDDDD";
|
|
876
|
+
let b = 0;
|
|
877
|
+
for (; b < p.length; ) {
|
|
878
|
+
const H = n.options.page.maxContentHeight - n.Y, w = p.length - b, L = H - m * 2;
|
|
879
|
+
let S = Math.floor(L / c);
|
|
880
|
+
if (S <= 0) {
|
|
881
|
+
Y(t);
|
|
628
882
|
continue;
|
|
629
883
|
}
|
|
630
|
-
|
|
631
|
-
const
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
),
|
|
635
|
-
if (
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
884
|
+
S > w && (S = w);
|
|
885
|
+
const J = p.slice(
|
|
886
|
+
b,
|
|
887
|
+
b + S
|
|
888
|
+
), E = b === 0, X = b + S >= p.length, B = S * c;
|
|
889
|
+
if (E && n.updateY(m, "add"), t.setFillColor(x), t.setDrawColor(F), t.roundedRect(
|
|
890
|
+
n.X,
|
|
891
|
+
n.Y - m,
|
|
892
|
+
n.options.page.maxContentWidth,
|
|
893
|
+
B + (E ? m : 0) + (X ? m : 0),
|
|
640
894
|
2,
|
|
641
895
|
2,
|
|
642
896
|
"FD"
|
|
643
|
-
),
|
|
644
|
-
const
|
|
897
|
+
), E && e.lang) {
|
|
898
|
+
const P = t.getFontSize();
|
|
645
899
|
t.setFontSize(10), t.setTextColor("#666666"), t.text(
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
900
|
+
e.lang,
|
|
901
|
+
n.X + n.options.page.maxContentWidth - t.getTextWidth(e.lang) - 4,
|
|
902
|
+
n.Y,
|
|
649
903
|
{ baseline: "top" }
|
|
650
|
-
), t.setFontSize(
|
|
904
|
+
), t.setFontSize(P), t.setTextColor("#000000");
|
|
651
905
|
}
|
|
652
|
-
let
|
|
653
|
-
for (const
|
|
654
|
-
t.text(
|
|
655
|
-
|
|
906
|
+
let N = n.Y;
|
|
907
|
+
for (const P of J)
|
|
908
|
+
t.text(P, n.X + 4, N, { baseline: "top" }), N += c;
|
|
909
|
+
n.updateY(B, "add"), n.recordContentY(n.Y + (X ? m : 0)), X && n.updateY(m, "add"), b += S, b < p.length && Y(t);
|
|
656
910
|
}
|
|
657
|
-
t.setFont(
|
|
658
|
-
},
|
|
659
|
-
const
|
|
660
|
-
switch (
|
|
911
|
+
t.setFont(h.fontName, h.fontStyle), t.setFontSize(o);
|
|
912
|
+
}, lt = (t, e, i) => {
|
|
913
|
+
const r = t.getFont().fontName, h = t.getFont().fontStyle, o = t.getFontSize(), l = (s) => {
|
|
914
|
+
switch (s) {
|
|
661
915
|
case "normal":
|
|
662
916
|
return 0;
|
|
663
917
|
case "bold":
|
|
@@ -671,52 +925,52 @@ const _ = (t, n, s, g) => {
|
|
|
671
925
|
default:
|
|
672
926
|
return 0;
|
|
673
927
|
}
|
|
674
|
-
},
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
) :
|
|
679
|
-
|
|
928
|
+
}, a = (s, g) => {
|
|
929
|
+
g === "bold" ? t.setFont(
|
|
930
|
+
n.options.font.bold.name && n.options.font.bold.name !== "" ? n.options.font.bold.name : r,
|
|
931
|
+
n.options.font.bold.style || "bold"
|
|
932
|
+
) : g === "italic" ? t.setFont(n.options.font.regular.name, "italic") : g === "bolditalic" ? t.setFont(
|
|
933
|
+
n.options.font.bold.name && n.options.font.bold.name !== "" ? n.options.font.bold.name : r,
|
|
680
934
|
"bolditalic"
|
|
681
|
-
) :
|
|
682
|
-
|
|
683
|
-
|
|
935
|
+
) : g === "codespan" ? (t.setFont("courier", "normal"), t.setFontSize(o * 0.9)) : t.setFont(
|
|
936
|
+
n.options.font.regular.name,
|
|
937
|
+
h
|
|
684
938
|
);
|
|
685
|
-
const
|
|
686
|
-
if (
|
|
939
|
+
const c = n.options.page.maxContentWidth - i - n.X, f = t.splitTextToSize(s, c), d = g === "codespan", p = 1, m = "#EEEEEE";
|
|
940
|
+
if (n.isInlineLockActive)
|
|
687
941
|
for (let x = 0; x < f.length; x++) {
|
|
688
942
|
if (d) {
|
|
689
|
-
const
|
|
943
|
+
const F = t.getTextWidth(f[x]) + y(t), b = C(t);
|
|
690
944
|
t.setFillColor(m), t.roundedRect(
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
945
|
+
n.X + i - p,
|
|
946
|
+
n.Y - p,
|
|
947
|
+
F + p * 2,
|
|
948
|
+
b + p * 2,
|
|
695
949
|
2,
|
|
696
950
|
2,
|
|
697
951
|
"F"
|
|
698
952
|
), t.setFillColor("#000000");
|
|
699
953
|
}
|
|
700
|
-
t.text(f[x],
|
|
954
|
+
t.text(f[x], n.X + i, n.Y, {
|
|
701
955
|
baseline: "top",
|
|
702
|
-
maxWidth:
|
|
703
|
-
}),
|
|
704
|
-
t.getTextDimensions(f[x]).w + (d ?
|
|
956
|
+
maxWidth: c
|
|
957
|
+
}), n.updateX(
|
|
958
|
+
t.getTextDimensions(f[x]).w + (d ? p * 2 : 1),
|
|
705
959
|
"add"
|
|
706
|
-
), x < f.length - 1 && (
|
|
707
|
-
|
|
960
|
+
), x < f.length - 1 && (n.updateY(C(t), "add"), n.updateX(
|
|
961
|
+
n.options.page.xpading,
|
|
708
962
|
"set"
|
|
709
963
|
));
|
|
710
964
|
}
|
|
711
965
|
else if (f.length > 1) {
|
|
712
|
-
const x = f[0],
|
|
966
|
+
const x = f[0], F = f?.slice(1)?.join(" ");
|
|
713
967
|
if (d) {
|
|
714
|
-
const
|
|
968
|
+
const w = t.getTextWidth(x) + y(t), L = C(t);
|
|
715
969
|
t.setFillColor(m), t.roundedRect(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
L +
|
|
970
|
+
n.X + (i >= 2 ? i + 2 : 0) - p,
|
|
971
|
+
n.Y - p,
|
|
972
|
+
w + p * 2,
|
|
973
|
+
L + p * 2,
|
|
720
974
|
2,
|
|
721
975
|
2,
|
|
722
976
|
"F"
|
|
@@ -724,244 +978,240 @@ const _ = (t, n, s, g) => {
|
|
|
724
978
|
}
|
|
725
979
|
t.text(
|
|
726
980
|
x,
|
|
727
|
-
|
|
728
|
-
|
|
981
|
+
n.X + (i >= 2 ? i + 2 * l(g) : 0),
|
|
982
|
+
n.Y,
|
|
729
983
|
{
|
|
730
984
|
baseline: "top",
|
|
731
|
-
maxWidth:
|
|
985
|
+
maxWidth: c
|
|
732
986
|
}
|
|
733
|
-
),
|
|
734
|
-
const
|
|
987
|
+
), n.updateX(n.options.page.xpading + i), n.updateY(C(t), "add");
|
|
988
|
+
const b = n.options.page.maxContentWidth - i - n.options.page.xpading;
|
|
735
989
|
t.splitTextToSize(
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
).forEach((
|
|
990
|
+
F,
|
|
991
|
+
b
|
|
992
|
+
).forEach((w) => {
|
|
739
993
|
if (d) {
|
|
740
|
-
const L = t.getTextWidth(
|
|
994
|
+
const L = t.getTextWidth(w) + y(t), S = C(t);
|
|
741
995
|
t.setFillColor(m), t.roundedRect(
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
L +
|
|
745
|
-
|
|
996
|
+
n.X + y(t) - p,
|
|
997
|
+
n.Y - p,
|
|
998
|
+
L + p * 2,
|
|
999
|
+
S + p * 2,
|
|
746
1000
|
2,
|
|
747
1001
|
2,
|
|
748
1002
|
"F"
|
|
749
1003
|
), t.setFillColor("#000000");
|
|
750
1004
|
}
|
|
751
1005
|
t.text(
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
1006
|
+
w,
|
|
1007
|
+
n.X + y(t),
|
|
1008
|
+
n.Y,
|
|
755
1009
|
{
|
|
756
1010
|
baseline: "top",
|
|
757
|
-
maxWidth:
|
|
1011
|
+
maxWidth: b
|
|
758
1012
|
}
|
|
759
1013
|
);
|
|
760
1014
|
});
|
|
761
1015
|
} else {
|
|
762
1016
|
if (d) {
|
|
763
|
-
const x = t.getTextWidth(
|
|
1017
|
+
const x = t.getTextWidth(s) + y(t), F = C(t);
|
|
764
1018
|
t.setFillColor(m), t.roundedRect(
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
x +
|
|
768
|
-
|
|
1019
|
+
n.X + i - p,
|
|
1020
|
+
n.Y - p,
|
|
1021
|
+
x + p * 2,
|
|
1022
|
+
F + p * 2,
|
|
769
1023
|
2,
|
|
770
1024
|
2,
|
|
771
1025
|
"F"
|
|
772
1026
|
), t.setFillColor("#000000");
|
|
773
1027
|
}
|
|
774
|
-
t.text(
|
|
1028
|
+
t.text(s, n.X + i, n.Y, {
|
|
775
1029
|
baseline: "top",
|
|
776
|
-
maxWidth:
|
|
777
|
-
}),
|
|
778
|
-
t.getTextDimensions(
|
|
1030
|
+
maxWidth: c
|
|
1031
|
+
}), n.updateX(
|
|
1032
|
+
t.getTextDimensions(s).w + (i >= 2 ? s.split(" ").length + 2 : 2) * l(g) * 0.5 + (d ? p * 2 : 0),
|
|
779
1033
|
"add"
|
|
780
1034
|
);
|
|
781
1035
|
}
|
|
782
1036
|
};
|
|
783
|
-
if (
|
|
784
|
-
for (const
|
|
785
|
-
if (
|
|
786
|
-
|
|
787
|
-
else if (
|
|
788
|
-
const
|
|
789
|
-
if (
|
|
790
|
-
for (const
|
|
791
|
-
|
|
792
|
-
|
|
1037
|
+
if (e.type === "text" && e.items && e.items.length > 0)
|
|
1038
|
+
for (const s of e.items)
|
|
1039
|
+
if (s.type === "codespan")
|
|
1040
|
+
a(s.content || "", "codespan");
|
|
1041
|
+
else if (s.type === "em" || s.type === "strong") {
|
|
1042
|
+
const g = s.type === "em" ? "italic" : "bold";
|
|
1043
|
+
if (s.items && s.items.length > 0)
|
|
1044
|
+
for (const c of s.items)
|
|
1045
|
+
c.type === "strong" && g === "italic" || c.type === "em" && g === "bold" ? a(
|
|
1046
|
+
c.content || "",
|
|
793
1047
|
"bolditalic"
|
|
794
|
-
) :
|
|
795
|
-
|
|
796
|
-
|
|
1048
|
+
) : a(
|
|
1049
|
+
c.content || "",
|
|
1050
|
+
g
|
|
797
1051
|
);
|
|
798
1052
|
else
|
|
799
|
-
|
|
1053
|
+
a(s.content || "", g);
|
|
800
1054
|
} else
|
|
801
|
-
|
|
802
|
-
else
|
|
803
|
-
t.setFont(
|
|
804
|
-
},
|
|
805
|
-
const
|
|
806
|
-
t.setTextColor(...
|
|
807
|
-
const
|
|
808
|
-
if (
|
|
1055
|
+
a(s.content || "", "normal");
|
|
1056
|
+
else e.type === "em" ? a(e.content || "", "italic") : e.type === "strong" ? a(e.content || "", "bold") : e.type === "codespan" ? a(e.content || "", "codespan") : a(e.content || "", "normal");
|
|
1057
|
+
t.setFont(r, h), t.setFontSize(o);
|
|
1058
|
+
}, gt = (t, e, i) => {
|
|
1059
|
+
const r = t.getFont().fontName, h = t.getFont().fontStyle, o = t.getFontSize(), l = t.getTextColor(), a = n.options.link?.linkColor || [0, 0, 255];
|
|
1060
|
+
t.setTextColor(...a);
|
|
1061
|
+
const s = n.options.page.maxContentWidth - i - n.X, g = e.text || e.content || "", c = e.href || "", f = t.splitTextToSize(g, s);
|
|
1062
|
+
if (n.isInlineLockActive)
|
|
809
1063
|
for (let d = 0; d < f.length; d++) {
|
|
810
|
-
const
|
|
1064
|
+
const p = t.getTextDimensions(f[d]).w, m = C(t) / 2;
|
|
811
1065
|
t.link(
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1066
|
+
n.X + i,
|
|
1067
|
+
n.Y,
|
|
1068
|
+
p,
|
|
815
1069
|
m,
|
|
816
|
-
{ url:
|
|
817
|
-
), t.text(f[d],
|
|
1070
|
+
{ url: c }
|
|
1071
|
+
), t.text(f[d], n.X + i, n.Y, {
|
|
818
1072
|
baseline: "top",
|
|
819
|
-
maxWidth:
|
|
820
|
-
}),
|
|
821
|
-
|
|
1073
|
+
maxWidth: s
|
|
1074
|
+
}), n.updateX(p + 1, "add"), n.X + p > n.options.page.maxContentWidth - i && (n.updateY(m, "add"), n.updateX(
|
|
1075
|
+
n.options.page.xpading + i,
|
|
822
1076
|
"set"
|
|
823
|
-
)), d < f.length - 1 && (
|
|
824
|
-
|
|
1077
|
+
)), d < f.length - 1 && (n.updateY(m, "add"), n.updateX(
|
|
1078
|
+
n.options.page.xpading + i,
|
|
825
1079
|
"set"
|
|
826
1080
|
));
|
|
827
1081
|
}
|
|
828
1082
|
else if (f.length > 1) {
|
|
829
|
-
const d = f[0],
|
|
1083
|
+
const d = f[0], p = f?.slice(1)?.join(" "), m = t.getTextDimensions(d).w, x = C(t) / 2;
|
|
830
1084
|
t.link(
|
|
831
|
-
|
|
832
|
-
|
|
1085
|
+
n.X + i,
|
|
1086
|
+
n.Y,
|
|
833
1087
|
m,
|
|
834
1088
|
x,
|
|
835
|
-
{ url:
|
|
836
|
-
), t.text(d,
|
|
1089
|
+
{ url: c }
|
|
1090
|
+
), t.text(d, n.X + i, n.Y, {
|
|
837
1091
|
baseline: "top",
|
|
838
|
-
maxWidth:
|
|
839
|
-
}),
|
|
840
|
-
const
|
|
841
|
-
t.splitTextToSize(
|
|
842
|
-
const
|
|
1092
|
+
maxWidth: s
|
|
1093
|
+
}), n.updateX(n.options.page.xpading + i), n.updateY(x, "add");
|
|
1094
|
+
const F = n.options.page.maxContentWidth - i - n.options.page.xpading;
|
|
1095
|
+
t.splitTextToSize(p, F).forEach((H) => {
|
|
1096
|
+
const w = t.getTextDimensions(H).w;
|
|
843
1097
|
t.link(
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
1098
|
+
n.X + y(t),
|
|
1099
|
+
n.Y,
|
|
1100
|
+
w,
|
|
847
1101
|
x,
|
|
848
|
-
{ url:
|
|
1102
|
+
{ url: c }
|
|
849
1103
|
), t.text(
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1104
|
+
H,
|
|
1105
|
+
n.X + y(t),
|
|
1106
|
+
n.Y,
|
|
853
1107
|
{
|
|
854
1108
|
baseline: "top",
|
|
855
|
-
maxWidth:
|
|
1109
|
+
maxWidth: F
|
|
856
1110
|
}
|
|
857
1111
|
);
|
|
858
1112
|
});
|
|
859
1113
|
} else {
|
|
860
|
-
const d = t.getTextDimensions(
|
|
1114
|
+
const d = t.getTextDimensions(g).w, p = C(t) / 2;
|
|
861
1115
|
t.link(
|
|
862
|
-
|
|
863
|
-
|
|
1116
|
+
n.X + i,
|
|
1117
|
+
n.Y,
|
|
864
1118
|
d,
|
|
865
|
-
|
|
866
|
-
{ url:
|
|
867
|
-
), t.text(
|
|
1119
|
+
p,
|
|
1120
|
+
{ url: c }
|
|
1121
|
+
), t.text(g, n.X + i, n.Y, {
|
|
868
1122
|
baseline: "top",
|
|
869
|
-
maxWidth:
|
|
870
|
-
}),
|
|
1123
|
+
maxWidth: s
|
|
1124
|
+
}), n.updateX(d + 2, "add");
|
|
871
1125
|
}
|
|
872
|
-
t.setFont(
|
|
873
|
-
},
|
|
874
|
-
const
|
|
875
|
-
|
|
876
|
-
|
|
1126
|
+
t.setFont(r, h), t.setFontSize(o), t.setTextColor(l);
|
|
1127
|
+
}, ct = (t, e, i, r) => {
|
|
1128
|
+
const h = n.options, o = i + 1, l = n.X + i * h.page.indent, a = n.Y, s = l + h.page.indent / 2, g = a, c = t.internal.getCurrentPageInfo().pageNumber;
|
|
1129
|
+
e.items && e.items.length > 0 && e.items.forEach((p) => {
|
|
1130
|
+
r(p, o);
|
|
877
1131
|
});
|
|
878
|
-
const f =
|
|
1132
|
+
const f = n.Y, d = t.internal.getCurrentPageInfo().pageNumber;
|
|
879
1133
|
t.setDrawColor(100), t.setLineWidth(1);
|
|
880
|
-
for (let
|
|
881
|
-
t.setPage(
|
|
882
|
-
const m =
|
|
883
|
-
t.line(
|
|
1134
|
+
for (let p = c; p <= d; p++) {
|
|
1135
|
+
t.setPage(p);
|
|
1136
|
+
const m = p === c, x = p === d, F = m ? g : h.page.topmargin, b = x ? f : h.page.maxContentHeight;
|
|
1137
|
+
t.line(s, F, s, b);
|
|
1138
|
+
}
|
|
1139
|
+
n.recordContentY(), t.setPage(d);
|
|
1140
|
+
}, ht = (t) => {
|
|
1141
|
+
if (t.data) {
|
|
1142
|
+
if (t.data.startsWith("data:image/png")) return "PNG";
|
|
1143
|
+
if (t.data.startsWith("data:image/jpeg") || t.data.startsWith("data:image/jpg"))
|
|
1144
|
+
return "JPEG";
|
|
1145
|
+
if (t.data.startsWith("data:image/webp") || t.data.startsWith("data:image/webp")) return "WEBP";
|
|
1146
|
+
if (t.data.startsWith("data:image/gif")) return "GIF";
|
|
884
1147
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
1148
|
+
if (t.src) {
|
|
1149
|
+
const i = t.src.split("?")[0].split("#")[0].split(".").pop()?.toUpperCase();
|
|
1150
|
+
if (i && ["PNG", "JPEG", "JPG", "WEBP", "GIF"].includes(i))
|
|
1151
|
+
return i === "JPG" ? "JPEG" : i;
|
|
1152
|
+
}
|
|
1153
|
+
return "JPEG";
|
|
1154
|
+
}, pt = (t, e, i) => {
|
|
1155
|
+
if (!e.data)
|
|
888
1156
|
return;
|
|
889
|
-
const
|
|
890
|
-
let
|
|
891
|
-
const r = g.page.maxContentWidth - s * g.page.indent;
|
|
1157
|
+
const r = n.options, h = r.page.unit || "mm", o = i * r.page.indent, l = r.page.maxContentWidth - o, a = n.X + o;
|
|
1158
|
+
let s = n.Y;
|
|
892
1159
|
try {
|
|
893
|
-
const
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
p > 0 && (p = r, f = p / d), l + f > g.page.maxContentHeight && (t.addPage(), l = g.page.topmargin, e.updateY(l));
|
|
897
|
-
let o = n.src?.split(".").pop()?.toUpperCase() || "JPEG";
|
|
898
|
-
n.data.startsWith("data:image/png") ? o = "PNG" : n.data.startsWith("data:image/jpeg") || n.data.startsWith("data:image/jpg") ? o = "JPEG" : n.data.startsWith("data:image/webp") && (o = "WEBP"), t.addImage(
|
|
899
|
-
n.data,
|
|
900
|
-
o,
|
|
901
|
-
c,
|
|
1160
|
+
const g = r.page.maxContentHeight - r.page.topmargin, { finalWidth: c, finalHeight: f } = _(
|
|
1161
|
+
t,
|
|
1162
|
+
e,
|
|
902
1163
|
l,
|
|
1164
|
+
g,
|
|
1165
|
+
h
|
|
1166
|
+
);
|
|
1167
|
+
s + f > r.page.maxContentHeight && (Y(t), s = n.Y);
|
|
1168
|
+
const d = e.align || r.image?.defaultAlign || "left";
|
|
1169
|
+
let p;
|
|
1170
|
+
switch (d) {
|
|
1171
|
+
case "right":
|
|
1172
|
+
p = a + l - c;
|
|
1173
|
+
break;
|
|
1174
|
+
case "center":
|
|
1175
|
+
p = a + (l - c) / 2;
|
|
1176
|
+
break;
|
|
1177
|
+
default:
|
|
1178
|
+
p = a;
|
|
1179
|
+
break;
|
|
1180
|
+
}
|
|
1181
|
+
const m = ht(e);
|
|
1182
|
+
c > 0 && f > 0 && t.addImage(
|
|
1183
|
+
e.data,
|
|
1184
|
+
m,
|
|
903
1185
|
p,
|
|
1186
|
+
s,
|
|
1187
|
+
c,
|
|
904
1188
|
f
|
|
905
|
-
),
|
|
906
|
-
} catch (
|
|
907
|
-
console.warn("Failed to render image",
|
|
1189
|
+
), n.updateY(f, "add"), n.recordContentY();
|
|
1190
|
+
} catch (g) {
|
|
1191
|
+
console.warn("Failed to render image", g);
|
|
908
1192
|
}
|
|
909
|
-
},
|
|
910
|
-
if (!
|
|
1193
|
+
}, ft = (t, e, i) => {
|
|
1194
|
+
if (!e.header || !e.rows)
|
|
911
1195
|
return;
|
|
912
|
-
const
|
|
913
|
-
(
|
|
914
|
-
),
|
|
915
|
-
|
|
916
|
-
head:
|
|
917
|
-
body:
|
|
918
|
-
startY:
|
|
919
|
-
margin: { left:
|
|
920
|
-
...
|
|
921
|
-
didDrawPage: (
|
|
922
|
-
|
|
1196
|
+
const r = n.options, h = r.page.xmargin + i * r.page.indent, o = [e.header.map((s) => s.content || "")], l = e.rows.map(
|
|
1197
|
+
(s) => s.map((g) => g.content || "")
|
|
1198
|
+
), a = r.table || {};
|
|
1199
|
+
O(t, {
|
|
1200
|
+
head: o,
|
|
1201
|
+
body: l,
|
|
1202
|
+
startY: n.Y,
|
|
1203
|
+
margin: { left: h, right: r.page.xmargin },
|
|
1204
|
+
...a,
|
|
1205
|
+
didDrawPage: (s) => {
|
|
1206
|
+
a.didDrawPage && a.didDrawPage(s);
|
|
923
1207
|
},
|
|
924
|
-
didDrawCell: (
|
|
925
|
-
|
|
926
|
-
x:
|
|
927
|
-
y:
|
|
1208
|
+
didDrawCell: (s) => {
|
|
1209
|
+
a.didDrawCell && a.didDrawCell(s), n.setCursor({
|
|
1210
|
+
x: n.X,
|
|
1211
|
+
y: s.cell.y + s.cell.height + 2 * r.page.lineSpace
|
|
928
1212
|
});
|
|
929
1213
|
}
|
|
930
1214
|
});
|
|
931
|
-
}, B = async (t) => {
|
|
932
|
-
for (const n of t) {
|
|
933
|
-
if (n.type === u.Image && n.src)
|
|
934
|
-
try {
|
|
935
|
-
if (n.src.startsWith("data:"))
|
|
936
|
-
n.data = n.src;
|
|
937
|
-
else {
|
|
938
|
-
const s = await fetch(n.src);
|
|
939
|
-
if (!s.ok)
|
|
940
|
-
throw new Error(
|
|
941
|
-
`Failed to fetch image: ${s.statusText}`
|
|
942
|
-
);
|
|
943
|
-
const g = await s.blob(), c = await new Promise(
|
|
944
|
-
(l, r) => {
|
|
945
|
-
const i = new FileReader();
|
|
946
|
-
i.onloadend = () => {
|
|
947
|
-
typeof i.result == "string" ? l(i.result) : r(
|
|
948
|
-
new Error(
|
|
949
|
-
"Failed to convert image to base64 string"
|
|
950
|
-
)
|
|
951
|
-
);
|
|
952
|
-
}, i.onerror = r, i.readAsDataURL(g);
|
|
953
|
-
}
|
|
954
|
-
);
|
|
955
|
-
n.data = c;
|
|
956
|
-
}
|
|
957
|
-
} catch (s) {
|
|
958
|
-
console.warn(
|
|
959
|
-
`[jspdf-md-renderer] Warning: Failed to load image at ${n.src}. It will be skipped.`,
|
|
960
|
-
s
|
|
961
|
-
);
|
|
962
|
-
}
|
|
963
|
-
n.items && n.items.length > 0 && await B(n.items);
|
|
964
|
-
}
|
|
965
1215
|
}, v = {
|
|
966
1216
|
page: {
|
|
967
1217
|
indent: 10,
|
|
@@ -981,83 +1231,87 @@ const _ = (t, n, s, g) => {
|
|
|
981
1231
|
bold: { name: "helvetica", style: "bold" },
|
|
982
1232
|
regular: { name: "helvetica", style: "normal" },
|
|
983
1233
|
light: { name: "helvetica", style: "light" }
|
|
1234
|
+
},
|
|
1235
|
+
image: {
|
|
1236
|
+
defaultAlign: "left"
|
|
984
1237
|
}
|
|
985
|
-
},
|
|
1238
|
+
}, dt = (t) => {
|
|
986
1239
|
if (!t)
|
|
987
1240
|
throw new Error("RenderOption is required");
|
|
988
|
-
const
|
|
989
|
-
return
|
|
1241
|
+
const e = { ...v.page, ...t.page }, i = { ...v.font, ...t.font }, r = { ...v.image, ...t.image };
|
|
1242
|
+
return e.maxContentWidth || (e.maxContentWidth = 190), e.maxContentHeight || (e.maxContentHeight = 277), {
|
|
990
1243
|
...t,
|
|
991
|
-
page:
|
|
992
|
-
font:
|
|
1244
|
+
page: e,
|
|
1245
|
+
font: i,
|
|
1246
|
+
image: r
|
|
993
1247
|
};
|
|
994
|
-
},
|
|
995
|
-
const
|
|
996
|
-
|
|
997
|
-
const
|
|
998
|
-
await
|
|
999
|
-
const
|
|
1000
|
-
const d =
|
|
1001
|
-
switch (
|
|
1248
|
+
}, xt = async (t, e, i) => {
|
|
1249
|
+
const r = dt(i);
|
|
1250
|
+
n.initialize(r);
|
|
1251
|
+
const h = await M(e);
|
|
1252
|
+
await $(h);
|
|
1253
|
+
const o = (l, a = 0, s = !1, g = 0, c = !1, f = !0) => {
|
|
1254
|
+
const d = a * r.page.indent;
|
|
1255
|
+
switch (l.type) {
|
|
1002
1256
|
case u.Heading:
|
|
1003
|
-
|
|
1257
|
+
et(t, l, d, o);
|
|
1004
1258
|
break;
|
|
1005
1259
|
case u.Paragraph:
|
|
1006
|
-
|
|
1260
|
+
nt(t, l, d, o);
|
|
1007
1261
|
break;
|
|
1008
1262
|
case u.List:
|
|
1009
|
-
|
|
1263
|
+
it(t, l, a, o);
|
|
1010
1264
|
break;
|
|
1011
1265
|
case u.ListItem:
|
|
1012
|
-
|
|
1266
|
+
st(
|
|
1013
1267
|
t,
|
|
1014
|
-
r,
|
|
1015
|
-
i,
|
|
1016
1268
|
l,
|
|
1017
|
-
|
|
1018
|
-
|
|
1269
|
+
a,
|
|
1270
|
+
o,
|
|
1271
|
+
g,
|
|
1272
|
+
c
|
|
1019
1273
|
);
|
|
1020
1274
|
break;
|
|
1021
1275
|
case u.Hr:
|
|
1022
|
-
|
|
1276
|
+
ot(t);
|
|
1023
1277
|
break;
|
|
1024
1278
|
case u.Code:
|
|
1025
|
-
|
|
1279
|
+
rt(t, l, a);
|
|
1026
1280
|
break;
|
|
1027
1281
|
case u.Strong:
|
|
1028
1282
|
case u.Em:
|
|
1029
1283
|
case u.CodeSpan:
|
|
1030
|
-
|
|
1284
|
+
lt(t, l, d);
|
|
1031
1285
|
break;
|
|
1032
1286
|
case u.Link:
|
|
1033
|
-
|
|
1287
|
+
gt(t, l, d);
|
|
1034
1288
|
break;
|
|
1035
1289
|
case u.Blockquote:
|
|
1036
|
-
|
|
1290
|
+
ct(t, l, a, o);
|
|
1037
1291
|
break;
|
|
1038
1292
|
case u.Image:
|
|
1039
|
-
|
|
1293
|
+
pt(t, l, a);
|
|
1040
1294
|
break;
|
|
1041
1295
|
case u.Table:
|
|
1042
|
-
|
|
1296
|
+
ft(t, l, a);
|
|
1043
1297
|
break;
|
|
1044
1298
|
case u.Raw:
|
|
1045
1299
|
case u.Text:
|
|
1046
|
-
|
|
1300
|
+
at(
|
|
1047
1301
|
t,
|
|
1048
|
-
r,
|
|
1049
|
-
i,
|
|
1050
|
-
a,
|
|
1051
1302
|
l,
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1303
|
+
a,
|
|
1304
|
+
s,
|
|
1305
|
+
o,
|
|
1306
|
+
g,
|
|
1307
|
+
c,
|
|
1308
|
+
r.page.defaultFontSize > 0
|
|
1055
1309
|
// Using validOptions here if needed, or just true for justify
|
|
1056
1310
|
);
|
|
1057
1311
|
break;
|
|
1058
1312
|
default:
|
|
1059
1313
|
console.warn(
|
|
1060
|
-
`Warning: Unsupported element type encountered: ${
|
|
1314
|
+
`Warning: Unsupported element type encountered: ${l.type}.
|
|
1061
1315
|
If you believe this element type should be supported, please create an issue at:
|
|
1062
1316
|
https://github.com/JeelGajera/jspdf-md-renderer/issues
|
|
1063
1317
|
with details of the element and expected behavior. Thanks for helping to improve this library!`
|
|
@@ -1065,11 +1319,11 @@ const _ = (t, n, s, g) => {
|
|
|
1065
1319
|
break;
|
|
1066
1320
|
}
|
|
1067
1321
|
};
|
|
1068
|
-
for (const
|
|
1069
|
-
l
|
|
1070
|
-
|
|
1322
|
+
for (const l of h)
|
|
1323
|
+
o(l);
|
|
1324
|
+
r.endCursorYHandler(n.Y);
|
|
1071
1325
|
};
|
|
1072
1326
|
export {
|
|
1073
|
-
|
|
1074
|
-
|
|
1327
|
+
M as MdTextParser,
|
|
1328
|
+
xt as MdTextRender
|
|
1075
1329
|
};
|