UNPKG

pdf-lib

Version:

Library for creating and modifying PDF files in JavaScript

69 lines (68 loc) 3.69 kB
import { PDFDictionary } from '../pdf-objects'; import { PDFTrailer } from '../pdf-structures'; import { arrayIndexOf, arrayToString, charCode, error, trimArrayAndRemoveComments, } from '../../utils'; import parseDict from './parseDict'; import parseNumber from './parseNumber'; /** * Accepts an array of bytes as input. Checks to see if the first characters in the * trimmed input make up a PDF Trailer. * * If so, returns a tuple containing (1) an object representing the parsed PDF * Trailer and (2) a subarray of the input with the characters making up the parsed * trailer removed. The "onParseTrailer" parse handler will be called with the * PDFTrailer object. The "onParseDict" parse handler will be called with the * dictionary of the PDFTrailer, and the "onParseNumber" parse handler will be * called with the "lastXRefOffset" of the PDFTrailer. * * If not, null is returned. */ var parseTrailer = function (input, index, parseHandlers) { if (parseHandlers === void 0) { parseHandlers = {}; } var trimmed = trimArrayAndRemoveComments(input); var trailerRegex = /^trailer[\n|\r| ]*([^]+)startxref[\n|\r| ]+?(\d+)[\n|\r| ]+?%%EOF/; // Find the nearest "%%EOF" of the input and match the regex up to that index var eofIdx = arrayIndexOf(trimmed, '%%EOF'); var result = arrayToString(trimmed, 0, eofIdx + 5).match(trailerRegex); if (!result) return undefined; var fullMatch = result[0], dictStr = result[1], lastXRefOffsetStr = result[2]; // Parse the dictionary string into a PDFDictionary var dictBytes = new Uint8Array(dictStr.split('').map(charCode)); var dict = (parseDict(dictBytes, index, parseHandlers) || error('Failed to parse trailer dictionary'))[0]; // Parse the xref offset string value into a PDFNumber var offsetBytes = new Uint8Array(lastXRefOffsetStr.split('').map(charCode)); var lastXRefOffset = (parseNumber(offsetBytes, parseHandlers) || error('Failed to parse lastXRefOffset of trailer'))[0]; var trailer = PDFTrailer.from(lastXRefOffset.number, dict); if (parseHandlers.onParseTrailer) parseHandlers.onParseTrailer(trailer); return [trailer, trimmed.subarray(fullMatch.length)]; }; /** * Same as "parseTrailer" function, except does not look for the complete trailer. * Specifically, the "trailer" keyword and the trailer's dictionary are not parsed. * * Documents that use Object Streams do not need the "trailer" keyword or the * associated dictionary. (The Object Streams store the trailer's dictionary.) */ var parseTrailerWithoutDict = function (input, index, parseHandlers) { if (parseHandlers === void 0) { parseHandlers = {}; } var trimmed = trimArrayAndRemoveComments(input); var trailerRegex = /^startxref[\n|\r| ]+?(\d+)[\n|\r| ]+?%%EOF/; // Find the nearest "%%EOF" of the input and match the regex up to that index var eofIdx = arrayIndexOf(trimmed, '%%EOF'); var result = arrayToString(trimmed, 0, eofIdx + 5).match(trailerRegex); if (!result) return undefined; var fullMatch = result[0], lastXRefOffsetStr = result[1]; // Parse the xref offset string value into a PDFNumber var offsetBytes = new Uint8Array(lastXRefOffsetStr.split('').map(charCode)); var lastXRefOffset = (parseNumber(offsetBytes, parseHandlers) || error('Failed to parse lastXRefOffset of trailer'))[0]; var trailer = PDFTrailer.from(lastXRefOffset.number, PDFDictionary.from(new Map(), index)); if (parseHandlers.onParseTrailer) parseHandlers.onParseTrailer(trailer); return [trailer, trimmed.subarray(fullMatch.length)]; }; export { parseTrailer, parseTrailerWithoutDict };