blob: 65c08510a1587f01015f4134ec3502f1b789ae0d (
plain)
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
|
#!/usr/bin/env node
/**
* Site Generator
*
* Reads markdown summaries from summaries/{id}.md and embeds them into
* data/books.json so the site works offline without a server.
*
* Usage: node build.js
*
* Run this after editing any summary markdown files.
*/
const fs = require('fs');
const path = require('path');
const SUMMARIES_DIR = path.join(__dirname, 'summaries');
const BOOKS_JSON = path.join(__dirname, 'data', 'books.json');
function readSummary(id) {
const filePath = path.join(SUMMARIES_DIR, `${id}.md`);
if (!fs.existsSync(filePath)) {
return null;
}
const content = fs.readFileSync(filePath, 'utf8').trim();
const lines = content.split('\n');
// Skip the title line (# Title) and return the rest
const summaryLines = lines.slice(1).join('\n').trim();
return summaryLines || null;
}
function build() {
console.log('Building site...\n');
// Read books.json
const booksData = JSON.parse(fs.readFileSync(BOOKS_JSON, 'utf8'));
let updated = 0;
let missing = [];
for (const book of booksData.books) {
const summary = readSummary(book.id);
if (summary) {
book.summary = summary;
updated++;
console.log(`✓ ${book.title}`);
} else {
delete book.summary;
missing.push(book.title);
console.log(`✗ ${book.title} (no summary file)`);
}
}
// Write updated books.json
fs.writeFileSync(BOOKS_JSON, JSON.stringify(booksData, null, 2));
console.log('\n=== Build Complete ===');
console.log(`Summaries embedded: ${updated}`);
console.log(`Missing summaries: ${missing.length}`);
if (missing.length > 0) {
console.log('\nCreate these files to add summaries:');
missing.forEach(title => {
const book = booksData.books.find(b => b.title === title);
console.log(` summaries/${book.id}.md`);
});
}
console.log('\nSite is ready. Open index.html in a browser.');
}
build();
|