67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import marked from "marked";
|
|
import express from "express"
|
|
import ejs from "ejs";
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import jsdom from "jsdom";
|
|
|
|
let app = express();
|
|
|
|
// set view engine to ejs
|
|
app.set("view engine", "ejs")
|
|
app.set('views', path.join(__dirname, 'templates'))
|
|
|
|
// type for post object
|
|
type Post = {
|
|
file: string;
|
|
title: string;
|
|
parsedPost: string;
|
|
rawPost: string;
|
|
metadata: fs.Stats;
|
|
}
|
|
|
|
// html stripper, used for title
|
|
async function htmlstripper(html: string){
|
|
return new jsdom.JSDOM(html).window.document.body.textContent || " ";
|
|
}
|
|
|
|
// returns Post array
|
|
async function contentScan(){
|
|
let posts: Post[] = []
|
|
let postsDir = path.join(__dirname, "posts")
|
|
let files = await fs.readdirSync(postsDir).filter((name: string) => name.toLowerCase().endsWith(".md"))
|
|
for (const file of files) {
|
|
let postPath = path.join(postsDir, file)
|
|
let metadata = fs.statSync(postPath)
|
|
let postContent = fs.readFileSync(postPath, "utf-8")
|
|
posts.push(
|
|
{
|
|
file: file,
|
|
title: await htmlstripper(
|
|
await marked.parse(
|
|
postContent.split("\n")[0]
|
|
)
|
|
),
|
|
metadata: metadata,
|
|
parsedPost: await marked.parse(postContent),
|
|
rawPost: postContent
|
|
}
|
|
)
|
|
}
|
|
return posts;
|
|
}
|
|
|
|
app.get("/", async (req:express.Request,res:express.Response) => {
|
|
res.render("index", {posts: (await contentScan())})
|
|
});
|
|
|
|
app.use("/post/:post", async (req:express.Request,res:express.Response) => {
|
|
let pathToPost = path.join(__dirname, "posts", req.params.post);
|
|
if(!fs.existsSync(pathToPost)) return res.end("404.");
|
|
let posts = await contentScan();
|
|
let post = posts.filter(post => post.file === req.params.post)
|
|
if(!post[0]) return res.end("404.")
|
|
res.render("post", {posts: posts, post: post[0]})
|
|
})
|
|
|
|
app.listen(3024)
|