diff --git a/news/changelog-1.12.md b/news/changelog-1.12.md index 2c099415446..c92f446eb60 100644 --- a/news/changelog-1.12.md +++ b/news/changelog-1.12.md @@ -16,6 +16,7 @@ All changes included in 1.12: ### `html` +- ([#9606](https://github.com/quarto-dev/quarto-cli/issues/9606)): Fix `format-links` entries written as `{format, text}` adding a second, default link for the same format instead of renaming its link. - ([#15269](https://github.com/quarto-dev/quarto-cli/pull/15269)): Fix `link-external-newwindow` overriding a `target` set explicitly on a link. (author: @mcanouil) ### `pdf` diff --git a/src/format/html/format-html-links.ts b/src/format/html/format-html-links.ts index f7ea856c92c..22f5565f16f 100644 --- a/src/format/html/format-html-links.ts +++ b/src/format/html/format-html-links.ts @@ -112,6 +112,9 @@ export function alternateLinks( }; }; + // Formats renamed by a `{format, text}` entry, so no default link is added for them + const renamedFormats = new Set(); + let count = 1; for (const userLink of userLinks || []) { if (typeof userLink === "string") { @@ -132,6 +135,7 @@ export function alternateLinks( f.format.identifier[kTargetFormat] === thatLink.format ); if (rf) { + renamedFormats.add(rf); // Just push through alternateLinks.push( alternateLinkForFormat(rf, count, thatLink.text, thatLink.icon), @@ -159,7 +163,10 @@ export function alternateLinks( if (!userLinksHasFormat) { formats.forEach((renderedFormat) => { const baseFormat = renderedFormat.format.identifier["base-format"]; - if (!kExcludeFormatUnlessExplicit.includes(baseFormat || "html")) { + if ( + !kExcludeFormatUnlessExplicit.includes(baseFormat || "html") && + !renamedFormats.has(renderedFormat) + ) { alternateLinks.push(alternateLinkForFormat(renderedFormat, count)); } count++; diff --git a/tests/docs/smoke-all/2026/11/06/9606-href.qmd b/tests/docs/smoke-all/2026/11/06/9606-href.qmd new file mode 100644 index 00000000000..7812c9c8a48 --- /dev/null +++ b/tests/docs/smoke-all/2026/11/06/9606-href.qmd @@ -0,0 +1,24 @@ +--- +title: "format-links with only an explicit href link" +format: + html: + format-links: + - text: Quarto + href: https://quarto.org/ + icon: globe + typst: default + docx: default +_quarto: + tests: + html: + ensureHtmlElementCount: + selectors: + - '.quarto-alternate-formats a' + - '.quarto-alternate-formats a[href="https://quarto.org/"]' + - '.quarto-alternate-formats a[href="9606-href.pdf"]' + - '.quarto-alternate-formats a[href="9606-href.docx"]' + counts: [3, 1, 1, 1] +--- + +`format-links` has a single `{text, href}` link, which names no format. +It is added on top of the default links, so Typst and docx keep theirs (#9606). diff --git a/tests/docs/smoke-all/2026/11/06/9606-partial.qmd b/tests/docs/smoke-all/2026/11/06/9606-partial.qmd new file mode 100644 index 00000000000..bfe0a93403b --- /dev/null +++ b/tests/docs/smoke-all/2026/11/06/9606-partial.qmd @@ -0,0 +1,26 @@ +--- +title: "format-links renaming only some formats" +format: + html: + format-links: + - format: typst + text: PDF + icon: file-pdf + typst: default + docx: default +_quarto: + tests: + html: + ensureHtmlElementCount: + selectors: + - '.quarto-alternate-formats a' + - '.quarto-alternate-formats a[href="9606-partial.pdf"]' + - '.quarto-alternate-formats a[href="9606-partial.docx"]' + counts: [2, 1, 1] + ensureHtmlElementContents: + selectors: ['.quarto-alternate-formats a[href="9606-partial.pdf"]'] + matches: ['^PDF$'] +--- + +`format-links` renames the Typst link with a `{format, text, icon}` object and does not mention docx. +The Typst link is renamed, with no second default link for it, and docx keeps its default link (#9606). diff --git a/tests/docs/smoke-all/2026/11/06/9606.qmd b/tests/docs/smoke-all/2026/11/06/9606.qmd new file mode 100644 index 00000000000..1881c1464c9 --- /dev/null +++ b/tests/docs/smoke-all/2026/11/06/9606.qmd @@ -0,0 +1,29 @@ +--- +title: "format-links with only `{format, text}` entries" +format: + html: + format-links: + - format: typst + text: PDF + icon: file-pdf + - format: docx + text: Word + icon: file-word + typst: default + docx: default +_quarto: + tests: + html: + ensureHtmlElementCount: + selectors: + - '.quarto-alternate-formats a' + - '.quarto-alternate-formats a[href="9606.pdf"]' + - '.quarto-alternate-formats a[href="9606.docx"]' + counts: [2, 1, 1] + ensureHtmlElementContents: + selectors: ['.quarto-alternate-formats a[href="9606.docx"]'] + matches: ['^Word$'] +--- + +`format-links` lists every format as a `{format, text, icon}` object and has no plain string entry. +Listing a format this way renames its link: "Other Formats" shows only PDF and Word, not the default Typst and MS Word links as well (#9606).