const http = require('http'); const fs = require('fs'); const path = require('path'); const POSTS_DIR = path.join(__dirname, 'content/posts'); const PORT = 3002; const STATUS_CLASSES = ['stable', 'corrupted', 'experimental']; function esc(s) { return String(s).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } function slugify(title) { return String(title) .toLowerCase() .replace(/[äöü]/g, m => ({ ä: 'ae', ö: 'oe', ü: 'ue' }[m])) .replace(/ß/g, 'ss') .replace(/[^a-z0-9]+/g, '-') .replace(/^-+|-+$/g, '') || 'projekt'; } function uniqueSlug(base) { let slug = base; let i = 2; while (fs.existsSync(path.join(POSTS_DIR, slug + '.md'))) { slug = base + '-' + i; i++; } return slug; } // ── FRONTMATTER PARSEN / SCHREIBEN ────────────────────────────── function parsePost(filename) { const raw = fs.readFileSync(path.join(POSTS_DIR, filename), 'utf8'); const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/); const fm = { title: '', date: '', status_class: 'stable', status_label: '', thumb: '' }; let body = raw; if (match) { const fmBlock = match[1]; body = match[2].replace(/^\n+/, ''); fmBlock.split('\n').forEach(line => { const idx = line.indexOf(':'); if (idx === -1) return; const key = line.slice(0, idx).trim(); let val = line.slice(idx + 1).trim(); val = val.replace(/^['"]|['"]$/g, ''); if (key in fm) fm[key] = val; }); } return { filename, ...fm, body }; } function serializePost(entry) { const q = v => `'${String(v).replace(/'/g, "''")}'`; return `--- title: ${q(entry.title)} date: ${entry.date} status_class: ${q(entry.status_class)} status_label: ${q(entry.status_label)} thumb: ${q(entry.thumb)} --- ${entry.body.trim()} `; } function readAllPosts() { return fs.readdirSync(POSTS_DIR) .filter(f => f.endsWith('.md')) .map(parsePost) .sort((a, b) => (a.date < b.date ? 1 : -1)); } // ── HTML ───────────────────────────────────────────────────────── function html(posts) { const statusOptions = STATUS_CLASSES.map(c => ``).join(''); const rows = posts.map(p => `
${esc(p.filename)}// LOKALES ADMIN-PANEL · localhost:${PORT} · schreibt content/posts/*.md
| TITEL | DATUM | STATUS | DATEI |
|---|