diff --git a/packages/ludic.i18n/README.md b/packages/ludic.i18n/README.md index 38a989b4..24f4cdc6 100644 --- a/packages/ludic.i18n/README.md +++ b/packages/ludic.i18n/README.md @@ -75,7 +75,7 @@ port I18nWorld { | --- | --- | | `L(s) -> string` | what the game draws, in the language in use (cached) | | `Ln(one, many, n) -> string` | a count's form, with `{1}` the count; English is one for 1, many otherwise (the old form) | -| `tr(k)`, `trf(k, a, b, c, d)`, `trn(k, n, a, b, c) -> string` | a key, a key with its holes' arguments, a plural key by `n`: made into text by `L` | +| `tr(k: Key)`, `trf(k: Key, a, b, c, d)`, `trn(k: Key, n, a, b, c) -> string` | a key (`k"..."`), a key with its holes' arguments, a plural key (`kn"..."`) by `n`: made into text by `L` | | `i18n_key(name)`, `i18n_key_plural(name)`, `key_text(k)`, `i18n_is_key(s)` | a key named at run time, its name without the marker, whether a string is one | | `i18n_base_text(text)`, `i18n_loud(on)` | the base (en.po) from text, for a test; a developer's build's loud missing key | | `i18n_init()`, `i18n_count()`, `i18n_index(code)`, `i18n_code_at(i)`, `i18n_name_at(i)`, `i18n_font_at(i)`, `i18n_mod_dir()` | the languages found, "en" first | diff --git a/packages/ludic.i18n/keys.ludic b/packages/ludic.i18n/keys.ludic index 91022f8b..6c4af390 100644 --- a/packages/ludic.i18n/keys.ludic +++ b/packages/ludic.i18n/keys.ludic @@ -1,6 +1,6 @@ -# keys.ludic - a key as the game carries it: its text behind a marker byte (the compiler's k"..." is -# exactly that), holes as byte 31 then each argument, a plural's count first. Nothing here needs the -# language: the text is made where it is drawn (L), so code that makes text never takes I18nState. +# keys.ludic - a key as the game carries it: the compiler's Key (k"..." is its text behind byte 1, kn"..." +# behind byte 2), made into a string with holes as byte 31 then each argument, a plural's count first. +# Nothing here needs the language: the text is made where it is drawn (L), never taking I18nState. export const I18N_KEY: int = 1 # k"pause.resume" is "\\x01pause.resume" export const I18N_PLURAL: int = 2 # kn"catch.count": a count chooses the form export const I18N_SEP: int = 31 # between the key and each argument @@ -22,16 +22,15 @@ export function key_text(k: string) -> string { return k[1..e] } -# the text of a key: drawn translated where it is drawn (a free cast once the key is typed) -export function tr(k: string) -> string { return k } +# the text of a key: drawn translated where it is drawn (its marked text, a free cast) +export function tr(k: Key) -> string { return string(k) } # a key's text with its holes, {1} .. {4}, filled by strings already made (a number, a name, another key) -export function trf(k: string, a: string, b: string, c: string, d: string) -> string { - var mark = I18N_KEY - if i18n_is_key(k) { mark = k[0] } - return kx_join(mark, key_text(k), a, b, c, d, kx_count(a, b, c, d)) +export function trf(k: Key, a: string, b: string, c: string, d: string) -> string { + let s = string(k) + return kx_join(I18N_KEY, key_text(s), a, b, c, d, kx_count(a, b, c, d)) } # a plural key's text by n: the count is {1}, a .. c are {2} .. {4} -export function trn(k: string, n: int, a: string, b: string, c: string) -> string { return kx_join(I18N_PLURAL, key_text(k), `{n}`, a, b, c, 1 + kx_count(a, b, c, "")) } +export function trn(k: Key, n: int, a: string, b: string, c: string) -> string { return kx_join(I18N_PLURAL, key_text(string(k)), `{n}`, a, b, c, 1 + kx_count(a, b, c, "")) } function kx_count(a: string, b: string, c: string, d: string) -> int { if len(d) > 0 { return 4 } diff --git a/packages/ludic.i18n/tests/keys_test.ludic b/packages/ludic.i18n/tests/keys_test.ludic index 5ed7de3e..a7be6db0 100644 --- a/packages/ludic.i18n/tests/keys_test.ludic +++ b/packages/ludic.i18n/tests/keys_test.ludic @@ -32,38 +32,38 @@ program I18nKeysTest { test "a key is its English under en.po, its own language's text when there is one, else English, else itself" (i18n_st: mut I18nState) { start (i18n_st) - expect(L(i18n_st, i18n_key("pause.resume")) == "Resume") - expect(L(i18n_st, tr(i18n_key("pause.quit"))) == "Quit") + expect(L(i18n_st, tr(k"pause.resume")) == "Resume") + expect(L(i18n_st, tr(k"pause.quit")) == "Quit") i18n_load_text(i18n_st, tt()) - expect(L(i18n_st, i18n_key("pause.resume")) == "Devam") + expect(L(i18n_st, tr(k"pause.resume")) == "Devam") expect(L(i18n_st, i18n_key("pause.quit")) == "Quit") # the language lacks it: English expect(L(i18n_st, i18n_key("nowhere.at_all")) == "nowhere.at_all") # en.po lacks it: the key i18n_loud(i18n_st, true) expect(L(i18n_st, i18n_key("nowhere.else")) == "[[nowhere.else]]") # a developer's build says so i18n_off(i18n_st) - expect(L(i18n_st, i18n_key("pause.resume")) == "Resume") # back to English: nothing stale kept + expect(L(i18n_st, tr(k"pause.resume")) == "Resume") # back to English: nothing stale kept } test "holes take their arguments in the language's order, and an argument that is a key is made first" (i18n_st: mut I18nState) { start (i18n_st) - expect(L(i18n_st, trf(i18n_key("hud.day"), "12", "", "", "")) == "Day 12") - let saw = trf(i18n_key("catch.saw"), i18n_key("species.elk.a_name"), "5:30", "", "") + expect(L(i18n_st, trf(k"hud.day", "12", "", "", "")) == "Day 12") + let saw = trf(k"catch.saw", tr(k"species.elk.a_name"), "5:30", "", "") expect(L(i18n_st, saw) == "You saw an elk at 5:30.") i18n_load_text(i18n_st, tt()) - expect(L(i18n_st, trf(i18n_key("hud.day"), "12", "", "", "")) == "12. Gun") + expect(L(i18n_st, trf(k"hud.day", "12", "", "", "")) == "12. Gun") expect(L(i18n_st, saw) == "5:30 saatinde bir geyik gordun.") - expect(L(i18n_st, trf(i18n_key("hud.day"), "", "", "", "")) == ". Gun") # a missing argument is empty + expect(L(i18n_st, trf(k"hud.day", "", "", "", "")) == ". Gun") # a missing argument is empty expect(key_text(saw) == "catch.saw" and key_text("Settings") == "Settings") } test "a plural key takes its form by the count, by each language's own rule, falling back to English's" (i18n_st: mut I18nState) { start (i18n_st) - expect(L(i18n_st, trn(i18n_key("pack.items"), 1, "", "", "")) == "1 item") - expect(L(i18n_st, trn(i18n_key("pack.items"), 3, "", "", "")) == "3 items") + expect(L(i18n_st, trn(kn"pack.items", 1, "", "", "")) == "1 item") + expect(L(i18n_st, trn(kn"pack.items", 3, "", "", "")) == "3 items") i18n_load_text(i18n_st, tt()) - expect(L(i18n_st, trn(i18n_key("pack.items"), 21, "", "", "")) == "21 esya") # n%10 == 1 - expect(L(i18n_st, trn(i18n_key("pack.items"), 5, "", "", "")) == "5 esyalar") - expect(L(i18n_st, trn(i18n_key("catch.count"), 2, "", "", "")) == "2 trout") # the language lacks it + expect(L(i18n_st, trn(kn"pack.items", 21, "", "", "")) == "21 esya") # n%10 == 1 + expect(L(i18n_st, trn(kn"pack.items", 5, "", "", "")) == "5 esyalar") + expect(L(i18n_st, trn(kn"catch.count", 2, "", "", "")) == "2 trout") # the language lacks it } test "the old English form still works beside keys, so a game can move over a file at a time" (i18n_st: mut I18nState) { @@ -71,7 +71,7 @@ program I18nKeysTest { expect(L(i18n_st, "Settings") == "Settings") i18n_load_text(i18n_st, tt()) expect(L(i18n_st, "Settings") == "Ayarlar") - expect(L(i18n_st, i18n_key("pause.resume")) == "Devam") + expect(L(i18n_st, tr(k"pause.resume")) == "Devam") expect(not i18n_is_key("Settings") and i18n_is_key(i18n_key("x")) and i18n_is_key(i18n_key_plural("x"))) } }