mirror of
https://github.com/lichess-org/lila.git
synced 2026-05-26 13:51:00 +00:00
107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
import { XMLParser } from 'fast-xml-parser';
|
|
import { readdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
interface TranslationXml {
|
|
'?xml': {
|
|
version: string;
|
|
encoding: string;
|
|
};
|
|
resources: {
|
|
string?: {
|
|
name: string;
|
|
text: string;
|
|
comment?: string;
|
|
}[];
|
|
plurals?: {
|
|
name: string;
|
|
text: string;
|
|
comment?: string;
|
|
item: {
|
|
quantity: 'one' | 'other';
|
|
text: string;
|
|
}[];
|
|
}[];
|
|
};
|
|
}
|
|
|
|
interface KeyList {
|
|
name: string;
|
|
code: string;
|
|
}
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const lilaDir = path.resolve(path.dirname(__filename), '..');
|
|
const baseDir = path.resolve(lilaDir, 'translation/source');
|
|
|
|
const xmls = readdirSync(baseDir)
|
|
.filter(f => f.endsWith('.xml'))
|
|
.map(f => f.replace(/\.xml$/, ''));
|
|
|
|
function convertObjectName(name: string) {
|
|
const renames = new Map([['class', 'clas']]);
|
|
|
|
return renames.get(name) || name;
|
|
}
|
|
|
|
function keyListFrom(name: string): KeyList {
|
|
const txt = readFileSync(path.resolve(baseDir, `${name}.xml`), 'utf-8');
|
|
const parser = new XMLParser({
|
|
ignoreAttributes: false,
|
|
isArray: tagName => ['string', 'plurals', 'item'].includes(tagName),
|
|
attributeNamePrefix: '',
|
|
textNodeName: 'text',
|
|
});
|
|
const xml: TranslationXml = parser.parse(txt);
|
|
|
|
const keys = [
|
|
...(xml.resources.string || []).map(e => e.name),
|
|
...(xml.resources.plurals || []).map(e => e.name),
|
|
];
|
|
const indent = ' '.repeat(4);
|
|
|
|
return {
|
|
name,
|
|
code:
|
|
keys
|
|
.map(k => `${indent}val \`${k}\`: I18nKey = "${name === 'site' ? '' : name + ':'}${k}"`)
|
|
.join('\n') + '\n',
|
|
};
|
|
}
|
|
|
|
const dbCode = (obj: KeyList) => ` object ${convertObjectName(obj.name)}:\n${obj.code}`;
|
|
|
|
const objs = xmls.map(keyListFrom);
|
|
const code = `// Generated with bin/i18n-file-gen.ts
|
|
package lila.core.i18n
|
|
|
|
opaque type I18nKey = String
|
|
object I18nKey:
|
|
def apply(key: String): I18nKey = key
|
|
import scalatags.Text.RawFrag
|
|
extension (key: I18nKey)
|
|
def value: String = key
|
|
def txt(args: Any*)(using trans: Translate): String =
|
|
trans.translator.txt.literal(key, args, trans.lang)
|
|
def pluralTxt(count: Count, args: Any*)(using trans: Translate): String =
|
|
trans.translator.txt.plural(key, count, args, trans.lang)
|
|
def pluralSameTxt(count: Long)(using Translate): String = pluralTxt(count, count)
|
|
def apply(args: Matchable*)(using trans: Translate): RawFrag =
|
|
trans.translator.frag.literal(key, args, trans.lang)
|
|
def plural(count: Count, args: Matchable*)(using trans: Translate): RawFrag =
|
|
trans.translator.frag.plural(key, count, args, trans.lang)
|
|
def pluralSame(count: Int)(using Translate): RawFrag = plural(count, count)
|
|
// the translated message contains HTML tags
|
|
def rawHtml(args: Any*)(using Translate): RawFrag = RawFrag(txt(args*))
|
|
def pluralRawHtml(count: Count, args: Any*)(using Translate): RawFrag = RawFrag(pluralTxt(count, args*))
|
|
|
|
// format: OFF
|
|
${objs.map(dbCode).join('\n')}
|
|
`;
|
|
|
|
const keyFile = path.resolve(lilaDir, 'modules/coreI18n/src/main/key.scala');
|
|
writeFileSync(keyFile, code);
|
|
|
|
console.log(`✅ Wrote ${keyFile}`);
|