overleaf/services/web/scripts/translations/translateLocales.js
Jakob Ackermann 9b6dfef590 Merge pull request #13909 from overleaf/jpa-i18n-script-tweaks
[web] scripts: translateLocales: tweaks

GitOrigin-RevId: 79deb3ccae9c55ab71b0e8f44fe08f240c9f695f
2023-07-18 08:04:49 +00:00

115 lines
3.2 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.

const yargs = require('yargs/yargs')
const { hideBin } = require('yargs/helpers')
const Path = require('path')
const fs = require('fs')
const LOCALES = Path.join(__dirname, '../../locales')
const VALID_LOCALES = Object.keys(
require('../../config/settings.defaults').translatedLanguages
).filter(locale => locale !== 'en')
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
})
const argv = yargs(hideBin(process.argv))
.usage('Translate locales')
.option('locale', {
alias: 'l',
type: 'string',
required: 'true',
description: 'Target 2-letter locale code',
choices: VALID_LOCALES,
})
.option('skip-until', {
type: 'string',
description: 'Skip locales until after the provided key',
})
.parse()
async function translateLocales() {
let { locale, skip } = argv
console.log(`Looking for missing [${locale}] translations...`)
const keysToUploadFolder = Path.join(__dirname, `translated-keys-to-upload`)
if (!fs.existsSync(keysToUploadFolder)) {
fs.mkdirSync(keysToUploadFolder)
}
const localeKeysToUploadPath = Path.join(keysToUploadFolder, `${locale}.json`)
const keysToUpload = fs.existsSync(localeKeysToUploadPath)
? JSON.parse(fs.readFileSync(localeKeysToUploadPath, 'utf-8'))
: []
const englishTranslations = await loadTranslations('en')
const englishKeys = Object.keys(englishTranslations)
const localeTranslations = await loadTranslations(locale)
const translatedKeys = Object.keys(localeTranslations)
console.log(
`Currently translated: ${translatedKeys.length} / ${englishKeys.length}`
)
for (const key of englishKeys) {
if (skip) {
if (key === skip) skip = ''
continue
}
const translation = localeTranslations[key]
if (!translation || translation.length === 0) {
let value = await prompt(
`\nMissing translation for: ${key}\n"${englishTranslations[key]}"\n`
)
while (value.includes("'")) {
value = await prompt(
`\nTranslations should not contain single-quote characters, please use curvy quotes ( or ) instead:\n`
)
}
if (!value) {
console.log(`Skipping ${key}`)
continue
}
localeTranslations[key] = value
const path = Path.join(LOCALES, `${locale}.json`)
const sorted =
JSON.stringify(
localeTranslations,
Object.keys(localeTranslations).sort(),
2
) + '\n'
fs.writeFileSync(path, sorted)
keysToUpload.push(key)
const formattedKeysToUpload =
JSON.stringify(Array.from(new Set(keysToUpload)), null, 2) + '\n'
await fs.writeFileSync(localeKeysToUploadPath, formattedKeysToUpload)
console.log(`"${key}": "${value}" added to ${locale}.json`)
}
}
}
async function loadTranslations(locale) {
return JSON.parse(
fs.readFileSync(Path.join(LOCALES, `${locale}.json`), 'utf-8')
)
}
function prompt(text) {
return new Promise((resolve, reject) =>
readline.question(text, value => {
resolve(value)
})
)
}
translateLocales()
.then(() => {
process.exit(0)
})
.catch(error => {
console.error(error)
process.exit(1)
})