(to preserve leading/tailing spaces when cargo query.) |
mNo edit summary |
||
(36 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
− | local cargo = mw.ext.cargo |
||
− | local db = {} |
||
− | |||
local trim = mw.text.trim |
local trim = mw.text.trim |
||
− | -- credit: http://richard.warburton.it |
||
− | -- this version is without trim. |
||
− | local function explode(div,str) |
||
− | if (div=='') then return false end |
||
− | local pos,arr = 0,{} |
||
− | -- for each divider found |
||
− | for st,sp in function() return string.find(str,div,pos,true) end do |
||
− | table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider |
||
− | pos = sp + 1 -- Jump past current divider |
||
− | end |
||
− | table.insert(arr, string.sub(str,pos)) -- Attach chars right of last divider |
||
− | return arr |
||
− | end |
||
local args_table -- cache |
local args_table -- cache |
||
Line 22: | Line 6: | ||
local value = trim(args_table[key] or '') |
local value = trim(args_table[key] or '') |
||
return (value ~= '') and value or nil |
return (value ~= '') and value or nil |
||
+ | end |
||
+ | |||
+ | local concatTable = function(tbl, sep) |
||
+ | local arr = {} |
||
+ | for _, v in pairs(tbl) do |
||
+ | arr[#arr+1] = v |
||
+ | end |
||
+ | return table.concat(arr, sep) |
||
+ | end |
||
+ | |||
+ | local db = {} |
||
+ | local loadDatabase = function(lang) |
||
+ | if not db[lang] then |
||
+ | local status, result = xpcall( |
||
+ | function() return mw.loadData("Module:GameText/loaddata-"..lang) end, -- try to load database for that language |
||
+ | function() return mw.loadData("Module:GameText/loaddata-en") end -- if it doesn't exist, load en database as fallback |
||
+ | ) |
||
+ | db[lang] = result or {} |
||
+ | end |
||
+ | return db[lang] |
||
end |
end |
||
-- key: e.g. "BuffName.ManaRegeneration". |
-- key: e.g. "BuffName.ManaRegeneration". |
||
− | -- return string or table, nil when key is invalid. |
+ | -- return string or table, nil when key or data is invalid. |
local get -- for recursion |
local get -- for recursion |
||
get = function(key, lang) |
get = function(key, lang) |
||
− | + | local data = db[lang] or loadDatabase(lang or 'en') |
|
+ | local key = trim(key) |
||
− | if not db[lang] then |
||
+ | local pos = 1 |
||
− | if lang == 'es' or lang == 'it' or lang =='zh' or lang == 'de' or lang == 'ru' or lang == 'fr' or lang == 'pl' or lang == 'pt' then |
||
+ | for st,sp in function() return string.find(key, '.', pos, true) end do |
||
− | db[lang] = mw.loadData("Module:GameText/db-"..lang) |
||
+ | index = string.sub(key, pos, st-1) |
||
− | else |
||
+ | data = data[tonumber(index) or index] -- convert to number for pure number index. |
||
− | db[lang] = mw.loadData("Module:GameText/db-en") |
||
+ | if not data then |
||
+ | return nil |
||
end |
end |
||
+ | pos = sp + 1 |
||
end |
end |
||
+ | if pos ~= 0 then |
||
− | local data, result = db[lang], nil |
||
− | + | key = string.sub(key, pos) |
|
− | for _, v in ipairs(explode('.', trim(key))) do |
||
− | if type(data) == 'table' then |
||
− | v = tonumber(v) or v -- convert to number for pure number index. |
||
− | result = data[v] |
||
− | data = result |
||
− | else |
||
− | break |
||
− | end |
||
− | end |
||
− | else |
||
− | result = data[trim(key)] |
||
end |
end |
||
− | + | local result = data[tonumber(key) or key] |
|
− | + | if result and type(result) == 'string' then |
|
+ | -- for ref marks such as {$CommonItemTooltip.RightClickToOpen} |
||
− | arr = {} |
||
+ | result = string.gsub(result, "({%$(.-)})", function(_, ref) return get(ref, lang) end) |
||
− | for _, v in pairs(result) do |
||
− | arr[#arr+1] = v |
||
− | end |
||
− | result = table.concat(arr, '₪') -- we must use a separator that is guaranteed not to be contained in any string. We can easily replace it in wikitext with any that we like |
||
− | else |
||
− | -- for such as {$CommonItemTooltip.RightClickToOpen} |
||
− | result = string.gsub(result, "({%$(.-)})", function(s, ref) return get(ref, lang) end) |
||
− | end |
||
end |
end |
||
return result |
return result |
||
end |
end |
||
− | -- args: |
+ | -- args: replacement table, e.g.: { ["{0}"] = "Party Girl", ["<right>"] = "Right click" } |
local getText = function(key, lang, args) |
local getText = function(key, lang, args) |
||
if not key then |
if not key then |
||
return |
return |
||
end |
end |
||
− | local str = get(key, lang) |
+ | local str = get(key, lang) or get(key, 'en') |
− | -- en as fallback. |
||
− | if not str and lang ~= 'en' then |
||
− | str = get(key, 'en') |
||
− | end |
||
if not str then |
if not str then |
||
− | return |
+ | return |
end |
end |
||
− | + | str = string.gsub(str, "{%?.-}", "") -- strip condition marks, e.g.: "{?Homeless}"" -> "" |
|
− | if |
+ | if args then |
str = string.gsub(str, "%b{}", args) |
str = string.gsub(str, "%b{}", args) |
||
str = string.gsub(str, "%b<>", args) |
str = string.gsub(str, "%b<>", args) |
||
Line 86: | Line 71: | ||
end |
end |
||
+ | -- bulid replacement table from template arguments. |
||
− | local query |
||
+ | -- e.g.: |x_0=Party Girl|y_right=Right click -> { ["{0}"] = "Party Girl", ["<right>"] = "Right click" } |
||
− | query = function(key, lang) |
||
+ | local replacementArgs = function(argsTable) |
||
− | lang = lang or 'en' |
||
+ | local args = {} |
||
− | local result = mw.ext.cargo.query('GameText', 'content', { |
||
+ | for k, v in pairs(argsTable) do |
||
− | where = 'lang='.. "'"..lang.."' AND name='"..key.."'", |
||
+ | string.gsub(k, '^x_(.+)', function(n) |
||
− | limit = 1, |
||
+ | args['{'..n..'}'] = v |
||
− | }) |
||
+ | end) |
||
− | local text |
||
+ | string.gsub(k, '^y_(.+)', function(n) |
||
− | for _, row in ipairs(result) do |
||
− | + | args['<'..n..'>'] = v |
|
+ | end) |
||
end |
end |
||
+ | return args == {} and nil or args |
||
− | if not text then |
||
− | return |
||
− | end |
||
− | return text |
||
end |
end |
||
− | local |
+ | local getSectionList = function() |
+ | local data = db['en'] or loadDatabase('en') |
||
− | if not key then |
||
+ | local arr = {} |
||
− | return |
||
+ | for k, v in pairs(data) do |
||
+ | arr[#arr + 1] = k |
||
end |
end |
||
+ | return arr |
||
− | local str = query(key, lang) |
||
− | -- en as fallback. |
||
− | if not str and lang ~= 'en' then |
||
− | str = query(key, 'en') |
||
− | end |
||
− | if not str then |
||
− | return '' |
||
− | end |
||
− | if str and args then |
||
− | str = string.gsub(str, "%b{}", args) |
||
− | str = string.gsub(str, "%b<>", args) |
||
− | end |
||
− | return string.sub(str,2,-2) |
||
end |
end |
||
+ | |||
+ | -- sorted pairs() function |
||
+ | local function spairs(t, order) |
||
+ | -- collect the keys |
||
+ | local keys = {} |
||
+ | for k in pairs(t) do keys[#keys+1] = tostring(k) end |
||
+ | |||
+ | -- if order function given, sort by it by passing the table and keys a, b, |
||
+ | -- otherwise just sort the keys |
||
+ | if order then |
||
+ | table.sort(keys, function(a,b) return order(t, a, b) end) |
||
+ | else |
||
+ | table.sort(keys) |
||
+ | end |
||
+ | |||
+ | -- return the iterator function |
||
+ | local i = 0 |
||
+ | return function() |
||
+ | i = i + 1 |
||
+ | if keys[i] then |
||
+ | return keys[i], t[keys[i]] |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | -------------------------------------------------------------------------------- |
||
+ | -------------------------------------------------------------------------------- |
||
+ | -------------------------------------------------------------------------------- |
||
return { |
return { |
||
Line 127: | Line 127: | ||
get = function(frame) |
get = function(frame) |
||
args_table = frame:getParent().args -- cache |
args_table = frame:getParent().args -- cache |
||
+ | local str = getText(getArg(1), getArg('lang') or frame.args['lang'], replacementArgs(args_table)) |
||
− | local args |
||
+ | if str then |
||
− | for k, v in pairs(args_table) do |
||
− | string.gsub( |
+ | return '<span class="gameText">' .. string.gsub(str, '\n', '<br/>') .. '</span>' |
− | if not args then args = {} end |
||
− | args['{'..n..'}'] = v |
||
− | end) |
||
− | string.gsub(k, '^y_(.+)', function(n) |
||
− | if not args then args = {} end |
||
− | args['<'..n..'>'] = v |
||
− | end) |
||
end |
end |
||
− | return getText(getArg(1), getArg('lang') or frame.args['lang'], args) |
||
end, |
end, |
||
getRaw = function(frame) |
getRaw = function(frame) |
||
− | return |
+ | return (frame.args['prefix'] or '') |
+ | ..(getText(frame.args[1], frame.args['lang'] or frame:expandTemplate{title = 'lang'}, replacementArgs(frame.args)) or '') |
||
+ | ..(frame.args['postfix'] or '') |
||
end, |
end, |
||
+ | |||
− | |||
− | query = function(frame) |
||
− | args_table = frame:getParent().args -- cache |
||
− | local args |
||
− | for k, v in pairs(args_table) do |
||
− | string.gsub(k, '^x_(.+)', function(n) |
||
− | if not args then args = {} end |
||
− | args['{'..n..'}'] = v |
||
− | end) |
||
− | string.gsub(k, '^y_(.+)', function(n) |
||
− | if not args then args = {} end |
||
− | args['<'..n..'>'] = v |
||
− | end) |
||
− | end |
||
− | return queryText(getArg(1), getArg('lang') or frame.args['lang'], args) |
||
− | end, |
||
− | |||
listAll = function(frame) |
listAll = function(frame) |
||
local lang = frame.args['lang'] or 'en' |
local lang = frame.args['lang'] or 'en' |
||
− | + | loadDatabase(lang) |
|
+ | local arr = {} |
||
− | if lang == 'es' or lang == 'it' or lang =='zh' or lang == 'de' or lang == 'ru' or lang == 'fr' or lang == 'pl' or lang == 'pt' then |
||
− | db[lang] = require("Module:GameText/db-"..lang) |
||
− | else |
||
− | db[lang] = require("Module:GameText/db-en") |
||
− | end |
||
− | end |
||
− | |||
if frame.args[1] then |
if frame.args[1] then |
||
− | local output |
||
if not db[lang][frame.args[1]] then |
if not db[lang][frame.args[1]] then |
||
return |
return |
||
end |
end |
||
for k, v in pairs(db[lang][frame.args[1]]) do |
for k, v in pairs(db[lang][frame.args[1]]) do |
||
+ | arr[#arr + 1] = k .. '₪' .. v |
||
− | if output then |
||
− | output = output .. '¦' .. k .. '₪' .. v |
||
− | else |
||
− | output = k .. '₪' .. v |
||
− | end |
||
− | |||
end |
end |
||
+ | |||
− | return output |
||
else |
else |
||
− | local output |
||
for k, v in pairs(db[lang]) do |
for k, v in pairs(db[lang]) do |
||
− | + | arr[#arr + 1] = k |
|
− | output = output .. '¦' .. k |
||
− | else |
||
− | output = k |
||
− | end |
||
end |
end |
||
− | return output |
||
end |
end |
||
+ | return table.concat(arr, '¦') |
||
end, |
end, |
||
+ | |||
− | |||
− | + | listAllNoKeys = function(frame) |
|
local lang = frame.args['lang'] or 'en' |
local lang = frame.args['lang'] or 'en' |
||
− | + | loadDatabase(lang) |
|
+ | local arr = {} |
||
− | if lang == 'es' or lang == 'it' or lang =='zh' or lang == 'de' or lang == 'ru' or lang == 'fr' or lang == 'pl' or lang == 'pt' then |
||
− | db[lang] = mw.loadData("Module:GameText/db-"..lang) |
||
− | else |
||
− | db[lang] = mw.loadData("Module:GameText/db-en") |
||
− | end |
||
− | end |
||
− | |||
if frame.args[1] then |
if frame.args[1] then |
||
− | local output |
||
if not db[lang][frame.args[1]] then |
if not db[lang][frame.args[1]] then |
||
return |
return |
||
end |
end |
||
for k, v in pairs(db[lang][frame.args[1]]) do |
for k, v in pairs(db[lang][frame.args[1]]) do |
||
− | + | arr[#arr + 1] = v |
|
− | output = output .. '¦' .. k |
||
− | else |
||
− | output = k |
||
− | end |
||
end |
end |
||
+ | end |
||
− | return output |
||
+ | return table.concat(arr, '₪') |
||
− | else |
||
+ | end, |
||
− | local output |
||
+ | |||
− | for k, v in pairs(db[lang]) do |
||
+ | listKeys = function(frame) |
||
− | if output then |
||
− | + | local lang = frame.args['lang'] or 'en' |
|
+ | loadDatabase(lang) |
||
− | else |
||
− | + | local arr = {} |
|
+ | for k, v in pairs(frame.args[1] and (db[lang][frame.args[1]] or {}) or db[lang]) do |
||
− | end |
||
+ | arr[#arr + 1] = k |
||
+ | end |
||
+ | return table.concat(arr, '¦') |
||
+ | end, |
||
+ | |||
+ | printTable = function(frame) |
||
+ | local lang = frame.args['lang'] or 'en' |
||
+ | local data = loadDatabase(lang) |
||
+ | |||
+ | local output = {'<table class="wikitable">', '<tr><th>Key</th><th>String</th></tr>'} |
||
+ | |||
+ | for mainKey, v in spairs(data) do |
||
+ | output[#output + 1] = '<tr><th colspan="2">' .. mainKey .. '</th></tr>' |
||
+ | for secondaryKey, str in pairs(v) do |
||
+ | output[#output + 1] = '<tr><td><code>' .. mainKey .. '.' .. secondaryKey .. '</code></td><td>' .. str .. '</td></tr>' |
||
end |
end |
||
− | return output |
||
end |
end |
||
+ | output[#output + 1] = '</table>' |
||
+ | return table.concat(output, '\n') |
||
end, |
end, |
||
+ | |||
+ | |||
+ | |||
+ | -- purge database cache |
||
+ | -- from template: {{#invoke:gameText|purge|lang=<lang>}} |
||
+ | -- from module: require('Module:gameText').purge(<lang>) |
||
+ | purge = function(frame) |
||
+ | local lang |
||
+ | if frame == mw.getCurrentFrame() then |
||
+ | lang = frame.args['lang'] |
||
+ | else |
||
+ | lang = frame |
||
+ | end |
||
+ | lang = lang or 'en' |
||
+ | require('Module:GameText/loaddata').purge(lang) |
||
+ | end, |
||
+ | |||
---------- for module ---------------- |
---------- for module ---------------- |
||
getText = getText, |
getText = getText, |
||
+ | getData = get, |
||
− | |||
+ | getSections = getSectionList, |
||
+ | replacementArgs = replacementArgs, |
||
} |
} |
Latest revision as of 01:26, 6 February 2024
Documentation The documentation below is transcluded from Module:GameText/doc. (edit | history)
This module is intended to provide functionality to the {{gameText}} template.
local trim = mw.text.trim
local args_table -- cache
-- helper function
local getArg = function(key)
local value = trim(args_table[key] or '')
return (value ~= '') and value or nil
end
local concatTable = function(tbl, sep)
local arr = {}
for _, v in pairs(tbl) do
arr[#arr+1] = v
end
return table.concat(arr, sep)
end
local db = {}
local loadDatabase = function(lang)
if not db[lang] then
local status, result = xpcall(
function() return mw.loadData("Module:GameText/loaddata-"..lang) end, -- try to load database for that language
function() return mw.loadData("Module:GameText/loaddata-en") end -- if it doesn't exist, load en database as fallback
)
db[lang] = result or {}
end
return db[lang]
end
-- key: e.g. "BuffName.ManaRegeneration".
-- return string or table, nil when key or data is invalid.
local get -- for recursion
get = function(key, lang)
local data = db[lang] or loadDatabase(lang or 'en')
local key = trim(key)
local pos = 1
for st,sp in function() return string.find(key, '.', pos, true) end do
index = string.sub(key, pos, st-1)
data = data[tonumber(index) or index] -- convert to number for pure number index.
if not data then
return nil
end
pos = sp + 1
end
if pos ~= 0 then
key = string.sub(key, pos)
end
local result = data[tonumber(key) or key]
if result and type(result) == 'string' then
-- for ref marks such as {$CommonItemTooltip.RightClickToOpen}
result = string.gsub(result, "({%$(.-)})", function(_, ref) return get(ref, lang) end)
end
return result
end
-- args: replacement table, e.g.: { ["{0}"] = "Party Girl", ["<right>"] = "Right click" }
local getText = function(key, lang, args)
if not key then
return
end
local str = get(key, lang) or get(key, 'en')
if not str then
return
end
str = string.gsub(str, "{%?.-}", "") -- strip condition marks, e.g.: "{?Homeless}"" -> ""
if args then
str = string.gsub(str, "%b{}", args)
str = string.gsub(str, "%b<>", args)
end
return str
end
-- bulid replacement table from template arguments.
-- e.g.: |x_0=Party Girl|y_right=Right click -> { ["{0}"] = "Party Girl", ["<right>"] = "Right click" }
local replacementArgs = function(argsTable)
local args = {}
for k, v in pairs(argsTable) do
string.gsub(k, '^x_(.+)', function(n)
args['{'..n..'}'] = v
end)
string.gsub(k, '^y_(.+)', function(n)
args['<'..n..'>'] = v
end)
end
return args == {} and nil or args
end
local getSectionList = function()
local data = db['en'] or loadDatabase('en')
local arr = {}
for k, v in pairs(data) do
arr[#arr + 1] = k
end
return arr
end
-- sorted pairs() function
local function spairs(t, order)
-- collect the keys
local keys = {}
for k in pairs(t) do keys[#keys+1] = tostring(k) end
-- if order function given, sort by it by passing the table and keys a, b,
-- otherwise just sort the keys
if order then
table.sort(keys, function(a,b) return order(t, a, b) end)
else
table.sort(keys)
end
-- return the iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
return {
---------- for template ----------------
get = function(frame)
args_table = frame:getParent().args -- cache
local str = getText(getArg(1), getArg('lang') or frame.args['lang'], replacementArgs(args_table))
if str then
return '<span class="gameText">' .. string.gsub(str, '\n', '<br/>') .. '</span>'
end
end,
getRaw = function(frame)
return (frame.args['prefix'] or '')
..(getText(frame.args[1], frame.args['lang'] or frame:expandTemplate{title = 'lang'}, replacementArgs(frame.args)) or '')
..(frame.args['postfix'] or '')
end,
listAll = function(frame)
local lang = frame.args['lang'] or 'en'
loadDatabase(lang)
local arr = {}
if frame.args[1] then
if not db[lang][frame.args[1]] then
return
end
for k, v in pairs(db[lang][frame.args[1]]) do
arr[#arr + 1] = k .. '₪' .. v
end
else
for k, v in pairs(db[lang]) do
arr[#arr + 1] = k
end
end
return table.concat(arr, '¦')
end,
listAllNoKeys = function(frame)
local lang = frame.args['lang'] or 'en'
loadDatabase(lang)
local arr = {}
if frame.args[1] then
if not db[lang][frame.args[1]] then
return
end
for k, v in pairs(db[lang][frame.args[1]]) do
arr[#arr + 1] = v
end
end
return table.concat(arr, '₪')
end,
listKeys = function(frame)
local lang = frame.args['lang'] or 'en'
loadDatabase(lang)
local arr = {}
for k, v in pairs(frame.args[1] and (db[lang][frame.args[1]] or {}) or db[lang]) do
arr[#arr + 1] = k
end
return table.concat(arr, '¦')
end,
printTable = function(frame)
local lang = frame.args['lang'] or 'en'
local data = loadDatabase(lang)
local output = {'<table class="wikitable">', '<tr><th>Key</th><th>String</th></tr>'}
for mainKey, v in spairs(data) do
output[#output + 1] = '<tr><th colspan="2">' .. mainKey .. '</th></tr>'
for secondaryKey, str in pairs(v) do
output[#output + 1] = '<tr><td><code>' .. mainKey .. '.' .. secondaryKey .. '</code></td><td>' .. str .. '</td></tr>'
end
end
output[#output + 1] = '</table>'
return table.concat(output, '\n')
end,
-- purge database cache
-- from template: {{#invoke:gameText|purge|lang=<lang>}}
-- from module: require('Module:gameText').purge(<lang>)
purge = function(frame)
local lang
if frame == mw.getCurrentFrame() then
lang = frame.args['lang']
else
lang = frame
end
lang = lang or 'en'
require('Module:GameText/loaddata').purge(lang)
end,
---------- for module ----------------
getText = getText,
getData = get,
getSections = getSectionList,
replacementArgs = replacementArgs,
}