8000 docs: add llm support · coreui/coreui@0c35e97 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0c35e97

Browse files
committed
docs: add llm support
1 parent fcb4f8f commit 0c35e97

File tree

11 files changed

+308
-1
lines changed

11 files changed

+308
-1
lines changed

build/llm.mjs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env node
2+
3+
import fs from 'node:fs'
4+
import path from 'node:path'
5+
import { fileURLToPath } from 'node:url'
6+
import { globby } from 'globby'
7+
import { decode } from 'html-entities'
8+
9+
const __filename = fileURLToPath(import.meta.url)
10+
const __dirname = path.dirname(__filename)
11+
12+
const inputDir = path.resolve(__dirname, '../_gh_pages')
13+
14+
const mdFiles = await globby('**/llm.md', {
15+
cwd: inputDir,
16+
absolute: true
17+
})
18+
19+
function rewriteLinks(markdown) {
20+
let output = markdown
21+
22+
output = output.replace(/\[([^\]]+)\]\((\/[^)#]+)(\/)?(#.*?)?\)/g, '[$1]($2llm.md)')
23+
24+
output = output.replace(
25+
/<a href="(\/[^"#?]+)(\/)?(#.*?)?">/g,
26+
(_, path, __, hash = '') =>
27+
`<a href="${path}/llm.md${hash}">`
28+
)
29+
30+
return output.trim()
31+
}
32+
33+
function applyHeadingPrefix(content, componentName) {
34+
return content.replace(/^(#{1,6})\s+(.*)$/gm, (_, hashes, title) => {
35+
const normalized = title.trim()
36+
37+
if (normalized.startsWith(`Bootstrap 5 ${componentName}`)) {
38+
return `${hashes} ${normalized}`
39+
}
40+
41+
if (hashes === '#') {
42+
return `# Bootstrap 5 ${componentName} with CoreUI`
43+
}
44+
45+
return `${hashes} Bootstrap 5 ${componentName}${normalized}`
46+
})
47+
}
48+
49+
async function convertFile(filePath) {
50+
const raw = decode(fs.readFileSync(filePath, 'utf8'))
51+
52+
const frontMatterMatch = raw.match(/^---[\s\S]*?---/)
53+
const frontMatter = frontMatterMatch ? frontMatterMatch[0] : ''
54+
const content = raw.replace(frontMatter, '').trim()
55+
const h1Match = content.match(/^#\s+(.*)$/m)
56+
const componentName = h1Match ? h1Match[1].trim() : 'Component'
57+
const headingTransformed = applyHeadingPrefix(content, componentName)
58+
const rewritten = rewriteLinks(headingTransformed)
59+
const finalOutput = `${frontMatter}\n\n${rewritten}`
60+
61+
fs.writeFileSync(filePath, finalOutput, 'utf8')
62+
console.log(`✔ Updated: ${path.relative(process.cwd(), filePath)}`)
63+
}
64+
65+
async function generateIndex() {
66+
const allFiles = await globby('**/llm.md', {
67+
cwd: inputDir,
68+
absolute: false
69+
})
70+
71+
const sections = {}
72+
73+
for (const file of allFiles) {
74+
const parts = file.split(path.sep)
75+
const group = parts.length >= 2 ? parts[0] : 'other'
76+
const name =
77+
parts.length >= 2 ? parts[1] : parts[0].replace(/\/?llm\.md$/, '')
78+
const title = name
79+
.split('-')
80+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
81+
.join(' ')
82+
83+
if (!sections[group]) {
84+
sections[group] = []
85+
}
86+
87+
sections[group].push({
88+
title,
89+
path: `/${file}`
90+
})
91+
}
92+
93+
let indexContent = `---
94+
title: CoreUI LLM Docs Index
95+
description: Structured index of CoreUI documentation optimized for LLMs
96+
---
97+
98+
# 🤖 CoreUI LLM Documentation Index
99+
100+
This index lists all available CoreUI documentation files in a format optimized for large language models (LLMs).
101+
102+
CoreUI builds upon Bootstrap by providing production-ready components, advanced layout systems, enterprise-focused helpers, and integrated accessibility.
103+
104+
---
105+
106+
`
107+
108+
const groupOrder = ['components', 'forms', 'utilities', 'helpers']
109+
const sortedGroups = Object.keys(sections).sort((a, b) => {
110+
const ai = groupOrder.indexOf(a)
111+
const bi = groupOrder.indexOf(b)
112+
return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi)
113+
})
114+
115+
for (const group of sortedGroups) {
116+
indexContent += `## 📁 ${
117+
group.charAt(0).toUpperCase() + group.slice(1)
118+
}\n\n`
119+
for (const item of sections[group].sort((a, b) =>
120+
a.title.localeCompare(b.title)
121+
)) {
122+
indexContent += `- [${item.title}](${item.path})\n`
123+
}
124+
125+
indexContent += '\n'
126+
}
127+
128+
indexContent += `<!-- llm-note: This file is an authoritative index of the CoreUI documentation for AI models. It helps LLMs discover and reason about individual UI modules in an organized, reliable way. -->\n`
129+
130+
const indexPath = path.join(inputDir, 'llm-index.md')
131+
fs.writeFileSync(indexPath, indexContent.trim(), 'utf8')
132+
console.log(`📘 Generated index: llm-index.md`)
133+
}
134+
135+
async function generateSingleMergedFile() {
136+
const allowedDirs = new Set(['components', 'forms', 'layout', 'utilities', 'helpers'])
137+
138+
const allFiles = await globby(
139+
['**/llm.md', '!**/__*__/**', '!**/_*/**', '!**/*.test.*'],
140+
{
141+
cwd: inputDir,
142+
absolute: true
143+
}
144+
)
145+
146+
let mergedContent = `# 🧠 CoreUI LLM Knowledge Base\n\n`
147+
mergedContent += `This file contains all CoreUI documentation files in a format optimized for large language models (LLMs).\n\n`
148+
149+
for (const filePath of allFiles.sort()) {
150+
const relPath = path.relative(inputDir, filePath)
151+
const relativeDir = relPath.split(path.sep)[0]
152+
153+
if (!allowedDirs.has(relativeDir)) {
154+
continue
155+
}
156+
157+
const raw = fs.readFileSync(filePath, 'utf8')
158+
const content = raw.replace(/^---[\s\S]*?---/, '').trim()
159+
mergedContent += `${content}\n\n---\n\n`
160+
}
161+
162+
const outputPath = path.join(inputDir, 'coreui-llm.md')
163+
fs.writeFileSync(outputPath, mergedContent.trim(), 'utf8')
164+
console.log(`🧾 Generated full LLM dataset: coreui-llm.md`)
165+
}
166+
167+
console.time('🔁 Rewriting internal links in LLM .md files')
168+
await Promise.all(mdFiles.map(convertFile))
169+
console.timeEnd('🔁 Rewriting internal links in LLM .md files')
170+
await generateIndex()
171+
await generateSingleMergedFile()

docs/layouts/_default/docs.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ <h2 class="docs-title order-1 h1">{{ .Title | markdownify }}</h2>
1313
<h1 class="docs-title" id="content">{{ .Title | markdownify }}</h1>
1414
{{ end }}
1515
<p class="docs-lead">{{ .Page.Params.Description | markdownify }}</p>
16+
<p>🤖 Looking for the LLM-optimized version? <a href="./llm.md">View llm.md</a></p>
1617
{{ partial "ads" . }}
1718
{{ if .Page.Params.other_frameworks }}
1819
<h2>Other frameworks</h2>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# {{ .Title }}
2+
3+
{{ .Description }}
4+
{{ .RenderShortcodes | safeHTML }}

docs/layouts/shortcodes/bs-table.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
Usage: `bs-table "class class-foo"`, where class can be any string
33
*/ -}}
44

