using System; using System.Collections.Generic; using System.Linq; namespace LocalizationTool.Services { /// 语言条目:系统代码 / 显示名 / 中文名 / 百度翻译代码 的映射。 public class LanguageEntry { /// 系统语言代码(= .dat 文件名 / 语言包 LanguageCode)。主流语言为 BCP 47(如 ja-JP),小众语言直接使用百度代码。 public string Code { get; set; } /// 显示名(主流语言为本地名,小众语言为中文名)。 public string Name { get; set; } /// 中文名,如 "日语"。 public string ChineseName { get; set; } /// 百度翻译 API 的语言代码,如 "jp"。 public string BaiduCode { get; set; } /// 百度是否支持该语言的自动语种检测。 public bool SupportsDetect { get; set; } /// 下拉框显示文本(显示名与中文名相同时不重复)。 public string Display => string.Equals(Name, ChineseName, StringComparison.Ordinal) ? $"{Name} ({Code})" : $"{Name} ({Code}) —— {ChineseName}"; } /// /// 语言映射目录:系统语言代码 ↔ 百度翻译代码 的全量对照表。 /// 数据来源:百度翻译开放平台官方语言列表(https://fanyi-api.baidu.com/doc/21 附录)。 /// 添加语言时从这里展开选择;翻译时由 GetBaiduCode 自动映射为百度的字段。 /// public static class LanguageCatalog { /// /// 百度全量语言原始数据:百度码 | 中文名 | 支持语种检测。 /// ("auto 自动检测"不属于可新增的翻译目标语言,未列入。) /// private static readonly string[] BaiduRaw = new[] { // A "ara|阿拉伯语|是", "gle|爱尔兰语|是", "oci|奥克语|是", "alb|阿尔巴尼亚语|是","arq|阿尔及利亚阿拉伯语|否","aka|阿肯语|否", "arg|阿拉贡语|否", "amh|阿姆哈拉语|是", "asm|阿萨姆语|是", "aym|艾马拉语|否", "aze|阿塞拜疆语|是", "ast|阿斯图里亚斯语|是", "oss|奥塞梯语|否", "est|爱沙尼亚语|是", "oji|奥杰布瓦语|否", "ori|奥里亚语|是", "orm|奥罗莫语|否", // B "pl|波兰语|是", "per|波斯语|是", "bre|布列塔尼语|是", "bak|巴什基尔语|否", "baq|巴斯克语|是", "pot|巴西葡萄牙语|否", "bel|白俄罗斯语|是", "ber|柏柏尔语|是", "pam|邦板牙语|否", "bul|保加利亚语|是", "sme|北方萨米语|否", "ped|北索托语|否", "bem|本巴语|否", "bli|比林语|否", "bis|比斯拉马语|否", "bal|俾路支语|否", "ice|冰岛语|是", "bos|波斯尼亚语|是", "bho|博杰普尔语|否", // C "chv|楚瓦什语|否", "tso|聪加语|否", // D "dan|丹麦语|是", "de|德语|是", "tat|鞑靼语|是", "sha|掸语|否", "tet|德顿语|否", "div|迪维希语|否", "log|低地德语|是", // E "ru|俄语|是", // F "fra|法语|是", "fil|菲律宾语|是", "fin|芬兰语|是", "san|梵语|否", "fri|弗留利语|否", "ful|富拉尼语|否", "fao|法罗语|否", // G "gla|盖尔语|否", "kon|刚果语|否", "ups|高地索布语|否", "hkm|高棉语|是", "kal|格陵兰语|否", "geo|格鲁吉亚语|是", "guj|古吉拉特语|是", "gra|古希腊语|否", "eno|古英语|否", "grn|瓜拉尼语|否", // H "kor|韩语|是", "nl|荷兰语|是", "hup|胡帕语|否", "hak|哈卡钦语|否", "ht|海地语|否", "mot|黑山语|否", "hau|豪萨语|否", // J "kir|吉尔吉斯语|否", "glg|加利西亚语|是", "frn|加拿大法语|否", "cat|加泰罗尼亚语|是","cs|捷克语|是", // K "kab|卡拜尔语|是", "kan|卡纳达语|是", "kau|卡努里语|否", "kah|卡舒比语|否", "cor|康瓦尔语|否", "xho|科萨语|是", "cos|科西嘉语|否", "cre|克里克语|否", "cri|克里米亚鞑靼语|否", "kli|克林贡语|否", "hrv|克罗地亚语|是", "que|克丘亚语|否", "kas|克什米尔语|否", "kok|孔卡尼语|否", "kur|库尔德语|是", // L "lat|拉丁语|是", "lao|老挝语|否", "rom|罗马尼亚语|是", "lag|拉特加莱语|否", "lav|拉脱维亚语|是", "lim|林堡语|否", "lin|林加拉语|否", "lug|卢干达语|否", "ltz|卢森堡语|否", "ruy|卢森尼亚语|否", "kin|卢旺达语|是", "lit|立陶宛语|是", "roh|罗曼什语|否", "ro|罗姆语|否", "loj|逻辑语|否", // M "may|马来语|是", "bur|缅甸语|是", "mar|马拉地语|否", "mg|马拉加斯语|是", "mal|马拉雅拉姆语|是", "mac|马其顿语|是", "mah|马绍尔语|否", "mai|迈蒂利语|是", "glv|曼克斯语|否", "mau|毛里求斯克里奥尔语|否","mao|毛利语|否", "ben|孟加拉语|是", "mlt|马耳他语|是", "hmn|苗语|否", // N "nor|挪威语|是", "nea|那不勒斯语|否", "nbl|南恩德贝莱语|否", "afr|南非荷兰语|是", "sot|南索托语|否", "nep|尼泊尔语|是", // P "pt|葡萄牙语|是", "pan|旁遮普语|是", "pap|帕皮阿门托语|否", "pus|普什图语|否", // Q "nya|齐切瓦语|否", "twi|契维语|否", "chr|切罗基语|否", // R "jp|日语|是", "swe|瑞典语|是", // S "srd|萨丁尼亚语|否", "sm|萨摩亚语|否", "sec|塞尔维亚-克罗地亚语|否", "srp|塞尔维亚语|是", "sol|桑海语|否", "sin|僧伽罗语|是", "epo|世界语|是", "nob|书面挪威语|是", "sk|斯洛伐克语|是", "slo|斯洛文尼亚语|是","swa|斯瓦希里语|是", "src|塞尔维亚语(西里尔)|否", "som|索马里语|是", "sco|苏格兰语|否", // T "th|泰语|是", "tr|土耳其语|是", "tgk|塔吉克语|是", "tam|泰米尔语|是", "tgl|他加禄语|是", "tir|提格利尼亚语|否", "tel|泰卢固语|是", "tua|突尼斯阿拉伯语|否","tuk|土库曼语|否", // W "ukr|乌克兰语|是", "wln|瓦隆语|是", "wel|威尔士语|是", "ven|文达语|否", "wol|沃洛夫语|否", "urd|乌尔都语|是", // X "spa|西班牙语|是", "heb|希伯来语|是", "el|希腊语|是", "hu|匈牙利语|是", "fry|西弗里斯语|是", "sil|西里西亚语|否", "hil|希利盖农语|否", "los|下索布语|否", "haw|夏威夷语|否", "nno|新挪威语|是", "nqo|西非书面语|否", "snd|信德语|否", "sna|修纳语|否", "ceb|宿务语|否", "syr|叙利亚语|否", "sun|巽他语|否", // Y "en|英语|是", "hi|印地语|是", "id|印尼语|是", "it|意大利语|是", "vie|越南语|是", "yid|意第绪语|否", "ina|因特语|否", "ach|亚齐语|否", "ing|印古什语|否", "ibo|伊博语|否", "ido|伊多语|否", "yor|约鲁巴语|否", "arm|亚美尼亚语|是", "iku|伊努克提图特语|否", // Z "zh|中文(简体)|是", "cht|中文(繁体)|是", "wyw|中文(文言文)|是", "yue|中文(粤语)|是", "zaz|扎扎其语|否", "frm|中古法语|否", "zul|祖鲁语|否", "jav|爪哇语|否", }; /// /// 主流语言的系统代码与本地显示名(百度码 → 系统码 + 本地名)。 /// 未在此表中的语言:系统码直接用百度码,显示名用中文名。 /// private static readonly Dictionary Preferred = new Dictionary(StringComparer.OrdinalIgnoreCase) { ["zh"] = ("zh-CN", "简体中文"), ["cht"] = ("zh-TW", "繁體中文"), ["yue"] = ("yue", "粵語"), ["en"] = ("en-US", "English"), ["jp"] = ("ja-JP", "日本語"), ["kor"] = ("ko-KR", "한국어"), ["fra"] = ("fr-FR", "Français"), ["spa"] = ("es-ES", "Español"), ["de"] = ("de-DE", "Deutsch"), ["it"] = ("it-IT", "Italiano"), ["pt"] = ("pt-BR", "Português"), ["ru"] = ("ru-RU", "Русский"), ["ara"] = ("ar-SA", "العربية"), ["th"] = ("th-TH", "ไทย"), ["nl"] = ("nl-NL", "Nederlands"), ["el"] = ("el-GR", "Ελληνικά"), ["pl"] = ("pl-PL", "Polski"), ["bul"] = ("bg-BG", "Български"), ["est"] = ("et-EE", "Eesti"), ["dan"] = ("da-DK", "Dansk"), ["fin"] = ("fi-FI", "Suomi"), ["cs"] = ("cs-CZ", "Čeština"), ["rom"] = ("ro-RO", "Română"), ["slo"] = ("sl-SI", "Slovenščina"), ["swe"] = ("sv-SE", "Svenska"), ["hu"] = ("hu-HU", "Magyar"), ["vie"] = ("vi-VN", "Tiếng Việt"), ["tr"] = ("tr-TR", "Türkçe"), ["id"] = ("id-ID", "Bahasa Indonesia"), ["may"] = ("ms-MY", "Bahasa Melayu"), ["ukr"] = ("uk-UA", "Українська"), ["heb"] = ("he-IL", "עברית"), ["ice"] = ("is-IS", "Íslenska"), ["lav"] = ("lv-LV", "Latviešu"), ["lit"] = ("lt-LT", "Lietuvių"), ["hrv"] = ("hr-HR", "Hrvatski"), ["srp"] = ("sr-RS", "Srpski"), ["sk"] = ("sk-SK", "Slovenčina"), ["alb"] = ("sq-AL", "Shqip"), ["aze"] = ("az-AZ", "Azərbaycanca"), ["geo"] = ("ka-GE", "ქართული"), ["cat"] = ("ca-ES", "Català"), ["glg"] = ("gl-ES", "Galego"), ["baq"] = ("eu-ES", "Euskara"), ["mlt"] = ("mt-MT", "Malti"), ["afr"] = ("af-ZA", "Afrikaans"), ["epo"] = ("eo", "Esperanto"), ["wel"] = ("cy-GB", "Cymraeg"), ["fil"] = ("fil-PH","Filipino"), ["ben"] = ("bn-IN", "বাংলা"), ["tam"] = ("ta-IN", "தமிழ்"), ["tel"] = ("te-IN", "తెలుగు"), ["pan"] = ("pa-IN", "ਪੰਜਾਬੀ"), ["mar"] = ("mr-IN", "मराठी"), ["mal"] = ("ml-IN", "മലയാളം"), ["kan"] = ("kn-IN", "ಕನ್ನಡ"), ["guj"] = ("gu-IN", "ગુજરાતી"), ["hi"] = ("hi-IN", "हिन्दी"), ["urd"] = ("ur-PK", "اردو"), ["per"] = ("fa-IR", "فارسی"), ["bur"] = ("my-MM", "မြန်မာ"), ["nep"] = ("ne-NP", "नेपाली"), ["sin"] = ("si-LK", "සිංහල"), ["swa"] = ("sw-KE", "Kiswahili"), ["amh"] = ("am-ET", "አማርኛ"), ["kur"] = ("ku", "Kurdî"), ["lat"] = ("la", "Latine"), ["san"] = ("sa", "संस्कृतम्"), }; /// 全量语言目录(已按系统码排序,主流语言在前风格由排序自然决定)。 public static readonly List All = Build(); private static List Build() { var list = new List(); var seen = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (var line in BaiduRaw) { var parts = line.Split('|'); if (parts.Length < 3) continue; var baidu = parts[0].Trim(); var cn = parts[1].Trim(); var detect = string.Equals(parts[2].Trim(), "是", StringComparison.Ordinal); // 去重(官方表偶有重复行,如斯洛文尼亚语出现两次) if (!seen.Add(baidu)) continue; var hasPreferred = Preferred.TryGetValue(baidu, out var pref); var code = hasPreferred ? pref.Code : baidu; var name = hasPreferred ? pref.Name : cn; list.Add(new LanguageEntry { Code = code, Name = name, ChineseName = cn, BaiduCode = baidu, SupportsDetect = detect, }); } // 主流语言排前面(系统码精确排序:zh 系 → 常见 → 其余按码) list.Sort((a, b) => { int Rank(LanguageEntry e) { switch (e.BaiduCode) { case "zh": return 0; case "cht": return 1; case "en": return 2; case "jp": return 3; case "kor": return 4; default: return 10; } } var r = Rank(a).CompareTo(Rank(b)); return r != 0 ? r : string.CompareOrdinal(a.Code, b.Code); }); return list; } /// /// 系统语言代码 → 百度翻译代码。 /// 优先精确匹配 Code;其次匹配主代码(如 "ja-XX" → ja-JP → jp);都没有则返回主代码本身兜底。 /// public static string GetBaiduCode(string langCode) { if (string.IsNullOrWhiteSpace(langCode)) return "zh"; var code = langCode.Trim(); // 1) 精确匹配 var exact = All.FirstOrDefault(e => string.Equals(e.Code, code, StringComparison.OrdinalIgnoreCase)); if (exact != null) return exact.BaiduCode; // 2) 主代码匹配("ja-XX" 之类非标准区域码也能命中) var main = code.Split('-')[0].ToLowerInvariant(); var byMain = All.FirstOrDefault(e => string.Equals(e.Code.Split('-')[0], main, StringComparison.OrdinalIgnoreCase)); if (byMain != null) return byMain.BaiduCode; // 3) 兜底:直接给主代码(也许百度认识) return main; } /// 按系统代码查找条目。 public static LanguageEntry Find(string langCode) => All.FirstOrDefault(e => string.Equals(e.Code, langCode, StringComparison.OrdinalIgnoreCase)); } }