diff --git a/astro.config.ts b/astro.config.ts index 86277cf..9022792 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -3,8 +3,10 @@ import partytown from '@astrojs/partytown' import sitemap from '@astrojs/sitemap' import robotsTxt from 'astro-robots-txt' import { defineConfig } from 'astro/config' +import rehypeAutolinkHeadings from 'rehype-autolink-headings' import rehypeExternalLinks from 'rehype-external-links' import rehypeKatex from 'rehype-katex' +import rehypeSlug from 'rehype-slug' import remarkDirective from 'remark-directive' import remarkMath from 'remark-math' import UnoCSS from 'unocss/astro' @@ -19,15 +21,10 @@ const url = themeConfig.site.url const locale = themeConfig.global.locale const linkPrefetch = themeConfig.preload.linkPrefetch const imageHostURL = themeConfig.preload.imageHostURL +// Configure domains and remotePatterns to optimize remote images in Markdown files using ![alt](src) syntax +// Docs: https://docs.astro.build/en/guides/images/#authorizing-remote-images const imageConfig = imageHostURL - ? { - // Configure domains and remotePatterns to optimize remote images in Markdown files using ![alt](src) syntax - // Docs: https://docs.astro.build/en/guides/images/#authorizing-remote-images - image: { - domains: [imageHostURL], - remotePatterns: [{ protocol: 'https' }], - }, - } + ? { image: { domains: [imageHostURL], remotePatterns: [{ protocol: 'https' }] } } : {} export default defineConfig({ @@ -69,7 +66,44 @@ export default defineConfig({ ], rehypePlugins: [ rehypeKatex, + rehypeSlug, rehypeImgToFigure, + [ + rehypeAutolinkHeadings, + { + behavior: 'append', + test: ['h1', 'h2', 'h3', 'h4'], + content: { + type: 'element', + tagName: 'svg', + properties: { + 'viewBox': '0 0 24 24', + 'aria-hidden': 'true', + 'fill': 'currentColor', + }, + children: [ + { + type: 'element', + tagName: 'path', + properties: { + d: 'm7.374 15.182 7.85-7.849 1.413 1.414-7.848 7.85z', + }, + }, + { + type: 'element', + tagName: 'path', + properties: { + d: 'M10.6 20c-1.8 1.8-4.7 1.8-6.5 0-.9-.9-1.4-2-1.4-3.3s.5-2.4 1.4-3.3l3.8-3.8-1.4-1.4-4.2 4.2c-2.5 2.5-2.5 6.7 0 9.3 1.3 1.3 3 1.9 4.6 1.9s3.4-.6 4.6-1.9l4.2-4.2-1.4-1.4-3.8 3.8ZM21.7 2.3C20.5 1.1 18.8.4 17.1.4s-3.4.7-4.6 1.9L8.3 6.5l1.4 1.4 3.8-3.8c1.8-1.8 4.7-1.8 6.5 0 .9.9 1.4 2 1.4 3.3s-.5 2.4-1.4 3.3l-3.8 3.8 1.4 1.4 4.2-4.2c1.2-1.2 1.9-2.9 1.9-4.6s-.7-3.4-1.9-4.6Z', + }, + }, + ], + }, + properties: { + className: ['heading-anchor-link'], + ariaLabel: 'Link to this section', + }, + }, + ], [ rehypeExternalLinks, { diff --git a/package.json b/package.json index b611807..de7250f 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,10 @@ "overlayscrollbars": "^2.11.2", "photoswipe": "^5.4.4", "reading-time": "^1.5.0", + "rehype-autolink-headings": "^7.1.0", "rehype-external-links": "^3.0.0", "rehype-katex": "^7.0.1", + "rehype-slug": "^6.0.0", "remark-directive": "^4.0.0", "remark-math": "^6.0.0", "sanitize-html": "^2.16.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fedeaf..cd347d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,12 +56,18 @@ importers: reading-time: specifier: ^1.5.0 version: 1.5.0 + rehype-autolink-headings: + specifier: ^7.1.0 + version: 7.1.0 rehype-external-links: specifier: ^3.0.0 version: 3.0.0 rehype-katex: specifier: ^7.0.1 version: 7.0.1 + rehype-slug: + specifier: ^6.0.0 + version: 6.0.0 remark-directive: specifier: ^4.0.0 version: 4.0.0 @@ -2366,6 +2372,9 @@ packages: hast-util-from-parse5@8.0.3: resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + hast-util-is-element@3.0.0: resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} @@ -2387,6 +2396,9 @@ packages: hast-util-to-parse5@8.0.0: resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + hast-util-to-text@4.0.2: resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} @@ -3317,6 +3329,9 @@ packages: resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} hasBin: true + rehype-autolink-headings@7.1.0: + resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} + rehype-external-links@3.0.0: resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==} @@ -3332,6 +3347,9 @@ packages: rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + rehype-stringify@10.0.1: resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} @@ -6833,6 +6851,10 @@ snapshots: vfile-location: 5.0.3 web-namespaces: 2.0.1 + hast-util-heading-rank@3.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-is-element@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -6922,6 +6944,10 @@ snapshots: web-namespaces: 2.0.1 zwitch: 2.0.4 + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-text@4.0.2: dependencies: '@types/hast': 3.0.4 @@ -8101,6 +8127,15 @@ snapshots: dependencies: jsesc: 3.0.2 + rehype-autolink-headings@7.1.0: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.3.0 + hast-util-heading-rank: 3.0.0 + hast-util-is-element: 3.0.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 + rehype-external-links@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -8140,6 +8175,14 @@ snapshots: transitivePeerDependencies: - supports-color + rehype-slug@6.0.0: + dependencies: + '@types/hast': 3.0.4 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.1 + unist-util-visit: 5.0.0 + rehype-stringify@10.0.1: dependencies: '@types/hast': 3.0.4 diff --git a/src/components/Header.astro b/src/components/Header.astro index cafa0f4..01ecec4 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -17,7 +17,7 @@ const SubtitleTag = isPost ? 'div' : 'h2'