/* blog-content.tsx spboucher.ai Web Author: Simon-Pierre Boucher Mail: contact@spboucher.ai */ import katex from "katex"; import "katex/dist/katex.min.css"; import type { BlogBlock } from "@/lib/blog"; function renderTex(tex: string, displayMode: boolean): string { return katex.renderToString(tex, { displayMode, throwOnError: false, strict: false, }); } /** Render the **bold** and inline-math \( ... \) spans used by the essays. */ function renderInline(text: string) { return text.split(/(\*\*[^*]+\*\*|\\\(.+?\\\))/g).map((part, i) => { if (part.startsWith("**") && part.endsWith("**")) { return ( {part.slice(2, -2)} ); } if (part.startsWith("\\(") && part.endsWith("\\)")) { return ( ); } return {part}; }); } /** Long-form essay body with sharp editorial typography. */ export function BlogContent({ blocks }: { blocks: BlogBlock[] }) { let paragraphIndex = 0; return (
{blocks.map((block, i) => { switch (block.type) { case "math": return (
); case "h2": return (
); case "quote": return (
{renderInline(block.text)}
); case "ul": return (
    {block.items.map((item) => (
  • ))}
); case "p": { paragraphIndex += 1; const isLead = paragraphIndex === 1; return (

{renderInline(block.text)}

); } } })}
); }