Skip to content

Commit e40cab5

Browse files
jeremymanningclaude
andcommitted
fix: Comprehensive fixes for GitHub Pages and GitHub Actions
## GitHub Pages Fixes - Add figures/ and fonts/ directories to deployment workflow - Change root URL redirect from demos to course outline (slides/) - Add Font Awesome icons to outline page, replacing all emojis - Reorder navigation links (Outline before Demos) on both pages - Update deployment triggers to include figures/ and fonts/ paths ## GitHub Actions Test Fixes - Update test file paths after demo renumbering (chatbot-evolution is now demo 02) - Fix test-demo02-tokenization.mjs → references 03-tokenization - Fix test-demo03-clustering.mjs → references 04-embeddings - Fix test-demo06-sampling.mjs → references 07-gpt-playground - Fix test-demo08-lda.mjs → references 09-topic-modeling - Fix test-demo11-analogies.mjs → references 12-analogies - Fix test-demo12-bm25.mjs → references 13-semantic-search - Fix all Demo 15 test files → reference 02-chatbot-evolution - Fix build-slides.yml YAML syntax (heredoc indentation) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 00cb4ae commit e40cab5

22 files changed

+121
-111
lines changed

.github/workflows/build-slides.yml

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -145,72 +145,72 @@ jobs:
145145
146146
# Create HTML viewer with Dartmouth branding (matching syllabus link format)
147147
cat > "$dir/${filename}.html" << 'VIEWER_EOF'
148-
<!DOCTYPE html>
149-
<html lang="en">
150-
<head>
151-
<meta charset="UTF-8">
152-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
153-
<title>FILENAME_PLACEHOLDER - PSYC 51.07</title>
154-
<style>
155-
* { margin: 0; padding: 0; box-sizing: border-box; }
156-
body {
157-
font-family: 'Helvetica Neue', Arial, sans-serif;
158-
background: #f5f5f5;
159-
color: #333;
160-
}
161-
.header {
162-
background: #00693e; /* Dartmouth Green */
163-
padding: 15px 20px;
164-
display: flex;
165-
justify-content: space-between;
166-
align-items: center;
167-
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
168-
}
169-
.header h1 {
170-
color: white;
171-
font-size: 1.4em;
172-
font-weight: 500;
173-
}
174-
.header .nav {
175-
display: flex;
176-
gap: 10px;
177-
}
178-
.header a {
179-
color: white;
180-
text-decoration: none;
181-
padding: 8px 16px;
182-
background: rgba(255,255,255,0.15);
183-
border-radius: 4px;
184-
font-size: 0.9em;
185-
transition: background 0.2s;
186-
}
187-
.header a:hover { background: rgba(255,255,255,0.25); }
188-
.pdf-container {
189-
width: 100%;
190-
height: calc(100vh - 60px);
191-
}
192-
iframe {
193-
width: 100%;
194-
height: 100%;
195-
border: none;
196-
}
197-
</style>
198-
</head>
199-
<body>
200-
<div class="header">
201-
<h1>FILENAME_PLACEHOLDER - Models of Language and Communication</h1>
202-
<div class="nav">
203-
<a href="FILENAME_PLACEHOLDER.pdf" download>Download PDF</a>
204-
<a href="../../index.html">All Slides</a>
205-
<a href="https://github.com/ContextLab/llm-course">GitHub</a>
206-
</div>
207-
</div>
208-
<div class="pdf-container">
209-
<iframe src="FILENAME_PLACEHOLDER.pdf"></iframe>
210-
</div>
211-
</body>
212-
</html>
213-
VIEWER_EOF
148+
<!DOCTYPE html>
149+
<html lang="en">
150+
<head>
151+
<meta charset="UTF-8">
152+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
153+
<title>FILENAME_PLACEHOLDER - PSYC 51.07</title>
154+
<style>
155+
* { margin: 0; padding: 0; box-sizing: border-box; }
156+
body {
157+
font-family: 'Helvetica Neue', Arial, sans-serif;
158+
background: #f5f5f5;
159+
color: #333;
160+
}
161+
.header {
162+
background: #00693e; /* Dartmouth Green */
163+
padding: 15px 20px;
164+
display: flex;
165+
justify-content: space-between;
166+
align-items: center;
167+
box-shadow: 0 2px 10px rgba(0,0,0,0.2);
168+
}
169+
.header h1 {
170+
color: white;
171+
font-size: 1.4em;
172+
font-weight: 500;
173+
}
174+
.header .nav {
175+
display: flex;
176+
gap: 10px;
177+
}
178+
.header a {
179+
color: white;
180+
text-decoration: none;
181+
padding: 8px 16px;
182+
background: rgba(255,255,255,0.15);
183+
border-radius: 4px;
184+
font-size: 0.9em;
185+
transition: background 0.2s;
186+
}
187+
.header a:hover { background: rgba(255,255,255,0.25); }
188+
.pdf-container {
189+
width: 100%;
190+
height: calc(100vh - 60px);
191+
}
192+
iframe {
193+
width: 100%;
194+
height: 100%;
195+
border: none;
196+
}
197+
</style>
198+
</head>
199+
<body>
200+
<div class="header">
201+
<h1>FILENAME_PLACEHOLDER - Models of Language and Communication</h1>
202+
<div class="nav">
203+
<a href="FILENAME_PLACEHOLDER.pdf" download>Download PDF</a>
204+
<a href="../../index.html">All Slides</a>
205+
<a href="https://github.com/ContextLab/llm-course">GitHub</a>
206+
</div>
207+
</div>
208+
<div class="pdf-container">
209+
<iframe src="FILENAME_PLACEHOLDER.pdf"></iframe>
210+
</div>
211+
</body>
212+
</html>
213+
VIEWER_EOF
214214
215215
# Replace placeholder with actual filename
216216
sed -i "s/FILENAME_PLACEHOLDER/$filename/g" "$dir/${filename}.html"

