Since the data's text became keys (26.4), a game's English patterns that take a table's name (Notify, txt_pat, a concatenation) drew the raw mark and key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.3 KiB
Text
69 lines
2.3 KiB
Text
# keyed_render.ludic - a marked string made into text where it is drawn: its key looked up (a plural's by
|
|
# its count), its holes filled with its arguments, each argument that is itself a key made first
|
|
|
|
# what L does with a key: made once per distinct marked string in this language, then kept
|
|
function keyed(i18n_st: mut I18nState, s: string) -> string {
|
|
if i18n_st.kc == null { kc_clear(i18n_st) }
|
|
let ci = Dict.get_or(i18n_st.kc, s, -1)
|
|
if ci >= 0 { return i18n_st.kc_out[ci] }
|
|
let r = kr_make(i18n_st, s)
|
|
if Dict.size(i18n_st.kc) >= CACHE_MAX { kc_clear(i18n_st) }
|
|
@alloc_ok("a key made into text: the result kept, up to CACHE_MAX")
|
|
Dict.set(i18n_st.kc, s, len(i18n_st.kc_out))
|
|
@alloc_ok("a key made into text: as above")
|
|
push(i18n_st.kc_out, r)
|
|
return r
|
|
}
|
|
|
|
# a language's change makes every kept text stale
|
|
@alloc_ok("on a language change: the made keys let go")
|
|
function kc_clear(i18n_st: mut I18nState) -> void {
|
|
i18n_st.kc = Dict.new()
|
|
i18n_st.kc_out = new []string
|
|
}
|
|
|
|
@alloc_ok("a key made into text (a cache miss): once per distinct marked string")
|
|
function kr_make(i18n_st: mut I18nState, s: string) -> string {
|
|
let args = new []string
|
|
var start = 1
|
|
var i = 1
|
|
while i <= len(s) {
|
|
if i < len(s) and s[i] == I18N_ESC {
|
|
i += 2 # an escaped byte belongs to its argument
|
|
continue
|
|
}
|
|
if i >= len(s) or s[i] == I18N_SEP {
|
|
var e = i
|
|
if e > len(s) { e = len(s) }
|
|
push(args, kr_unescape(s[start..e]))
|
|
start = i + 1
|
|
}
|
|
i += 1
|
|
}
|
|
let key = args[0]
|
|
var t = ""
|
|
if s[0] == I18N_PLURAL and len(args) > 1 { t = kb_plural(i18n_st, key, kr_int(args[1])) } else { t = kb_text(i18n_st, key) }
|
|
return kr_fill(i18n_st, t, args)
|
|
}
|
|
|
|
# {k} is argument k (args[0] is the key); a missing one is empty, a key is made into its own text
|
|
@alloc_ok("a key made into text (a cache miss): its holes filled")
|
|
function kr_fill(i18n_st: mut I18nState, t: string, args: []string) -> string {
|
|
var r = ""
|
|
var seg = 0
|
|
var i = 0
|
|
while i < len(t) {
|
|
let h = hole_at(t, i)
|
|
if h >= 1 {
|
|
var v = ""
|
|
if h < len(args) { v = args[h] }
|
|
if i18n_is_key(v) or kx_mixed(v) { v = L(i18n_st, v) } else if i18n_st.on and kr_words(v) { v = L(i18n_st, v) }
|
|
r = r + t[seg..i] + v
|
|
i = hole_end(t, i)
|
|
seg = i
|
|
continue
|
|
}
|
|
i += 1
|
|
}
|
|
return r + t[seg..len(t)]
|
|
}
|