diff --git a/server-ce/nginx/clsi-nginx.conf b/server-ce/nginx/clsi-nginx.conf
index 0d045b9052..9815974651 100644
--- a/server-ce/nginx/clsi-nginx.conf
+++ b/server-ce/nginx/clsi-nginx.conf
@@ -48,9 +48,9 @@ server {
rewrite ^/project/([0-9a-f]+)/user/([0-9a-f]+)/build/([0-9a-f-]+)/output/(.+)$ /$4 break;
root /var/lib/overleaf/data/output/$1-$2/generated-files/$3/;
}
- # handle output files for anonymous users
- location ~ ^/project/([0-9a-f]+)/build/([0-9a-f-]+)/output/(.+)$ {
- rewrite ^/project/([0-9a-f]+)/build/([0-9a-f-]+)/output/(.+)$ /$3 break;
+ # handle output files for anonymous users (project ID may be a UUID with hyphens for conversions)
+ location ~ ^/project/([0-9a-f-]+)/build/([0-9a-f-]+)/output/(.+)$ {
+ rewrite ^/project/([0-9a-f-]+)/build/([0-9a-f-]+)/output/(.+)$ /$3 break;
root /var/lib/overleaf/data/output/$1/generated-files/$2/;
}
diff --git a/services/clsi/app/js/ConversionController.js b/services/clsi/app/js/ConversionController.js
index f1c69d7fae..42b83d026c 100644
--- a/services/clsi/app/js/ConversionController.js
+++ b/services/clsi/app/js/ConversionController.js
@@ -26,6 +26,7 @@ const CONVERSION_CONFIGS = {
markdown: { extension: 'zip' },
html: { extension: 'zip' },
typst: { extension: 'typ' },
+ latex: { extension: 'tex' },
}
async function convertDocumentToLaTeX(req, res) {
diff --git a/services/clsi/app/js/ConversionManager.js b/services/clsi/app/js/ConversionManager.js
index d6e4b13f46..a41873c4f0 100644
--- a/services/clsi/app/js/ConversionManager.js
+++ b/services/clsi/app/js/ConversionManager.js
@@ -191,6 +191,19 @@ const LATEX_EXPORT_CONFIGS = {
'typst',
],
},
+ latex: {
+ fileExtension: 'tex',
+ compressOutput: false,
+ getPandocArgs: ({ outputPath }) => [
+ '--output',
+ outputPath,
+ '--from',
+ 'typst',
+ '--to',
+ 'latex',
+ '--standalone',
+ ],
+ },
}
async function convertLaTeXToDocumentInDirWithLock(
diff --git a/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs b/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs
index fb84e0b167..bd34559b14 100644
--- a/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs
+++ b/services/web/app/src/Features/Downloads/ProjectDownloadsController.mjs
@@ -21,6 +21,7 @@ const SUPPORTED_CONVERSION_TYPES = new Map([
['markdown', 'zip'],
['html', 'zip'],
['typst', 'typ'],
+ ['latex', 'tex'],
])
const exportProjectConversionSchema = z.object({
@@ -100,14 +101,14 @@ async function exportProjectConversion(req, res) {
{ compileFromHistory, rootResourcePath }
)
AnalyticsManager.recordEventForUserInBackground(userId, 'convert-format', {
- sourceFormat: 'latex',
+ sourceFormat: type === 'latex' ? 'typst' : 'latex',
targetFormat: type,
status: 'success',
operation: 'export',
})
} catch (error) {
AnalyticsManager.recordEventForUserInBackground(userId, 'convert-format', {
- sourceFormat: 'latex',
+ sourceFormat: type === 'latex' ? 'typst' : 'latex',
targetFormat: type,
status: 'failure',
operation: 'export',
diff --git a/services/web/frontend/js/features/ide-react/components/toolbar/export-project-with-conversion-button.tsx b/services/web/frontend/js/features/ide-react/components/toolbar/export-project-with-conversion-button.tsx
index d8aa288841..a642dde55e 100644
--- a/services/web/frontend/js/features/ide-react/components/toolbar/export-project-with-conversion-button.tsx
+++ b/services/web/frontend/js/features/ide-react/components/toolbar/export-project-with-conversion-button.tsx
@@ -10,7 +10,7 @@ import { useProjectSettingsContext } from '@/features/editor-left-menu/context/p
type ExportProjectWithConversionProps = {
featureFlag?: string
- conversionType: 'docx' | 'markdown' | 'html' | 'typst'
+ conversionType: 'docx' | 'markdown' | 'html' | 'typst' | 'latex'
label: string
menuBarId: string
}
@@ -25,6 +25,9 @@ export const ExportProjectWithConversionButton: FC<
const anonymous = getMeta('ol-anonymous')
const { compiler } = useProjectSettingsContext()
const isLatexProject = !['typst', 'quarto'].includes(compiler ?? '')
+ // latex export is for converting Typst projects to LaTeX; all others are for LaTeX projects
+ const isProjectTypeMatch =
+ conversionType === 'latex' ? compiler === 'typst' : isLatexProject
const getRootDocInfo = useRootDoc()
const { openDocs } = useEditorManagerContext()
const downloadConversion = useConvertProject(
@@ -37,7 +40,7 @@ export const ExportProjectWithConversionButton: FC<
splitTestEnabledIfNeeded &&
enablePandocConversions &&
!anonymous &&
- isLatexProject
+ isProjectTypeMatch
useCommandProvider(
() =>
diff --git a/services/web/frontend/js/features/ide-react/components/toolbar/menu-bar.tsx b/services/web/frontend/js/features/ide-react/components/toolbar/menu-bar.tsx
index 39ee468f87..ee90eb28f5 100644
--- a/services/web/frontend/js/features/ide-react/components/toolbar/menu-bar.tsx
+++ b/services/web/frontend/js/features/ide-react/components/toolbar/menu-bar.tsx
@@ -98,6 +98,7 @@ export const ToolbarMenuBar = () => {
'export-as-markdown',
'export-as-html',
'export-as-typst',
+ 'export-as-latex',
],
},
],
diff --git a/services/web/frontend/js/features/ide-react/components/toolbar/project-title.tsx b/services/web/frontend/js/features/ide-react/components/toolbar/project-title.tsx
index 30b11726c3..0d1e8ff3a0 100644
--- a/services/web/frontend/js/features/ide-react/components/toolbar/project-title.tsx
+++ b/services/web/frontend/js/features/ide-react/components/toolbar/project-title.tsx
@@ -100,6 +100,11 @@ export const ToolbarProjectTitle = () => {
label={t('export_as_typst')}
menuBarId="export-as-typst"
/>
+
RootDocInfo
) {
diff --git a/services/web/locales/en.json b/services/web/locales/en.json
index 30b2cacd1b..11e8f0a84f 100644
--- a/services/web/locales/en.json
+++ b/services/web/locales/en.json
@@ -879,6 +879,7 @@
"export_as_docx": "Export as Word document (.docx)",
"export_as_html": "Export as HTML (.html)",
"export_as_typst": "Export as Typst",
+ "export_as_latex": "Export as LaTeX (.tex)",
"export_as_markdown": "Export as Markdown (.md)",
"export_csv": "Export CSV",
"export_project_to_github": "Export Project to GitHub",
diff --git a/services/web/locales/fr.json b/services/web/locales/fr.json
index 344003e1f5..4c9c383639 100644
--- a/services/web/locales/fr.json
+++ b/services/web/locales/fr.json
@@ -882,6 +882,7 @@
"export_as_docx": "Exporter sous forme de document Word (.docx)",
"export_as_html": "Exporter au format HTML (.html)",
"export_as_typst": "Exporter en Typst",
+ "export_as_latex": "Exporter en LaTeX (.tex)",
"export_as_markdown": "Exporter en Markdown (.md)",
"export_csv": "Exporter en CSV",
"export_project_to_github": "Exporter le projet vers GitHub",