-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.eleventy.js
More file actions
165 lines (146 loc) · 7.73 KB
/
Copy path.eleventy.js
File metadata and controls
165 lines (146 loc) · 7.73 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const markdownIt = require("markdown-it");
const markdownItAnchor = require("markdown-it-anchor");
const markdownItCheckbox = require("markdown-it-checkbox");
module.exports = function (eleventyConfig) {
// ── Plugins ──────────────────────────────────────────────────────────────
eleventyConfig.addPlugin(syntaxHighlight);
// ── Markdown ──────────────────────────────────────────────────────────────
const md = markdownIt({
html: true,
linkify: true,
typographer: true,
})
.use(markdownItAnchor, {
permalink: markdownItAnchor.permalink.headerLink(),
slugify: (s) =>
s
.toLowerCase()
.replace(/[^\w\s-]/g, "")
.trim()
.replace(/\s+/g, "-"),
})
.use(markdownItCheckbox, {
divWrap: false,
divClass: "checkbox",
idPrefix: "cbx_",
});
// Wrap tables in a scroll container
md.renderer.rules.table_open = () =>
'<div class="table-scroll"><table>\n';
md.renderer.rules.table_close = () => "</table></div>\n";
eleventyConfig.setLibrary("md", md);
// ── Checkbox label spill fix ──────────────────────────────────────────────
// markdown-it-checkbox closes <label> at the first inline child, so any
// <code>/<a>/<strong>/text that follows lands outside the <label> as raw
// siblings in the <li>. This transform pulls that spilled content back into
// the label so the accessible name is complete and the flex layout stays intact.
eleventyConfig.addTransform("fixCheckboxLabelSpill", function (content, outputPath) {
if (!outputPath || !outputPath.endsWith(".html")) return content;
// Match: <input type="checkbox"…><label …>…</label>SPILLED</li>
// Capture: group1 = input+label open through </label>, group2 = spilled content
return content.replace(
/(<input\b[^>]*type="checkbox"[^>]*>\s*<label\b[^>]*>[\s\S]*?<\/label>)([\s\S]*?)(<\/li>)/g,
(match, labelBlock, spill, closeLi) => {
// Only act when there is actually inline content spilled after </label>.
// A spill that consists only of whitespace or block elements (ul/ol/p…)
// is harmless — leave it untouched.
const blockTag = /^\s*<\s*(ul|ol|li|p|div|pre|blockquote|table|section|article|figure|hr|h[1-6])\b/i;
const trimmed = spill.trim();
if (!trimmed || blockTag.test(trimmed)) return match;
// Move spilled content inside the label, just before </label>.
const fixedLabel = labelBlock.replace(/<\/label>$/, spill + "</label>");
return fixedLabel + closeLi;
}
);
});
// ── Pass-through ──────────────────────────────────────────────────────────
// Copy public/ contents to _site/ root (not under _site/public/)
eleventyConfig.addPassthroughCopy({ "public/css": "css" });
eleventyConfig.addPassthroughCopy({ "public/js": "js" });
eleventyConfig.addPassthroughCopy({ "public/icons": "icons" });
eleventyConfig.addPassthroughCopy({ "public/manifest.json": "manifest.json" });
eleventyConfig.addPassthroughCopy({ "public/sw.js": "sw.js" });
eleventyConfig.addPassthroughCopy({ "public/robots.txt": "robots.txt" });
eleventyConfig.addPassthroughCopy({ "public/favicon.ico": "favicon.ico" });
eleventyConfig.addPassthroughCopy({ "public/favicon.svg": "favicon.svg" });
eleventyConfig.addPassthroughCopy({ "public/og-image.png": "og-image.png" });
eleventyConfig.addPassthroughCopy({ "public/8053702bdb002fcad5c0de97fe10f61b.txt": "8053702bdb002fcad5c0de97fe10f61b.txt" });
// ── Filters ───────────────────────────────────────────────────────────────
eleventyConfig.addFilter("year", () => new Date().getFullYear());
// Build a <title> tag value: "Page Title | Address Normalization" capped at 65 chars
// If title+suffix > 65, fall back to just the title (truncated to 65 if needed)
eleventyConfig.addFilter("pageTitle", (title) => {
if (!title) return "Address Normalization Pipelines";
const suffix = " | Address Normalization";
const full = title + suffix;
if (full.length <= 65) return full;
if (title.length <= 65) return title;
return title.slice(0, 62) + "...";
});
// JSON-serialize a single value (safe for embedding in JSON-LD script blocks)
eleventyConfig.addFilter("jsonStr", (value) => {
return JSON.stringify(String(value || "")).replace(/<\/script/gi, "<\\/script");
});
// ISO 8601 date string from a Date or date-like value
eleventyConfig.addFilter("dateIso", (date) => {
if (!date) return "";
return (date instanceof Date ? date : new Date(date)).toISOString();
});
// Number of path segments in a URL (used for sitemap priority)
eleventyConfig.addFilter("urlDepth", (url) => {
return url.replace(/^\/|\/$/g, "").split("/").filter(Boolean).length;
});
// Build breadcrumbs array from a URL string
eleventyConfig.addFilter("breadcrumbs", (url) => {
const parts = url.replace(/^\/|\/$/g, "").split("/").filter(Boolean);
const crumbs = [{ label: "Home", url: "/" }];
let cumulative = "";
parts.forEach((part, i) => {
cumulative += "/" + part;
const label = part
.replace(/-/g, " ")
.replace(/\b\w/g, (c) => c.toUpperCase());
crumbs.push({
label,
url: cumulative + "/",
current: i === parts.length - 1,
});
});
return crumbs;
});
// ── Collections ───────────────────────────────────────────────────────────
eleventyConfig.addCollection("coreSection", (api) =>
api
.getFilteredByGlob("content/core-address-parsing-standardization/**/*.md")
.filter((p) => !p.inputPath.endsWith("core-address-parsing-standardization/index.md"))
);
eleventyConfig.addCollection("multiApiSection", (api) =>
api
.getFilteredByGlob("content/multi-api-routing-fallback-chains/**/*.md")
.filter((p) => !p.inputPath.endsWith("multi-api-routing-fallback-chains/index.md"))
);
eleventyConfig.addCollection("cachingSection", (api) =>
api
.getFilteredByGlob("content/caching-deduplication-spatial-indexing/**/*.md")
.filter((p) => !p.inputPath.endsWith("caching-deduplication-spatial-indexing/index.md"))
);
eleventyConfig.addCollection("validationSection", (api) =>
api
.getFilteredByGlob("content/accuracy-validation-and-cicd-sync/**/*.md")
.filter((p) => !p.inputPath.endsWith("accuracy-validation-and-cicd-sync/index.md"))
);
// ── Dev server ────────────────────────────────────────────────────────────
eleventyConfig.setServerOptions({ watch: ["public/**"] });
// ── Directory config ──────────────────────────────────────────────────────
return {
markdownTemplateEngine: "njk",
htmlTemplateEngine: "njk",
dir: {
input: "content",
output: "_site",
includes: "../_includes",
data: "../_data",
},
};
};