jspdf-md-renderer 3.3.2 → 3.3.3

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