Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active October 27, 2020 18:24
Show Gist options
  • Save ryanflorence/e5266b8bfaf05ac7fc374fe552f95c65 to your computer and use it in GitHub Desktop.
Save ryanflorence/e5266b8bfaf05ac7fc374fe552f95c65 to your computer and use it in GitHub Desktop.
// put markdown files in articles/*.md
// run `node build.mjs`
// upload to a host
import path from "path";
import { promises as fs } from "fs";
import shell from "shelljs";
import cheerio from "cheerio";
import remark from "remark";
import html from "remark-html";
import report from "vfile-reporter";
const __dirname = path.resolve();
async function go() {
shell.rm("-rf", "build");
shell.mkdir("build");
let articles = await fs.readdir(path.join(__dirname, "articles"));
await Promise.all(
articles.map(async (filename) => {
let page = path.join(__dirname, "articles", filename);
let body = await createPage(page);
await fs.writeFile(
path.join(__dirname, "build", filename.replace(/\.md$/, ".html")),
body
);
console.log("›", filename);
})
);
console.log("Done!");
}
export default async function createPage(filePath) {
let markdown = await fs.readFile(filePath);
return new Promise(async (resolve, reject) => {
remark()
.use(html)
.process(String(markdown), async (err, markup) => {
if (err) {
console.error(report(err));
reject(err);
}
let page = getPage(String(markup));
resolve(page);
});
});
}
function getPage(body) {
let $ = cheerio.load(body);
let title = $("h1").text();
return `
<!DOCTYPE html>
<html lang="en">
<head>
<title>${title}</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://unpkg.com/@exampledev/new.css@1.1.3/new.css" />
<style>body { font-family: "Iowan Old Style", "Apple Garamond", Baskerville, "Times New Roman", "Droid Serif", Times, "Source Serif Pro", serif; }</style>
</head>
<body>
${body}
</body>
</html>
`;
}
go();
@ryanflorence
Copy link
Author

I actually have createPage as as separate module, then in development you can have a simple little express server that builds pages on demand:

import express from "express";
import path from "path";
import createPage from "./createPage.mjs";

const __dirname = path.resolve();

let app = express();
app.use(express.static("public"));
app
  .get("*", async (req, res) => {
    let slug = req.url.replace(/^\//, "");
    let page = path.join(
      __dirname,
      "articles",
      (slug === "" ? "index" : slug) + ".md"
    );
    let body = await createPage(page);
    res.send(body);
  })
  .listen(3000);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment