From c82ebcb23de31edfffbb3676ea2432a416699a30 Mon Sep 17 00:00:00 2001 From: Dorian Niemiec Date: Thu, 7 Nov 2024 18:06:11 +0100 Subject: [PATCH] feat: add the documentation layout --- .../[[...slug]]/_styles/prism-twilight.css | 123 ++++++++ .../_styles/prism.twilight.min.css | 98 ++++++ app/docs/[[...slug]]/page.jsx | 108 +++++++ app/docs/layout.jsx | 17 ++ components/Header.jsx | 4 +- components/SidebarLinks.jsx | 35 +++ constants/docLinks.js | 7 + docs/index.md | 3 + package-lock.json | 278 +++++++++++++++++- package.json | 5 +- 10 files changed, 672 insertions(+), 6 deletions(-) create mode 100644 app/docs/[[...slug]]/_styles/prism-twilight.css create mode 100644 app/docs/[[...slug]]/_styles/prism.twilight.min.css create mode 100644 app/docs/[[...slug]]/page.jsx create mode 100644 app/docs/layout.jsx create mode 100644 components/SidebarLinks.jsx create mode 100644 constants/docLinks.js create mode 100644 docs/index.md diff --git a/app/docs/[[...slug]]/_styles/prism-twilight.css b/app/docs/[[...slug]]/_styles/prism-twilight.css new file mode 100644 index 0000000..650904b --- /dev/null +++ b/app/docs/[[...slug]]/_styles/prism-twilight.css @@ -0,0 +1,123 @@ +/** + * okaidia theme for JavaScript, CSS and HTML + * Loosely based on Monokai textmate theme by http://www.monokai.nl/ + * @author ocodia + */ + +code[class*="language-"], +pre[class*="language-"] { + color: #f8f8f2; + background: none; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #272822; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: #8292a2; +} + +.token.punctuation { + color: #f8f8f2; +} + +.token.namespace { + opacity: 0.7; +} + +.token.property, +.token.tag, +.token.constant, +.token.symbol, +.token.deleted { + color: #f92672; +} + +.token.boolean, +.token.number { + color: #ae81ff; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #a6e22e; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: #f8f8f2; +} + +.token.atrule, +.token.attr-value, +.token.function, +.token.class-name { + color: #e6db74; +} + +.token.keyword { + color: #66d9ef; +} + +.token.regex, +.token.important { + color: #fd971f; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/app/docs/[[...slug]]/_styles/prism.twilight.min.css b/app/docs/[[...slug]]/_styles/prism.twilight.min.css new file mode 100644 index 0000000..6771ee8 --- /dev/null +++ b/app/docs/[[...slug]]/_styles/prism.twilight.min.css @@ -0,0 +1,98 @@ +code[class*="language-"], +pre[class*="language-"] { + color: #f8f8f2; + background: 0 0; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} +pre[class*="language-"] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; +} +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #272822; +} +:not(pre) > code[class*="language-"] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; +} +.token.cdata, +.token.comment, +.token.doctype, +.token.prolog { + color: #8292a2; +} +.token.punctuation { + color: #f8f8f2; +} +.token.namespace { + opacity: 0.7; +} +.token.constant, +.token.deleted, +.token.property, +.token.symbol, +.token.tag { + color: #f92672; +} +.token.boolean, +.token.number { + color: #ae81ff; +} +.token.attr-name, +.token.builtin, +.token.char, +.token.inserted, +.token.selector, +.token.string { + color: #a6e22e; +} +.language-css .token.string, +.style .token.string, +.token.entity, +.token.operator, +.token.url, +.token.variable { + color: #f8f8f2; +} +.token.atrule, +.token.attr-value, +.token.class-name, +.token.function { + color: #e6db74; +} +.token.keyword { + color: #66d9ef; +} +.token.important, +.token.regex { + color: #fd971f; +} +.token.bold, +.token.important { + font-weight: 700; +} +.token.italic { + font-style: italic; +} +.token.entity { + cursor: help; +} diff --git a/app/docs/[[...slug]]/page.jsx b/app/docs/[[...slug]]/page.jsx new file mode 100644 index 0000000..e6d61aa --- /dev/null +++ b/app/docs/[[...slug]]/page.jsx @@ -0,0 +1,108 @@ +import React from "react"; +import docLinks from "@/constants/docLinks"; +import { globby } from "globby"; +import fs from "fs/promises"; +import { notFound } from "next/navigation"; +import Markdown from "react-markdown"; +import rehypePrism from "rehype-prism"; + +import "./_styles/prism-twilight.css"; +import "./_styles/prism.twilight.min.css"; + +import "prismjs/components/prism-javascript"; +import "prismjs/components/prism-python"; +import "prismjs/components/prism-php"; +import "prismjs/components/prism-bash"; +import "prismjs/components/prism-sql"; +import "prismjs/components/prism-yaml"; +import "prismjs/components/prism-markdown"; +import "prismjs/components/prism-markup-templating"; +import "prismjs/components/prism-json"; +import "prismjs/components/prism-perl"; + +export async function generateMetadata({ params }) { + const obtainedParams = await params; + const foundDocLink = docLinks.find( + (docLink) => + docLink.href == + `/docs${obtainedParams.slug ? "/" + obtainedParams.slug.join("/") : ""}` + ); + return { + title: `${foundDocLink ? foundDocLink.label : obtainedParams.slug && obtainedParams.slug.length > 0 ? obtainedParams.slug[obtainedParams.slug.length - 1] : "Documentation"} - MERNMail`, + description: + "The MERNMail documentation provides comprehensive information and instructions on how to use and configure the MERNMail webmail application.", + openGraph: { + title: `${foundDocLink ? foundDocLink.label : obtainedParams.slug && obtainedParams.slug.length > 0 ? obtainedParams.slug[obtainedParams.slug.length - 1] : "Documentation"} - MERNMail`, + description: + "The MERNMail documentation provides comprehensive information and instructions on how to use and configure the MERNMail webmail application.", + url: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/docs${obtainedParams.slug ? "/" + obtainedParams.slug.join("/") : ""}`, + type: "website", + images: [ + { + url: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/metadata/mernmail-cover.png`, + width: 2560, + height: 1440, + alt: `${foundDocLink ? foundDocLink.label : obtainedParams.slug && obtainedParams.slug.length > 0 ? obtainedParams.slug[obtainedParams.slug.length - 1] : "Documentation"} - MERNMail` + } + ] + }, + twitter: { + card: "summary_large_image", + site: "@MERNMail", + title: `${foundDocLink ? foundDocLink.label : obtainedParams.slug && obtainedParams.slug.length > 0 ? obtainedParams.slug[obtainedParams.slug.length - 1] : "Documentation"} - MERNMail`, + description: + "The MERNMail documentation provides comprehensive information and instructions on how to use and configure the MERNMail webmail application.", + images: [ + `${process.env.NEXT_PUBLIC_WEBSITE_URL}/metadata/mernmail-cover.png` + ], + creator: "@MERNMail" + } + }; +} + +export async function generateStaticParams() { + const markdownFiles = await globby("**/*.md", { + cwd: process.cwd() + "/docs" + }); + return markdownFiles.map((filePath) => { + const splitPath = filePath.split("/"); + if (splitPath[splitPath.length - 1] == "index.md") splitPath.pop(); + else { + splitPath[splitPath.length - 1] = splitPath[splitPath.length - 1].replace( + /\.md$/, + "" + ); + } + return { + slug: splitPath.length == 0 ? undefined : splitPath + }; + }); +} + +async function page({ params }) { + const { slug } = await params; + let markdownData = ""; + try { + markdownData = await fs.readFile( + `${process.cwd()}/docs/${slug ? slug.join("/") : ""}.md` + ); + // eslint-disable-next-line no-unused-vars + } catch (err) { + try { + markdownData = await fs.readFile( + `${process.cwd()}/docs/${slug ? slug.join("/") : ""}/index.md` + ); + } catch (err) { + notFound(); + return; + } + } + markdownData = markdownData.toString(); + return ( +
+ {markdownData} +
+ ); +} + +export default page; diff --git a/app/docs/layout.jsx b/app/docs/layout.jsx new file mode 100644 index 0000000..6fa87e2 --- /dev/null +++ b/app/docs/layout.jsx @@ -0,0 +1,17 @@ +import SidebarLinks from "@/components/SidebarLinks"; +import Header from "@/components/Header"; +import docLinks from "@/constants/docLinks"; + +export default function DocsLayout({ children }) { + return ( +
+
+
+ +
{children}
+
+
+ ); +} diff --git a/components/Header.jsx b/components/Header.jsx index 099169d..1308832 100644 --- a/components/Header.jsx +++ b/components/Header.jsx @@ -132,7 +132,7 @@ function Header({ docLinks }) { {navLink.label} @@ -168,7 +168,7 @@ function Header({ docLinks }) { {docLink.label} diff --git a/components/SidebarLinks.jsx b/components/SidebarLinks.jsx new file mode 100644 index 0000000..97e23fb --- /dev/null +++ b/components/SidebarLinks.jsx @@ -0,0 +1,35 @@ +"use client"; +import Logo from "@/components/Logo"; +import { headerLinks } from "@/constants"; +import Link from "next/link"; +import { usePathname } from "next/navigation"; +import { Menu, Moon, Sun, X } from "lucide-react"; +import { useTheme } from "next-themes"; +import { useEffect, useState } from "react"; +import PropTypes from "prop-types"; + +function Header({ links }) { + const pathname = usePathname(); + + return ( + + ); +} + +Header.propTypes = { + links: PropTypes.arrayOf(PropTypes.object) +}; + +export default Header; diff --git a/constants/docLinks.js b/constants/docLinks.js new file mode 100644 index 0000000..903839a --- /dev/null +++ b/constants/docLinks.js @@ -0,0 +1,7 @@ +export default [ + { + href: "/docs", + target: "_self", + label: "Welcome to MERNMail documentation!" + } +]; diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..c550ff3 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,3 @@ +# Welcome to MERNMail documentation! + +The documentation is work in progress... \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e0d0029..0e4efe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,13 +9,16 @@ "version": "0.1.0", "dependencies": { "@tailwindcss/typography": "^0.5.15", + "globby": "^14.0.2", "lucide-react": "^0.454.0", "next": "^15.0.2", "next-themes": "^0.4.3", + "prismjs": "^1.29.0", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-markdown": "^9.0.1" + "react-markdown": "^9.0.1", + "rehype-prism": "^2.3.3" }, "devDependencies": { "@commitlint/cli": "^19.5.0", @@ -1515,6 +1518,17 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@swc/cli": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.5.0.tgz", @@ -2769,6 +2783,11 @@ "readable-stream": "^3.4.0" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3482,6 +3501,21 @@ "node": ">= 8" } }, + "node_modules/css-selector-parser": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.0.5.tgz", + "integrity": "sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ] + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3899,6 +3933,17 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -5337,6 +5382,62 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/globby": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/globby/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -5466,6 +5567,54 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", + "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^8.0.0", + "property-information": "^6.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.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", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", @@ -5504,6 +5653,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", + "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -5604,7 +5769,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, "engines": { "node": ">= 4" } @@ -7951,6 +8115,17 @@ "node": ">=4" } }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8270,6 +8445,17 @@ "node": ">=0.10.0" } }, + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -8316,6 +8502,17 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/peek-readable": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz", @@ -8574,6 +8771,14 @@ "node": ">=6.0.0" } }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -8790,6 +8995,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-prism": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rehype-prism/-/rehype-prism-2.3.3.tgz", + "integrity": "sha512-J9mhio/CwcJRDyIhsp5hgXmyGeQsFN+/1eNEKnBRxfdJAx2CqH41kV0dqn/k2OgMdjk21IoGFgar0MfVtGYTSg==", + "dependencies": { + "hastscript": "^8.0.0", + "prismjs": "^1.29.0", + "rehype-parse": "^9.0.1", + "unist-util-is": "^6.0.0", + "unist-util-select": "^5.1.0", + "unist-util-visit": "^5.0.0" + }, + "peerDependencies": { + "unified": "^10 || ^11" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -10104,7 +10339,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", - "dev": true, "engines": { "node": ">=18" }, @@ -10165,6 +10399,22 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-5.1.0.tgz", + "integrity": "sha512-4A5mfokSHG/rNQ4g7gSbdEs+H586xyd24sdJqF1IWamqrLHvYb+DH48fzxowyOhOfK7YSqX+XlCojAyuuyyT2A==", + "dependencies": { + "@types/unist": "^3.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.1.0", + "nth-check": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/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", @@ -10270,6 +10520,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -10292,6 +10555,15 @@ "defaults": "^1.0.3" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index b03a915..1541b5f 100644 --- a/package.json +++ b/package.json @@ -13,13 +13,16 @@ }, "dependencies": { "@tailwindcss/typography": "^0.5.15", + "globby": "^14.0.2", "lucide-react": "^0.454.0", "next": "^15.0.2", "next-themes": "^0.4.3", + "prismjs": "^1.29.0", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-markdown": "^9.0.1" + "react-markdown": "^9.0.1", + "rehype-prism": "^2.3.3" }, "devDependencies": { "@commitlint/cli": "^19.5.0",