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// Disabled Plugins: 43// import nav from "lume/plugins/nav.ts"; 44// import og_images from "lume/plugins/og_images.ts"; 45// import pagefind from "lume/plugins/pagefind.ts"; 46// import purgecss from "lume/plugins/purgecss.ts"; 47// import relations from "lume/plugins/relations.ts"; 48// import sri from "lume/plugins/sri.ts"; 49// import { default as md_linenums } from "npm:markdown-it-inject-linenumbers@0.3.0"; 50 51// To Add: 52// https://deno.land/x/lume_markdown_plugins@v0.8.0 (footnotes plugins) 53// https://deno.land/x/lume_shiki@0.0.16 54 55const site = lume({ 56 src: "./src", 57 location: new URL("https://pyrox.dev"), 58}); 59 60// site.hooks.addMarkdownItPlugin(md_linenums, {}); 61site.hooks.addMarkdownItPlugin(BiDirectionalLinks({ 62 dir: Deno.cwd() + "/src/", 63 stillRenderNoMatched: false, 64})); 65site.hooks.addMarkdownItPlugin(mdItObsidianCallouts, { 66 icons: { 67 abstract: '<i class="bi bi-clipboard2-data"></i>', 68 bug: '<i class="bi bi-bug"></i>', 69 danger: '<i class="bi bi-lightning"></i>', 70 example: '<i class="bi bi-list-ul"></i>', 71 failure: '<i class="bi bi-x-lg"></i>', 72 info: '<i class="bi bi-info-circle"></i>', 73 note: '<i class="bi bi-pencil"></i>', 74 question: '<i class="bi bi-question-circle"></i>', 75 quote: '<i class="bi bi-quote"></i>', 76 success: '<i class="bi bi-check2"></i>', 77 tip: '<i class="bi bi-fire"></i>', 78 todo: '<i class="bi bi-check-circle"></i>', 79 warning: '<i class="bi bi-exclamation-triangle"></i>', 80 }, 81}); 82 83// Copy Static Files 84site.add(".css"); 85site.add("static/.well-known", ".well-known"); 86site.add(".woff2"); 87// Tailwind CSS 88site.use(tailwindcss()); 89 90// Fonts 91site.use( 92 googleFonts({ 93 subsets: ["latin", "latin-ext"], 94 folder: "/static/fonts/", 95 cssFile: "/static/fonts.css", 96 fonts: 97 "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", 98 }), 99); 100 101site.use(metas()); 102site.use(picture()); 103site.use(transform_images()); 104// site.use(relations()); 105site.use(sitemap()); 106site.use(slugify_urls()); 107site.use(svgo()); 108site.use(toml()); 109site.use( 110 date({ 111 formats: { 112 SHORT_DATE: "yyyy-MM-dd", 113 POST_DATE: "dd MMM, yyyy", 114 }, 115 }), 116); 117site.use(toc()); 118site.use(resolveUrls()); 119 120// RSS/JSON Feed Generation 121site.use( 122 feed({ 123 output: ["/blog.rss", "/blog.json"], 124 query: "category=blog", 125 info: { 126 title: "dish blog", 127 description: "dish's thoughts on many things", 128 published: new Date(), 129 lang: "en", 130 generator: true, 131 authorName: "dish", 132 authorUrl: "https://blog.pyrox.dev", 133 }, 134 items: { 135 title: "=title", 136 description: "=summary", 137 published: "=published", 138 updated: "=updated", 139 content: "$.e-content", 140 lang: "=lang", 141 image: "=banner", 142 authorName: "=author.name", 143 authorUrl: "=author.url", 144 }, 145 }), 146); 147 148// CSS postprocessing 149// site.use(purgecss()); 150site.use(lightningcss({ 151 options: { 152 minify: true, 153 bundle: false, 154 }, 155})); 156 157// Source Map Generation 158// Applies to CSS and JS 159site.use(source_maps()); 160 161site.use(validateHTML()); 162 163// Minify HTML Output 164site.use(minify_html({ 165 options: { 166 keep_html_and_head_opening_tags: true, 167 keep_spaces_between_attributes: true, 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: parseInt(Deno.env.get("BROTLI_LEVEL") as string), 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// Get current commit as a version number 240// Taken from https://github.com/pixeldesu/pixelde.su/blob/main/_config.ts 241const commitCmd = new Deno.Command("git", { args: ["rev-parse", "HEAD"] }); 242const { stdout } = await commitCmd.output(); 243const commitHash = new TextDecoder().decode(stdout); 244site.data("commit", commitHash); 245 246export default site;