diff --git a/services/clsi/app/js/TypstRunner.js b/services/clsi/app/js/TypstRunner.js index 5e3f4ed319..c25045a9be 100644 --- a/services/clsi/app/js/TypstRunner.js +++ b/services/clsi/app/js/TypstRunner.js @@ -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] } diff --git a/services/web/frontend/js/features/pdf-preview/hooks/use-synctex.ts b/services/web/frontend/js/features/pdf-preview/hooks/use-synctex.ts index 06ef1226fd..a91c05935c 100644 --- a/services/web/frontend/js/features/pdf-preview/hooks/use-synctex.ts +++ b/services/web/frontend/js/features/pdf-preview/hooks/use-synctex.ts @@ -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