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"; 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;