maia.crimew.gay/.eleventy.js

161 lines
5.3 KiB
JavaScript

const path = require("node:path");
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight');
const pluginRss = require('@11ty/eleventy-plugin-rss');
const timeToRead = require('eleventy-plugin-time-to-read');
const safeLinks = require('@sardine/eleventy-plugin-external-links');
const related = require("eleventy-plugin-related");
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const sass = require("sass");
const footnotes = require('eleventy-plugin-footnotes');
const figure = require('./src/_includes/components/figure.js');
const bounce = require('./src/_includes/components/bounce.js');
module.exports = function (eleventyConfig) {
const isDev = (process.env.ELEVENTY_ENV || "dev") == "dev";
const parseDate = (str) => {
if (str instanceof Date) {
return str;
}
return Date.parse(str);
};
const formatPart = (part, date) =>
new Intl.DateTimeFormat("en", part).format(date);
eleventyConfig.setNunjucksEnvironmentOptions({
lstripBlocks: true,
trimBlocks: true
});
const md = markdownIt({ "html": true }).use(markdownItAnchor, { "level": 2 });
eleventyConfig.setLibrary("md", md);
eleventyConfig.addPlugin(pluginRss);
eleventyConfig.addPlugin(syntaxHighlight);
eleventyConfig.addPlugin(timeToRead);
eleventyConfig.addPlugin(safeLinks);
eleventyConfig.addPlugin(footnotes, {
"title": "footnotes",
"baseClass": "footnotes"
});
eleventyConfig.addShortcode('figure', figure(md));
eleventyConfig.addShortcode('bounce', bounce);
eleventyConfig.addPassthroughCopy({ "src/static": "/" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/dist/reveal.css": "reveal.js/reveal.css" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/dist/reveal.esm.js": "reveal.js/reveal.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/markdown/markdown.esm.js": "reveal.js/plugin/markdown/markdown.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/highlight/highlight.esm.js": "reveal.js/plugin/highlight/highlight.esm.js" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/highlight/monokai.css": "reveal.js/plugin/highlight/monokai.css" });
eleventyConfig.addPassthroughCopy({ "node_modules/reveal.js/plugin/notes/notes.esm.js": "reveal.js/plugin/notes/notes.esm.js" });
eleventyConfig.addFilter("date_to_datetime", async (obj) => {
if (!obj) {
return "";
}
const date = parseDate(obj);
return date.toISOString();
});
eleventyConfig.addFilter("date_formatted", async (obj) => {
if (!obj) {
return "";
}
const date = parseDate(obj);
const month = formatPart({ month: "short" }, date);
const day = formatPart({ day: "numeric" }, date);
const year = formatPart({ year: "numeric" }, date);
const hours = date.getUTCHours();
const minutes = date.getUTCMinutes();
if (hours != 0 && minutes != 0) {
return `${month} ${day}, ${year} - ${hours}:${minutes} UTC`;
}
return `${month} ${day}, ${year}`;
});
eleventyConfig.addFilter('urlescape', async str => {
return str.split('/').map(part => encodeURI(part)).join('/')
});
// TODO: possibly turn this into a post processing step instead of a filter (or at least make it a shortcode)
eleventyConfig.addFilter("related", async function(obj) {
const post = this.ctx;
const posts = this.ctx.collections.posts.map(post => post.data);
const tagScore = (a, b) => {
const total = a.tags.length + b.tags.length;
const intersection = a.tags.filter(tag => b.tags.includes(tag)).length;
return (intersection * 2) / total;
}
const results = related.related({
serializer: (doc) => [doc.title, doc.description],
weights: [10, 10],
})(post, posts).map(result => {
return {
relative: result.relative + tagScore(post, result.document),
document: result.document
}
});
return results.filter(result => result.relative > 0.2).sort((a, b) => a.relative - b.relative).reverse().slice(0,3);
});
eleventyConfig.addCollection('posts', collection => {
return collection.getFilteredByGlob('src/posts/*.md').reverse()
});
eleventyConfig.addCollection('decks', collection => {
return collection.getFilteredByGlob('src/decks/*.md')
// append the raw content
.map(item => {
const content = item.template.frontMatter.content;
item.data.rawMarkdown = content || "";
return item;
});
});
eleventyConfig.addTemplateFormats("scss");
eleventyConfig.addExtension("scss", {
outputFileExtension: "css",
compile: function (inputContent, inputPath) {
let parsed = path.parse(inputPath);
let result = sass.compileString(inputContent, {
style: isDev ? "expanded" : "compressed",
loadPaths: [
parsed.dir || "."
]
});
this.addDependencies(inputPath, result.loadedUrls);
return async (data) => {
return result.css;
};
}
})
return {
templateFormats: ["njk", "md", "html"],
dir: {
input: "src",
includes: "_includes",
data: "_data",
output: "www",
},
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
dataTemplateEngine: "njk",
passthroughFileCopy: false,
};
};