Add SyncTeX support for Typst projects
Build and Deploy Verso / deploy (push) Successful in 11m58s

- TypstRunner: add --synctex output.synctex.gz to quarto typst compile,
  generating a synctex file alongside the PDF (requires Typst 0.11+,
  bundled in Quarto 1.5+).
- use-synctex: extend the root-doc guard from LaTeX-only to also cover
  .typ files, enabling the Show in PDF / Show in code buttons for Typst.

The rest of the sync infrastructure (OutputCacheManager, synctex binary,
SynctexOutputParser, CLSI routes) is already format-agnostic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
claude
2026-06-06 21:52:05 +00:00
parent 9079b545f7
commit 43a622cd71
2 changed files with 12 additions and 8 deletions
+3 -1
View File
@@ -58,8 +58,10 @@ function _buildTypstCommand(mainFile) {
// is merged into stdout (2>&1). LocalCommandRunner replaces $COMPILE_DIR
// before the shell sees it; the output path is relative because the shell
// CWD is already the compile directory.
// --synctex generates output.synctex.gz alongside the PDF, enabling
// bidirectional editor↔PDF sync (same infrastructure as LaTeX SyncTeX).
const inputPath = `$COMPILE_DIR/${mainFile}`
const cmd = `quarto typst compile ${inputPath} output.pdf 2>&1`
const cmd = `quarto typst compile ${inputPath} output.pdf --synctex output.synctex.gz 2>&1`
return ['/bin/sh', '-c', cmd]
}
@@ -176,11 +176,13 @@ export default function useSynctex(): {
positionRef.current = position
}, [position])
// SyncTeX only works for LaTeX projects (requires output.synctex.gz).
// Typst and Quarto do not produce this file.
const LATEX_EXTENSIONS_RE = /\.(tex|ltx|Rtex|Rnw)$/i
// SyncTeX works for LaTeX and Typst projects — both produce output.synctex.gz.
// Quarto does not (its intermediate files make path mapping unreliable).
const SYNCTEX_EXTENSIONS_RE = /\.(tex|ltx|Rtex|Rnw|typ)$/i
const rootDocPath = rootDocId ? pathInFolder(rootDocId) : null
const isLatexRootDoc = rootDocPath ? LATEX_EXTENSIONS_RE.test(rootDocPath) : false
const isSynctexRootDoc = rootDocPath
? SYNCTEX_EXTENSIONS_RE.test(rootDocPath)
: false
const _syncToCode = useCallback(
({
@@ -192,7 +194,7 @@ export default function useSynctex(): {
selectText?: string
visualOffset?: number
}) => {
if (!isLatexRootDoc || !position) {
if (!isSynctexRootDoc || !position) {
return
}
@@ -245,7 +247,7 @@ export default function useSynctex(): {
})
},
[
isLatexRootDoc,
isSynctexRootDoc,
pdfFile,
clsiServerId,
projectId,
@@ -290,7 +292,7 @@ export default function useSynctex(): {
}, [selectedEntities, setHasSingleSelectedDoc])
const canSyncToPdf: boolean =
isLatexRootDoc &&
isSynctexRootDoc &&
hasSingleSelectedDoc &&
!!cursorPosition &&
!!openDocName