Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hedgehog1029 committed Apr 25, 2019
0 parents commit 3165713
Show file tree
Hide file tree
Showing 22 changed files with 795 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:10.15.3-alpine

WORKDIR /app
VOLUME /app/posts

COPY index.js /app/index.js
COPY package.json /app/package.json
COPY lib /app/lib
COPY static /app/static
COPY views /app/views

RUN npm i

EXPOSE 1440
CMD ["node", "index.js"]
48 changes: 48 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const express = require("express");
const {Watcher} = require("watch-fs");
const jetpack = require("fs-jetpack");
const md = require("markdown-it")();

const posts = require("./lib/posts");

const app = express();
const postPath = `${__dirname}/posts`;
const watcher = new Watcher({
paths: [postPath],
filters: {
includeFile: ((name) => name.endsWith(".md"))
}
});

app.set("view engine", "pug");
app.use("/static", express.static(`${__dirname}/static`))

app.get("/", (req, res) =>
res.render("index.pug", { posts: posts.fetch() })
);

app.get("/p/:slug", (req, res) =>
res.render("post.pug", { post: posts.fetchBySlug(req.params.slug) })
);

watcher.on("create", (path) =>
posts.load(path)
);

watcher.on("change", (path) =>
posts.reload(path)
);

watcher.on("delete", (path) =>
posts.remove(path)
);

watcher.start((err, failed) => {
jetpack.listAsync(postPath).then((files) =>
files.forEach((filepath) =>
posts.load(`${postPath}/${filepath}`)
)
);

app.listen(1440);
});
83 changes: 83 additions & 0 deletions lib/posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const jetpack = require("fs-jetpack");
const YAML = require("yaml");
const markdownit = require("markdown-it");
const frontmatter = require("markdown-it-front-matter");
const emoji = require("markdown-it-emoji");
const hljs = require("highlight.js");
const pathutil = require("path");

class Post {
constructor(content, kwargs, filename) {
this.html_content = content;

this.title = kwargs.title;
this.author = {
name: kwargs.author,
id: kwargs.discord
};

this.published = kwargs.date;
this.slug = filename.replace(/[^a-zA-Z0-9-]/, "-");
}

summary() {
let start = this.html_content.indexOf("<p>") + 3;
let end = this.html_content.indexOf("\n", start);

if (end < 0) end = start + 100;

return this.html_content.slice(start, end).replace("</p>", "");
}
}

function hljsHighlight(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
let block = hljs.highlight(lang, str, true).value;
return '<pre class="hljs"><code>' + block + '</code></pre>';
} catch (err) {
console.error(err);
}
}

return '<pre class="hljs"><code>' + this.md.utils.escapeHtml(str) + '</code></pre>';
}

class PostLoader {
constructor() {
this.posts = {};
this.postBySlug = {};
this.md = markdownit({ highlight: hljsHighlight.bind(this) });

this.md.use(emoji);
this.md.use(frontmatter, (fm) =>
YAML.parse(fm)
);
}

load(filename) {
return jetpack.readAsync(filename).then((content) => {
let ctx = {};
this.posts[filename] = new Post(this.md.render(content, ctx), ctx.result, pathutil.basename(filename, ".md"));
this.postBySlug[this.posts[filename].slug] = filename;
});
}

remove(filename) {
delete this.posts[filename];
}

reload(filename) {
return this.load(filename);
}

fetch() {
return Object.values(this.posts).sort((a, b) => b.published.localeCompare(a.published));
}

fetchBySlug(slug) {
return this.posts[this.postBySlug[slug]];
}
}

module.exports = new PostLoader();
39 changes: 39 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "thonkblog",
"version": "1.0.0",
"description": "genprog's simple markdown-based blog",
"main": "index.js",
"directories": {
"lib": "lib"
},
"dependencies": {
"express": "^4.16.4",
"fs-jetpack": "^2.2.2",
"highlight.js": "^9.15.6",
"markdown-it": "^8.4.2",
"markdown-it-emoji": "^1.4.0",
"markdown-it-front-matter": "git+https://github.com/hedgehog1029/markdown-it-front-matter.git",
"pug": "^2.0.3",
"watch-fs": "^0.0.7",
"yaml": "^1.5.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+ssh://[email protected]/general-programming/thonkblog.git"
},
"keywords": [
"blog",
"genprog",
"thonk"
],
"author": "offbeatwitch",
"license": "MIT",
"bugs": {
"url": "https://github.com/general-programming/thonkblog/issues"
},
"homepage": "https://github.com/general-programming/thonkblog#readme"
}
Loading

0 comments on commit 3165713

Please sign in to comment.