feat: add table of contents and strip fCC directive syntax
Node.js CI / CI (push) Failing after 17s
Security Scan and Upload / Security & DefectDojo Upload (push) Successful in 2m12s

This commit is contained in:
2026-04-17 13:52:40 -07:00
committed by Naomi Carrigan
parent 99b5cb6935
commit 330c4946b8
+43 -28
View File
@@ -4,13 +4,7 @@
* @author Naomi Carrigan * @author Naomi Carrigan
*/ */
import { import { readFile, writeFile, readdir, unlink } from "node:fs/promises";
readFile,
appendFile,
writeFile,
readdir,
unlink,
} from "node:fs/promises";
import { join } from "node:path"; import { join } from "node:path";
import { mdToPdf } from "md-to-pdf"; import { mdToPdf } from "md-to-pdf";
import order from "../data/order.json" assert { type: "json" }; import order from "../data/order.json" assert { type: "json" };
@@ -46,38 +40,59 @@ const sortFiles = (a: string, b: string): number => {
return aIndex - bIndex; return aIndex - bIndex;
}; };
interface FileEntry {
body: string;
title: string;
}
const slugify = (text: string): string => {
return text.
toLowerCase().
replaceAll(/[^\w\s-]/gu, "").
replaceAll(/\s+/gu, "-");
};
const processFile = async(file: string): Promise<FileEntry> => {
const content = await readFile(file, "utf8");
const titleMatch = /^title: (?<title>.*)/mu.exec(content);
const title = titleMatch?.groups?.title ?? "Unknown";
const body = content.
replace(/^---\n[\S\s]*?\n---\n/u, "").
trim().
replace(/^#+ --.*--/u, "").
trim().
replaceAll(/^:::.*$/gmu, "").
trim();
return { body, title };
};
const rollupFiles = async( const rollupFiles = async(
inputDirectory: string, inputDirectory: string,
outputFile: string, outputFile: string,
): Promise<void> => { ): Promise<void> => {
try { try {
console.log("Process started..."); console.log("Process started...");
await writeFile(outputFile, `${starterText}\n`);
console.log("Reading content directory..."); console.log("Reading content directory...");
const unsortedFiles = await readDirectoryRecursively(inputDirectory); const unsortedFiles = await readDirectoryRecursively(inputDirectory);
console.log(unsortedFiles);
const files = unsortedFiles.toSorted(sortFiles); const files = unsortedFiles.toSorted(sortFiles);
console.log("Files found, processing..."); console.log("Files found, processing...");
for (const file of files) { const mdFiles = files.filter((file) => {
if (file === ".gitkeep") { return file.endsWith(".md");
continue; });
} const entries = await Promise.all(
if (file.endsWith(".md")) { mdFiles.map(async(file) => {
const content = await readFile(file, "utf8"); return await processFile(file);
const strippedFrontmatter = content. }),
replace(/^---\n[\S\s]*?\n---\n/, "").
trim();
// Title is in front matter
const title = /^title: (?<title>.*)/m.exec(content)?.groups?.title;
const strippedFccHeadings = strippedFrontmatter.
replace(/^#+ --.*--/, "").
trim();
await appendFile(
outputFile,
`---\n\n# ${title ?? "Unknown"}\n${strippedFccHeadings}\n\n`,
); );
} const tocLines = entries.map(({ title }) => {
} return `- [${title}](#${slugify(title)})`;
});
const toc = `## Table of Contents\n\n${tocLines.join("\n")}\n\n---`;
const sections = entries.map(({ body, title }) => {
return `---\n\n# ${title}\n\n${body}\n\n`;
});
await writeFile(outputFile, `${starterText}\n${toc}\n\n${sections.join("")}`);
console.log(`Successfully rolled up files into ${outputFile}`); console.log(`Successfully rolled up files into ${outputFile}`);
} catch (error) { } catch (error) {
console.error("Error rolling up files:", error); console.error("Error rolling up files:", error);