mirror of
https://github.com/robonen/tools.git
synced 2026-03-20 10:54:44 +00:00
feat(docs): add document generator
This commit is contained in:
64
docs/app/composables/useDocs.ts
Normal file
64
docs/app/composables/useDocs.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import metadata from '#docs/metadata';
|
||||
import type { DocsMetadata, PackageMeta, CategoryMeta, ItemMeta } from '../../modules/extractor/types';
|
||||
|
||||
export function useDocs() {
|
||||
const data = metadata as unknown as DocsMetadata;
|
||||
|
||||
function getPackages(): PackageMeta[] {
|
||||
return data.packages;
|
||||
}
|
||||
|
||||
function getPackage(slug: string): PackageMeta | undefined {
|
||||
return data.packages.find(p => p.slug === slug);
|
||||
}
|
||||
|
||||
function getItem(packageSlug: string, itemSlug: string): { pkg: PackageMeta; category: CategoryMeta; item: ItemMeta } | undefined {
|
||||
const pkg = getPackage(packageSlug);
|
||||
if (!pkg) return undefined;
|
||||
|
||||
for (const category of pkg.categories) {
|
||||
const item = category.items.find(i => i.slug === itemSlug);
|
||||
if (item) return { pkg, category, item };
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function searchItems(query: string): Array<{ pkg: PackageMeta; item: ItemMeta }> {
|
||||
if (!query.trim()) return [];
|
||||
const q = query.toLowerCase();
|
||||
const results: Array<{ pkg: PackageMeta; item: ItemMeta }> = [];
|
||||
|
||||
for (const pkg of data.packages) {
|
||||
for (const category of pkg.categories) {
|
||||
for (const item of category.items) {
|
||||
if (
|
||||
item.name.toLowerCase().includes(q)
|
||||
|| item.description.toLowerCase().includes(q)
|
||||
) {
|
||||
results.push({ pkg, item });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
function getTotalItems(): number {
|
||||
return data.packages.reduce(
|
||||
(sum, pkg) => sum + pkg.categories.reduce(
|
||||
(catSum, cat) => catSum + cat.items.length, 0,
|
||||
), 0,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
getPackages,
|
||||
getPackage,
|
||||
getItem,
|
||||
searchItems,
|
||||
getTotalItems,
|
||||
};
|
||||
}
|
||||
41
docs/app/composables/useShiki.ts
Normal file
41
docs/app/composables/useShiki.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { createHighlighter, type Highlighter } from 'shiki';
|
||||
|
||||
let highlighterPromise: Promise<Highlighter> | null = null;
|
||||
|
||||
function getHighlighter(): Promise<Highlighter> {
|
||||
if (!highlighterPromise) {
|
||||
highlighterPromise = createHighlighter({
|
||||
themes: ['github-light', 'github-dark'],
|
||||
langs: ['typescript', 'vue', 'json', 'bash'],
|
||||
});
|
||||
}
|
||||
return highlighterPromise;
|
||||
}
|
||||
|
||||
export function useShiki() {
|
||||
const highlighted = ref<string>('');
|
||||
const isReady = ref(false);
|
||||
|
||||
async function highlight(code: string, lang: string = 'typescript'): Promise<string> {
|
||||
const highlighter = await getHighlighter();
|
||||
return highlighter.codeToHtml(code, {
|
||||
lang,
|
||||
themes: {
|
||||
light: 'github-light',
|
||||
dark: 'github-dark',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function highlightReactive(code: string, lang: string = 'typescript'): Promise<void> {
|
||||
highlighted.value = await highlight(code, lang);
|
||||
isReady.value = true;
|
||||
}
|
||||
|
||||
return {
|
||||
highlight,
|
||||
highlighted,
|
||||
highlightReactive,
|
||||
isReady,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user