mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-12 08:07:37 -05:00
9b6dfef590
[web] scripts: translateLocales: tweaks GitOrigin-RevId: 79deb3ccae9c55ab71b0e8f44fe08f240c9f695f
115 lines
3.2 KiB
JavaScript
115 lines
3.2 KiB
JavaScript
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)
|
||
})
|