Skip to content

Commit 481eb9d

Browse files
committed
add Extras page
1 parent 9b4f35b commit 481eb9d

File tree

7 files changed

+156
-105
lines changed

7 files changed

+156
-105
lines changed

Extras.qmd

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
title: "Bonus lessons"
3+
author: "Austin Daigle"
4+
format:
5+
html:
6+
toc: true
7+
---
8+
9+
# Supplemental Materials
10+
11+
Welcome to the **Bonus lessons** page. Below are two extra chapters you can explore:
12+
13+
---
14+
15+
## Bonus: Git and GitHub
16+
17+
Learn how to create a GitHub account, set up Git on your computer, and start version-controlling your projects. This guide will walk you through:
18+
19+
- Registering for GitHub
20+
- Installing and configuring Git
21+
- Your first commit and push
22+
23+
[Go to Bonus: Git and GitHub](bonus-git-and-github.html)
24+
25+
---
26+
27+
## Alternative Data Wrangling (Class 6 Old Version)
28+
29+
This is an alternate take on **Data Wrangling Day 2**, covering the same concepts with a slightly different workflow and examples. It’s great if you want more practice or a different perspective.
30+
31+
[Go to Class 6 (Old Version)](class6_old.html)

docs/robots.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Sitemap: https://h2l2cR.com/sitemap.xml
1+
Sitemap: https://how-to-learn-to-code.github.io/Rclass-DataScience/sitemap.xml

docs/search.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,5 +638,35 @@
638638
"crumbs": [
639639
"<span class='chapter-number'>9</span>  <span class='chapter-title'>Practicing on Real-World Data</span>"
640640
]
641+
},
642+
{
643+
"objectID": "Extras.html",
644+
"href": "Extras.html",
645+
"title": "Bonus lessons",
646+
"section": "",
647+
"text": "Supplemental Materials\nWelcome to the Bonus lessons page. Below are two extra chapters you can explore:",
648+
"crumbs": [
649+
"<span class='chapter-number'>9</span>  <span class='chapter-title'>Bonus lessons</span>"
650+
]
651+
},
652+
{
653+
"objectID": "Extras.html#bonus-git-and-github",
654+
"href": "Extras.html#bonus-git-and-github",
655+
"title": "Bonus lessons",
656+
"section": "Bonus: Git and GitHub",
657+
"text": "Bonus: Git and GitHub\nLearn how to create a GitHub account, set up Git on your computer, and start version-controlling your projects. This guide will walk you through:\n\nRegistering for GitHub\n\nInstalling and configuring Git\n\nYour first commit and push\n\nGo to Bonus: Git and GitHub",
658+
"crumbs": [
659+
"<span class='chapter-number'>9</span>  <span class='chapter-title'>Bonus lessons</span>"
660+
]
661+
},
662+
{
663+
"objectID": "Extras.html#alternative-data-wrangling-class-6-old-version",
664+
"href": "Extras.html#alternative-data-wrangling-class-6-old-version",
665+
"title": "Bonus lessons",
666+
"section": "Alternative Data Wrangling (Class 6 Old Version)",
667+
"text": "Alternative Data Wrangling (Class 6 Old Version)\nThis is an alternate take on Data Wrangling Day 2, covering the same concepts with a slightly different workflow and examples. It’s great if you want more practice or a different perspective.\nGo to Class 6 (Old Version)",
668+
"crumbs": [
669+
"<span class='chapter-number'>9</span>  <span class='chapter-title'>Bonus lessons</span>"
670+
]
641671
}
642672
]

docs/site_libs/quarto-html/quarto.js

Lines changed: 49 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as tabsets from "./tabsets/tabsets.js";
2+
13
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
24
detail: {},
35
bubbles: true,
@@ -64,19 +66,41 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
6466
}
6567
};
6668