.github/workflows/deploy-demos.yml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ on:
88
paths:
99
- 'demos/**'
1010
- 'slides/**'
11+
- 'figures/**'
12+
- 'fonts/**'
1113
- '.github/workflows/deploy-demos.yml'
1214

1315
# Allow manual trigger from Actions tab
@@ -61,25 +63,29 @@ jobs:
6163
6264
- name: Create build artifact
6365
run: |
64-
echo "Preparing demos and slides for deployment..."
66+
echo "Preparing demos, slides, and assets for deployment..."
6567
mkdir -p _site/demos
6668
mkdir -p _site/slides
69+
mkdir -p _site/figures
70+
mkdir -p _site/fonts
6771
cp -r demos/* _site/demos/
6872
cp -r slides/* _site/slides/
73+
cp -r figures/* _site/figures/
74+
cp -r fonts/* _site/fonts/
6975
7076
# Create a .nojekyll file to bypass Jekyll processing
7177
touch _site/.nojekyll
7278
73-
# Create root redirect to demos
79+
# Create root redirect to course outline
7480
cat > _site/index.html << 'EOF'
7581
<!DOCTYPE html>
7682
<html>
7783
<head>
78-
<meta http-equiv="refresh" content="0; url=demos/">
79-
<script>window.location.href = 'demos/';</script>
84+
<meta http-equiv="refresh" content="0; url=slides/">
85+
<script>window.location.href = 'slides/';</script>
8086
</head>
8187
<body>
82-
<p>Redirecting to <a href="demos/">demos</a>...</p>
88+
<p>Redirecting to <a href="slides/">course outline</a>...</p>
8389
</body>
8490
</html>
8591
EOF
@@ -150,6 +156,10 @@ jobs:
150156
echo "Build directory structure:"
151157
ls -la _site/
152158
echo ""
159+
echo "Figures and fonts:"
160+
ls -la _site/figures/ | head -10
161+
ls -la _site/fonts/ | head -10
162+
echo ""
153163
echo "Demos available:"
154164
find _site -type d -maxdepth 1 | sort
155165

demos/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,8 +433,8 @@
433433
<div class="nav-container">
434434
<div class="logo">Interactive Demonstrations</div>
435435
<div class="nav-links">
436-
<a href="./" class="active">Demos</a>
437436
<a href="../slides/">Outline</a>
437+
<a href="./" class="active">Demos</a>
438438
<a href="https://github.com/ContextLab/llm-course" target="_blank">GitHub</a>
439439
<a href="https://pbs.dartmouth.edu/undergraduate/courses-and-syllabi/topics-courses" target="_blank">Course Info</a>
440440
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme">

slides/index.html

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>Course Outline - Models of Language and Communication</title>
77
<meta name="description" content="Course syllabus and lecture schedule for PSYC 51.17: Language Models from Scratch">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
89
<link rel="stylesheet" href="../demos/shared/css/demo-styles.css">
910

1011
<style>
@@ -558,8 +559,8 @@
558559
<nav class="course-nav" id="navbar">
559560
<div class="logo">Course Outline</div>
560561
<div class="nav-links">
561-
<a href="../demos/">Demos</a>
562562
<a href="./" class="active">Outline</a>
563+
<a href="../demos/">Demos</a>
563564
<a href="https://github.com/ContextLab/llm-course" target="_blank">GitHub</a>
564565
<a href="https://pbs.dartmouth.edu/undergraduate/courses-and-syllabi/topics-courses" target="_blank">Course Info</a>
565566
<button class="theme-toggle" id="themeToggle" aria-label="Toggle theme">
@@ -573,15 +574,15 @@ <h1>Models of Language and Communication</h1>
573574
<p>PSYC 51.17 - Explore the building blocks of modern language models, from classical NLP techniques to cutting-edge transformers and large language models.</p>
574575
<div class="course-meta">
575576
<div class="meta-item">
576-
<span class="icon">&#128197;</span>
577+
<span class="icon"><i class="fa-regular fa-calendar"></i></span>
577578
<span>MWF 10:10-11:15</span>
578579
</div>
579580
<div class="meta-item">
580-
<span class="icon">&#128218;</span>
581+
<span class="icon"><i class="fa-solid fa-book"></i></span>
581582
<span>X-Hour: Thu 12:15-1:05</span>
582583
</div>
583584
<div class="meta-item">
584-
<span class="icon">&#127891;</span>
585+
<span class="icon"><i class="fa-solid fa-graduation-cap"></i></span>
585586
<span>Winter 2026</span>
586587
</div>
587588
</div>
@@ -950,26 +951,26 @@ <h1>Models of Language and Communication</h1>
950951
if (lecture.slides) {
951952
html += '<div class="resource-group"><div class="resource-label">Slides</div><div class="resource-links">';
952953
if (lecture.slides.html) {
953-
html += '<a href="' + escapeHtml(lecture.slides.html) + '" class="resource-link primary"><span class="icon">\u{1F310}</span> HTML</a>';
954+
html += '<a href="' + escapeHtml(lecture.slides.html) + '" class="resource-link primary"><span class="icon"><i class="fa-solid fa-globe"></i></span> HTML</a>';
954955
}
955956
if (lecture.slides.pdf) {
956-
html += '<a href="' + escapeHtml(lecture.slides.pdf) + '" class="resource-link"><span class="icon">\u{1F4C4}</span> PDF</a>';
957+
html += '<a href="' + escapeHtml(lecture.slides.pdf) + '" class="resource-link"><span class="icon"><i class="fa-solid fa-file-pdf"></i></span> PDF</a>';
957958
}
958959
html += '</div></div>';
959960
}
960961

961962
// Notebook
962963
if (lecture.notebook) {
963964
html += '<div class="resource-group"><div class="resource-label">Materials</div><div class="resource-links">';
964-
html += '<a href="' + escapeHtml(lecture.notebook) + '" class="resource-link"><span class="icon">\u{1F4D3}</span> X-hour Notebook</a>';
965+
html += '<a href="' + escapeHtml(lecture.notebook) + '" class="resource-link"><span class="icon"><i class="fa-solid fa-book-open"></i></span> X-hour Notebook</a>';
965966
html += '</div></div>';
966967
}
967968

968969
// Demos
969970
if (lecture.demos && lecture.demos.length > 0) {
970971
html += '<div class="resource-group"><div class="resource-label">Try It</div><div class="resource-links">';
971972
lecture.demos.forEach(demo => {
972-
html += '<a href="' + escapeHtml(demo.url) + '" class="resource-link' + (demo.primary ? ' primary' : '') + '"><span class="icon">\u{1F3AE}</span> ' + escapeHtml(demo.name) + '</a>';
973+
html += '<a href="' + escapeHtml(demo.url) + '" class="resource-link' + (demo.primary ? ' primary' : '') + '"><span class="icon"><i class="fa-solid fa-gamepad"></i></span> ' + escapeHtml(demo.name) + '</a>';
973974
});
974975
html += '</div></div>';
975976
}
@@ -978,8 +979,7 @@ <h1>Models of Language and Communication</h1>
978979
if (lecture.readings && lecture.readings.length > 0) {
979980
html += '<div class="resource-group readings"><div class="resource-label">Readings</div>';
980981
lecture.readings.forEach(reading => {
981-
const icon = reading.icon || '\u{1F4D6}';
982-
html += '<div class="reading-item"><span class="icon">' + icon + '</span><span>';
982+
html += '<div class="reading-item"><span class="icon"><i class="fa-solid fa-book"></i></span><span>';
983983
html += '<a href="' + escapeHtml(reading.url) + '" target="_blank">' + escapeHtml(reading.text) + '</a>';
984984
if (reading.desc) html += ' - ' + escapeHtml(reading.desc);
985985
html += '</span></div>';
@@ -993,15 +993,15 @@ <h1>Models of Language and Communication</h1>
993993
// Assignment released
994994
if (lecture.assignment) {
995995
const parts = lecture.assignment.text.split(':');
996-
html += '<div class="assignment-badge"><span class="icon">\u{1F4DD}</span><span><strong>' + escapeHtml(parts[0]) + ':</strong> ';
996+
html += '<div class="assignment-badge"><span class="icon"><i class="fa-solid fa-clipboard-list"></i></span><span><strong>' + escapeHtml(parts[0]) + ':</strong> ';
997997
html += '<a href="' + escapeHtml(lecture.assignment.url) + '" target="_blank">' + escapeHtml(parts.slice(1).join(':').trim()) + '</a>';
998998
if (lecture.assignment.due) html += ' (Due: ' + escapeHtml(lecture.assignment.due) + ')';
999999
html += '</span></div>';
10001000
}
10011001

10021002
// Assignment due
10031003
if (lecture.assignmentDue) {
1004-
html += '<div class="assignment-badge due"><span class="icon">\u{1F4C5}</span><span><strong>' + escapeHtml(lecture.assignmentDue) + '</strong></span></div>';
1004+
html += '<div class="assignment-badge due"><span class="icon"><i class="fa-regular fa-calendar-check"></i></span><span><strong>' + escapeHtml(lecture.assignmentDue) + '</strong></span></div>';
10051005
}
10061006

10071007
html += '</div>';
@@ -1016,15 +1016,15 @@ <h1>Models of Language and Communication</h1>
10161016
html += '<h2 class="week-title">' + escapeHtml(week.title) + '</h2>';
10171017
html += '<p class="week-subtitle">' + escapeHtml(week.subtitle || '') + '</p>';
10181018
html += '</div>';
1019-
html += '<span class="expand-icon">\u25BC</span>';
1019+
html += '<span class="expand-icon"><i class="fa-solid fa-chevron-down"></i></span>';
10201020
html += '</div>';
10211021

10221022
html += '<div class="week-content' + (week.expanded ? ' expanded' : '') + '">';
10231023

10241024
// No class notice
10251025
if (week.noClassNotice) {
10261026
html += '<div class="no-class-notice">';
1027-
html += '<h4>\u{1F4C5} ' + escapeHtml(week.noClassNotice) + '</h4>';
1027+
html += '<h4><i class="fa-regular fa-calendar-xmark"></i> ' + escapeHtml(week.noClassNotice) + '</h4>';
10281028
if (week.noClassDetails) {
10291029
html += '<p>' + escapeHtml(week.noClassDetails.trim()) + '</p>';
10301030
}

tests/test-demo02-tokenization.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ global.fetch = async (url) => {
4747
};
4848

4949
// Load the BPE visualizer code
50-
const bpeCode = await readFile(join(__dirname, '../demos/02-tokenization/js/bpe-visualizer.js'), 'utf-8');
50+
const bpeCode = await readFile(join(__dirname, '../demos/03-tokenization/js/bpe-visualizer.js'), 'utf-8');
5151

5252
// Remove everything from document.addEventListener('DOMContentLoaded' onwards
5353
const domContentLoadedIndex = bpeCode.indexOf("document.addEventListener('DOMContentLoaded'");

tests/test-demo03-clustering.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const __filename = fileURLToPath(import.meta.url);
1313
const __dirname = dirname(__filename);
1414

1515
// Load the clustering module
16-
const clusteringCode = await readFile(join(__dirname, '../demos/03-embeddings/js/clustering.js'), 'utf-8');
16+
const clusteringCode = await readFile(join(__dirname, '../demos/04-embeddings/js/clustering.js'), 'utf-8');
1717
const executableCode = clusteringCode
1818
.replace(/export class (\w+)/g, 'globalThis.$1 = class $1')
1919
.replace(/export default .+;?/g, '');

tests/test-demo06-sampling.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const __filename = fileURLToPath(import.meta.url);
1313
const __dirname = dirname(__filename);
1414

1515
// Load the sampling strategies module
16-
const samplingCode = await readFile(join(__dirname, '../demos/06-gpt-playground/js/sampling-strategies.js'), 'utf-8');
16+
const samplingCode = await readFile(join(__dirname, '../demos/07-gpt-playground/js/sampling-strategies.js'), 'utf-8');
1717

1818
// Convert ES module to eval-able code and make class globally available
1919
const executableCode = samplingCode

tests/test-demo08-lda.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const __filename = fileURLToPath(import.meta.url);
1414
const __dirname = dirname(__filename);
1515

1616
// Load the LDA module
17-
const ldaCode = await readFile(join(__dirname, '../demos/08-topic-modeling/js/lda.js'), 'utf-8');
17+
const ldaCode = await readFile(join(__dirname, '../demos/09-topic-modeling/js/lda.js'), 'utf-8');
1818
const executableCode = ldaCode
1919
.replace(/export class (\w+)/g, 'globalThis.$1 = class $1')
2020
.replace(/export default .+;?/g, '');

tests/test-demo11-analogies.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const __filename = fileURLToPath(import.meta.url);
1313
const __dirname = dirname(__filename);
1414

1515
// Load the embeddings module
16-
const embeddingsCode = await readFile(join(__dirname, '../demos/11-analogies/js/embeddings.js'), 'utf-8');
16+
const embeddingsCode = await readFile(join(__dirname, '../demos/12-analogies/js/embeddings.js'), 'utf-8');
1717
const executableCode = embeddingsCode
1818
.replace(/export class (\w+)/g, 'globalThis.$1 = class $1')
1919
.replace(/export default .+;?/g, '');

tests/test-demo11-embeddings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# Get the directory of this script to resolve relative paths
1212
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
13-
DATA_DIR = os.path.join(SCRIPT_DIR, '..', 'demos', '11-analogies', 'data')
13+
DATA_DIR = os.path.join(SCRIPT_DIR, '..', 'demos', '12-analogies', 'data')
1414
DEFAULT_JSON = os.path.join(DATA_DIR, 'glove-50d.json')
1515

1616
def test_embeddings(json_file=None):

0 commit comments

Comments
 (0)