summaryrefslogtreecommitdiff
path: root/packages/pogen/src/po2ts.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/pogen/src/po2ts.ts')
-rw-r--r--packages/pogen/src/po2ts.ts104
1 files changed, 92 insertions, 12 deletions
diff --git a/packages/pogen/src/po2ts.ts b/packages/pogen/src/po2ts.ts
index 7e831e6f8..0b5b1384d 100644
--- a/packages/pogen/src/po2ts.ts
+++ b/packages/pogen/src/po2ts.ts
@@ -19,11 +19,54 @@
*/
// @ts-ignore
-import * as po2json from "po2json";
+import * as po2jsonLib from "po2json";
import * as fs from "fs";
-import * as path from "path";
import glob = require("glob");
+//types defined by the po2json library
+type Header = {
+ domain: string;
+ lang: string;
+ 'plural_forms': string;
+};
+
+type MessagesType = Record<string, undefined | Array<string>> & { "": Header }
+interface pojsonType {
+ // X-Domain or 'messages'
+ domain: string;
+ locale_data: {
+ messages: MessagesType
+ }
+}
+// ----------- end pf po2json
+
+interface StringsType {
+ // X-Domain or 'messages'
+ domain: string;
+ lang: string;
+ completeness: number,
+ 'plural_forms': string;
+ locale_data: {
+ messages: Record<string, undefined | Array<string>>
+ }
+}
+
+// This prelude match the types above
+const TYPES_FOR_STRING_PRELUDE = `
+export interface StringsType {
+ domain: string;
+ lang: string;
+ completeness: number;
+ 'plural_forms': string;
+ locale_data: {
+ messages: Record<string, unknown>;
+ };
+};
+`;
+
+const DEFAULT_STRING_PRELUDE = `${TYPES_FOR_STRING_PRELUDE}export const strings: Record<string,StringsType> = {};\n\n`
+
+
export function po2ts(): void {
const files = glob.sync("src/i18n/*.po");
@@ -34,9 +77,14 @@ export function po2ts(): void {
console.log(files);
- const chunks: string[] = [
- "export const strings: any = {};\n\n"
- ];
+ let prelude: string;
+ try {
+ prelude = fs.readFileSync("src/i18n/strings-prelude", "utf-8")
+ } catch (e) {
+ prelude = DEFAULT_STRING_PRELUDE
+ }
+
+ const chunks = [prelude];
for (const filename of files) {
const m = filename.match(/([a-zA-Z0-9-_]+).po/);
@@ -47,16 +95,26 @@ export function po2ts(): void {
}
const lang = m[1];
- const pojson = po2json.parseFileSync(filename, {
+ const poAsJson: pojsonType = po2jsonLib.parseFileSync(filename, {
format: "jed1.x",
fuzzy: true,
});
- const s =
- "strings['" +
- lang +
- "'] = " +
- JSON.stringify(pojson, null, " ") +
- ";\n\n";
+ const header = poAsJson.locale_data.messages[""]
+ const total = calculateTotalTranslations(poAsJson.locale_data.messages)
+ const completeness =
+ header.lang === "en"
+ ? 100 // 'en' is always complete
+ : Math.floor(total.translations * 100 / total.keys);
+
+ const strings: StringsType = {
+ locale_data: poAsJson.locale_data,
+ domain: poAsJson.domain,
+ plural_forms: header.plural_forms,
+ lang: header.lang,
+ completeness,
+ }
+ const value = JSON.stringify(strings, undefined, 2)
+ const s = `strings['${lang}'] = ${value};\n\n`
chunks.push(s);
}
@@ -64,3 +122,25 @@ export function po2ts(): void {
fs.writeFileSync("src/i18n/strings.ts", tsContents);
}
+
+function calculateTotalTranslations(msgs: MessagesType): { keys: number, translations: number } {
+ const kv = Object.entries(msgs)
+ const [keys, translations] = kv.reduce(([total, withTranslation], translation) => {
+ if (!translation || translation.length !== 2 || !translation[1]) {
+ //current key is empty
+ return [total, withTranslation]
+ }
+ const v = translation[1]
+ if (!Array.isArray(v)) {
+ // this is not a translation
+ return [total, withTranslation]
+ }
+ if (!v.length || !v[0].length) {
+ //translation is missing
+ return [total + 1, withTranslation]
+ }
+ //current key has a translation
+ return [total + 1, withTranslation + 1]
+ }, [0, 0])
+ return { keys, translations }
+} \ No newline at end of file