Commit 4481f54

HPCesia <me@hpcesia.com>
2025-02-26 13:59:55
feat: components in `.md`
1 parent 68d6253
src/plugins/rehype-components-list.ts
@@ -0,0 +1,29 @@
+/**
+ * All components in this file should sync with the components in `src/components/user`
+ */
+import { h } from 'hastscript';
+import type { Child } from 'hastscript';
+
+const Collapse = function (
+  props: {
+    title: string;
+    open?: true;
+  },
+  children: Child
+) {
+  const { title, open } = props;
+  const wrapperClassName =
+    'bg-base-100 border-base-content/25 collapse-arrow collapse my-4 border';
+  const titleClassName = 'collapse-title font-semibold';
+  const contentClassName = 'collapse-content';
+
+  const inputNode = h('input', {
+    type: 'checkbox',
+    ...(open && { checked: true }),
+  });
+  const titleNode = h('div', { class: titleClassName }, title);
+  const contentNode = h('div', { class: contentClassName }, children);
+  return h('div', { class: wrapperClassName }, [inputNode, titleNode, contentNode]);
+};
+
+export const rehypeComponentsList = { collapse: Collapse };
astro.config.mjs
@@ -1,5 +1,6 @@
 // @ts-check
 import { CDN } from './src/constants/cdn.mjs';
+import { rehypeComponentsList } from './src/plugins/rehype-components-list.ts';
 import { rehypePrettierCodes } from './src/plugins/rehype-prettier-codes.ts';
 import { rehypeWrapTables } from './src/plugins/rehype-wrap-tables.ts';
 import { remarkExcerpt } from './src/plugins/remark-excerpt.ts';
@@ -18,7 +19,10 @@ import icon from 'astro-icon';
 import pagefind from 'astro-pagefind';
 import { defineConfig } from 'astro/config';
 import rehypeAutolinkHeadings from 'rehype-autolink-headings';
+import rehypeComponents from 'rehype-components';
 import rehypeMathJaxCHtml from 'rehype-mathjax/chtml';
+import remarkDirective from 'remark-directive';
+import remarkDirectiveRehype from 'remark-directive-rehype';
 import remarkMath from 'remark-math';
 
 // https://astro.build/config
@@ -43,12 +47,16 @@ export default defineConfig({
       transformers: [
         // transformerNotationDiff(),
         // transformerNotationHighlight(),
+        // @ts-expect-error Type of shiki transformer in astro is not up to date.
         wrapCode(),
       ],
     },
     remarkPlugins: [
       // remarkHeadingShift,
       remarkMath,
+      remarkDirective,
+      // @ts-expect-error Types of the plugin are not correct
+      remarkDirectiveRehype,
       remarkReadingTime,
       remarkExcerpt,
       remarkImageProcess,
@@ -79,6 +87,7 @@ export default defineConfig({
       ],
       rehypeWrapTables,
       rehypePrettierCodes,
+      [rehypeComponents, { components: rehypeComponentsList }],
     ],
   },
   vite: {
package.json
@@ -35,6 +35,8 @@
     "autoprefixer": "^10.4.20",
     "daisyui": "5.0.0-beta.8",
     "dayjs": "^1.11.13",
+    "hast-util-from-html": "^2.0.3",
+    "hast-util-to-html": "^9.0.5",
     "hastscript": "^9.0.1",
     "markdown-it": "^14.1.0",
     "mdast-util-to-string": "^4.0.0",
@@ -43,7 +45,10 @@
     "postcss-load-config": "^6.0.1",
     "reading-time": "^1.5.0",
     "rehype-autolink-headings": "^7.1.0",
+    "rehype-components": "^0.3.0",
     "rehype-mathjax": "^6.0.0",
+    "remark-directive": "^3.0.1",
+    "remark-directive-rehype": "^0.4.2",
     "remark-github-beta-blockquote-admonitions": "^3.1.1",
     "remark-math": "^6.0.0",
     "sanitize-html": "^2.14.0",