Add SEO and agent-readable documentation
This commit is contained in:
@@ -173,6 +173,16 @@ export function allDocSlugs(locale = 'en') {
|
||||
return Object.keys(docsByLocale[locale] ?? {}).filter((slug) => slug !== 'index');
|
||||
}
|
||||
|
||||
function flattenNav(items) {
|
||||
return items.flatMap((item) => [item.slug, ...(item.children ? flattenNav(item.children) : [])]);
|
||||
}
|
||||
|
||||
export function orderedDocSlugs(locale = 'en', { includeIndex = false } = {}) {
|
||||
const localizedDocs = docsByLocale[locale] ?? docsByLocale.en;
|
||||
const slugs = flattenNav(getNav(locale)).filter((slug) => localizedDocs[slug]);
|
||||
return includeIndex ? ['index', ...slugs] : slugs;
|
||||
}
|
||||
|
||||
function findDocTitle(slug, items) {
|
||||
for (const item of items) {
|
||||
if (item.slug === slug) return item.title;
|
||||
@@ -185,13 +195,51 @@ function findDocTitle(slug, items) {
|
||||
}
|
||||
|
||||
export function docTitle(slug, locale = 'en') {
|
||||
if (slug === 'index') return locale === 'ja' ? 'Decodalマニュアル' : 'Decodal Manual';
|
||||
return findDocTitle(slug, getNav(locale)) ?? slug;
|
||||
}
|
||||
|
||||
export function renderMarkdown(slug, locale = 'en') {
|
||||
function getSource(slug, locale) {
|
||||
const localizedDocs = docsByLocale[locale] ?? docsByLocale.en;
|
||||
const source = localizedDocs[slug] ?? localizedDocs.index;
|
||||
const html = marked.parse(source ?? '# Not found\n');
|
||||
return localizedDocs[slug] ?? localizedDocs.index ?? '# Not found\n';
|
||||
}
|
||||
|
||||
function stripInlineMarkdown(value) {
|
||||
return value
|
||||
.replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
|
||||
.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
|
||||
.replace(/[`*_~]/g, '')
|
||||
.replace(/<[^>]+>/g, '')
|
||||
.replace(/\s+/g, ' ')
|
||||
.trim();
|
||||
}
|
||||
|
||||
export function docDescription(slug, locale = 'en') {
|
||||
const blocks = getSource(slug, locale)
|
||||
.replace(/```[\s\S]*?```/g, '')
|
||||
.split(/\n\s*\n/)
|
||||
.map((block) => block.trim())
|
||||
.filter((block) => block && !block.startsWith('#') && !/^[-*]\s/.test(block));
|
||||
const description = stripInlineMarkdown(blocks[0] ?? '');
|
||||
if (description.length <= 180) return description;
|
||||
const shortened = description.slice(0, 177).replace(/\s+\S*$/, '').trimEnd();
|
||||
return `${shortened || description.slice(0, 177)}…`;
|
||||
}
|
||||
|
||||
export function sourceMarkdown(slug, locale = 'en') {
|
||||
return getSource(slug, locale).replace(/\]\(([^)\s]+)\)/g, (all, destination) => {
|
||||
const [href, hash = ''] = destination.split('#', 2);
|
||||
if (!href.endsWith('.md')) return all;
|
||||
const target = normalizeDocLink(locale, slug, href.slice(0, -3));
|
||||
const pathname = target === 'index'
|
||||
? `/docs/${locale}.md`
|
||||
: `/docs/${locale}/${target}.md`;
|
||||
return `](${pathname}${hash ? `#${hash}` : ''})`;
|
||||
});
|
||||
}
|
||||
|
||||
export function renderMarkdown(slug, locale = 'en') {
|
||||
const html = marked.parse(getSource(slug, locale));
|
||||
return html.replace(/href="([^"#][^"]*)\.md(#[^"]*)?"/g, (_all, href, hash = '') => {
|
||||
const target = normalizeDocLink(locale, slug, href);
|
||||
const pathname = target === 'index' ? `/docs/${locale}/` : `/docs/${locale}/${target}/`;
|
||||
|
||||
Reference in New Issue
Block a user