pdf-lib
Version:
Library for creating and modifying PDF files in JavaScript
227 lines (226 loc) • 7.95 kB
JavaScript
/* tslint:disable no-bitwise */
import sum from 'lodash/sum';
// export const writeToDebugFile = (data: any, postfix = 0) => {
// // eslint-disable-next-line
// const fs = require('fs');
// fs.writeFileSync(`/Users/user/Desktop/pdf-lib/debug${postfix}`, data);
// };
export var error = function (msg) {
throw new Error(msg);
};
export var digits = function (num) { return String(num).split('').length; };
export var sizeInBytes = function (n) { return Math.ceil(n.toString(2).length / 8); };
/**
* Converts a number into its constituent bytes and returns them as
* a number[].
*
* Returns most significant byte as first element in array. It may be necessary
* to call .reverse() to get the bits in the desired order.
*
* Example:
* bytesFor(0x02A41E) => [ 0b10, 0b10100100, 0b11110 ]
*
* Credit for algorithm: https://stackoverflow.com/a/1936865
*/
export var bytesFor = function (n) {
var bytes = new Uint8Array(sizeInBytes(n));
for (var i = 1; i <= bytes.length; i++) {
bytes[i - 1] = n >> ((bytes.length - i) * 8);
}
return bytes;
};
// Arrays and TypedArrays in JS both have .reverse() methods, which would seem
// to negate the need for this function. However, not all runtimes support this
// method (e.g. React Native), so using this function compensates for that.
export var reverseArray = function (array) {
for (var i = 0; i < Math.floor(array.length / 2); i++) {
var leftIdx = i;
var rightIdx = array.length - i - 1;
var temp = array[i];
array[leftIdx] = array[rightIdx];
array[rightIdx] = temp;
}
return array;
};
export var isInt = function (num) { return num % 1 === 0; };
export var and = function () {
var predicates = [];
for (var _i = 0; _i < arguments.length; _i++) {
predicates[_i] = arguments[_i];
}
return function () {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
return predicates.every(function (predicate) { return predicate.apply(void 0, values); });
};
};
export var or = function () {
var predicates = [];
for (var _i = 0; _i < arguments.length; _i++) {
predicates[_i] = arguments[_i];
}
return function () {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
return predicates.some(function (predicate) { return predicate.apply(void 0, values); });
};
};
export var not = function (predicate) { return function () {
var values = [];
for (var _i = 0; _i < arguments.length; _i++) {
values[_i] = arguments[_i];
}
return !predicate.apply(void 0, values);
}; };
export var toBoolean = function (boolStr) {
if (boolStr === 'true')
return true;
if (boolStr === 'false')
return false;
throw new Error("\"" + boolStr + "\" cannot be converted to a boolean");
};
export var charCode = function (charStr) {
if (charStr.length !== 1) {
throw new Error('"char" must be exactly one character long');
}
return charStr.charCodeAt(0);
};
export var charFromCode = function (code) { return String.fromCharCode(code); };
export var mergeUint8Arrays = function () {
var arrs = [];
for (var _i = 0; _i < arguments.length; _i++) {
arrs[_i] = arguments[_i];
}
var totalLength = sum(arrs.map(function (a) { return a.length; }));
var newArray = new Uint8Array(totalLength);
var offset = 0;
arrs.forEach(function (a) {
newArray.set(a, offset);
offset += a.length;
});
return newArray;
};
export var addStringToBuffer = function (str, buffer) {
for (var i = 0; i < str.length; i += 1) {
buffer[i] = str.charCodeAt(i);
}
return buffer.subarray(str.length);
};
export var charCodes = function (str) {
return str.split('').map(function (c) { return c.charCodeAt(0); });
};
export var typedArrayFor = function (str) { return new Uint8Array(charCodes(str)); };
export var arrayToString = function (arr, startAt, stopAt) {
if (startAt === void 0) { startAt = 0; }
var stopIdx = stopAt === undefined || stopAt >= arr.length ? arr.length : stopAt;
var str = '';
for (var i = startAt; i < stopIdx; i += 1) {
str += charFromCode(arr[i]);
}
return str;
};
export var arrayCharAt = function (arr, idx) {
return String.fromCharCode(arr[idx]);
};
export var trimArray = function (arr) {
var idx = 0;
while (String.fromCharCode(arr[idx]).match(/^[\0\t\n\f\r ]/) &&
idx < arr.length) {
idx += 1;
}
return arr.subarray(idx);
};
var PERCENT_SIGN_CODE = charCode('%');
var NEWLINE_CODE = charCode('\n');
var CARRIAGE_RETURN_CODE = charCode('\r');
var isEOLMarker = function (code) {
return code === NEWLINE_CODE || code === CARRIAGE_RETURN_CODE;
};
export var trimArrayAndRemoveComments = function (arr) {
var strippedComment = true;
var newArray = arr;
while (strippedComment) {
newArray = trimArray(newArray);
if (newArray[0] === PERCENT_SIGN_CODE) {
var idx = 0;
while (!isEOLMarker(newArray[idx]) && idx < newArray.length)
idx += 1;
var foundEOLMarker = isEOLMarker(newArray[idx]);
if (foundEOLMarker)
newArray = newArray.subarray(idx);
strippedComment = foundEOLMarker;
}
else {
strippedComment = false;
}
}
return newArray;
};
export var arraysAreEqual = function (arr1, arr1Start, arr1Stop, arr2, arr2Start, arr2Stop) {
var arr1Length = arr1Stop - arr1Start;
if (arr1Length !== arr2Stop - arr2Start)
return false;
for (var i = 0; i < arr1Length; i += 1) {
if (arr1[arr1Start + i] !== arr2[arr2Start + i])
return false;
}
return true;
};
export var arrayIndexOf = function (arr, targetStr, startFrom) {
if (startFrom === void 0) { startFrom = 0; }
var targetArr = targetStr.split('').map(function (c) { return c.charCodeAt(0); });
var currIdx = startFrom;
while (!arraysAreEqual(arr, currIdx, currIdx + targetStr.length, targetArr, 0, targetArr.length)) {
currIdx += 1;
if (currIdx >= arr.length)
return undefined;
}
return currIdx;
};
export var arrayIndexOneOf = function (arr, targetStrings, startFrom) {
if (startFrom === void 0) { startFrom = 0; }
var targetArrs = targetStrings.map(function (str) { return str.split('').map(charCode); });
var currIdx = startFrom;
var match = null;
while (!match) {
currIdx += 1;
if (currIdx >= arr.length)
return undefined;
match = targetArrs.find(function (target) {
return arraysAreEqual(arr, currIdx, currIdx + target.length, target, 0, target.length);
});
}
return [currIdx, arrayToString(match)];
};
export var arrayIndexOfReverse = function (arr, targetStr, startFrom) {
// validate(
// startFrom,
// and(_.isNumber, not(_.isNaN)),
// `startFrom must be a number, found: "${startFrom}"`,
// );
var targetArr = targetStr.split('').map(function (c) { return c.charCodeAt(0); });
var currIdx = startFrom;
while (!arraysAreEqual(arr, currIdx, currIdx + targetStr.length, targetArr, 0, targetArr.length)) {
currIdx -= 1;
if (currIdx === -1)
return undefined;
}
return currIdx;
};
export var arrayFindIndexOf = function (arr, predicate, startFrom) {
if (startFrom === void 0) { startFrom = 0; }
var currIdx = startFrom;
while (!predicate(arr.subarray(currIdx, currIdx + 1)[0])) {
currIdx += 1;
if (currIdx >= arr.length)
return undefined;
}
return currIdx;
};
export var setCharAt = function (str, idx, newChar) {
return str.substring(0, idx) + newChar + str.substring(idx + 1);
};