diff --git a/apps/wiki/app/[language]/(documents)/[...slug]/page.tsx b/apps/wiki/app/[language]/(documents)/[...slug]/page.tsx index d3027be..e819c7c 100644 --- a/apps/wiki/app/[language]/(documents)/[...slug]/page.tsx +++ b/apps/wiki/app/[language]/(documents)/[...slug]/page.tsx @@ -15,6 +15,7 @@ import { LanguageAlternate } from '@/components/LanguageAlternate'; import { LocalImage } from '@/components/LocalImage'; import { MarkdownCopyInterceptor } from '@/components/MarkdownCopyInterceptor'; import { Link } from '@/components/progress'; +import SearchableTerminologyTable from '@/components/SearchableTerminologyTable'; import { ShortCodeComp } from '@/components/shortcode'; import { cache } from '@/lib/cache'; import { t } from '@/lib/i18n/client'; @@ -33,6 +34,7 @@ import SingleChildRedirect from '../components/SingleChildRedirect'; import remarkCsvToTable from './remarkCsvToTable'; import remarkHtmlContent from './remarkHtmlContent'; import remarkQrCode, { remarkHugoShortcode } from './remarkHugoShortcode'; +import remarkTerminologyGlossary from './remarkTerminologyGlossary'; import type { Frontmatter } from './types'; import { getAvailableLanguages, @@ -40,6 +42,19 @@ import { getContentGitRootDir, } from './utils'; +const loadTerminologyData = cache(async (): Promise => { + try { + const tsvPath = path.join( + getContentGitRootDir(), + 'data', + 'terminology.tsv', + ); + return await fs.readFile(tsvPath, 'utf-8'); + } catch { + return ''; + } +}); + interface DocParams { language: string; slug: string[]; @@ -322,11 +337,18 @@ export default async function DocPage({ }); } + const terminologyData = await loadTerminologyData(); + + function remarkTerminologyGlossaryPlugin() { + return remarkTerminologyGlossary({ language, data: terminologyData }); + } + const mdxRawContent: string = strippedSource; const remarkPlugins = [ remarkHeadingIdPlugin, remarkCsvToTablePlugin, remarkHugoShortcodePlugin, + remarkTerminologyGlossaryPlugin, remarkGfm, remarkMath, remarkHtmlContent, @@ -352,6 +374,7 @@ export default async function DocPage({ // 定义组件映射 const components: MDXComponents = { + SearchableTerminologyTable, ShortCodeComp: (props) => ( }} shortcode nodes + * (already converted to ShortCodeComp by remarkHugoShortcode) with a + * SearchableTerminologyTable MDX element carrying pre-loaded TSV data. + */ +export default function remarkTerminologyGlossary({ language, data }: Options) { + return (tree: Root) => { + visit(tree, 'mdxJsxFlowElement', (node, index, parent) => { + const el = node as unknown as MdxJsxFlowElement; + if (el.name !== 'ShortCodeComp') return; + + const compNameAttr = el.attributes?.find((a) => a.name === 'compName'); + if (compNameAttr?.value !== 'terminology-glossary') return; + + const replacement: MdxJsxFlowElement = { + type: 'mdxJsxFlowElement', + name: 'SearchableTerminologyTable', + attributes: [ + { type: 'mdxJsxAttribute', name: 'data', value: data }, + { type: 'mdxJsxAttribute', name: 'lang', value: language }, + ], + children: [], + }; + + if (parent && typeof index === 'number' && 'children' in parent) { + (parent.children as unknown[])[index] = replacement; + } + }); + }; +} diff --git a/apps/wiki/app/[language]/(documents)/[...slug]/utils.ts b/apps/wiki/app/[language]/(documents)/[...slug]/utils.ts index e6ba05b..4cd716e 100644 --- a/apps/wiki/app/[language]/(documents)/[...slug]/utils.ts +++ b/apps/wiki/app/[language]/(documents)/[...slug]/utils.ts @@ -51,5 +51,6 @@ export function getNonSelfClosingElements() { 'meme/onimai-ja', 'project-trans', 'github/contributors', + 'terminology-glossary', ]; } diff --git a/apps/wiki/components/HomeRedirect.tsx b/apps/wiki/components/HomeRedirect.tsx index 1028ace..c9ac97d 100644 --- a/apps/wiki/components/HomeRedirect.tsx +++ b/apps/wiki/components/HomeRedirect.tsx @@ -61,6 +61,14 @@ export default function HomeRedirect({ } } + // 韩语:将 ko-KR、kor 等映射到 'ko' + if (normalizedLang.startsWith('ko')) { + if (languageConfigs.some((config) => config.code === 'ko')) { + targetLanguage = 'ko'; + break; + } + } + // 处理主要语言代码(取前两位) const mainLang = normalizedLang.split('-')[0]; if (languageConfigs.some((config) => config.code === mainLang)) { @@ -161,7 +169,7 @@ export default function HomeRedirect({