Restore the original Quartz Producer on the CV without duplicating the pitch link.
The script now repairs metadata independently of the annotation, and a repeat run leaves the bytes untouched. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,10 @@ const TEXT_X = 59.6;
|
|||||||
const TEXT_Y = 215.4;
|
const TEXT_Y = 215.4;
|
||||||
const FONT_SIZE = 10.5;
|
const FONT_SIZE = 10.5;
|
||||||
const PADDING = 2;
|
const PADDING = 2;
|
||||||
|
const ORIGINAL_TITLE = 'CV';
|
||||||
|
const ORIGINAL_CREATOR = 'Pages';
|
||||||
|
// Producer from the unmodified Pages/Quartz export of CV.pdf.
|
||||||
|
const ORIGINAL_PRODUCER = 'macOS Version 26.5.2 (Build 25F84) Quartz PDFContext';
|
||||||
|
|
||||||
function asString(value) {
|
function asString(value) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@@ -50,18 +54,26 @@ function pageHasPitchLink(page) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bytes = readFileSync(CV_PATH);
|
function hasOriginalMetadata(pdfDoc) {
|
||||||
const pdfDoc = await PDFDocument.load(bytes);
|
return (
|
||||||
const title = pdfDoc.getTitle();
|
pdfDoc.getTitle() === ORIGINAL_TITLE &&
|
||||||
const author = pdfDoc.getAuthor();
|
pdfDoc.getCreator() === ORIGINAL_CREATOR &&
|
||||||
const creator = pdfDoc.getCreator();
|
pdfDoc.getProducer() === ORIGINAL_PRODUCER
|
||||||
const page = pdfDoc.getPage(0);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (pageHasPitchLink(page)) {
|
const bytes = readFileSync(CV_PATH);
|
||||||
console.log('Pitch link annotation already present; leaving CV.pdf unchanged.');
|
const pdfDoc = await PDFDocument.load(bytes, { updateMetadata: false });
|
||||||
|
const page = pdfDoc.getPage(0);
|
||||||
|
const needsLink = !pageHasPitchLink(page);
|
||||||
|
const needsMetadata = !hasOriginalMetadata(pdfDoc);
|
||||||
|
|
||||||
|
if (!needsLink && !needsMetadata) {
|
||||||
|
console.log('Pitch link and original metadata already present; leaving CV.pdf unchanged.');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsLink) {
|
||||||
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
|
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
|
||||||
const textWidth = font.widthOfTextAtSize(VISIBLE_TEXT, FONT_SIZE);
|
const textWidth = font.widthOfTextAtSize(VISIBLE_TEXT, FONT_SIZE);
|
||||||
|
|
||||||
@@ -91,17 +103,21 @@ const link = pdfDoc.context.register(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
page.node.addAnnot(link);
|
page.node.addAnnot(link);
|
||||||
|
}
|
||||||
|
|
||||||
if (title) {
|
if (needsMetadata) {
|
||||||
pdfDoc.setTitle(title);
|
pdfDoc.setTitle(ORIGINAL_TITLE);
|
||||||
}
|
pdfDoc.setCreator(ORIGINAL_CREATOR);
|
||||||
if (author) {
|
pdfDoc.setProducer(ORIGINAL_PRODUCER);
|
||||||
pdfDoc.setAuthor(author);
|
|
||||||
}
|
|
||||||
if (creator) {
|
|
||||||
pdfDoc.setCreator(creator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const saved = await pdfDoc.save({ useObjectStreams: false });
|
const saved = await pdfDoc.save({ useObjectStreams: false });
|
||||||
writeFileSync(CV_PATH, saved);
|
writeFileSync(CV_PATH, saved);
|
||||||
|
|
||||||
|
if (needsLink && needsMetadata) {
|
||||||
|
console.log('Added the pitch link and restored the original CV.pdf metadata.');
|
||||||
|
} else if (needsLink) {
|
||||||
console.log('Added visible pitch URL and link annotation to page 1 of CV.pdf.');
|
console.log('Added visible pitch URL and link annotation to page 1 of CV.pdf.');
|
||||||
|
} else {
|
||||||
|
console.log('Restored the original Title, Creator and Producer on CV.pdf.');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user