Skip to content

preview: port rendered-HTML change highlighting from ucdavis/win #761

Description

@d-morrison

Child of #256. Depends on #760 (the changed-chapter substrate). See the reversal comment.

What to port

ucdavis/win/.github/scripts/highlight-html-changes.py (16 KB — the largest of the four). It compares the PR's rendered HTML against the published version on gh-pages and injects highlighting for changed sections, so a reviewer sees what changed in the output rather than in the source.

That distinction is the whole value. A Quarto source diff shows markdown and code; a reviewer of a book or manuscript wants to see the rendered prose that actually changed.

Proposed input on preview: highlight-changes (boolean, default false).

The hard part is the diff granularity, not the plumbing

HTMLDiffer works over rendered HTML with difflib. Two failure modes decide whether this is useful or unusable, and neither is visible from the code:

  • Over-reporting. Quarto injects build-varying content (timestamps, ids, search indices). If those register as changes, every page highlights and the feature is noise. preview: port changed-chapter detection from ucdavis/win as the shared substrate for rendered-output diffing #760's substrate has the same exposure and should settle it first.
  • Under-reporting / corruption. Injecting markup into rendered HTML can break the page — an unclosed tag, or highlighting inserted inside an attribute rather than between elements. escape/unescape are imported, so the source is aware of this; verify it rather than trusting it.

Validate against a real two-render comparison of an actual Quarto book before accepting the port, not a synthetic fixture alone. A synthetic fixture cannot exhibit the injected-build-metadata problem, which is the one most likely to sink it.

Rewrite, not copy

3 check=False and 2 broad except blocks in this file. The fetch_base_html fallback path silently returns None when the base file is absent (highlight-html-changes.py:36-41), which conflates "this page is new in the PR" with "the comparison failed". Those are different facts and only the first should render as an unhighlighted new page; the second is a skip with a reason.

Tests

Generate fixtures at runtime. Keep, at minimum:

  • A page with no change → no highlighting injected, and the output is byte-identical to the input.
  • A page with a changed paragraph → highlighting present, and the page still parses.
  • A page absent from gh-pages → treated as new, not as an error, and distinguishable in the output from a comparison failure.
  • A page differing only in build metadata → no highlighting.

That last one is the keep-if-trimmed case, for the same reason as in #760.

Ordering

After #760 — this consumes its changed-chapter list, and building both at once means debugging two unproven layers against each other.


Posted by Claude Code (AI agent) --- not written by a human.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions