Skip to content

Commit eec6170

Browse files
committed
Refactor api.data.ts: Add comments and improve code clarity (#3098)
1 parent 30e255f commit eec6170

File tree

1 file changed

+88
-58
lines changed

1 file changed

+88
-58
lines changed

src/api/api.data.ts

Lines changed: 88 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
// api.data.ts
2-
// a file ending with data.(j|t)s will be evaluated in Node.js
32
import fs from 'fs'
43
import path from 'path'
54
import type { MultiSidebarConfig } from '@vue/theme/src/vitepress/config.ts'
65
import { sidebar } from '../../.vitepress/config'
76

7+
// Interface, který definuje strukturu jednoho API nadpisu
88
interface APIHeader {
99
anchor: string
1010
text: string
1111
}
1212

13+
// Interface, kter definuje strukturu API skupiny s textem, odkazem a polem objektů
1314
export interface APIGroup {
1415
text: string
1516
anchor: string
@@ -20,79 +21,108 @@ export interface APIGroup {
2021
}[]
2122
}
2223

23-
// declare resolved data type
24+
// Deklarace typu pro vyhodnocené API skupiny
2425
export declare const data: APIGroup[]
2526

26-
export default {
27-
// declare files that should trigger HMR
28-
watch: './*.md',
29-
// read from fs and generate the data
30-
load(): APIGroup[] {
31-
return (sidebar as MultiSidebarConfig)['/api/'].map((group) => ({
32-
text: group.text,
33-
anchor: slugify(group.text),
34-
items: group.items.map((item) => ({
35-
...item,
36-
headers: parsePageHeaders(item.link)
37-
}))
38-
}))
39-
}
27+
// Utility funkce pro vygenerování "slug" odkazu z řetězce (používaná pro odkazy (#anchors) na stránce)
28+
function slugify(text: string): string {
29+
return (
30+
text
31+
// nahradit speciální znaky a mezery pomlčkami
32+
.replace(/[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g, '-')
33+
// odstranit vícenásobné pomlčky
34+
.replace(/-{2,}/g, '-')
35+
// odstranit pomlčky na začátku a na konci
36+
.replace(/^-+|-+$/g, '')
37+
// ujistit se, že hodnota nezačíná číslem (např. #121)
38+
.replace(/^(\d)/, '_$1')
39+
// převést na lowercase
40+
.toLowerCase()
41+
)
4042
}
4143

42-
const headersCache = new Map<
43-
string,
44-
{
45-
headers: APIHeader[]
46-
timestamp: number
47-
}
48-
>()
49-
50-
function parsePageHeaders(link: string) {
51-
const fullPath = path.join(__dirname, '../', link) + '.md'
52-
const timestamp = fs.statSync(fullPath).mtimeMs
44+
// Utility funkce na načtení nadpisů z markdown souboru na předaném odkazu
45+
function parsePageHeaders(link: string): APIHeader[] {
46+
const fullPath = path.join(__dirname, '../', link) + '.md' // vyhodnotit úplnou cestu k souboru
47+
const timestamp = fs.statSync(fullPath).mtimeMs // získat čas poslední modifikace souboru
5348

49+
// kontrola, jestli je soubor uložen v cache a jestli čas poslední modifikace odpovídá
5450
const cached = headersCache.get(fullPath)
5551
if (cached && timestamp === cached.timestamp) {
56-
return cached.headers
52+
return cached.headers // vrátit uložené nadpisy, když jsou akutální
5753
}
5854

59-
const src = fs.readFileSync(fullPath, 'utf-8')
60-
const h2s = src.match(/^## [^\n]+/gm)
55+
const src = fs.readFileSync(fullPath, 'utf-8') // číst markdown soubor
56+
const headers = extractHeadersFromMarkdown(src) // získat nadpisy z obsahu
57+
58+
// uložit získané nadpisy spolu s datem poslední modifikace do cache
59+
headersCache.set(fullPath, {
60+
timestamp,
61+
headers
62+
})
63+
64+
return headers
65+
}
66+
67+
// Pomocná funkce na získání všech nadpisů (h2) z markdown obsahu
68+
function extractHeadersFromMarkdown(src: string): APIHeader[] {
69+
const h2s = src.match(/^## [^\n]+/gm) // získat všechny h2 nadpisy (## nadpis)
70+
const anchorRE = /\{#([^}]+)\}/ // regulární výraz pro načtení odkazu (např.: {#some-anchor})
6171
let headers: APIHeader[] = []
72+
6273
if (h2s) {
63-
const anchorRE = /\{#([^}]+)\}/
74+
// zpracovat každý h2 nadpis a získat text + odkaz
6475
headers = h2s.map((h) => {
65-
const text = h
66-
.slice(2)
67-
.replace(/<sup class=.*/, '')
68-
.replace(/\\</g, '<')
69-
.replace(/`([^`]+)`/g, '$1')
70-
.replace(anchorRE, '') // hidden anchor tag
71-
.trim()
72-
const anchor = h.match(anchorRE)?.[1] ?? slugify(text)
76+
const text = cleanHeaderText(h, anchorRE) // vyčistit text nadpsisu
77+
const anchor = extractAnchor(h, anchorRE, text) // extrahovat nebo vygenerovat odkaz
7378
return { text, anchor }
7479
})
7580
}
76-
headersCache.set(fullPath, {
77-
timestamp,
78-
headers
79-
})
81+
8082
return headers
8183
}
8284

83-
// same as vitepress' slugify logic
84-
function slugify(text: string): string {
85-
return (
86-
text
87-
// Replace special characters
88-
.replace(/[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.?/]+/g, '-')
89-
// Remove continuous separators
90-
.replace(/-{2,}/g, '-')
91-
// Remove prefixing and trailing separators
92-
.replace(/^-+|-+$/g, '')
93-
// ensure it doesn't start with a number (#121)
94-
.replace(/^(\d)/, '_$1')
95-
// lowercase
96-
.toLowerCase()
97-
)
85+
// Pomocná funkce pro vyčištění texu nadpisu (např. odstranit superscript či formátování kódu)
86+
function cleanHeaderText(h: string, anchorRE: RegExp): string {
87+
return h
88+
.slice(2) // odstranit "##" část
89+
.replace(/<sup class=.*/, '') // odstranit superscript (např. tagy <sup>)
90+
.replace(/\\</g, '<') // dekódovat escape znaky jako \<
91+
.replace(/`([^`]+)`/g, '$1') // odstranit inline formátování (např. `code`)
92+
.replace(anchorRE, '') // odstranit tagy odkazů (např. {#anchor})
93+
.trim() // oříznout prázdné znaky na začátku a na konci
94+
}
95+
96+
// Pomocná funkce pro extrahování odkazu z nadpisu (nebo generování nového, pokud neexistuje)
97+
function extractAnchor(h: string, anchorRE: RegExp, text: string): string {
98+
const anchorMatch = h.match(anchorRE) // načíst odkaz, pokud existuje
99+
return anchorMatch?.[1] ?? slugify(text) // pokud odkaz neexistuje, vygenerovat nový přes `slugify`
98100
}
101+
102+
// Cache pro ukládání nadpisů a jim odpovídajících časů poslední modifikace pro omezení znovu načítání souborů
103+
const headersCache = new Map<
104+
string,
105+
{
106+
headers: APIHeader[]
107+
timestamp: number
108+
}
109+
>()
110+
111+
// Hlavní funkce pro načítání API dat
112+
export default {
113+
// deklarace souborů, které mají vyvolat HMR
114+
watch: './*.md',
115+
116+
// načíst API data a zpracovat objekty na postranní liště
117+
load(): APIGroup[] {
118+
// generovat data API skupiny zpracováním konfigurace lišty
119+
return (sidebar as MultiSidebarConfig)['/api/'].map((group) => ({
120+
text: group.text, // text pro skupinu (např. 'API')
121+
anchor: slugify(group.text), // generovat odkaz pro název skupiny
122+
items: group.items.map((item) => ({
123+
...item, // původní vlastnosti objektu
124+
headers: parsePageHeaders(item.link), // zpracovat nadpisy z markdown odkazu
125+
}))
126+
}))
127+
}
128+
}

0 commit comments

Comments
 (0)