diff --git a/scripts/lint-font-config.ts b/scripts/lint-font-config.ts index dc67a19..6995d6c 100644 --- a/scripts/lint-font-config.ts +++ b/scripts/lint-font-config.ts @@ -52,6 +52,14 @@ async function main() { let hasError = false; + /** 检查 font/ 目录下所有字体是否都在 config 中有配置 */ + for (const fontFile of fontPathMap.keys()) { + if (!config[fontFile]) { + console.error(`❌ [${fontFile}] 字体文件存在但 font-config.json 中没有配置`); + hasError = true; + } + } + for (const [fileName, cfg] of Object.entries(config)) { const fontPath = fontPathMap.get(fileName); if (!fontPath) { @@ -59,6 +67,17 @@ async function main() { continue; } + /** 检查必填字段是否都配置了 */ + const missingFields = TEXT_FIELDS.filter(({ key }) => !cfg[key]); + if (missingFields.length > 0) { + const displayName = cfg.displayName ?? fileName; + hasError = true; + console.error( + `❌ [${displayName}] 缺少字段:${missingFields.map((f) => f.label).join(", ")}`, + ); + continue; + } + /** 读取字体 codepoints(有缓存则复用) */ let supportedCps = cpCache.get(fileName); if (!supportedCps) { diff --git a/src/pages/FontDetail.vue b/src/pages/FontDetail.vue index d1bb111..fd6040e 100644 --- a/src/pages/FontDetail.vue +++ b/src/pages/FontDetail.vue @@ -11,6 +11,7 @@ import { useRoute, useRouter } from "vue-router"; import { useHead } from "@unhead/vue"; import { fetchFonts, fetchFontMeta } from "../api"; import type { FontInfo, FontMeta } from "../api"; +import CodeBlock from "../components/CodeBlock.vue"; import { FONT_NAME, FONT_SLUG, ORIGIN } from "../placeholders"; import { SITE_NAME } from "../seo"; @@ -74,11 +75,8 @@ function splitSemicolon(text: string | undefined): string[] { .filter(Boolean); } -/** 默认预览文案(font-config.json 未配 previewText 时使用) */ -const DEFAULT_PREVIEW = "静心茶舍以茶为媒观自在一叶知秋山间晨露未晞茶人已入林深处指尖轻捻择其嫩芽天地无极乾坤借法"; - -/** 当前字体的预览文案:优先用 config.previewText */ -const previewContent = computed(() => meta.value?.config?.previewText ?? DEFAULT_PREVIEW); +/** 当前字体的预览文案:来自 config.previewText,未配置则不渲染预览 */ +const previewContent = computed(() => meta.value?.config?.previewText ?? ""); /** 预览文字拆分:第一段做大标题,其余做副文本 */ const previewLines = computed(() => { @@ -92,20 +90,31 @@ const previewLines = computed(() => { }; }); -/** 正文标题:优先 config.bodyTitle */ -const bodyTitle = computed(() => meta.value?.config?.bodyTitle ?? "清风明月"); +/** 正文标题:来自 config.bodyTitle */ +const bodyTitle = computed(() => meta.value?.config?.bodyTitle ?? ""); -/** 正文段落:优先 config.bodyText */ -const bodyText = computed(() => meta.value?.config?.bodyText ?? "山中有桂树,常伴青云飞。"); +/** 正文段落:来自 config.bodyText */ +const bodyText = computed(() => meta.value?.config?.bodyText ?? ""); -/** 字符预览行:优先 config.charsetPreview */ -const charsetPreview = computed(() => meta.value?.config?.charsetPreview ?? "天地玄黄宇宙洪荒:0123456789 ABCDEF"); +/** 字符预览行:来自 config.charsetPreview */ +const charsetPreview = computed(() => meta.value?.config?.charsetPreview ?? ""); + +/** 使用方法示例代码(动态拼接 origin + fontName) */ +const usageCode = computed(() => + ` + +` +);