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