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