import { DateTime } from "luxon"; import markdownIt from "markdown-it"; import markdownItFootnote from "markdown-it-footnote"; import markdownItAnchor from "markdown-it-anchor"; import mdfigcaption from "markdown-it-image-figures"; import pluginRss from "@11ty/eleventy-plugin-rss"; import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; import pluginBundle from "@11ty/eleventy-plugin-bundle"; import pluginNavigation from "@11ty/eleventy-navigation"; import prettier from "prettier"; import { EleventyHtmlBasePlugin } from "@11ty/eleventy"; import { dateSuffixAdder, monthMap, timeFormatter, } from "./public/js/modules/dateTools.js"; const figoptions = { figcaption: true, }; export default async function (eleventyConfig) { // Helper Functions const multiReplace = (text, replacementTable) => { let newText = text; replacementTable.forEach((x) => { newText = newText.replace(x[0], x[1]); }); return newText; }; // Collections eleventyConfig.addCollection("galleryImages", (collection) => { const galleries = collection.getAll()[0].data.galleries; let galleryImages = []; galleries.forEach((gallery) => { gallery.pictures.forEach((picture, i, arr) => { picture.containingGallery = `${gallery.title}`; picture.baseUrl = `${gallery.url}`; i ? (picture.previousImage = arr[i - 1].filename) : null; i + 1 != arr.length ? (picture.nextImage = arr[i + 1].filename) : null; galleryImages.push(picture); }); }); return galleryImages; }); // Transforms eleventyConfig.addTransform("prettier", function (content, outputPath) { if (outputPath && outputPath.endsWith(".html")) { return prettier.format(content, { parser: "html", bracketSameLine: true, vueIndentScriptAndStyle: true, singleAttributePerLine: true, htmlWhitespaceSensitivity: "css", }); } else { return content; } }); eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}"); // Official plugins eleventyConfig.addPlugin(pluginRss); eleventyConfig.addPlugin(pluginSyntaxHighlight, { preAttributes: { tabindex: 0 }, }); eleventyConfig.addPlugin(pluginNavigation); eleventyConfig.addPlugin(EleventyHtmlBasePlugin); eleventyConfig.addPlugin(pluginBundle); // Filters eleventyConfig.addFilter("niceDate", (date) => { var day = new Date(date).getUTCDate(); var monthIndex = new Date(date).getUTCMonth(); var year = new Date(date).getUTCFullYear(); return `${day}${dateSuffixAdder(day)} of ${monthMap[monthIndex]}, ${year}`; }); eleventyConfig.addFilter("htmlDateString", (dateObj) => { // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd"); }); eleventyConfig.addFilter("removeMostRecent", (arr) => { return arr.slice(0, arr.length - 1); }); // Shortcodes // Cowsay eleventyConfig.addFilter("cowsay", (cowText) => { const cowCaptionReplacementTable = [ [ ` o ^__^ o (oo)\\_______ (__)\\ )\\/\\ ||----w | || ||`, "", ], [/\(\s+/g, ""], [/\s+\(/g, ""], [/_{3,}/g, ""], [/-{3,}/g, ""], [/\s\)/g, ""], [/\n/g, ""], [/\s{2,}/g, " "], [/^ /, ""], ]; return `
A cow thinking: ${multiReplace(cowText, cowCaptionReplacementTable)}. The cow is illustrated using preformatted text characters.
`; }); // Embed a toot eleventyConfig.addAsyncShortcode("toot", async function (instance, ID) { const tootData = await fetch(`https://${instance}/api/v1/statuses/${ID}`); const toot = await tootData.json(); const dateObj = new Date(toot.created_at); const dateTime = `${dateObj.getDate()}${dateSuffixAdder(dateObj.getDate())} of ${monthMap[dateObj.getMonth()]}, ${dateObj.getFullYear()}, at ${timeFormatter(dateObj.getHours(), dateObj.getMinutes())}`; return ` `; }); // Embed audio eleventyConfig.addShortcode( "audio", function (title, artist, media_url, cover_url) { return ` `; }, ); // Passthrough eleventyConfig.addPassthroughCopy({ "./public/": "/" }); // Get the first `n` elements of a collection. eleventyConfig.addFilter("head", (array, n) => { if (!Array.isArray(array) || array.length === 0) { return []; } if (n < 0) { return array.slice(n); } return array.slice(0, n); }); // Return the smallest number argument eleventyConfig.addFilter("min", (...numbers) => { return Math.min.apply(null, numbers); }); // Return all the tags used in a collection eleventyConfig.addFilter("getAllTags", (collection) => { let tagSet = new Set(); for (let item of collection) { (item.data.tags || []).forEach((tag) => tagSet.add(tag)); } return Array.from(tagSet); }); eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { return (tags || []).filter( (tag) => ["all", "nav", "post", "posts", "gallery", "quiz"].indexOf(tag) === -1, ); }); // Customize Markdown library settings: let markdownItOptions = { html: true, typographer: true, }; let mdLib = markdownIt(markdownItOptions); eleventyConfig.amendLibrary("md", (mdLib) => { mdLib .use(markdownItAnchor, { permalink: markdownItAnchor.permalink.ariaHidden({ placement: "after", class: "header-anchor", symbol: "#", ariaHidden: false, }), level: [1, 2, 3, 4], slugify: eleventyConfig.getFilter("slugify"), }) .use(markdownItFootnote) .use(mdfigcaption, figoptions); }); eleventyConfig.setLibrary("md", mdLib); return { templateFormats: ["md", "njk", "html", "liquid"], markdownTemplateEngine: "njk", htmlTemplateEngine: "njk", dir: { input: "content", // default: "." includes: "../_includes", // default: "_includes" data: "../_data", // default: "_data" output: "_site", }, pathPrefix: "/", }; }