67-
// fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
68-
function fireSlideEnter(e) {
69+
// dispatch for htmlwidgets
70+
// they use slideenter event to trigger resize
71+
function fireSlideEnter() {
6972
const event = window.document.createEvent("Event");
7073
event.initEvent("slideenter", true, true);
7174
window.document.dispatchEvent(event);
7275
}
76+
7377
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
7478
tabs.forEach((tab) => {
7579
tab.addEventListener("shown.bs.tab", fireSlideEnter);
7680
});
7781

78-
// fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
79-
document.addEventListener("tabby", fireSlideEnter, false);
82+
// dispatch for shiny
83+
// they use BS shown and hidden events to trigger rendering
84+
function distpatchShinyEvents(previous, current) {
85+
if (window.jQuery) {
86+
if (previous) {
87+
window.jQuery(previous).trigger("hidden");
88+
}
89+
if (current) {
90+
window.jQuery(current).trigger("shown");
91+
}
92+
}
93+
}
94+
95+
// tabby.js listener: Trigger event for htmlwidget and shiny
96+
document.addEventListener(
97+
"tabby",
98+
function (event) {
99+
fireSlideEnter();
100+
distpatchShinyEvents(event.detail.previousTab, event.detail.tab);
101+
},
102+
false
103+
);
80104

81105
// Track scrolling and mark TOC links as active
82106
// get table of contents and sidebar (bail if we don't have at least one)
@@ -94,7 +118,7 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
94118
if (link.href.indexOf("#") !== -1) {
95119
const anchor = link.href.split("#")[1];
96120
const heading = window.document.querySelector(
97-
`[data-anchor-id=${anchor}]`
121+
`[data-anchor-id="${anchor}"]`
98122
);
99123
if (heading) {
100124
// Add the class
@@ -134,8 +158,10 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
134158
window.innerHeight + window.pageYOffset >=
135159
window.document.body.offsetHeight
136160
) {
161+
// This is the no-scroll case where last section should be the active one
137162
sectionIndex = 0;
138163
} else {
164+
// This finds the last section visible on screen that should be made active
139165
sectionIndex = [...sections].reverse().findIndex((section) => {
140166
if (section) {
141167
return window.pageYOffset >= section.offsetTop - sectionMargin;
@@ -223,17 +249,21 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
223249
}
224250

225251
async function findAndActivateCategories() {
226-
const currentPagePath = offsetAbsoluteUrl(window.location.href);
252+
// Categories search with listing only use path without query
253+
const currentPagePath = offsetAbsoluteUrl(
254+
window.location.origin + window.location.pathname
255+
);
227256
const response = await fetch(offsetRelativeUrl("listings.json"));
228257
if (response.status == 200) {
229258
return response.json().then(function (listingPaths) {
230259
const listingHrefs = [];
231260
for (const listingPath of listingPaths) {
232261
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
233262
for (const item of listingPath.items) {
263+
const encodedItem = encodeURI(item);
234264
if (
235-
item === currentPagePath ||
236-
item === currentPagePath + "index.html"
265+
encodedItem === currentPagePath ||
266+
encodedItem === currentPagePath + "index.html"
237267
) {
238268
// Resolve this path against the offset to be sure
239269
// we already are using the correct path to the listing
@@ -317,6 +347,7 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
317347
for (const child of el.children) {
318348
child.style.opacity = 0;
319349
child.style.overflow = "hidden";
350+
child.style.pointerEvents = "none";
320351
}
321352

322353
nexttick(() => {
@@ -358,6 +389,7 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
358389

359390
const clone = child.cloneNode(true);
360391
clone.style.opacity = 1;
392+
clone.style.pointerEvents = null;
361393
clone.style.display = null;
362394
toggleContents.append(clone);
363395
}
@@ -432,6 +464,7 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
432464
for (const child of el.children) {
433465
child.style.opacity = 1;
434466
child.style.overflow = null;
467+
child.style.pointerEvents = null;
435468
}
436469

437470
const placeholderEl = window.document.getElementById(
@@ -732,13 +765,14 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
732765

733766
// See if there is an active child to this element
734767
let hasActiveChild = false;
735-
for (child of el.children) {
768+
for (const child of el.children) {
736769
hasActiveChild = walk(child, depth) || hasActiveChild;
737770
}
738771

739772
// Process the collapse state if this is an UL
740773
if (el.tagName === "UL") {
741774
if (tocOpenDepth === -1 && depth > 1) {
775+
// toc-expand: false
742776
el.classList.add("collapse");
743777
} else if (
744778
depth <= tocOpenDepth ||
@@ -757,10 +791,9 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
757791
};
758792

759793
// walk the TOC and expand / collapse any items that should be shown
760-
761794
if (tocEl) {
762-
walk(tocEl, 0);
763795
updateActiveLink();
796+
walk(tocEl, 0);
764797
}
765798

766799
// Throttle the scroll event and walk peridiocally
@@ -779,6 +812,10 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
779812
window.addEventListener(
780813
"resize",
781814
throttle(() => {
815+
if (tocEl) {
816+
updateActiveLink();
817+
walk(tocEl, 0);
818+
}
782819
if (!isReaderMode()) {
783820
hideOverlappedSidebars();
784821
}
@@ -788,98 +825,7 @@ window.document.addEventListener("DOMContentLoaded", function (_event) {
788825
highlightReaderToggle(isReaderMode());
789826
});
790827

791-
// grouped tabsets
792-
window.addEventListener("pageshow", (_event) => {
793-
function getTabSettings() {
794-
const data = localStorage.getItem("quarto-persistent-tabsets-data");
795-
if (!data) {
796-
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
797-
return {};
798-
}
799-
if (data) {
800-
return JSON.parse(data);
801-
}
802-
}
803-
804-
function setTabSettings(data) {
805-
localStorage.setItem(
806-
"quarto-persistent-tabsets-data",
807-
JSON.stringify(data)
808-
);
809-
}
810-
811-
function setTabState(groupName, groupValue) {
812-
const data = getTabSettings();
813-
data[groupName] = groupValue;
814-
setTabSettings(data);
815-
}
816-
817-
function toggleTab(tab, active) {
818-
const tabPanelId = tab.getAttribute("aria-controls");
819-
const tabPanel = document.getElementById(tabPanelId);
820-
if (active) {
821-
tab.classList.add("active");
822-
tabPanel.classList.add("active");
823-
} else {
824-
tab.classList.remove("active");
825-
tabPanel.classList.remove("active");
826-
}
827-
}
828-
829-
function toggleAll(selectedGroup, selectorsToSync) {
830-
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
831-
const active = selectedGroup === thisGroup;
832-
for (const tab of tabs) {
833-
toggleTab(tab, active);
834-
}
835-
}
836-
}
837-
838-
function findSelectorsToSyncByLanguage() {
839-
const result = {};
840-
const tabs = Array.from(
841-
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
842-
);
843-
for (const item of tabs) {
844-
const div = item.parentElement.parentElement.parentElement;
845-
const group = div.getAttribute("data-group");
846-
if (!result[group]) {
847-
result[group] = {};
848-
}
849-
const selectorsToSync = result[group];
850-
const value = item.innerHTML;
851-
if (!selectorsToSync[value]) {
852-
selectorsToSync[value] = [];
853-
}
854-
selectorsToSync[value].push(item);
855-
}
856-
return result;
857-
}
858-
859-
function setupSelectorSync() {
860-
const selectorsToSync = findSelectorsToSyncByLanguage();
861-
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
862-
Object.entries(tabSetsByValue).forEach(([value, items]) => {
863-
items.forEach((item) => {
864-
item.addEventListener("click", (_event) => {
865-
setTabState(group, value);
866-
toggleAll(value, selectorsToSync[group]);
867-
});
868-
});
869-
});
870-
});
871-
return selectorsToSync;
872-
}
873-
874-
const selectorsToSync = setupSelectorSync();
875-
for (const [group, selectedName] of Object.entries(getTabSettings())) {
876-
const selectors = selectorsToSync[group];
877-
// it's possible that stale state gives us empty selections, so we explicitly check here.
878-
if (selectors) {
879-
toggleAll(selectedName, selectors);
880-
}
881-
}
882-
});
828+
tabsets.init();
883829

884830
function throttle(func, wait) {
885831
let waiting = false;

docs/site_libs/quarto-nav/quarto-nav.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,45 @@ const headroomChanged = new CustomEvent("quarto-hrChanged", {
55
composed: false,
66
});
77

8+
const announceDismiss = () => {
9+
const annEl = window.document.getElementById("quarto-announcement");
10+
if (annEl) {
11+
annEl.remove();
12+
13+
const annId = annEl.getAttribute("data-announcement-id");
14+
window.localStorage.setItem(`quarto-announce-${annId}`, "true");
15+
}
16+
};
17+
18+
const announceRegister = () => {
19+
const annEl = window.document.getElementById("quarto-announcement");
20+
if (annEl) {
21+
const annId = annEl.getAttribute("data-announcement-id");
22+
const isDismissed =
23+
window.localStorage.getItem(`quarto-announce-${annId}`) || false;
24+
if (isDismissed) {
25+
announceDismiss();
26+
return;
27+
} else {
28+
annEl.classList.remove("hidden");
29+
}
30+
31+
const actionEl = annEl.querySelector(".quarto-announcement-action");
32+
if (actionEl) {
33+
actionEl.addEventListener("click", function (e) {
34+
e.preventDefault();
35+
// Hide the bar immediately
36+
announceDismiss();
37+
});
38+
}
39+
}
40+
};
41+
842
window.document.addEventListener("DOMContentLoaded", function () {
943
let init = false;
1044

45+
announceRegister();
46+
1147
// Manage the back to top button, if one is present.
1248
let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
1349
const scrollDownBuffer = 5;

docs/site_libs/quarto-search/quarto-search.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1275,7 +1275,11 @@ async function fuseSearch(query, fuse, fuseOptions) {
12751275

12761276
// If we don't have a subfuse and the query is long enough, go ahead
12771277
// and create a subfuse to use for subsequent queries
1278-
if (now - then > kFuseMaxWait && subSearchFuse === undefined) {
1278+
if (
1279+
now - then > kFuseMaxWait &&
1280+
subSearchFuse === undefined &&
1281+
resultsRaw.length < fuseOptions.limit
1282+
) {
12791283
subSearchTerm = query;
12801284
subSearchFuse = new window.Fuse([], kFuseIndexOptions);
12811285
resultsRaw.forEach((rr) => {

0 commit comments

Comments
 (0)