import lume from "lume/mod.ts"; import date from "lume/plugins/date.ts"; import toml from "lume/plugins/toml.ts"; // Images import picture from "lume/plugins/picture.ts"; import transformImages from "lume/plugins/transform_images.ts"; // URL Management import slugifyUrls from "lume/plugins/slugify_urls.ts"; import resolveUrls from "lume/plugins/resolve_urls.ts"; // File Generation import feed from "lume/plugins/feed.ts"; import metas from "lume/plugins/metas.ts"; import readingInfo from "lume/plugins/reading_info.ts"; import robots from "lume/plugins/robots.ts"; import sitemap from "lume/plugins/sitemap.ts"; import sourceMaps from "lume/plugins/source_maps.ts"; // Optimization import brotli from "lume/plugins/brotli.ts"; import gzip from "lume/plugins/gzip.ts"; import minifyHTML from "lume/plugins/minify_html.ts"; import svgo from "lume/plugins/svgo.ts"; // Markdown-it plugins import { BiDirectionalLinks } from "@nolebase/markdown-it-bi-directional-links"; import { default as mdItObsidianCallouts } from "markdown-it-obsidian-callouts"; // Additional external plugins import toc from "lume_markdown_plugins/toc.ts"; import slugify from "npm:@sindresorhus/slugify"; // CSS // // Base dependencies import tailwindcss from "lume/plugins/tailwindcss.ts"; // // Fonts import googleFonts from "lume/plugins/google_fonts.ts"; // // Optimization import lightningcss from "lume/plugins/lightningcss.ts"; // Custom Plugins import validateHTML from "./plugins/validateHTML.ts"; import openInEditor from "./plugins/openInEditor.ts"; import footnotes from "./plugins/footnotes.ts"; // import checkAccessibility from "./plugins/checkAccessibility.ts"; // Disabled Plugins: // import nav from "lume/plugins/nav.ts"; // import og_images from "lume/plugins/og_images.ts"; // import pagefind from "lume/plugins/pagefind.ts"; // import purgecss from "lume/plugins/purgecss.ts"; // import relations from "lume/plugins/relations.ts"; // import sri from "lume/plugins/sri.ts"; // To Add: // https://deno.land/x/lume_shiki@0.0.16 const markdown = { plugins: [ BiDirectionalLinks({ dir: Deno.cwd() + "/src/", stillRenderNoMatched: false, debug: false, }), mdItObsidianCallouts, footnotes, ], }; const site = lume({ src: "./src", location: new URL("https://pyrox.dev"), cssFile: "/styles.css", }, { markdown }); // Ensure all URLs are to the final page links site.use(resolveUrls()); // Copy Static Files // site.ignore("/static/mocha.css"); site.add("static/.well-known", ".well-known"); // Fonts site.use( googleFonts({ subsets: ["latin", "latin-ext"], fontsFolder: "/static/fonts/", fonts: "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", }), ); // Tailwind CSS site.use(tailwindcss()); site.use(lightningcss({ options: { minify: true, }, })); site.add([".css", ".woff2"]); // Source Map Generation // Applies to CSS and JS site.use(sourceMaps()); site.use(slugifyUrls()); site.use(picture()); site.use(transformImages()); site.add([".png"]); // site.use(relations()); site.use(svgo()); site.use(toml()); // Metadata site.use( date({ formats: { SHORT_DATE: "yyyy-MM-dd", POST_DATE: "dd MMM, yyyy", }, }), ); site.use(metas()); site.use(readingInfo({ // Number taken from: // https://reader.ku.edu/sites/reader/files/2024-01/How%20many%20words%20do%20we%20read%20per%20minute%20(1).pdf wordsPerMinute: 238, })); site.use(toc({ slugify: (s: string) => slugify(s), })); // RSS/JSON Feed Generation site.use( feed({ output: ["/blog.rss", "/blog.json"], query: "category=blog", info: { title: "dish blog", description: "dish's thoughts on many things", published: new Date(), lang: "en", generator: true, authorName: "dish", authorUrl: "https://blog.pyrox.dev", }, items: { title: "=title", description: "=summary", published: "=published", updated: "=updated", content: "$.e-content", lang: "=lang", image: "=banner", authorName: "=author.name", authorUrl: "=author.url", }, }), ); // CSS postprocessing site.use(sitemap()); // site.use(checkAccessibility()); site.use(validateHTML()); site.data("production", Deno.env.get("PRODUCTION") == "true"); // This only applies in dev mode if (Deno.env.get("PRODUCTION") == "false") { site.use(openInEditor()); site.add("static/scripts/open-in-editor.js"); site.add("static/scripts/highlight-accessibility.js"); } // This only applies in prod mode if (Deno.env.get("PRODUCTION") == "true") { // Minify HTML site.use(minifyHTML({ options: { do_not_minify_doctype: true, keep_closing_tags: false, keep_html_and_head_opening_tags: true, keep_spaces_between_attributes: true, ensure_spec_compliant_unquoted_attribute_values: true, keep_comments: false, }, })); } // robots.txt generation site.use( robots({ disallow: [ "AI2Bot", "Amazonbot", "Applebot-Extended", "Bytespider", "ChatGPT-User", "ClaudeBot", "Diffbot", "DuckAssistBot", "FacebookBot", "GPTBot", "Google-Extended", "Meta-ExternalAgent", "Meta-ExternalFetcher", "OAI-SearchBot", "Operator", "PanguBot", "PerplexityBot", "SemrushBot", "SemrushBot-OCOB", "Timpibot", "Webzio-Extended", "YouBot", "cohere-training-data-crawler", "omgili", "t3versions", ], }), ); // Compress everything with Brotli/Gzip site.use( brotli({ quality: 11, extensions: [ ".html", ".css", ".js", ".mjs", ".svg", ".json", ".xml", ".txt", ".rss", ".map", ], }), ); site.use( gzip({ extensions: [ ".html", ".css", ".js", ".mjs", ".svg", ".json", ".xml", ".txt", ".rss", ".map", ], }), ); // Open in Editor in Dev mode // Get current commit as a version number // Taken from https://github.com/pixeldesu/pixelde.su/blob/main/_config.ts const commitCmd = new Deno.Command("git", { args: ["rev-parse", "HEAD"] }); const { stdout } = await commitCmd.output(); const commitHash = new TextDecoder().decode(stdout); site.data("commit", commitHash); export default site;