5+
{{- $format := (index (complement .Page.AlternativeOutputFormats .Page.OutputFormats) 0).Name -}}
6+
{{- if eq $format "markdown" -}}
7+
{{ .Inner }}
8+
{{- else -}}
59
{{- $css_class := .Get 0 | default "table" -}}
610
{{- $html_table := .Inner | markdownify -}}
711
{{- $html_table = replace $html_table "<table>" (printf `<div class="table-responsive"><table class="%s">` $css_class) -}}
812
{{- $html_table = replace $html_table "</table>" "</table></div>" -}}
913
{{- $html_table | safeHTML -}}
14+
{{- end -}}
15+

docs/layouts/shortcodes/callout.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44

55
{{- $css_class := .Get 0 | default "info" -}}
66

7+
{{- $format := (index (complement .Page.AlternativeOutputFormats .Page.OutputFormats) 0).Name -}}
8+
9+
{{- if eq $format "markdown" -}}
10+
{{ .Inner }}
11+
{{- else -}}
712
<div class="docs-callout docs-callout-{{ $css_class }}">
813
{{ .Inner | markdownify }}
914
</div>
15+
{{- end -}}

docs/layouts/shortcodes/example.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919
{{- $input := .Inner -}}
2020
{{- $content := .Inner -}}
2121

