/* blog.ts spboucher.ai Web Author: Simon-Pierre Boucher Mail: contact@spboucher.ai */ import fs from "node:fs"; import path from "node:path"; export interface BlogPostMeta { slug: string; file: string; title: string; excerpt: string; date: string; // ISO date dateLabel: string; tags: string[]; } export type BlogBlock = | { type: "h2"; text: string } | { type: "p"; text: string } | { type: "quote"; text: string } | { type: "ul"; items: string[] } | { type: "math"; tex: string }; export interface BlogPost extends BlogPostMeta { blocks: BlogBlock[]; readingMinutes: number; } /** Registry of published essays — sources live in /blog/*.txt. */ const registry: BlogPostMeta[] = [ { slug: "macroeconomics-of-white-collar-automation", file: "blog4.txt", title: "The Macroeconomics of White-Collar Automation", excerpt: "White-collar workers sit near the center of developed economies — their incomes support taxes, mortgages, consumption, and urban housing. If AI automates cognitive work faster than institutions redistribute the gains, the shock becomes macroeconomic, not merely occupational.", date: "2026-08-09", dateLabel: "August 9, 2026", tags: ["AI", "Economics", "Macroeconomics"], }, { slug: "cost-of-intelligence", file: "blog1.txt", title: "What Happens When the Cost of Intelligence Approaches Zero?", excerpt: "For most of economic history, useful cognitive work required scarce, educated humans. AI breaks that coupling — and when the price of a fundamental input collapses, the entire economy reorganizes around whatever remains scarce.", date: "2026-08-09", dateLabel: "August 9, 2026", tags: ["AI", "Economics"], }, { slug: "who-owns-ai-wealth", file: "blog2.txt", title: "If AI Creates Enormous Wealth, Who Owns It?", excerpt: "Growth and the distribution of growth are two different things. AI may create extraordinary wealth while shifting the defining economic divide from skilled versus unskilled labor to those who sell labor versus those who own productive intelligence.", date: "2026-08-09", dateLabel: "August 9, 2026", tags: ["AI", "Economics", "Ownership"], }, { slug: "ai-prevents-its-own-singularity", file: "blog3.txt", title: "What If AI Prevents Its Own Singularity?", excerpt: "The intelligence explosion assumes fresh information. But as machines generate more of the internet they learn from, recursive contamination could turn the exponential into a plateau — unless AI becomes radically more empirical.", date: "2026-08-09", dateLabel: "August 9, 2026", tags: ["AI", "Data", "Scaling"], }, ]; /** Parse the constrained Markdown subset used by the essays. */ function parseBlocks(raw: string): BlogBlock[] { const lines = raw.split("\n"); const blocks: BlogBlock[] = []; let listItems: string[] | null = null; let mathLines: string[] | null = null; const flushList = () => { if (listItems && listItems.length > 0) { blocks.push({ type: "ul", items: listItems }); } listItems = null; }; for (const rawLine of lines) { const line = rawLine.trim(); // Display math: $$ ... $$ on one line, or a fenced multi-line block. if (mathLines !== null) { if (line === "$$" || line.endsWith("$$")) { if (line !== "$$") mathLines.push(line.slice(0, -2).trim()); blocks.push({ type: "math", tex: mathLines.join("\n").trim() }); mathLines = null; } else { mathLines.push(line); } continue; } if (line.startsWith("$$")) { flushList(); const inner = line.slice(2); if (inner.endsWith("$$") && inner.length >= 2) { blocks.push({ type: "math", tex: inner.slice(0, -2).trim() }); } else { mathLines = inner.trim() ? [inner.trim()] : []; } continue; } if (line.length === 0) { flushList(); continue; } if (line.startsWith("# ")) { // Post title — carried by the registry, not repeated in the body. flushList(); continue; } if (line.startsWith("## ")) { flushList(); blocks.push({ type: "h2", text: line.slice(3).trim() }); continue; } if (line.startsWith("> ")) { flushList(); blocks.push({ type: "quote", text: line.slice(2).trim() }); continue; } if (line.startsWith("* ")) { (listItems ??= []).push(line.slice(2).trim().replace(/,$/, "")); continue; } flushList(); blocks.push({ type: "p", text: line }); } flushList(); if (mathLines !== null && mathLines.length > 0) { blocks.push({ type: "math", tex: mathLines.join("\n").trim() }); } return blocks; } function loadPost(meta: BlogPostMeta): BlogPost { const raw = fs.readFileSync( path.join(process.cwd(), "blog", meta.file), "utf8", ); const blocks = parseBlocks(raw); const words = raw.split(/\s+/).filter(Boolean).length; return { ...meta, blocks, readingMinutes: Math.max(1, Math.round(words / 220)) }; } /** All posts, newest first (registry order breaks ties). */ export function getBlogPosts(): BlogPost[] { return [...registry] .map(loadPost) .sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0)); } export function getBlogPost(slug: string): BlogPost | undefined { const meta = registry.find((p) => p.slug === slug); return meta ? loadPost(meta) : undefined; } export function getBlogSlugs(): string[] { return registry.map((p) => p.slug); }