diff --git a/CV.pdf b/CV.pdf index 2b7a238..5f7429c 100644 Binary files a/CV.pdf and b/CV.pdf differ diff --git a/scripts/add-cv-pitch-link.mjs b/scripts/add-cv-pitch-link.mjs index aee8866..6ad17b9 100644 --- a/scripts/add-cv-pitch-link.mjs +++ b/scripts/add-cv-pitch-link.mjs @@ -11,6 +11,10 @@ const TEXT_X = 59.6; const TEXT_Y = 215.4; const FONT_SIZE = 10.5; 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) { if (!value) { @@ -50,58 +54,70 @@ function pageHasPitchLink(page) { return false; } -const bytes = readFileSync(CV_PATH); -const pdfDoc = await PDFDocument.load(bytes); -const title = pdfDoc.getTitle(); -const author = pdfDoc.getAuthor(); -const creator = pdfDoc.getCreator(); -const page = pdfDoc.getPage(0); +function hasOriginalMetadata(pdfDoc) { + return ( + pdfDoc.getTitle() === ORIGINAL_TITLE && + pdfDoc.getCreator() === ORIGINAL_CREATOR && + pdfDoc.getProducer() === ORIGINAL_PRODUCER + ); +} -if (pageHasPitchLink(page)) { - console.log('Pitch link annotation already present; leaving CV.pdf unchanged.'); +const bytes = readFileSync(CV_PATH); +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); } -const font = await pdfDoc.embedFont(StandardFonts.Helvetica); -const textWidth = font.widthOfTextAtSize(VISIBLE_TEXT, FONT_SIZE); +if (needsLink) { + const font = await pdfDoc.embedFont(StandardFonts.Helvetica); + const textWidth = font.widthOfTextAtSize(VISIBLE_TEXT, FONT_SIZE); -page.drawText(VISIBLE_TEXT, { - x: TEXT_X, - y: TEXT_Y, - size: FONT_SIZE, - font, - color: rgb(54 / 255, 125 / 255, 162 / 255), -}); + page.drawText(VISIBLE_TEXT, { + x: TEXT_X, + y: TEXT_Y, + size: FONT_SIZE, + font, + color: rgb(54 / 255, 125 / 255, 162 / 255), + }); -const link = pdfDoc.context.register( - pdfDoc.context.obj({ - Type: 'Annot', - Subtype: 'Link', - Rect: [ - TEXT_X - PADDING, - TEXT_Y - PADDING, - TEXT_X + textWidth + PADDING, - TEXT_Y + FONT_SIZE + PADDING, - ], - Border: [0, 0, 0], - A: { - S: 'URI', - URI: PDFString.of(PITCH_URI), - }, - }), -); -page.node.addAnnot(link); - -if (title) { - pdfDoc.setTitle(title); + const link = pdfDoc.context.register( + pdfDoc.context.obj({ + Type: 'Annot', + Subtype: 'Link', + Rect: [ + TEXT_X - PADDING, + TEXT_Y - PADDING, + TEXT_X + textWidth + PADDING, + TEXT_Y + FONT_SIZE + PADDING, + ], + Border: [0, 0, 0], + A: { + S: 'URI', + URI: PDFString.of(PITCH_URI), + }, + }), + ); + page.node.addAnnot(link); } -if (author) { - pdfDoc.setAuthor(author); -} -if (creator) { - pdfDoc.setCreator(creator); + +if (needsMetadata) { + pdfDoc.setTitle(ORIGINAL_TITLE); + pdfDoc.setCreator(ORIGINAL_CREATOR); + pdfDoc.setProducer(ORIGINAL_PRODUCER); } const saved = await pdfDoc.save({ useObjectStreams: false }); writeFileSync(CV_PATH, saved); -console.log('Added visible pitch URL and link annotation to page 1 of CV.pdf.'); + +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.'); +} else { + console.log('Restored the original Title, Creator and Producer on CV.pdf.'); +}