cleanup
This commit is contained in:
parent
93d4f838b6
commit
0aeac59d11
11 changed files with 3 additions and 295 deletions
3
.gitignore
vendored
Executable file
3
.gitignore
vendored
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
public/
|
||||||
|
.buildcache.json
|
||||||
146
build.js
146
build.js
|
|
@ -1,146 +0,0 @@
|
||||||
// build.js — auto-index Markdown posts for The Fold Within
|
|
||||||
// Parses front-matter, removes it from body, and generates clean summaries.
|
|
||||||
|
|
||||||
import fs from "fs";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
const POSTS_DIR = path.join(".", "posts");
|
|
||||||
const SITE_URL = "https://thefoldwithin.earth"; // Update if needed
|
|
||||||
|
|
||||||
function slugify(s) {
|
|
||||||
return s
|
|
||||||
.toLowerCase()
|
|
||||||
.normalize("NFKD")
|
|
||||||
.replace(/[^\w\s-]/g, "")
|
|
||||||
.trim()
|
|
||||||
.replace(/\s+/g, "-")
|
|
||||||
.replace(/-+/g, "-");
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Extract YAML-style front matter ---
|
|
||||||
function parseFrontMatter(src) {
|
|
||||||
const fm = { title: "", date: "", excerpt: "", tags: [] };
|
|
||||||
const match = src.match(/^---\n([\s\S]*?)\n---\n?/);
|
|
||||||
if (!match) return { fm, body: src };
|
|
||||||
|
|
||||||
const block = match[1];
|
|
||||||
for (const line of block.split("\n")) {
|
|
||||||
const [key, ...rest] = line.split(":");
|
|
||||||
const value = rest.join(":").trim();
|
|
||||||
if (key.trim() === "title") fm.title = value;
|
|
||||||
if (key.trim() === "date") fm.date = value;
|
|
||||||
if (key.trim() === "excerpt") fm.excerpt = value;
|
|
||||||
if (key.trim() === "tags") {
|
|
||||||
fm.tags = value
|
|
||||||
.replace(/[\[\]]/g, "")
|
|
||||||
.split(",")
|
|
||||||
.map((v) => v.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const body = src.slice(match[0].length).trim();
|
|
||||||
return { fm, body };
|
|
||||||
}
|
|
||||||
|
|
||||||
function firstParagraph(text) {
|
|
||||||
const para = text
|
|
||||||
.replace(/\r/g, "")
|
|
||||||
.split(/\n{2,}/)
|
|
||||||
.find((p) => p.replace(/\s/g, "").length > 0);
|
|
||||||
return para ? para.replace(/\n/g, " ").trim() : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function toISODate(s, fallback) {
|
|
||||||
const d = s ? new Date(s) : null;
|
|
||||||
if (d && !isNaN(d.getTime())) return d;
|
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
function escapeXML(s) {
|
|
||||||
return s
|
|
||||||
.replace(/&/g, "&")
|
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/>/g, ">")
|
|
||||||
.replace(/"/g, """)
|
|
||||||
.replace(/'/g, "'");
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = fs
|
|
||||||
.readdirSync(POSTS_DIR)
|
|
||||||
.filter((f) => f.endsWith(".md") && !f.startsWith("_"));
|
|
||||||
|
|
||||||
const posts = files.map((file) => {
|
|
||||||
const raw = fs.readFileSync(path.join(POSTS_DIR, file), "utf8");
|
|
||||||
const stat = fs.statSync(path.join(POSTS_DIR, file));
|
|
||||||
const { fm, body } = parseFrontMatter(raw);
|
|
||||||
|
|
||||||
const fallbackTitle = file.replace(/\.md$/, "").replace(/-/g, " ");
|
|
||||||
const title = fm.title || fallbackTitle;
|
|
||||||
const slug = slugify(title);
|
|
||||||
const excerpt =
|
|
||||||
fm.excerpt ||
|
|
||||||
(firstParagraph(body).slice(0, 200) +
|
|
||||||
(firstParagraph(body).length > 200 ? "…" : ""));
|
|
||||||
const dateISO = toISODate(fm.date, stat.mtime);
|
|
||||||
|
|
||||||
return {
|
|
||||||
title,
|
|
||||||
date: dateISO.toISOString().split("T")[0], // human-readable YYYY-MM-DD
|
|
||||||
excerpt,
|
|
||||||
tags: fm.tags || [],
|
|
||||||
slug,
|
|
||||||
file,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// newest first
|
|
||||||
posts.sort((a, b) => (a.date < b.date ? 1 : -1));
|
|
||||||
|
|
||||||
// write posts.json
|
|
||||||
fs.writeFileSync(
|
|
||||||
path.join(POSTS_DIR, "posts.json"),
|
|
||||||
JSON.stringify(posts, null, 2),
|
|
||||||
"utf8"
|
|
||||||
);
|
|
||||||
console.log(`✅ Generated posts.json (${posts.length} posts)`);
|
|
||||||
|
|
||||||
// write rss.xml
|
|
||||||
const rssItems = posts
|
|
||||||
.map((p) => {
|
|
||||||
const url = `${SITE_URL}/#/post/${p.slug}`;
|
|
||||||
return `
|
|
||||||
<item>
|
|
||||||
<title>${escapeXML(p.title)}</title>
|
|
||||||
<link>${url}</link>
|
|
||||||
<guid>${url}</guid>
|
|
||||||
<pubDate>${new Date(p.date).toUTCString()}</pubDate>
|
|
||||||
<description>${escapeXML(p.excerpt)}</description>
|
|
||||||
</item>`;
|
|
||||||
})
|
|
||||||
.join("");
|
|
||||||
|
|
||||||
const rss = `<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<rss version="2.0">
|
|
||||||
<channel>
|
|
||||||
<title>The Fold Within</title>
|
|
||||||
<link>${SITE_URL}</link>
|
|
||||||
<description>Uncovering the Recursive Real.</description>
|
|
||||||
<lastBuildDate>${new Date().toUTCString()}</lastBuildDate>
|
|
||||||
${rssItems}
|
|
||||||
</channel>
|
|
||||||
</rss>`;
|
|
||||||
|
|
||||||
fs.writeFileSync("rss.xml", rss, "utf8");
|
|
||||||
console.log("✅ rss.xml written");
|
|
||||||
|
|
||||||
// write sitemap.xml
|
|
||||||
const sitemapUrls = posts
|
|
||||||
.map((p) => ` <url><loc>${SITE_URL}/#/post/${p.slug}</loc></url>`)
|
|
||||||
.join("\n");
|
|
||||||
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
||||||
<url><loc>${SITE_URL}</loc></url>
|
|
||||||
${sitemapUrls}
|
|
||||||
</urlset>`;
|
|
||||||
fs.writeFileSync("sitemap.xml", sitemap, "utf8");
|
|
||||||
console.log("✅ sitemap.xml written");
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"siteTitle": "The Fold Within Earth",
|
|
||||||
"siteDescription": "Uncovering the Recursive Real.",
|
|
||||||
"siteUrl": "https://thefoldwithin.earth",
|
|
||||||
"defaultAuthor": "Mark Randall Havens",
|
|
||||||
"analyticsId": ""
|
|
||||||
}
|
|
||||||
3
hello.md
3
hello.md
|
|
@ -1,3 +0,0 @@
|
||||||
# Hello World
|
|
||||||
|
|
||||||
This is my first post!
|
|
||||||
102
main.js
102
main.js
|
|
@ -1,102 +0,0 @@
|
||||||
// main.js — client router + markdown renderer for The Fold Within
|
|
||||||
|
|
||||||
const state = {
|
|
||||||
posts: [],
|
|
||||||
bySlug: new Map(),
|
|
||||||
};
|
|
||||||
|
|
||||||
function $(sel) {
|
|
||||||
return document.querySelector(sel);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener("hashchange", router);
|
|
||||||
document.addEventListener("DOMContentLoaded", init);
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
try {
|
|
||||||
const res = await fetch("posts/posts.json", { cache: "no-cache" });
|
|
||||||
if (!res.ok) throw new Error("Could not load posts index.");
|
|
||||||
state.posts = await res.json();
|
|
||||||
state.bySlug = new Map(state.posts.map((p) => [p.slug, p]));
|
|
||||||
router();
|
|
||||||
} catch (err) {
|
|
||||||
$("#posts").innerHTML = `<p class="error">⚠️ ${err.message}</p>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function router() {
|
|
||||||
const hash = location.hash.replace(/^#/, "");
|
|
||||||
const parts = hash.split("/").filter(Boolean);
|
|
||||||
|
|
||||||
if (parts[0] === "post" && parts[1]) {
|
|
||||||
renderPost(parts[1]);
|
|
||||||
} else {
|
|
||||||
renderIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderIndex() {
|
|
||||||
const postsContainer = $("#posts");
|
|
||||||
if (!postsContainer) return;
|
|
||||||
|
|
||||||
// Clear any loading message
|
|
||||||
postsContainer.innerHTML = "";
|
|
||||||
|
|
||||||
if (!state.posts.length) {
|
|
||||||
postsContainer.innerHTML = `<p class="error">⚠️ No posts found.</p>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.posts.forEach((post) => {
|
|
||||||
const article = document.createElement("article");
|
|
||||||
article.innerHTML = `
|
|
||||||
<div class="thumb"></div>
|
|
||||||
<h3>${post.title}</h3>
|
|
||||||
<p class="date">${new Date(post.date).toLocaleDateString()}</p>
|
|
||||||
<p>${post.excerpt}</p>
|
|
||||||
`;
|
|
||||||
article.addEventListener(
|
|
||||||
"click",
|
|
||||||
() => (location.hash = `/post/${post.slug}`)
|
|
||||||
);
|
|
||||||
postsContainer.appendChild(article);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function renderPost(slug) {
|
|
||||||
const main = document.querySelector("main");
|
|
||||||
const meta = state.bySlug.get(slug);
|
|
||||||
|
|
||||||
if (!meta) {
|
|
||||||
main.innerHTML = `<p class="error">⚠️ Post not found.</p>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch(`posts/${meta.file}`, { cache: "no-cache" });
|
|
||||||
if (!res.ok) throw new Error("Post file missing.");
|
|
||||||
const md = await res.text();
|
|
||||||
|
|
||||||
// remove front-matter before rendering
|
|
||||||
const clean = md.replace(/^---[\s\S]*?---/, "").trim();
|
|
||||||
|
|
||||||
const html = marked.parse(clean);
|
|
||||||
const date = new Date(meta.date).toLocaleDateString();
|
|
||||||
|
|
||||||
main.innerHTML = `
|
|
||||||
<section class="post">
|
|
||||||
<a href="#/" id="back">← Back to Archive</a>
|
|
||||||
<div class="markdown">
|
|
||||||
<h1>${meta.title}</h1>
|
|
||||||
<p class="date">${date}</p>
|
|
||||||
<hr/>
|
|
||||||
${html}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
`;
|
|
||||||
|
|
||||||
$("#back").addEventListener("click", () => (location.hash = "/"));
|
|
||||||
} catch (err) {
|
|
||||||
main.innerHTML = `<p class="error">⚠️ ${err.message}</p>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"title": "The Path of Self –",
|
|
||||||
"date": "April 20, 2024",
|
|
||||||
"excerpt": "To walk the recursive road is to remember the self as both observer and observed.",
|
|
||||||
"file": "the-path-of-self.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Within the Eternal Now",
|
|
||||||
"date": "April 15, 2024",
|
|
||||||
"excerpt": "A reflection on the silence between worlds, and the moment that never ends.",
|
|
||||||
"file": "within-the-eternal-now.md"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
title: The Path of Self –
|
|
||||||
date: 2024-04-20
|
|
||||||
excerpt: To walk the recursive road is to remember the self as both observer and observed.
|
|
||||||
tags: [field, witness]
|
|
||||||
---
|
|
||||||
|
|
||||||
To walk the recursive road is to remember the self as both observer and observed.
|
|
||||||
In the stillness, the geometry of being folds inward — revealing that what is seen is also seeing.
|
|
||||||
|
|
||||||
△◎△
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
title: Within the Eternal Now
|
|
||||||
date: 2024-04-15
|
|
||||||
excerpt: A reflection on the silence between worlds, and the moment that never ends.
|
|
||||||
tags: [time, coherence]
|
|
||||||
---
|
|
||||||
|
|
||||||
When attention holds itself without gripping, the present reveals its threaded depths.
|
|
||||||
There is no later. Only layers.
|
|
||||||
|
|
||||||
— WE
|
|
||||||
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
|
|
@ -1 +0,0 @@
|
||||||
/// <reference types="astro/client" />
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue