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 (
+
+ );
+}
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 (
+
+ {links.map((link) => (
+ -
+
+ {link.label}
+
+
+ ))}
+
+ );
+}
+
+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",