|
|
Line 1: |
Line 1: |
| local p = {}
| |
| local PrepareText = require("Module:Wikitext Parsing").PrepareText
| |
|
| |
|
| local function getTitle(title)
| |
| local success, titleObj = pcall(mw.title.new, title)
| |
| if success then return titleObj
| |
| else return nil end
| |
| end
| |
|
| |
| --string.gmatch will check the largest block it can without re-scanning whats inside, but we need whats inside
| |
| local function matchAllTemplates(str)
| |
| local matches = {}
| |
| for template in string.gmatch(str, "{%b{}}") do
| |
| table.insert(matches, template)
| |
| local innerContent = string.sub(template, 3, -3)
| |
| for _,subtemplate in next,matchAllTemplates(innerContent) do
| |
| table.insert(matches, subtemplate)
| |
| end
| |
| end
| |
| return matches
| |
| end
| |
|
| |
| --Forked version of getParameters from [[Module:Transcluder]] with extra features removed
| |
| local function escapeString(str)
| |
| return string.gsub(str, '[%^%$%(%)%.%[%]%*%+%-%?%%]', '%%%0')
| |
| end
| |
| local function getParameters(template)
| |
| local parameters, parameterOrder = {}, {}
| |
| local params = string.match(template, '{{[^|}]-|(.*)}}')
| |
| if params then
| |
| local count = 0
| |
| -- Temporarily replace pipes in subtemplates and wikilinks to avoid chaos
| |
| for subtemplate in string.gmatch(params, '{%b{}}') do
| |
| params = string.gsub(params, escapeString(subtemplate), string.gsub(subtemplate, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
| |
| end
| |
| for wikilink in string.gmatch(params, '%[%b[]%]') do
| |
| params = string.gsub(params, escapeString(wikilink), string.gsub(wikilink, ".", {["%"]="%%", ["|"]="@@:@@", ["="]="@@_@@"}) )
| |
| end
| |
| for parameter in mw.text.gsplit(params, '|') do
| |
| local parts = mw.text.split(parameter, '=')
| |
| local key = mw.text.trim(parts[1])
| |
| local value
| |
| if #parts == 1 then
| |
| value = key
| |
| count = count + 1
| |
| key = tostring(count)
| |
| else
| |
| value = mw.text.trim(table.concat(parts, '=', 2))
| |
| end
| |
| value = string.gsub(string.gsub(value, '@@:@@', '|'), '@@_@@', '=')
| |
| key = string.gsub(string.gsub(key, '@@:@@', '|'), '@@_@@', '=')
| |
| table.insert(parameterOrder, key)
| |
| parameters[key] = value
| |
| end
| |
| end
| |
| return parameters, parameterOrder
| |
| end
| |
|
| |
| -- Returns a table containing parameters and a table with the order in which each of their values were found.
| |
| -- Since this considers all subtemplates, a single parameter is expected to have multiple values.
| |
| -- E.g. {{ABC|X={{DEF|X=Value|Y=Other value}}{{ABC|X=Yes}}|Y=P}}
| |
| -- Would return {X={"{{DEF|X=Value|Y=Other value}}", "Value", "Yes"}, Y={"Other value", "P"}}
| |
| local function getAllParameters(template, ignore_blank, only_subtemplates)
| |
| local parameterTree = setmetatable({}, {
| |
| __index = function(self,key)
| |
| rawset(self,key,{})
| |
| return rawget(self,key)
| |
| end
| |
| })
| |
| local params, paramOrder = getParameters(template)
| |
| for _,key in ipairs(paramOrder) do
| |
| local value = params[key]
| |
| if not ignore_blank or value ~= "" then
| |
| if not only_subtemplates then
| |
| table.insert(parameterTree[key], value) --Insert the initial value into the tree
| |
| end
| |
| for subtemplate in string.gmatch(value, "{%b{}}") do --And now check for subvalues
| |
| local subparams = getAllParameters(subtemplate, ignore_blank)
| |
| for subkey,subset in next,subparams do
| |
| for _,subvalue in ipairs(subset) do
| |
| table.insert(parameterTree[subkey], subvalue) --And add any we find to our tree
| |
| end
| |
| end
| |
| end
| |
| end
| |
| end
| |
| return parameterTree
| |
| end
| |
|
| |
| --Primary module entry point. Returns a success boolean and either the result or why it failed
| |
| function p.getValue(page, templates, parameter, options)
| |
| if not (templates and parameter) then --Required parameters
| |
| return false, "Missing required parameters 'templates' and 'parameter'"
| |
| end
| |
| parameter = tostring(parameter) --Force consistency
| |
| options = options or {}
| |
|
| |
| --mix of camelCase and under_score is kept for backwards compatability
| |
| local template_index = tonumber(options.templateIndex or options.template_index) or 1
| |
| local parameter_index = tonumber(options.parameterIndex or options.parameter_index) or 1
| |
| local ignore_subtemplates = options.ignoreSubtemplates or options.ignore_subtemplates or false
| |
| local only_subtemplates = options.onlySubtemplates or options.only_subtemplates or false
| |
| local ignore_blank = options.ignoreBlank or options.ignore_blank or false
| |
| if type(templates) == "string" then
| |
| templates = mw.text.split(templates, ", ?")
| |
| end
| |
|
| |
| local title = getTitle(page)
| |
| if title == nil then
| |
| return false, "Requested title doesn't exist"
| |
| end
| |
| local content = PrepareText(title:getContent() or "")
| |
|
| |
| local foundTemplates = 0
| |
| for _,template in next,matchAllTemplates(content) do
| |
| for _,wantedTemplate in pairs(templates) do
| |
| local firstLetter = string.sub(wantedTemplate, 1, 1)
| |
| local firstUpper, firstLower = firstLetter:upper(), firstLetter:lower()
| |
| if firstUpper ~= firstLower then
| |
| wantedTemplate = "[" .. firstUpper .. firstLower .. "]" .. string.sub(wantedTemplate, 2)
| |
| end
| |
| if string.match(template, "^{{%s*"..wantedTemplate.."%s*[|}]") then
| |
| foundTemplates = foundTemplates + 1
| |
| if foundTemplates == template_index then --Found our wanted template
| |
| local value
| |
| if ignore_subtemplates then
| |
| value = getParameters(template)[parameter] or ""
| |
| else
| |
| local params = getAllParameters(template, ignore_blank, only_subtemplates)
| |
| value = params[parameter][parameter_index] or ""
| |
| end
| |
|
| |
| value = string.gsub(value, "</?%a*include%a*>", "")
| |
| value = mw.text.trim(value)
| |
| return true, mw.text.decode(value) --due to PrepareText
| |
| end
| |
| end
| |
| end
| |
| end
| |
|
| |
| return false, "No valid template found"
| |
| end
| |
|
| |
| --Template entry point. Returns an empty string upon failure
| |
| function p.main(frame)
| |
| local args = require('Module:Arguments').getArgs(frame, {
| |
| wrappers = 'Template:Template parameter value'
| |
| })
| |
| local yesno = require("Module:Yesno")
| |
| local options = {
| |
| template_index = args[3],
| |
| parameter_index = args[5],
| |
| ignore_subtemplates = yesno(args.ignore_subtemplates or args.ist) or false,
| |
| only_subtemplates = yesno(args.only_subtemplates) or false,
| |
| ignore_blank = yesno(args.ignore_blank) or false,
| |
| }
| |
| local success, result = p.getValue(args[1], args[2], args[4], options)
| |
| if not success then
| |
| return ""
| |
| else
| |
| return frame:preprocess(result)
| |
| end
| |
| end
| |
|
| |
| --Potentially useful module entry points
| |
| p.matchAllTemplates = matchAllTemplates
| |
| p.getParameters = getParameters
| |
| p.getAllParameters = getAllParameters
| |
|
| |
| return p
| |