const path = require("path"); const markdownIt = require("markdown-it"); const slugify = require("@sindresorhus/slugify"); const markdownItAnchor = require("markdown-it-anchor"); const markdownItObsidian = require("markdown-it-obsidian"); const markdownItAttrs = require("markdown-it-attrs"); const markdownItEleventyImg = require("markdown-it-eleventy-img"); const pluginRss = require("@11ty/eleventy-plugin-rss"); const embedYouTube = require("eleventy-plugin-youtube-embed"); const sanitizeHtml = require("sanitize-html"); const metadata = require("./src/_data/metadata.json"); const sanitize = (html) => { return sanitizeHtml(html, { allowedTags: ['b', 'i', 'em', 'strong', 'a'], allowedAttributes: { 'a': ['href'] } }); }; module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(embedYouTube); eleventyConfig.addPlugin(pluginRss); eleventyConfig.addPassthroughCopy("css"); eleventyConfig.addPassthroughCopy("fonts"); eleventyConfig.addPassthroughCopy("images/**/*.{gif,png,jpg,jpeg}"); eleventyConfig.addPassthroughCopy({ "favicon": "/" }); eleventyConfig.addPassthroughCopy({ "node_modules/simpledotcss/simple.css": "css/simple.css", }); eleventyConfig.addPassthroughCopy({ "src/robots.txt": "robots.txt" }); eleventyConfig.addFilter("buildPageTitle", function(title) { if (this.page.url === '/') { return title; } else { return title + ' ⇢ Devon.LoL 😆'; } }); eleventyConfig.addFilter("stringToDate", function(value) { return new Date(value); }); eleventyConfig.addFilter("formatDatetimeForHumans", function(value) { const dt = new Date(value); const formattedDt = new Intl.DateTimeFormat("en", { dateStyle: "medium", timeStyle: "medium", }).format(dt); return formattedDt; }); eleventyConfig.addFilter("formatDateForHumans", function(value) { const dt = new Date(value); const formattedDt = new Intl.DateTimeFormat("en", { dateStyle: "medium", }).format(dt); return formattedDt; }); eleventyConfig.addFilter("formatDateForRobots", function(value) { const dt = new Date(value); return dt.toISOString(); }); eleventyConfig.addFilter("convertYouTubeURLsToEmbeds", function(value) { const youtubeUrlRegex = /
\s*(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?!channel\/|@)([^\s&<>"']*)\s*<\/p>/gim; return value.replace(youtubeUrlRegex, function(match, videoId) { return ''; }); }); eleventyConfig.addFilter('webmentionsByUrl', function(webmentions, url) { const allowedTypes = ['in-reply-to', 'like-of', 'repost-of']; const hasRequiredFields = mention => { const { author, published, content } = mention; return author.name && published && content; }; const matchesUrl = mention => { return mention['wm-target'] === url; }; const filteredMentions = webmentions .filter(mention => { const isAllowedType = allowedTypes.includes(mention['wm-property']); if (isAllowedType) { const isReply = mention['wm-property'] === 'in-reply-to'; if (isReply) { return matchesUrl(mention) && hasRequiredFields(mention); } return matchesUrl(mention); } } ); const sanitizedMentions = filteredMentions.map((mention) => { if (mention?.content?.html) { mention.content.html = sanitize(mention.content.html); const mastodonInstance = metadata.author.mastodon.instance; const mastodonUsername = metadata.author.mastodon.username; const mentionLink = `@${metadata.author.mastodon.username} `; if (mention.content.html.startsWith(mentionLink)) { mention.content.html = mention.content.html.substring(mentionLink.length) } } return mention; }); const sortedMentions = sanitizedMentions.reduce((accumulator, mention) => { const key = mention['wm-property']; const curGroup = accumulator[key] ?? []; return { ...accumulator, [key]: [...curGroup, mention] }; }, {}); return sortedMentions; }); const markdownLibrary = markdownIt({ html: true }) .use(markdownItAnchor, { slugify }) .use( markdownItObsidian({ slugifyOnPageLinks: slugify, }) ) .use(markdownItAttrs) .use(markdownItEleventyImg, { imgOptions: { widths: [75, 150, 300, 600, 900, 1100], outputDir: path.join("dist", "img"), }, globalAttributes: { loading: "lazy", decoding: "async", sizes: "100vw", }, }); eleventyConfig.setLibrary("md", markdownLibrary); return { dir: { input: "src", output: "dist", }, }; };