(Changed return 'n/a' to a blank return for easier use in templates that check if data exists) |
Flachdachs (talk | contribs) (removed error message for absent or wrong creature) |
||
(7 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
+ | ---------------------------------------------------------------------------------------------------- |
||
+ | -- Usage: use the Template:Dv |
||
+ | ---------------------------------------------------------------------------------------------------- |
||
+ | |||
+ | -- override values in table dst with values of table src, or adds them |
||
+ | local function merge(dst, src) |
||
+ | for k, v in pairs(src) do |
||
+ | if type(dst[k]) == 'table' and type(v) == 'table' then |
||
+ | dst[k] = merge(dst[k], v) |
||
⚫ | |||
+ | dst[k] = v |
||
+ | end |
||
+ | end |
||
⚫ | |||
+ | end |
||
+ | |||
+ | local function deepcopy(orig) |
||
+ | if type(orig) == 'table' then |
||
+ | local copy = {} |
||
+ | for k, v in pairs(orig) do |
||
+ | copy[deepcopy(k)] = deepcopy(v) |
||
+ | end |
||
+ | return copy |
||
+ | end |
||
+ | return orig |
||
+ | end |
||
+ | |||
+ | local function createVardefines(t, f, prefix) |
||
+ | for k, v in pairs(t) do |
||
+ | if type(v) == 'table' then |
||
+ | f:callParserFunction('#vardefine:' .. (prefix == '' and prefix or prefix .. '/') .. k, 'table') |
||
+ | createVardefines(v, f, (prefix == '' and prefix or prefix .. '/') .. k) |
||
+ | else |
||
+ | f:callParserFunction('#vardefine:' .. (prefix == '' and prefix or prefix .. '/') .. k, v) |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | |||
local p = {} |
local p = {} |
||
− | function p.data( |
+ | function p.data(f) |
local args = f:getParent().args |
local args = f:getParent().args |
||
+ | -- expects one or more non-named arguments in the template, the /-separated path to the data |
||
− | if args[1 |
+ | if args[1] == nil then |
− | return 'not enough parameters' |
||
+ | return 'arguments expected, see documentation of Template:Dv' |
||
end |
end |
||
+ | -- concat all non-named arguments (args is not a real table, deepcopy creates one) |
||
+ | local path = table.concat(deepcopy(args), '/') |
||
+ | -- remove non-word characters except / then lowercase |
||
− | local entity, attribute = args[1]:gsub('%W',''):lower(), args[2]:gsub('%W',''):lower() |
||
+ | path = path:gsub('[^%w/]', ''):lower() |
||
+ | local folders = {} -- list of path parts |
||
+ | for part in path:gmatch("[^/]+") do |
||
+ | table.insert(folders, part) |
||
+ | end |
||
+ | |||
+ | -- separate creature name from the rest of the path |
||
+ | local creature = table.remove(folders, 1) |
||
+ | |||
+ | -- replace creature name alias with actual name |
||
local aliases = mw.loadData('Module:dv/aliases') |
local aliases = mw.loadData('Module:dv/aliases') |
||
− | if aliases[ |
+ | if aliases[creature] ~= nil then |
− | + | creature = aliases[creature] |
|
end |
end |
||
+ | -- retrieve the database |
||
local data = mw.loadData('Module:dv/data') |
local data = mw.loadData('Module:dv/data') |
||
+ | |||
⚫ | |||
+ | -- search the creature |
||
− | return data[entity][attribute] |
||
+ | local node = data[creature] |
||
⚫ | |||
+ | if node == nil then |
||
⚫ | |||
+ | return '' -- 'creature data not found: ' .. creature |
||
+ | end |
||
+ | |||
+ | -- merge inherited data with own data |
||
⚫ | |||
+ | node = merge(deepcopy(data[node.inherits]), data[creature]) |
||
+ | end |
||
+ | |||
+ | -- apply overrides from other section of 'data' |
||
+ | if type(node.overridewith) == 'string' and data[node.overridewith] ~= nil then |
||
+ | node = merge(node, data[node.overridewith]) |
||
+ | end |
||
+ | |||
+ | -- search data for path |
||
+ | for _,f in ipairs(folders) do |
||
+ | if node[f] ~= nil then |
||
+ | node = node[f] |
||
+ | else |
||
+ | return '' -- no data available for given path |
||
+ | end |
||
+ | end |
||
+ | |||
+ | if type(node) == 'table' then |
||
+ | if args.defineVars ~= nil then |
||
+ | createVardefines(node, f, args.defineVars) |
||
+ | return 'variables defined' |
||
+ | end |
||
+ | return 'path not specific enough: ' .. path -- given path leads to a folder instead of a value |
||
end |
end |
||
+ | return node |
||
end |
end |
||
return p |
return p |
Revision as of 05:34, 11 April 2018
Documentation
[purge]
This is the Lua backend of the Dinosaur Values system. Please do not use it directly; use the template instead, and check it for actual documentation.
----------------------------------------------------------------------------------------------------
-- Usage: use the Template:Dv
----------------------------------------------------------------------------------------------------
-- override values in table dst with values of table src, or adds them
local function merge(dst, src)
for k, v in pairs(src) do
if type(dst[k]) == 'table' and type(v) == 'table' then
dst[k] = merge(dst[k], v)
else
dst[k] = v
end
end
return dst
end
local function deepcopy(orig)
if type(orig) == 'table' then
local copy = {}
for k, v in pairs(orig) do
copy[deepcopy(k)] = deepcopy(v)
end
return copy
end
return orig
end
local function createVardefines(t, f, prefix)
for k, v in pairs(t) do
if type(v) == 'table' then
f:callParserFunction('#vardefine:' .. (prefix == '' and prefix or prefix .. '/') .. k, 'table')
createVardefines(v, f, (prefix == '' and prefix or prefix .. '/') .. k)
else
f:callParserFunction('#vardefine:' .. (prefix == '' and prefix or prefix .. '/') .. k, v)
end
end
end
local p = {}
function p.data(f)
local args = f:getParent().args
-- expects one or more non-named arguments in the template, the /-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 = table.concat(deepcopy(args), '/')
-- remove non-word characters except / then lowercase
path = path:gsub('[^%w/]', ''):lower()
local folders = {} -- list of path parts
for part in path:gmatch("[^/]+") do
table.insert(folders, part)
end
-- separate creature name from the rest of the path
local creature = table.remove(folders, 1)
-- replace creature name alias with actual name
local aliases = mw.loadData('Module:dv/aliases')
if aliases[creature] ~= nil then
creature = aliases[creature]
end
-- retrieve the database
local data = mw.loadData('Module:dv/data')
-- search the creature
local node = data[creature]
if node == nil then
return '' -- 'creature data not found: ' .. creature
end
-- merge inherited data with own data
if node.inherits ~= nil and data[node.inherits] ~= nil then
node = merge(deepcopy(data[node.inherits]), data[creature])
end
-- apply overrides from other section of 'data'
if type(node.overridewith) == 'string' and data[node.overridewith] ~= nil then
node = merge(node, data[node.overridewith])
end
-- search data for path
for _,f in ipairs(folders) do
if node[f] ~= nil then
node = node[f]
else
return '' -- no data available for given path
end
end
if type(node) == 'table' then
if args.defineVars ~= nil then
createVardefines(node, f, args.defineVars)
return 'variables defined'
end
return 'path not specific enough: ' .. path -- given path leads to a folder instead of a value
end
return node
end
return p