#!/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();