Skip to content

Add citation/reference hover preview#5611

Open
koppor wants to merge 5 commits intosumatrapdfreader:masterfrom
koppor:add-reference-hovering
Open

Add citation/reference hover preview#5611
koppor wants to merge 5 commits intosumatrapdfreader:masterfrom
koppor:add-reference-hovering

Conversation

@koppor
Copy link
Copy Markdown

@koppor koppor commented May 6, 2026

Unfortunately it's too complicated. I don't see us implementing that.

#128 (comment)

11 years later, Claude can help.

This update is entirely written by claude - "only" driven by me in a code-and-fix mannger

Screenshot:

grafik

Summary

Hovering an internal-document link (citation, figure reference, footnote marker, etc.) shows a small popup rendering the destination region of the target page — so a [1] citation, a "Figure 2.3" reference, or a footnote can be inspected without leaving the current page. Inspired by PDFRefPreview.

Fixes #128
Fixes #4221

Demo

Hover any in-text reference for ~300 ms. The popup shows just the relevant entry / figure / footnote, cropped to its actual text box. Works for both 1-column and 2-column layouts, hanging-indent and numeric [N] bibliographies, and figure references (where the strip falls back to a generous region around the anchor).

Implementation

Detection (src/Canvas.cpp + src/RefHover.cpp):

  • IsCitationLink accepts any internal kindPageElementDest link.
  • DetectEntryBox does a per-glyph text+coords scan starting at destY, with several boundary signals: [N at the entry's first-line X, indent change back to that X, an X that matches neither first-line nor continuation X, vertical paragraph break, single-line-entry pattern, and column wrap.
  • Falls back to a fixed strip when text scan finds nothing near destY, and to a taller strip when the detected box is suspiciously small (figure / diagram fragment).
  • The detected region is rendered via engine->RenderPage and blitted into a popup, letterboxed to fit max bounds.

Engine API change (would appreciate a quick eyeball on this part):

  • New virtual IPageDestination::GetDestPoint2() in src/EngineBase.h, default returns GetRect2() (so existing implementations are unaffected).
  • New helper PageDestGetDestPoint().
  • PageDestinationMupdf (in src/EngineMupdf.cpp) now stores destX/destY resolved via fz_resolve_link at construction; previously the resolved (x, y) from ResolveLink was discarded after the page number was extracted.

Plumbing:

  • New files src/RefHover.cpp / src/RefHover.h.
  • MainWindow gets a refHover member, destroyed in dtor.
  • Canvas::OnMouseMove schedules / hides the popup; OnTimer renders.
  • Both vs2022/*.vcxproj and *.vcxproj.filters updated.

Setting: EnableCitationHover advanced setting (default true, version 3.7), defined in cmd/gen-settings.ts. Generated files updated.

Test plan

  • bun ./cmd/build.ts clean — 0 warnings, 0 errors.
  • 2-column academic paper, numeric [N] citations: tight popup of the right column entry only.
  • 1-column paper, author-year hanging-indent bibliography (Bischoff and Küchlin, 2017 → bib entry Daniel Bischoff and Wolfgang Küchlin. Adapting…): single entry, correctly cropped.
  • Last bibliography entry (no [N] follows): stops before author bios / footers thanks to the indent-change signal.
  • Footnote markers (single-line stacked footnotes ¹url \n ²url \n …): just the hovered footnote.
  • Figure / table reference (Figure 2.2): falls back to a generous strip around the anchor so the diagram is visible.
  • Toggle EnableCitationHover to false: existing popup is hidden, no further popups scheduled.

Notes

  • Test PDF used during development: tests-manual/extract-references/paper1/main.pdf from the JabRef repo. Not included in this PR.
  • The RefHover.cpp text-scan boundary heuristics are defensive (multiple signals), but they're heuristics — happy to iterate based on PDFs that don't crop cleanly.

🤖 Generated with Claude Code

Hovering an internal-document link (citation, figure, footnote, etc.)
now shows a small popup that renders the destination region of the
target page, so the bibliography entry / figure / footnote is visible
without leaving the current page. Inspired by PDFRefPreview.

Detection:
- IsCitationLink: any internal kindPageElementDest link.
- DetectEntryBox: per-glyph text+coords scan from the destination
  anchor, ending at one of: "[N" at the entry's first-line X, indent
  change back to that X, an X that matches neither first-line nor
  continuation X, vertical paragraph break, single-line-entry pattern,
  or column wrap.
- Falls back to a fixed strip when text-based detection finds nothing
  near destY, and to a taller strip when the detected box is too small
  (figure / diagram fragment).
- Result is rendered via engine->RenderPage and blitted into a yellow
  popup, letterboxed to fit max bounds.

Engine API:
- IPageDestination::GetDestPoint2() (default returns GetRect2()).
- PageDestGetDestPoint() helper.
- PageDestinationMupdf caches resolved (destX, destY) from
  fz_resolve_link at construction.

Plumbing:
- New RefHover.cpp/.h.
- MainWindow gets a refHover member, destroyed in dtor.
- Canvas OnMouseMove schedules / hides the popup; OnTimer renders.

Configurable via the EnableCitationHover advanced setting (default
true).

fixes sumatrapdfreader#128
fixes sumatrapdfreader#4221

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@GitHubRulesOK
Copy link
Copy Markdown
Collaborator

Looks very usefull do you have a compiled exe for me to play with while testing some other files

@koppor
Copy link
Copy Markdown
Author

koppor commented May 6, 2026

Looks very usefull

Thank you! I was searching for that feature for a long time - but none of the existing apps convinced me. Sioyek kind of looked nice, but it has other issues (e.g., ahrm/sioyek#1350)

do you have a compiled exe for me to play with while testing some other files

Sure! I put it at https://builds.jabref.org/main/SumatraPDF-dll.exe .

@GitHubRulesOK
Copy link
Copy Markdown
Collaborator

GitHubRulesOK commented May 6, 2026

Thanks so not your fault the first file I opened is another new oddity where fonts are big and thus window content is limited which begs the question what do other apps have such as is there a zoomin out function
image
image

Initial render uses page zoom so popup text height matches visible page
text. Wheel on the citation link re-renders a region sized to fill the
popup at the new zoom (anchored at detection top-left, clamped to page).
Wheeling out brings in new page content; wheeling in crops to detail.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@koppor
Copy link
Copy Markdown
Author

koppor commented May 7, 2026

Good question — I just added mouse-wheel zoom for the popup. Hover a citation link to bring up the popup, then scroll the wheel while still hovering the link to zoom the preview in/out:

  • Wheel down (zoom out): the popup re-renders a larger region of the page, so previously-empty space fills with new content from below/right of the detected entry. Useful when the destination has large fonts or when the auto-detected region was too small.
  • Wheel up (zoom in): re-renders a smaller region at higher detail, cropping the trailing whitespace.

The popup window keeps its initial size; only the rendered content changes. The initial zoom now matches the document's current page zoom, so popup text height is comparable to the visible page text.

New build: https://builds.jabref.org/main/SumatraPDF-dll-2.exe

@GitHubRulesOK
Copy link
Copy Markdown
Collaborator

GitHubRulesOK commented May 7, 2026

@koppor Fantastic improvement though took me a while to grasp the concept of zoom the source box but once tried out it makes sense as an alternative to try to zoom the quick viewbox (I have had issues with that when attempting a magnifier box as mouse focus is then relocated). The last core issue I see is the "window" is highly varied depending on sources own desired target. Take this silly example, where the target is a wide set of goto with a topbar target. It would be better if the quickview is a fixed ratio.
image

koppor and others added 2 commits May 7, 2026 16:07
Reviewer noted that internal links pointing to non-bibliography destinations
(TOC entries, topbar goto targets, page anchors) produced ugly wide-thin
popups because the entry-detection fallback returned a strip that ran from
destX to the right page margin. Replace those fallback paths with a
fixed-pt box anchored on the destination so every non-reference target
gets the same popup shape. Bibliography entries that the detector can
identify keep their existing (content-shaped) box.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@koppor
Copy link
Copy Markdown
Author

koppor commented May 7, 2026

@GitHubRulesOK Good catch — pushed 77b017f to address that.

Now the popup shape depends on what the link actually points to:

  • Reference (bibliography entry): detection finds a [N]/author-year-shaped block — popup is sized to that block (as before).
  • Non-reference (TOC, topbar, generic goto): detection's text scan doesn't find a bibliography-shaped entry — popup falls back to a fixed-ratio box (≈ 360×260 pt) anchored on the destination, regardless of what's nearby.

So your wide-thin "topbar goto" example now gets the same compact box as any other non-reference target, rather than stretching to the right page margin.

Build with this fix: https://builds.jabref.org/main/SumatraPDF-dll-3.exe

@GitHubRulesOK
Copy link
Copy Markdown
Collaborator

@koppor I am not trying to be a killjoy this IS a good improvement
image
but it may just be that the examples I have to hand are wildly variable so in the case shown below the target is top of table but user would expect a box much higher than the target zone more like a landscape view of page width or half page width for 2 column content. I understand it cannot always be known what users desire but the qwickview overlay could be as wide as the current viewport page width and half the current source page height as it is temporary.
image

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.

Can we have a snapshot feature like Skim in MacOS Popup preview of PDF links

2 participants