Skip to content
Merged
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.11.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ All changes included in 1.11:
- ([#15125](https://github.com/quarto-dev/quarto-cli/pull/15125)): Fix Google Scholar metadata failing the render with a CSL JSON (`.json`) bibliography.
- ([#15128](https://github.com/quarto-dev/quarto-cli/pull/15128)): Fix Google Scholar metadata missing references with a YAML bibliography not wrapped in `---` delimiters.
- ([#15131](https://github.com/quarto-dev/quarto-cli/issues/15131)): Fix the light/dark toggle appearing, with no dark styles to switch to, when the `dark` brand file holds only comments and is ignored.
- ([#15207](https://github.com/quarto-dev/quarto-cli/issues/15207)): Fix the BibTeX citation in the HTML appendix showing a copy button that does nothing when `code-copy: false` is set.

### `pdf`

Expand Down
18 changes: 12 additions & 6 deletions src/format/html/format-html-appendix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import {
createCodeBlock,
createCodeCopyButton,
formatHasCodeCopy,
hasMarginCites,
hasMarginRefs,
insertFootnotesTitle,
Expand Down Expand Up @@ -306,13 +307,18 @@ export async function processDocumentAppendix(
const bibTexDiv = createCodeBlock(doc, cite.bibtex, "bibtex");
bibTexDiv.classList.add(kQuartoCiteBibtexClass);

const outerScaffold = doc.createElement("div");
outerScaffold.classList.add("code-copy-outer-scaffold");
outerScaffold.appendChild(bibTexDiv);
contentsDiv.appendChild(outerScaffold);
if (formatHasCodeCopy(format)) {
bibTexDiv.classList.add("code-with-copy");
const outerScaffold = doc.createElement("div");
outerScaffold.classList.add("code-copy-outer-scaffold");
outerScaffold.appendChild(bibTexDiv);
contentsDiv.appendChild(outerScaffold);

const copyButton = createCodeCopyButton(doc, format);
outerScaffold.appendChild(copyButton);
const copyButton = createCodeCopyButton(doc, format);
outerScaffold.appendChild(copyButton);
} else {
contentsDiv.appendChild(bibTexDiv);
}
}

if (cite?.html) {
Expand Down
30 changes: 29 additions & 1 deletion src/format/html/format-html-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
import { formatResourcePath } from "../../core/resources.ts";
import { Document, Element } from "../../core/deno-dom.ts";
import { normalizePath } from "../../core/path.ts";
import { formatHasBootstrap } from "./format-html-info.ts";
import { HtmlFormatFeatureDefaults } from "./format-html-types.ts";

// features that are enabled by default for 'html'. setting
// all of these to false will yield the minimal html output
Expand Down Expand Up @@ -73,6 +75,33 @@ export const kCitation = "citation";
export const kDocumentCss = "document-css";
export const kBootstrapDependencyName = "bootstrap";

export function htmlFormatFeatureDefaults(
format: Format,
): HtmlFormatFeatureDefaults {
const bootstrap = formatHasBootstrap(format);
const minimal = format.metadata[kMinimal] === true;
return {
tabby: !minimal && !bootstrap,
copyCode: !minimal,
anchors: !minimal,
hoverCitations: !minimal,
hoverFootnotes: !minimal,
figResponsive: !minimal,
codeAnnotations: !minimal,
hoverXrefs: !minimal,
};
}

// whether code copy buttons (and clipboard.js) are enabled for this format
export function formatHasCodeCopy(
format: Format,
enabledByDefault = htmlFormatFeatureDefaults(format).copyCode,
): boolean {
return enabledByDefault
? format.metadata[kCodeCopy] !== false
: !!format.metadata[kCodeCopy];
}

export const clipboardDependency = () => {
const dependency: FormatDependency = { name: "clipboard" };
dependency.scripts = [];
Expand Down Expand Up @@ -492,7 +521,6 @@ export function createCodeBlock(
) {
const preEl = doc.createElement("PRE");
preEl.classList.add("sourceCode");
preEl.classList.add("code-with-copy");

const codeEl = doc.createElement("CODE");
codeEl.classList.add("sourceCode");
Expand Down
30 changes: 4 additions & 26 deletions src/format/html/format-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ import { bootstrapExtras } from "./format-html-bootstrap.ts";
import {
clipboardDependency,
createCodeCopyButton,
formatHasCodeCopy,
htmlFormatFeatureDefaults,
kAnchorSections,
kAxe,
kBootstrapDependencyName,
kCitationsHover,
kCodeAnnotations,
kCodeCopy,
kComments,
kDocumentCss,
kFootnotesHover,
Expand Down Expand Up @@ -306,11 +307,7 @@ export async function htmlFormatExtras(
} else {
options.tabby = format.metadata[kTabsets] || false;
}
if (featureDefaults.copyCode) {
options.copyCode = format.metadata[kCodeCopy] !== false;
} else {
options.copyCode = format.metadata[kCodeCopy] || false;
}
options.copyCode = formatHasCodeCopy(format, featureDefaults.copyCode);
if (featureDefaults.anchors) {
options.anchors = format.metadata[kAnchorSections] !== false;
} else {
Expand Down Expand Up @@ -682,23 +679,6 @@ function htmlFormatFilterParams(format: Format) {
};
}

function htmlFormatFeatureDefaults(
format: Format,
): HtmlFormatFeatureDefaults {
const bootstrap = formatHasBootstrap(format);
const minimal = format.metadata[kMinimal] === true;
return {
tabby: !minimal && !bootstrap,
copyCode: !minimal,
anchors: !minimal,
hoverCitations: !minimal,
hoverFootnotes: !minimal,
figResponsive: !minimal,
codeAnnotations: !minimal,
hoverXrefs: !minimal,
};
}

function htmlFormatPostprocessor(
format: Format,
featureDefaults?: HtmlFormatFeatureDefaults,
Expand All @@ -712,9 +692,7 @@ function htmlFormatPostprocessor(
}

// read options
const codeCopy = featureDefaults.copyCode
? format.metadata[kCodeCopy] !== false
: format.metadata[kCodeCopy] || false;
const codeCopy = formatHasCodeCopy(format, featureDefaults.copyCode);

const anchors = featureDefaults.anchors
? format.metadata[kAnchorSections] !== false
Expand Down
19 changes: 19 additions & 0 deletions tests/docs/smoke-all/2026/10/27/issue-15207.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: "Citation BibTeX block without code-copy"
author: "Author name"
date: "2025-01-01"
format: html
citation: true
code-copy: false
_quarto:
tests:
html:
ensureHtmlElements:
-
- '#quarto-citation pre.quarto-appendix-bibtex'
-
- '#quarto-citation button.code-copy-button'
- '#quarto-citation div.code-copy-outer-scaffold'
---

With `code-copy: false`, clipboard.js is not loaded, so a copy button on the BibTeX block in the citation appendix would do nothing. The BibTeX block is still rendered, but without the copy button or its scaffold, the same as other code blocks in the document (#15207).
Loading