UNPKG

@cantoo/pdf-lib

Version:

Create and modify PDF files with JavaScript

159 lines 6.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findLastMatch = exports.parseDate = exports.breakTextIntoLines = exports.charSplit = exports.charAtIndex = exports.mergeLines = exports.lineSplit = exports.isNewlineChar = exports.newlineChars = exports.escapedNewlineChars = exports.cleanText = exports.escapeRegExp = exports.addRandomSuffix = exports.copyStringIntoBuffer = exports.stringAsByteArray = exports.padStart = exports.charFromHexCode = exports.charFromCode = exports.toHexString = exports.toHexStringOfMinLength = exports.toCodePoint = exports.toCharCode = void 0; const toCharCode = (character) => character.charCodeAt(0); exports.toCharCode = toCharCode; const toCodePoint = (character) => character.codePointAt(0); exports.toCodePoint = toCodePoint; const toHexStringOfMinLength = (num, minLength) => (0, exports.padStart)(num.toString(16), minLength, '0').toUpperCase(); exports.toHexStringOfMinLength = toHexStringOfMinLength; const toHexString = (num) => (0, exports.toHexStringOfMinLength)(num, 2); exports.toHexString = toHexString; const charFromCode = (code) => String.fromCharCode(code); exports.charFromCode = charFromCode; const charFromHexCode = (hex) => (0, exports.charFromCode)(parseInt(hex, 16)); exports.charFromHexCode = charFromHexCode; const padStart = (value, length, padChar) => { let padding = ''; for (let idx = 0, len = length - value.length; idx < len; idx++) { padding += padChar; } return padding + value; }; exports.padStart = padStart; const stringAsByteArray = (str) => { const buffer = new Uint8Array(str.length); (0, exports.copyStringIntoBuffer)(str, buffer, 0); return buffer; }; exports.stringAsByteArray = stringAsByteArray; const copyStringIntoBuffer = (str, buffer, offset) => { const length = str.length; for (let idx = 0; idx < length; idx++) { buffer[offset++] = str.charCodeAt(idx); } return length; }; exports.copyStringIntoBuffer = copyStringIntoBuffer; const addRandomSuffix = (prefix, suffixLength = 4) => `${prefix}-${Math.floor(Math.random() * Math.pow(10, suffixLength))}`; exports.addRandomSuffix = addRandomSuffix; const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); exports.escapeRegExp = escapeRegExp; const cleanText = (text) => text.replace(/\t|\u0085|\u2028|\u2029/g, ' ').replace(/[\b\v]/g, ''); exports.cleanText = cleanText; exports.escapedNewlineChars = ['\\n', '\\f', '\\r', '\\u000B']; exports.newlineChars = ['\n', '\f', '\r', '\u000B']; // eslint-disable-next-line no-control-regex const isNewlineChar = (text) => /^[\n\f\r\u000B]$/.test(text); exports.isNewlineChar = isNewlineChar; // eslint-disable-next-line no-control-regex const lineSplit = (text) => text.split(/[\n\f\r\u000B]/); exports.lineSplit = lineSplit; const mergeLines = (text) => // eslint-disable-next-line no-control-regex text.replace(/[\n\f\r\u000B]/g, ' '); exports.mergeLines = mergeLines; // JavaScript's String.charAt() method doesn work on strings containing UTF-16 // characters (with high and low surrogate pairs), such as 💩 (poo emoji). This // `charAtIndex()` function does. // // Credit: https://github.com/mathiasbynens/String.prototype.at/blob/master/at.js#L14-L48 const charAtIndex = (text, index) => { // Get the first code unit and code unit value const cuFirst = text.charCodeAt(index); let cuSecond; const nextIndex = index + 1; let length = 1; if ( // Check if it's the start of a surrogate pair. cuFirst >= 0xd800 && cuFirst <= 0xdbff && // high surrogate text.length > nextIndex // there is a next code unit ) { cuSecond = text.charCodeAt(nextIndex); if (cuSecond >= 0xdc00 && cuSecond <= 0xdfff) length = 2; // low surrogate } return [text.slice(index, index + length), length]; }; exports.charAtIndex = charAtIndex; const charSplit = (text) => { const chars = []; for (let idx = 0, len = text.length; idx < len;) { const [c, cLen] = (0, exports.charAtIndex)(text, idx); chars.push(c); idx += cLen; } return chars; }; exports.charSplit = charSplit; const buildWordBreakRegex = (wordBreaks) => { const newlineCharUnion = exports.escapedNewlineChars.join('|'); const escapedRules = ['$']; for (let idx = 0, len = wordBreaks.length; idx < len; idx++) { const wordBreak = wordBreaks[idx]; if ((0, exports.isNewlineChar)(wordBreak)) { throw new TypeError(`\`wordBreak\` must not include ${newlineCharUnion}`); } escapedRules.push(wordBreak === '' ? '.' : (0, exports.escapeRegExp)(wordBreak)); } const breakRules = escapedRules.join('|'); return new RegExp(`(${newlineCharUnion})|((.*?)(${breakRules}))`, 'gm'); }; const breakTextIntoLines = (text, wordBreaks, maxWidth, computeWidthOfText) => { const regex = buildWordBreakRegex(wordBreaks); const words = (0, exports.cleanText)(text).match(regex); let currLine = ''; let currWidth = 0; const lines = []; const pushCurrLine = () => { if (currLine !== '') lines.push(currLine); currLine = ''; currWidth = 0; }; for (let idx = 0, len = words.length; idx < len; idx++) { const word = words[idx]; if ((0, exports.isNewlineChar)(word)) { pushCurrLine(); } else { const width = computeWidthOfText(word); if (currWidth + width > maxWidth) pushCurrLine(); currLine += word; currWidth += width; } } pushCurrLine(); return lines; }; exports.breakTextIntoLines = breakTextIntoLines; // See section "7.9.4 Dates" of the PDF specification const dateRegex = /^D:(\d\d\d\d)(\d\d)?(\d\d)?(\d\d)?(\d\d)?(\d\d)?([+\-Z])?(\d\d)?'?(\d\d)?'?$/; const parseDate = (dateStr) => { const match = dateStr.match(dateRegex); if (!match) return undefined; const [, year, month = '01', day = '01', hours = '00', mins = '00', secs = '00', offsetSign = 'Z', offsetHours = '00', offsetMins = '00',] = match; // http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.15 const tzOffset = offsetSign === 'Z' ? 'Z' : `${offsetSign}${offsetHours}:${offsetMins}`; const date = new Date(`${year}-${month}-${day}T${hours}:${mins}:${secs}${tzOffset}`); return date; }; exports.parseDate = parseDate; const findLastMatch = (value, regex) => { var _a; let position = 0; let lastMatch; while (position < value.length) { const match = value.substring(position).match(regex); if (!match) return { match: lastMatch, pos: position }; lastMatch = match; position += ((_a = match.index) !== null && _a !== void 0 ? _a : 0) + match[0].length; } return { match: lastMatch, pos: position }; }; exports.findLastMatch = findLastMatch; //# sourceMappingURL=strings.js.map