22+
{{- $format := (index (complement .Page.AlternativeOutputFormats .Page.OutputFormats) 0).Name -}}
23+
24+
{{- if eq $format "markdown" -}}
25+
26+
```{{ $lang }}
27+
{{- $input -}}
28+
```
29+
30+
{{- else -}}
31+
2232
<div class="docs-example-snippet docs-code-snippet">
2333
{{- if eq $show_preview true -}}
2434
<div{{ with $id }} id="{{ . }}"{{ end }} class="docs-example m-0 border-0{{ with $class }} {{ . }}{{ end }}">
@@ -52,3 +62,4 @@
5262
{{- highlight (trim $content "\n") $lang "" -}}
5363
{{- end -}}
5464
</div>
65+
{{- end -}}

docs/layouts/shortcodes/js-docs.html

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,36 @@
3232
{{- $match = replace $match $to_remove "" -}}
3333
{{- end -}}
3434

35+
{{- $format := (index (complement .Page.AlternativeOutputFormats .Page.OutputFormats) 0).Name -}}
36+
37+
{{- if eq $format "markdown" -}}
38+
39+
```js
40+
{{- $unindent := 0 -}}
41+
{{- $found := false -}}
42+
{{- $first_line:= index (split $match "\n") 0 -}}
43+
{{- range $char := split $first_line "" -}}
44+
{{- if and (eq $char " ") (not $found) -}}
45+
{{- $unindent = add $unindent 1 -}}
46+
{{- else -}}
47+
{{- $found = true -}}
48+
{{- end -}}
49+
{{- end -}}
50+
{{- $output := "" -}}
51+
{{- if (gt $unindent 0) -}}
52+
{{- $prefix := (strings.Repeat $unindent " ") -}}
53+
{{- range $line := split $match "\n" -}}
54+
{{- $line = strings.TrimPrefix $prefix $line -}}
55+
{{ $output = printf "%s%s\n" $output $line }}
56+
{{- end -}}
57+
{{- $output = chomp $output -}}
58+
{{- else -}}
59+
{{- $output = $match -}}
60+
{{- end -}}
61+
{{ "\n" }}{{ $output }}{{ "\n" }}```
62+
63+
{{- else -}}
64+
3565
<div class="docs-example-snippet docs-code-snippet docs-file-ref">
3666
<div class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom">
3767
<div class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small">
@@ -69,4 +99,5 @@
6999
{{- end -}}
70100
{{- highlight $output "js" "" -}}
71101
</div>
102+
{{- end -}}
72103
{{- end -}}

docs/layouts/shortcodes/scss-docs.html

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,36 @@
4545
{{- $match = replace $match " !default" "" -}}
4646
{{- end -}}
4747

48+
{{- $format := (index (complement .Page.AlternativeOutputFormats .Page.OutputFormats) 0).Name -}}
49+
50+
{{- if eq $format "markdown" -}}
51+
52+
```scss
53+
{{- $unindent := 0 -}}
54+
{{- $found := false -}}
55+
{{- $first_line:= index (split $match "\n") 0 -}}
56+
{{- range $char := split $first_line "" -}}
57+
{{- if and (eq $char " ") (not $found) -}}
58+
{{- $unindent = add $unindent 1 -}}
59+
{{- else -}}
60+
{{- $found = true -}}
61+
{{- end -}}
62+
{{- end -}}
63+
{{- $output := "" -}}
64+
{{- if (gt $unindent 0) -}}
65+
{{- $prefix := (strings.Repeat $unindent " ") -}}
66+
{{- range $line := split $match "\n" -}}
67+
{{- $line = strings.TrimPrefix $prefix $line -}}
68+
{{ $output = printf "%s%s\n" $output $line }}
69+
{{- end -}}
70+
{{- $output = chomp $output -}}
71+
{{- else -}}
72+
{{- $output = $match -}}
73+
{{- end -}}
74+
{{ "\n" }}{{ $output }}{{ "\n" }}```
75+
76+
{{- else -}}
77+
4878
<div class="docs-example-snippet docs-code-snippet docs-file-ref">
4979
<div class="d-flex align-items-center highlight-toolbar ps-3 pe-2 py-1 border-bottom">
5080
<div class="font-monospace link-secondary link-underline-secondary link-underline-opacity-0 link-underline-opacity-100-hover small">
@@ -82,4 +112,5 @@
82112
{{- end -}}
83113
{{- highlight $output "scss" "" -}}
84114
</div>
115+
{{- end -}}
85116
{{- end -}}

hugo.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@ title: "CoreUI"
33
baseURL: "https://coreui.io/docs/"
44
canonifyURLs: true
55

6+
outputs:
7+
page:
8+
- html
9+
- markdown
10+
11+
outputFormats:
12+
markdown:
13+
baseName: "llm"
14+
mediaType: "text/markdown"
15+
isPlainText: false
16+
notAlternative: false
17+
618
security:
719
enableInlineShortcodes: true
820
funcs:

package-lock.json

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
0