local module = {} -- 常量,表示获取Data的根页面路径。 module.BASEPAGE = "Module:少女歌剧" module.DATABASEPAGE = module.BASEPAGE .. "/Data" module.SNIPPETBASEPAGE = "模块:Sandbox/サンムル/少女歌剧片段" or (module.BASEPAGE .. "/Snippet") module.NGROUPPAGE = module.BASEPAGE .. "/NGroup" local mps = require("模块:Sandbox/サンムル/ModulePageSystem") function module.snippet(frame) local args if (function() for k, _ in pairs(frame.args) do if type(k) == "number" then return true end end end)() then args = frame.args else args = require("Module:Arguments").getArgs(frame:getParent() or frame) end local ignoreerror = frame.args.ignoreerror == "yes" or args.ignoreerror == "yes" or false local indexes = {} for k, _ in pairs(args) do if type(k) == "number" then table.insert(indexes, k) end end table.sort(indexes) local path = {} for _, index in ipairs(indexes) do local name = args[index] table.insert(path, name) end local params = { frame = frame, ngpage = module.NGROUPPAGE } local result = mps.find(module.SNIPPETBASEPAGE, path, params) if result:hasValue(params) then return result:value(params) else return nil end end local loadData = function(page, ignoreerror) local success, result = pcall(mw.loadData, page) if success then return result elseif not ignoreerror then error(mw.ustring.format("加载数据页\"%s\"时发生错误:%s", page, result)) else return nil end end function module.data(frame) local args if (function() for k, _ in pairs(frame.args) do if type(k) == "number" then return true end end end)() then args = frame.args else args = require("Module:Arguments").getArgs(frame:getParent() or frame) end local ignoreerror = frame.args.ignoreerror == "yes" or args.ignoreerror == "yes" or false local indexes = {} for k, _ in pairs(args) do if type(k) == "number" then table.insert(indexes, k) end end table.sort(indexes) local path = {} for _, index in ipairs(indexes) do local name = args[index] name = mw.text.trim(mw.ustring.gsub(name or "", "[_%s]+", "_")) -- 标准化格式。 if name == "" then -- 排除无法识别的名称。 if not ignoreerror then error(mw.ustring.format("指定名称\"%s\"为空白字符串或空。", args[index] or "")) end else table.insert(path, name) end end local page = frame.args.page or args.page or module.DATABASEPAGE local result = loadData(page, true) or {} for index, name in ipairs(path) do if type(result) ~= "table" then -- 上级节点含有值。 -- 回溯一次查询,并将上级节点的键作为目录尝试加载本级页面,以重新从本级页面中查询。 page = mw.ustring.format("%s/%s", page, path[index - 1]) result = loadData(page, true) or {} end if result[name] then -- 表中含有这个值 result = result[name] else local alias = nil for k, v in pairs(result) do if type(k) == "string" and mw.ustring.sub(k, 1, mw.ustring.len(name)) == name and k ~= name then -- 查找别名列表。 alias = mw.text.split(k, "%s+") end end if alias ~= nil and (function() for _, alia in alias do if alia == name then return true end end return false end)() then -- 若别名列表中含有这个名称。 result = result[alias[1]] else -- 尝试加载次级页面,以从次级页面中继续查询。 page = mw.ustring.format("%s/%s", page, name) result = loadData(page, true) or {} end end end if type(result) == "table" then -- 查询结果不是值。 if not ignoreerror then error("查询到的值为空(可能在指定名称上的值的类型不是字符串,或者指定名称不存在)。") else return nil end else -- 成功查询到值。 return result end end return module