Files
2022-07-03 17:37:19 -07:00

188 lines
5.6 KiB
JavaScript

'use strict';
const csso = require('csso');
const eleventyNavigationPlugin = require('@11ty/eleventy-navigation');
const eleventySvgContentsPlugin = require('eleventy-plugin-svg-contents');
const eleventySyntaxHighlightPlugin = require('@11ty/eleventy-plugin-syntaxhighlight');
const htmlmin = require('html-minifier');
const markdown = require('markdown-it');
const markdownAnchor = require('markdown-it-anchor');
const markdownAttrs = require('markdown-it-attrs');
const markdownContainer = require('markdown-it-container');
const markdownEmoji = require('markdown-it-emoji');
const markdownFootnote = require('markdown-it-footnote');
const markdownTasks = require('markdown-it-task-lists');
const UglifyJS = require('uglify-es');
/**
* Markdown plugin
* Add classes to markdown elements by default
*/
function markdownitTagToClass(md, mapping = {}) {
const toArray = (a) => (Array.isArray(a) ? a : [a]);
const splitWithSpace = (s) => (s ? s.split(' ') : []);
function parseTokens(tokens) {
tokens.forEach((token) => {
if (/(_open$|hr|image)/.test(token.type) && mapping[token.tag]) {
const orig = splitWithSpace(token.attrGet('class'));
const addition = toArray(mapping[token.tag]);
token.attrSet('class', [...orig, ...addition].join(' '));
}
if (token.children) {
parseTokens(token.children);
}
});
}
md.core.ruler.push('markdownit-tag-to-class', (state) =>
parseTokens(state.tokens)
);
}
module.exports = function (eleventyConfig) {
// Merge data instead of overriding
// https://www.11ty.dev/docs/data-deep-merge/
eleventyConfig.setDataDeepMerge(true);
// PLUGINS -----
// Eleventy Navigation https://www.11ty.dev/docs/plugins/navigation/
eleventyConfig.addPlugin(eleventyNavigationPlugin);
// Inline SVG files https://www.npmjs.com/package/eleventy-plugin-svg-contents
eleventyConfig.addPlugin(eleventySvgContentsPlugin);
// Syntax Highlighting https://www.11ty.dev/docs/plugins/syntaxhighlight/
eleventyConfig.addPlugin(eleventySyntaxHighlightPlugin);
// TRANSFORMS -----
// Minify HTML output
eleventyConfig.addTransform('htmlmin', function (content, outputPath) {
if (typeof outputPath === 'string' && outputPath.includes('.html')) {
return htmlmin.minify(content, {
useShortDoctype: true,
removeComments: true,
collapseWhitespace: true
});
}
return content;
});
// FILTERS -----
// Date formatting (human readable)
eleventyConfig.addFilter('readableDate', (dateObj) => {
const options = { month: 'long', day: 'numeric', year: 'numeric' };
return new Intl.DateTimeFormat('en-US', options).format(dateObj);
});
// Date formatting (machine readable)
eleventyConfig.addFilter('machineDate', (dateObj) => {
return dateObj.toISOString();
});
// Minify CSS
eleventyConfig.addFilter('cssmin', function (code) {
return csso.minify(code).css;
});
// Minify JS
eleventyConfig.addFilter('jsmin', function (code) {
const minified = UglifyJS.minify(code);
if (minified.error) {
console.log('UglifyJS error: ', minified.error);
return code;
}
return minified.code;
});
// SHORTCODES -----
eleventyConfig.addShortcode('version', function () {
return String(Date.now());
});
// PASSTHROUGH -----
eleventyConfig.addPassthroughCopy('src/static');
// COLLECTIONS -----
// Collection of items for navigation
eleventyConfig.addCollection('nav', function (collection) {
return collection
.getAll()
.filter(function (item) {
return 'eleventyNavigation' in item.data;
})
.sort((a, b) => {
const keyA = a.data.eleventyNavigation.key;
const keyB = b.data.eleventyNavigation.key;
if (keyA > keyB) {
return 1;
} else if (keyA < keyB) {
return -1;
}
return 0;
});
});
// MARKDOWN -----
const options = {
html: true,
breaks: true,
linkify: true,
typographer: true
};
const markdownLib = markdown(options);
markdownLib
// Customize markdown HTML
// .use(markdownitTagToClass, {})
// Automatically place anchors next to headings
// https://github.com/valeriangalliat/markdown-it-anchor
.use(markdownAnchor, {
level: [2, 3],
permalink: markdownAnchor.permalink.headerLink({ safariReaderFix: true }),
// permalinkClass: "direct-link",
permalinkSymbol: '#'
})
// Syntax for adding attributes {.class decode=async}
// https://github.com/arve0/markdown-it-attrs
.use(markdownAttrs, {
allowedAttributes: ['class', 'decode', 'height', 'lazy', 'width']
})
// Custom containers (::: name)
// https://github.com/markdown-it/markdown-it-container
.use(markdownContainer, 'callout')
.use(markdownContainer, 'lead')
.use(markdownContainer, 'warning')
// Emoji replacement
// https://github.com/markdown-it/markdown-it-emoji
.use(markdownEmoji)
// Add footnotes
// https://github.com/markdown-it/markdown-it-footnote
.use(markdownFootnote)
// Render a task list
// https://github.com/revin/markdown-it-task-lists
.use(markdownTasks);
eleventyConfig.setLibrary('md', markdownLib);
// ELEVENTY CONFIG -----
return {
templateFormats: ['md', 'njk', 'html'],
markdownTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
dataTemplateEngine: 'njk',
passthroughFileCopy: true,
dir: {
input: './src',
includes: 'includes',
data: 'data',
output: 'dist'
},
// Matches the GitHub Pages subdirectory of the site (necolas.github.io/react-native-web)
pathPrefix: '/react-native-web/'
};
};