✨ feat(tutorial): Add common tutorial list
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
const BASE_URL = 'https://cdn.jsdelivr.net/gh/perfect-panel/ppanel-tutorial@main';
|
||||
|
||||
export async function getTutorial(path: string): Promise<string> {
|
||||
try {
|
||||
const url = `${BASE_URL}/${path}`;
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const text = await response.text();
|
||||
const markdown = addPrefixToImageUrls(text, getUrlPrefix(url));
|
||||
return markdown;
|
||||
} catch (error) {
|
||||
console.error('Error fetching the markdown file:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
type TutorialItem = {
|
||||
title: string;
|
||||
path: string;
|
||||
subItems?: TutorialItem[];
|
||||
};
|
||||
|
||||
export async function getTutorialList() {
|
||||
return await getTutorial('SUMMARY.md').then((markdown) => {
|
||||
const map = parseTutorialToMap(
|
||||
markdown.replace(/en-us/gi, 'en-US').replace(/zh-cn/gi, 'zh-CN'),
|
||||
);
|
||||
map.forEach((value, key) => {
|
||||
map.set(
|
||||
key,
|
||||
value.filter((item) => item.title !== 'README'),
|
||||
);
|
||||
});
|
||||
return map;
|
||||
});
|
||||
}
|
||||
|
||||
function parseTutorialToMap(markdown: string): Map<string, TutorialItem[]> {
|
||||
const map = new Map<string, TutorialItem[]>();
|
||||
let currentSection = '';
|
||||
const lines = markdown.split('\n');
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('## ')) {
|
||||
currentSection = line.replace('## ', '').trim();
|
||||
map.set(currentSection, []);
|
||||
} else if (line.startsWith('* ')) {
|
||||
const [, text, link] = line.match(/\* \[(.*?)\]\((.*?)\)/) || [];
|
||||
if (text && link) {
|
||||
if (!map.has(currentSection)) {
|
||||
map.set(currentSection, []);
|
||||
}
|
||||
map.get(currentSection)!.push({ title: text, path: link });
|
||||
}
|
||||
} else if (line.startsWith(' * ')) {
|
||||
const [, text, link] = line.match(/\* \[(.*?)\]\((.*?)\)/) || [];
|
||||
if (text && link) {
|
||||
const lastItem = map.get(currentSection)?.slice(-1)[0];
|
||||
if (lastItem) {
|
||||
if (!lastItem.subItems) {
|
||||
lastItem.subItems = [];
|
||||
}
|
||||
lastItem.subItems.push({ title: text, path: link });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
function getUrlPrefix(url: string): string {
|
||||
return url.replace(/\/[^/]+\.md$/, '/');
|
||||
}
|
||||
function addPrefixToImageUrls(markdown: string, prefix: string): string {
|
||||
return markdown.replace(/!\[(.*?)\]\((.*?)\)/g, (match, imgAlt, imgUrl) => {
|
||||
return ` ? imgUrl : `${prefix}${imgUrl}`})`;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user