generate ts methods for translations

This commit is contained in:
Damien Elmes 2021-03-26 17:54:07 +10:00
parent 3d366d5264
commit 264b9204c0
2 changed files with 58 additions and 17 deletions

View file

@ -4,6 +4,7 @@
import json import json
import sys import sys
from typing import List from typing import List
from typing import List, Literal, TypedDict
import stringcase import stringcase
@ -11,6 +12,11 @@ strings_json, outfile = sys.argv[1:]
modules = json.load(open(strings_json)) modules = json.load(open(strings_json))
class Variable(TypedDict):
name: str
kind: Literal["Any", "Int", "String", "Float"]
def legacy_enum() -> str: def legacy_enum() -> str:
out = ["export enum LegacyEnum {"] out = ["export enum LegacyEnum {"]
for module in modules: for module in modules:
@ -25,39 +31,70 @@ def legacy_enum() -> str:
def methods() -> str: def methods() -> str:
out = [ out = [
"class AnkiTranslations:", "export class GeneratedTranslations {",
" def _translate(self, module: int, translation: int, args: Dict) -> str:", " translate(key: string, args?: Record<string, any>): string { return 'nyi' } ",
" raise Exception('not implemented')",
] ]
for module in modules: for module in modules:
for translation in module["translations"]: for translation in module["translations"]:
key = translation["key"].replace("-", "_") key = stringcase.camelcase(translation["key"].replace("-", "_"))
arg_types = get_arg_types(translation["variables"]) arg_types = get_arg_name_and_types(translation["variables"])
args = get_args(translation["variables"]) args = get_args(translation["variables"])
doc = translation["text"] doc = translation["text"]
out.append( out.append(
f""" f"""
def {key}(self, {arg_types}) -> str: /** {doc} */
r''' {doc} ''' {key}({arg_types}): string {{
return self._translate({module["index"]}, {translation["index"]}, {{{args}}}) return this.translate("{translation["key"]}"{args})
}}
""" """
) )
out.append("}")
return "\n".join(out) + "\n" return "\n".join(out) + "\n"
def get_arg_types(args: List[str]) -> str: def get_arg_name_and_types(args: List[Variable]) -> str:
return ", ".join([f"{stringcase.snakecase(arg)}: FluentVariable" for arg in args]) if not args:
return ""
else:
return (
"args: {"
+ ", ".join(
[f"{typescript_arg_name(arg)}: {arg_kind(arg)}" for arg in args]
)
+ "}"
)
def get_args(args: List[str]) -> str: def arg_kind(arg: Variable) -> str:
return ", ".join([f'"{arg}": {stringcase.snakecase(arg)}' for arg in args]) if arg["kind"] in ("Int", "Float"):
return "number"
elif arg["kind"] == "Any":
return "number | string"
else:
return "string"
def get_args(args: List[Variable]) -> str:
if not args:
return ""
else:
return ", args"
def typescript_arg_name(arg: Variable) -> str:
name = stringcase.camelcase(arg["name"])
if name == "new":
return "new_"
else:
return name
out = "" out = ""
out += legacy_enum() out += legacy_enum()
# out += methods() out += methods()
open(outfile, "wb").write( open(outfile, "wb").write(

View file

@ -3,7 +3,7 @@
import "intl-pluralrules"; import "intl-pluralrules";
import { FluentBundle, FluentResource, FluentNumber } from "@fluent/bundle/compat"; import { FluentBundle, FluentResource, FluentNumber } from "@fluent/bundle/compat";
import { LegacyEnum } from "./i18n_generated"; import { LegacyEnum, GeneratedTranslations } from "anki/i18n_generated";
type RecordVal = number | string | FluentNumber; type RecordVal = number | string | FluentNumber;
@ -20,14 +20,13 @@ function formatNumbers(args?: Record<string, RecordVal>): void {
} }
} }
export class I18n { export class I18n extends GeneratedTranslations {
bundles: FluentBundle[] = []; bundles: FluentBundle[] = [];
langs: string[] = []; langs: string[] = [];
TR = LegacyEnum; TR = LegacyEnum;
tr(id: LegacyEnum, args?: Record<string, RecordVal>): string { translate(key: string, args: Record<string, RecordVal>): string {
formatNumbers(args); formatNumbers(args);
const key = this.keyName(id);
for (const bundle of this.bundles) { for (const bundle of this.bundles) {
const msg = bundle.getMessage(key); const msg = bundle.getMessage(key);
if (msg && msg.value) { if (msg && msg.value) {
@ -37,6 +36,11 @@ export class I18n {
return `missing key: ${key}`; return `missing key: ${key}`;
} }
tr(id: LegacyEnum, args?: Record<string, RecordVal>): string {
const key = this.keyName(id);
return this.translate(key, args || {});
}
supportsVerticalText(): boolean { supportsVerticalText(): boolean {
const firstLang = this.bundles[0].locales[0]; const firstLang = this.bundles[0].locales[0];
return ( return (