diff --git a/.eleventy.js b/.eleventy.js index cf74199..a40b966 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -4,6 +4,13 @@ const pluginRss = require("@11ty/eleventy-plugin-rss"); const Image = require("@11ty/eleventy-img"); const htmlmin = require("html-minifier"); const outdent = require("outdent"); +const pluginNavigation = require("@11ty/eleventy-navigation"); +const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); +const markdownItAnchor = require("markdown-it-anchor"); +const markdownItAttrs = require("markdown-it-attrs"); +const pluginTOC = require("eleventy-plugin-toc"); +const pluginFilters = require("./_config/filters.js"); +const pluginShortCodes = require("./_config/shortcode.js"); /** Maps a config of attribute-value pairs to an HTML string * representing those same attribute-value pairs. @@ -83,14 +90,61 @@ const imageShortcode = async ( module.exports = function (eleventyConfig) { // 11ty plugins eleventyConfig.addPlugin(pluginRss); - eleventyConfig.addPlugin(Webmentions, { - domain: "benkutil.com", - token: process.env.WEBMENTIONS_TOKEN + + // Only add Webmentions if token is provided + if (process.env.WEBMENTIONS_TOKEN) { + eleventyConfig.addPlugin(Webmentions, { + domain: "benkutil.com", + token: process.env.WEBMENTIONS_TOKEN + }); + } + + eleventyConfig.addPlugin(pluginNavigation); + eleventyConfig.addPlugin(pluginSyntaxHighlight, { + preAttributes: { tabindex: 0 } + }); + eleventyConfig.addPlugin(pluginTOC, { + tags: ['h2', 'h3', 'h4', 'h5'], + ul: true, + flat: false, + wrapper: 'div' }); + // Add Tufte filters and shortcodes + eleventyConfig.addPlugin(pluginFilters); + eleventyConfig.addPlugin(pluginShortCodes); + // 11ty shortcodes eleventyConfig.addShortcode('image', imageShortcode); + // Configure markdown-it + const markdownIt = require("markdown-it"); + let options = { + html: true, + breaks: true, + linkify: true, + typographer: true, + }; + let markdownLib = markdownIt(options).use(markdownItAttrs); + eleventyConfig.setLibrary("md", markdownLib); + + 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") + }); + }); + + // Pass through Tufte CSS and fonts + eleventyConfig.addPassthroughCopy("src/css"); + eleventyConfig.addPassthroughCopy("src/et-book"); + // run these configs in production only if (process.env.ELEVENTY_ENV === 'production') { eleventyConfig.addTransform("htmlmin", function (content, outputPath) { diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/Readme.md b/Readme.md index 2de86b9..4ba1202 100644 --- a/Readme.md +++ b/Readme.md @@ -4,4 +4,4 @@ Personal website using [11ty](https://11ty.dev) and [Cloudflare Pages](https://p ## Setup ### Environment variables - `ELEVENTY_ENV` is either `production` or `preview`. Defaults to not set. -- In Cloudflare Pages, set `NODE_VERSION` to desired nodejs version. Currently set to `16.18` to match GitHub Codespace version. +- Node version is set to `20` via `.nvmrc` file for compatibility with 11ty and dependencies. diff --git a/_config/filters.js b/_config/filters.js new file mode 100644 index 0000000..db6d07a --- /dev/null +++ b/_config/filters.js @@ -0,0 +1,40 @@ +const { DateTime } = require("luxon"); + +module.exports = function(eleventyConfig) { + eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { + // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens + return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy"); + }); + + 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'); + }); + + // 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 the keys used in an object + eleventyConfig.addFilter("getKeys", target => { + return Object.keys(target); + }); + + eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { + return (tags || []).filter(tag => ["all", "posts"].indexOf(tag) === -1); + }); + +}; diff --git a/_config/shortcode.js b/_config/shortcode.js new file mode 100644 index 0000000..da1f18f --- /dev/null +++ b/_config/shortcode.js @@ -0,0 +1,23 @@ +module.exports = function(eleventyConfig) { + eleventyConfig.addShortcode("notes",(id,content) =>`${content}`); + + eleventyConfig.addShortcode("notesimage",(id,image,alt,content) =>`${alt}${content}`); + + eleventyConfig.addShortcode("fullimage",(image,alt) =>`
${alt}
`); + + eleventyConfig.addShortcode("videos",(video,title) =>`
`); + + eleventyConfig.addShortcode("sidenote",(id,title,sidenote,content) =>`${title}${sidenote}, ${content}`); + + eleventyConfig.addShortcode("sidenoteinternal",(id,title,sidenote,content) =>`${title}${sidenote}, ${content}`); + + eleventyConfig.addShortcode("sidenoteexternal",(id,title,sidenote,content,content_link,url) =>`${title}${sidenote} ${content_link}, ${content} `); + + eleventyConfig.addShortcode("epigraph",(content,footer) =>`

${content}

`); + + eleventyConfig.addShortcode("blockquote",(content,footer) =>`

${content}

`); + + eleventyConfig.addShortcode("epigraphlink",(content,footer,info,url) =>`

${content}

`); + + eleventyConfig.addShortcode("blockquotelink",(content,footer,info,url) =>`

${content}

`); +}; diff --git a/package.json b/package.json index 50968b8..34864b4 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,19 @@ "devDependencies": { "@11ty/eleventy": "^2.0.0-beta.3", "@11ty/eleventy-img": "^3.0.0", + "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^1.2.0", + "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "eleventy-plugin-webmentions": "^2.0.0", "html-minifier": "^4.0.0", + "luxon": "^3.5.0", + "markdown-it-anchor": "^9.2.0", + "markdown-it-attrs": "^4.3.1", "outdent": "^0.8.0" }, "dependencies": { "@11ty/eleventy-upgrade-help": "^2.0.5", - "dotenv": "^16.0.3" + "dotenv": "^16.0.3", + "eleventy-plugin-toc": "^1.1.5" } } diff --git a/src/_includes/layouts/base.njk b/src/_includes/layouts/base.njk index 3049413..b4ee3c7 100644 --- a/src/_includes/layouts/base.njk +++ b/src/_includes/layouts/base.njk @@ -17,6 +17,9 @@ + + +