From 078a127d290c0b61015dfd21fe3c98cebf2f0c3b Mon Sep 17 00:00:00 2001 From: Zeke Abshire Date: Thu, 1 Jun 2023 22:18:54 -0500 Subject: [PATCH] Added syntax highlighting to code blocks --- package-lock.json | 170 +++++++++++++++++++++++++++++ package.json | 2 + src/components/MDX.tsx | 10 +- src/pages/projects/[projectId].tsx | 8 +- 4 files changed, 185 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8f4def7..999fc08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "@trpc/server": "^10.9.0", "class-variance-authority": "^0.4.0", "dayjs": "^1.11.7", + "highlight.js": "^11.8.0", "next": "13.1.6", "next-auth": "^4.19.0", "next-mdx-remote": "^4.4.1", @@ -37,6 +38,7 @@ "react-hook-form": "^7.43.8", "react-hot-toast": "^2.4.0", "react-icons": "^4.8.0", + "rehype-highlight": "^6.0.0", "superjson": "1.9.1", "zod": "^3.20.2" }, @@ -4445,6 +4447,18 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -4513,6 +4527,14 @@ "is-callable": "^1.1.3" } }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -4833,6 +4855,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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-to-estree": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", @@ -4859,6 +4894,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-text": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz", + "integrity": "sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "unist-util-find-after": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", @@ -4868,6 +4918,14 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/highlight.js": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", + "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -5563,6 +5621,20 @@ "loose-envify": "cli.js" } }, + "node_modules/lowlight": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz", + "integrity": "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw==", + "dependencies": { + "@types/hast": "^2.0.0", + "fault": "^2.0.0", + "highlight.js": "~11.8.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7436,6 +7508,22 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/rehype-highlight": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-6.0.0.tgz", + "integrity": "sha512-q7UtlFicLhetp7K48ZgZiJgchYscMma7XjzX7t23bqEJF8m6/s+viXQEe4oHjrATTIZpX7RG8CKD7BlNZoh9gw==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-to-text": "^3.0.0", + "lowlight": "^2.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "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", @@ -8177,6 +8265,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-find-after": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz", + "integrity": "sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-generated": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", @@ -11842,6 +11943,14 @@ "reusify": "^1.0.4" } }, + "fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "requires": { + "format": "^0.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -11895,6 +12004,11 @@ "is-callable": "^1.1.3" } }, + "format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" + }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -12115,6 +12229,15 @@ "has-symbols": "^1.0.2" } }, + "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==", + "requires": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" + } + }, "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", @@ -12137,11 +12260,27 @@ "zwitch": "^2.0.0" } }, + "hast-util-to-text": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz", + "integrity": "sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==", + "requires": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "unist-util-find-after": "^4.0.0" + } + }, "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==" }, + "highlight.js": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.8.0.tgz", + "integrity": "sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -12622,6 +12761,16 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lowlight": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-2.9.0.tgz", + "integrity": "sha512-OpcaUTCLmHuVuBcyNckKfH5B0oA4JUavb/M/8n9iAvanJYNQkrVm4pvyX0SUaqkBG4dnWHKt7p50B3ngAG2Rfw==", + "requires": { + "@types/hast": "^2.0.0", + "fault": "^2.0.0", + "highlight.js": "~11.8.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -13766,6 +13915,18 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "rehype-highlight": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-highlight/-/rehype-highlight-6.0.0.tgz", + "integrity": "sha512-q7UtlFicLhetp7K48ZgZiJgchYscMma7XjzX7t23bqEJF8m6/s+viXQEe4oHjrATTIZpX7RG8CKD7BlNZoh9gw==", + "requires": { + "@types/hast": "^2.0.0", + "hast-util-to-text": "^3.0.0", + "lowlight": "^2.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + } + }, "remark-mdx": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", @@ -14283,6 +14444,15 @@ "vfile": "^5.0.0" } }, + "unist-util-find-after": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz", + "integrity": "sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==", + "requires": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + } + }, "unist-util-generated": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", diff --git a/package.json b/package.json index c4b319f..f933493 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@trpc/server": "^10.9.0", "class-variance-authority": "^0.4.0", "dayjs": "^1.11.7", + "highlight.js": "^11.8.0", "next": "13.1.6", "next-auth": "^4.19.0", "next-mdx-remote": "^4.4.1", @@ -38,6 +39,7 @@ "react-hook-form": "^7.43.8", "react-hot-toast": "^2.4.0", "react-icons": "^4.8.0", + "rehype-highlight": "^6.0.0", "superjson": "1.9.1", "zod": "^3.20.2" }, diff --git a/src/components/MDX.tsx b/src/components/MDX.tsx index 546a58c..dd1cd17 100644 --- a/src/components/MDX.tsx +++ b/src/components/MDX.tsx @@ -4,6 +4,7 @@ import type { ComponentPropsWithoutRef, HTMLAttributes, } from "react"; +import "highlight.js/styles/base16/gruvbox-dark-medium.css"; type Tag = JSX.IntrinsicAttributes & ClassAttributes & HTMLAttributes; type HTMLTag = Tag; @@ -26,7 +27,10 @@ const components = { /> ), blockquote: (props: Tag) => ( -
+
), br: (props: Tag) =>
, code: (props: HTMLTag) => ( @@ -34,7 +38,7 @@ const components = { ), em: (props: HTMLTag) => , hr: (props: Tag) => ( -
+
), img: (props: Tag) => ( @@ -47,7 +51,7 @@ const components = {
    ), pre: (props: Tag) => ( -
    +    
       ),
       strong: (props: HTMLTag) => ,
     };
    diff --git a/src/pages/projects/[projectId].tsx b/src/pages/projects/[projectId].tsx
    index 025cfdf..969ee79 100644
    --- a/src/pages/projects/[projectId].tsx
    +++ b/src/pages/projects/[projectId].tsx
    @@ -6,6 +6,7 @@ import type {
       InferGetServerSidePropsType,
       NextPage,
     } from "next";
    +import rehypeHighlight from "rehype-highlight";
     import { serialize } from "next-mdx-remote/serialize";
     import { prisma } from "@server/db";
     import superjson from "superjson";
    @@ -132,7 +133,8 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
       // const projectDescription = project?.description ?? "";
       // const mdxSource = await serialize(projectDescription);
     
    -  const mdxSource = await serialize(`
    +  const mdxSource = await serialize(
    +    `
     # Heading 1
     
     ## Heading 2
    @@ -174,7 +176,9 @@ function greet() {
     *Emphasized* text.
     
     **Strong** text.
    -      `);
    +      `,
    +    { mdxOptions: { rehypePlugins: [rehypeHighlight] } }
    +  );
     
       return { props: { projectId, description: mdxSource } };
     };