diff --git a/apps/cli/sync.ts b/apps/cli/sync.ts index c617604..d062262 100755 --- a/apps/cli/sync.ts +++ b/apps/cli/sync.ts @@ -45,11 +45,14 @@ * segment — while the topic folder is a real segment * (`/tree-dfs/invert-binary-tree`), so a hand-written `index.mdx` in it is the * topic's landing page at `/tree-dfs` and Blume links the sidebar group row to - * it. Sync never writes or moves an `index.mdx`, and never removes a folder - * that still holds one. A phase folder's `meta.ts` is written once, when - * missing, then hand-owned (its title is yours to rename); a topic's is - * script-owned. An unplanned category group has no phase and sits at the - * content root. + * it. The topic's problem pages sit one level down in a `(problems)` group, + * `tree-dfs/(problems)/226_invert-binary-tree.mdx`: no route segment either, + * and Blume strips the `_` prefix from the route while sorting by it, so + * the URL is still `/tree-dfs/invert-binary-tree`. Sync never writes or moves + * an `index.mdx`, and never removes a folder that still holds one. A phase + * folder's `meta.ts` is written once, when missing, then hand-owned (its + * title is yours to rename); a topic's is script-owned. An unplanned category + * group has no phase and sits at the content root. * * Only the first-solve bucket is read: work/3 and work/7 hold blind re-solves * of problems whose page already exists (see work.ts), and a fresh scaffold @@ -337,8 +340,9 @@ function phaseMeta(phase: Phase): string { /** * Blume folder meta for a topic: exact label (the folder slug loses `/` and - * case), curriculum order, the sidebar icon, and `display: "group"` so the - * topic collapses under its phase heading. An unplanned category group + * case), curriculum order, the sidebar icon, and `display: "page"` so the + * topic is one row under its phase heading that drills into its own panel + * (the landing page, then its `(problems)` list). An unplanned category group * (warm-ups) has no README number and sorts at 0, ahead of phase 1, so the * sidebar opens on the basics. */ @@ -347,7 +351,7 @@ function groupMeta(topic: Topic): string { if (!icon) console.warn(`no icon for group ${JSON.stringify(topic.name)}: add it to TOPIC_ICONS`); const fields = [`title: ${JSON.stringify(topic.name)}`, `order: ${topic.order ?? 0}`]; if (icon) fields.push(`icon: ${JSON.stringify(icon)}`); - fields.push(`display: "group"`); + fields.push(`display: "page"`); return `import { defineMeta } from "blume";\n\nexport default defineMeta({ ${fields.join(", ")} });\n`; } @@ -706,16 +710,16 @@ const tags = new Map(); // every tag slug any problem page car for (const sol of ordered) { const langs = Object.keys(sol.code).sort().join("+"); const workRef = `${sol.num}.${sol.slug} (${langs})`; - // (0N-)// folder (the topic is a real route segment, so its - // index.mdx is the landing page) + leetcode-number prefix: numeric sidebar - // order, prefix stripped from the URL. + // (0N-)//(problems)/ folder (the topic is a real route segment, + // so its index.mdx is the landing page; `(problems)` adds none) + + // leetcode-number prefix: numeric sidebar order, prefix stripped from the URL. const topic = topics.get(sol.num) ?? topicByName.get(sol.category) ?? { name: sol.category }; const dir = topicDir(topic); groups.set(dir, topic); if (topic.phase) phases.set(phaseDir(topic.phase), topic.phase); - const name = `${dir}/${sol.num}-${sol.slug}.mdx`; + const name = `${dir}/(problems)/${sol.num}_${sol.slug}.mdx`; const existing = pages.get(sol.num); - await mkdir(join(DOCS, dir), { recursive: true }); + await mkdir(join(DOCS, dirname(name)), { recursive: true }); let written: string; // the page as it stands after this run, for its topics if (existing) {