Skip to content

Commit 27eedd3

Browse files
authored
Provide entire docs in a single text file for LLMs. (#962)
* feat: script for generating llm files * feat: adding mdx files on generating llm * feat: adding llms to sidebar + redirects to latest * fix: format * fix: changing to RegExp and String Rescript Core types * feat: adding redirect for `next` version
1 parent d832f29 commit 27eedd3

15 files changed

+257
-3
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ lib/
2727

2828
src/**/*.mjs
2929
scripts/**/*.mjs
30+
31+
# Generated via generate-llms script
32+
public/llms/manual/**/llm*.txt
33+
public/llms/react/**/llm*.txt
34+
pages/docs/**/**/llms.mdx

data/sidebar_manual_v1100.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"Extra": [
7474
"newcomer-examples",
7575
"project-structure",
76-
"faq"
76+
"faq",
77+
"llms"
7778
]
7879
}

data/sidebar_manual_v1200.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"Extra": [
7373
"newcomer-examples",
7474
"project-structure",
75-
"faq"
75+
"faq",
76+
"llms"
7677
]
7778
}

data/sidebar_react_latest.json

+3
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@
3131
"beyond-jsx",
3232
"forwarding-refs",
3333
"extensions-of-props"
34+
],
35+
"Extra": [
36+
"llms"
3437
]
3538
}

data/sidebar_react_v0100.json

+3
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@
2626
"Guides": [
2727
"beyond-jsx",
2828
"forwarding-refs"
29+
],
30+
"Extra": [
31+
"llms"
2932
]
3033
}

data/sidebar_react_v0110.json

+3
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@
2727
"beyond-jsx",
2828
"forwarding-refs",
2929
"extensions-of-props"
30+
],
31+
"Extra": [
32+
"llms"
3033
]
3134
}

next.config.mjs

