From 3a599a90b7d820a189d33d8c3bcd6adff8be8d9e Mon Sep 17 00:00:00 2001 From: Kirk Lin Date: Wed, 30 Aug 2023 21:26:37 +0800 Subject: [PATCH] feat: add support for `chineseType`, `fallbackFont`, and `declareEnglishFont` options --- src/constants.ts | 3 ++ src/{defaultChineseFonts.ts => core.ts} | 69 ++++++++++++------------- src/index.ts | 24 ++++++--- src/types.ts | 38 +++++++++++++- 4 files changed, 90 insertions(+), 44 deletions(-) create mode 100644 src/constants.ts rename src/{defaultChineseFonts.ts => core.ts} (74%) diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..43b8fba --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,3 @@ +import type { FontType } from "./types"; + +export const fontType: FontType[] = ["chinese", "helvetica", "italics", "song", "imitation-song", "new-song", "li"]; diff --git a/src/defaultChineseFonts.ts b/src/core.ts similarity index 74% rename from src/defaultChineseFonts.ts rename to src/core.ts index 47520f7..44889d5 100644 --- a/src/defaultChineseFonts.ts +++ b/src/core.ts @@ -1,17 +1,19 @@ -const macosSimplifiedChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC", "Hiragino Sans GB", "Heiti SC"]; -const macosTraditionalChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC"]; -const windowsSimplifiedChinese = ["Microsoft YaHei"]; -const windowsTraditionalChinese = ["Microsoft Jhenghei"]; -const linuxSimplifiedChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans"]; -const linuxTraditionalChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans"]; +import { fontType } from "./constants"; +import type { ChineseType, FontType } from "./types"; + +export const macosSimplifiedChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC", "Hiragino Sans GB", "Heiti SC"]; +export const macosTraditionalChinese = ["-apple-system", "BlinkMacSystemFont", "PingFang SC"]; +export const windowsSimplifiedChinese = ["Microsoft YaHei"]; +export const windowsTraditionalChinese = ["Microsoft Jhenghei"]; +export const linuxSimplifiedChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans SC", "Source Han Sans CN", "Source Han Sans"]; +export const linuxTraditionalChinese = ["system-ui", "Ubuntu", "Droid Sans", "Source Han Sans TC", "Source Han Sans TW", "Source Han Sans"]; -export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation-song" | "new-song" | "li"; /** * Generates a list of fonts for the specified character type and font type, with optional fallback font. * 根据指定的字符类型和字体类型生成字体列表,可以选择性地指定回退字体。 * - * @param characterType - The type of characters to consider: "simplified" or "traditional". - * 要考虑的字符类型:"simplified"(简体)或 "traditional"(繁体)。 + * @param chineseType - The type of chinese: "simplified" or "traditional". + * 要考虑的汉字类型:"simplified"(简体)或 "traditional"(繁体)。 * @param fontType - The type of font to generate the list for: "chinese", "helvetica", "italics", "song", "imitation-song", "new-song", or "li". * 要生成列表的字体类型:"chinese"、"helvetica"、"italics"、"song"、"imitation-song"、"new-song" 或 "li"。 * @param fallbackFont - The fallback font to use if the desired font type is not available. Pass `null` for no fallback. @@ -23,21 +25,21 @@ export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation * 基于指定条件的字体名称数组。 */ export function generateFontList( - characterType: "simplified" | "traditional", + chineseType: ChineseType, fontType: FontType, - fallbackFont: string | null = "sans-serif", - declareEnglishFont: boolean = true, + fallbackFont: string[] | null = ["sans-serif"], + declareEnglishFont: string[] = ["Arial"], ): string[] { const fontList: string[] = []; // Add English font declaration if required - if (declareEnglishFont) { - fontList.push(`Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`); - fontList.push("Arial"); + if (declareEnglishFont.length > 0) { + fontList.push(generatePunctuationFontName(fontType)); + fontList.push(...declareEnglishFont); } // Determine the appropriate font list based on the character type - if (characterType === "simplified") { + if (chineseType === "simplified") { const chineseFonts = [macosSimplifiedChinese, windowsSimplifiedChinese, linuxSimplifiedChinese].flat(); // Select the font list based on the font type switch (fontType) { @@ -153,28 +155,16 @@ export function generateFontList( // Add fallback font if specified if (fallbackFont !== null) { - fontList.push(fallbackFont); + fontList.push(...fallbackFont); } return fontList; } -export const defaultChineseFonts = { - - "chinese": generateFontList("simplified", "chinese"), - // 黑体 - "helvetica": generateFontList("simplified", "helvetica"), - // 楷体 - "italics": generateFontList("simplified", "italics"), - // 宋体 - "song": generateFontList("simplified", "song"), - // 仿宋体 - "imitation-song": generateFontList("simplified", "imitation-song"), - // 新宋体 - "new-song": generateFontList("simplified", "new-song"), - // 隶书 - "li": generateFontList("simplified", "li"), -}; +export const defaultChineseFonts: Record = fontType.reduce((fonts, type) => { + fonts[type] = generateFontList("simplified", type); + return fonts; +}, {} as Record); /** * Generates a CSS @font-face rule for the specified font type. @@ -182,18 +172,20 @@ export const defaultChineseFonts = { * * @param fontType - The type of font to generate the @font-face rule for. * 要生成 @font-face 规则的字体类型。 - * + * @param {string[]} filterFontList - The list of fonts to be filtered out from the default font list. + * 要从默认字体列表中过滤掉的字体列表。 * @returns {string} The generated @font-face CSS rule as a string. * 生成的 @font-face CSS 规则作为字符串。 */ -export function generateFontFaceRule(fontType: FontType): string { +export function generateFontFaceRule(fontType: FontType, filterFontList: string[]): string { const fontList = defaultChineseFonts[fontType]; if (!fontList) { throw new Error(`Font type "${fontType}" is not valid.`); } - const fontName = `Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`; - const filteredFontList = fontList.filter(font => font !== "Arial"); // Filtering out Arial + const fontName = generatePunctuationFontName(fontType); + // Filtering out specified fonts + const filteredFontList = fontList.filter(font => !filterFontList.includes(font)); const fontSrc = filteredFontList.map(font => `local('${font}')`).join(", "); return ` @@ -204,3 +196,6 @@ export function generateFontFaceRule(fontType: FontType): string { } `; } +export function generatePunctuationFontName(fontType: FontType): string { + return `Punctuation ${fontType.charAt(0).toUpperCase() + fontType.slice(1)}`; +} diff --git a/src/index.ts b/src/index.ts index 83e9164..b87d6d6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,29 @@ import { toArray } from "@unocss/core"; import type { Preset } from "unocss"; -import type { FontType } from "./defaultChineseFonts"; -import { defaultChineseFonts, generateFontFaceRule } from "./defaultChineseFonts"; -import type { ChineseFontsOptions } from "./types"; +import { fontType } from "./constants"; +import type { ChineseFontsOptions, FontType } from "./types"; +import { defaultChineseFonts, generateFontFaceRule, generateFontList } from "./core"; export * from "./types"; const presetChinese = (options: ChineseFontsOptions = {}): Preset => { // 解构参数并提供默认值 - const { extendTheme = true, themeKey = "fontFamily" } = options; + const { + extendTheme = true, + themeKey = "fontFamily", + chineseType = "simplified", + fallbackFont = ["sans-serif"], + declareEnglishFont = ["Arial"], + } = options; // 合并字体选项 - const fonts = { ...defaultChineseFonts, ...options?.fonts }; + const fonts = { + ...fontType.reduce((fonts, type) => { + fonts[type] = generateFontList(chineseType, type, fallbackFont, declareEnglishFont); + return fonts; + }, {} as Record), + ...options?.fonts, + }; // 转换字体选项为字体对象 const fontObject = Object.fromEntries( @@ -46,7 +58,7 @@ const presetChinese = (options: ChineseFontsOptions = {}): Preset => { } const fontFacePreflights = Object.keys(defaultChineseFonts).map(fontType => ({ - getCSS: () => generateFontFaceRule(fontType), + getCSS: () => generateFontFaceRule(fontType, declareEnglishFont), })); preset.preflights = fontFacePreflights; diff --git a/src/types.ts b/src/types.ts index 3b26fa5..f44d298 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,20 +1,56 @@ +/** + * Options for configuring Chinese fonts. + * 配置中文字体的选项。 + */ export interface ChineseFontsOptions { /** * Extend the theme object + * 扩展主题对象 * @default true */ extendTheme?: boolean; /** * Key for the theme object + * 主题对象的键 * * @default 'fontFamily' */ themeKey?: string; /** - * extend fonts + * Extend fonts + * 扩展字体 */ fonts?: Record; + /** + * The type of Chinese: "simplified" or "traditional". + * 中文的类型: "simplified"(简体)或 "traditional"(繁体)。 + */ + chineseType?: ChineseType; + + /** + * Fallback font for Chinese characters. + * 备选字体。 + */ + fallbackFont?: string[] | null; + + /** + * Declare fonts for English text. + * 声明英文文本的字体。 + */ + declareEnglishFont?: string[]; } + +/** + * Represents different font types that can be used, including various Chinese fonts and styles. + * 表示可用的不同字体类型,包括各种中文字体和样式。 + */ +export type FontType = "chinese" | "helvetica" | "italics" | "song" | "imitation-song" | "new-song" | "li"; + +/** + * Represents different types of Chinese characters, such as simplified or traditional. + * 表示不同类型的中文字符,例如简体或繁体。 + */ +export type ChineseType = "simplified" | "traditional";