Skip to content
This repository has been archived by the owner on Jan 8, 2025. It is now read-only.

Commit

Permalink
Progress
Browse files Browse the repository at this point in the history
  • Loading branch information
ptgott committed Jul 8, 2024
1 parent 97258d9 commit af24806
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 80 deletions.
36 changes: 27 additions & 9 deletions server/remark-toc.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as nodeFS from "fs";
import * as path from "path";
import "process";
import matter from "gray-matter";
import { visitParents } from "unist-util-visit-parents";
import { fromMarkdown } from "mdast-util-from-markdown";
Expand Down Expand Up @@ -27,8 +28,9 @@ export const getTOC = (dirPath: string, fs = nodeFS) => {
const parts = path.parse(dirPath);
const tocIntro = path.join(parts.dir, parts.name, parts.name + ".mdx");
if (!fs.existsSync(tocIntro)) {
console.log("bad stuff!");
throw `There must be a page called ${tocIntro} to introduce ${dirPath}".`;
return {
error: `There must be a page called ${tocIntro} to introduce ${dirPath}".`,
};
}

const files = fs.readdirSync(dirPath, "utf8");
Expand Down Expand Up @@ -68,9 +70,9 @@ export const getTOC = (dirPath: string, fs = nodeFS) => {
dirs.forEach((f, idx) => {
const menuPath = path.join(f, path.parse(f).base + ".mdx");
if (!fs.existsSync(menuPath)) {
throw new Error(
`there must be a page called ${menuPath} that introduces ${f}`
);
return {
error: `there must be a page called ${menuPath} that introduces ${f}`,
};
}
const text = fs.readFileSync(menuPath, "utf8");
let relPath = relativePathToFile(dirPath, menuPath);
Expand All @@ -81,13 +83,26 @@ export const getTOC = (dirPath: string, fs = nodeFS) => {
);
});
entries.sort();
return entries.join("\n");
return { result: entries.join("\n") };
};

const tocRegexpPattern = "^\\(!toc ([^!]+)!\\)$";

export default function remarkTOC(): Transformer {
export interface RemarkTOCOptions {
rootDir?: string | ((vfile: VFile) => string);
}

export default function remarkTOC({
rootDir = "",
}: RemarkTOCOptions): Transformer {
return (root: Content, vfile: VFile) => {
let resolvedRootDir: string;
if (typeof rootDir === "function") {
resolvedRootDir = rootDir(vfile);
} else {
resolvedRootDir = rootDir;
}

const lastErrorIndex = vfile.messages.length;

visitParents(root, (node, ancestors: Parent[]) => {
Expand All @@ -108,8 +123,11 @@ export default function remarkTOC(): Transformer {
return;
}

// TODO: Don't throw errors. Add messages instead.
const result = getTOC(tocExpr[1]);
const { result, error } = getTOC(path.join(resolvedRootDir, tocExpr[1]));
if (!!error) {
vfile.message(error, node);
return;
}
const tree = fromMarkdown(result, {
extensions: [mdxjs(), gfm(), frontmatter()],
mdastExtensions: [
Expand Down
138 changes: 67 additions & 71 deletions uvu-tests/remark-toc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,6 @@ import { remark } from "remark";

const Suite = suite("server/remark-toc");

const transformer = (vfileOptions: VFileOptions) => {
const file = new VFile(vfileOptions);

return remark()
.use(remarkMdx)
.use(remarkGFM)
.use(remarkTOC)
.processSync(file);
};

Suite("replaces inclusion expressions", () => {
console.log("blah");
const value = readFileSync(
resolve("server/fixtures/toc/source.mdx"),
"utf-8"
);

console.log("value:", value);

const result = transformer({
value,
path: "/content/4.0/docs/pages/filename.mdx",
}).toString();

console.log("result:", result);

const expected = readFileSync(
resolve("server/fixtures/toc/expected.mdx"),
"utf-8"
);

console.log(result);
assert.equal(result, expected);
});

const testFilesTwoSections = {
"/docs/docs.mdx": `---
title: "Documentation Home"
Expand Down Expand Up @@ -118,7 +83,7 @@ description: "Protecting App 2 with Teleport"
});
const fs = createFsFromVolume(vol);
const actual = getTOC("/docs/", fs);
assert.equal(actual, expected);
assert.equal(actual.result, expected);
});

Suite("getTOC with multiple links to directories", () => {
Expand All @@ -128,43 +93,42 @@ Suite("getTOC with multiple links to directories", () => {
const vol = Volume.fromJSON(testFilesTwoSections);
const fs = createFsFromVolume(vol);
const actual = getTOC("/docs/", fs);
assert.equal(actual, expected);
assert.equal(actual.result, expected);
});

// Suite(
// `getTOC throws an error on a generated menu page that does not correspond to a subdirectory`,
// () => {
// const vol = Volume.fromJSON({
// "/docs/docs.mdx": `---
// title: "Documentation Home"
// description: "Guides to setting up the product."
// ---
//
// `,
// "/docs/application-access/application-access.mdx": `---
// title: "Application Access"
// description: "Guides related to Application Access"
// ---
//
// `,
// "/docs/application-access/page1.mdx": `---
// title: "Application Access Page 1"
// description: "Protecting App 1 with Teleport"
// ---`,
// "/docs/jwt.mdx": `---
// title: "JWT guides"
// description: "Guides related to JWTs"
// ---
//
// `,
// });
//
// const fs = createFsFromVolume(vol);
// assert.throws(() => {
// const actual = getTOC("/docs/", fs);
// }, "jwt.mdx");
// }
// );
Suite(
`getTOC returns an error on a generated menu page that does not correspond to a subdirectory`,
() => {
const vol = Volume.fromJSON({
"/docs/docs.mdx": `---
title: "Documentation Home"
description: "Guides to setting up the product."
---
`,
"/docs/application-access/application-access.mdx": `---
title: "Application Access"
description: "Guides related to Application Access"
---
`,
"/docs/application-access/page1.mdx": `---
title: "Application Access Page 1"
description: "Protecting App 1 with Teleport"
---`,
"/docs/jwt.mdx": `---
title: "JWT guides"
description: "Guides related to JWTs"
---
`,
});

const fs = createFsFromVolume(vol);
const actual = getTOC("/docs/", fs);
assert.equal(actual.error, "");
}
);

Suite("getTOC orders sections correctly", () => {
const expected = `- [API Usage](api.mdx): Using the API.
Expand Down Expand Up @@ -219,6 +183,38 @@ description: "Using the API."
});
const fs = createFsFromVolume(vol);
const actual = getTOC("/docs/", fs);
assert.equal(actual.result, expected);
});

const transformer = (vfileOptions: VFileOptions) => {
const file = new VFile(vfileOptions);

return remark()
.use(remarkMdx)
.use(remarkGFM)
.use(remarkTOC, { rootDir: "server/fixtures/toc" })
.processSync(file);
};

Suite("replaces inclusion expressions", () => {
const value = readFileSync(
resolve("server/fixtures/toc/source.mdx"),
"utf-8"
);

const result = transformer({
value,
path: "/content/4.0/docs/pages/filename.mdx",
});

const actual = result.toString();

const expected = readFileSync(
resolve("server/fixtures/toc/expected.mdx"),
"utf-8"
);

assert.equal(result.messages, []);
assert.equal(actual, expected);
});

Expand Down

0 comments on commit af24806

Please sign in to comment.