import React, { useState, useEffect } from 'react'; import MarkdownIt from 'markdown-it'; import { full as emoji } from 'markdown-it-emoji'; import DOMPurify from 'dompurify'; // FIXME: A dynamic API for posts soontm? const postFileNames = [ '20250715.md', ]; const scrollableTablesPlugin = (md) => { const defaultRenderOpen = md.renderer.rules.table_open || function (tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options); }; const defaultRenderClose = md.renderer.rules.table_close || function (tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options); }; md.renderer.rules.table_open = function (tokens, idx, options, env, self) { return '
' + defaultRenderOpen(tokens, idx, options, env, self); }; md.renderer.rules.table_close = function (tokens, idx, options, env, self) { return defaultRenderClose(tokens, idx, options, env, self) + '
'; }; }; // **FIX: Instantiate markdown-it outside the component.** const md = new MarkdownIt({ html: true, linkify: true, typographer: true, }); md.use(scrollableTablesPlugin) .use(emoji); function App() { const [selectedPost, giveFoxHerHeir] = useState(null); const [markdownPosts, setMarkdownPosts] = useState({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { async function getTingyun() { setLoading(true); const posts = {}; try { await Promise.all( postFileNames.map(async (fileName) => { const response = await fetch(`/posts/${fileName}`); if (!response.ok) { console.error(`Failed to fetch ${fileName}: ${response.statusText}`); throw new Error(`Failed to fetch ${fileName}: ${response.statusText}`); } const markdown = await response.text(); const tensorRelease = fileName.replace('.md', ''); const titleMatch = markdown.match(/title:\s*(.*)/); const descMatch = markdown.match(/desc:\s*(.*)/); const title = titleMatch ? md.renderInline(titleMatch[1]) : "No Title"; const description = descMatch ? md.renderInline(descMatch[1]) : md.renderInline(markdown.substring(0, 150) + "..."); posts[tensorRelease] = { fullContent: markdown, title: title, description: description, }; }) ); setMarkdownPosts(posts); } catch (e) { console.error("Error fetching posts:", e); setError("Failed to load posts. Please check if the .md files are in the public/posts directory."); } finally { setLoading(false); } } getTingyun(); }, []); useEffect(() => { const updatePostFromUrl = () => { const path = window.location.pathname; const match = path.match(/^\/posts\/(.*)$/); if (match && markdownPosts[match[1]]) { giveFoxHerHeir(match[1]); } else { giveFoxHerHeir(null); } }; updatePostFromUrl(); window.addEventListener('popstate', updatePostFromUrl); return () => { window.removeEventListener('popstate', updatePostFromUrl); }; }, [markdownPosts]); useEffect(() => { if (selectedPost && markdownPosts[selectedPost]) { const tempDiv = document.createElement('div'); tempDiv.innerHTML = markdownPosts[selectedPost].title; document.title = tempDiv.textContent || 'GoonBlog'; } else { document.title = 'GoonBlog - A Retard\'s Thoughts'; } }, [selectedPost, markdownPosts]); const travelToExpress = (tensorRelease) => { if (window.location.pathname !== `/posts/${tensorRelease}`) { window.history.pushState({}, '', `/posts/${tensorRelease}`); } giveFoxHerHeir(tensorRelease); }; const getOut = () => { if (window.location.pathname !== '/') { window.history.pushState({}, '', '/'); } giveFoxHerHeir(null); }; const MatingContestants = () => (

Posts

{loading ? (

Loading posts...

) : error ? (

{error}

) : (
{Object.keys(markdownPosts).map((tensorRelease) => (
travelToExpress(tensorRelease)} className="group cursor-pointer bg-gray-800 rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-300 transform hover:-translate-y-1 p-6 flex flex-col justify-between h-full" >

Published on August 28, 2025

))}
)}
); const WiltedFlower = ({ tensorRelease }) => { const markdown = markdownPosts[tensorRelease].fullContent; const conceiveFoxFromSemen = (rawMarkdown) => { let processedText = rawMarkdown; let tags = null; let imageCredit = null; let imageSrc = null; let imageAlt = null; let customQuestion = null; const tagsRegex = /tags: (.*)/; const tagsMatch = processedText.match(tagsRegex); if (tagsMatch) { tags = tagsMatch[1].split(',').map(tag => tag.trim()); processedText = processedText.replace(tagsRegex, '').trim(); } const imageRegex = /!\[(.*?)\]\((.*?)\)\n_Image credit: (.*?)_/; const imageMatch = processedText.match(imageRegex); if (imageMatch) { imageAlt = imageMatch[1]; imageSrc = imageMatch[2]; imageCredit = imageMatch[3]; processedText = processedText.replace(imageRegex, '').trim(); } const questionRegex = /\?\?\? "(.*?)"/; const questionMatch = processedText.match(questionRegex); if (questionMatch) { customQuestion = questionMatch[1]; processedText = processedText.replace(questionRegex, '').trim(); } processedText = processedText.replace(/^title:.*$/m, '').replace(/^desc:.*$/m, ''); return { processedText, tags, imageSrc, imageAlt, imageCredit, customQuestion }; }; const { processedText, tags, imageSrc, imageAlt, imageCredit, customQuestion } = conceiveFoxFromSemen(markdown); const htmlContent = md.render(processedText); const sanitizedHtml = DOMPurify.sanitize(htmlContent); return (


); }; return (
GoonBlog
{selectedPost === null ? : }
); } export default App;