parse country code for language out of i18n/lccc.json
This commit is contained in:
parent
e7cf57ec1b
commit
48d92ce963
|
@ -2,6 +2,8 @@
|
|||
|
||||
The easiets way to help translate the game is with weblate. Simply use [hosted.weblate.org/projects/pixelplanet](https://hosted.weblate.org/projects/pixelplanet/). Feel free to ask in the Translation section in [our Discord](https://pixelplanet.fun/guilded) if you need help.
|
||||
|
||||
If a language code differs from the country code of a wanted flag, it can be defined in the `i18n/lccc.json` file. In example `{ "en": "gb" }` maps the english language to the flag of Great Britain.
|
||||
|
||||
[![Translation status](https://hosted.weblate.org/widget/pixelplanet/open-graph.png)](https://hosted.weblate.org/engage/pixelplanet/)
|
||||
|
||||
# Translating Offline
|
||||
|
@ -12,8 +14,6 @@ Translation files can be created out of the templates [template.pot](https://git
|
|||
|
||||
All translated languages get an own chat channel that just people who use this language can access.
|
||||
|
||||
If a language code differs from the country code of a wanted flag, it can be defined in the ssr filename, like `ssr-en-gb.po` would be the english language, with the flag of Great Britain.
|
||||
|
||||
## With poedit
|
||||
|
||||
### Create new translation
|
||||
|
|
104
scripts/build.js
104
scripts/build.js
|
@ -5,13 +5,13 @@
|
|||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const readline = require('readline');
|
||||
const { spawn } = require('child_process');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const minifyCss = require('./minifyCss');
|
||||
const serverConfig = require('../webpack.config.server.js');
|
||||
const clientConfig = require('../webpack.config.client.js');
|
||||
const { getAllAvailableLocals } = clientConfig;
|
||||
|
||||
let langs = 'all';
|
||||
let doBuildServer = false;
|
||||
|
@ -46,6 +46,88 @@ if (!doBuildServer && !doBuildClient) {
|
|||
doBuildClient = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* get available locals based on the files available in ../i18n
|
||||
*/
|
||||
function getAllAvailableLocals() {
|
||||
const langDir = path.resolve(__dirname, '..', 'i18n');
|
||||
const langs = fs.readdirSync(langDir)
|
||||
.filter((e) => (e.endsWith('.po') && !e.startsWith('ssr')))
|
||||
.map((l) => l.slice(0, -3));
|
||||
langs.unshift('en');
|
||||
return langs;
|
||||
}
|
||||
|
||||
/*
|
||||
* get amount of msgid and msgstr of po file
|
||||
*/
|
||||
function getPoFileStats(file) {
|
||||
return new Promise((resolve) => {
|
||||
const fileStream = fs.createReadStream(file);
|
||||
const lineReader = readline.createInterface({
|
||||
input: fileStream,
|
||||
crlfDelay: Infinity,
|
||||
});
|
||||
|
||||
let msgid = 0;
|
||||
let msgstr = 0;
|
||||
|
||||
lineReader.on('line', (l) => {
|
||||
l = l.trim();
|
||||
if (l.endsWith('""')) {
|
||||
return;
|
||||
}
|
||||
let seperator = l.indexOf(' ');
|
||||
if (seperator === -1) {
|
||||
seperator = l.indexOf('\t');
|
||||
}
|
||||
if (seperator === -1) {
|
||||
return;
|
||||
}
|
||||
const tag = l.substring(0, seperator);
|
||||
if (tag === 'msgid') {
|
||||
msgid += 1;
|
||||
} else if (tag === 'msgstr') {
|
||||
msgstr += 1;
|
||||
}
|
||||
});
|
||||
|
||||
lineReader.on('close', (l) => {
|
||||
resolve({ msgid, msgstr });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function filterLackingLocals(langs, percentage) {
|
||||
langs = langs.filter((l) => l !== 'en');
|
||||
const promises = [];
|
||||
const { msgid, msgstr } = await getPoFileStats(path.resolve(
|
||||
__dirname, '..', 'i18n', `template.pot`,
|
||||
));
|
||||
|
||||
const langStats = await Promise.all(langs
|
||||
.map((l) => getPoFileStats(
|
||||
path.resolve(__dirname, '..', 'i18n', `${l}.po`),
|
||||
)));
|
||||
const goodLangs = [ 'en' ];
|
||||
const badLangs = [];
|
||||
for (let i = 0; i < langs.length; i += 1) {
|
||||
const lang = langs[i];
|
||||
const stats = langStats[i];
|
||||
const percent = Math.floor(stats.msgstr / msgid * 100);
|
||||
if (percent >= percentage) {
|
||||
goodLangs.push(lang);
|
||||
} else {
|
||||
console.log(`Lang ${lang} completion:`, percent, '%');
|
||||
badLangs.push(lang);
|
||||
}
|
||||
}
|
||||
return {
|
||||
goodLangs,
|
||||
badLangs,
|
||||
};
|
||||
}
|
||||
|
||||
function compile(webpackConfig) {
|
||||
return new Promise((resolve, reject) => {
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
|
@ -156,13 +238,23 @@ async function buildProduction() {
|
|||
if (langs !== 'all') {
|
||||
avlangs = langs.split(',').map((l) => l.trim())
|
||||
.filter((l) => avlangs.includes(l));
|
||||
if (!avlangs.length) {
|
||||
console.error(`ERROR: language ${langs} not available`);
|
||||
process.exit(1);
|
||||
return;
|
||||
} else {
|
||||
const { avlangs: goodLangs, badLangs } = await filterLackingLocals(avlangs, 50);
|
||||
if (badLangs.length) {
|
||||
console.log(
|
||||
'Skipping',
|
||||
badLangs.length,
|
||||
'locals because of low completition:',
|
||||
badLangs,
|
||||
);
|
||||
}
|
||||
}
|
||||
console.log('Building locales:', avlangs);
|
||||
if (!avlangs.length) {
|
||||
console.error(`ERROR: language ${langs} not available`);
|
||||
process.exit(1);
|
||||
return;
|
||||
}
|
||||
console.log('Building', avlangs.length, 'locales:', avlangs);
|
||||
|
||||
const promises = [];
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import cookie from 'cookie';
|
|||
|
||||
import assetWatcher from './fsWatcher';
|
||||
import { getLangsOfJsAsset } from './assets';
|
||||
import lccc from '../../i18n/lccc.json';
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
const localeImports = require.context('../../i18n', false, /^\.[/\\]ssr-.+\.po$/);
|
||||
|
@ -32,16 +33,11 @@ function loadTtags() {
|
|||
const file = langs[i];
|
||||
// ./ssr-de.po
|
||||
let lang = file.replace('./ssr-', '').replace('.po', '').toLowerCase();
|
||||
let flag = lang;
|
||||
/*
|
||||
* in cases where the language code and country code differ,
|
||||
* the country code can be given seperately in the file name
|
||||
* i.e.: ./ssr-en-gb.po
|
||||
* In cases where the language code and country code differ,
|
||||
* it can be mapped in i18n/lccc.json
|
||||
*/
|
||||
const seperator = lang.indexOf('-');
|
||||
if (seperator !== -1) {
|
||||
[lang, flag] = lang.split('-');
|
||||
}
|
||||
let flag = lccc[lang] || lang;
|
||||
if (jsLangs.includes(lang)) {
|
||||
if (!ttags[lang]) {
|
||||
const ttag = new TTag();
|
||||
|
|
|
@ -183,13 +183,3 @@ module.exports = ({
|
|||
};
|
||||
}
|
||||
|
||||
function getAllAvailableLocals() {
|
||||
const langDir = path.resolve('i18n');
|
||||
const langs = fs.readdirSync(langDir)
|
||||
.filter((e) => (e.endsWith('.po') && !e.startsWith('ssr')))
|
||||
.map((l) => l.slice(0, -3));
|
||||
langs.unshift('en');
|
||||
return langs;
|
||||
}
|
||||
|
||||
module.exports.getAllAvailableLocals = getAllAvailableLocals;
|
||||
|
|
Loading…
Reference in New Issue