モジュール:Dv/staging
< モジュール:Dv
ナビゲーションに移動
検索に移動
このモジュールについての説明文ページを モジュール:Dv/staging/doc に作成できます
local Utility = require('Module:Utility')
local Data = mw.loadData('Module:Dv/MergedJsonData')
local Aliases = mw.loadData('Module:Dv/aliases')
local p = {}
p.Error = {
CreatureMissing = {-10002},
NoData = {-10003},
}
function p.cleanQueryPath(name)
-- Remove non-word characters except / and ? (Unicode enabled)
return mw.ustring.gsub(name, '[^%w/?]', '')
end
function p.getNodeWithInheritanceSolved(creature)
-- Handle an alias (if one exists) for the creature
if Aliases[creature] ~= nil then
creature = Aliases[creature]
end
-- Retrieve the creature from the table
local node = Data[creature]
if node == nil then
-- Creature is missing from the data table
return nil
end
-- Solve inheritance if node inherits from another.
local inherits = node.inherits
if inherits ~= nil and inherits ~= '' then
-- Node inherits information from another. retrieve it with its inheritance solved.
local parentNode = p.getNodeWithInheritanceSolved(inherits)
if parentNode ~= nil then
node = Utility.merge(Utility.deepcopy(parentNode), node)
end
end
-- Apply data overrides if the node is set to require those.
local overrideWith = node.overrideWith
if overrideWith ~= nil and overrideWith ~= '' then
local overridesNode = p.getNodeWithInheritanceSolved(overrideWith)
if overridesNode ~= nil then
node = Utility.merge(Utility.deepcopy(node), overridesNode)
end
end
return node
end
function p.query(route)
-- Break the path down by slash
local path = {}
for part in route:gmatch("[^/]+") do
table.insert(path, part)
end
-- Separate creature name from the rest of the path and turn it lower-case
local creature = table.remove(path, 1):lower()
-- Retrieve the creature from the table
local node = p.getNodeWithInheritanceSolved(creature)
if node == nil then
-- Creature is missing from the data table
return p.Error.CreatureMissing
end
-- Traverse data by the path
for index, f in ipairs(path) do
if f == '?' then
-- Special case to check if a node exists.
return true
elseif node[f] == 'null' then
-- Special case where node is set to a "null" string. Treat it as if it was a real nil.
-- Table elements in Lua "don't exist" if their value is null, therefore we need this hack.
return p.Error.NoData
elseif node[f] ~= nil then
node = node[f]
elseif path[index-1] == 'colorRegions' and tonumber(f) ~= nil and node[tonumber(f)+1] ~= nil then
-- Shift index of a colour region by one.
node = node[tonumber(f)+1]
elseif path[index-1] ~= 'colorRegions' and tonumber(f) ~= nil and node[tonumber(f)] ~= nil then
-- Number-indexed array, treat `f` as a number.
node = node[tonumber(f)]
else
-- Path led to a dead-end. Nothing available.
return p.Error.NoData
end
end
return node
end
function p.data(f)
local args = f:getParent().args
-- Expect one or more non-named arguments in the template, the slash-separated path to the data
if args[1] == nil then
return 'arguments expected, see documentation of Template:Dv'
end
-- Concat all non-named arguments (args is not a real table, deepcopy creates one)
local path = p.cleanQueryPath(table.concat(Utility.deepcopy(args), '/'))
local result = p.query(path)
if result == nil then
-- Return an empty string instead of nulls.
return ''
elseif result == p.Error.CreatureMissing or result == p.Error.NoData then
-- Return the default value or an empty string on query failure.
return args.default or ''
elseif type(result) == 'boolean' then
-- Convert boolean result into a 'yes' or 'no'.
return result and 'Yes' or 'No'
elseif type(result) == 'table' then
-- TODO: result is a table, define variables in a compatible way
return table.concat(Utility.deepcopy(result), ', ')
else
-- Return the result.
return result
end
end
return p