Style PDF cover and TOC links

This commit is contained in:
2026-06-15 13:49:31 -05:00
parent b51a4c46ce
commit ab280daf63
2 changed files with 8 additions and 2 deletions
+3 -2
View File
@@ -232,7 +232,8 @@ function exportPdf(ast, outDir, template = {}) {
pdf.addPage();
if (tpl.includeCover) {
y = M + usableH * 0.18;
// Keep the cover title near the top edge instead of vertically centering it.
y = M;
writeLines(ast.guide.title, { size: 28, font: 'F2' });
y += 10;
pdf.rect(M, y, usableW, 3, { fill: tpl.accentColor });
@@ -267,7 +268,7 @@ function exportPdf(ast, outDir, template = {}) {
tocTargets.set(step.stepId, target);
for (const line of pdf.wrapText(`${step.number}. ${step.title || 'Untitled step'}`, tocSize, usableW - indent, 'F1')) {
ensure(lineH);
pdf.text(line, M + indent, y, { size: tocSize });
pdf.text(line, M + indent, y, { size: tocSize, color: tpl.accentColor });
pdf.linkRect(M + indent, y, usableW - indent, lineH, target);
y += lineH;
}
+5
View File
@@ -127,8 +127,12 @@ test('PDF Contents: each entry is a clickable link to its step\'s page', (t) =>
const bookmarks = bookmarkPages(buf); // one per step, in document order
const tocTargets = tocLinkTargets(buf, 1); // page 0 = cover, page 1 = Contents
const tocPage = pageContents(buf)[1];
const blueTocLines = [...tocPage.matchAll(/BT \/F1 10\.5 Tf 0\.145 0\.388 0\.922 rg 1 0 0 1 [\d.]+ [\d.]+ Tm \(([^)]*)\) Tj ET/g)]
.map((m) => m[1]);
assert.deepEqual(tocTargets, bookmarks.map((b) => b.pageIndex));
assert.deepEqual(blueTocLines, ast.steps.map((step) => `${step.number}. ${step.title || 'Untitled step'}`));
});
test('PDF renders under Ghostscript end-to-end', { skip: !hasTool('gs') }, (t) => {
@@ -169,6 +173,7 @@ test('PDF cover: title in big text above the accent rule, guide metadata below i
const titleY = Number(/\/F2 28 Tf [\d.]+ [\d.]+ [\d.]+ rg 1 0 0 1 [\d.]+ ([\d.]+) Tm \(Configure AcmeSync backups\) Tj/.exec(cover)[1]);
const ruleY = Number(/[\d.]+ [\d.]+ [\d.]+ rg ([\d.]+) ([\d.]+) [\d.]+ 3\.00 re f/.exec(cover)[2]);
const authorY = Number(/\/F1 11 Tf [\d.]+ [\d.]+ [\d.]+ rg 1 0 0 1 [\d.]+ ([\d.]+) Tm \(Author: Jane Doe\) Tj/.exec(cover)[1]);
assert.ok(titleY > 740, 'title starts near the top edge');
assert.ok(titleY > ruleY, 'title sits above the accent rule');
assert.ok(ruleY > authorY, 'metadata sits below the accent rule');
});