-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate_exercises.mjs
More file actions
124 lines (99 loc) · 4.55 KB
/
Copy pathupdate_exercises.mjs
File metadata and controls
124 lines (99 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/**
* Utility script to update the exercise dropdown
*/
import fs from 'fs';
import path from 'path';
const REPOS = [
{
owner: 'impermeable',
repo: 'waterproof-exercise-sheets',
branch: 'main',
title: 'Waterproof Exercise Sheets'
},
{
owner: 'impermeable',
repo: 'introduction-to-proof-sheets',
branch: 'main',
title: 'Introduction To Proof Sheets'
}
];
async function fetchRepoFiles(repoInfo) {
const { owner, repo, branch } = repoInfo;
const response = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`);
if (!response.ok) {
throw new Error(`Failed to fetch info from github api for '${owner}/${repo}': ${response.status} ${response.statusText}`);
}
const data = await response.json();
return data.tree.filter((node) => node.type === 'blob' && node.path.endsWith('.mv'));
}
async function updateDropdown() {
try {
console.log('Fetching exercise files from GitHub...');
const indentationLevel = 5; // in tabs
const indentation = '\t'.repeat(indentationLevel);
const options = [indentation + '<option value="">-- Select Sheet --</option>'];
let totalFiles = 0;
for (const repoInfo of REPOS) {
const files = await fetchRepoFiles(repoInfo);
totalFiles += files.length;
// Sort files logically by chapter / lecture, then by sheet
files.sort((a, b) => {
const getNum = (path, regex) => {
const match = path.match(regex);
return match ? parseInt(match[1], 10) : 0;
};
const aCh = getNum(a.path, /(?:ch|lecture)(\d+)/i);
const bCh = getNum(b.path, /(?:ch|lecture)(\d+)/i);
if (aCh !== bCh) return aCh - bCh;
const aSh = getNum(a.path, /sheet(\d+)/i);
const bSh = getNum(b.path, /sheet(\d+)/i);
if (aSh !== bSh) return aSh - bSh;
return a.path.localeCompare(b.path);
});
// Add separator line
if (REPOS.length > 0) {
options.push(`${indentation}<option disabled>──────────</option>`);
}
files.forEach(file => {
let basename = path.basename(file.path);
let prettyName = basename;
if (basename === 'waterproof_tutorial.mv') {
prettyName = 'Waterproof Tutorial';
} else {
prettyName = prettyName
.replace('.mv', '')
.replace(/^ch(\d+)_/i, 'Chapter $1: ')
.replace(/^sheet(\d+)_/i, 'Sheet $1: ')
.replace(/_/g, ' ');
prettyName = prettyName.replace(/\b\w/g, c => c.toUpperCase());
}
if (repoInfo.repo === 'introduction-to-proof-sheets') {
const match = file.path.match(/^lecture(\d+)\//i);
if (match) {
prettyName = `Lecture ${match[1]} - ${prettyName}`;
}
}
const rawUrl = `https://raw.githubusercontent.com/${repoInfo.owner}/${repoInfo.repo}/${repoInfo.branch}/${file.path}`;
options.push(`${indentation}<option value="${rawUrl}">${repoInfo.title} - ${prettyName}</option>`);
});
}
// Locate index.html
const htmlPath = path.join(process.cwd(), 'out', 'index.html');
let htmlContent = fs.readFileSync(htmlPath, 'utf-8');
const selectRegex = /(<select id="exercise-dropdown">)[\s\S]*?(<\/select>)/m;
if (!selectRegex.test(htmlContent)) {
throw new Error('Could not find <select id="exercise-dropdown"> in index.html');
}
const newHtmlContent = htmlContent.replace(
selectRegex,
`$1\n${options.join('\n')}\n${'\t'.repeat(indentationLevel - 1)}$2`
);
fs.writeFileSync(htmlPath, newHtmlContent, 'utf-8');
console.log(`Successfully updated dropdown list in out/index.html with ${totalFiles} files from ${REPOS.length} repositories:`);
REPOS.forEach(repo => console.log(`- ${repo.title} (${repo.repo})`));
} catch (error) {
console.error("An error occurred while updating the dropdown:", error);
process.exit(1);
}
}
updateDropdown();