Add remaining samples, tooling, and local project assets
This commit is contained in:
1 parent
05d43a7999
commit
1ff6c6cbb2
862 files changed
+18979
-21
No files matched your search
@@ -0,0 +1,143 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { getCollection } from 'astro:content';
|
||||
import { unified } from 'unified';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkRehype from 'remark-rehype';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import { pageRoutes } from './navigation.js';
|
||||
|
||||
/* -------------------------------
|
||||
* Markdown → 순수 텍스트
|
||||
* ------------------------------- */
|
||||
export async function extractPlainText(markdown) {
|
||||
if (!markdown) return '';
|
||||
|
||||
const cleaned = markdown
|
||||
.replace(/^import\s+.*from\s+['"].*['"];?$/gm, '')
|
||||
.replace(/<!--[\s\S]*?-->/g, '')
|
||||
.replace(/<[^>]+>/g, '')
|
||||
.trim();
|
||||
|
||||
const result = await unified()
|
||||
.use(remarkParse)
|
||||
.use(remarkGfm)
|
||||
.use(remarkRehype)
|
||||
.use(rehypeStringify)
|
||||
.process(cleaned);
|
||||
|
||||
return String(result)
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/&[a-zA-Z#0-9]+;/g, ' ')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
/* -------------------------------
|
||||
* Astro 파일 → 순수 텍스트
|
||||
* ------------------------------- */
|
||||
export function extractAstroText(fileContent) {
|
||||
return fileContent
|
||||
.replace(/---[\s\S]*?---/g, '')
|
||||
.replace(/<script[\s\S]*?<\/script>/gi, '')
|
||||
.replace(/<style[\s\S]*?<\/style>/gi, '')
|
||||
.replace(/<!--[\s\S]*?-->/g, '')
|
||||
.replace(/\{[\s\S]*?\}/g, '')
|
||||
.replace(/<[^>]+>/g, ' ')
|
||||
.replace(/ /gi, ' ')
|
||||
.replace(/\s{2,}/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
/* -------------------------------
|
||||
* 폴더 재귀 탐색
|
||||
* ------------------------------- */
|
||||
function getAstroFiles(dir) {
|
||||
if (!fs.existsSync(dir)) return [];
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
let results = [];
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) results = results.concat(getAstroFiles(fullPath));
|
||||
else if (entry.isFile() && entry.name.endsWith('.astro')) results.push(fullPath);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/* -------------------------------
|
||||
* 전체 검색 데이터 생성
|
||||
* ------------------------------- */
|
||||
export async function generateSearchData() {
|
||||
// ① Docs 전부
|
||||
const allDocs = await getCollection('docs');
|
||||
const mdxSearchData = await Promise.all(
|
||||
allDocs.map(async (doc) => {
|
||||
const plain = await extractPlainText(doc.body);
|
||||
const text = plain.toLowerCase();
|
||||
const slugPath = (doc.slug || doc.id).replace(/^ko\//, '');
|
||||
const url = `/${slugPath}${slugPath.endsWith('/') ? '' : '/'}`;
|
||||
return {
|
||||
id: slugPath,
|
||||
title: doc.data.title || slugPath,
|
||||
titleLower: (doc.data.title || slugPath).toLowerCase(),
|
||||
content: plain.slice(0, 500),
|
||||
fullContent: plain,
|
||||
fullLower: text,
|
||||
url,
|
||||
category: 'mdx',
|
||||
type: 'mdx'
|
||||
};
|
||||
})
|
||||
);
|
||||
|
||||
// ② 메뉴
|
||||
const menuSearchData = pageRoutes
|
||||
.filter(r => r.path?.startsWith('/'))
|
||||
.map(route => {
|
||||
const rawTitle = route.title || path.basename(route.path);
|
||||
const titleText = rawTitle.startsWith('가이드-') ? rawTitle.substring(4) : rawTitle;
|
||||
return {
|
||||
id: route.path,
|
||||
title: titleText,
|
||||
titleLower: titleText.toLowerCase(),
|
||||
content: '',
|
||||
fullContent: '',
|
||||
fullLower: '',
|
||||
url: `/help${route.path}`,
|
||||
category: 'menu',
|
||||
type: 'menu'
|
||||
};
|
||||
});
|
||||
|
||||
// ③ 실제 Astro 파일
|
||||
const subRoot = path.resolve('./src/content/sub');
|
||||
const subFiles = getAstroFiles(subRoot);
|
||||
const subSearchData = subFiles.map(filePath => {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const text = extractAstroText(content);
|
||||
const fileName = path.basename(filePath, '.astro');
|
||||
|
||||
// ✅ navigation/pageRoutes에서 title 가져오기
|
||||
const route = pageRoutes.find(r => r.path.endsWith(fileName));
|
||||
let title = route
|
||||
? route.title.startsWith('가이드-') ? route.title.substring(4) : route.title
|
||||
: content.match(/<title>(.*?)<\/title>/i)?.[1] ||
|
||||
content.match(/<h1[^>]*>(.*?)<\/h1>/i)?.[1] ||
|
||||
fileName;
|
||||
|
||||
return {
|
||||
id: fileName,
|
||||
title,
|
||||
titleLower: title.toLowerCase(),
|
||||
content: text.slice(0, 500),
|
||||
fullContent: text,
|
||||
fullLower: text.toLowerCase(),
|
||||
url: `/help/${fileName}`,
|
||||
category: 'astro-file',
|
||||
type: 'astro-file'
|
||||
};
|
||||
});
|
||||
|
||||
return [...mdxSearchData, ...menuSearchData, ...subSearchData];
|
||||
}
|
||||
Reference in new issue
Block a user