-
Notifications
You must be signed in to change notification settings - Fork 1
/
eleventy.config.js
102 lines (87 loc) · 3.3 KB
/
eleventy.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const pluginWebc = require("@11ty/eleventy-plugin-webc");
const markdownItAnchor = require("markdown-it-anchor");
const markdownLinks = require("markdown-it-link-attributes");
const tableOfContents = require("eleventy-plugin-toc");
let options = {
dir: { input: "src", layouts: "_layouts" },
htmlTemplateEngine: "webc",
markdownTemplateEngine: "webc",
};
module.exports = function (config) {
config.addWatchTarget("src/_css");
config.amendLibrary("md", markdown);
config.addPlugin(pluginWebc, {
components: `${options.dir.input}/_components/**/*.html`,
});
config.addPlugin(tableOfContents, { tags: ["h2"] });
// browsers expect favicons to be served at the site root
config.addPassthroughCopy({ "src/_assets/favicon.ico": "favicon.ico" });
// all other assets are served from /assets
config.addPassthroughCopy({ "src/_assets": "assets" });
// so images can be co-located with case studies rather than in _assets
config.addPassthroughCopy("src/{work,blog}/**/*.{png,jpg,gif,webp}");
config.addFilter("assert", assert);
config.addFilter("readingTime", readingTime);
config.addFilter("inMinutes", inMinutes);
config.addFilter("readableDate", readableDate);
config.addFilter("relativeTime", relativeTime);
config.addFilter("ariaCurrent", ariaCurrent);
return options;
};
function markdown(md) {
md.set({ linkify: true, typographer: true })
// add icon links to every h2/h3
.use(markdownItAnchor, {
level: [2, 3],
permalink: true,
permalinkSymbol: `<svg width="24" height="24"><use href="/assets/icons.svg#link" /></svg>`,
permalinkAttrs: (slug) => ({ "aria-label": `link to ${slug} section` }),
})
// make sure links to external sites open in new tab
.use(markdownLinks, {
matcher: (href) => href.match(/^https?:/),
attrs: { target: "_blank", rel: "noopener" },
});
}
function assert(x, msg = "") {
if (!x) {
throw new Error(msg);
}
}
function readingTime(content) {
const contentWithoutHtml = content.replace(/(<([^>]+)>)/gi, "");
const words = contentWithoutHtml.match(/[\u0400-\u04FF]+|\S+\s*/g);
const wordCount = words ? words.length : 0;
const wordsPerSecond = 200 / 60;
return wordCount / wordsPerSecond;
}
function inMinutes(seconds) {
let mins = Math.round(seconds / 60);
let label = "minute";
if (mins !== 1) label += "s";
return mins + " " + label;
}
function readableDate(date) {
let options = { month: "long", day: "numeric", year: "numeric" };
return date.toLocaleDateString("en-GB", options);
}
function relativeTime(then) {
const now = new Date();
const yearDiff = now.getFullYear() - then.getFullYear();
const monthDiff = now.getMonth() - then.getMonth();
const dayDiff = now.getDay() - then.getDay();
const dateDiff = now.getDate() - then.getDate();
const startOfLastWeek = now.getDay() + 7;
if (yearDiff > 0) return "More than a year ago";
if (monthDiff > 1) return "This year";
if (monthDiff === 1) return "Last month";
if (dateDiff === 1) return "Yesterday";
if (dateDiff === 0) return "Today";
if (dateDiff >= startOfLastWeek) return "This month";
if (dateDiff < today) return "This week";
if (dayDiff < startOfLastWeek) return "Last week";
}
function ariaCurrent(current, href) {
if (current === href) return "page";
if (current.includes(href) && href !== "/") return true;
}