Skip to content

Commit e31af1d

Browse files
brabojclaude
andcommitted
feat: split playbook into individual recipe pages (#129)
Split the monolithic playbook chapter into 11 individual recipe pages under chapters/playbook/, each with its own URL for independent SEO ranking. Updated cross-references in glossary and appendix, and extended the remark link-rewriting plugin to handle subdirectory and sibling file links. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d3dc20f commit e31af1d

16 files changed

Lines changed: 509 additions & 424 deletions

astro-site/src/plugins/remark-rewrite-links.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,28 @@
11
import { visit } from "unist-util-visit";
22
import type { Root, Link } from "mdast";
33

4-
const CHAPTER_LINK = /^(\d{2}-)(.+)\.md(#.*)?$/;
4+
const CHAPTER_LINK = /^(?:\.\.\/)?(\d{2}-)(.+)\.md(#.*)?$/;
5+
const SUBDIR_FILE_LINK = /^([\w-]+)\/([\w-]+)\.md(#.*)?$/;
6+
const SIBLING_LINK = /^([a-z][\w-]*)\.md(#.*)?$/;
57

68
export function remarkRewriteLinks() {
79
return (tree: Root) => {
810
visit(tree, "link", (node: Link) => {
11+
// Links from top-level to subdir: playbook/index.md → ../playbook/
12+
// Links from top-level to subdir page: playbook/undoing-changes.md → ../playbook/undoing-changes/
13+
const subdirMatch = node.url.match(SUBDIR_FILE_LINK);
14+
if (subdirMatch) {
15+
const slug = subdirMatch[2] === "index" ? "" : `${subdirMatch[2]}/`;
16+
node.url = `../${subdirMatch[1]}/${slug}${subdirMatch[3] || ""}`;
17+
return;
18+
}
19+
// Links to sibling files in same directory: slug.md → slug/
20+
const siblingMatch = node.url.match(SIBLING_LINK);
21+
if (siblingMatch) {
22+
node.url = `${siblingMatch[1]}/${siblingMatch[2] || ""}`;
23+
return;
24+
}
25+
// Links to numbered chapters: NN-slug.md or ../NN-slug.md → ../slug/
926
const match = node.url.match(CHAPTER_LINK);
1027
if (match) {
1128
node.url = `../${match[2]}/${match[3] || ""}`;

0 commit comments

Comments
 (0)