Skip to content

Commit 46a0c72

Browse files
queeliusclaude
andcommitted
fix: detect MiKTeX in quarto check LaTeX detection on Windows
Previously, `quarto check` only looked for TeX Live (via tlmgr) and TinyTeX when checking for LaTeX installations. MiKTeX, which uses `initexmf` instead of `tlmgr`, was never detected -- even when installed, in PATH, and successfully used for PDF compilation. Add a MiKTeX detection fallback that runs when TeX Live is not found. It locates `initexmf` in PATH and extracts the MiKTeX distribution version from its --version output. Closes #14265 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d577ef4 commit 46a0c72

2 files changed

Lines changed: 70 additions & 2 deletions

File tree

news/changelog-1.10.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ All changes included in 1.10:
66

77
- ([#14261](https://github.com/quarto-dev/quarto-cli/issues/14261)): Fix theorem/example block titles containing inline code producing invalid Typst markup when syntax highlighting is applied.
88

9+
## Commands
10+
11+
### `quarto check`
12+
13+
- ([#14265](https://github.com/quarto-dev/quarto-cli/issues/14265)): Fix `quarto check` not detecting MiKTeX on Windows even when available in system PATH.
14+

src/command/check/check.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,8 +414,23 @@ async function checkInstall(conf: CheckConfiguration) {
414414
latexOutput.push(`${kIndent}Version: ${version}`);
415415
latexJson["version"] = version;
416416
} else {
417-
latexOutput.push(`${kIndent}Tex: (not detected)`);
418-
latexJson["installed"] = false;
417+
// Check for MiKTeX (uses initexmf instead of tlmgr)
418+
const miktexDetection = await detectMiktex();
419+
if (miktexDetection) {
420+
latexOutput.push(`${kIndent}Using: MiKTeX`);
421+
if (miktexDetection.path) {
422+
latexOutput.push(`${kIndent}Path: ${miktexDetection.path}`);
423+
latexJson["path"] = miktexDetection.path;
424+
}
425+
latexJson["source"] = "miktex";
426+
if (miktexDetection.version) {
427+
latexOutput.push(`${kIndent}Version: ${miktexDetection.version}`);
428+
latexJson["version"] = miktexDetection.version;
429+
}
430+
} else {
431+
latexOutput.push(`${kIndent}Tex: (not detected)`);
432+
latexJson["installed"] = false;
433+
}
419434
}
420435
};
421436
if (conf.jsonResult) {
@@ -561,3 +576,50 @@ async function detectChromeForCheck(): Promise<ChromeCheckInfo> {
561576

562577
return result;
563578
}
579+
580+
interface MiktexDetectionResult {
581+
path?: string;
582+
version?: string;
583+
}
584+
585+
async function detectMiktex(): Promise<MiktexDetectionResult | undefined> {
586+
try {
587+
const initexmfPath = await which("initexmf");
588+
if (!initexmfPath) {
589+
return undefined;
590+
}
591+
592+
const result: MiktexDetectionResult = {
593+
path: dirname(initexmfPath),
594+
};
595+
596+
// Get MiKTeX version via initexmf --version
597+
try {
598+
const versionResult = await execProcess({
599+
cmd: "initexmf",
600+
args: ["--version"],
601+
stdout: "piped",
602+
stderr: "piped",
603+
});
604+
if (versionResult.code === 0 && versionResult.stdout) {
605+
// initexmf --version outputs lines like:
606+
// MiKTeX Configuration Utility 4.12 (MiKTeX 24.1)
607+
// The parenthesized version is the distribution version
608+
const distVersionMatch = versionResult.stdout.match(
609+
/\(MiKTeX\s+(\d[\d.]*)\)/i,
610+
);
611+
const versionMatch = distVersionMatch ||
612+
versionResult.stdout.match(/MiKTeX\s+(\d[\d.]*)/i);
613+
if (versionMatch) {
614+
result.version = versionMatch[1];
615+
}
616+
}
617+
} catch {
618+
// Version detection is best-effort
619+
}
620+
621+
return result;
622+
} catch {
623+
return undefined;
624+
}
625+
}

0 commit comments

Comments
 (0)