+10
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ const config = {
136136
destination: `/docs/manual/${process.env.VERSION_NEXT}/:slug*`,
137137
permanent: false,
138138
},
139+
{
140+
source: "/llms/manual/latest/:file*",
141+
destination: `/llms/manual/${process.env.VERSION_LATEST}/:file*`,
142+
permanent: false,
143+
},
144+
{
145+
source: "/llms/manual/next/:file*",
146+
destination: `/llms/manual/${process.env.VERSION_NEXT}/:file*`,
147+
permanent: false,
148+
},
139149
];
140150
},
141151
};

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@
6161
"build": "rescript && npm run update-index && next build",
6262
"test": "node scripts/test-examples.mjs && node scripts/test-hrefs.mjs",
6363
"reanalyze": "reanalyze -all-cmt .",
64-
"update-index": "node scripts/extract-indices.mjs && node scripts/extract-tocs.mjs && node scripts/extract-syntax.mjs && node scripts/generate_feed.mjs > public/blog/feed.xml"
64+
"update-index": "npm run generate-llms && node scripts/extract-indices.mjs && node scripts/extract-tocs.mjs && node scripts/extract-syntax.mjs && node scripts/generate_feed.mjs > public/blog/feed.xml",
65+
"generate-llms": "node scripts/generate_llms.mjs"
6566
},
6667
"devDependencies": {
6768
"@mdx-js/react": "^2.3.0",

public/_redirects

+3
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@
1111

1212
/docs/manual/latest/:slug* /docs/manual/v11.0.0/:slug* 307
1313
/docs/manual/next/:slug* /docs/manual/v12.0.0/:slug* 307
14+
15+
/llms/manual/latest/:file* /llms/manual/v11.0.0/:file* 307
16+
/llms/manual/next/:file* /llms/manual/v12.0.0/:file* 307

public/llms/manual/template.mdx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: "LLMs"
3+
description: "Documentation for LLMs"
4+
canonical: "/docs/manual/<VERSION>/llms"
5+
---
6+
7+
# Documentation for LLMs
8+
9+
We adhere to the [llms.txt convention](https://llmstxt.org/) to make documentation accessible to large language models and their applications.
10+
11+
Currently, we have the following files...
12+
13+
- [/docs/manual/llms.txt](/llms/manual/<VERSION>/llms.txt) — a list of the available files for ReScript language.
14+
- [/docs/manual/llm-full.txt](/llms/manual/<VERSION>/llm-full.txt) — complete documentation for ReScript language.
15+
- [/docs/manual/llm-small.txt](/llms/manual/<VERSION>/llm-small.txt) — compressed version of the former, without examples.
16+
17+
...and package-level documentation:
18+
19+
- [/docs/react/llms](/docs/react/latest/llms) — the LLms documentation for ReScript React.
20+
21+
## Notes
22+
23+
- The content is automatically generated from the same source as the official documentation for the specific version

public/llms/manual/template.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# ReScript Documentation for LLMs
2+
3+
> ReScript is a robustly typed language that compiles to efficient and human-readable JavaScript. It comes with a lightning fast compiler toolchain that scales to any codebase size.
4+
5+
## Documentation Sets
6+
7+
- [Complete documentation](https://rescript-lang.org/llms/manual/<VERSION>/llm-full.txt): The complete ReScript documentation including all examples and additional content
8+
- [Abridged documentation](https://rescript-lang.org/llms/manual/<VERSION>/llm-small.txt): A minimal version of the ReScript documentation, with the essential content for quick reference
9+
10+
## Individual Package Documentation
11+
12+
- [ReScript React documentation](https://rescript-lang.org/llms/react/latest/llms.txt): This is the developer documentation for ReScript React.
13+
14+
## Notes
15+
16+
- The abridged documentation excludes the detailed examples, and supplementary information
17+
- The complete documentation includes all content from the official documentation
18+
- Package-specific documentation files contain only the content relevant to that package
19+
- The content is automatically generated from the same source as the official documentation for the specific version

public/llms/react/template.mdx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
---
2+
title: "LLMs"
3+
description: "Documentation for LLMs"
4+
canonical: "/docs/react/<VERSION>/llms"
5+
---
6+
7+
# Documentation for LLMs
8+
9+
We adhere to the [llms.txt convention](https://llmstxt.org/) to make documentation accessible to large language models and their applications.
10+
11+
Currently, we have the following files...
12+
13+
- [/docs/react/llms.txt](/llms/react/<VERSION>/llms.txt) — a list of the available files for ReScript React.
14+
- [/docs/react/llms-full.txt](/llms/react/<VERSION>/llm-full.txt) — complete documentation for ReScript React.
15+
- [/docs/react/llms-small.txt](/llms/react/<VERSION>/llm-small.txt) — compressed version of the former, without examples for ReScript React.
16+
17+
...and the language documentation:
18+
19+
- [/docs/manual/llms](/docs/manual/latest/llms) — the LLms documentation for ReScript.
20+
21+
## Notes
22+
23+
- The content is automatically generated from the same source as the official documentation for the specific version

public/llms/react/template.txt

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# ReScript React Documentation for LLMs
2+
3+
> ReScript React is a strongly typed interface for React, designed to integrate seamlessly with modern React (>= v18.0) while compiling to idiomatic JavaScript, enabling robust and scalable React applications.
4+
5+
## ReScript React Documentation
6+
7+
- [Complete documentation](https://rescript-lang.org/llms/react/<VERSION>/llm-full.txt): The complete ReScript React documentation including all examples and additional content
8+
- [Abridged documentation](https://rescript-lang.org/llms/react/<VERSION>/llm-small.txt): A minimal version of the ReScript React documentation, with the essential content for quick reference
9+
10+
## Language Documentation
11+
12+
- [ReScript documentation](https://rescript-lang.org/llms/manual/latest/llms.txt): This is the developer documentation for ReScript.
13+
14+
## Notes
15+
16+
- The abridged documentation excludes the detailed examples, and supplementary information
17+
- The complete documentation includes all content from the official documentation
18+
- Package-specific documentation files contain only the content relevant to that package
19+
- The content is automatically generated from the same source as the official documentation for the specific version

scripts/generate_llms.res

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
let readMarkdownFile = (filePath: string): string => {
2+
let fileContent = Node.Fs.readFileSync2(filePath, "utf8")
3+
fileContent
4+
}
5+
6+
let rec collectFiles = (dirPath: string): array<string> => {
7+
let entries = Node.Fs.readdirSync(dirPath)
8+
entries->Array.reduce([], (acc, entry) => {
9+
let fullPath = Node.Path.join([dirPath, entry])
10+
let stats = Node.Fs.statSync(fullPath)
11+
switch stats["isDirectory"]() {
12+
| true => acc->Array.concat(collectFiles(fullPath))
13+
| false => {
14+
acc->Array.push(fullPath)
15+
acc
16+
}
17+
}
18+
})
19+
}
20+
21+
let clearFile = (filePath: string): unit => {
22+
Node.Fs.writeFileSync(filePath, "")
23+
}
24+
25+
let createDirectoryIfNotExists = (dirPath: string): unit => {
26+
if !Node.Fs.existsSync(dirPath) {
27+
Node.Fs.mkdirSync(dirPath)
28+
}
29+
}
30+
31+
let removeCodeTabTags = (content: string): string => {
32+
let regex = RegExp.fromStringWithFlags("<CodeTab.*?>[\\s\\S]*?</CodeTab>", ~flags="g")
33+
String.replaceRegExp(content, regex, "")
34+
}
35+
36+
let removeCodeBlocks = (content: string): string => {
37+
let regex = RegExp.fromStringWithFlags("```[a-zA-Z]+\\s*[\\s\\S]*?```", ~flags="g")
38+
String.replaceRegExp(content, regex, "")
39+
}
40+
41+
let removeFileTitle = (content: string): string => {
42+
let regex = RegExp.fromStringWithFlags("---\ntitle[\\s\\S]*?---", ~flags="g")
43+
String.replaceRegExp(content, regex, "")
44+
}
45+
46+
let removeUnnecessaryBreaks = (content: string): string => {
47+
let regex = RegExp.fromStringWithFlags("^\n{2,}", ~flags="g")
48+
String.replaceRegExp(content, regex, "")
49+
}
50+
51+
let removeToDos = (content: string): string => {
52+
let regex = RegExp.fromStringWithFlags("<!-- TODO[\\s\\S]*?-->", ~flags="g")
53+
String.replaceRegExp(content, regex, "")
54+
}
55+
56+
let fillContentWithVersion = (content: string, version: string): string => {
57+
let regex = RegExp.fromStringWithFlags("<VERSION>", ~flags="g")
58+
String.replaceRegExp(content, regex, version)
59+
}
60+
61+
let createFullFile = (content: string, filePath: string): unit => {
62+
Node.Fs.appendFileSync(filePath, content ++ "\n", "utf8")
63+
}
64+
65+
let createSmallFile = (content: string, filePath: string): unit => {
66+
let smallContent =
67+
content
68+
->removeCodeTabTags
69+
->removeFileTitle
70+
->removeToDos
71+
->removeCodeBlocks
72+
->removeUnnecessaryBreaks
73+
Node.Fs.appendFileSync(filePath, smallContent, "utf8")
74+
}
75+
76+
let createLlmsFiles = (version: string, docsDirectory: string, llmsDirectory: string): unit => {
77+
let mdxFileTemplatePath = llmsDirectory->Node.Path.join2("template.mdx")
78+
let mdxFilePath = docsDirectory->Node.Path.join2(version)->Node.Path.join2("llms.mdx")
79+
let txtFileTemplatePath = llmsDirectory->Node.Path.join2("template.txt")
80+
let txtFilePath = llmsDirectory->Node.Path.join2(version)->Node.Path.join2("llms.txt")
81+
82+
Node.Fs.writeFileSync(
83+
mdxFilePath,
84+
readMarkdownFile(mdxFileTemplatePath)->fillContentWithVersion(version),
85+
)
86+
87+
Node.Fs.writeFileSync(
88+
txtFilePath,
89+
readMarkdownFile(txtFileTemplatePath)->fillContentWithVersion(version),
90+
)
91+
}
92+
93+
let processVersions = (
94+
versions: array<string>,
95+
docsDirectory: string,
96+
llmsDirectory: string,
97+
): unit => {
98+
let fullFileName = "llm-full.txt"
99+
let smallFileName = "llm-small.txt"
100+
101+
versions->Array.forEach(version => {
102+
let versionDir = docsDirectory->Node.Path.join2(version)
103+
let llmsDir = llmsDirectory->Node.Path.join2(version)
104+
let fullFilePath = llmsDir->Node.Path.join2(fullFileName)
105+
let smallFilePath = llmsDir->Node.Path.join2(smallFileName)
106+
107+
createDirectoryIfNotExists(llmsDir)
108+
clearFile(fullFilePath)
109+
clearFile(smallFilePath)
110+
111+
createLlmsFiles(version, docsDirectory, llmsDirectory)
112+
113+
versionDir
114+
->collectFiles
115+
->Array.forEach(filePath => {
116+
if String.endsWith(filePath, ".mdx") {
117+
let content = readMarkdownFile(filePath)
118+
119+
content->createFullFile(fullFilePath)
120+
121+
content->createSmallFile(smallFilePath)
122+
}
123+
})
124+
})
125+
}
126+
127+
let manualVersions = ["v12.0.0", "v11.0.0"]
128+
let reactManualVersions = ["latest", "v0.10.0", "v0.11.0"]
129+
130+
let manualDocsDirectory = "pages/docs/manual"
131+
let reactDocsDirectory = "pages/docs/react"
132+
133+
let manualLlmsDirectory = "public/llms/manual"
134+
let reactLlmsDirectory = "public/llms/react"
135+
136+
processVersions(manualVersions, manualDocsDirectory, manualLlmsDirectory)
137+
processVersions(reactManualVersions, reactDocsDirectory, reactLlmsDirectory)

src/bindings/Node.res

+3
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ module Process = {
2020

2121
module Fs = {
2222
@module("fs") external readFileSync: string => string = "readFileSync"
23+
@module("fs") external readFileSync2: (string, string) => string = "readFileSync"
2324
@module("fs") external readdirSync: string => array<string> = "readdirSync"
2425
@module("fs") external writeFileSync: (string, string) => unit = "writeFileSync"
26+
@module("fs") external appendFileSync: (string, string, string) => unit = "appendFileSync"
2527
@module("fs") external existsSync: string => bool = "existsSync"
2628
@module("fs") external mkdirSync: string => unit = "mkdirSync"
29+
@module("fs") external statSync: string => {.."isDirectory": unit => bool} = "statSync"
2730
}
2831

2932
module Buffer = {

0 commit comments

Comments
 (0)