110 lines
3.7 KiB
TypeScript
110 lines
3.7 KiB
TypeScript
import {
|
|
PDFAcroField,
|
|
PDFHexString,
|
|
PDFName,
|
|
PDFString,
|
|
toHexString,
|
|
} from "pdf-lib";
|
|
import { loadPdfForm, savePdf } from "util/saveLoadPdf.ts";
|
|
import { PDFDocument } from "pdf-lib";
|
|
import { call, callWithArgPrompt } from "util/call.ts";
|
|
|
|
// const thing = PDFAcroField.prototype.getFullyQualifiedName;
|
|
// PDFAcroField.prototype.getFullyQualifiedName = function () {
|
|
// const name = thing.call(this)
|
|
// // if (name?.includes('langauge'))
|
|
// console.log(name)
|
|
// return name;
|
|
// }
|
|
|
|
// const thing = PDFHexString.prototype.copyBytesInto
|
|
// PDFHexString.prototype.copyBytesInto = function (buffer: Uint8Array, offset: number) {
|
|
// console.log((this as any).value)
|
|
|
|
// const result = thing.call(this, buffer, offset)
|
|
// return result;
|
|
// }
|
|
|
|
async function renameFields(
|
|
path: string,
|
|
pattern: string | RegExp,
|
|
change: string,
|
|
) {
|
|
if (typeof pattern === "string") pattern = new RegExp(pattern);
|
|
const form = await loadPdfForm(path);
|
|
const fields = form.getFields();
|
|
let changesMade = false;
|
|
for (const field of fields) {
|
|
const name = field.getName();
|
|
if (pattern.test(name)) {
|
|
console.log(name + " %cfound", "color: red");
|
|
const segments = name.split(".");
|
|
const matchingSegments = segments.filter((s) => pattern.test(s));
|
|
let cField: PDFAcroField | undefined = field.acroField;
|
|
while (cField) {
|
|
if (
|
|
cField.getPartialName() &&
|
|
matchingSegments.includes(cField.getPartialName()!)
|
|
) {
|
|
const mName = cField.getPartialName()?.replace(pattern, change);
|
|
if (mName) {
|
|
changesMade = true;
|
|
cField.dict.set(PDFName.of("T"), PDFString.of(mName));
|
|
// console.log(cField.getPartialName())
|
|
}
|
|
}
|
|
cField = cField.getParent();
|
|
// console.log(cField?.getPartialName())
|
|
}
|
|
console.log(field.getName());
|
|
// const newName = name.replace(pattern, change);
|
|
// console.log("Change to: %c" + newName, "color: yellow");
|
|
// if (confirm('Ok?')) {
|
|
// let parent = field.acroField.getParent();
|
|
// field.acroField.setPartialName(segments.pop())
|
|
// while (parent && segments.length) {
|
|
// console.log(parent.getPartialName())
|
|
// parent.setPartialName(segments.pop())
|
|
// parent = parent.getParent();
|
|
// }
|
|
// changesMade = true;
|
|
// console.log(field.getName())
|
|
// // dict.set(PDFName.of("T"), PDFHexString.fromText(newName))
|
|
// console.log("%cDone!", "color: lime")
|
|
// }
|
|
// break;
|
|
}
|
|
}
|
|
if (changesMade) {
|
|
savePdf(form.doc, path);
|
|
}
|
|
}
|
|
|
|
class RenameFields implements ITool {
|
|
name = "renamefields";
|
|
description = "Renames fields in a PDF form";
|
|
help() {
|
|
console.log("Usage: renamefields <pdfPath> <pattern> <change>");
|
|
}
|
|
async run(pdfPath: string = "", pattern: string = "", change: string = "") {
|
|
await callWithArgPrompt(renameFields, [
|
|
["Please provide path to PDF:", (p) => !!p && p.endsWith(".pdf")],
|
|
"Please provide search string:",
|
|
"Please provide requested change:",
|
|
], [pdfPath, pattern, change]);
|
|
}
|
|
}
|
|
export default new RenameFields();
|
|
|
|
if (import.meta.main) {
|
|
// await call(renameFields)
|
|
// while (!path || !path.endsWith('.pdf')) path = prompt("Please provide path to PDF:") || '';
|
|
// while (!pattern) pattern = prompt("Please provide search string:") || '';
|
|
// while (!change) change = prompt("Please provide requested change:") || '';
|
|
await callWithArgPrompt(renameFields, [
|
|
["Please provide path to PDF:", (p) => !!p && p.endsWith(".pdf")],
|
|
"Please provide search string:",
|
|
"Please provide requested change:",
|
|
]);
|
|
}
|