Skip to content

Commit

Permalink
types+don't show deprecated categories in navbar
Browse files Browse the repository at this point in the history
  • Loading branch information
3vorp committed Jun 22, 2024
1 parent dabfd5b commit f4354a2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 72 deletions.
78 changes: 78 additions & 0 deletions .vitepress/computeCategories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { readdirSync, readFileSync, statSync } from "fs";
import { sep } from "path";
import matter from "gray-matter";
import type { DocCategory, DocFile, DocFrontmatter } from "./types";

/**
* Convert a string to title case
* @author Evorp
* @param str - String to convert
* @returns String in title case
*/
export function toTitleCase(str: string) {
if (!str) return str;
return str
.split(/-|_| /g)
.map((word) => word[0].toUpperCase() + word.slice(1))
.join(" ");
}

/**
* Return an array of all filepaths in a directory
* @author Juknum, Evorp
* @param dir - Directory to search
* @param filelist - Used for recursion
* @returns Array of file paths
*/
export function walkSync(dir: string, filelist: string[] = []) {
// add trailing slash if not present
if (!dir.endsWith(sep)) dir += sep;
for (const file of readdirSync(dir)) {
if (statSync(dir + file).isDirectory())
// read directories inside directories recursively
filelist = walkSync(dir + file + sep, filelist);
else filelist.push(dir + file);
}
return filelist;
}

/**
* Read pages folder and map files to a sidebar and navbar compatible format
* @author Evorp
* @param dir - Directory to read
* @returns Array of category objects
*/
export default function computeCategories(dir: string) {
return walkSync(dir)
.filter((f) => f.endsWith(".md"))
.map((fileName) => {
const file = readFileSync(fileName, { encoding: "utf8" });
const name = fileName.replace(process.cwd(), "").replace(".md", "");
// parse yaml frontmatter into object
const frontmatter = matter(file).data as DocFrontmatter;
return {
text: frontmatter.title,
link: name,
// fall back to the parent folder
category: frontmatter.category || toTitleCase(name.split("/").at(-2) || ""),
date: frontmatter.date,
// default false
archived: frontmatter.archived ?? false,
deprecated: frontmatter.deprecated ?? false,
} as DocFile;
})
.reduce((acc, cur) => {
// because this isn't just an object with the names as keys we need to search
const found = acc.findIndex((v) => v.text === cur.category);
if (found === -1) acc.push({ text: cur.category, collapsed: false, items: [cur] });
else acc[found].items?.push(cur);
return acc;
}, [] as DocCategory[])
.map((category) => {
// collapse categories that are entirely archived/deprecated by default
if (category.items.every((i) => i.deprecated || i.archived))
return { ...category, collapsed: true };
return category;
})
.sort();
}
79 changes: 7 additions & 72 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
@@ -1,78 +1,13 @@
import { defineConfig } from "vitepress";
import { readdirSync, readFileSync, statSync } from "fs";
import { join, sep } from "path";
import matter from "gray-matter";
import { fileURLToPath } from "url";
import metaTags from "./meta";

function toTitleCase(str?: string) {
if (!str) return str;
return str
.split(/-|_| /g)
.map((word) => word[0].toUpperCase() + word.slice(1))
.join(" ");
}

/**
* Return an array of all filepaths in a directory
* @author Juknum, Evorp
* @param dir
* @param filelist recursion
* @returns array of file paths
*/
function walkSync(dir: string, filelist: string[] = []) {
// add trailing slash if not present
if (!dir.endsWith(sep)) dir += sep;
for (const file of readdirSync(dir)) {
if (statSync(dir + file).isDirectory())
// read directories inside directories recursively
filelist = walkSync(dir + file + sep, filelist);
else filelist.push(dir + file);
}
return filelist;
}

function computeBars() {
return walkSync(join(process.cwd(), "pages"))
.filter((f) => f.endsWith(".md"))
.map((fileName) => {
const file = readFileSync(fileName, { encoding: "utf8" });
const name = fileName.replace(process.cwd(), "").replace(".md", "");
// parse yaml frontmatter into object
const frontmatter = matter(file).data;
return {
frontmatter,
text: frontmatter.title,
link: name,
date: frontmatter.date,
archived: frontmatter.archived ?? false,
deprecated: frontmatter.deprecated ?? false,
};
})
.reduce((acc, cur) => {
const category = cur.frontmatter.category || toTitleCase(cur.link.split("/").at(-2));

// delete because unused
delete (cur as any).frontmatter;

// because this isn't just an object with the names as keys we need to search
const found = acc.findIndex((v) => v.text === category);
if (found === -1) acc.push({ text: category, collapsed: false, items: [cur] });
else acc[found].items?.push(cur);
return acc;
}, [] as any[])
.map((category) => {
// collapse categories that are entirely archived/deprecated by default
if (category.items.every((i: any) => i.deprecated || i.archived))
return { ...category, collapsed: true };
return category;
})
.sort();
}
import computeCategories from "./computeCategories";
import { join } from "path";

// https://vitepress.dev/reference/site-config
export default () => {
const bars = computeBars();
// DocCategory satisfies both navbar and sidebar interfaces
const categories = computeCategories(join(process.cwd(), "pages"));
return defineConfig({
title: "Faithful Docs",
description: "The official site with documentation and guides related to Faithful.",
Expand All @@ -86,15 +21,15 @@ export default () => {
},
],
],
// https://vitepress.dev/reference/default-theme-config
themeConfig: {
logo: "https://raw.githubusercontent.com/Faithful-Resource-Pack/Branding/main/site/favicon.ico",
nav: [
{ text: "Home", link: "/" },
...bars,
// don't put all archived/deprecated categories in navbar
...categories.filter((c) => !c.collapsed),
{ text: "Main Site", link: "https://faithfulpack.net" },
],
sidebar: bars,
sidebar: categories,
docFooter: {
prev: false,
next: false,
Expand Down
22 changes: 22 additions & 0 deletions .vitepress/types.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export interface DocMeta {
category?: string;
date: string;
archived?: boolean;
deprecated?: boolean;
}

export interface DocFrontmatter extends DocMeta {
title: string;
}

// at this point all optional fields are filled
export interface DocFile extends Required<DocMeta> {
text: string;
link: string;
}

export interface DocCategory {
text: string;
collapsed: boolean;
items: DocFile[];
}

0 comments on commit f4354a2

Please sign in to comment.