Auto-generate list of catalogs from PO files

Then auto-list them based on percentage threshold
This commit is contained in:
Lim Chee Aun 2024-08-19 10:52:56 +08:00
parent b286511f44
commit 8c02d336be
3 changed files with 159 additions and 9 deletions

60
scripts/catalogs.js Normal file
View file

@ -0,0 +1,60 @@
import fs from 'node:fs';
// Dependency from Lingui, not listed in package.json
import PO from 'pofile';
const DEFAULT_LANG = 'en';
const IGNORE_LANGS = [DEFAULT_LANG, 'pseudo-LOCALE'];
const files = fs.readdirSync('src/locales');
const catalogs = {};
const enCatalog = files.find((file) => file.endsWith('en.po'));
const enContent = fs.readFileSync(`src/locales/${enCatalog}`, 'utf8');
const enPo = PO.parse(enContent);
const total = enPo.items.length;
console.log('Total strings:', total);
files.forEach((file) => {
if (file.endsWith('.po')) {
const code = file.replace(/\.po$/, '');
if (IGNORE_LANGS.includes(code)) return;
const content = fs.readFileSync(`src/locales/${file}`, 'utf8');
const po = PO.parse(content);
const { items } = po;
// Percentage of translated strings
const translated = items.filter(
(item) => item.msgstr !== '' && item.msgstr[0] !== '',
).length;
const percentage = Math.round((translated / total) * 100);
po.percentage = percentage;
if (percentage > 0) {
// Ignore empty catalogs
catalogs[code] = percentage;
}
}
});
// Sort by percentage
const sortedCatalogs = Object.entries(catalogs)
.sort((a, b) => b[1] - a[1])
.map(([code, percentage]) => {
const name = new Intl.DisplayNames(['en'], { type: 'language' }).of(code);
return { code, name, percentage };
});
console.table(sortedCatalogs);
const path = 'src/data/catalogs.json';
fs.writeFileSync(
path,
JSON.stringify(
Object.entries(catalogs).map(([code, percentage]) => ({
code,
completion: percentage,
})),
null,
2,
),
);
console.log('File written:', path);

90
src/data/catalogs.json Normal file
View file

@ -0,0 +1,90 @@
[
{
"code": "ar-SA",
"completion": 22
},
{
"code": "ca-ES",
"completion": 99
},
{
"code": "cs-CZ",
"completion": 54
},
{
"code": "de-DE",
"completion": 99
},
{
"code": "eo-UY",
"completion": 15
},
{
"code": "es-ES",
"completion": 100
},
{
"code": "eu-ES",
"completion": 100
},
{
"code": "fa-IR",
"completion": 51
},
{
"code": "fi-FI",
"completion": 100
},
{
"code": "fr-FR",
"completion": 92
},
{
"code": "gl-ES",
"completion": 100
},
{
"code": "he-IL",
"completion": 11
},
{
"code": "it-IT",
"completion": 13
},
{
"code": "ja-JP",
"completion": 32
},
{
"code": "kab-KAB",
"completion": 33
},
{
"code": "ko-KR",
"completion": 76
},
{
"code": "lt-LT",
"completion": 25
},
{
"code": "nl-NL",
"completion": 49
},
{
"code": "ru-RU",
"completion": 24
},
{
"code": "th-TH",
"completion": 3
},
{
"code": "zh-CN",
"completion": 100
},
{
"code": "zh-TW",
"completion": 3
}
]

View file

@ -1,16 +1,16 @@
import catalogs from './data/catalogs.json';
export const DEFAULT_LANG = 'en';
export const CATALOGS = catalogs;
// Get locales that's >= X% translated
const PERCENTAGE_THRESHOLD = 50;
const locales = [
DEFAULT_LANG,
'zh-CN', // Chinese (Simplified)
'eu-ES', // Basque
'es-ES', // Spanish
'fi-FI', // Finnish
'gl-ES', // Galician
'de-DE', // German
'ca-ES', // Catalan
'fr-FR', // French
'ko-KR', // Korean
...catalogs
.filter(({ completion }) => completion >= PERCENTAGE_THRESHOLD)
.map(({ code }) => code),
];
if (import.meta.env.DEV) {
locales.push('pseudo-LOCALE');