actually generate doc index for real this time

This commit is contained in:
MapleLeaf
2021-12-30 14:07:00 -06:00
parent a4bd7736d5
commit 4c5164518f
12 changed files with 158 additions and 153 deletions

View File

@@ -0,0 +1,39 @@
import glob from "fast-glob"
import matter from "gray-matter"
import { readFile } from "node:fs/promises"
import { join, parse, posix } from "node:path"
export type ContentIndexEntry = {
title: string
route: string
order: number
}
export async function createContentIndex(
contentFolderPath: string,
): Promise<ContentIndexEntry[]> {
const contentFiles = await glob(["**/*.mdx", "**/*.md"], {
cwd: contentFolderPath,
absolute: true,
})
const entries = await Promise.all(contentFiles.map(getIndexInfo))
return entries.sort((a, b) => a.order - b.order)
}
async function getIndexInfo(filePath: string): Promise<ContentIndexEntry> {
const { dir, name } = parse(filePath)
const route = "/" + posix.relative("app/routes", join(dir, name))
const { data } = matter(await readFile(filePath, "utf8"))
const title = String(data.meta?.title ?? "")
let order = Number(data.order)
if (!Number.isFinite(order)) {
order = Number.POSITIVE_INFINITY
}
return { title, route, order }
}

View File

@@ -1,62 +0,0 @@
import { readFile } from "node:fs/promises"
import remarkFrontmatter from "remark-frontmatter"
import remarkParse from "remark-parse"
import type { LoaderFunction } from "remix"
import { Link, Outlet } from "remix"
import { unified } from "unified"
import { SideNav } from "~/components/side-nav"
import { SidebarLayout } from "~/components/sidebar-layout"
import { linkClass } from "~/styles"
export const loader: LoaderFunction = async () => {
const glob = await import("fast-glob")
const contentFiles = await glob.default(["**/*.mdx", "**/*.md"], {
cwd: "content",
absolute: true,
})
const contentModules = await Promise.all(
contentFiles.map(async (filePath) => {
const content = await readFile(filePath, "utf8")
const result = await unified()
.use(remarkParse)
.use(remarkFrontmatter)
.process(content)
return { filePath, result: result.toString() }
}),
)
console.log(contentModules)
return {}
}
export default function Docs() {
return (
<SidebarLayout
sidebar={
<SideNav heading="Guides">
<Link className={linkClass} to="getting-started">
Getting Started
</Link>
<Link className={linkClass} to="embeds">
Embeds
</Link>
<Link className={linkClass} to="buttons">
Buttons
</Link>
<Link className={linkClass} to="select-menus">
Select Menus
</Link>
</SideNav>
}
body={
<section className="prose max-w-none prose-invert prose-h1:font-light flex-1 prose-h1:mb-4 prose-p:my-4 prose-pre:text-[15px] prose-pre:font-monospace prose-h2:font-light h-[200vh]">
<Outlet />
</section>
}
/>
)
}

View File

@@ -48,34 +48,7 @@ export default function App() {
<Links />
</head>
<body>
<HeaderLayout
header={
<nav className="flex justify-between items-center">
<Link to="/">
<h1 className="text-3xl font-light">
reacord{" "}
<CodeIcon className="inline w-8 align-sub opacity-50" />
</h1>
</Link>
<div className="flex gap-4">
<Link className={linkClass} to="/docs/getting-started">
<DocumentTextIcon className="inline align-sub w-5" /> Guides
</Link>
<Link className={linkClass} to="/api">
<DatabaseIcon className="inline align-sub w-5" /> API
Reference
</Link>
<ExternalLink
className={linkClass}
href="https://github.com/itsMapleLeaf/reacord"
>
<ExternalLinkIcon className="inline align-sub w-5" /> GitHub
</ExternalLink>
</div>
</nav>
}
body={<Outlet />}
/>
<HeaderLayout header={<HeaderNav />} body={<Outlet />} />
<ScrollRestoration />
<Scripts />
{process.env.NODE_ENV === "development" && <LiveReload />}
@@ -83,3 +56,29 @@ export default function App() {
</html>
)
}
function HeaderNav() {
return (
<nav className="flex justify-between items-center">
<Link to="/">
<h1 className="text-3xl font-light">
reacord <CodeIcon className="inline w-8 align-sub opacity-50" />
</h1>
</Link>
<div className="flex gap-4">
<Link className={linkClass} to="/docs/guides/getting-started">
<DocumentTextIcon className="inline align-sub w-5" /> Guides
</Link>
<Link className={linkClass} to="/docs/api">
<DatabaseIcon className="inline align-sub w-5" /> API Reference
</Link>
<ExternalLink
className={linkClass}
href="https://github.com/itsMapleLeaf/reacord"
>
<ExternalLinkIcon className="inline align-sub w-5" /> GitHub
</ExternalLink>
</div>
</nav>
)
}

