UNPKG

pdf-lib

Version:

Library for creating and modifying PDF files in JavaScript

76 lines (75 loc) 3.61 kB
import { PDFDictionary, PDFName } from '../pdf-objects'; import { PDFCatalog, PDFLinearizationParams, PDFPage, PDFPageTree, } from '../pdf-structures'; import { arrayToString, error, trimArrayAndRemoveComments } from '../../utils'; import { isIdentity, validate } from '../../utils/validate'; import parseArray from './parseArray'; import parseBool from './parseBool'; import parseHexString from './parseHexString'; import parseIndirectRef from './parseIndirectRef'; import parseName from './parseName'; import parseNull from './parseNull'; import parseNumber from './parseNumber'; import parseString from './parseString'; // prettier-ignore var typeDict = function (dict) { if (dict.getMaybe('Linearized')) return PDFLinearizationParams.fromDict(dict); switch (dict.getMaybe('Type')) { case PDFName.from('Catalog'): return PDFCatalog.fromDict(dict); case PDFName.from('Pages'): return PDFPageTree.fromDict(dict); case PDFName.from('Page'): return PDFPage.fromDict(dict); default: return dict; } }; /** * Accepts an array of bytes as input. Checks to see if the first characters in * the trimmed input make up a PDF Dictionary. * * If so, returns a tuple containing (1) an object representing the parsed * PDFDictionary and (2) a subarray of the input with the characters making up * the parsed dictionary removed. The "onParseDict" parse handler will also be * called with the PDFDictionary object. * * If not, null is returned. * * Note that the entries of the PDF Dictionary are recursively parsed, so the * appropriate parse handlers will be called when each entry of the dictionary * is parsed. The returned PDFDictionary's keys will be PDFName objects, and its * values will be PDFObjects. */ var parseDict = function (input, index, parseHandlers) { if (parseHandlers === void 0) { parseHandlers = {}; } var trimmed = trimArrayAndRemoveComments(input); if (arrayToString(trimmed, 0, 2) !== '<<') return undefined; var pdfDict = PDFDictionary.from(new Map(), index); // Recursively parse each entry in the dictionary var remainder = trimArrayAndRemoveComments(trimmed.subarray(2)); while (arrayToString(trimArrayAndRemoveComments(remainder), 0, 2) !== '>>') { // Parse the key for this entry var _a = parseName(remainder) || error('Failed to parse dictionary key'), key = _a[0], r1 = _a[1]; remainder = r1; // Parse the value for this entry var _b = parseName(remainder, parseHandlers) || parseDict(remainder, index, parseHandlers) || parseArray(remainder, index, parseHandlers) || parseString(remainder, parseHandlers) || parseIndirectRef(remainder, parseHandlers) || parseNumber(remainder, parseHandlers) || parseHexString(remainder, parseHandlers) || parseBool(remainder, parseHandlers) || parseNull(remainder, parseHandlers) || error('Failed to parse dictionary value'), pdfObject = _b[0], r2 = _b[1]; pdfDict.set(key, pdfObject); remainder = r2; } var remainderTrim = trimArrayAndRemoveComments(remainder); // Make sure the brackets are paired validate(arrayToString(remainderTrim, 0, 2), isIdentity('>>'), 'Mismatched brackets!'); remainder = trimArrayAndRemoveComments(remainderTrim.subarray(2)); // Remove ending '>>' pair var typedDict = typeDict(pdfDict); if (parseHandlers.onParseDict) parseHandlers.onParseDict(typedDict); return [typedDict, remainder]; }; export default parseDict;