diff --git a/astro.config.ts b/astro.config.ts index 8671440..b5c9750 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -3,10 +3,11 @@ import mdx from "@astrojs/mdx"; import sitemap from "@astrojs/sitemap"; import { astroImageTools } from "astro-imagetools"; -import { remarkReadingTime } from "./plugin/remark-reading-time"; +import remarkReadingTime from "./plugin/remark-reading-time"; import emoji from "remark-emoji"; import remarkMermaid from "astro-diagram/remark-mermaid"; import remarkDescription from "astro-remark-description"; +import remarkAdmonitions from "./plugin/remark-admonitions"; // https://astro.build/config export default defineConfig({ @@ -15,6 +16,7 @@ export default defineConfig({ markdown: { syntaxHighlight: false, remarkPlugins: [ + remarkAdmonitions, remarkReadingTime, remarkMermaid, emoji, diff --git a/package-lock.json b/package-lock.json index 980cfac..73670fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,13 +19,18 @@ "lodash-es": "^4.17.21", "mdast-util-to-string": "^4.0.0", "reading-time": "^1.5.0", - "remark-emoji": "^4.0.0" + "remark-emoji": "^4.0.0", + "remark-github-beta-blockquote-admonitions": "^2.1.0", + "remark-parse": "^10.0.2" }, "devDependencies": { "@types/lodash-es": "^4.17.9", + "mdast": "^3.0.0", "prettier": "^3.0.3", "prettier-plugin-astro": "^0.12.0", - "sass": "^1.66.1" + "sass": "^1.66.1", + "unified": "^11.0.2", + "unist-util-visit": "^5.0.0" } }, "node_modules/@ampproject/remapping": { @@ -73,6 +78,38 @@ "astro": "^3.0.0" } }, + "node_modules/@astrojs/markdown-remark/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/@astrojs/markdown-remark/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/@astrojs/mdx": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-1.0.0.tgz", @@ -104,6 +141,20 @@ "astro": "^3.0.0" } }, + "node_modules/@astrojs/mdx/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/@astrojs/prism": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.0.0.tgz", @@ -1364,6 +1415,38 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@mdx-js/mdx/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/@mdx-js/mdx/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/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1569,6 +1652,12 @@ "@types/node": "*" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -1798,6 +1887,20 @@ "mermaid": "^9.1.6" } }, + "node_modules/astro-diagram/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/astro-imagetools": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/astro-imagetools/-/astro-imagetools-0.9.0.tgz", @@ -1892,6 +1995,34 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/astro-remark-description/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/astro/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/b4a": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", @@ -2926,6 +3057,19 @@ "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/devtools-protocol": { "version": "0.0.1045489", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz", @@ -3602,6 +3746,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-raw/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/hast-util-to-estree": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", @@ -4435,6 +4593,13 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/mdast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast/-/mdast-3.0.0.tgz", + "integrity": "sha512-xySmf8g4fPKMeC07jXGz971EkLbWAJ83s4US2Tj9lEdnZ142UP5grN73H1Xd3HzrdbU5o9GYYP/y8F9ZSwLE9g==", + "deprecated": "`mdast` was renamed to `remark`", + "dev": true + }, "node_modules/mdast-util-definitions": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", @@ -4449,6 +4614,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-definitions/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/mdast-util-find-and-replace": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", @@ -4715,6 +4894,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-hast/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/mdast-util-to-markdown": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", @@ -4746,6 +4939,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-to-markdown/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/mdast-util-to-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", @@ -6546,6 +6753,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-parse/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/rehype-raw": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", @@ -6560,6 +6785,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-raw/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/rehype-stringify": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.4.tgz", @@ -6574,6 +6817,42 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-stringify/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/rehype/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/remark-emoji": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.0.tgz", @@ -6666,6 +6945,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-frontmatter/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/remark-gfm": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", @@ -6681,6 +6978,46 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-gfm/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/remark-github-beta-blockquote-admonitions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-github-beta-blockquote-admonitions/-/remark-github-beta-blockquote-admonitions-2.1.0.tgz", + "integrity": "sha512-mWCU9DHDWCGSGiAnAEkPVrIteeIc6uTH6sv7Jv807ndmeioqocu3PExWe7/a6ajMMKDSU4dKWpdExCA0UtJplQ==", + "dependencies": { + "unist-util-visit": "^4.1.2" + } + }, + "node_modules/remark-github-beta-blockquote-admonitions/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/remark-mdx": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", @@ -6708,6 +7045,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-parse/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/remark-rehype": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", @@ -6723,6 +7078,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-rehype/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/remark-smartypants": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", @@ -6736,6 +7109,20 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/remark-smartypants/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/resolve": { "version": "1.22.4", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", @@ -6824,6 +7211,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/retext-latin/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/retext-smartypants": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", @@ -6839,6 +7244,38 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/retext-smartypants/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/retext-smartypants/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/retext-stringify": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", @@ -6853,6 +7290,42 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/retext-stringify/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/retext/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/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -7613,17 +8086,66 @@ } }, "node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.2.tgz", + "integrity": "sha512-Zta++onvS/dJ6xUvXQOR5q8XJZOkiMCE5wQ8Yv9mLR25pxRS567EX0GO6HZRxxNV/lznwfsvRZ/1pqe9K9QLeQ==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", + "devlop": "^1.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", - "vfile": "^5.0.0" + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==", + "dev": true + }, + "node_modules/unified/node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/vfile": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", + "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified/node_modules/vfile-message": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" }, "funding": { "type": "opencollective", @@ -7701,6 +8223,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-remove-position/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/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", @@ -7714,13 +8250,14 @@ } }, "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==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", @@ -7752,6 +8289,39 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==", + "dev": true + }, + "node_modules/unist-util-visit/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dev": true, + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", diff --git a/package.json b/package.json index 22baf37..4724264 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,17 @@ "lodash-es": "^4.17.21", "mdast-util-to-string": "^4.0.0", "reading-time": "^1.5.0", - "remark-emoji": "^4.0.0" + "remark-emoji": "^4.0.0", + "remark-github-beta-blockquote-admonitions": "^2.1.0", + "remark-parse": "^10.0.2" }, "devDependencies": { "@types/lodash-es": "^4.17.9", + "mdast": "^3.0.0", "prettier": "^3.0.3", "prettier-plugin-astro": "^0.12.0", - "sass": "^1.66.1" + "sass": "^1.66.1", + "unified": "^11.0.2", + "unist-util-visit": "^5.0.0" } } diff --git a/plugin/remark-admonitions.ts b/plugin/remark-admonitions.ts new file mode 100644 index 0000000..73e4ca8 --- /dev/null +++ b/plugin/remark-admonitions.ts @@ -0,0 +1,147 @@ +// https://github.com/myl7/remark-github-beta-blockquote-admonitions +// License: Apache-2.0 + +import { visit } from "unist-util-visit"; +import type { Data } from "unist"; +import type { BuildVisitor } from "unist-util-visit"; +import type { Blockquote, Paragraph, Text } from "mdast"; +import type { RemarkPlugin } from "@astrojs/markdown-remark"; + +const remarkAdmonitions: RemarkPlugin = function (providedConfig?: Partial) { + return (tree) => { + visit(tree, handleNode({ ...defaultConfig, ...providedConfig })); + }; +}; + +export default remarkAdmonitions; + +const handleNode = + (config: Config): BuildVisitor => + (node) => { + // Filter required elems + if (node.type != "blockquote") return; + const blockquote = node as Blockquote; + + if (blockquote.children[0]?.type != "paragraph") return; + + const paragraph = blockquote.children[0]; + if (paragraph.children[0]?.type != "text") return; + + const text = paragraph.children[0]; + + // A link break after the title is explicitly required by GitHub + const titleEnd = text.value.indexOf("\n"); + console.log("Title End", titleEnd); + if (titleEnd < 0) return; + + const textBody = text.value.substring(titleEnd + 1); + let title = text.value.substring(0, titleEnd); + // Handle whitespaces after the title. + // Whitespace characters are defined by GFM + const m = /[ \t\v\f\r]+$/.exec(title); + if (m && !config.titleKeepTrailingWhitespaces) { + title = title.substring(0, title.length - m[0].length); + } + console.log("TITLE IS", title); + if (!nameFilter(config.titleFilter)(title)) return; + const { displayTitle, checkedTitle } = config.titleTextMap(title); + + // Update the text body + text.value = textBody; + + // Insert the title element and add classes for the title + const paragraphTitleText: Text = { type: "text", value: displayTitle }; + const paragraphTitle: Paragraph = { + type: "paragraph", + children: [paragraphTitleText], + data: config.dataMaps.title({ + hProperties: { className: classNameMap(config.classNameMaps.title)(checkedTitle) }, + }), + }; + blockquote.children.unshift(paragraphTitle); + + // Add classes for the block + blockquote.data = config.dataMaps.block({ + ...blockquote.data, + hProperties: { className: classNameMap(config.classNameMaps.block)(checkedTitle) }, + // The blockquote should be rendered as a div, which is explicitly required by GitHub + hName: "div", + }); + }; + +export const mkdocsConfig: Partial = { + classNameMaps: { + block: (title) => [ + "admonition", + ...(title.startsWith("admonition: ") ? title.substring("admonition: ".length) : title).split( + " ", + ), + ], + title: "admonition-title", + }, + titleFilter: (title) => + (title.startsWith("[!admonition: ") && title.endsWith("]")) || + (Boolean(title.match(/^\[!(attention|caution|danger|error|hint|important|note|tip|warning)/)) && + title.endsWith("]")), + titleTextMap: (title) => { + title = title.substring(2, title.length - 1); + // ' "' will not occur in classes + const i = title.indexOf(' "'); + const displayTitle = + i >= 0 + ? title.substring(i + 2, title.length - 1) // Display title is wrapped with "" + : ""; + const checkedTitle = title.substring(0, i); + return { displayTitle, checkedTitle }; + }, +}; +export interface Config { + classNameMaps: { + block: ClassNameMap; + title: ClassNameMap; + }; + titleFilter: NameFilter; + titleTextMap: (title: string) => { displayTitle: string; checkedTitle: string }; + dataMaps: { + block: (data: Data) => Data; + title: (data: Data) => Data; + }; + titleKeepTrailingWhitespaces: boolean; + legacyTitle: boolean; +} + +export const defaultConfig: Config = { + classNameMaps: { + block: "admonition", + title: "admonition-title", + }, + titleFilter: ["[!NOTE]", "[!IMPORTANT]", "[!WARNING]"], + titleTextMap: (title) => ({ + displayTitle: title.substring(2, title.length - 1), + checkedTitle: title.substring(2, title.length - 1), + }), + dataMaps: { + block: (data) => data, + title: (data) => data, + }, + titleKeepTrailingWhitespaces: false, + legacyTitle: false, +}; + +type ClassNames = string | string[]; +type ClassNameMap = ClassNames | ((title: string) => ClassNames); + +export function classNameMap(gen: ClassNameMap) { + return (title: string) => { + const classNames = typeof gen == "function" ? gen(title) : gen; + return typeof classNames == "object" ? classNames.join(" ") : classNames; + }; +} + +type NameFilter = ((title: string) => boolean) | string[]; + +export function nameFilter(filter: NameFilter) { + return (title: string) => { + return typeof filter == "function" ? filter(title) : filter.includes(title); + }; +} diff --git a/plugin/remark-reading-time.ts b/plugin/remark-reading-time.ts index 535540a..efb0681 100644 --- a/plugin/remark-reading-time.ts +++ b/plugin/remark-reading-time.ts @@ -1,12 +1,16 @@ import getReadingTime from "reading-time"; import { toString } from "mdast-util-to-string"; +import type { RemarkPlugin } from "@astrojs/markdown-remark"; -export function remarkReadingTime() { +const remarkReadingTime: RemarkPlugin = () => { return function (tree, { data }) { const textOnPage = toString(tree); const readingTime = getReadingTime(textOnPage); + // readingTime.text will give us minutes read as a friendly string, // i.e. "3 min read" data.astro.frontmatter.minutesRead = readingTime.text; }; -} +}; + +export default remarkReadingTime; diff --git a/src/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md b/src/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md index dd672e6..7876718 100644 --- a/src/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md +++ b/src/content/posts/2023-03-29-shell-in-docker-compose-container-without-shell.md @@ -12,6 +12,7 @@ container without exiting it. Some Docker containers are incredibly stripped down to optimize away bloat (which is good!) but this may make debugging them relatively annoying. +> [!NOTE] > These are my specific steps for running it, please replace the paths and > container names with the ones relevant to your specific use-case. diff --git a/src/content/posts/2023-04-20-developing-without-flake.md b/src/content/posts/2023-04-20-developing-without-flake.md index a693607..c88cf7d 100644 --- a/src/content/posts/2023-04-20-developing-without-flake.md +++ b/src/content/posts/2023-04-20-developing-without-flake.md @@ -61,6 +61,7 @@ I shove new config files in their root directory.  flake.nix ✗ ``` +> [!NOTE] > The `✗` indicates that I added the file to the project, and it hasn't been > committed to the repo yet. @@ -130,9 +131,10 @@ project structure should look a bit more like this:  flake.nix ``` -> Remember, since you moved the `.envrc` file, you will need to run `direnv -allow` again. Depending on how you moved it, you might also need to change the -> path you wrote in the `use flake` command. +> [!NOTE] +> Remember, since you moved the `.envrc` file, you will need to run `direnv allow` +> again. Depending on how you moved it, you might also need to change the path you +> wrote in the `use flake` command. With this setup, the `project` directory can contain a clean clone of upstream and your flake files will create the appropriate environment. diff --git a/src/content/posts/2023-08-31-thoughts-on-organization/index.md b/src/content/posts/2023-08-31-thoughts-on-organization/index.md index 7d76c54..4baa175 100644 --- a/src/content/posts/2023-08-31-thoughts-on-organization/index.md +++ b/src/content/posts/2023-08-31-thoughts-on-organization/index.md @@ -29,6 +29,7 @@ my personal schedule, yet they only see a small slice of your life. The only things calendars can see automatically with no intervention on my part are emails that are sent from airlines. +> [!NOTE] > I'm sure Google or Apple could probably ritz up their services to scan text > and guess events to put on your calendar, but that's missing the point. The vast > majority of people I associate with rarely coordinate events over email in the @@ -117,10 +118,12 @@ data using various visualizations for this purpose. [2]: https://git.mzhang.io/michael/logseq-calendar -> Side note: this isn't sponsored in any way. While this post makes me sound -> like just a Logseq shill, it's actually quite the opposite; I've been donating -> to them monthly on [Open Collective] and they've been actively developing -> really cool features! +> [!NOTE] +> As an aside, this isn't sponsored in any way. While this post makes me sound +> like just a Logseq shill, it's actually quite the opposite: they're an +> open-source project solely funded by donations. I've been donating to them +> monthly on [Open Collective] and they've been actively developing really cool +> features! [open collective]: https://opencollective.com/logseq diff --git a/src/styles/post.scss b/src/styles/post.scss index 6d5947c..7bfa09f 100644 --- a/src/styles/post.scss +++ b/src/styles/post.scss @@ -228,3 +228,21 @@ hr.endline { } } } + +.admonition { + // TODO: Figure out how to distinguish admonitions + --color: var(--link-color); + + border-left: 4px solid var(--color); + padding-left: 8px; + font-size: 0.9rem; + + .admonition-title { + color: var(--color); + margin-bottom: 6px; + } + + p { + margin: 0; + } +} diff --git a/tsconfig.json b/tsconfig.json index 6e224ec..a023039 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "astro/tsconfigs/strictest", "compilerOptions": { + "moduleResolution": "Node", "strictNullChecks": true } }