-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtr-format.ts
91 lines (68 loc) · 3.16 KB
/
tr-format.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { readFile, writeFile } from "node:fs/promises";
import k from "kleur";
import type { TrLocale } from "../utils/index.js";
import locales from "../../assets/locales.json" with { type: "json" };
const prepTranslate = process.argv.find((v) => v.match(/--prep(are)?/) || v.toLowerCase() === "-p");
const onlyLocalesRaw = process.argv.find((v) => v.startsWith("--only") || v.toLowerCase().startsWith("-o"));
const onlyLocales = onlyLocalesRaw?.split("=")[1]?.replace(/"/g, "")
?.replace(/\s/g, "")?.split(",") as TrLocale[] | undefined;
const includeBased = Boolean(process.argv.find((v) => v.match(/--include-based/) || v.toLowerCase() === "-b"));
async function run() {
console.log("\nReformatting translation files...");
const enUS = await readFile("./assets/translations/en-US.json", "utf-8");
const enUS_obj = JSON.parse(enUS);
const localeKeysRaw = Object.keys(locales) as TrLocale[];
const localeKeys = localeKeysRaw.filter((key) => key !== "en-US") as Exclude<TrLocale, "en-US">[];
let reformattedAmt = 0;
for(const locale of localeKeys) {
if(onlyLocales && !onlyLocales.includes(locale))
continue;
// use en-US as base, replace values with values from locale file
let localeFile = enUS;
const localeObj = JSON.parse(await readFile(`./assets/translations/${locale}.json`, "utf-8"));
if(!includeBased && localeObj.base)
continue;
for(const k of Object.keys(enUS_obj.translations)) {
const val = localeObj?.translations?.[k];
if(val)
localeFile = localeFile.replace(new RegExp(`"${k}":\\s+".*"`, "m"), `"${k}": "${escapeJsonVal(val).trim()}"`);
else {
if(prepTranslate)
localeFile = localeFile.replace(new RegExp(`\\n\\s+"${k}":\\s+".*",?`, "m"), `\n "${k}": "",\n "${k}": "${escapeJsonVal(enUS_obj.translations[k]).trim()}",`);
else
localeFile = localeFile.replace(new RegExp(`\\n\\s+"${k}":\\s+".*",?`, "m"), "");
}
}
// remove last trailing comma if present
const pattern = /^\s*".*":\s+".*",?$/gm;
const matchesAmt = localeFile.match(pattern)?.length ?? 0;
let match: RegExpExecArray | null = null;
let i = 0;
while(match = pattern.exec(localeFile)) {
const part = localeFile.substring(match.index, pattern.lastIndex);
if(i === matchesAmt - 1) {
if(part.endsWith(","))
localeFile = localeFile.replace(part, part.substring(0, part.length - 1));
}
i++;
}
// reinsert base if present in locale file
if(localeObj.base)
localeFile = localeFile.replace(/\s*\{\s*/, `{\n "base": "${localeObj.base}",\n `);
// add EOL newline if not present
if(!localeFile.endsWith("\n"))
localeFile += "\n";
// overwrite original file
// (backup is available through git history so idc)
await writeFile(`./assets/translations/${locale}.json`, localeFile);
reformattedAmt++;
}
console.log(`\nDone reformatting ${k.green(reformattedAmt)} translation file${reformattedAmt === 1 ? "" : "s"}!\n`);
}
/** Escapes various characters for use as a JSON value */
function escapeJsonVal(val: string) {
return val
.replace(/\n/gm, "\\n")
.replace(/"/gm, "\\\"");
}
run();