const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..'); function parseFrontmatter(content) { const m = content.match(/^---\n([\s\S]*?)\n---/); if (!m) return {}; const fm = {}; for (const line of m[1].split('\n')) { const idx = line.indexOf(':'); if (idx === -1) continue; const key = line.slice(0, idx).trim(); let val = line.slice(idx + 1).trim(); // Remove quotes if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) val = val.slice(1, -1); fm[key] = val; } return fm; } function guessTag(folderName) { if (folderName.startsWith('dgx-spark')) return 'DGX Spark'; if (folderName.startsWith('gitea')) return 'Gitea'; if (folderName.startsWith('searxng')) return 'SearXNG'; if (folderName.startsWith('ollama')) return 'Ollama'; if (folderName.startsWith('browser')) return 'Browser'; if (folderName.startsWith('game')) return 'Game'; return 'Tech'; } function getTag(fm, folderName, defaultTag) { if (fm.tag) return fm.tag; if (fm.tags) return fm.tags.replace(/[\[\]]/g, '').split(',')[0].trim(); if (defaultTag === 'blog') return 'AI'; return guessTag(folderName); } function scanDir(dir, urlPrefix, isBlog) { if (!fs.existsSync(dir)) return []; const entries = fs.readdirSync(dir, { withFileTypes: true }); const posts = []; for (const e of entries) { if (!e.isDirectory()) continue; const indexPath = path.join(dir, e.name, 'index.md'); if (!fs.existsSync(indexPath)) continue; const content = fs.readFileSync(indexPath, 'utf8'); const fm = parseFrontmatter(content); const title = fm.title || e.name; const tag = getTag(fm, e.name, isBlog ? 'blog' : 'tech'); // Extract date let date = null; const dateMatch = e.name.match(/^(\d{4}-\d{2}-\d{2})/); if (dateMatch) { date = dateMatch[1]; } else if (fm.date) { date = fm.date.slice(0, 10); } else { // Use file mtime const stat = fs.statSync(indexPath); date = stat.mtime.toISOString().slice(0, 10); } posts.push({ title, date, tag, url: `${urlPrefix}${e.name}` }); } posts.sort((a, b) => b.date.localeCompare(a.date)); return posts.slice(0, 5); } const tech = scanDir(path.join(ROOT, 'docs-tech'), '/tech/', false); const blog = scanDir(path.join(ROOT, 'docs'), '/blog/', true); const outPath = path.join(ROOT, 'src', 'data', 'recent-posts.json'); fs.writeFileSync(outPath, JSON.stringify({ tech, blog }, null, 2)); console.log(`Generated ${outPath} (tech: ${tech.length}, blog: ${blog.length})`);