Jump to content

Recommended Posts

I'm trying to add language support to the mod character but using PO files overrides all of the strings for that language, not just the strings I added, making the strings I did not include in PO file display in English.

Is there a way to only add translation for specific strings or a way to merge two PO files?

I found a way to "merge" po files using a python module called "polib", it's quite slow  but it does the job. 

I still haven't found a way to partially load po files though, please tell me if there's a way to do it.

 

But you can just sort out the strings from the po file. If you mean you want to override STRINGS...here is my wheel.

local supported = {"zh","en"}
local defaultlang = "zh"
local character_name = "gallop"
local lang_conf = GetModConfigData("language")
local jsonfiles = {} -- {"x"}
local pofiles = {} -- po format
local stringsfiles = {"gallop_%s", "gallop_item_%s"} -- STRINGS.XXX=""
local luafiles = {} -- {"STRINGS.XXX"=""}
local function catstring(...)
  local args = {...}
  local strs = {}
  for k, v in pairs(args) do if v ~= nil then table.insert(strs, tostring(v)) end end
  return table.concat(strs, "")
end

local function mergeinto(table1, table2)
  if not table1 or not table2 then return end
  for key, value in pairs(table2) do
    if type(value) == "table" then
      if type(table1[key]) ~= "table" then
        local oldkey = table1[key]
        table1[key] = {GENERIC = oldkey}
      end
      mergeinto(table1[key], value)
    else
      table1[key] = value
    end
  end
end
local function GetLanguageCode()
  local loc = locale or (LOC.CurrentLocale and LOC.CurrentLocale.code) or LanguageTranslator.defaultlang
  local traditional = loc == "zht"
  -- replace wegame suffix
  if loc == "zhr" then loc = "zh" end
  return loc, traditional
end
-- why the game engine don't do this? Maybe because there is no Chinese involved.
-- but the string is utf-8 coded, so it has to be lua file work
local function separator(sentence)
  local maxlength = 16
  local len = string.len(sentence)
  if len <= maxlength then return sentence end
  local accumulated = 0
  local sep = {}
  for i = 1, len do
    if string.sub(sentence, i, i) == " " then
      table.insert(sep, string.sub(sentence, i - accumulated, i - 1))
      accumulated = 0
    else
      accumulated = accumulated + 1
    end
    if accumulated == maxlength then
      table.insert(sep, string.sub(sentence, i - maxlength + 1, i))
      accumulated = 0
    end
  end
  table.insert(sep, string.sub(sentence, len - accumulated + 1, len))
  return table.concat(sep, " ")
end
local function PatchMissingTables(strings, startdepth, sep)
  if not strings then return end
  startdepth = startdepth or 1
  for k, v in pairs(strings) do
    local keys = {undotted(k)}
    for i = 1, startdepth do table.remove(keys, 1) end
    local leaf = table.remove(keys, #keys)
    local root = STRINGS
    for i, node in ipairs(keys) do
      local oldval = root[node]
      if type(oldval) ~= "table" then root[node] = {} end
      root = root[node]
    end
    if type(tonumber(leaf)) == "number" then
      root[tonumber(leaf)] = v -- patched number circumstances
    else
      -- root[leaf] = sep and separator(v) or v
      root[leaf] = v
    end
  end
end
local function MergeTranslationFromPO(filepath, override_lang)
  local _defaultlang = LanguageTranslator.defaultlang
  local lang = override_lang or _defaultlang
  if not lang then
    print("[MergeTranslationFromPO]No language specified", filepath)
    return
  end
  if not softresolvefilepath(filepath) then
    print("[MergeTranslationFromPO]Could not find a language file matching", filepath)
    return
  end
  local temp_lang = lang .. math.random()
  LanguageTranslator:LoadPOFile(filepath, temp_lang)
  if not LanguageTranslator.languages[lang] then LanguageTranslator.languages[lang] = {} end
  mergeinto(LanguageTranslator.languages[lang], LanguageTranslator.languages[temp_lang])
  -- insert logic for patch
  PatchMissingTables(LanguageTranslator.languages[temp_lang])
  LanguageTranslator.languages[temp_lang] = nil
  LanguageTranslator.defaultlang = _defaultlang
end
local function MergeTranslationFromLUA(filename, sep)
  local content = require(filename)
  PatchMissingTables(content, 1, sep)
end
local function LoadJson(filename)
  local path = softresolvefilepath(filename)
  if not path then
    print("[LoadJson] file: ", filename, "cannot be found")
    return
  end
  local f = io.open(path)
  if not f then
    print("[LoadJson] file: ", filename, "cannot be opened")
    return
  end
  local data = f:read("*all")
  f:close()
  if data then
    local success, result = pcall(json.decode, data)
    if success then
      return result
    else
      print("[LoadJson] file: ", filename, "cannot be parsed")
    end
  else
    print("[LoadJson] file: ", filename, "cannot be read")
  end
end
local function MergeTranslationFromJSON(filename)
  local content = LoadJson(filename)
  if content then mergeinto(STRINGS, content) end
end
local function MergeTranslationFromSTRINGS(filename, charname)
  -- patch describe
  charname = charname:upper()
  STRINGS.CHARACTERS[charname] = STRINGS.CHARACTERS[charname] or {}
  for i, v in pairs(STRINGS.CHARACTERS) do
    v.DESCRIBE = v.DESCRIBE or {}
    v.DESCRIBE[charname] = v.DESCRIBE[charname] or {}
  end
  utils.onemod(filename)
end
local lang = lang_conf == "default" and GetLanguageCode() or lang_conf
if lang == "zhr" or lang == "zht" then lang = "zh" end
if not table.contains(supported, lang) then lang = defaultlang end
local function loader()
  for i, v in ipairs(stringsfiles) do
    MergeTranslationFromSTRINGS(catstring("scripts/languages/", v:format(lang), ".lua"), character_name)
  end
  for i, v in ipairs(luafiles) do MergeTranslationFromLUA(catstring("languages/", v:format(lang))) end
  for i, v in ipairs(jsonfiles) do MergeTranslationFromJSON(catstring("scripts/languages/", v:format(lang), ".json")) end
  for i, v in ipairs(pofiles) do MergeTranslationFromPO(catstring("scripts/languages/", v:format(lang), ".po")) end
end
-- if exposeToGlobal then exposeToGlobal("reloadlang", loader) end
loader()

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...