pdf-codec 3.1.4 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/annotations.cjs +104 -0
- package/dist/annotations.d.cts +9 -0
- package/dist/annotations.d.ts +9 -0
- package/dist/annotations.js +103 -0
- package/dist/attachments.cjs +65 -0
- package/dist/attachments.d.cts +8 -0
- package/dist/attachments.d.ts +8 -0
- package/dist/attachments.js +64 -0
- package/dist/bytes/flate.cjs +1 -1
- package/dist/bytes/flate.js +1 -1
- package/dist/codec.d.cts +109 -0
- package/dist/codec.d.ts +109 -0
- package/dist/content-read.cjs +1 -1
- package/dist/content-read.js +1 -1
- package/dist/content-write.cjs +2 -2
- package/dist/content-write.js +2 -2
- package/dist/document.cjs +12 -3
- package/dist/document.d.cts +2 -0
- package/dist/document.d.ts +2 -0
- package/dist/document.js +12 -3
- package/dist/embedded-font-write.cjs +1 -1
- package/dist/embedded-font-write.js +1 -1
- package/dist/encrypt.cjs +1 -1
- package/dist/encrypt.js +1 -1
- package/dist/filters.cjs +1 -1
- package/dist/filters.js +1 -1
- package/dist/font-read.cjs +1 -1
- package/dist/font-read.js +1 -1
- package/dist/font-registry.cjs +1 -1
- package/dist/font-registry.js +1 -1
- package/dist/form.cjs +138 -0
- package/dist/form.d.cts +9 -0
- package/dist/form.d.ts +9 -0
- package/dist/form.js +137 -0
- package/dist/image/png-decode.cjs +1 -1
- package/dist/image/png-decode.js +1 -1
- package/dist/image/png-encode.cjs +1 -1
- package/dist/image/png-encode.js +1 -1
- package/dist/index.cjs +12 -2
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/interpret.cjs +70 -10
- package/dist/interpret.d.cts +9 -1
- package/dist/interpret.d.ts +9 -1
- package/dist/interpret.js +70 -10
- package/dist/layout.cjs +132 -2
- package/dist/layout.d.cts +335 -1
- package/dist/layout.d.ts +335 -1
- package/dist/layout.js +124 -4
- package/dist/math-content-write.cjs +1 -1
- package/dist/math-content-write.js +1 -1
- package/dist/math-font.cjs +1 -1
- package/dist/math-font.js +1 -1
- package/dist/names.cjs +41 -0
- package/dist/names.d.cts +11 -0
- package/dist/names.d.ts +11 -0
- package/dist/names.js +40 -0
- package/dist/navigation.cjs +210 -0
- package/dist/navigation.d.cts +18 -0
- package/dist/navigation.d.ts +18 -0
- package/dist/navigation.js +207 -0
- package/dist/optional-content.cjs +63 -0
- package/dist/optional-content.d.cts +12 -0
- package/dist/optional-content.d.ts +12 -0
- package/dist/optional-content.js +62 -0
- package/dist/parse.cjs +1 -1
- package/dist/parse.d.cts +1 -1
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +1 -1
- package/dist/pdf-text.cjs +21 -0
- package/dist/pdf-text.d.cts +5 -0
- package/dist/pdf-text.d.ts +5 -0
- package/dist/pdf-text.js +19 -0
- package/dist/read.cjs +272 -72
- package/dist/read.d.cts +2 -4
- package/dist/read.d.ts +2 -4
- package/dist/read.js +269 -67
- package/dist/serialize.cjs +5 -1
- package/dist/serialize.d.cts +3 -2
- package/dist/serialize.d.ts +3 -2
- package/dist/serialize.js +5 -2
- package/dist/write.cjs +51 -5
- package/dist/write.js +51 -5
- package/dist/xmp.cjs +46 -0
- package/dist/xmp.d.cts +14 -0
- package/dist/xmp.d.ts +14 -0
- package/dist/xmp.js +45 -0
- package/dist/xref.cjs +2 -2
- package/dist/xref.js +2 -2
- package/package.json +2 -2
package/dist/write.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { a as winAnsiGlyphName, n as widthOfCode, t as STANDARD_METRICS } from "./afm-widths-Dxucrg7D.js";
|
|
2
|
-
import {
|
|
2
|
+
import { NOTES_ANNOTATION_AUTHOR } from "./notes-annotation-author.js";
|
|
3
|
+
import { pdfArray, pdfDict, pdfHexString, pdfName, pdfNull, pdfNum, pdfRef, pdfStream } from "./objects.js";
|
|
3
4
|
import { ByteWriter, concatBytes } from "./bytes/writer.js";
|
|
4
|
-
import {
|
|
5
|
+
import { writeObject } from "./serialize.js";
|
|
5
6
|
import { deflate } from "./bytes/flate.js";
|
|
7
|
+
import { base64ToBytes } from "./util/base64.js";
|
|
6
8
|
import { throwIfAborted } from "./util/abort.js";
|
|
7
9
|
import { readJpegInfo } from "./image/jpeg-info.js";
|
|
8
|
-
import { NOTES_ANNOTATION_AUTHOR } from "./notes-annotation-author.js";
|
|
9
10
|
import { decodePng } from "./image/png-decode.js";
|
|
10
11
|
import { collectEmbeddedGlyphs } from "./embedded-font.js";
|
|
11
|
-
import { writeObject } from "./serialize.js";
|
|
12
12
|
import { writeContentStream } from "./content-write.js";
|
|
13
13
|
import { buildEmbeddedFontObjects } from "./embedded-font-write.js";
|
|
14
14
|
import { resolveFaceWithRegistry } from "./font-registry.js";
|
|
@@ -177,9 +177,55 @@ function buildLinkAnnotDict(link) {
|
|
|
177
177
|
})
|
|
178
178
|
});
|
|
179
179
|
}
|
|
180
|
+
function destinationViewArray(target) {
|
|
181
|
+
const n = (value) => value === void 0 ? pdfNull() : pdfNum(value);
|
|
182
|
+
if (target.kind === "xyz") return [
|
|
183
|
+
pdfName("XYZ"),
|
|
184
|
+
n(target.leftPt),
|
|
185
|
+
n(target.topPt),
|
|
186
|
+
n(target.zoom)
|
|
187
|
+
];
|
|
188
|
+
if (target.kind === "fitH") return [pdfName("FitH"), n(target.topPt)];
|
|
189
|
+
if (target.kind === "fitV") return [pdfName("FitV"), n(target.leftPt)];
|
|
190
|
+
if (target.kind === "fitR") return [
|
|
191
|
+
pdfName("FitR"),
|
|
192
|
+
n(target.leftPt),
|
|
193
|
+
n(target.bottomPt),
|
|
194
|
+
n(target.rightPt),
|
|
195
|
+
n(target.topPt)
|
|
196
|
+
];
|
|
197
|
+
if (target.kind === "fitBH") return [pdfName("FitBH"), n(target.topPt)];
|
|
198
|
+
if (target.kind === "fitBV") return [pdfName("FitBV"), n(target.leftPt)];
|
|
199
|
+
return [pdfName(target.kind === "fitB" ? "FitB" : "Fit")];
|
|
200
|
+
}
|
|
201
|
+
function buildInternalLinkAnnotDict(link, doc, pageAllocs) {
|
|
202
|
+
const destination = doc.destinations?.find((d) => d.name === link.destination);
|
|
203
|
+
if (destination === void 0) throw new Error(`internal link names destination "${link.destination}", which the document's destinations table does not carry -- this is a caller-invariant violation`);
|
|
204
|
+
const targetPage = pageAllocs[destination.pageIndex];
|
|
205
|
+
if (targetPage === void 0) throw new Error(`destination "${link.destination}" names page index ${destination.pageIndex}, which is beyond the document's own pages -- this is a caller-invariant violation`);
|
|
206
|
+
return pdfDict({
|
|
207
|
+
Type: pdfName("Annot"),
|
|
208
|
+
Subtype: pdfName("Link"),
|
|
209
|
+
Rect: pdfArray([
|
|
210
|
+
link.xPt,
|
|
211
|
+
link.yPt,
|
|
212
|
+
link.xPt + link.widthPt,
|
|
213
|
+
link.yPt + link.heightPt
|
|
214
|
+
].map((v) => pdfNum(v))),
|
|
215
|
+
Border: pdfArray([
|
|
216
|
+
0,
|
|
217
|
+
0,
|
|
218
|
+
0
|
|
219
|
+
].map((v) => pdfNum(v))),
|
|
220
|
+
Dest: pdfArray([pdfRef(targetPage.pageNum, 0), ...destinationViewArray(destination.target)])
|
|
221
|
+
});
|
|
222
|
+
}
|
|
180
223
|
function isLinkItem(item) {
|
|
181
224
|
return item.kind === "link";
|
|
182
225
|
}
|
|
226
|
+
function isInternalLinkItem(item) {
|
|
227
|
+
return item.kind === "internalLink";
|
|
228
|
+
}
|
|
183
229
|
const NOTES_ANNOTATION_HIDDEN_FLAG = 2;
|
|
184
230
|
function buildNotesAnnotDict(notes) {
|
|
185
231
|
return pdfDict({
|
|
@@ -435,7 +481,7 @@ function writePdf(doc, options = {}) {
|
|
|
435
481
|
num: contentsNum,
|
|
436
482
|
value: pdfStream(contentsDict, finalContentBytes)
|
|
437
483
|
});
|
|
438
|
-
const annots = page.items.filter(isLinkItem).map((link) => buildLinkAnnotDict(link));
|
|
484
|
+
const annots = [...page.items.filter(isLinkItem).map((link) => buildLinkAnnotDict(link)), ...page.items.filter(isInternalLinkItem).map((link) => buildInternalLinkAnnotDict(link, doc, pageAllocs))];
|
|
439
485
|
if (page.notes !== void 0 && page.notes.length > 0) annots.push(buildNotesAnnotDict(page.notes));
|
|
440
486
|
const pageEntries = /* @__PURE__ */ new Map([
|
|
441
487
|
["Type", pdfName("Page")],
|
package/dist/xmp.cjs
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/xmp.ts
|
|
3
|
+
function readXmpMetadata(packet) {
|
|
4
|
+
return {
|
|
5
|
+
...field(xmpValue(packet, "dc:title"), "title"),
|
|
6
|
+
...field(xmpValue(packet, "dc:creator"), "author"),
|
|
7
|
+
...field(xmpValue(packet, "dc:description"), "subject"),
|
|
8
|
+
...field(xmpValue(packet, "xmp:CreatorTool"), "creator"),
|
|
9
|
+
...field(xmpValue(packet, "pdf:Producer"), "producer"),
|
|
10
|
+
...field(xmpValue(packet, "xmp:CreateDate"), "createdIso"),
|
|
11
|
+
...field(xmpValue(packet, "xmp:ModifyDate"), "modifiedIso"),
|
|
12
|
+
...keywordsOf(packet)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function xmpValue(packet, element) {
|
|
16
|
+
const match = new RegExp(`<${element}(?:\\s[^>]*)?>([\\s\\S]*?)</${element}>`).exec(packet);
|
|
17
|
+
if (match === null) return;
|
|
18
|
+
const inner = match[1] ?? "";
|
|
19
|
+
const items = listItems(inner);
|
|
20
|
+
if (items.length > 0) return items;
|
|
21
|
+
const text = inner.trim();
|
|
22
|
+
return text.length > 0 ? text : void 0;
|
|
23
|
+
}
|
|
24
|
+
function listItems(inner) {
|
|
25
|
+
const items = [];
|
|
26
|
+
const pattern = /<rdf:li(?:\s[^>]*)?>([\s\S]*?)<\/rdf:li>/g;
|
|
27
|
+
let match;
|
|
28
|
+
while ((match = pattern.exec(inner)) !== null) {
|
|
29
|
+
const text = (match[1] ?? "").trim();
|
|
30
|
+
if (text.length > 0) items.push(text);
|
|
31
|
+
}
|
|
32
|
+
return items;
|
|
33
|
+
}
|
|
34
|
+
function field(value, key) {
|
|
35
|
+
if (typeof value === "string") return { [key]: value };
|
|
36
|
+
if (Array.isArray(value) && value.length > 0) return { [key]: value.join(", ") };
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
function keywordsOf(packet) {
|
|
40
|
+
const match = (/* @__PURE__ */ new RegExp("<dc:subject(?:\\s[^>]*)?>([\\s\\S]*?)</dc:subject>")).exec(packet);
|
|
41
|
+
if (match === null) return {};
|
|
42
|
+
const items = listItems(match[1] ?? "");
|
|
43
|
+
return items.length > 0 ? { keywords: items } : {};
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
exports.readXmpMetadata = readXmpMetadata;
|
package/dist/xmp.d.cts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/xmp.d.ts
|
|
2
|
+
interface XmpMetadata {
|
|
3
|
+
readonly title?: string;
|
|
4
|
+
readonly author?: string;
|
|
5
|
+
readonly subject?: string;
|
|
6
|
+
readonly keywords?: string[];
|
|
7
|
+
readonly creator?: string;
|
|
8
|
+
readonly producer?: string;
|
|
9
|
+
readonly createdIso?: string;
|
|
10
|
+
readonly modifiedIso?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function readXmpMetadata(packet: string): XmpMetadata;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { XmpMetadata, readXmpMetadata };
|
package/dist/xmp.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/xmp.d.ts
|
|
2
|
+
interface XmpMetadata {
|
|
3
|
+
readonly title?: string;
|
|
4
|
+
readonly author?: string;
|
|
5
|
+
readonly subject?: string;
|
|
6
|
+
readonly keywords?: string[];
|
|
7
|
+
readonly creator?: string;
|
|
8
|
+
readonly producer?: string;
|
|
9
|
+
readonly createdIso?: string;
|
|
10
|
+
readonly modifiedIso?: string;
|
|
11
|
+
}
|
|
12
|
+
declare function readXmpMetadata(packet: string): XmpMetadata;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { XmpMetadata, readXmpMetadata };
|
package/dist/xmp.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
//#region src/xmp.ts
|
|
2
|
+
function readXmpMetadata(packet) {
|
|
3
|
+
return {
|
|
4
|
+
...field(xmpValue(packet, "dc:title"), "title"),
|
|
5
|
+
...field(xmpValue(packet, "dc:creator"), "author"),
|
|
6
|
+
...field(xmpValue(packet, "dc:description"), "subject"),
|
|
7
|
+
...field(xmpValue(packet, "xmp:CreatorTool"), "creator"),
|
|
8
|
+
...field(xmpValue(packet, "pdf:Producer"), "producer"),
|
|
9
|
+
...field(xmpValue(packet, "xmp:CreateDate"), "createdIso"),
|
|
10
|
+
...field(xmpValue(packet, "xmp:ModifyDate"), "modifiedIso"),
|
|
11
|
+
...keywordsOf(packet)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function xmpValue(packet, element) {
|
|
15
|
+
const match = new RegExp(`<${element}(?:\\s[^>]*)?>([\\s\\S]*?)</${element}>`).exec(packet);
|
|
16
|
+
if (match === null) return;
|
|
17
|
+
const inner = match[1] ?? "";
|
|
18
|
+
const items = listItems(inner);
|
|
19
|
+
if (items.length > 0) return items;
|
|
20
|
+
const text = inner.trim();
|
|
21
|
+
return text.length > 0 ? text : void 0;
|
|
22
|
+
}
|
|
23
|
+
function listItems(inner) {
|
|
24
|
+
const items = [];
|
|
25
|
+
const pattern = /<rdf:li(?:\s[^>]*)?>([\s\S]*?)<\/rdf:li>/g;
|
|
26
|
+
let match;
|
|
27
|
+
while ((match = pattern.exec(inner)) !== null) {
|
|
28
|
+
const text = (match[1] ?? "").trim();
|
|
29
|
+
if (text.length > 0) items.push(text);
|
|
30
|
+
}
|
|
31
|
+
return items;
|
|
32
|
+
}
|
|
33
|
+
function field(value, key) {
|
|
34
|
+
if (typeof value === "string") return { [key]: value };
|
|
35
|
+
if (Array.isArray(value) && value.length > 0) return { [key]: value.join(", ") };
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
function keywordsOf(packet) {
|
|
39
|
+
const match = (/* @__PURE__ */ new RegExp("<dc:subject(?:\\s[^>]*)?>([\\s\\S]*?)</dc:subject>")).exec(packet);
|
|
40
|
+
if (match === null) return {};
|
|
41
|
+
const items = listItems(match[1] ?? "");
|
|
42
|
+
return items.length > 0 ? { keywords: items } : {};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { readXmpMetadata };
|
package/dist/xref.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_bytes_reader = require("./bytes/reader.cjs");
|
|
3
|
-
const require_lexer = require("./lexer.cjs");
|
|
4
2
|
const require_objects = require("./objects.cjs");
|
|
3
|
+
const require_bytes_reader = require("./bytes/reader.cjs");
|
|
5
4
|
const require_filters = require("./filters.cjs");
|
|
5
|
+
const require_lexer = require("./lexer.cjs");
|
|
6
6
|
const require_parse = require("./parse.cjs");
|
|
7
7
|
//#region src/xref.ts
|
|
8
8
|
const STARTXREF_BYTES = new TextEncoder().encode("startxref");
|
package/dist/xref.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ByteReader, isAsciiWhitespace } from "./bytes/reader.js";
|
|
2
|
-
import { nextToken } from "./lexer.js";
|
|
3
1
|
import { asArray, asDict, asNumber, dictGet, isName, pdfDict, pdfRef } from "./objects.js";
|
|
2
|
+
import { ByteReader, isAsciiWhitespace } from "./bytes/reader.js";
|
|
4
3
|
import { decodeStream } from "./filters.js";
|
|
4
|
+
import { nextToken } from "./lexer.js";
|
|
5
5
|
import { parseIndirectObject, parseValue } from "./parse.js";
|
|
6
6
|
//#region src/xref.ts
|
|
7
7
|
const STARTXREF_BYTES = new TextEncoder().encode("startxref");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pdf-codec",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Hand-written, dependency-minimal PDF codec: parses arbitrary real-world PDFs and generates new ones, built on its own codec-owned LayoutDocument item model and Zod 4 codecs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"packageManager": "pnpm@11.6.0",
|
|
99
99
|
"dependencies": {
|
|
100
100
|
"byte-codec": "^1.1.13",
|
|
101
|
-
"document-schema.js": "^4.
|
|
101
|
+
"document-schema.js": "^4.8.0",
|
|
102
102
|
"fflate": "^0.8.3",
|
|
103
103
|
"zod": "^4.4.3"
|
|
104
104
|
},
|