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
4 changes: 4 additions & 0 deletions news/changelog-1.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ All changes included in 1.6:
- ([#10328](https://github.com/quarto-dev/quarto-cli/issues/10328)): Interpret subcells as subfloats when subcap count matches subcell count.
- ([#10624](https://github.com/quarto-dev/quarto-cli/issues/10624)): Don't crash when proof environments are empty in `pdf`.

## `dashboard` Format

- ([#10340](https://github.com/quarto-dev/quarto-cli/issues/10340)): Build card title correctly in the presence of equations and other markup.

## `html` Format

- Fix `kbd` element styling on dark themes.
Expand Down
29 changes: 22 additions & 7 deletions src/format/dashboard/format-dashboard-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const kCardHeaderClass = "card-header";
const kCardFooterClass = "card-footer";
const kCardTitleClass = "card-title";
const kCardToolbarClass = "card-toolbar";
const kCardTitleToolbarClass = "card-title-toolbar";

const kCardSidebarClass = "card-sidebar";

Expand Down Expand Up @@ -152,17 +151,27 @@ export function processCards(doc: Document, dashboardMeta: DashboardMeta) {
if (cardHeaderEl) {
// Loose text gets grouped into a div for alignment purposes
// Always place this element first no matter what else is going on
const looseText: string[] = [];
const looseText: Node[] = [];

// See if there is a toolbar in the header
const cardToolbarEl = cardHeaderEl.querySelector(`.${kCardToolbarClass}`);

for (const headerChildNode of cardHeaderEl.childNodes) {
const isText = (node: Node) => node.nodeType === Node.TEXT_NODE;
const isEmphasis = (node: Node) => node.nodeName === "EM";
const isBold = (node: Node) => node.nodeName === "STRONG";
const isMath = (node: Node) =>
node.nodeName === "SPAN" &&
(node as Element).classList.contains("math") &&
(node as Element).classList.contains("inline");

for (const headerChildNode of Array.from(cardHeaderEl.childNodes)) {
if (
headerChildNode.nodeType === Node.TEXT_NODE &&
headerChildNode.textContent.trim() !== ""
isText(headerChildNode) ||
isEmphasis(headerChildNode) ||
isBold(headerChildNode) ||
isMath(headerChildNode)
) {
looseText.push(headerChildNode.textContent.trim());
looseText.push(headerChildNode);
headerChildNode.parentNode?.removeChild(headerChildNode);
}
}
Expand All @@ -172,7 +181,13 @@ export function processCards(doc: Document, dashboardMeta: DashboardMeta) {
const classes = [kCardTitleClass];

const titleTextDiv = makeEl("DIV", { classes }, doc);
titleTextDiv.innerText = looseText.join(" ");
const innerSpan = makeEl("SPAN", {
attributes: { style: "display: inline" },
}, doc);
titleTextDiv.appendChild(innerSpan);
for (const node of looseText) {
innerSpan.appendChild(node);
}
if (cardToolbarEl) {
cardToolbarEl.insertBefore(titleTextDiv, cardToolbarEl.firstChild);
} else {
Expand Down
20 changes: 20 additions & 0 deletions tests/docs/smoke-all/2024/09/13/issue-10340.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: "Test Dashboard"
format: dashboard
_quarto:
tests:
dashboard:
ensureHtmlElements:
- []
-
- "div.card-header > span.math.inline"
- "div.card-header > em"
- "div.card-header > strong"
---

##
::: {.card title="Math $y=mx+b$ between *emphasized* and **bold** words"}

Math $y=mx+b$ between words

:::
Loading