From e1ebf41c88f002e7f5824cec328a003eacd9980f Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 20:14:11 +0000 Subject: [PATCH 1/2] Put each code fold inside its language tab Quarto hoists a figure's code folds above the figure, so R and Python folds stacked outside the tabset. A small after-body script moves each fold into the tab for its language, and the fold label no longer says R. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_019xfc9pT9FcXoVbp61GC7NJ --- .gitignore | 1 + _quarto-website.yml | 1 + tabset-code-in-tabs.html | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 tabset-code-in-tabs.html diff --git a/.gitignore b/.gitignore index d93d7e5fb..6678e8e49 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ # Source HTML partials we intentionally track (not build output). !qwt-reveal-toggle.html !theme-picker.html +!tabset-code-in-tabs.html !anchor-landing.html !watch-anchors.html !table-roles.html diff --git a/_quarto-website.yml b/_quarto-website.yml index d0ad2f2c9..9e14f9beb 100644 --- a/_quarto-website.yml +++ b/_quarto-website.yml @@ -200,6 +200,7 @@ format: # Replaces Quarto's two-way toggle with a Light / Off-white / Parchment / Dark dropdown. include-in-header: theme-picker.html include-after-body: + - tabset-code-in-tabs.html - anchor-landing.html - watch-anchors.html - table-roles.html diff --git a/tabset-code-in-tabs.html b/tabset-code-in-tabs.html new file mode 100644 index 000000000..5bdccb69b --- /dev/null +++ b/tabset-code-in-tabs.html @@ -0,0 +1,39 @@ + From d9a8a44c1c9d25a84688aa67db75df8ed0489566 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 20:23:16 +0000 Subject: [PATCH 2/2] Move code folds into tabs on slides too The slide tabsets use tabby markup, so the script now selects panes and tabs without Bootstrap class names, and a fold with no language match takes the first unused tab. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_019xfc9pT9FcXoVbp61GC7NJ --- _quarto-website.yml | 1 + tabset-code-in-tabs.html | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/_quarto-website.yml b/_quarto-website.yml index 9e14f9beb..7ed5a118a 100644 --- a/_quarto-website.yml +++ b/_quarto-website.yml @@ -236,6 +236,7 @@ format: search: false # decks duplicate the HTML pages, so the search indexes only the HTML format theme: [simple, styles-reveal.scss] include-in-header: qwt-reveal-toggle.html + include-after-body: tabset-code-in-tabs.html slide-number: true chalkboard: false preview-links: auto diff --git a/tabset-code-in-tabs.html b/tabset-code-in-tabs.html index 5bdccb69b..e47e025b2 100644 --- a/tabset-code-in-tabs.html +++ b/tabset-code-in-tabs.html @@ -4,33 +4,39 @@ // so an R and a Python tab end up with their folds stacked above the whole figure. // For every language tabset, take the run of folds immediately before it (or before the figure // that holds it), match each fold to a tab by language, and move it to the top of that tab. +// The selectors cover both the website tabsets (Bootstrap) and the slide tabsets (tabby). document.querySelectorAll("div.panel-tabset").forEach(function (tabset) { var anchor = tabset.closest("div.quarto-float") || tabset; - var panes = Array.prototype.slice.call(tabset.querySelectorAll(":scope > .tab-content > .tab-pane")); - var tabs = Array.prototype.slice.call(tabset.querySelectorAll(":scope > .nav-tabs > li > a")); + var panes = Array.prototype.slice.call(tabset.querySelectorAll(":scope > .tab-content > div")); + var tabs = Array.prototype.slice.call(tabset.querySelectorAll(":scope > ul > li > a")); var folds = []; var node = anchor.previousElementSibling; while (node && node.matches("details.code-fold")) { folds.unshift(node); node = node.previousElementSibling; } - if (folds.length === 0 || folds.length !== panes.length) { + if (folds.length === 0 || folds.length !== panes.length || tabs.length !== panes.length) { return; } var language = function (fold) { - var pre = fold.querySelector("pre.sourceCode"); - var found = pre && Array.prototype.find.call(pre.classList, function (name) { + var code = fold.querySelector("pre.sourceCode"); + var found = code && Array.prototype.find.call(code.classList, function (name) { return name !== "sourceCode" && name !== "downlit" && name !== "code-with-copy"; }); return found ? found.toLowerCase() : ""; }; var used = {}; - folds.forEach(function (fold, i) { + var unused = function () { + return tabs.findIndex(function (tab, j) { + return !used[j]; + }); + }; + folds.forEach(function (fold) { var index = tabs.findIndex(function (tab, j) { return !used[j] && tab.textContent.trim().toLowerCase() === language(fold); }); if (index < 0) { - index = i; + index = unused(); } used[index] = true; panes[index].insertBefore(fold, panes[index].firstChild);