Skip to content

Fix misplaced anchors for remark and proof-like divs - #160

Merged
d-morrison merged 2 commits into
mainfrom
fix/remark-anchors
Oct 7, 2026
Merged

d-morrison merged 2 commits into
mainfrom
fix/remark-anchors

Conversation

@d-morrison

@d-morrison d-morrison commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #159

Summary

In Quarto, theorem environments render their headings with .theorem-title while proof-like environments (proof, remark, solution) render their headings with .proof-title. Previously, div-anchors.js only queried .theorem-title when moving AnchorJS anchor links inline, causing remark and other proof-like divs to leave the anchor link at the bottom of the div rather than beside the heading.

Changes

  1. Title selector: Update moveTheoremDivAnchorsInline to select .theorem-title, .proof-title.
  2. Whitespace handling: Quarto appends ". " inside .proof-title and immediately follows with the body text without leading whitespace. We trim trailing whitespace from the title's last text node before appending the non-breaking space separator (\u00A0) and anchor link, and ensure a trailing space separates the anchor from subsequent body content.
  3. Class and ID aliases:
    • Added "rem" and "sol" aliases to theorem_div_classes and theoremLikeClasses.
    • Added crossref ID prefix matching (rem-, sol-, thm-, etc.) to is_theorem_div in both div-anchors.lua and div-anchors.js.

Verification

  • Rendered chapters/theorem-examples.qmd to HTML.
  • Verified DOM with headless Chrome and BeautifulSoup: anchor links for rem-convergence and sol-integration are placed directly inline after the heading inside .proof-title, with no misplaced link at the bottom of the div.
  • Verified theorems (thm-mean-value, def-derivative, etc.) continue to render correctly with inline anchors.
  • Ran devtools::check(), lintr::lint_dir(), and package spellcheck — all passed cleanly.

morri313 added 2 commits October 6, 2026 16:50
Quarto theorem environments render titles with class .theorem-title,
while proof-like environments (proof, remark, solution) render titles
with class .proof-title. Previously, div-anchors.js only queried
.theorem-title when relocating AnchorJS anchor links inline, causing
remark and other proof-like divs to leave the anchor link at the bottom
of the div rather than next to the title.

- Support .proof-title alongside .theorem-title in div-anchors.js
- Trim trailing whitespace from .proof-title (which ends with '. ')
  so the non-breaking separator and anchor stay attached to the title,
  and ensure a space separates the anchor from subsequent body content
- Add 'rem' and 'sol' aliases and crossref ID prefix matching (rem-,
  thm-, def-, etc.) to is_theorem_div in both Lua and JS
@d-morrison
d-morrison marked this pull request as ready for review October 6, 2026 23:56
Copilot AI balanced review requested due to automatic review settings October 6, 2026 23:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished review — View run


Review: PR #160 — Fix misplaced anchors for remark and proof-like divs

Scope: Only _extensions/div-anchors/div-anchors.js and _extensions/div-anchors/div-anchors.lua are touched — tightly scoped to issue #159, consistent with the "keep PRs scoped" guidance in CLAUDE.md. chapters/theorem-examples.qmd (used for manual verification per the PR description) is unchanged, and no _site/_freeze artifacts are included.

Verification performed

I don't have quarto/pandoc/R in this sandbox, so I couldn't render the site directly. Instead I pulled the actual upstream quarto-cli source for theorem.lua and proof.lua (src/resources/filters/customnodes/{theorem,proof}.lua on quarto-dev/quarto-cli@main) to confirm the real DOM shape Quarto emits, then reconstructed that exact shape in a scratch jsdom harness (under /tmp, not committed) and ran the new trimming logic verbatim:

  • For .proof-title: Quarto appends the span as the first inline child of the body paragraph, ending with a bare ". " text node, immediately followed (no leading space) by the paragraph's original text as the title span's nextSibling. Running the PR's trim/insert logic against this exact structure correctly produces Remark 1 (...).<nbsp><anchor> The limit in … — the anchor lands inline and a space correctly separates it from the following prose. This confirms the fix in div-anchors.js:126-139 works as intended.
  • For .theorem-title: Quarto's renderer inserts the separator as a sibling pandoc.Space() node rather than trailing whitespace inside the span, so the new trim branch correctly never fires for theorem titles (no trailing whitespace found), preserving prior passing behavior — i.e., this change is backward-compatible with the existing theorem-title path.
  • theoremLikeClasses/theorem_div_classes stay in sync between the .js and .lua copies (both gained "rem"/"sol"), and theoremLikePrefixes/theorem_id_prefixes list the same 10 prefixes in the same order in both files — good parity between the JS and Lua implementations, which matters since they must agree on what counts as theorem-like.
  • Lua id_is_theorem_like correctly guards nil identifiers and uses 1-indexed sub prefix comparison correctly.

