pdf-lite 1.6.4 → 1.7.1
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/acroform/appearance/pdf-button-appearance-stream.js +1 -1
- package/dist/acroform/appearance/pdf-graphics.d.ts +48 -0
- package/dist/acroform/appearance/pdf-graphics.js +177 -4
- package/dist/acroform/appearance/pdf-text-appearance-stream.d.ts +3 -0
- package/dist/acroform/appearance/pdf-text-appearance-stream.js +58 -29
- package/dist/acroform/fields/pdf-button-form-field.d.ts +11 -2
- package/dist/acroform/fields/pdf-button-form-field.js +76 -37
- package/dist/acroform/fields/pdf-choice-form-field.js +2 -2
- package/dist/acroform/fields/pdf-form-field.d.ts +39 -9
- package/dist/acroform/fields/pdf-form-field.js +234 -46
- package/dist/acroform/fields/pdf-text-form-field.js +23 -3
- package/dist/acroform/pdf-acro-form.d.ts +1 -0
- package/dist/acroform/pdf-acro-form.js +15 -4
- package/dist/acroform/xfa/pdf-xfa-data.d.ts +2 -1
- package/dist/acroform/xfa/pdf-xfa-data.js +36 -28
- package/dist/annotations/pdf-annotation.d.ts +1 -1
- package/dist/annotations/pdf-annotation.js +16 -2
- package/dist/core/objects/pdf-array.d.ts +6 -1
- package/dist/core/objects/pdf-array.js +3 -0
- package/dist/core/objects/pdf-boolean.d.ts +6 -2
- package/dist/core/objects/pdf-boolean.js +3 -0
- package/dist/core/objects/pdf-comment.d.ts +6 -2
- package/dist/core/objects/pdf-comment.js +3 -0
- package/dist/core/objects/pdf-date.d.ts +4 -0
- package/dist/core/objects/pdf-date.js +3 -0
- package/dist/core/objects/pdf-dictionary.d.ts +5 -0
- package/dist/core/objects/pdf-dictionary.js +16 -0
- package/dist/core/objects/pdf-hexadecimal.d.ts +6 -2
- package/dist/core/objects/pdf-hexadecimal.js +3 -0
- package/dist/core/objects/pdf-indirect-object.d.ts +8 -1
- package/dist/core/objects/pdf-indirect-object.js +14 -0
- package/dist/core/objects/pdf-name.d.ts +6 -2
- package/dist/core/objects/pdf-name.js +3 -0
- package/dist/core/objects/pdf-null.d.ts +5 -2
- package/dist/core/objects/pdf-null.js +3 -0
- package/dist/core/objects/pdf-number.d.ts +6 -1
- package/dist/core/objects/pdf-number.js +3 -0
- package/dist/core/objects/pdf-object-reference.d.ts +5 -0
- package/dist/core/objects/pdf-object-reference.js +7 -0
- package/dist/core/objects/pdf-object.d.ts +1 -0
- package/dist/core/objects/pdf-start-xref.d.ts +6 -1
- package/dist/core/objects/pdf-start-xref.js +3 -0
- package/dist/core/objects/pdf-stream.d.ts +8 -0
- package/dist/core/objects/pdf-stream.js +7 -0
- package/dist/core/objects/pdf-string.d.ts +8 -2
- package/dist/core/objects/pdf-string.js +9 -0
- package/dist/core/objects/pdf-trailer.d.ts +7 -0
- package/dist/core/objects/pdf-trailer.js +3 -0
- package/dist/core/objects/pdf-xref-table.d.ts +31 -5
- package/dist/core/objects/pdf-xref-table.js +23 -0
- package/dist/fonts/font-family.d.ts +12 -0
- package/dist/fonts/font-family.js +1 -0
- package/dist/fonts/index.d.ts +1 -0
- package/dist/fonts/index.js +1 -0
- package/dist/fonts/parsers/otf-parser.d.ts +2 -2
- package/dist/fonts/parsers/ttf-parser.d.ts +2 -2
- package/dist/fonts/parsers/woff-parser.d.ts +2 -0
- package/dist/fonts/parsers/woff-parser.js +6 -0
- package/dist/fonts/pdf-font.js +94 -8
- package/dist/fonts/types.d.ts +10 -0
- package/dist/pdf/pdf-document.d.ts +7 -0
- package/dist/pdf/pdf-document.js +6 -0
- package/dist/pdf/pdf-revision.d.ts +4 -0
- package/dist/pdf/pdf-revision.js +6 -0
- package/dist/utils/iterable-readable-stream.d.ts +2 -0
- package/dist/utils/iterable-readable-stream.js +8 -1
- package/dist/utils/parse-markdown-segments.d.ts +12 -0
- package/dist/utils/parse-markdown-segments.js +27 -0
- package/dist/utils/xml.d.ts +9 -0
- package/dist/utils/xml.js +59 -0
- package/package.json +2 -2
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Ref } from '../ref.js';
|
|
2
|
-
import {
|
|
3
|
-
import { PdfXRefTableSectionStartToken } from '../tokens/xref-table-section-start-token.js';
|
|
2
|
+
import { PdfToken } from '../tokens/token.js';
|
|
4
3
|
import { PdfIndirectObject } from './pdf-indirect-object.js';
|
|
5
4
|
import { PdfNumber } from './pdf-number.js';
|
|
6
5
|
import { PdfObject } from './pdf-object.js';
|
|
@@ -15,8 +14,15 @@ export declare class PdfXRefTableEntry extends PdfObject {
|
|
|
15
14
|
generationNumber: number | PdfNumber;
|
|
16
15
|
inUse: boolean;
|
|
17
16
|
});
|
|
18
|
-
protected tokenize():
|
|
17
|
+
protected tokenize(): PdfToken[];
|
|
19
18
|
cloneImpl(): this;
|
|
19
|
+
toJSON(): {
|
|
20
|
+
type: string;
|
|
21
|
+
objectNumber: number;
|
|
22
|
+
generationNumber: number;
|
|
23
|
+
byteOffset: number;
|
|
24
|
+
inUse: boolean;
|
|
25
|
+
};
|
|
20
26
|
isModified(): boolean;
|
|
21
27
|
}
|
|
22
28
|
export declare class PdfXRefTableSectionHeader extends PdfObject {
|
|
@@ -26,8 +32,13 @@ export declare class PdfXRefTableSectionHeader extends PdfObject {
|
|
|
26
32
|
startObjectNumber: number | PdfNumber;
|
|
27
33
|
entryCount: number | PdfNumber;
|
|
28
34
|
});
|
|
29
|
-
protected tokenize():
|
|
35
|
+
protected tokenize(): PdfToken[];
|
|
30
36
|
cloneImpl(): this;
|
|
37
|
+
toJSON(): {
|
|
38
|
+
type: string;
|
|
39
|
+
startObjectNumber: number;
|
|
40
|
+
entryCount: number;
|
|
41
|
+
};
|
|
31
42
|
}
|
|
32
43
|
export declare class PdfXRefTable extends PdfObject {
|
|
33
44
|
sections: PdfXRefTableSectionHeader[];
|
|
@@ -42,7 +53,22 @@ export declare class PdfXRefTable extends PdfObject {
|
|
|
42
53
|
addEntryForObject(obj: PdfIndirectObject): void;
|
|
43
54
|
getEntry(objectNumber: number): PdfXRefTableEntry | undefined;
|
|
44
55
|
get lastSection(): PdfXRefTableSectionHeader | null;
|
|
45
|
-
protected tokenize():
|
|
56
|
+
protected tokenize(): PdfToken[];
|
|
46
57
|
private sortEntriesIntoSections;
|
|
47
58
|
cloneImpl(): this;
|
|
59
|
+
toJSON(): {
|
|
60
|
+
type: string;
|
|
61
|
+
sections: {
|
|
62
|
+
type: string;
|
|
63
|
+
startObjectNumber: number;
|
|
64
|
+
entryCount: number;
|
|
65
|
+
}[];
|
|
66
|
+
entries: {
|
|
67
|
+
type: string;
|
|
68
|
+
objectNumber: number;
|
|
69
|
+
generationNumber: number;
|
|
70
|
+
byteOffset: number;
|
|
71
|
+
inUse: boolean;
|
|
72
|
+
}[];
|
|
73
|
+
};
|
|
48
74
|
}
|
|
@@ -44,6 +44,15 @@ export class PdfXRefTableEntry extends PdfObject {
|
|
|
44
44
|
inUse: this.inUse,
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
+
toJSON() {
|
|
48
|
+
return {
|
|
49
|
+
type: 'xref-entry',
|
|
50
|
+
objectNumber: this.objectNumber.value,
|
|
51
|
+
generationNumber: this.generationNumber.value,
|
|
52
|
+
byteOffset: this.byteOffset.value,
|
|
53
|
+
inUse: this.inUse,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
47
56
|
isModified() {
|
|
48
57
|
return (super.isModified() ||
|
|
49
58
|
this.byteOffset.isModified() ||
|
|
@@ -70,6 +79,13 @@ export class PdfXRefTableSectionHeader extends PdfObject {
|
|
|
70
79
|
entryCount: this.entryCount.clone(),
|
|
71
80
|
});
|
|
72
81
|
}
|
|
82
|
+
toJSON() {
|
|
83
|
+
return {
|
|
84
|
+
type: 'xref-section-header',
|
|
85
|
+
startObjectNumber: this.startObjectNumber.value,
|
|
86
|
+
entryCount: this.entryCount.value,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
73
89
|
}
|
|
74
90
|
export class PdfXRefTable extends PdfObject {
|
|
75
91
|
sections;
|
|
@@ -180,4 +196,11 @@ export class PdfXRefTable extends PdfObject {
|
|
|
180
196
|
offset: new Ref(this.offset.resolve()),
|
|
181
197
|
});
|
|
182
198
|
}
|
|
199
|
+
toJSON() {
|
|
200
|
+
return {
|
|
201
|
+
type: 'xref-table',
|
|
202
|
+
sections: this.sections.map((s) => s.toJSON()),
|
|
203
|
+
entries: this.entries.map((e) => e.toJSON()),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
183
206
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PdfFont } from './pdf-font.js';
|
|
2
|
+
/**
|
|
3
|
+
* A group of font variants for a single typeface family.
|
|
4
|
+
* Set on a form field via `field.fontFamily` to enable true bold/italic
|
|
5
|
+
* rendering in markdown appearance streams rather than stroke simulation.
|
|
6
|
+
*/
|
|
7
|
+
export interface FontFamily {
|
|
8
|
+
regular: PdfFont;
|
|
9
|
+
bold?: PdfFont;
|
|
10
|
+
italic?: PdfFont;
|
|
11
|
+
boldItalic?: PdfFont;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/fonts/index.d.ts
CHANGED
package/dist/fonts/index.js
CHANGED
|
@@ -41,10 +41,10 @@ export declare class OtfParser implements FontParser {
|
|
|
41
41
|
private parseOS2;
|
|
42
42
|
private parsePost;
|
|
43
43
|
private parseName;
|
|
44
|
-
|
|
44
|
+
parseCmap(): Map<number, number>;
|
|
45
45
|
private parseCmapFormat4;
|
|
46
46
|
private parseCmapFormat12;
|
|
47
|
-
|
|
47
|
+
parseHmtx(): Map<number, number>;
|
|
48
48
|
private parseMaxp;
|
|
49
49
|
private estimateStemV;
|
|
50
50
|
}
|
|
@@ -33,10 +33,10 @@ export declare class TtfParser implements FontParser {
|
|
|
33
33
|
private parseOS2;
|
|
34
34
|
private parsePost;
|
|
35
35
|
private parseName;
|
|
36
|
-
|
|
36
|
+
parseCmap(): Map<number, number>;
|
|
37
37
|
private parseCmapFormat4;
|
|
38
38
|
private parseCmapFormat12;
|
|
39
|
-
|
|
39
|
+
parseHmtx(): Map<number, number>;
|
|
40
40
|
private parseMaxp;
|
|
41
41
|
private estimateStemV;
|
|
42
42
|
}
|
|
@@ -24,6 +24,8 @@ export declare class WoffParser implements FontParser {
|
|
|
24
24
|
* Gets character widths for a range of characters.
|
|
25
25
|
*/
|
|
26
26
|
getCharWidths(firstChar: number, lastChar: number): number[];
|
|
27
|
+
parseCmap(): Map<number, number>;
|
|
28
|
+
parseHmtx(): Map<number, number>;
|
|
27
29
|
private decompressWoff;
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
@@ -35,6 +35,12 @@ export class WoffParser {
|
|
|
35
35
|
getCharWidths(firstChar, lastChar) {
|
|
36
36
|
return this.ttfParser.getCharWidths(firstChar, lastChar);
|
|
37
37
|
}
|
|
38
|
+
parseCmap() {
|
|
39
|
+
return this.ttfParser.parseCmap();
|
|
40
|
+
}
|
|
41
|
+
parseHmtx() {
|
|
42
|
+
return this.ttfParser.parseHmtx();
|
|
43
|
+
}
|
|
38
44
|
decompressWoff(woffData) {
|
|
39
45
|
const data = new DataView(woffData.buffer, woffData.byteOffset, woffData.byteLength);
|
|
40
46
|
// Verify WOFF signature
|
package/dist/fonts/pdf-font.js
CHANGED
|
@@ -213,6 +213,27 @@ export class PdfFont extends PdfIndirectObject {
|
|
|
213
213
|
* @returns The raw character width or null if not found
|
|
214
214
|
*/
|
|
215
215
|
getRawCharacterWidth(charCode) {
|
|
216
|
+
// For Type0 fonts, check CID widths in descriptor
|
|
217
|
+
if (this.isUnicode && this._descriptor) {
|
|
218
|
+
const unicodeDesc = this._descriptor;
|
|
219
|
+
if (unicodeDesc.cidWidths) {
|
|
220
|
+
// Find width for this CID (which equals Unicode code point for Identity-H)
|
|
221
|
+
for (const entry of unicodeDesc.cidWidths) {
|
|
222
|
+
if ('width' in entry && entry.cid === charCode) {
|
|
223
|
+
return entry.width;
|
|
224
|
+
}
|
|
225
|
+
else if ('widths' in entry) {
|
|
226
|
+
const offset = charCode - entry.startCid;
|
|
227
|
+
if (offset >= 0 && offset < entry.widths.length) {
|
|
228
|
+
return entry.widths[offset];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Not found, use default width
|
|
233
|
+
return unicodeDesc.defaultWidth ?? 1000;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// For Type1/TrueType fonts, use simple widths array
|
|
216
237
|
if (this.widths === undefined || this.firstChar === undefined) {
|
|
217
238
|
return null;
|
|
218
239
|
}
|
|
@@ -285,8 +306,7 @@ export class PdfFont extends PdfIndirectObject {
|
|
|
285
306
|
* @returns A PdfFont instance ready to be written to the PDF
|
|
286
307
|
*/
|
|
287
308
|
static fromBytes(data) {
|
|
288
|
-
|
|
289
|
-
return PdfFont.fromParser(parser);
|
|
309
|
+
return PdfFont.fromFile(data);
|
|
290
310
|
}
|
|
291
311
|
/**
|
|
292
312
|
* Creates a PdfFont from a FontParser instance.
|
|
@@ -582,8 +602,37 @@ export class PdfFont extends PdfIndirectObject {
|
|
|
582
602
|
if (descriptor.cidWidths && descriptor.cidWidths.length > 0) {
|
|
583
603
|
cidFontDict.set('W', PdfFont.buildCIDWidthArray(descriptor.cidWidths));
|
|
584
604
|
}
|
|
585
|
-
// CIDToGIDMap
|
|
586
|
-
|
|
605
|
+
// CIDToGIDMap - Generate binary stream if unicodeMappings provided
|
|
606
|
+
if (unicodeMappings && unicodeMappings.size > 0) {
|
|
607
|
+
// Create a binary CIDToGIDMap stream
|
|
608
|
+
// For Identity-H encoding, CID = Unicode value
|
|
609
|
+
// We need to map each CID to its GID
|
|
610
|
+
const maxCid = Math.max(...Array.from(unicodeMappings.keys()));
|
|
611
|
+
const cidToGidData = new Uint8Array((maxCid + 1) * 2);
|
|
612
|
+
// Initialize all mappings to 0 (missing glyph)
|
|
613
|
+
for (let i = 0; i < cidToGidData.length; i++) {
|
|
614
|
+
cidToGidData[i] = 0;
|
|
615
|
+
}
|
|
616
|
+
// Fill in the mappings
|
|
617
|
+
for (const [unicode, glyphId] of unicodeMappings.entries()) {
|
|
618
|
+
const offset = unicode * 2;
|
|
619
|
+
// Big-endian 16-bit glyph ID
|
|
620
|
+
cidToGidData[offset] = (glyphId >> 8) & 0xff;
|
|
621
|
+
cidToGidData[offset + 1] = glyphId & 0xff;
|
|
622
|
+
}
|
|
623
|
+
const cidToGidStream = new PdfStream({
|
|
624
|
+
header: new PdfDictionary(),
|
|
625
|
+
original: cidToGidData,
|
|
626
|
+
});
|
|
627
|
+
cidToGidStream.addFilter('FlateDecode');
|
|
628
|
+
const cidToGidObject = new PdfIndirectObject({
|
|
629
|
+
content: cidToGidStream,
|
|
630
|
+
});
|
|
631
|
+
cidFontDict.set('CIDToGIDMap', cidToGidObject.reference);
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
cidFontDict.set('CIDToGIDMap', new PdfName(descriptor.cidToGidMap ?? 'Identity'));
|
|
635
|
+
}
|
|
587
636
|
const cidFontObject = new PdfIndirectObject({
|
|
588
637
|
content: cidFontDict,
|
|
589
638
|
});
|
|
@@ -611,21 +660,58 @@ export class PdfFont extends PdfIndirectObject {
|
|
|
611
660
|
static fromFile(fontData, options) {
|
|
612
661
|
// Parse the font to extract metadata
|
|
613
662
|
const parser = parseFont(fontData);
|
|
663
|
+
// Check if CFF-based OTF (not supported)
|
|
664
|
+
if (parser instanceof OtfParser && parser.isCFFBased()) {
|
|
665
|
+
throw new Error('CFF-based OTF fonts are not supported yet');
|
|
666
|
+
}
|
|
614
667
|
const info = parser.getFontInfo();
|
|
615
668
|
// Auto-generate font name from metadata if not provided
|
|
616
669
|
const fontName = options?.fontName ?? info.postScriptName ?? info.fullName;
|
|
617
670
|
// Get the appropriate descriptor based on unicode option
|
|
618
671
|
const descriptor = parser.getFontDescriptor(fontName);
|
|
672
|
+
// Auto-detect if Unicode font is needed if not explicitly specified
|
|
673
|
+
let useUnicode = options?.unicode;
|
|
674
|
+
if (useUnicode === undefined) {
|
|
675
|
+
// Check if font has glyphs beyond WinAnsiEncoding range (0-255)
|
|
676
|
+
const cmap = parser.parseCmap();
|
|
677
|
+
useUnicode = Array.from(cmap.keys()).some((unicode) => unicode > 0xff);
|
|
678
|
+
}
|
|
619
679
|
// Embed using the appropriate method and return PdfFont
|
|
620
|
-
if (
|
|
680
|
+
if (useUnicode) {
|
|
681
|
+
// Auto-extract cmap if not provided
|
|
682
|
+
const unicodeMappings = options?.unicodeMappings ?? parser.parseCmap();
|
|
683
|
+
// Extract glyph widths for Unicode characters
|
|
684
|
+
const hmtx = parser.parseHmtx();
|
|
685
|
+
const unitsPerEm = info.unitsPerEm;
|
|
686
|
+
const cidWidths = [];
|
|
687
|
+
// Build CID widths array from cmap + hmtx
|
|
688
|
+
for (const [unicode, glyphId] of unicodeMappings.entries()) {
|
|
689
|
+
const glyphWidth = hmtx.get(glyphId) ?? 0;
|
|
690
|
+
// Scale to 1000-unit em square
|
|
691
|
+
const scaledWidth = Math.round((glyphWidth * 1000) / unitsPerEm);
|
|
692
|
+
cidWidths.push({ cid: unicode, width: scaledWidth });
|
|
693
|
+
}
|
|
694
|
+
// Compute average width for default
|
|
695
|
+
const avgWidth = cidWidths.length > 0
|
|
696
|
+
? Math.round(cidWidths.reduce((sum, entry) => {
|
|
697
|
+
if ('width' in entry) {
|
|
698
|
+
return sum + entry.width;
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
// Average the widths in the range
|
|
702
|
+
const rangeSum = entry.widths.reduce((a, b) => a + b, 0);
|
|
703
|
+
return sum + rangeSum / entry.widths.length;
|
|
704
|
+
}
|
|
705
|
+
}, 0) / cidWidths.length)
|
|
706
|
+
: 1000;
|
|
621
707
|
// For Unicode fonts, we need a UnicodeFontDescriptor
|
|
622
|
-
// Create one by extending the base descriptor
|
|
623
708
|
const unicodeDescriptor = {
|
|
624
709
|
...descriptor,
|
|
625
|
-
defaultWidth:
|
|
710
|
+
defaultWidth: avgWidth,
|
|
711
|
+
cidWidths,
|
|
626
712
|
cidToGidMap: 'Identity',
|
|
627
713
|
};
|
|
628
|
-
return PdfFont.fromType0Data(fontData, fontName, unicodeDescriptor,
|
|
714
|
+
return PdfFont.fromType0Data(fontData, fontName, unicodeDescriptor, unicodeMappings);
|
|
629
715
|
}
|
|
630
716
|
else {
|
|
631
717
|
// Use standard TrueType embedding
|
package/dist/fonts/types.d.ts
CHANGED
|
@@ -8,6 +8,16 @@ export interface FontParser {
|
|
|
8
8
|
getFontDescriptor(fontName?: string): FontDescriptor;
|
|
9
9
|
getCharWidths(firstChar: number, lastChar: number): number[];
|
|
10
10
|
getFontData(): ByteArray;
|
|
11
|
+
/**
|
|
12
|
+
* Parses the font's cmap table to extract Unicode to glyph ID mappings.
|
|
13
|
+
* @returns A map from Unicode code points to glyph IDs
|
|
14
|
+
*/
|
|
15
|
+
parseCmap(): Map<number, number>;
|
|
16
|
+
/**
|
|
17
|
+
* Parses the font's hmtx table to extract glyph advance widths.
|
|
18
|
+
* @returns A map from glyph IDs to advance widths (in font units)
|
|
19
|
+
*/
|
|
20
|
+
parseHmtx(): Map<number, number>;
|
|
11
21
|
}
|
|
12
22
|
/**
|
|
13
23
|
* Parsed TrueType font information.
|
|
@@ -311,6 +311,13 @@ export declare class PdfDocument extends PdfObject implements IPdfObjectResolver
|
|
|
311
311
|
* @returns A cloned PdfDocument instance
|
|
312
312
|
*/
|
|
313
313
|
cloneImpl(): this;
|
|
314
|
+
toJSON(): {
|
|
315
|
+
type: string;
|
|
316
|
+
revisions: {
|
|
317
|
+
type: string;
|
|
318
|
+
objects: object[];
|
|
319
|
+
}[];
|
|
320
|
+
};
|
|
314
321
|
/**
|
|
315
322
|
* Creates a PdfDocument from a byte stream.
|
|
316
323
|
*
|
package/dist/pdf/pdf-document.js
CHANGED
|
@@ -967,6 +967,12 @@ export class PdfDocument extends PdfObject {
|
|
|
967
967
|
securityHandler: this.securityHandler,
|
|
968
968
|
});
|
|
969
969
|
}
|
|
970
|
+
toJSON() {
|
|
971
|
+
return {
|
|
972
|
+
type: 'document',
|
|
973
|
+
revisions: this.revisions.map((rev) => rev.toJSON()),
|
|
974
|
+
};
|
|
975
|
+
}
|
|
970
976
|
/**
|
|
971
977
|
* Creates a PdfDocument from a byte stream.
|
|
972
978
|
*
|
|
@@ -124,6 +124,10 @@ export declare class PdfRevision extends PdfObject {
|
|
|
124
124
|
*
|
|
125
125
|
* @returns A cloned PdfRevision instance
|
|
126
126
|
*/
|
|
127
|
+
toJSON(): {
|
|
128
|
+
type: string;
|
|
129
|
+
objects: object[];
|
|
130
|
+
};
|
|
127
131
|
cloneImpl(): this;
|
|
128
132
|
protected tokenize(): PdfToken[];
|
|
129
133
|
isEmpty(): boolean;
|
package/dist/pdf/pdf-revision.js
CHANGED
|
@@ -251,6 +251,12 @@ export class PdfRevision extends PdfObject {
|
|
|
251
251
|
*
|
|
252
252
|
* @returns A cloned PdfRevision instance
|
|
253
253
|
*/
|
|
254
|
+
toJSON() {
|
|
255
|
+
return {
|
|
256
|
+
type: 'revision',
|
|
257
|
+
objects: this._objects.map((obj) => obj.toJSON()),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
254
260
|
cloneImpl() {
|
|
255
261
|
const clonedObjects = this.objects.map((obj) => obj.clone());
|
|
256
262
|
return new PdfRevision({ objects: clonedObjects });
|
|
@@ -20,11 +20,18 @@ export class IterableReadableStream extends ReadableStream {
|
|
|
20
20
|
*/
|
|
21
21
|
[Symbol.asyncIterator]() {
|
|
22
22
|
const reader = this.getReader();
|
|
23
|
-
|
|
23
|
+
const iterator = {
|
|
24
24
|
async next() {
|
|
25
25
|
const result = await reader.read();
|
|
26
26
|
return result;
|
|
27
27
|
},
|
|
28
|
+
[Symbol.asyncIterator]() {
|
|
29
|
+
return iterator;
|
|
30
|
+
},
|
|
31
|
+
async [Symbol.asyncDispose]() {
|
|
32
|
+
reader.releaseLock();
|
|
33
|
+
},
|
|
28
34
|
};
|
|
35
|
+
return iterator;
|
|
29
36
|
}
|
|
30
37
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type StyledSegment = {
|
|
2
|
+
text: string;
|
|
3
|
+
bold: boolean;
|
|
4
|
+
italic: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Parses a markdown string with **bold**, *italic*, and ***bold+italic***
|
|
8
|
+
* syntax into an array of styled text segments.
|
|
9
|
+
*
|
|
10
|
+
* Unrecognized or unmatched asterisks are emitted as plain text.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseMarkdownSegments(text: string): StyledSegment[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a markdown string with **bold**, *italic*, and ***bold+italic***
|
|
3
|
+
* syntax into an array of styled text segments.
|
|
4
|
+
*
|
|
5
|
+
* Unrecognized or unmatched asterisks are emitted as plain text.
|
|
6
|
+
*/
|
|
7
|
+
export function parseMarkdownSegments(text) {
|
|
8
|
+
const segments = [];
|
|
9
|
+
// Match *** before ** before * to handle longest-match first
|
|
10
|
+
const re = /\*\*\*(.+?)\*\*\*|\*\*(.+?)\*\*|\*(.+?)\*|([^*]+|\*)/gs;
|
|
11
|
+
let match;
|
|
12
|
+
while ((match = re.exec(text)) !== null) {
|
|
13
|
+
if (match[1] !== undefined) {
|
|
14
|
+
segments.push({ text: match[1], bold: true, italic: true });
|
|
15
|
+
}
|
|
16
|
+
else if (match[2] !== undefined) {
|
|
17
|
+
segments.push({ text: match[2], bold: true, italic: false });
|
|
18
|
+
}
|
|
19
|
+
else if (match[3] !== undefined) {
|
|
20
|
+
segments.push({ text: match[3], bold: false, italic: true });
|
|
21
|
+
}
|
|
22
|
+
else if (match[4] !== undefined && match[4].length > 0) {
|
|
23
|
+
segments.push({ text: match[4], bold: false, italic: false });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return segments;
|
|
27
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class Xml {
|
|
2
|
+
static escapeValue(value: string): string;
|
|
3
|
+
static getElementContent(xml: string, tagName: string): string | null;
|
|
4
|
+
static setElementContent(xml: string, tagName: string, content: string): string;
|
|
5
|
+
static hasElement(xml: string, tagName: string): boolean;
|
|
6
|
+
static insertChild(xml: string, parentTagName: string, childXml: string): string;
|
|
7
|
+
static wrapInElements(content: string, tagNames: string[]): string;
|
|
8
|
+
static escapeRegex(str: string): string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export class Xml {
|
|
2
|
+
static escapeValue(value) {
|
|
3
|
+
return value
|
|
4
|
+
.replace(/&/g, '&')
|
|
5
|
+
.replace(/</g, '<')
|
|
6
|
+
.replace(/>/g, '>')
|
|
7
|
+
.replace(/"/g, '"')
|
|
8
|
+
.replace(/'/g, ''');
|
|
9
|
+
}
|
|
10
|
+
static getElementContent(xml, tagName) {
|
|
11
|
+
const escaped = Xml.escapeRegex(tagName);
|
|
12
|
+
const regex = new RegExp(`<${escaped}(?:\\s[^>]*)?>([\\s\\S]*?)</${escaped}\\s*>`);
|
|
13
|
+
const match = xml.match(regex);
|
|
14
|
+
return match ? match[1] : null;
|
|
15
|
+
}
|
|
16
|
+
static setElementContent(xml, tagName, content) {
|
|
17
|
+
const escaped = Xml.escapeRegex(tagName);
|
|
18
|
+
// Try expanding a self-closing tag
|
|
19
|
+
const selfClosing = new RegExp(`<${escaped}\\s*/>`);
|
|
20
|
+
if (selfClosing.test(xml)) {
|
|
21
|
+
return xml.replace(selfClosing, `<${tagName}>${content}</${tagName}>`);
|
|
22
|
+
}
|
|
23
|
+
// Try replacing content of an existing tag
|
|
24
|
+
const contentRegex = new RegExp(`(<${escaped}(?:\\s[^>]*)?>)[\\s\\S]*?(</${escaped}\\s*>)`);
|
|
25
|
+
if (contentRegex.test(xml)) {
|
|
26
|
+
return xml.replace(contentRegex, `$1${content}$2`);
|
|
27
|
+
}
|
|
28
|
+
return xml;
|
|
29
|
+
}
|
|
30
|
+
static hasElement(xml, tagName) {
|
|
31
|
+
const escaped = Xml.escapeRegex(tagName);
|
|
32
|
+
return (new RegExp(`</${escaped}\\s*>`).test(xml) ||
|
|
33
|
+
new RegExp(`<${escaped}\\s*/>`).test(xml));
|
|
34
|
+
}
|
|
35
|
+
static insertChild(xml, parentTagName, childXml) {
|
|
36
|
+
const escaped = Xml.escapeRegex(parentTagName);
|
|
37
|
+
// Insert before closing tag
|
|
38
|
+
const closingRegex = new RegExp(`(</${escaped}\\s*>)`);
|
|
39
|
+
if (closingRegex.test(xml)) {
|
|
40
|
+
return xml.replace(closingRegex, `${childXml}$1`);
|
|
41
|
+
}
|
|
42
|
+
// Expand self-closing tag
|
|
43
|
+
const selfClosing = new RegExp(`<${escaped}\\s*/>`);
|
|
44
|
+
if (selfClosing.test(xml)) {
|
|
45
|
+
return xml.replace(selfClosing, `<${parentTagName}>${childXml}</${parentTagName}>`);
|
|
46
|
+
}
|
|
47
|
+
return xml;
|
|
48
|
+
}
|
|
49
|
+
static wrapInElements(content, tagNames) {
|
|
50
|
+
let result = content;
|
|
51
|
+
for (let i = tagNames.length - 1; i >= 0; i--) {
|
|
52
|
+
result = `<${tagNames[i]}>${result}</${tagNames[i]}>`;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
static escapeRegex(str) {
|
|
57
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
58
|
+
}
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-lite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@vitest/browser-playwright": "^4.0.14",
|
|
36
36
|
"@vitest/coverage-v8": "^4.0.14",
|
|
37
37
|
"playwright": "^1.56.1",
|
|
38
|
-
"typescript": "
|
|
38
|
+
"typescript": "6.0.2",
|
|
39
39
|
"vitest": "^4.0.14"
|
|
40
40
|
},
|
|
41
41
|
"repository": {
|