From af54b5fd49accd20ef9884dcc16e61b4c0ef0b26 Mon Sep 17 00:00:00 2001 From: claude Date: Sun, 31 May 2026 12:29:12 +0000 Subject: [PATCH] Fix Quarto compiler integration: UI, root doc detection, type safety - compiler-setting.tsx: replace hardcoded LaTeX compiler list with a single Quarto option; drop now-unused getMeta/lodash imports - project-settings.ts: add 'quarto' to ProjectCompiler union type - ClsiManager: detect main.qmd as a default root document (preferred over main.tex); replace hasMainFile boolean with detectedMainFile so we know which filename to use - settings.defaults.js: add 'qmd' to validRootDocExtensions so .qmd files appear as selectable root documents in the UI - ProjectRootDocManager: sort main.qmd before main.tex in the root doc candidate list Co-Authored-By: Claude Sonnet 4.6 --- .../web/app/src/Features/Compile/ClsiManager.mjs | 13 ++++++++----- .../src/Features/Project/ProjectRootDocManager.mjs | 14 ++++++++------ services/web/config/settings.defaults.js | 2 +- .../compiler-settings/compiler-setting.tsx | 14 +------------- services/web/types/project-settings.ts | 2 +- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/services/web/app/src/Features/Compile/ClsiManager.mjs b/services/web/app/src/Features/Compile/ClsiManager.mjs index f527b4be86..ab5dd73423 100644 --- a/services/web/app/src/Features/Compile/ClsiManager.mjs +++ b/services/web/app/src/Features/Compile/ClsiManager.mjs @@ -1068,7 +1068,7 @@ function _finaliseRequest(projectId, options, project, docs, files) { let flags let rootResourcePath = options.rootResourcePath let rootResourcePathOverride = null - let hasMainFile = false + let detectedMainFile = null let numberOfDocsInProject = 0 for (let path in docs) { @@ -1094,8 +1094,11 @@ function _finaliseRequest(projectId, options, project, docs, files) { ) { rootResourcePathOverride = path } - if (path === 'main.tex') { - hasMainFile = true + // prefer main.qmd over main.tex as the default root document + if (path === 'main.qmd') { + detectedMainFile = 'main.qmd' + } else if (path === 'main.tex' && detectedMainFile == null) { + detectedMainFile = 'main.tex' } } @@ -1103,8 +1106,8 @@ function _finaliseRequest(projectId, options, project, docs, files) { rootResourcePath = rootResourcePathOverride } if (rootResourcePath == null) { - if (hasMainFile) { - rootResourcePath = 'main.tex' + if (detectedMainFile != null) { + rootResourcePath = detectedMainFile } else if (numberOfDocsInProject === 1) { // only one file, must be the main document for (const path in docs) { diff --git a/services/web/app/src/Features/Project/ProjectRootDocManager.mjs b/services/web/app/src/Features/Project/ProjectRootDocManager.mjs index 8b4b212d87..59fd4ffcf0 100644 --- a/services/web/app/src/Features/Project/ProjectRootDocManager.mjs +++ b/services/web/app/src/Features/Project/ProjectRootDocManager.mjs @@ -191,12 +191,14 @@ function _rootDocSort(a, b) { if (a.elements !== b.elements) { return a.elements - b.elements } - // ensure main.tex is at the start of each folder - if (a.name === 'main.tex' && b.name !== 'main.tex') { - return -1 - } - if (a.name !== 'main.tex' && b.name === 'main.tex') { - return 1 + // prefer main.qmd, then main.tex, at the start of each folder + const PREFERRED = ['main.qmd', 'main.tex'] + const aIdx = PREFERRED.indexOf(a.name) + const bIdx = PREFERRED.indexOf(b.name) + if (aIdx !== bIdx) { + if (aIdx === -1) return 1 + if (bIdx === -1) return -1 + return aIdx - bIdx } // prefer smaller files if (a.size !== b.size) { diff --git a/services/web/config/settings.defaults.js b/services/web/config/settings.defaults.js index b839ecdd99..15ea6445f0 100644 --- a/services/web/config/settings.defaults.js +++ b/services/web/config/settings.defaults.js @@ -889,7 +889,7 @@ module.exports = { process.env.FILE_IGNORE_PATTERN || '**/{{__MACOSX,.git,.texpadtmp,.R}{,/**},.!(latexmkrc),*.{dvi,aux,log,toc,out,pdfsync,synctex,synctex(busy),fdb_latexmk,fls,nlo,ind,glo,gls,glg,bbl,blg,doc,docx,gz,swp}}', - validRootDocExtensions: ['tex', 'Rtex', 'ltx', 'Rnw'], + validRootDocExtensions: ['qmd', 'tex', 'Rtex', 'ltx', 'Rnw'], emailConfirmationDisabled: process.env.EMAIL_CONFIRMATION_DISABLED === 'true' || false, diff --git a/services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx b/services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx index 45f9c29424..f0e7a38e0b 100644 --- a/services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx +++ b/services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx @@ -6,20 +6,8 @@ import { useTranslation } from 'react-i18next' import { usePermissionsContext } from '@/features/ide-react/context/permissions-context' import { ProjectCompiler } from '@ol-types/project-settings' import { useSetCompilationSettingWithEvent } from '@/features/editor-left-menu/hooks/use-set-compilation-setting' -import getMeta from '@/utils/meta' -import _ from 'lodash' - function getCompilerOptions(): Option[] { - const compilerOptions = ['pdfLaTeX', 'LaTeX', 'XeLaTeX', 'LuaLaTeX'] - const defaultCompiler = getMeta('ol-defaultLatexCompiler') as ProjectCompiler - const sortedOptions = _.sortBy( - compilerOptions, - option => option.toLowerCase() !== defaultCompiler.toLowerCase() - ) - return sortedOptions.map(option => ({ - value: option.toLowerCase() as ProjectCompiler, - label: option, - })) + return [{ value: 'quarto', label: 'Quarto' }] } export default function CompilerSetting() { diff --git a/services/web/types/project-settings.ts b/services/web/types/project-settings.ts index 0d43e9c8e5..b7fa5374b5 100644 --- a/services/web/types/project-settings.ts +++ b/services/web/types/project-settings.ts @@ -17,7 +17,7 @@ export type MainDocument = { path: string } -export type ProjectCompiler = 'pdflatex' | 'latex' | 'xelatex' | 'lualatex' +export type ProjectCompiler = 'quarto' | 'pdflatex' | 'latex' | 'xelatex' | 'lualatex' export type OverallThemeMeta = { name: string