Editing Module:Test
Jump to navigation
Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision | Your text | ||
Line 1: | Line 1: | ||
− | + | local p = {} | |
− | local | ||
− | |||
− | |||
− | |||
− | |||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
Line 11: | Line 6: | ||
if mw then | if mw then | ||
− | + | ENV = "wiki" | |
log = mw.log | log = mw.log | ||
− | |||
− | + | util = require("Module:Test/lib/util") | |
− | + | search = require("Module:Test/lib/search") | |
− | + | else | |
+ | ENV = "dev" | ||
− | + | mw = {} | |
− | log | + | log = {} |
− | + | inspect = require './lib/inspect' | |
− | + | util = require("./lib/util") | |
− | + | search = require("./lib/search") | |
+ | diet = require("./data/diet") | ||
− | + | function pp(tbl, title) -- pretty print tables | |
− | + | util.hl(title) | |
− | + | print(inspect(tbl)) | |
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | logObject = function(obj, prefix) | + | -- (re)define used mw functions that don't exist in dev environment |
+ | mw.logObject = function(obj, prefix) | ||
if prefix then | if prefix then | ||
assert(type(prefix) == "string") | assert(type(prefix) == "string") | ||
− | table.insert( | + | table.insert(log, prefix .. " = " .. inspect(obj)) |
else | else | ||
− | table.insert( | + | table.insert(log, inspect(obj)) |
end | end | ||
end | end | ||
− | function | + | mw.dumpObject = function(arg) |
− | + | return inspect(arg) | |
− | + | end | |
+ | |||
+ | mw.log = function(arg) | ||
+ | table.insert(log, arg) | ||
end | end | ||
+ | end | ||
+ | |||
+ | --------------- | ||
+ | -- load data -- | ||
+ | --------------- | ||
− | + | if ENV == "dev" then | |
+ | data = loadfile("../output.lua")() | ||
+ | diet = loadfile("./data/diet.lua")() | ||
+ | elseif ENV == "wiki" then | ||
+ | data = mw.loadData('Module:Test/data') | ||
+ | end | ||
− | + | version = data.version | |
+ | data.version = nil | ||
− | + | ------------------ | |
− | + | -- virtual keys -- | |
+ | ------------------ | ||
− | + | local virtual_store = {} | |
− | + | local virtual_keys = { | |
− | + | ["Pawn"] = { | |
− | |||
− | + | function (def) | |
+ | virtField = "lives_in" | ||
+ | biomes = {} | ||
+ | for k,v in pairs(data) do | ||
+ | prefix = string.match(k, '(.+):') | ||
+ | if prefix == "BiomeDef" then | ||
+ | table.insert(biomes, v) | ||
+ | end | ||
+ | end | ||
− | end | + | local list = {} |
+ | for _,biome in pairs(biomes) do | ||
+ | for animal,_ in pairs(biome.wildAnimals or {}) do | ||
+ | if def.defName == animal then | ||
+ | table.insert(list, biome.label) | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | def._virtual_[virtField] = list | ||
+ | end, | ||
+ | |||
+ | function (def) | ||
+ | virtField = "foodTypes" | ||
+ | foodTypes = def.race.foodType | ||
+ | flags = {} | ||
+ | virtual_store.diet = {} | ||
+ | |||
+ | for _,foodType in ipairs(foodTypes) do | ||
+ | for foodItem,_ in pairs(diet.foodType[foodType]) do | ||
+ | flags[foodItem] = true | ||
+ | end | ||
+ | end | ||
+ | |||
+ | for flag,_ in pairs(flags) do | ||
+ | table.insert(virtual_store.diet, flag) | ||
+ | end | ||
+ | |||
+ | def._virtual_[virtField] = virtual_store.diet | ||
+ | end, | ||
+ | |||
+ | function (def) | ||
+ | virtField = "foodTypesExpanded" | ||
+ | flags = {} | ||
+ | eats = {} | ||
+ | |||
+ | for _,def in pairs(data) do | ||
+ | if def.defName and def.ingestible and def.ingestible.foodType then | ||
+ | for _,ingestible in ipairs(def.ingestible.foodType) do | ||
+ | for _,dietV in ipairs(virtual_store.diet) do | ||
+ | if ingestible == dietV then | ||
+ | flags[def.defName] = true | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | |||
+ | for flag,_ in pairs(flags) do | ||
+ | table.insert(eats, flag) | ||
+ | end | ||
+ | |||
+ | def._virtual_[virtField] = eats | ||
+ | end, | ||
+ | |||
+ | } | ||
+ | } | ||
----------------------- | ----------------------- | ||
Line 70: | Line 140: | ||
----------------------- | ----------------------- | ||
− | function | + | local function vardefine(name, value) |
− | assert( | + | local f_name = "vardefine" |
− | assert( | + | assert(var_name, string.format("bad argument #1 to '%s' (argument missing, name of variable to define)", f_name)) |
− | assert( | + | assert(var_name == "string", string.format("bad argument #1 to '%s' (string expected, got %s)", f_name, type(var_name))) |
− | assert( | + | assert(var_value, string.format("bad argument #2 to '%s' (argument missing, value to assign to variable)", f_name)) |
− | + | assert(var_value == "string" or var_value == "number", string.format("bad argument #2 to '%s' (string or number expected, got %s)", f_name, type(var_value))) | |
− | frame:callParserFunction('#vardefine', | + | |
+ | frame:callParserFunction('#vardefine', var_name, var_value) | ||
end | end | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | function | + | local function mergeParents(baseDef, ignoreKeys) |
local ancestorIDs = {} | local ancestorIDs = {} | ||
local mergedDef = {} | local mergedDef = {} | ||
Line 97: | Line 159: | ||
local parentID = def._.DefCategory .. ":" .. def._.ParentName | local parentID = def._.DefCategory .. ":" .. def._.ParentName | ||
table.insert(ancestorIDs, parentID) | table.insert(ancestorIDs, parentID) | ||
− | def = | + | def = data[parentID] |
end | end | ||
− | ancestorIDs = | + | ancestorIDs = util.table.reverse(ancestorIDs) |
table.insert(ancestorIDs, baseDef._.DefCategory .. ":" .. baseDef.defName) | table.insert(ancestorIDs, baseDef._.DefCategory .. ":" .. baseDef.defName) | ||
for _,parentID in ipairs(ancestorIDs) do | for _,parentID in ipairs(ancestorIDs) do | ||
− | + | util.table.overwrite(mergedDef, data[parentID], ignoreKeys) | |
end | end | ||
Line 110: | Line 172: | ||
end | end | ||
− | |||
− | |||
+ | function getDef(defIDsuffix, defIDprefix) | ||
local ignoreKeys = {"Abstract", "Name", "ParentName"} | local ignoreKeys = {"Abstract", "Name", "ParentName"} | ||
local baseDef | local baseDef | ||
− | local def | + | local mergedDef |
+ | |||
+ | if defIDprefix then | ||
+ | local defID = defIDprefix .. ":" .. defIDsuffix | ||
+ | baseDef = data[defID] | ||
+ | assert(not baseDef, string.format("getDef: Def '%s' not found", defID)) | ||
+ | else | ||
+ | for defID,def in pairs(data) do | ||
+ | -- WARNING: this depends on there not being any preexisting colons in the relevant substrings | ||
+ | prefix = string.match(defID, '(.+):') | ||
+ | suffix = string.match(defID, ':(.+)') | ||
+ | if suffix == defIDsuffix then | ||
+ | assert(not baseDef, string.format("getDef: Def conflict (more than one '%s')", defIDsuffix)) | ||
+ | baseDef = def | ||
+ | end | ||
+ | end | ||
+ | assert(baseDef, string.format("getDef: Def '%s' not found", defIDsuffix)) | ||
+ | end | ||
− | + | mergedDef = mergeParents(baseDef, ignoreKeys) | |
− | + | if virtual_keys[mergedDef.category] then | |
− | + | mergedDef._virtual_ = {} | |
− | + | for k,func in ipairs(virtual_keys[mergedDef.category]) do | |
− | + | func(mergedDef) | |
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
− | + | return mergedDef | |
+ | end | ||
− | |||
− | + | ---------------------- | |
+ | -- public interface -- | ||
+ | ---------------------- | ||
− | + | function p.getDefName(frame) | |
− | + | local defName | |
+ | local label = frame.args[1] | ||
− | + | if not label then | |
− | + | mw.logObject(frame.args, "frame.args") | |
+ | mw.log("getDefName: missing argument #1 (label)") | ||
+ | return nil | ||
+ | end | ||
− | for | + | for defID,def in pairs(data) do |
− | + | if string.upper(def.label or "") == string.upper(label) then | |
− | + | defName = def.label | |
− | |||
− | |||
− | |||
end | end | ||
end | end | ||
− | + | if not defName then | |
− | end | + | mw.logObject(frame.args, "frame.args") |
+ | mw.log(string.format("getDefName: '%s' not found", label)) | ||
+ | end | ||
− | + | return defName | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | |||
− | |||
− | |||
− | function | + | function p.count(frame) |
− | local query = | + | local query = p.query(frame) |
− | + | return #query | |
− | |||
− | |||
end | end | ||
− | |||
− | local argLen = | + | function p.query(frame) |
+ | local argLen = util.table.count(frame.args, "number") -- #frame.args won't work as expected, check the doc | ||
− | if not frame.args[ | + | -- implement expressive argument checks so we know what's going on |
− | logObject(frame.args, | + | -- use them as a kind of usage guide (give as much info as possible) |
+ | |||
+ | if not frame.args[1] then | ||
+ | mw.logObject(frame.args, "frame.args") | ||
+ | mw.log("query: missing argument #1 (defName or Name, for abstract Defs)") | ||
return nil | return nil | ||
end | end | ||
− | local def = | + | local def = getDef(frame.args[1]) |
if not def then | if not def then | ||
− | logObject(frame.args, string.format("query | + | mw.logObject(frame.args, "frame.args") |
+ | mw.log(string.format("query: bad argument #1 ('%s' not found)", frame.args[1])) | ||
return nil | return nil | ||
end | end | ||
− | + | local prune = def | |
− | |||
− | |||
− | |||
− | + | for i,arg in ipairs(frame.args) do -- arguments | |
− | |||
arg = tonumber(arg) or arg -- frame.args are always strings on MediaWiki so convert back the numbers | arg = tonumber(arg) or arg -- frame.args are always strings on MediaWiki so convert back the numbers | ||
− | if i == argLen | + | -- NOTE: might consider doing something about the if tree (trim it down a bit) |
− | + | ||
− | + | if i > 1 then -- additional arguments | |
− | + | ||
− | + | if i == argLen then -- if final argument | |
− | + | ||
− | + | if frame.args["sibling"] then -- sibling | |
− | + | prune = search.conductor({nil, frame.args["sibling"]} , prune) | |
− | + | if not prune then | |
+ | mw.logObject(frame.args, "frame.args") | ||
+ | mw.log(string.format("query: bad argument 'sibling' ('%s' not found in '%s')", frame.args["sibling"], frame.args[i-1])) | ||
+ | return nil | ||
+ | else | ||
+ | prune = prune.parent.table[arg] | ||
+ | if not prune then | ||
+ | mw.logObject(frame.args, "frame.args") | ||
+ | mw.log(string.format("query: bad argument #%i ('%s' is not a sibling of '%s')", i, arg, frame.args["sibling"])) | ||
+ | end | ||
+ | end | ||
+ | else | ||
+ | prune = search.conductor(arg, prune) | ||
+ | if not prune then | ||
+ | mw.logObject(frame.args, "frame.args") | ||
+ | mw.log(string.format("query: bad argument #%i ('%s' not found in '%s')", i, frame.args[i], frame.args[i-1])) | ||
+ | return nil | ||
+ | else | ||
+ | prune = prune.value | ||
+ | end | ||
+ | end -- sibling | ||
+ | |||
+ | else -- if not final argument | ||
+ | prune = search.conductor(arg, prune) | ||
+ | if not prune then | ||
+ | mw.logObject(frame.args, "frame.args") | ||
+ | mw.log(string.format("query: bad argument #%i ('%s' not found in '%s')", i, frame.args[i], frame.args[i-1])) | ||
return nil | return nil | ||
+ | else | ||
+ | prune = prune.value | ||
end | end | ||
end | end | ||
− | |||
− | + | end -- additional arguments | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end -- for arguments | end -- for arguments | ||
− | if type( | + | if type(prune) == "table" then mw.logObject(prune) end |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | return prune | |
− | return | ||
end | end | ||
− | ------------------------------------ | + | --------------------------------- |
− | -- | + | -- simulate module invocation -- |
− | ------------------------------------ | + | --------------------------------- |
+ | |||
+ | local simframe = { ["args"] = {} } | ||
+ | frame = frame or simframe | ||
+ | |||
+ | --~ simframe.args[1] = "fennec fox" | ||
+ | simframe.args[1] = "Hare" | ||
+ | --~ simframe.args[2] = "eats" | ||
+ | |||
+ | if ENV == "dev" then | ||
+ | |||
+ | --~ p.query(frame) | ||
+ | pp(p.query(frame)) | ||
+ | --~ pp(p.getDefName(frame)) | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | if | + | local clock = string.format("os.clock(): %i ms", os.clock() * 1000) |
− | + | mw.log("--" .. string.rep("-", #clock) .. "--") | |
− | for _,v in ipairs( | + | mw.log("- " .. clock .. " -") |
+ | mw.log("--" .. string.rep("-", #clock) .. "--") | ||
+ | |||
+ | ---------------------------------------- | ||
+ | -- simulate wiki log while developing -- | ||
+ | ---------------------------------------- | ||
+ | |||
+ | if ENV == "dev" then | ||
+ | util.hl("log") | ||
+ | for _,v in ipairs(log) do | ||
print(v) | print(v) | ||
end | end | ||
end | end | ||
− | + | return p -- return module | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |