diff --git a/ts/lib/genfluent.py b/ts/lib/genfluent.py index e13bd61a8..89fe05318 100644 --- a/ts/lib/genfluent.py +++ b/ts/lib/genfluent.py @@ -4,6 +4,7 @@ import json import sys from typing import List +from typing import List, Literal, TypedDict import stringcase @@ -11,6 +12,11 @@ strings_json, outfile = sys.argv[1:] modules = json.load(open(strings_json)) +class Variable(TypedDict): + name: str + kind: Literal["Any", "Int", "String", "Float"] + + def legacy_enum() -> str: out = ["export enum LegacyEnum {"] for module in modules: @@ -25,39 +31,70 @@ def legacy_enum() -> str: def methods() -> str: out = [ - "class AnkiTranslations:", - " def _translate(self, module: int, translation: int, args: Dict) -> str:", - " raise Exception('not implemented')", + "export class GeneratedTranslations {", + " translate(key: string, args?: Record): string { return 'nyi' } ", ] for module in modules: for translation in module["translations"]: - key = translation["key"].replace("-", "_") - arg_types = get_arg_types(translation["variables"]) + key = stringcase.camelcase(translation["key"].replace("-", "_")) + arg_types = get_arg_name_and_types(translation["variables"]) args = get_args(translation["variables"]) doc = translation["text"] out.append( f""" - def {key}(self, {arg_types}) -> str: - r''' {doc} ''' - return self._translate({module["index"]}, {translation["index"]}, {{{args}}}) + /** {doc} */ + {key}({arg_types}): string {{ + return this.translate("{translation["key"]}"{args}) + }} """ ) + out.append("}") + return "\n".join(out) + "\n" -def get_arg_types(args: List[str]) -> str: - return ", ".join([f"{stringcase.snakecase(arg)}: FluentVariable" for arg in args]) +def get_arg_name_and_types(args: List[Variable]) -> str: + 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: - return ", ".join([f'"{arg}": {stringcase.snakecase(arg)}' for arg in args]) +def arg_kind(arg: Variable) -> str: + 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 += legacy_enum() -# out += methods() +out += methods() open(outfile, "wb").write( diff --git a/ts/lib/i18n.ts b/ts/lib/i18n.ts index aca9e6d9d..eea12ce81 100644 --- a/ts/lib/i18n.ts +++ b/ts/lib/i18n.ts @@ -3,7 +3,7 @@ import "intl-pluralrules"; 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; @@ -20,14 +20,13 @@ function formatNumbers(args?: Record): void { } } -export class I18n { +export class I18n extends GeneratedTranslations { bundles: FluentBundle[] = []; langs: string[] = []; TR = LegacyEnum; - tr(id: LegacyEnum, args?: Record): string { + translate(key: string, args: Record): string { formatNumbers(args); - const key = this.keyName(id); for (const bundle of this.bundles) { const msg = bundle.getMessage(key); if (msg && msg.value) { @@ -37,6 +36,11 @@ export class I18n { return `missing key: ${key}`; } + tr(id: LegacyEnum, args?: Record): string { + const key = this.keyName(id); + return this.translate(key, args || {}); + } + supportsVerticalText(): boolean { const firstLang = this.bundles[0].locales[0]; return (