diff --git a/astro.config.ts b/astro.config.ts index 6445503..5064310 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -14,6 +14,7 @@ import rehypePrettyCode from 'rehype-pretty-code' import remarkEmoji from 'remark-emoji' import remarkMath from 'remark-math' import remarkToc from 'remark-toc' +import sectionize from '@hbsnow/rehype-sectionize' // https://astro.build/config export default defineConfig({ @@ -31,6 +32,8 @@ export default defineConfig({ rehypePlugins: [ rehypeHeadingIds, rehypeKatex, + // @ts-expect-error + sectionize, [ rehypePrettyCode, { diff --git a/package-lock.json b/package-lock.json index 849ddbf..9d49be2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@astrojs/tailwind": "^5.1.0", "@fontsource/geist-mono": "^5.0.3", "@fontsource/geist-sans": "^5.0.3", + "@hbsnow/rehype-sectionize": "^1.0.7", "@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-icons": "^1.3.0", @@ -1182,6 +1183,328 @@ "integrity": "sha512-oGwoSIqNPMvjtCwj1lZaEr47MeiG27XPhypwkF643u1TQduvwbm3V3hYB01JekeaT34SAGP4I1h+WCdRpJkcwA==", "license": "OFL-1.1" }, + "node_modules/@hbsnow/rehype-sectionize": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@hbsnow/rehype-sectionize/-/rehype-sectionize-1.0.7.tgz", + "integrity": "sha512-twbVxCFf4YwgTm6FIdGtHfJ14vvIHedk2fqZTpE3X6+vszEeZlMTy7tOyI9KaP/6S2DN2Jnk7zZGtZANTD+vEg==", + "dependencies": { + "hast-util-heading": "^2.0.1", + "hast-util-heading-rank": "^2.1.1", + "rehype": "^12.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-from-parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-raw": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", + "parse5": "^6.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-to-html": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", + "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-raw": "^7.0.0", + "hast-util-whitespace": "^2.0.0", + "html-void-elements": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-to-parse5": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/html-void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/rehype": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.1.tgz", + "integrity": "sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==", + "dependencies": { + "@types/hast": "^2.0.0", + "rehype-parse": "^8.0.0", + "rehype-stringify": "^9.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/rehype-parse": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.5.tgz", + "integrity": "sha512-Ds3RglaY/+clEX2U2mHflt7NlMA72KspZ0JLUJgBBLpRddBcEw3H8uYZQliQriku22NZpYMfjDdSgHcjxue24A==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-from-parse5": "^7.0.0", + "parse5": "^6.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/rehype-stringify": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.4.tgz", + "integrity": "sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-to-html": "^8.0.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unist-util-position": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/vfile": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/vfile-location": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/@hbsnow/rehype-sectionize/node_modules/vfile-message": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/@img/sharp-darwin-arm64": { "version": "0.33.4", "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", @@ -2867,6 +3190,11 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse5": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", @@ -4087,10 +4415,9 @@ "license": "MIT" }, "node_modules/dset": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", - "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", - "license": "MIT", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", "engines": { "node": ">=4" } @@ -4371,9 +4698,9 @@ } }, "node_modules/fast-xml-parser": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", - "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", "funding": [ { "type": "github", @@ -4384,7 +4711,6 @@ "url": "https://paypal.me/naturalintelligence" } ], - "license": "MIT", "dependencies": { "strnum": "^1.0.5" }, @@ -4731,6 +5057,70 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-heading": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-heading/-/hast-util-heading-2.0.1.tgz", + "integrity": "sha512-nwRggTanShzHRYMUX46lm6pbJ2c1+TUQCETahENb6yR6c8ro8MkE0hRJm8G0IqAZl35ONgJiW8RC8+D3484vYg==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-is-element": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-2.1.1.tgz", + "integrity": "sha512-iAuRp+ESgJoRFJbSyaqsfvJDY6zzmFoEnL1gtz1+U8gKtGGj1p0CVlysuUAUjq95qlZESHINLThwJzNGmgGZxA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-heading-rank/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/hast-util-heading-rank/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/hast-util-heading/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/hast-util-heading/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/hast-util-heading/node_modules/hast-util-is-element": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", + "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-is-element": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", @@ -5051,6 +5441,28 @@ "node": ">=8" } }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, "node_modules/is-core-module": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", @@ -6687,10 +7099,9 @@ "license": "MIT" }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "license": "MIT", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -7156,10 +7567,9 @@ } }, "node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "license": "MIT" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" }, "node_modules/periscopic": { "version": "3.1.0", diff --git a/package.json b/package.json index f085c97..be430cf 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@astrojs/tailwind": "^5.1.0", "@fontsource/geist-mono": "^5.0.3", "@fontsource/geist-sans": "^5.0.3", + "@hbsnow/rehype-sectionize": "^1.0.7", "@radix-ui/react-avatar": "^1.1.0", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-icons": "^1.3.0", diff --git a/src/components/ProjectCard.astro b/src/components/ProjectCard.astro index 6c65ebf..9e7b39f 100644 --- a/src/components/ProjectCard.astro +++ b/src/components/ProjectCard.astro @@ -1,7 +1,7 @@ --- -import { Image } from 'astro:assets' import { Badge } from '@/components/ui/badge' import Link from '@components/Link.astro' +import { Image } from 'astro:assets' import type { CollectionEntry } from 'astro:content' type Props = { @@ -11,7 +11,9 @@ type Props = { const { project } = Astro.props --- -
+

