diff --git a/docs/creating-pdf-documents.md b/docs/creating-pdf-documents.md index 47e4b30d9..47737f198 100644 --- a/docs/creating-pdf-documents.md +++ b/docs/creating-pdf-documents.md @@ -87,6 +87,14 @@ See the official documentation for installation instructions for $\LaTeX$ at: Ensure that you download a full distribution with appropriate libraries installed. +(install-tectonic)= + +#### Tectonic as a lightweight alternative +As an alternative, you can also install [Tectonic](https://tectonic-typesetting.github.io/), "a modernized, complete, self-contained TeX/LaTeX engine, powered by XeTeX and TeXLive".
+> Tectonic automatically downloads support files so you don’t have to install a full LaTeX system in order to start using it. If you start using a new LaTeX package, Tectonic just pulls down the files it needs and continues processing. +> +> – [Tectonic Website](https://tectonic-typesetting.github.io/) + % Probably a note in the future about running this remotely? (rendering-pdfs-with-typst)= diff --git a/packages/jtex/src/tex/export.ts b/packages/jtex/src/tex/export.ts index a981930c7..5222aaece 100644 --- a/packages/jtex/src/tex/export.ts +++ b/packages/jtex/src/tex/export.ts @@ -1,6 +1,15 @@ import path from 'node:path'; import type MystTemplate from 'myst-templates'; import { createCommand } from '../utils.js'; +import which from 'which'; + +export function isLatexmkAvailable() { + return which.sync('latexmk', { nothrow: true }); +} + +export function isTectonicAvailable() { + return which.sync('tectonic', { nothrow: true }); +} export function pdfTexExportCommand( texFile: string, @@ -8,9 +17,13 @@ export function pdfTexExportCommand( template?: MystTemplate, ): string { const templateYml = template?.getValidatedTemplateYml(); - const engine = templateYml?.build?.engine ?? '-xelatex'; - const baseCommand = `latexmk -f ${engine} -synctex=1 -interaction=batchmode -file-line-error -latexoption="-shell-escape" ${texFile}`; - + // Use Tectonic by default (https://tectonic-typesetting.github.io) + let baseCommand = `tectonic -X compile --keep-intermediates --keep-logs ${texFile}`; + // Alternatively, switch to Latexmk with xelatex + if (!isTectonicAvailable() && isLatexmkAvailable()) { + const engine = templateYml?.build?.engine ?? '-xelatex'; + baseCommand = `latexmk -f ${engine} -synctex=1 -interaction=batchmode -file-line-error -latexoption="-shell-escape" ${texFile}`; + } return createCommand(baseCommand, logFile); } diff --git a/packages/myst-cli/src/build/pdf/create.ts b/packages/myst-cli/src/build/pdf/create.ts index bfdcd11d8..93b8ffc41 100644 --- a/packages/myst-cli/src/build/pdf/create.ts +++ b/packages/myst-cli/src/build/pdf/create.ts @@ -14,7 +14,7 @@ import { uniqueArray } from '../../utils/uniqueArray.js'; import { logMessagesFromVFile } from '../../utils/logging.js'; import { createTempFolder } from '../../utils/createTempFolder.js'; import { cleanOutput } from '../utils/cleanOutput.js'; -import { isLatexmkAvailable, isMakeglossariesAvailable } from './utils.js'; +import { isTectonicAvailable, isLatexmkAvailable, isMakeglossariesAvailable } from './utils.js'; const copyFile = util.promisify(fs.copyFile); @@ -263,10 +263,10 @@ async function runPdfBuildCommand( vfile: VFile, debugLogsOnly?: boolean, ) { - if (!isLatexmkAvailable()) { + if (!(isTectonicAvailable() || isLatexmkAvailable())) { fileError( vfile, - `⚠️ The "latexmk" command is not available. See documentation on installing LaTeX:\n\n${docLinks.installLatex}`, + `⚠️ Neither "tectonic" nor "latexmk" command is available. See documentation on installing LaTeX:\n\n${docLinks.installLatex}\n${docLinks.installTectonic}`, { ruleId: RuleId.pdfBuildCommandsAvailable }, ); } diff --git a/packages/myst-cli/src/build/pdf/utils.ts b/packages/myst-cli/src/build/pdf/utils.ts index 2dbc3c999..7075d888b 100644 --- a/packages/myst-cli/src/build/pdf/utils.ts +++ b/packages/myst-cli/src/build/pdf/utils.ts @@ -6,6 +6,10 @@ export function isLatexmkAvailable() { return which.sync('latexmk', { nothrow: true }); } +export function isTectonicAvailable() { + return which.sync('tectonic', { nothrow: true }); +} + export function isMakeglossariesAvailable() { return which.sync('makeglossaries', { nothrow: true }); } diff --git a/packages/myst-cli/src/docs.ts b/packages/myst-cli/src/docs.ts index cb6124e6c..a177569b3 100644 --- a/packages/myst-cli/src/docs.ts +++ b/packages/myst-cli/src/docs.ts @@ -1,4 +1,5 @@ export const docLinks = { installNode: 'https://nodejs.org/en/download/', installLatex: 'https://mystmd.org/guide/creating-pdf-documents#install-latex', + installTectonic: 'https://mystmd.org/guide/creating-pdf-documents#install-tectonic' };