Skip to content

SyncTeX forward search (source line → PDF position) #730

Description

@jeonghun-jj-lee

SyncTeX forward search (source line → PDF position)

Important

Problem — When a researcher edits a .tex file and previews the compiled PDF, the PDF opens at page 1. There is no way to jump to the section corresponding to the code being edited.

Approach — Parse the .synctex.gz file that latexmk generates by default and implement forward search: given a source file and cursor line, scroll the PDF viewer to the corresponding page and position. This is a trailing additive slice — it depends on both the CodeMirror editor (slice 4) for cursor position and the TeX compilation pipeline (slice 5) for the .synctex.gz artifact.

Scope — in: SyncTeX .synctex.gz parser, forward search (source line → PDF page + position), PDF viewer scroll-to-position API. out: inverse search (PDF click → source line), SyncTeX file generation (handled by latexmk), custom SyncTeX configuration.

Risk — This is the highest-risk slice. The SyncTeX binary format is non-trivial and existing JS parsers (synctex-js) are minimally maintained. If the parser proves unreliable, this slice may be dropped without affecting the rest of the feature.

Acceptance Criteria

  • When the cursor moves in a .tex file being edited in CodeMirror, and a compiled PDF with a .synctex.gz file exists, the PDF viewer scrolls to the corresponding page and vertical position
  • Forward search triggers on cursor line change (not every keystroke — debounced or on explicit action)
  • When no .synctex.gz file exists (compilation not run, or latexmk configured without SyncTeX), forward search is silently disabled — no error, no UI element
  • The .synctex.gz file is read from the build output directory (same location as the compiled PDF)
  • Forward search accuracy: correct page and approximate vertical position (within ~100px at default zoom)

Testing Decisions

  • Unit test the SyncTeX parser with a fixture .synctex.gz file — verify page and position extraction for known source lines
  • Unit test the debounce logic for cursor-line-change triggers
  • Integration test: compile a fixture .tex file, verify forward search scrolls to the correct page (gated on which latexmk)

Key Decisions

Forward search only. Inverse search (click PDF → jump to source) is out of scope. Forward search is the higher-value feature (the researcher knows where they are in source and wants to see the output).

Debounced cursor tracking. Forward search triggers when the cursor line changes, not on every keystroke. A 500ms debounce prevents the PDF from jumping while the user is typing.

Best-effort parser. If the SyncTeX format proves too fragile to parse reliably in JS, this slice is dropped. The rest of #721 does not depend on it.

Constraints & Invariants

  • SyncTeX is purely additive — its absence never degrades the core experience
  • The parser never blocks the main thread (parse in a web worker or async chunks)
  • Forward search never fires without a valid .synctex.gz file

Prior Art

  • synctex-js — minimally maintained JS SyncTeX parser (evaluate before building custom)
  • @anthropic-ai/claude-code SyncTeX reference — not applicable (different architecture)

Source

harmoniqs/opencode — new SyncTeX parser module + PDF viewer scroll API extension in packages/app/src/components/

Activity

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

Metadata

Metadata

Labels

afkImplementable without human interactionarea:uienhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions