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",