# plural.ludic - msgid_plural / msgstr[k], chosen by the file's Plural-Forms. The rules a game meets # are named rather than evaluated: one form, n != 1, n > 1 and the three East Slavic forms export const PL_NOT_ONE: int = 0 # English, German, Turkish as most files write it export const PL_ABOVE_ONE: int = 1 # French, Portuguese (0 and 1 are singular) export const PL_ONE_FORM: int = 2 # Japanese, Chinese export const PL_SLAVIC: int = 3 # Russian, Ukrainian: one, few, many @alloc_ok("on a language change: its plural rule read from the header") function plural_rule_of(h: string) -> int { let k = i18n_find(h, len(h), 0, "plural=", 7) if k < 0 { return PL_NOT_ONE } let e: string = h[k + 7..len(h)] if i18n_find(e, len(e), 0, "n%10", 4) >= 0 or i18n_find(e, len(e), 0, "n % 10", 6) >= 0 { return PL_SLAVIC } if i18n_find(e, len(e), 0, ">", 1) >= 0 { return PL_ABOVE_ONE } if i18n_find(e, len(e), 0, "n", 1) < 0 { return PL_ONE_FORM } return PL_NOT_ONE } export function i18n_plural_rule(i18n_st: I18nState) -> int { return i18n_st.plural_rule } # which msgstr[k] a count takes under a rule export function i18n_plural_form(rule: int, n: int) -> int { if rule == PL_ONE_FORM { return 0 } if rule == PL_ABOVE_ONE { if n > 1 { return 1 } return 0 } if rule == PL_SLAVIC { if n % 10 == 1 and n % 100 != 11 { return 0 } if n % 10 >= 2 and n % 10 <= 4 and (n % 100 < 10 or n % 100 >= 20) { return 1 } return 2 } if n != 1 { return 1 } return 0 } function plural_add(i18n_st: mut I18nState, e: PoEntry) -> void { if len(e.forms) == 0 or blank(e.forms[0]) { return } Dict.set(i18n_st.plural, e.id, len(i18n_st.forms) / 3) for k in 0 .. 3 { if k < len(e.forms) { push(i18n_st.forms, e.forms[k]) } else { push(i18n_st.forms, e.forms[len(e.forms) - 1]) } } }