Observations (non-blocking)

  • ID-prefix heuristic's necessity is not fully demonstrated. Tracing quarto-cli's theorem.lua, the built-in renderer unconditionally inserts class="theorem" plus the full env name (lemma, corollary, definition, …) on any div it recognizes as a Theorem node — and theoremLikeClasses/theorem_div_classes already contain those full env names, so class-based matching alone already covers thm-/lem-/etc. in the un-wrapped rendering path. Because this repo wraps every theorem/proof type in a callout via sun123zxy/callouty-theorem (_quarto-website.yml:67-130), the outer div the user sees may instead carry callout classes, which is plausibly why the author added the ID-prefix fallback. I can't confirm from the diff alone whether the prefix check is load-bearing or just defensive redundancy, since I can't render the site to check the final callout DOM — the PR description's claim of having verified this with headless Chrome/BeautifulSoup is the best evidence available and I have no basis to contradict it. Worth a quick sanity check by the author (temporarily removing the prefix branch and re-rendering) only if there's any doubt — not a merge blocker.
  • _extensions/div-anchors/_extension.yml keeps version: 1.0.0 unchanged. The repo has no established convention requiring a version bump for extension edits (confirmed via git log on that file and no NEWS/CHANGELOG), so this isn't a violation of anything documented — just flagging for awareness in case the maintainer wants one.
  • The PR description says prefix matching was "added to is_theorem_div... in both div-anchors.lua and div-anchors.js" — the JS function is actually named isTheoremLikeDiv (camelCase, matching JS convention), not is_theorem_div. Purely a wording nit in the description, not a code issue.
  • New ID-prefix matching is scoped to 10 specific 3-4 letter dash-suffixed prefixes (thm-, lem-, …, rem-, sol-), mirroring Quarto's own crossref refType convention, so collision risk with unrelated div IDs is the same risk Quarto itself already accepts — not a new concern introduced by this PR.

CLAUDE.md / lab-manual compliance

No R, .qmd, bibliography, or build-artifact changes — the R-specific (lintr, tidyverse, function-length) and Quarto-prose sections of the lab manual don't apply here. No new dependencies introduced. Comment added at div-anchors.js:126-128 explains non-obvious Quarto whitespace behavior (the "why"), consistent with good comment practice rather than restating the "what."

I found no correctness bugs, no CLAUDE.md violations, and no hallucinated APIs/symbols — callouty-theorem and custom-callout are real vendored extensions present in _extensions/, and the Quarto rendering behavior described in the PR matches the actual upstream quarto-cli source.

Verdict

Ready for merge — no blocking findings; one non-blocking observation about unverified necessity of the ID-prefix fallback (not a correctness issue, just an open question for the author's own confidence).

Structured Review Data (JSON)
{
  "schema_version": "1.1",
  "reviewer": "claude",
  "commit_sha": "71bb81772d081b9d2bf725d44b3d6ce9a681201d",
  "verdict": "CLEAN",
  "findings": [],
  "detailed_assessment": "Reconstructed quarto-cli's real proof-title DOM shape in a jsdom harness and confirmed the trim-and-reinsert logic in div-anchors.js correctly places the anchor inline without breaking the pre-existing theorem-title path.",
  "holistic_assessment": "Scope stays limited to the two div-anchors extension files for issue 159, parity between the JS and Lua class/prefix lists is maintained, and no regression risk was found for downstream template consumers."
}

Reviewed commit: 71bb817

@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

💰 Cost: $1.2615 (review) — run

@d-morrison

Copy link
Copy Markdown
Collaborator Author

Done with my local session — unclaiming.

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

@d-morrison
d-morrison merged commit aa7b773 into main Oct 7, 2026
22 checks passed
@d-morrison
d-morrison deleted the fix/remark-anchors branch October 7, 2026 00:33
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-06 17:34 PDT

dem-extra1 pushed a commit to Morrison-Lab/mds that referenced this pull request Oct 7, 2026
Port div-anchors extension fix from Morrison-Lab/qwt#160 (Morrison-Lab/qwt#159).

Quarto theorem environments render titles with class .theorem-title,
while proof-like environments (proof, remark, solution) render titles
with class .proof-title. Previously, div-anchors.js only queried
.theorem-title when relocating AnchorJS anchor links inline, causing
remark and other proof-like divs to leave the anchor link at the bottom
of the div rather than next to the title.

- Support .proof-title alongside .theorem-title in div-anchors.js
- Trim trailing whitespace from .proof-title (which ends with '. ')
  so the non-breaking separator and anchor stay attached to the title,
  and ensure a space separates the anchor from subsequent body content
- Add 'rem' and 'sol' aliases and crossref ID prefix matching (rem-,
  thm-, def-, etc.) to is_theorem_div in both Lua and JS

Co-authored-by: morri313 <morri313@cf463-02.cs.wwu.edu>
d-morrison added a commit to Morrison-Lab/pds that referenced this pull request Oct 7, 2026
Port div-anchors extension fix from Morrison-Lab/qwt#160 (Morrison-Lab/qwt#159).

Quarto theorem environments render titles with class .theorem-title,
while proof-like environments (proof, remark, solution) render titles
with class .proof-title. Previously, div-anchors.js only queried
.theorem-title when relocating AnchorJS anchor links inline, causing
remark and other proof-like divs to leave the anchor link at the bottom
of the div rather than next to the title.

- Support .proof-title alongside .theorem-title in div-anchors.js
- Trim trailing whitespace from .proof-title (which ends with '. ')
  so the non-breaking separator and anchor stay attached to the title,
  and ensure a space separates the anchor from subsequent body content
- Add 'rem' and 'sol' aliases and crossref ID prefix matching (rem-,
  thm-, def-, etc.) to is_theorem_div in both Lua and JS

Co-authored-by: morri313 <morri313@cf463-02.cs.wwu.edu>
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.

anchors for remark divs are misplaced

2 participants