pdf-lib
Version:
Library for creating and modifying PDF files in JavaScript
69 lines (68 loc) • 3.69 kB
JavaScript
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 };