fresh start
This commit is contained in:
parent
62c3e2d368
commit
7f86647175
570 changed files with 4895 additions and 866 deletions
184
.old/build.mjs
Executable file
184
.old/build.mjs
Executable file
|
|
@ -0,0 +1,184 @@
|
|||
// build.mjs — The Fold Within Earth
|
||||
// Markdown-native static site builder with no external generator.
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Imports
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import yaml from "js-yaml";
|
||||
import { marked } from "marked";
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Setup
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const CONFIG_PATH = path.join(__dirname, "config.json");
|
||||
const CONTENT_DIR = path.join(__dirname, "content");
|
||||
const PUBLIC_DIR = path.join(__dirname, "public");
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Config loader
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
let config = {};
|
||||
try {
|
||||
const cfgText = await fs.readFile(CONFIG_PATH, "utf8");
|
||||
config = JSON.parse(cfgText);
|
||||
console.log("Loaded config.json");
|
||||
} catch {
|
||||
console.warn("config.json not found or invalid; using defaults.");
|
||||
config = {
|
||||
siteTitle: "The Fold Within Earth",
|
||||
baseUrl: "",
|
||||
};
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Utilities
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
async function walk(dir) {
|
||||
const entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
const files = await Promise.all(
|
||||
entries.map(async (entry) => {
|
||||
const res = path.resolve(dir, entry.name);
|
||||
return entry.isDirectory() ? walk(res) : res;
|
||||
})
|
||||
);
|
||||
return Array.prototype.concat(...files);
|
||||
}
|
||||
|
||||
function parseFrontMatter(text) {
|
||||
if (!text.startsWith("---")) return { meta: {}, body: text };
|
||||
const end = text.indexOf("---", 3);
|
||||
if (end === -1) return { meta: {}, body: text };
|
||||
const yamlText = text.slice(3, end).trim();
|
||||
const body = text.slice(end + 3).trim();
|
||||
let meta = {};
|
||||
try {
|
||||
meta = yaml.load(yamlText) || {};
|
||||
} catch (err) {
|
||||
console.error("YAML parse error:", err);
|
||||
}
|
||||
return { meta, body };
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Build Posts
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
async function buildPosts() {
|
||||
const mdFiles = (await walk(CONTENT_DIR)).filter((f) => f.endsWith(".md"));
|
||||
console.log(`Found ${mdFiles.length} markdown files.`);
|
||||
|
||||
const postsPromises = mdFiles.map(async (file) => {
|
||||
try {
|
||||
const text = await fs.readFile(file, "utf8");
|
||||
const { meta, body } = parseFrontMatter(text);
|
||||
if (meta.status === "draft") return null;
|
||||
|
||||
const html = marked.parse(body);
|
||||
const slug =
|
||||
meta.slug ||
|
||||
path.basename(file, ".md").replace(/\s+/g, "-").toLowerCase();
|
||||
|
||||
const relPath = path.relative(CONTENT_DIR, file);
|
||||
const section = relPath.split(path.sep)[0] || "general";
|
||||
|
||||
return {
|
||||
title: meta.title || slug,
|
||||
date: meta.date || new Date().toISOString().slice(0, 10),
|
||||
excerpt: meta.excerpt || body.slice(0, 200),
|
||||
tags: meta.tags || [],
|
||||
section,
|
||||
slug,
|
||||
cover: meta.cover || "",
|
||||
html,
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(`Error reading ${file}:`, err);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
const postObjects = await Promise.all(postsPromises);
|
||||
const posts = postObjects.filter(Boolean);
|
||||
posts.sort((a, b) => b.date.localeCompare(a.date));
|
||||
console.log(`Processed ${posts.length} posts.`);
|
||||
return posts;
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Copy Helpers
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
async function copyDir(src, dest) {
|
||||
await fs.mkdir(dest, { recursive: true });
|
||||
const entries = await fs.readdir(src, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
const srcPath = path.join(src, entry.name);
|
||||
const destPath = path.join(dest, entry.name);
|
||||
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
||||
else await fs.copyFile(srcPath, destPath);
|
||||
}
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
// Main Build
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
async function main() {
|
||||
const posts = await buildPosts();
|
||||
|
||||
// Reset public dir
|
||||
await fs.rm(PUBLIC_DIR, { recursive: true, force: true });
|
||||
await fs.mkdir(PUBLIC_DIR, { recursive: true });
|
||||
|
||||
// Copy static assets
|
||||
const staticFiles = [
|
||||
"index.html",
|
||||
"styles.css",
|
||||
"app.js",
|
||||
"render.js",
|
||||
"sanitize.js",
|
||||
"util.js",
|
||||
"mud.js",
|
||||
];
|
||||
|
||||
for (const f of staticFiles) {
|
||||
try {
|
||||
await fs.copyFile(path.join(__dirname, f), path.join(PUBLIC_DIR, f));
|
||||
} catch {
|
||||
console.warn(`⚠️ Skipped missing static file: ${f}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy content for direct linking
|
||||
await copyDir(CONTENT_DIR, path.join(PUBLIC_DIR, "content"));
|
||||
|
||||
// Write index.json
|
||||
await fs.writeFile(
|
||||
path.join(PUBLIC_DIR, "index.json"),
|
||||
JSON.stringify(posts, null, 2),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
// Write search.json
|
||||
const searchData = posts.map((p) => ({
|
||||
title: p.title,
|
||||
excerpt: p.excerpt,
|
||||
tags: p.tags.join(" "),
|
||||
section: p.section,
|
||||
slug: p.slug,
|
||||
}));
|
||||
await fs.writeFile(
|
||||
path.join(PUBLIC_DIR, "search.json"),
|
||||
JSON.stringify(searchData, null, 2),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
console.log("✅ Build complete. Files written to /public.");
|
||||
}
|
||||
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
await main().catch((err) => {
|
||||
console.error("Build failed:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue