summaryrefslogtreecommitdiff
path: root/.eleventy.js
diff options
context:
space:
mode:
Diffstat (limited to '.eleventy.js')
-rw-r--r--.eleventy.js95
1 files changed, 95 insertions, 0 deletions
diff --git a/.eleventy.js b/.eleventy.js
new file mode 100644
index 0000000..2ffec7d
--- /dev/null
+++ b/.eleventy.js
@@ -0,0 +1,95 @@
+const fs = require("fs");
+const hljs = require("highlight.js");
+const twemoji = require("twemoji");
+const { DateTime } = require("luxon");
+const utils = require("markdown-it/lib/common/utils");
+
+const excerptMinimumLength = 280;
+const excerptSeparator = "<!--more-->"
+
+function extractExcerpt(doc) {
+ if (doc.data.readOnline) return "[[ No Excerpt Available ]]";
+ if (doc.data.excerpt) return doc.data.excerpt;
+
+ if (!doc.hasOwnProperty("templateContent")) {
+ console.warn("Failed to extract excerpt: Document has no property `templateContent`.");
+ return "";
+ }
+
+ const content = doc.templateContent;
+ if (content.includes(excerptSeparator))
+ return content.substring(0, content.indexOf(excerptSeparator)).trim();
+ else if (content.length <= excerptMinimumLength) return content.trim();
+
+ const excerptEnd = findExcerptEnd(content);
+ return content.substring(0, excerptEnd).trim();
+}
+
+function findExcerptEnd(content, skipLength = 0) {
+ if (content === "") return 0;
+ const paragraphEnd = content.indexOf("</p>", skipLength) + 4;
+ return paragraphEnd + ((paragraphEnd < excerptMinimumLength)?
+ findExcerptEnd(content.substring(paragraphEnd), paragraphEnd):0);
+}
+
+function demark(content) {
+ return content.replace(/<mark>(.*?)<\/mark>/gis, (m,a) => "&#x2588;".repeat(a.length))
+}
+
+module.exports = (cfg) => {
+ cfg.addPlugin(require("@11ty/eleventy-plugin-rss"));
+ cfg.addFilter("excerpt", post => extractExcerpt(post));
+ cfg.addFilter("demark", content => demark(content));
+ cfg.addFilter("date", (date, fmt) =>
+ DateTime.fromJSDate(date).toFormat(fmt));
+ cfg.addPassthroughCopy({"static": "./"});
+ cfg.setDataDeepMerge(true);
+
+ cfg.addFilter("fixAnchors", (c,u) =>
+ c.replace(/<a class="header-anchor" href="/g, "$&"+u));
+
+ const md = require("markdown-it")({
+ typographer: true, html: true,
+ highlight: (str, lang) => {
+ if (lang && hljs.getLanguage(lang)) { try {
+ return '<pre class="hljs"><code>' +
+ hljs.highlight(str, { language: lang, ignoreIllegals: true }).value +
+ '</code></pre>';
+ } catch (__) {} }
+ return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
+ }
+
+ }).use(require("markdown-it-anchor"), {
+ permalink: true, permalinkBefore: true, permalinkSymbol: "#"})
+ .use(require("markdown-it-emoji"), {shortcuts: {}})
+ .use(require("markdown-it-mark"));
+
+ md.renderer.rules.emoji = (token, i) =>
+ `<span class="emoji-container emoji_${token[i].markup}" ` +
+ `title="${token[i].markup}">${twemoji.parse(token[i].content)}</span>`;
+ md.renderer.rules.code_block = (tokens, i, options, env, slf) =>
+ `<pre${slf.renderAttrs(tokens[i])}><code>` +
+ utils.escapeHtml(tokens[i].content.replace(/ /g, "\xA0"))+'</code></pre>\n';
+
+ cfg.setLibrary("md", md);
+
+ cfg.setBrowserSyncConfig({callbacks: {
+ ready: (e,b) => b.addMiddleware("*", (req, res) => {
+ res.writeHead(404, { "Content-Type": "text/html; charset=UTF-8" });
+ res.write(fs.readFileSync("build/404.html"));
+ res.end();
+ })
+ }});
+
+ return {
+ templateFormats: ["md", "njk"],
+ markdownTemplateEngine: "njk",
+ dir: {
+ input: "posts",
+ output: "build",
+ data: "../globals",
+ layouts: "../layouts",
+ includes: "../includes",
+ },
+ };
+};