View File

@@ -0,0 +1,36 @@
import type { LoaderFunction } from "remix"
import { Link, Outlet, useLoaderData } from "remix"
import { SideNav } from "~/components/side-nav"
import { SidebarLayout } from "~/components/sidebar-layout"
import type { ContentIndexEntry } from "~/create-index.server"
import { createContentIndex } from "~/create-index.server"
import { linkClass } from "~/styles"
type LoaderData = ContentIndexEntry[]
export const loader: LoaderFunction = async () => {
const data: LoaderData = await createContentIndex("app/routes/docs/guides")
return data
}
export default function Docs() {
const data: LoaderData = useLoaderData()
return (
<SidebarLayout
sidebar={
<SideNav heading="Guides">
{data.map(({ title, route }) => (
<Link className={linkClass} key={route} to={route}>
{title}
</Link>
))}
</SideNav>
}
body={
<section className="prose max-w-none prose-invert prose-h1:font-light flex-1 prose-h1:mb-4 prose-p:my-4 prose-pre:text-[15px] prose-pre:font-monospace prose-h2:font-light h-[200vh]">
<Outlet />
</section>
}
/>
)
}

View File

@@ -1,4 +1,5 @@
---
order: 0
meta:
title: Getting Started
description: Learn how to get started with Reacord.

View File

@@ -1,17 +1,10 @@
import type { LoaderFunction } from "remix"
import { useLoaderData } from "remix"
import type { DocsJson } from "~/docs.server"
import { loadDocs } from "~/docs.server"
export const loader: LoaderFunction = () => loadDocs()
export default function Index() {
const data: DocsJson = useLoaderData()
return (
<main>
<pre className="w-full overflow-x-auto">
{JSON.stringify(data, undefined, 2)}
</pre>
<h1>Reacord</h1>
<pre>code snippet here</pre>
<p>Create interactive Discord messages using React and JSX.</p>
<button>Get Started</button>
</main>
)
}

View File

@@ -17,6 +17,7 @@
"@tailwindcss/typography": "^0.5.0",
"autoprefixer": "^10.4.1",
"clsx": "^1.1.1",
"gray-matter": "^4.0.3",
"postcss": "^8.4.5",
"react": "^17.0.2",
"react-dom": "^17.0.2",

View File

@@ -1,45 +0,0 @@
/* eslint-disable unicorn/prefer-module */
const glob = require("fast-glob")
const { join, relative, normalize, parse } = require("path/posix")
/**
* @type {import('@remix-run/dev/config').AppConfig}
*/
module.exports = {
appDirectory: "app",
assetsBuildDirectory: "public/build",
publicPath: "/build/",
serverBuildDirectory: "build",
devServerPort: 8002,
ignoredRouteFiles: [".*"],
serverModuleFormat: "esm",
routes: async (defineRoutes) => {
const contentFolder = join(__dirname, "content")
const contentFiles = await glob("**/*.{md,mdx}", {
cwd: contentFolder,
absolute: true,
})
return defineRoutes((route) => {
route("docs", "docs.tsx", () => {
for (const filePath of contentFiles) {
const localFilePath = relative(contentFolder, filePath)
const { dir, name } = parse(localFilePath)
const routePath = join(dir, name)
route(routePath, filePath, { index: true })
}
})
})
},
mdx: async (filename) => {
const highlight = await import("rehype-prism-plus").then(
(mod) => mod.default,
)
return {
rehypePlugins: [highlight],
}
},
}

