Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dashboard - build card title correctly in the presence of math and other markup #10800

Merged
merged 2 commits into from
Sep 20, 2024
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