ids theme: automatic chapter numbering, ported from gdoc2reveal
Chapter headings (#) are numbered automatically when the presentation is
opened: "1. Introduction", "2. Methods", and so on. References, appendix
and thank-you chapters keep their bare titles and are not counted.
Manually typed leading numbers ("# 2. Methods") are stripped before
renumbering, so decks migrated from the old Google Docs pipeline and
repeated numbering runs stay stable.
The menu plugin and the transcript view show the numbers, too; the
Overview slide's table of contents prepends them as orange
.ids-toc-number spans flush with the slide heading, with the theme's
drawn list markers suppressed for the top-level entries (sub-headings
keep their bullets). Decks rendered with slide_level: 1 are left
unnumbered -- there, headings denote slides, not chapters.
Bump version to 0.9.1.9010.
Change-Id: I233086e039aee0da156cfaaebe04d05f3ad851ce
diff --git a/inst/reveal.js-5.2.1/css/theme/source/ids.scss b/inst/reveal.js-5.2.1/css/theme/source/ids.scss
index e0a7634..e833b8f 100644
--- a/inst/reveal.js-5.2.1/css/theme/source/ids.scss
+++ b/inst/reveal.js-5.2.1/css/theme/source/ids.scss
@@ -202,11 +202,17 @@
// Ordered lists: the CSS list-item counter honours the HTML start/value
// attributes, so pandoc's `start`/`value` lists keep their numbers. Numbers
-// are right-aligned into the indent, ending just before the item text.
+// are anchored with their right edge $idsNumberGap away from the item text
+// (a shrink-to-fit box; anchoring from the right instead of a fixed-width,
+// right-aligned box, because over-wide numbers would otherwise overflow
+// INTO the text). Longer numbers like "10." grow to the left.
+$idsNumberGap: 0.3em;
+
.reveal .slides section:not(.title-frame) ol > li::before {
content: counter(list-item, decimal) "." !important;
- width: calc(#{$idsListIndent} - 0.12em) !important;
- text-align: right !important;
+ left: auto !important;
+ right: 100% !important;
+ margin-right: $idsNumberGap !important;
}
// Checkbox (pandoc task) lists keep their checkboxes, no markers on top.
@@ -1124,9 +1130,23 @@
/*********************************************
* OVERVIEW / TOC SLIDES
*********************************************/
-/* Entries stay at the normal slide body size and keep the theme's link
- colour, so they read as the navigation links they are. Only the denser
- two-column variant with sub-headings is scaled down. */
+/* The auto-generated TOC lists the chapters with their numbers as
+ .ids-toc-number spans in the marker colour, prepended to the entry
+ titles: the enumeration therefore starts flush with the slide heading
+ (the drawn ol/ul markers are suppressed for the top-level entries;
+ sub-headings below their chapters keep their bullets). Entries stay at
+ the normal slide body size and keep the theme's link colour, so they
+ read as the navigation links they are. Only the denser two-column
+ variant with sub-headings is scaled down. */
+.reveal .slides section:not(.title-frame) .ids-overview-toc {
+ padding-left: 0 !important;
+}
+.reveal .slides section:not(.title-frame) .ids-overview-toc > li::before {
+ content: none !important;
+}
+.reveal .ids-overview-toc .ids-toc-number {
+ color: var(--r-list-bullet-color);
+}
.reveal .ids-overview-toc {
list-style: none;
margin: 0.2em 0 0 0;
diff --git a/inst/reveal.js-5.2.1/dist/theme/ids.css b/inst/reveal.js-5.2.1/dist/theme/ids.css
index 43fe710..dd54e86 100644
--- a/inst/reveal.js-5.2.1/dist/theme/ids.css
+++ b/inst/reveal.js-5.2.1/dist/theme/ids.css
@@ -415,8 +415,9 @@
.reveal .slides section:not(.title-frame) ol > li::before {
content: counter(list-item, decimal) "." !important;
- width: calc(0.65em - 0.12em) !important;
- text-align: right !important;
+ left: auto !important;
+ right: 100% !important;
+ margin-right: 0.3em !important;
}
.reveal .slides section:not(.title-frame) ul.task-list li::before {
@@ -1146,9 +1147,26 @@
/*********************************************
* OVERVIEW / TOC SLIDES
*********************************************/
-/* Entries stay at the normal slide body size and keep the theme's link
- colour, so they read as the navigation links they are. Only the denser
- two-column variant with sub-headings is scaled down. */
+/* The auto-generated TOC lists the chapters with their numbers as
+ .ids-toc-number spans in the marker colour, prepended to the entry
+ titles: the enumeration therefore starts flush with the slide heading
+ (the drawn ol/ul markers are suppressed for the top-level entries;
+ sub-headings below their chapters keep their bullets). Entries stay at
+ the normal slide body size and keep the theme's link colour, so they
+ read as the navigation links they are. Only the denser two-column
+ variant with sub-headings is scaled down. */
+.reveal .slides section:not(.title-frame) .ids-overview-toc {
+ padding-left: 0 !important;
+}
+
+.reveal .slides section:not(.title-frame) .ids-overview-toc > li::before {
+ content: none !important;
+}
+
+.reveal .ids-overview-toc .ids-toc-number {
+ color: var(--r-list-bullet-color);
+}
+
.reveal .ids-overview-toc {
list-style: none;
margin: 0.2em 0 0 0;
diff --git a/inst/rmarkdown/templates/revealjs_presentation/resources/default.html b/inst/rmarkdown/templates/revealjs_presentation/resources/default.html
index cf56f8e..45b55e4 100644
--- a/inst/rmarkdown/templates/revealjs_presentation/resources/default.html
+++ b/inst/rmarkdown/templates/revealjs_presentation/resources/default.html
@@ -1013,16 +1013,101 @@
</script>
$endif$
<script>
+ // Chapter classification shared by the numbering and overview TOC scripts
+ // below (ported from the gdoc2reveal workflow): chapters are the level-1
+ // (pandoc "title-slide") sections of a deck. References, appendix and
+ // thank-you chapters are exempt from numbering and left out of the
+ // overview TOC.
+ window.idsChapters = (function () {
+ var EXCLUDED = ['references', 'literatur', 'literaturverzeichnis',
+ 'referenzen', 'publikationen', 'herausgeberschaften', 'appendix',
+ 'anhang'];
+ var THANK_YOU = /thank[\s\S]*you|vielen[\s\S]*dank/i;
+ // like the old pipeline: drop a leading "12.", "3)" or "-" plus
+ // whitespace, but leave headings like "3D printing" alone
+ var STRIP_NUMBER = /^\s*[-\d]+\s*(?:[.)]|\s)\s*/;
+
+ function isExcluded(title) {
+ var t = title.trim().toLowerCase();
+ return EXCLUDED.indexOf(t) !== -1 || THANK_YOU.test(t);
+ }
+
+ function isChapterSlide(slide) {
+ return !slide.classList.contains('title-frame') &&
+ slide.classList.contains('title-slide') &&
+ !!slide.querySelector('h1');
+ }
+
+ return {
+ isExcluded: isExcluded,
+ isChapterSlide: isChapterSlide,
+ stripNumber: function (title) { return title.replace(STRIP_NUMBER, ''); }
+ };
+ })();
+</script>
+<script>
+ // Automatic chapter numbering (ported from the gdoc2reveal workflow):
+ // chapter headings get a sequential "1. ", "2. " ... prefix, except
+ // references, appendix and thank-you chapters, which keep their bare
+ // titles and are not counted. Manually typed leading numbers are stripped
+ // first, so rendering twice or renumbering an already numbered deck stays
+ // stable. Runs before the overview TOC builder below: the menu plugin and
+ // the transcript view show the numbers, while the overview TOC strips
+ // them again and numbers its ordered list entries instead, like the old
+ // Google Docs workflow did.
+ (function () {
+ function firstTextNode(el) {
+ var n = el.firstChild;
+ while (n && n.nodeType !== Node.TEXT_NODE) n = n.nextSibling;
+ return n;
+ }
+
+ function numberChapters() {
+ if (typeof Reveal === 'undefined' || !Reveal.isReady()) return;
+ var n = 0;
+ Reveal.getSlides().forEach(function (slide) {
+ if (!window.idsChapters.isChapterSlide(slide)) return;
+ var h = slide.querySelector('h1');
+ if (window.idsChapters.isExcluded(h.textContent)) return;
+ n += 1;
+ slide.dataset.chapterNumber = n;
+ var t = firstTextNode(h);
+ if (!t) {
+ t = document.createTextNode('');
+ h.insertBefore(t, h.firstChild);
+ }
+ var label = window.idsChapters.stripNumber(t.nodeValue);
+ if (t === h.firstChild) {
+ t.nodeValue = n + '. ' + label;
+ } else {
+ // the heading starts with an element (e.g. <em>): put the number
+ // in front of it instead of into the first text node
+ t.nodeValue = label;
+ h.insertBefore(document.createTextNode(n + '. '), h.firstChild);
+ }
+ });
+ }
+
+ if (typeof Reveal !== 'undefined') {
+ if (Reveal.isReady()) numberChapters();
+ else Reveal.addEventListener('ready', numberChapters);
+ }
+ })();
+</script>
+<script>
// Slides whose (only) heading is "Overview" or "Überblick" are
// automatically populated with a table of contents of the deck's h1 slide
// headings, replacing whatever body content the slide had (ported from the
// Google Docs slide workflow). By adding {data-overview-subheadings=true}
// to the heading, h2 sub-headings are included below their chapters and
// the list is laid out in two columns. References and appendix chapters
- // (English and German) are left out. Styling in the ids theme.
+ // (English and German) are left out. The chapter numbers (set on the
+ // headings by the numbering script above) are prepended to the entry
+ // titles as .ids-toc-number spans, so the enumeration starts flush with
+ // the slide heading; the ids theme styles the spans in the marker colour
+ // and suppresses its own drawn list markers for the top-level entries.
(function () {
var TITLES = ['overview', 'überblick'];
- var EXCLUDED = ['references', 'literatur', 'literaturverzeichnis', 'appendix', 'anhang'];
function isOverviewSlide(slide) {
var h = slide.querySelector('h1,h2');
@@ -1041,7 +1126,7 @@
var includeSub = (heading.getAttribute('data-overview-subheadings') || '')
.toLowerCase() !== 'false'
&& heading.hasAttribute('data-overview-subheadings');
- var list = document.createElement('ul');
+ var list = document.createElement('ol');
list.className = 'ids-overview-toc';
if (includeSub) list.classList.add('with-subheadings');
var subList = null;
@@ -1051,12 +1136,22 @@
var h = slide.querySelector('h1,h2');
if (!h) return;
if (h.tagName === 'H1') {
- excluded = EXCLUDED.indexOf(h.textContent.trim().toLowerCase()) !== -1;
+ excluded = window.idsChapters.isExcluded(h.textContent);
}
if (excluded || (h.tagName !== 'H1' && !includeSub)) return;
var link = document.createElement('a');
link.href = '#/' + slide.id;
- link.textContent = h.textContent;
+ if (h.tagName === 'H1' && slide.dataset.chapterNumber) {
+ var number = document.createElement('span');
+ number.className = 'ids-toc-number';
+ number.textContent = slide.dataset.chapterNumber + '. ';
+ link.appendChild(number);
+ link.appendChild(document.createTextNode(
+ window.idsChapters.stripNumber(h.textContent)
+ ));
+ } else {
+ link.textContent = h.textContent;
+ }
var item = document.createElement('li');
item.appendChild(link);
if (h.tagName === 'H1') {