View File

@@ -0,0 +1,24 @@
/* eslint-disable unicorn/prefer-module */
const glob = require("fast-glob")
const { join, relative, normalize, parse } = require("path/posix")
/**
* @type {import('@remix-run/dev/config').AppConfig}
*/
module.exports = {
appDirectory: "app",
assetsBuildDirectory: "public/build",
publicPath: "/build/",
serverBuildDirectory: "build",
devServerPort: 8002,
ignoredRouteFiles: [".*"],
mdx: async (filename) => {
const highlight = await import("rehype-prism-plus").then(
(mod) => mod.default,
)
return {
rehypePlugins: [highlight],
}
},
}

32
pnpm-lock.yaml generated
View File

@@ -48,6 +48,7 @@ importers:
clsx: ^1.1.1
concurrently: ^6.5.1
fast-glob: ^3.2.7
gray-matter: ^4.0.3
postcss: ^8.4.5
prettier: ^2.5.1
react: ^17.0.2
@@ -72,6 +73,7 @@ importers:
'@tailwindcss/typography': 0.5.0_tailwindcss@3.0.8
autoprefixer: 10.4.1_postcss@8.4.5
clsx: 1.1.1
gray-matter: 4.0.3
postcss: 8.4.5
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
@@ -1603,7 +1605,6 @@ packages:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
dependencies:
sprintf-js: 1.0.3
dev: true
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -3784,7 +3785,6 @@ packages:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: true
/esquery/1.4.0:
resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
@@ -3986,7 +3986,6 @@ packages:
engines: {node: '>=0.10.0'}
dependencies:
is-extendable: 0.1.1
dev: true
/extend-shallow/3.0.2:
resolution: {integrity: sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=}
@@ -4423,6 +4422,16 @@ packages:
/graceful-fs/4.2.8:
resolution: {integrity: sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==}
/gray-matter/4.0.3:
resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
engines: {node: '>=6.0'}
dependencies:
js-yaml: 3.14.1
kind-of: 6.0.3
section-matter: 1.0.0
strip-bom-string: 1.0.0
dev: false
/hard-rejection/2.1.0:
resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
engines: {node: '>=6'}
@@ -4923,7 +4932,6 @@ packages:
/is-extendable/0.1.1:
resolution: {integrity: sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=}
engines: {node: '>=0.10.0'}
dev: true
/is-extendable/1.0.1:
resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
@@ -5748,7 +5756,6 @@ packages:
dependencies:
argparse: 1.0.10
esprima: 4.0.1
dev: true
/js-yaml/4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
@@ -5901,7 +5908,6 @@ packages:
/kind-of/6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
dev: true
/kleur/3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
@@ -7937,6 +7943,14 @@ packages:
object-assign: 4.1.1
dev: false
/section-matter/1.0.0:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}
dependencies:
extend-shallow: 2.0.1
kind-of: 6.0.3
dev: false
/semver-diff/3.1.1:
resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
engines: {node: '>=8'}
@@ -8174,7 +8188,6 @@ packages:
/sprintf-js/1.0.3:
resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
dev: true
/ssri/8.0.1:
resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
@@ -8276,6 +8289,11 @@ packages:
ansi-regex: 6.0.1
dev: true
/strip-bom-string/1.0.0:
resolution: {integrity: sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=}
engines: {node: '>=0.10.0'}
dev: false
/strip-bom/3.0.0:
resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=}
engines: {node: '>=4'}

View File

@@ -6,6 +6,7 @@
"exclude": [
"**/node_modules/**",
"**/coverage/**",
"**/build/**",
"**/dist/**",
"**/.cache/**",
"**/api/_build/**",