80 lines
2.5 KiB
Text
80 lines
2.5 KiB
Text
# translate.ludic - what the game draws, in the language in use: a key (keyed_render.ludic); else, the old
|
|
# English form, exact, else a pattern, else padding taken off, else a paragraph a sentence at a time
|
|
export function L(i18n_st: mut I18nState, s: string) -> string {
|
|
if i18n_is_key(s) { return keyed(i18n_st, s) }
|
|
if not i18n_st.on { return s }
|
|
let ci = Dict.get_or(i18n_st.cache, s, -1)
|
|
if ci >= 0 { return i18n_st.cache_out[ci] }
|
|
let r = whole(i18n_st, s)
|
|
if Dict.size(i18n_st.cache) >= CACHE_MAX {
|
|
Dict.clear(i18n_st.cache)
|
|
List.clear(i18n_st.cache_out)
|
|
}
|
|
@alloc_ok("a translation cache miss: the entry is kept, up to CACHE_MAX")
|
|
Dict.set(i18n_st.cache, s, len(i18n_st.cache_out))
|
|
@alloc_ok("a translation cache miss: as above")
|
|
push(i18n_st.cache_out, r)
|
|
return r
|
|
}
|
|
|
|
@alloc_ok("a translation cache miss (L): once per distinct text, bounded by CACHE_MAX")
|
|
function whole(i18n_st: mut I18nState, s: string) -> string {
|
|
let n = len(s)
|
|
if n == 0 { return s }
|
|
let e = Dict.get_or(i18n_st.exact, s, -1)
|
|
if e >= 0 { return i18n_st.out[e] }
|
|
let r = pattern(i18n_st, s, 0)
|
|
if i18n_st.hit { return r }
|
|
# the padding a layout put round a word: " owned"
|
|
var a = 0
|
|
var b = n
|
|
while a < n and s[a] == 32 { a += 1 }
|
|
while b > a and s[b - 1] == 32 { b -= 1 }
|
|
if a > 0 or b < n {
|
|
if b <= a { return s }
|
|
let core: string = s[a..b]
|
|
let t = whole(i18n_st, core)
|
|
if t == core { return s }
|
|
return s[0..a] + t + s[b..n]
|
|
}
|
|
return sentences(i18n_st, s)
|
|
}
|
|
|
|
# a paragraph built from sentences, one at a time; English stays where a sentence is unknown
|
|
@alloc_ok("a translation cache miss (L): once per distinct text")
|
|
function sentences(i18n_st: mut I18nState, s: string) -> string {
|
|
let n = len(s)
|
|
var r = ""
|
|
var start = 0
|
|
var any = false
|
|
var pieces = 0
|
|
var i = 0
|
|
while i < n - 1 {
|
|
let c = s[i]
|
|
if (c == 46 or c == 33 or c == 63) and s[i + 1] == 32 {
|
|
let t = sentence(i18n_st, s[start..i + 1])
|
|
if i18n_st.hit { any = true }
|
|
r = r + t + " "
|
|
start = i + 2
|
|
pieces += 1
|
|
i += 2
|
|
continue
|
|
}
|
|
i += 1
|
|
}
|
|
if pieces == 0 { return s }
|
|
let t = sentence(i18n_st, s[start..n])
|
|
if i18n_st.hit { any = true }
|
|
if not any { return s }
|
|
return r + t
|
|
}
|
|
|
|
function sentence(i18n_st: mut I18nState, p: string) -> string {
|
|
i18n_st.hit = false
|
|
let e = Dict.get_or(i18n_st.exact, p, -1)
|
|
if e >= 0 {
|
|
i18n_st.hit = true
|
|
return i18n_st.out[e]
|
|
}
|
|
return pattern(i18n_st, p, 0)
|
|
}
|