Skip to content

make-pdf: fix smartypants corrupting autolinked reference URLs + custom cover extraction#2339

Open
BrendaB24 wants to merge 2 commits into
garrytan:mainfrom
BrendaB24:make-pdf-doi-fix-and-custom-cover
Open

make-pdf: fix smartypants corrupting autolinked reference URLs + custom cover extraction#2339
BrendaB24 wants to merge 2 commits into
garrytan:mainfrom
BrendaB24:make-pdf-doi-fix-and-custom-cover

Conversation

@BrendaB24

Copy link
Copy Markdown

Two make-pdf changes, found while producing publication PDFs with large APA reference lists:

1. fix: smartypants corrupting autolinked reference URLs (ce7834e)
Bare URLs in reference lists were passing through smartypants typographic substitution, which corrupted DOI links (and, when the preservation tokens failed to restore, leaked literal SMARTPANTS_PRESERVED_### text into the rendered page). Autolinked URLs are now protected from substitution end-to-end.

2. feat: extractCustomCover() (9309984)
A document that starts with <section class="ai4ld-cover">...</section> gets that section extracted before title derivation and placed in the same document-assembly slot the built-in --cover template occupies (mutually exclusive with --cover; the TOC lands after it). This enables publisher-branded covers — full-bleed background color, custom typography — that the built-in cover template can't produce. Also fixes two rendering issues found while building one: Chromium dropping background colors in print rendering without -webkit-print-color-adjust: exact, and a cover-text offset issue.

Tests: 74 pass in make-pdf/test/render.test.ts (new coverage: smartypants URL preservation, references wrapping, custom-cover extraction).

🤖 Generated with Claude Code

BrendaB24 and others added 2 commits July 20, 2026 13:00
…URLs

A bare autolinked URL (<a href="X">X</a>, the shape produced whenever
markdown links a plain https:// URL directly) sits with zero whitespace
before its own closing </a> tag. smartypants' URL_RE used a greedy \S+,
which swallowed the adjacent already-carved SMARTPANTS_PRESERVED_N
placeholder (left by the earlier TAG_RE carve pass) into the URL match
itself. That placeholder never got restored — it leaked through as
literal "SMARTPANTS_PRESERVED_N" text glued onto the end of the link,
and the link's real closing tag was lost, leaving the anchor open and
bleeding link styling onto all following text until the next <a> closed
it. Found in DOI reference lists across the AI4LD ebook PDFs.

Fix: exclude the NUL placeholder delimiter from the URL character class
so the match can never cross into an adjacent carved zone.

Also adds APA-style hanging indent for reference lists: a new
wrapReferencesSection() detects an <h1>References</h1> heading and wraps
its content in <div class="references">, scoped print CSS applies the
0.5in hanging indent — this never existed before, reference entries
rendered as plain paragraphs.

4 new regression tests (2 smartypants placeholder-leak cases, 2
references-wrapping cases); narrowed one pre-existing test's assertion
that had banned text-indent globally instead of scoping it to ordinary
body paragraphs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…uilt-in cover

A document starting with <section class="ai4ld-cover">...</section> gets that
section extracted before title derivation and placed in the document-assembly
slot the --cover template would occupy (mutually exclusive with --cover, and
the TOC lands after it). Enables publisher-branded covers (background color,
custom typography) that the built-in cover template can't produce. Written
2026-07-21 alongside ce7834e; committed 2026-07-24 with tests (74 pass).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@trunk-io

trunk-io Bot commented Jul 24, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant