Module: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 local args = f.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

--if folders ~= nil then --   return folders --end

-- separate dataset name from the rest of the path local dataname = table.remove(folders, 1)

-- retrieve the dataset local data = mw.loadData('Module:dv/' .. dataname)

-- separate node name from the rest of the path local nodename = table.remove(folders, 1)

-- search the node local node = data[nodename] if node == nil then return 'node data not found: ' .. nodename end

-- merge inherited data with own data if node.inherits ~= nil and data[node.inherits] ~= nil then node = merge(deepcopy(data[node.inherits]), data[nodename]) 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:' .. 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