{project.data.name}

-

{project.data.description}

+

+ {project.data.description} +

- {project.data.tags.map((tag) => ( - {tag} - ))} + { + project.data.tags.map((tag) => ( + + {tag} + + )) + }
-
\ No newline at end of file +
diff --git a/src/components/TableOfContents.astro b/src/components/TableOfContents.astro index d3b2898..dab81bf 100644 --- a/src/components/TableOfContents.astro +++ b/src/components/TableOfContents.astro @@ -1,28 +1,37 @@ --- +import { ChevronDown } from 'lucide-react' import TableOfContentsHeading from './TableOfContentsHeading.astro' -// https://kld.dev/building-table-of-contents/ -const { headings } = Astro.props -const toc = buildToc(headings) - export interface Heading { depth: number slug: string text: string + subheadings: Heading[] } -function buildToc(headings: Heading[]) { +const { headings } = Astro.props +const toc = buildToc(headings) + +function buildToc(headings: Heading[]): Heading[] { const toc: Heading[] = [] - const parentHeadings = new Map() + const stack: Heading[] = [] + headings.forEach((h) => { const heading = { ...h, subheadings: [] } - parentHeadings.set(heading.depth, heading) - if (heading.depth === 2) { + + while (stack.length > 0 && stack[stack.length - 1].depth >= heading.depth) { + stack.pop() + } + + if (stack.length === 0) { toc.push(heading) } else { - parentHeadings.get(heading.depth - 1).subheadings.push(heading) + stack[stack.length - 1].subheadings.push(heading) } + + stack.push(heading) }) + return toc } --- @@ -32,17 +41,9 @@ function buildToc(headings: Heading[]) { class="flex cursor-pointer items-center justify-between text-xl font-semibold" > Table of Contents - - - + + + + diff --git a/src/components/TableOfContentsHeading.astro b/src/components/TableOfContentsHeading.astro index 12c9487..b397fdd 100644 --- a/src/components/TableOfContentsHeading.astro +++ b/src/components/TableOfContentsHeading.astro @@ -8,7 +8,10 @@ const { heading } = Astro.props
  • - + {heading.text} { @@ -21,33 +24,3 @@ const { heading } = Astro.props ) }
  • - - diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx index d820e8f..0b7bc4d 100644 --- a/src/components/ui/card.tsx +++ b/src/components/ui/card.tsx @@ -7,7 +7,7 @@ const Card = React.forwardRef< >(({ className, ...props }, ref) => (
    )) diff --git a/src/components/ui/mode-toggle.tsx b/src/components/ui/mode-toggle.tsx index 064a7e5..652dfe2 100644 --- a/src/components/ui/mode-toggle.tsx +++ b/src/components/ui/mode-toggle.tsx @@ -23,13 +23,15 @@ export function ModeToggle() { theme === 'dark' || (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches) - + document.documentElement.classList.add('disable-transitions') document.documentElement.classList[isDark ? 'add' : 'remove']('dark') - - window.getComputedStyle(document.documentElement).getPropertyValue('opacity') - + + window + .getComputedStyle(document.documentElement) + .getPropertyValue('opacity') + requestAnimationFrame(() => { document.documentElement.classList.remove('disable-transitions') }) @@ -65,4 +67,4 @@ export function ModeToggle() { ) -} \ No newline at end of file +} diff --git a/src/content/blog/2024-post/index.mdx b/src/content/blog/2024-post/index.mdx index 3a411e2..99b17ab 100644 --- a/src/content/blog/2024-post/index.mdx +++ b/src/content/blog/2024-post/index.mdx @@ -8,3 +8,35 @@ authors: ['enscribe', 'jktrn'] --- This is a dummy post written in the year 2024. + +## Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +#### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +#### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +#### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +###### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? + +### Test + +Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? diff --git a/src/content/blog/the-state-of-static-blogs/index.mdx b/src/content/blog/the-state-of-static-blogs/index.mdx index bf0e261..c13fa06 100644 --- a/src/content/blog/the-state-of-static-blogs/index.mdx +++ b/src/content/blog/the-state-of-static-blogs/index.mdx @@ -106,6 +106,54 @@ Within the blog itself (as in the layout, appearance, and navigation) are featur - You can specify multiple post authors via frontmatter. If this post author's slug is found within the `Authors` collection, then it will render particular info from that author's frontmatter file, `[author-name].md` (e.g. avatar, link to profile). For example, the previous post (2024 Post) has two authors: "enscribe" and "jktrn", where "enscribe" is the only author with a custom avatar since "jktrn" is unregistered. - Each author will have their own page, which lists all of their posts. If you're the only author throughout the entire blog then you can simply disregard all aspects regarding both inserting authors and the `Authors` collection. - Each tag will also have their own page, which lists all of the posts under that tag! +- $\LaTeX$ is fully supported with [KaTeX](https://katex.org/): + +
    + + To solve the cubic equation $t^3 + pt + q = 0$ (where the real numbers + $p, q$ satisfy ${4p^3 + 27q^2} > 0$) one can use Cardano's formula: + + $$ + \sqrt[{3}]{ + -\frac{q}{2} + +\sqrt{\frac{q^2}{4} + {\frac{p^{3}}{27}}} + }+ + \sqrt[{3}]{ + -\frac{q}{2} + -\sqrt{\frac{q^2}{4} + {\frac{p^{3}}{27}}} + } + $$ + + For any $u_1, \dots, u_n \in \mathbb{C}$ and + $v_1, \dots, v_n \in \mathbb{C}$, the Cauchy–Bunyakovsky–Schwarz + inequality can be written as follows: + + $$ + \left| \sum_{k=1}^n {u_k \bar{v_k}} \right|^2 + \leq + { + \left( \sum_{k=1}^n {|u_k|} \right)^2 + \left( \sum_{k=1}^n {|v_k|} \right)^2 + } + $$ + + Finally, the determinant of a Vandermonde matrix can be calculated + using the following expression: + + $$ + \begin{vmatrix} + 1 & x_1 & x_1^2 & \dots & x_1^{n-1} \\ + 1 & x_2 & x_2^2 & \dots & x_2^{n-1} \\ + 1 & x_3 & x_3^2 & \dots & x_3^{n-1} \\ + \vdots & \vdots & \vdots & \ddots & \vdots \\ + 1 & x_n & x_n^2 & \dots & x_n^{n-1} \\ + \end{vmatrix} + = {\prod_{1 \leq {i,j} \leq n} {(x_i - x_j)}} + $$ + + —[Three famous mathematical formulas](https://developer.mozilla.org/en-US/docs/Learn/MathML/First_steps/Three_famous_mathematical_formulas) (Mozilla Docs) + +
    ## Foregoing some slop @@ -117,3 +165,15 @@ Within the blog itself (as in the layout, appearance, and navigation) are featur - You really don't need a CMS unless you have thousands of posts and/or are willing to navigate through a clunky management interface. Markdown and folders is really all you need, which you can organize to your preference via folder or file naming conventions. - If you have literally anything involving an `.env` file in a blogging site, please think about what you are doing very carefully. - Please do not override the browser's Ctrl + K functionality to open up a command palette. There should not be a single reason why a user would use a small context menu to browse your blog over the `/blog` route. Most of the time, command palettes on sites do nothing more than regurgitate shortcuts that are already on the same page you're hiding with the palette's modal. + +## Something important + +Before we wrap up, I want to emphasize that everything that I've shared here is based on my own personal opinions and experiences. While I believe these practices and choices lead to a better blogging experience, you're absolutely free to disagree. + +The web development community, especially in spaces like Twitter and various online forums, is constantly engaged in heated debates about what constitutes "best practices." You'll find a wide spectrum of viewpoints: + +1. Fundamentalists who adhere strictly to established patterns and completely disregard change, +2. Accelerationists who gobble up whatever Vercel cooks as if it's the second coming of Christ, +3. and everyone in between this spectrum who just wants to ship. + +I'm just another guy who loves to blog, and I wanted to share what particular technology stack worked the best for me in this particular use case. A stack for one project can be completely unusable for another. If you vehemently hate any of the design choices I've made then simply get rid of them. MIT license! Happy blogging. diff --git a/src/content/projects/project-a.md b/src/content/projects/project-a.md index 2bf6faa..d7a8f5f 100644 --- a/src/content/projects/project-a.md +++ b/src/content/projects/project-a.md @@ -1,7 +1,7 @@ --- -name: "Project A" -description: "This is an example project description! You should replace this with a description of your own project." -tags: ["Framework A", "Library B", "Tool C", "Resource D"] -image: "../../../public/static/1200x630.png" -link: "https://example.com" ---- \ No newline at end of file +name: 'Project A' +description: 'This is an example project description! You should replace this with a description of your own project.' +tags: ['Framework A', 'Library B', 'Tool C', 'Resource D'] +image: '../../../public/static/1200x630.png' +link: 'https://example.com' +--- diff --git a/src/content/projects/project-b.md b/src/content/projects/project-b.md index 08bebc5..17004a8 100644 --- a/src/content/projects/project-b.md +++ b/src/content/projects/project-b.md @@ -1,7 +1,7 @@ --- -name: "Project B" -description: "This is an example project description! You should replace this with a description of your own project." -tags: ["Framework A", "Library B", "Tool C", "Resource D"] -image: "../../../public/static/1200x630.png" -link: "https://example.com" ---- \ No newline at end of file +name: 'Project B' +description: 'This is an example project description! You should replace this with a description of your own project.' +tags: ['Framework A', 'Library B', 'Tool C', 'Resource D'] +image: '../../../public/static/1200x630.png' +link: 'https://example.com' +--- diff --git a/src/content/projects/project-c.md b/src/content/projects/project-c.md index e63aafe..b9d0af5 100644 --- a/src/content/projects/project-c.md +++ b/src/content/projects/project-c.md @@ -1,7 +1,7 @@ --- -name: "Project C" -description: "This is an example project description! You should replace this with a description of your own project." -tags: ["Framework A", "Library B", "Tool C", "Resource D"] -image: "../../../public/static/1200x630.png" -link: "https://example.com" ---- \ No newline at end of file +name: 'Project C' +description: 'This is an example project description! You should replace this with a description of your own project.' +tags: ['Framework A', 'Library B', 'Tool C', 'Resource D'] +image: '../../../public/static/1200x630.png' +link: 'https://example.com' +--- diff --git a/src/pages/about.astro b/src/pages/about.astro index a001145..7b38799 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -16,18 +16,16 @@ const projects = await getCollection('projects')

    Some more about us

    -

    +

    {SITE.TITLE} is an opinionated, no-frills static blogging template built with Astro.

    Our Projects

    - {projects.map((project) => ( - - ))} + {projects.map((project) => )}
    - \ No newline at end of file + diff --git a/src/pages/authors/index.astro b/src/pages/authors/index.astro index fbc62ed..7f3358e 100644 --- a/src/pages/authors/index.astro +++ b/src/pages/authors/index.astro @@ -11,18 +11,18 @@ const authors = await getCollection('authors') - {authors.length > 0 ? ( -
      - { - authors.map((author) => ( + { + authors.length > 0 ? ( +
        + {authors.map((author) => (
      • - )) - } -
      - ) : ( -

      No authors found.

      - )} + ))} +
    + ) : ( +

    No authors found.

    + ) + }
    diff --git a/src/pages/tags/[...slug].astro b/src/pages/tags/[...slug].astro index d58fcdc..878b4c0 100644 --- a/src/pages/tags/[...slug].astro +++ b/src/pages/tags/[...slug].astro @@ -38,7 +38,7 @@ export async function getStaticPaths() { > -
    +

    Posts tagged with