Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/changelog-1.12.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ All changes included in 1.12:
- ([jgm/pandoc#11831](https://github.com/jgm/pandoc/pull/11831)): HTML documents using `theme: pandoc` pick up Pandoc 3.13's style updates. Links now inherit the surrounding text color unless `linkcolor` is set, horizontal rules and table borders follow the text color, and printed output drops backgrounds and the fixed 12pt font size, rendering at the 11pt print size used by other Quarto HTML themes. Pandoc 3.13's automatic dark mode is not enabled for `theme: pandoc`.
- ([jgm/pandoc#11845](https://github.com/jgm/pandoc/issues/11845)): In Word output, cross-reference targets are now hidden bookmarks with generated names instead of their Quarto id (`fig-plot`). Cross-reference links inside the document still work, but a link or script that looks a bookmark up by its Quarto id from outside the document, such as `report.docx#fig-plot` or `officer`, VBA or `python-docx` code, no longer finds it.
- ([jgm/pandoc 3.13](https://github.com/jgm/pandoc/releases/tag/3.13)): A YAML bibliography file with a duplicated key, such as two `title` fields in one reference, now stops the render with an error giving the file, line and column. Before, the last value was kept silently. Remove the duplicate key to render again.
- ([jgm/pandoc@c73a35a](https://github.com/jgm/pandoc/commit/c73a35a2e7ed1144132f1e533b4f0ae4c3648143)): Support Pandoc's `--math-method` option in `quarto render`, so that `--math-method=katex` works with `--embed-resources` and keeps math intact in `llms.md` output, like `--katex` does.

## Accessibility

Expand Down
13 changes: 13 additions & 0 deletions src/command/render/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
kDate,
kEmbedResources,
kListings,
kMathMethod,
kNumberOffset,
kNumberSections,
kReferenceLocation,
Expand Down Expand Up @@ -204,6 +205,18 @@ export async function parseRenderFlags(args: string[]) {
arg = argsStack.shift();
break;

case `--${kMathMethod}`: {
// METHOD[:URL]; the URL itself contains ':', so split on the first one
arg = argsStack.shift();
if (arg) {
const colon = arg.indexOf(":");
flags[kMathMethod] = colon === -1
? { method: arg }
: { method: arg.slice(0, colon), url: arg.slice(colon + 1) };
}
break;
}

case "--execute":
flags.execute = true;
arg = argsStack.shift();
Expand Down
8 changes: 3 additions & 5 deletions src/command/render/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { normalizePath } from "../../core/path.ts";
import { isGlob } from "../../core/lib/glob.ts";
import { ProjectContext } from "../../project/types.ts";
import { isWindows } from "../../deno_ral/platform.ts";
import { resolveHtmlMathMethod } from "../../format/html/format-html-math.ts";

export const kPatchedTemplateExt = ".patched";
export const kTemplatePartials = "template-partials";
Expand Down Expand Up @@ -214,11 +215,8 @@ function applyTemplatePatches(
}

function mathConfig(format: Format, flags?: RenderFlags) {
// if any command line math flags were passed then bail
if (
flags?.mathjax || flags?.katex || flags?.webtex || flags?.gladtex ||
flags?.mathml
) {
// if a command line math flag chose the method, Pandoc handles it
if (resolveHtmlMathMethod(format, flags)?.fromFlag) {
return undefined;
}

Expand Down
1 change: 1 addition & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ export const kKatex = "katex";
export const kMathml = "mathml";
export const kGladtex = "gladtex";
export const kWebtex = "webtex";
export const kMathMethod = "math-method";

// metadata fields
export const kQuartoInternal = "quarto-internal";
Expand Down
2 changes: 2 additions & 0 deletions src/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ import {
kManuscriptMecaBundle,
kMarkdownHeadings,
kMathjax,
kMathMethod,
kMathml,
kMergeIncludes,
kMermaidFormat,
Expand Down Expand Up @@ -645,6 +646,7 @@ export interface PandocFlags {
[kMathml]?: boolean;
[kGladtex]?: boolean;
[kWebtex]?: boolean;
[kMathMethod]?: { method: string; url?: string };
}

// the requested pdf engine, it's options, and the bib engine
Expand Down
12 changes: 10 additions & 2 deletions src/format/html/format-html-math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@

import { kHtmlEmptyPostProcessResult } from "../../command/render/constants.ts";
import { Document } from "../../core/deno-dom.ts";
import { kHtmlMathMethod } from "../../config/constants.ts";
import { kHtmlMathMethod, kMathMethod } from "../../config/constants.ts";
import { Format, PandocFlags } from "../../config/types.ts";
import { MathMethods } from "../../resources/types/schema-types.ts";

export interface HtmlMathMethod {
method: MathMethods;
url?: string;
// true when a command line flag (--katex, --mathjax, ...) chose the method
// true when a command line flag (--math-method, --katex, ...) chose the method
fromFlag: boolean;
}

Expand All @@ -29,6 +29,14 @@ export function resolveHtmlMathMethod(
format: Format,
flags?: PandocFlags,
): HtmlMathMethod | undefined {
const mathMethod = flags?.[kMathMethod];
if (mathMethod) {
return {
method: mathMethod.method as MathMethods,
url: mathMethod.url,
fromFlag: true,
};
}
const flagMethod = kMathFlags.find((method) => flags?.[method]);
if (flagMethod) {
return { method: flagMethod, fromFlag: true };
Expand Down
12 changes: 12 additions & 0 deletions tests/docs/render/math-method-flag.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
title: "Math method chosen with the --math-method command line option"
format: html
---

Inline math $x^2$.

$$
E = mc^2
$$ {#eq-energy}

See @eq-energy.
32 changes: 32 additions & 0 deletions tests/smoke/render/render-math-method-flag.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* render-math-method-flag.test.ts
*
* Pandoc 3.11 replaced --katex, --mathjax, ... with --math-method=METHOD[:URL].
* Quarto must see the method chosen that way, as it does for the older flags.
*
* Copyright (C) 2026 Posit Software, PBC
*/

import { docs, outputForInput } from "../../utils.ts";
import { ensureFileRegexMatches, noErrorsOrWarnings } from "../../verify.ts";
import { testRender } from "./render.ts";

const input = docs("render/math-method-flag.qmd");
const output = outputForInput(input, "html");

// With embed-resources, Pandoc embeds the KaTeX library itself (its error
// strings are in the page); Quarto must not swap in its MathJax loader.
testRender(input, "html", true, [
noErrorsOrWarnings,
ensureFileRegexMatches(output.outputPath, [/KaTeX parse error/], [
/mathjax@3\/es5\/tex-chtml-full\.js/,
]),
], {}, ["--math-method=katex", "--embed-resources"]);

// Without embed-resources, Quarto's KaTeX post-processor runs
testRender(input, "html", false, [
noErrorsOrWarnings,
ensureFileRegexMatches(output.outputPath, [
/window\.backupDefine = window\.define/,
]),
], {}, ["--math-method", "katex"]);
17 changes: 17 additions & 0 deletions tests/unit/format-html-math.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,20 @@ async () => {
assertEquals(resolveHtmlMathMethod(createMockFormat()), undefined);
assertEquals(resolveHtmlMathMethod(createMockFormat(), {}), undefined);
});

unitTest("resolveHtmlMathMethod - --math-method flag", //deno-lint-ignore require-await
async () => {
const format = createMockFormat({
pandoc: { "html-math-method": "mathjax" },
});
assertEquals(
resolveHtmlMathMethod(format, {
"math-method": { method: "katex", url: "https://example.com/katex/" },
}),
{ method: "katex", url: "https://example.com/katex/", fromFlag: true },
);
assertEquals(
resolveHtmlMathMethod(format, { "math-method": { method: "plain" } }),
{ method: "plain", url: undefined, fromFlag: true },
);
});
25 changes: 25 additions & 0 deletions tests/unit/render-flags.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* render-flags.test.ts
*
* Copyright (C) 2026 Posit Software, PBC
*/

import { assertEquals } from "../asserts.ts";
import { parseRenderFlags } from "../../src/command/render/flags.ts";
import { unitTest } from "../test.ts";

unitTest("parseRenderFlags - --math-method=METHOD:URL", async () => {
const flags = await parseRenderFlags([
"--math-method=katex:https://example.com/katex/",
]);
assertEquals(flags["math-method"], {
method: "katex",
url: "https://example.com/katex/",
});
});

unitTest("parseRenderFlags - --math-method METHOD", async () => {
const flags = await parseRenderFlags(["--math-method", "katex", "--toc"]);
assertEquals(flags["math-method"], { method: "katex" });
assertEquals(flags.toc, true);
});
Loading