overleaf/services/web/scripts/translations/translateLocales.js
Liangjun Song 8293771f58 Merge pull request #21290 from overleaf/ls-scripts-to-esm-translations
Migrate scripts/translation to esm

GitOrigin-RevId: 475ec949f0ba238791df91de109169584e68c701
2024-10-25 08:06:12 +00:00

113 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.

import yargs from 'yargs/yargs'
import { hideBin } from 'yargs/helpers'
import Path from 'path'
import fs from 'fs'
import { fileURLToPath } from 'url'
import Settings from '../../config/settings.defaults.js'
import Readline from 'readline'
import { loadLocale as loadTranslations } from './utils.js'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
const LOCALES = Path.join(__dirname, '../../locales')
const VALID_LOCALES = Object.keys(Settings.translatedLanguages).filter(
locale => locale !== 'en'
)
const readline = 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'
fs.writeFileSync(localeKeysToUploadPath, formattedKeysToUpload)
console.log(`"${key}": "${value}" added to ${locale}.json`)
}
}
}
function prompt(text) {
return new Promise((resolve, reject) =>
readline.question(text, value => {
resolve(value)
})
)
}
try {
await translateLocales()
process.exit(0)
} catch (error) {
console.error(error)
process.exit(1)
}