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 "https://deno.land/x/lume_markdown_plugins@v0.8.0/toc.ts";
30
31// CSS
32// // Base dependencies
33import tailwindcss from "lume/plugins/tailwindcss.ts";
34// // Fonts
35import googleFonts from "lume/plugins/google_fonts.ts";
36// // Optimization
37import lightningcss from "lume/plugins/lightningcss.ts";
38
39// Validation
40import validateHTML from "./plugins/validateHTML.ts";
41
42// Open in Editor
43import openInEditor from "./plugins/openInEditor.ts";
44
45// Disabled Plugins:
46// import nav from "lume/plugins/nav.ts";
47// import og_images from "lume/plugins/og_images.ts";
48// import pagefind from "lume/plugins/pagefind.ts";
49// import purgecss from "lume/plugins/purgecss.ts";
50// import relations from "lume/plugins/relations.ts";
51// import sri from "lume/plugins/sri.ts";
52// import { default as md_linenums } from "npm:markdown-it-inject-linenumbers@0.3.0";
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
63// site.hooks.addMarkdownItPlugin(md_linenums, {});
64site.hooks.addMarkdownItPlugin(BiDirectionalLinks({
65 dir: Deno.cwd() + "/src/",
66 stillRenderNoMatched: false,
67}));
68site.hooks.addMarkdownItPlugin(mdItObsidianCallouts, {
69 icons: {
70 abstract: '<i class="bi bi-clipboard2-data"></i>',
71 bug: '<i class="bi bi-bug"></i>',
72 danger: '<i class="bi bi-lightning"></i>',
73 example: '<i class="bi bi-list-ul"></i>',
74 failure: '<i class="bi bi-x-lg"></i>',
75 info: '<i class="bi bi-info-circle"></i>',
76 note: '<i class="bi bi-pencil"></i>',
77 question: '<i class="bi bi-question-circle"></i>',
78 quote: '<i class="bi bi-quote"></i>',
79 success: '<i class="bi bi-check2"></i>',
80 tip: '<i class="bi bi-fire"></i>',
81 todo: '<i class="bi bi-check-circle"></i>',
82 warning: '<i class="bi bi-exclamation-triangle"></i>',
83 },
84});
85
86// Copy Static Files
87site.add(".css");
88site.add("static/.well-known", ".well-known");
89site.add(".woff2");
90// Tailwind CSS
91site.use(tailwindcss());
92
93// Fonts
94site.use(
95 googleFonts({
96 subsets: ["latin", "latin-ext"],
97 folder: "/static/fonts/",
98 cssFile: "/static/fonts.css",
99 fonts:
100 "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",
101 }),
102);
103
104site.use(metas());
105site.use(picture());
106site.use(transform_images());
107// site.use(relations());
108site.use(sitemap());
109site.use(slugify_urls());
110site.use(svgo());
111site.use(toml());
112site.use(
113 date({
114 formats: {
115 SHORT_DATE: "yyyy-MM-dd",
116 POST_DATE: "dd MMM, yyyy",
117 },
118 }),
119);
120site.use(toc());
121site.use(resolveUrls());
122
123// RSS/JSON Feed Generation
124site.use(
125 feed({
126 output: ["/blog.rss", "/blog.json"],
127 query: "category=blog",
128 info: {
129 title: "dish blog",
130 description: "dish's thoughts on many things",
131 published: new Date(),
132 lang: "en",
133 generator: true,
134 authorName: "dish",
135 authorUrl: "https://blog.pyrox.dev",
136 },
137 items: {
138 title: "=title",
139 description: "=summary",
140 published: "=published",
141 updated: "=updated",
142 content: "$.e-content",
143 lang: "=lang",
144 image: "=banner",
145 authorName: "=author.name",
146 authorUrl: "=author.url",
147 },
148 }),
149);
150
151// CSS postprocessing
152// site.use(purgecss());
153site.use(lightningcss({
154 options: {
155 minify: true,
156 },
157}));
158
159// Source Map Generation
160// Applies to CSS and JS
161site.use(source_maps());
162
163site.use(validateHTML());
164
165// Minify HTML Output
166site.use(minify_html({
167 options: {
168 do_not_minify_doctype: true,
169 keep_closing_tags: false,
170 keep_html_and_head_opening_tags: true,
171 keep_spaces_between_attributes: true,
172 ensure_spec_compliant_unquoted_attribute_values: true,
173 keep_comments: false,
174 },
175}));
176
177// robots.txt generation
178site.use(
179 robots({
180 disallow: [
181 "AI2Bot",
182 "Amazonbot",
183 "Applebot-Extended",
184 "Bytespider",
185 "ChatGPT-User",
186 "ClaudeBot",
187 "Diffbot",
188 "DuckAssistBot",
189 "FacebookBot",
190 "GPTBot",
191 "Google-Extended",
192 "Meta-ExternalAgent",
193 "Meta-ExternalFetcher",
194 "OAI-SearchBot",
195 "Operator",
196 "PanguBot",
197 "PerplexityBot",
198 "SemrushBot",
199 "SemrushBot-OCOB",
200 "Timpibot",
201 "Webzio-Extended",
202 "YouBot",
203 "cohere-training-data-crawler",
204 "omgili",
205 "t3versions",
206 ],
207 }),
208);
209
210// Compress everything with Brotli/Gzip
211site.use(
212 brotli({
213 quality: 11,
214 extensions: [
215 ".html",
216 ".css",
217 ".js",
218 ".mjs",
219 ".svg",
220 ".json",
221 ".xml",
222 ".txt",
223 ".rss",
224 ".map",
225 ],
226 }),
227);
228site.use(
229 gzip({
230 extensions: [
231 ".html",
232 ".css",
233 ".js",
234 ".mjs",
235 ".svg",
236 ".json",
237 ".xml",
238 ".txt",
239 ".rss",
240 ".map",
241 ],
242 }),
243);
244
245// Open in Editor in Dev mode
246site.data("production", Deno.env.get("PRODUCTION"));
247if (Deno.env.get("PRODUCTION") == "false") {
248 site.use(openInEditor());
249 site.add("static/scripts/open-in-editor.js");
250}
251
252// Get current commit as a version number
253// Taken from https://github.com/pixeldesu/pixelde.su/blob/main/_config.ts
254const commitCmd = new Deno.Command("git", { args: ["rev-parse", "HEAD"] });
255const { stdout } = await commitCmd.output();
256const commitHash = new TextDecoder().decode(stdout);
257site.data("commit", commitHash);
258
259export default site;