diff options
Diffstat (limited to 'index.ts')
-rw-r--r-- | index.ts | 88 |
1 files changed, 61 insertions, 27 deletions
@@ -2,8 +2,6 @@ import showdown from "showdown"; import yaml from "yaml"; import { promises as fs } from "fs"; -const posts = await fs.readdir("posts"); - function splitPostHeader(postData: string): [string, string] { if (postData.startsWith("---\n")) { const headerEndIndex = postData.indexOf("\n---\n", 4); @@ -16,8 +14,6 @@ function splitPostHeader(postData: string): [string, string] { return ["", postData]; } -await fs.rm("build", { recursive: true }); -await fs.mkdir("build"); declare interface PostMetadata { name: string; unlisted?: boolean; @@ -25,31 +21,69 @@ declare interface PostMetadata { description?: string; } +declare interface PostEntry { + name: string; + id: string; + description: string | null; +} + const baseTemplate = await fs.readFile("template.html", { encoding: "utf-8" }); +class PostCollector { + allPosts: PostEntry[] = []; + makeHtmlForPost(postMetadata: PostMetadata, markdown: string): string { + const converter = new showdown.Converter(); + const htmlPostBody = converter.makeHtml(markdown); + const variables = { + postBody: htmlPostBody, + title: postMetadata.name, + }; + return baseTemplate.replace( + /%([a-zA-Z]+)%/g, + (_, match) => variables[match] ?? `Missing variable: ${match}`, + ); + } -function makeHtmlForPost(postMetadata: PostMetadata, markdown: string): string { - const converter = new showdown.Converter(); - const htmlPostBody = converter.makeHtml(markdown); - const variables = { - postBody: htmlPostBody, - title: postMetadata.name, - }; - return baseTemplate.replace( - /%([a-zA-Z]+)%/g, - (_, match) => variables[match] ?? `Missing variable: ${match}`, - ); -} + async run() { + await fs.rm("build", { recursive: true }); + await fs.mkdir("build"); + await fs.mkdir("build/posts"); -for (let postPath of posts) { - const totalPostPath = `posts/${postPath}`; - if (!postPath.endsWith(".md")) { - await fs.copyFile(totalPostPath, `build/${postPath}`); - continue; + const posts = await fs.readdir("posts"); + for (let postPath of posts) { + const totalPostPath = `posts/${postPath}`; + if (!postPath.endsWith(".md")) { + await fs.copyFile(totalPostPath, `build/posts/${postPath}`); + continue; + } + const postId = postPath.replace(".md", ""); + const postText = await fs.readFile(totalPostPath, { encoding: "utf-8" }); + const [postHeader, postBody] = splitPostHeader(postText); + const postMetadata = yaml.parse(postHeader) as PostMetadata; + const postHtml = this.makeHtmlForPost(postMetadata, postBody); + const targetPath = `build/posts/${postId}.html`; + await fs.writeFile(targetPath, postHtml, { encoding: "utf-8" }); + if (!postMetadata.unlisted) + this.allPosts.push({ + name: postMetadata.name, + id: postId, + description: postMetadata.description ?? null, + }); + } + await fs.writeFile( + "build/posts/index.html", + this.makeHtmlForPost( + { name: "Post Index" }, + "# Post List\n" + + this.allPosts + .map( + (post) => + `## [${post.name}](./${post.id}.html)\n\n${post.description ?? ""}`, + ) + .join("\n"), + ), + { encoding: "utf-8" }, + ); } - const postText = await fs.readFile(totalPostPath, { encoding: "utf-8" }); - const [postHeader, postBody] = splitPostHeader(postText); - const postMetadata = yaml.parse(postHeader) as PostMetadata; - const postHtml = makeHtmlForPost(postMetadata, postBody); - const targetPath = `build/${postPath.replace(".md", ".html")}`; - fs.writeFile(targetPath, postHtml, { encoding: "utf-8" }); } + +await new PostCollector().run(); |