Files
iD/scripts/language_names.js
2025-01-22 15:19:23 +01:00

326 lines
8.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Downloads the latest translations from Transifex */
const fs = require('fs');
const cldrMainDir = 'node_modules/cldr-localenames-full/main/';
const rematchCodes = {
'ar-AA': 'ar',
'pt-BR': 'pt',
'pt': 'pt-PT',
'zh-CN': 'zh',
'zh-TW': 'zh-Hant',
'zh-HK': 'zh-Hant-HK'
};
const codesToSkip = ['ase', 'mis', 'mul', 'und', 'zxx'];
let referencedScripts = [];
function getLangNamesInNativeLang() {
// manually add languages we want that aren't in CLDR
// see for example https://github.com/openstreetmap/iD/pull/9241/
let unordered = {
aer: { nativeName: 'Arrernte' },
aoi: { nativeName: 'Anindilyakwa' },
aus: { nativeName: 'Australian Aboriginal Languages' },
bdy: { nativeName: 'YugambehBandjalangic' },
'bft': {
nativeName: 'بلتی'
},
'bha': {
nativeName: 'भरीयाटी'
},
'brh': {
nativeName: 'براہوئی'
},
coa: { nativeName: 'Basa Pulu Kokos' },
'cdo': {
nativeName: '閩東語'
},
'cdo-Hans': {
base: 'cdo',
script: 'Hans',
nativeName: '闽东语(简化汉字)'
},
'cdo-Hant': {
base: 'cdo',
script: 'Hant',
nativeName: '閩東語(傳統漢字)'
},
'cdo-Latn': {
base: 'cdo',
script: 'Latn',
nativeName: 'Mìng-dĕ̤ng-ngṳ̄ (Bàng-uâ-cê)'
},
'cpx': {
nativeName: '莆仙語'
},
'cpx-Hans': {
base: 'cpx',
script: 'Hans',
nativeName: '莆仙语(简体)'
},
'cpx-Hant': {
base: 'cpx',
script: 'Hant',
nativeName: '莆仙語(繁體)'
},
'cpx-Latn': {
base: 'cpx',
script: 'Latn',
nativeName: 'Pó-sing-gṳ̂ (Báⁿ-uā-ci̍)'
},
dgw: { nativeName: 'Daungwurrung' },
'gan': {
nativeName: '贛語'
},
'gan-Hans': {
base: 'gan',
script: 'Hans',
nativeName: '赣语(简体)'
},
'gan-Hant': {
base: 'gan',
script: 'Hant',
nativeName: '贛語(繁體)'
},
gjm: { nativeName: 'Gunditjmara' },
gjr: { nativeName: 'Gurindji Kriol' },
gup: { nativeName: 'Bininj Gun-Wok' },
'hak': {
nativeName: '客家語'
},
'hak-Hans': {
base: 'hak',
script: 'Hans',
nativeName: '客家语(简体)'
},
'hak-Hant': {
base: 'hak',
script: 'Hant',
nativeName: '客家語(繁體)'
},
'hak-Latn': {
base: 'hak',
script: 'Latn',
nativeName: 'Hak-kâ-ngî (Pha̍k-fa-sṳ)'
},
'hsn': {
nativeName: '湘語'
},
'ja-Hira': {
base: 'ja',
script: 'Hira'
},
'ja-Latn': {
base: 'ja',
script: 'Latn'
},
jay: { nativeName: 'Yan-nhaŋu' },
'kls': {
nativeName: 'Kal\'as\'amondr'
},
'ko-Latn': {
base: 'ko',
script: 'Latn'
},
'mnc-Latn': {
base: 'mnc',
script: 'Latn',
nativeName: 'manju gisun'
},
'mnc-Mong': {
base: 'mnc',
script: 'Mong',
nativeName: 'ᠮᠠᠨᠵᡠ ᡤᡳᠰᡠᠨ'
},
mwf: { nativeName: 'Murrinh-Patha' },
mwp: { nativeName: 'Kalaw Lagaw Ya' },
'nan': {
nativeName: '閩南語'
},
'nan-Hant': {
base: 'nan',
script: 'Hant',
nativeName: '閩南語(傳統漢字)'
},
'nan-Latn-pehoeji': {
base: 'nan',
script: 'Latn',
nativeName: 'Bân-lâm-gú (Pe̍h-ōe-jī)'
},
'nan-Latn-tailo': {
base: 'nan',
script: 'Latn',
nativeName: 'Bân-lâm-gú (Tâi-lô)'
},
nys: { nativeName: 'Nyungar' },
'oc': {
nativeName: 'Occitan'
},
pih: { nativeName: 'PitkernNorfuk' },
piu: { nativeName: 'Pintupi' },
pjt: { nativeName: 'Pitjantjatjara' },
'pnb': {
nativeName: 'پنجابی'
},
rop: { nativeName: 'Australian Kriol' },
rrm: { nativeName: 'Moriori' },
'scl': {
nativeName: 'ݜݨیاٗ'
},
'shg': {
nativeName: 'хуг̌ну̊н зив'
},
'skr': {
nativeName: 'سرائیکی'
},
tcs: { nativeName: 'Yumplatok' },
tiw: { nativeName: 'Tiwi' },
'trw': {
nativeName: 'توروالی'
},
ulk: { nativeName: 'Meriam Mir' },
'wbl': {
nativeName: 'وخی'
},
wlp: { nativeName: 'Warlpiri' },
'wuu': {
nativeName: '吳語'
},
'wuu-Hans': {
base: 'wuu',
script: 'Hans',
nativeName: '吴语(简体)'
},
'wuu-Hant': {
base: 'wuu',
script: 'Hant',
nativeName: '吳語(正體)'
},
wrh: { nativeName: 'Wiradjuri' },
wth: { nativeName: 'Wathawurrung' },
wyi: { nativeName: 'Woiwurrung' },
xdk: { nativeName: 'Dharug' },
xni: { nativeName: 'Ngarigo' },
xph: { nativeName: 'Tyerrernotepanner' },
xrd: { nativeName: 'Gundungurra' },
'yue-Hans': {
base: 'yue',
script: 'Hans',
nativeName: '粵语(简体)'
},
'yue-Hant': {
base: 'yue',
script: 'Hant',
nativeName: '粵語(繁體)'
},
'zh-Latn-pinyin': {
base: 'zh',
script: 'Latn',
nativeName: 'Zhōngwén (Hànyǔ Pīnyīn)'
},
zku: { nativeName: 'Kaurna' },
};
let langDirectoryPaths = fs.readdirSync(cldrMainDir);
langDirectoryPaths.forEach(code => {
let languagesPath = `${cldrMainDir}${code}/languages.json`;
if (!fs.existsSync(languagesPath)) return;
let languageObj = JSON.parse(fs.readFileSync(languagesPath, 'utf8')).main[code];
let identity = languageObj.identity;
// skip locale-specific languages
if (identity.letiant || identity.territory) return;
let info = {};
const script = identity.script;
if (script) {
referencedScripts.push(script);
info.base = identity.language;
info.script = script;
}
const nativeName = languageObj.localeDisplayNames.languages[code];
if (nativeName) {
info.nativeName = nativeName;
}
unordered[code] = info;
});
// CLDR locales don't cover all the languages people might want to use for iD tags,
// so also add the language names that we have English translations for
let englishNamesByCode = JSON.parse(fs.readFileSync(`${cldrMainDir}en/languages.json`, 'utf8')).main.en.localeDisplayNames.languages;
Object.keys(englishNamesByCode).forEach(code => {
if (code in unordered) return;
if (code.indexOf('-') !== -1) return;
if (codesToSkip.indexOf(code) !== -1) return;
unordered[code] = {};
});
// delete codes which should not be used
delete unordered['pa-Arab']; // https://github.com/openstreetmap/iD/pull/9241/
delete unordered['pa-Guru']; // - " -
let ordered = {};
Object.keys(unordered).sort().forEach(key => ordered[key] = unordered[key]);
return ordered;
}
const langNamesInNativeLang = getLangNamesInNativeLang();
exports.langNamesInNativeLang = langNamesInNativeLang;
exports.languageNamesInLanguageOf = function(code) {
if (rematchCodes[code]) code = rematchCodes[code];
let languageFilePath = `${cldrMainDir}${code}/languages.json`;
if (!fs.existsSync(languageFilePath)) return null;
let translatedLangsByCode = JSON.parse(fs.readFileSync(languageFilePath, 'utf8')).main[code].localeDisplayNames.languages;
// ignore codes for non-languages
codesToSkip.forEach(skipCode => {
delete translatedLangsByCode[skipCode];
});
for (let langCode in translatedLangsByCode) {
let altLongIndex = langCode.indexOf('-alt-long');
if (altLongIndex !== -1) { // prefer long names (e.g. Chinese -> Mandarin Chinese)
let base = langCode.substring(0, altLongIndex);
translatedLangsByCode[base] = translatedLangsByCode[langCode];
}
if (langCode.includes('-alt-')) {
// remove alternative names
delete translatedLangsByCode[langCode];
} else if (langCode === translatedLangsByCode[langCode]) {
// no localized value available
delete translatedLangsByCode[langCode];
} else if (!langNamesInNativeLang[langCode]){
// we don't need to include language names that we probably won't be showing in the UI
delete translatedLangsByCode[langCode];
}
}
return translatedLangsByCode;
};
exports.scriptNamesInLanguageOf = function(code) {
if (rematchCodes[code]) code = rematchCodes[code];
let languageFilePath = `${cldrMainDir}${code}/scripts.json`;
if (!fs.existsSync(languageFilePath)) return null;
let allTranslatedScriptsByCode = JSON.parse(fs.readFileSync(languageFilePath, 'utf8')).main[code].localeDisplayNames.scripts;
let translatedScripts = {};
referencedScripts.forEach(script => {
if (!allTranslatedScriptsByCode[script] || script === allTranslatedScriptsByCode[script]) return;
translatedScripts[script] = allTranslatedScriptsByCode[script];
});
return translatedScripts;
};