Просмотр исходного кода

[web] Added `DEFAULT_LATEX_COMPILER` env (#32455)

This is mainly intended to be used in CE/Server Pro

GitOrigin-RevId: 277f9afca389a1e7b00db2d987129432fb1707b5
Miguel Serrano 2 месяцев назад
Родитель
Сommit
f9c53fe147

+ 2 - 2
services/web/app/src/Features/Compile/ClsiManager.mjs

@@ -36,7 +36,7 @@ const NewBackendCloudClsiCookieManager = ClsiCookieManagerFactory(
   Settings.apis.clsi_new?.backendGroupName
 )
 
-const VALID_COMPILERS = ['pdflatex', 'latex', 'xelatex', 'lualatex']
+const VALID_COMPILERS = Settings.safeCompilers
 const OUTPUT_FILE_TIMEOUT_MS = 60000
 const CLSI_COOKIES_ENABLED = (Settings.clsiCookie?.key ?? '') !== ''
 
@@ -747,7 +747,7 @@ async function _buildRequest(projectId, userId, options) {
     throw new Errors.NotFoundError(`project does not exist: ${projectId}`)
   }
   if (!VALID_COMPILERS.includes(project.compiler)) {
-    project.compiler = 'pdflatex'
+    project.compiler = Settings.defaultLatexCompiler
   }
   const historyId = project.overleaf.history.id
   let { baseHistoryVersion } = options

+ 1 - 0
services/web/app/src/Features/Project/ProjectController.mjs

@@ -955,6 +955,7 @@ const _ProjectController = {
         capabilities,
         roMirrorOnClientNoLocalStorage:
           Settings.adminOnlyLogin || project.name.startsWith('Debug: '),
+        defaultLatexCompiler: Settings.defaultLatexCompiler,
         languages: Settings.languages,
         learnedWords,
         editorThemes: THEME_LIST,

+ 1 - 2
services/web/app/src/Features/Project/ProjectOptionsHandler.mjs

@@ -5,7 +5,6 @@ import { db, ObjectId } from '../../infrastructure/mongodb.mjs'
 import Errors from '../Errors/Errors.js'
 import mongodb from 'mongodb-legacy'
 import OError from '@overleaf/o-error'
-const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex']
 
 const { ReturnDocument } = mongodb
 
@@ -16,7 +15,7 @@ const ProjectOptionsHandler = {
    */
   normalizeCompiler(compiler) {
     compiler = compiler.toLowerCase()
-    if (!safeCompilers.includes(compiler)) {
+    if (!settings.safeCompilers.includes(compiler)) {
       throw new OError('invalid compiler', { compiler })
     }
     return compiler

+ 3 - 1
services/web/app/src/Features/Templates/TemplatesManager.mjs

@@ -32,7 +32,9 @@ const TemplatesManager = {
     userId,
     imageName
   ) {
-    compiler = ProjectOptionsHandler.normalizeCompiler(compiler || 'pdflatex')
+    compiler = ProjectOptionsHandler.normalizeCompiler(
+      compiler || settings.defaultLatexCompiler
+    )
     imageName = ProjectOptionsHandler.normalizeImageName(
       imageName || 'wl_texlive:2018.1'
     )

+ 2 - 1
services/web/app/src/models/Project.mjs

@@ -1,5 +1,6 @@
 import mongoose from '../infrastructure/Mongoose.mjs'
 import _ from 'lodash'
+import settings from '@overleaf/settings'
 import { FolderSchema } from './Folder.mjs'
 import Errors from '../Features/Errors/Errors.js'
 
@@ -36,7 +37,7 @@ export const ProjectSchema = new Schema(
     mainBibliographyDoc_id: { type: ObjectId },
     version: { type: Number }, // incremented for every change in the project structure (folders and filenames)
     publicAccesLevel: { type: String, default: 'private' },
-    compiler: { type: String, default: 'pdflatex' },
+    compiler: { type: String, default: settings.defaultLatexCompiler },
     spellCheckLanguage: { type: String, default: 'en' },
     deletedByExternalDataSource: { type: Boolean, default: false },
     description: { type: String, default: '' },

+ 1 - 0
services/web/app/views/project/editor/_meta.pug

@@ -28,6 +28,7 @@ meta(name="ol-showAiFeatures" data-type="boolean" content=showAiFeatures)
 meta(name="ol-hasUnlimitedAi" data-type="boolean" content=hasUnlimitedAi)
 meta(name="ol-hasAiFreeTier" data-type="boolean" content=hasAiFreeTier)
 meta(name="ol-detachRole" data-type="string" content=detachRole)
+meta(name="ol-defaultLatexCompiler" data-type="string" content=defaultLatexCompiler)
 meta(name="ol-imageNames" data-type="json" content=imageNames)
 meta(name="ol-languages" data-type="json" content=languages)
 meta(name="ol-editorThemes" data-type="json" content=editorThemes)

+ 8 - 0
services/web/config/settings.defaults.js

@@ -115,6 +115,8 @@ const httpPermissionsPolicy = {
   },
 }
 
+const safeCompilers = ['xelatex', 'pdflatex', 'latex', 'lualatex']
+
 module.exports = {
   env: 'server-ce',
 
@@ -460,6 +462,12 @@ module.exports = {
 
   disableChat: process.env.OVERLEAF_DISABLE_CHAT === 'true',
   disableLinkSharing: process.env.OVERLEAF_DISABLE_LINK_SHARING === 'true',
+  safeCompilers,
+  defaultLatexCompiler: safeCompilers.includes(
+    process.env.DEFAULT_LATEX_COMPILER
+  )
+    ? process.env.DEFAULT_LATEX_COMPILER
+    : 'pdflatex',
   enableSubscriptions: false,
   restrictedCountries: [],
   enableOnboardingEmails: process.env.ENABLE_ONBOARDING_EMAILS === 'true',

+ 17 - 19
services/web/frontend/js/features/settings/components/compiler-settings/compiler-setting.tsx

@@ -1,3 +1,4 @@
+import { useState } from 'react'
 import { useProjectSettingsContext } from '@/features/editor-left-menu/context/project-settings-context'
 import DropdownSetting from '../dropdown-setting'
 import type { Option } from '../dropdown-setting'
@@ -5,28 +6,25 @@ 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'
 
-const OPTIONS: Option<ProjectCompiler>[] = [
-  {
-    value: 'pdflatex',
-    label: 'pdfLaTeX',
-  },
-  {
-    value: 'latex',
-    label: 'LaTeX',
-  },
-  {
-    value: 'xelatex',
-    label: 'XeLaTeX',
-  },
-  {
-    value: 'lualatex',
-    label: 'LuaLaTeX',
-  },
-]
+function getCompilerOptions(): Option<ProjectCompiler>[] {
+  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,
+  }))
+}
 
 export default function CompilerSetting() {
   const { compiler, setCompiler } = useProjectSettingsContext()
+  const [compilerOptions] = useState(() => getCompilerOptions())
   const { t } = useTranslation()
   const { write } = usePermissionsContext()
   const changeCompiler = useSetCompilationSettingWithEvent(
@@ -40,7 +38,7 @@ export default function CompilerSetting() {
       label={t('compiler')}
       description={t('the_latex_engine_used_for_compiling')}
       disabled={!write}
-      options={OPTIONS}
+      options={compilerOptions}
       onChange={changeCompiler}
       value={compiler}
       translateOptions="no"

+ 2 - 0
services/web/frontend/js/utils/meta.ts

@@ -7,6 +7,7 @@ import { ExposedSettings } from '../../../types/exposed-settings'
 import {
   type ImageName,
   OverallThemeMeta,
+  ProjectCompiler,
   type SpellCheckLanguage,
 } from '../../../types/project-settings'
 import { CurrencyCode } from '../../../types/subscription/currency'
@@ -116,6 +117,7 @@ export interface Meta {
   'ol-currentUrl': string
   'ol-customerIoEnabled': boolean
   'ol-debugPdfDetach': boolean
+  'ol-defaultLatexCompiler': ProjectCompiler
   'ol-detachRole': 'detached' | 'detacher' | ''
   'ol-dictionariesRoot': 'string'
   'ol-domainCaptureEnabled': boolean | undefined

+ 1 - 0
services/web/test/frontend/helpers/editor-providers.tsx

@@ -197,6 +197,7 @@ export function EditorProviders({
     'dropbox',
     'link-sharing',
   ])
+  window.metaAttributesCache.set('ol-defaultLatexCompiler', 'pdflatex')
 
   const scope = merge(
     {

+ 2 - 0
services/web/test/unit/src/Compile/ClsiManager.test.mjs

@@ -182,6 +182,8 @@ describe('ClsiManager', function () {
       },
       enablePdfCaching: true,
       clsiCookie: { key: 'clsiserver' },
+      safeCompilers: ['pdflatex', 'latex', 'xelatex', 'lualatex'],
+      defaultLatexCompiler: 'pdflatex',
     }
     ctx.ClsiCacheHandler = {
       clearCache: sinon.stub().resolves(),

+ 1 - 0
services/web/test/unit/src/Project/ProjectOptionsHandler.test.mjs

@@ -35,6 +35,7 @@ describe('ProjectOptionsHandler', function () {
           { imageName: 'texlive-0000.0', imageDesc: 'test image 0' },
           { imageName: 'texlive-1234.5', imageDesc: 'test image 1' },
         ],
+        safeCompilers: ['pdflatex', 'latex', 'xelatex', 'lualatex'],
       },
     }))
 

+ 1 - 0
services/web/test/unit/src/Templates/TemplatesManager.test.mjs

@@ -112,6 +112,7 @@ describe('TemplatesManager', function () {
           dumpFolder: ctx.dumpFolder,
         },
         siteUrl: (ctx.siteUrl = 'http://127.0.0.1:3000'),
+        defaultLatexCompiler: 'pdflatex',
         apis: {
           v1: {
             url: (ctx.v1Url = 'http://overleaf.com'),