1import lume from "lume/mod.ts";
2import date from "lume/plugins/date.ts";
3import picture from "lume/plugins/picture.ts";
4import source_maps from "lume/plugins/source_maps.ts";
5import toml from "lume/plugins/toml.ts";
6
7// URL Management
8import slugify_urls from "lume/plugins/slugify_urls.ts";
9import resolveUrls from "lume/plugins/resolve_urls.ts";
10
11// File Generation
12import feed from "lume/plugins/feed.ts";
13import metas from "lume/plugins/metas.ts";
14import robots from "lume/plugins/robots.ts";
15import sitemap from "lume/plugins/sitemap.ts";
16
17// Optimization
18import brotli from "lume/plugins/brotli.ts";
19import gzip from "lume/plugins/gzip.ts";
20import minify_html from "lume/plugins/minify_html.ts";
21import svgo from "lume/plugins/svgo.ts";
22import transform_images from "lume/plugins/transform_images.ts";
23
24// Markdown-it plugins
25import { BiDirectionalLinks } from "@nolebase/markdown-it-bi-directional-links";
26import { default as mdItObsidianCallouts } from "markdown-it-obsidian-callouts";
27
28// Additional external plugins
29import toc from "lume_markdown_plugins/toc.ts";
30import anchor from "npm:markdown-it-anchor";
31import footnotes from "./plugins/footnotes.ts";
32import slugify from "npm:@sindresorhus/slugify";
33
34// CSS
35// // Base dependencies
36import tailwindcss from "lume/plugins/tailwindcss.ts";
37// // Fonts
38import googleFonts from "lume/plugins/google_fonts.ts";
39// // Optimization
40import lightningcss from "lume/plugins/lightningcss.ts";
41
42// Custom Plugins
43import validateHTML from "./plugins/validateHTML.ts";
44import openInEditor from "./plugins/openInEditor.ts";
45
46// Disabled Plugins:
47// import nav from "lume/plugins/nav.ts";
48// import og_images from "lume/plugins/og_images.ts";
49// import pagefind from "lume/plugins/pagefind.ts";
50// import purgecss from "lume/plugins/purgecss.ts";
51// import relations from "lume/plugins/relations.ts";
52// import sri from "lume/plugins/sri.ts";
53
54// To Add:
55// https://deno.land/x/lume_markdown_plugins@v0.8.0 (footnotes plugins)
56// https://deno.land/x/lume_shiki@0.0.16
57
58const site = lume({
59 src: "./src",
60 location: new URL("https://pyrox.dev"),
61}, {
62 markdown: {
63 plugins: [
64 [BiDirectionalLinks, {
65 dir: Deno.cwd() + "/src/",
66 stillRenderNoMatched: false,
67 }],
68 mdItObsidianCallouts,
69 [anchor, {
70 permalink: anchor.permalink.headerLink(),
71 slugify: (s: string) => slugify(s),
72 }],
73 footnotes,
74 ],
75 },
76});
77
78// Copy Static Files
79site.add(".css");
80site.add("static/.well-known", ".well-known");
81site.add(".woff2");
82// Tailwind CSS
83site.use(tailwindcss());
84
85// Fonts
86site.use(
87 googleFonts({
88 subsets: ["latin", "latin-ext"],
89 folder: "/static/fonts/",
90 cssFile: "/static/fonts.css",
91 fonts:
92 "https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600;1,700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900",
93 }),
94);
95
96site.use(metas());
97site.use(picture());
98site.use(transform_images());
99// site.use(relations());
100site.use(sitemap());
101site.use(slugify_urls());
102site.use(svgo());
103site.use(toml());
104site.use(
105 date({
106 formats: {
107 SHORT_DATE: "yyyy-MM-dd",
108 POST_DATE: "dd MMM, yyyy",
109 },
110 }),
111);
112site.use(toc({
113 anchor: false,
114}));
115site.use(resolveUrls());
116
117// RSS/JSON Feed Generation
118site.use(
119 feed({
120 output: ["/blog.rss", "/blog.json"],
121 query: "category=blog",
122 info: {
123 title: "dish blog",
124 description: "dish's thoughts on many things",
125 published: new Date(),
126 lang: "en",
127 generator: true,
128 authorName: "dish",
129 authorUrl: "https://blog.pyrox.dev",
130 },
131 items: {
132 title: "=title",
133 description: "=summary",
134 published: "=published",
135 updated: "=updated",
136 content: "$.e-content",
137 lang: "=lang",
138 image: "=banner",
139 authorName: "=author.name",
140 authorUrl: "=author.url",
141 },
142 }),
143);
144
145// CSS postprocessing
146// site.use(purgecss());
147site.use(lightningcss({
148 options: {
149 minify: true,
150 },
151}));
152
153// Source Map Generation
154// Applies to CSS and JS
155site.use(source_maps());
156
157site.use(validateHTML());
158
159// Minify HTML Output
160site.use(minify_html({
161 options: {
162 do_not_minify_doctype: true,
163 keep_closing_tags: false,
164 keep_html_and_head_opening_tags: true,
165 keep_spaces_between_attributes: true,
166 ensure_spec_compliant_unquoted_attribute_values: true,
167 keep_comments: false,
168 },
169}));
170
171// robots.txt generation
172site.use(
173 robots({
174 disallow: [
175 "AI2Bot",
176 "Amazonbot",
177 "Applebot-Extended",
178 "Bytespider",
179 "ChatGPT-User",
180 "ClaudeBot",
181 "Diffbot",
182 "DuckAssistBot",
183 "FacebookBot",
184 "GPTBot",
185 "Google-Extended",
186 "Meta-ExternalAgent",
187 "Meta-ExternalFetcher",
188 "OAI-SearchBot",
189 "Operator",
190 "PanguBot",
191 "PerplexityBot",
192 "SemrushBot",
193 "SemrushBot-OCOB",
194 "Timpibot",
195 "Webzio-Extended",
196 "YouBot",
197 "cohere-training-data-crawler",
198 "omgili",
199 "t3versions",
200 ],
201 }),
202);
203
204// Compress everything with Brotli/Gzip
205site.use(
206 brotli({
207 quality: 11,
208 extensions: [
209 ".html",
210 ".css",
211 ".js",
212 ".mjs",
213 ".svg",
214 ".json",
215 ".xml",
216 ".txt",
217 ".rss",
218 ".map",
219 ],
220 }),
221);
222site.use(
223 gzip({
224 extensions: [
225 ".html",
226 ".css",
227 ".js",
228 ".mjs",
229 ".svg",
230 ".json",
231 ".xml",
232 ".txt",
233 ".rss",
234 ".map",
235 ],
236 }),
237);
238
239// Open in Editor in Dev mode
240site.data("production", Deno.env.get("PRODUCTION") == "true");
241if (Deno.env.get("PRODUCTION") == "false") {
242 site.use(openInEditor());
243 site.add("static/scripts/open-in-editor.js");
244}
245
246// Get current commit as a version number
247// Taken from https://github.com/pixeldesu/pixelde.su/blob/main/_config.ts
248const commitCmd = new Deno.Command("git", { args: ["rev-parse", "HEAD"] });
249const { stdout } = await commitCmd.output();
250const commitHash = new TextDecoder().decode(stdout);
251site.data("commit", commitHash);
252
253export default site;