Skip to content

Commit 54e4e8b

Browse files
authored
refactor: Nest pages in llms.txt to match sidebar sections (#1309)
1 parent 45909c3 commit 54e4e8b

File tree

2 files changed

+39
-17
lines changed

2 files changed

+39
-17
lines changed

plugins/generate-llms-txt.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import fsSync from 'fs';
33
import path from 'path';
44
import { fileURLToPath } from 'url';
55
import { parseFrontmatter, cleanReplComments } from '../src/lib/frontmatter.js';
6+
import { v10StructuredDocRoutes } from '../src/lib/route-utils.js';
67

78
const __filename = fileURLToPath(import.meta.url);
89
const __dirname = path.dirname(__filename);
@@ -42,29 +43,42 @@ Preact is a fast, lightweight alternative to React that provides the same modern
4243

4344
let content = header;
4445

45-
files.sort((a, b) => a.filename.localeCompare(b.filename));
46+
for (const section of v10StructuredDocRoutes) {
47+
content += `## ${section.name}\n\n`;
4648

47-
files.forEach(({ filename, content: fileContent }) => {
48-
const { description, body } = parseFrontmatter(fileContent, filename);
49-
let cleanedBody = cleanReplComments(body);
49+
for (const route of section.routes) {
50+
const { filename, content: fileContent } = files.find(
51+
file => file.filename === `${route.replace('/', '')}.md`
52+
);
5053

51-
// Remove <toc></toc> tags
52-
cleanedBody = cleanedBody.replace(/<toc><\/toc>/g, '');
54+
const { description, body } = parseFrontmatter(fileContent, filename);
55+
let cleanedBody = cleanReplComments(body);
5356

54-
// Clean up multiple consecutive newlines and empty lines around separators
55-
cleanedBody = cleanedBody.replace(/\n{3,}/g, '\n\n');
56-
cleanedBody = cleanedBody.replace(/---\s*\n\s*\n\s*---/g, '');
57+
// Remove <toc></toc> tags
58+
cleanedBody = cleanedBody.replace(/<toc><\/toc>/g, '');
5759

58-
// Fix heading hierarchy: convert # to ## for consistency
59-
cleanedBody = cleanedBody.replace(/^# /gm, '## ');
60+
// Clean up multiple consecutive newlines and empty lines around separators
61+
cleanedBody = cleanedBody.replace(/\n{3,}/g, '\n\n');
62+
cleanedBody = cleanedBody.replace(/---\s*\n\s*\n\s*---/g, '');
6063

61-
if (description) {
62-
content += `**Description:** ${description}\n\n`;
63-
}
64+
// Fix heading hierarchy: page headings should be 3 levels deep to accommodate
65+
// the llms document heading & the section headings for page/concept groups.
66+
cleanedBody = cleanedBody
67+
.replace(/^#### /gm, '###### ')
68+
.replace(/^### /gm, '##### ')
69+
.replace(/^## /gm, '#### ')
70+
// Not `/g` as there should only be one top-level heading per file
71+
// and this would conflict with bash comments that we have in a few places.
72+
.replace(/^# /m, '### ');
73+
74+
if (description) {
75+
content += `**Description:** ${description}\n\n`;
76+
}
6477

65-
content += `${cleanedBody}\n\n`;
66-
content += `------\n\n`;
67-
});
78+
content += `${cleanedBody}\n\n`;
79+
content += `------\n\n`;
80+
}
81+
}
6882

6983
return content;
7084
}

src/lib/route-utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ for (const k in config.docs) {
3535
docRoutes[k] = flattenRoutes(config.docs[k]);
3636
}
3737

38+
export const v10StructuredDocRoutes = [];
39+
for (const k of config.docs.v10) {
40+
v10StructuredDocRoutes.push({
41+
name: k.name.en,
42+
routes: k.routes.map(route => route.path)
43+
});
44+
}
45+
3846
export const blogRoutes = flattenRoutes(config.blog);
3947

4048
export const tutorialRoutes = flattenRoutes(config.tutorial);

0 commit comments

Comments
 (0)