mirror of
https://github.com/ankitects/anki.git
synced 2025-09-20 15:02:21 -04:00
generate ts methods for translations
This commit is contained in:
parent
3d366d5264
commit
264b9204c0
2 changed files with 58 additions and 17 deletions
|
@ -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(
|
||||||
|
|
|
@ -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 (
|
||||||
|
|
Loading…
Reference in a new issue