mirror of
https://github.com/prdlk/leetcode.git
synced 2026-09-16 23:16:26 +00:00
feat(sync): organize solution docs by category and add sidebar labels
This commit is contained in:
+21
-9
@@ -10,7 +10,7 @@
|
||||
* renders as a <CodeGroup> (Python first); single-language solutions
|
||||
* render as a plain fence.
|
||||
*/
|
||||
import { readdir, rename } from "node:fs/promises";
|
||||
import { mkdir, rename } from "node:fs/promises";
|
||||
import { basename, join } from "node:path";
|
||||
|
||||
const ROOT = join(import.meta.dir, "..");
|
||||
@@ -284,6 +284,7 @@ function renderPage(sol: Solution, topic: string): string {
|
||||
`title: '${h.num}. ${h.title.replaceAll("'", "''")}'`,
|
||||
/[:#]/.test(description) ? `description: '${description.replaceAll("'", "''")}'` : `description: ${description}`,
|
||||
"sidebar:",
|
||||
` label: '${h.title.replaceAll("'", "''")}'`,
|
||||
` badge: '${h.difficulty}'`,
|
||||
"---",
|
||||
"",
|
||||
@@ -346,12 +347,20 @@ for await (const rel of new Bun.Glob("**/*.{js,py}").scan(WORK)) {
|
||||
|
||||
const topics = await readmeTopics();
|
||||
|
||||
/** Insert a number-free `sidebar.label` into existing frontmatter when missing. */
|
||||
function ensureLabel(page: string, h: Header): string {
|
||||
const fm = page.match(/^---\n[\s\S]*?\n---/);
|
||||
if (!fm || /^ {2}label: /m.test(fm[0])) return page;
|
||||
const label = ` label: '${h.title.replaceAll("'", "''")}'`;
|
||||
return page.replace(/^sidebar:$/m, `sidebar:\n${label}`);
|
||||
}
|
||||
|
||||
// Existing docs pages, keyed by leetcode number from the frontmatter title.
|
||||
const pages = new Map<number, string>(); // num -> filename
|
||||
for (const f of (await readdir(DOCS)).filter((f) => f.endsWith(".mdx")).sort()) {
|
||||
const text = await Bun.file(join(DOCS, f)).text();
|
||||
const pages = new Map<number, string>(); // num -> path relative to DOCS
|
||||
for (const rel of (await Array.fromAsync(new Bun.Glob("**/*.mdx").scan(DOCS))).sort()) {
|
||||
const text = await Bun.file(join(DOCS, rel)).text();
|
||||
const t = text.match(/^title: '(\d+)\./m);
|
||||
if (t) pages.set(Number(t[1]), f);
|
||||
if (t) pages.set(Number(t[1]), rel);
|
||||
}
|
||||
|
||||
const report: [string, string, string][] = [];
|
||||
@@ -360,8 +369,11 @@ const ordered = [...solutions.values()].sort((a, b) => a.num - b.num);
|
||||
for (const sol of ordered) {
|
||||
const langs = Object.keys(sol.code).sort().join("+");
|
||||
const workRef = `${sol.num}.${sol.slug} (${langs})`;
|
||||
const name = `${sol.num}-${sol.slug}.mdx`; // prefix = leetcode number (numeric sidebar order, stripped from the URL)
|
||||
// (category) group folder + leetcode-number prefix: numeric sidebar order, both stripped from the URL.
|
||||
const group = `(${sol.category.toLowerCase().replaceAll(" ", "-")})`;
|
||||
const name = `${group}/${sol.num}-${sol.slug}.mdx`;
|
||||
const existing = pages.get(sol.num);
|
||||
await mkdir(join(DOCS, group), { recursive: true });
|
||||
|
||||
if (existing) {
|
||||
const page = await Bun.file(join(DOCS, existing)).text();
|
||||
@@ -370,15 +382,15 @@ for (const sol of ordered) {
|
||||
report.push([workRef, existing, "ERROR: no '## Solution' heading"]);
|
||||
continue;
|
||||
}
|
||||
const next = page.slice(0, at) + solutionSection(sol);
|
||||
const next = ensureLabel(page.slice(0, at) + solutionSection(sol), sol.header);
|
||||
const actions: string[] = [];
|
||||
if (existing !== name) {
|
||||
await rename(join(DOCS, existing), join(DOCS, name));
|
||||
actions.push("renamed");
|
||||
actions.push("moved");
|
||||
}
|
||||
if (next !== page) {
|
||||
await Bun.write(join(DOCS, name), next);
|
||||
actions.push("updated (solution)");
|
||||
actions.push("updated");
|
||||
}
|
||||
report.push([workRef, name, actions.join(" + ") || "skipped (in sync)"]);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user