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));
}
}