diff --git a/astro.config.mjs b/astro.config.mjs index 0155cbe..d7e6109 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -4,7 +4,10 @@ import sitemap from '@astrojs/sitemap'; //import cloudflare from "@astrojs/cloudflare"; import remarkGfm from "remark-gfm"; import remarkRehype from "remark-rehype"; +import rehypeSlug from "rehype-slug"; import rehypePrettyCode from "rehype-pretty-code"; +import rehypeAutolinkHeadings from "rehype-autolink-headings"; +import { s } from "hastscript"; import json from "./public/themes/github_light.json" assert { type: "json" }; import tailwind from "@astrojs/tailwind"; @@ -42,7 +45,23 @@ export default defineConfig({ syntaxHighlight: false, remarkPlugins: [ remarkGfm, + /* Conerts remark to rehype (md -> html) */ [remarkRehype, { clobberPrefix: "" }], + /* + * rehypeSlug adds IDs to headings... which rehypeAutolinkHeadings then + * extends to tags + */ + [rehypeSlug, {}], + [rehypeAutolinkHeadings, { + content(node) { + return [ + s('svg', {viewBox: "0 0 16 16", class: "icon-link", width: "16", height: "16"}, [ + s('path', {d: "m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"}) + ]) + ] + } + }], + /* Does the syntax highlighting and parsing on code */ [rehypePrettyCode, options], ], //shikiConfig: { diff --git a/package-lock.json b/package-lock.json index 339e6c1..99437d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,10 @@ "@astrojs/sitemap": "^3.0.3", "@astrojs/tailwind": "^5.0.4", "astro": "^4.0.7", + "hastscript": "^8.0.0", + "rehype-autolink-headings": "^7.1.0", "rehype-pretty-code": "^0.12.3", + "rehype-slug": "^6.0.0", "remark-gfm": "^4.0.0", "remark-rehype": "^11.0.0", "sharp": "^0.33.1", @@ -3359,6 +3362,30 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-heading-rank": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz", + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "dependencies": { + "@types/hast": "^3.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", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", @@ -6093,6 +6120,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-autolink-headings": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz", + "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-parse": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.0.tgz", @@ -6140,6 +6184,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz", + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "dependencies": { + "@types/hast": "^3.0.0", + "github-slugger": "^2.0.0", + "hast-util-heading-rank": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-stringify": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", diff --git a/package.json b/package.json index 809b418..6f69fa1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,10 @@ "@astrojs/sitemap": "^3.0.3", "@astrojs/tailwind": "^5.0.4", "astro": "^4.0.7", + "hastscript": "^8.0.0", + "rehype-autolink-headings": "^7.1.0", "rehype-pretty-code": "^0.12.3", + "rehype-slug": "^6.0.0", "remark-gfm": "^4.0.0", "remark-rehype": "^11.0.0", "sharp": "^0.33.1", diff --git a/src/layouts/BlogPost.astro b/src/layouts/BlogPost.astro index eab7fcf..a4bb8cc 100644 --- a/src/layouts/BlogPost.astro +++ b/src/layouts/BlogPost.astro @@ -15,6 +15,7 @@ const { title, description, pubDate, updatedDate, heroImage } = Astro.props;