local p =
local function matchBlacklist(text) local match = -- first all local list = xtemplates.all if list then for i = 1, #list do match = if match[1] then return unpack(match) end end end -- now a specific letter chr = string.lower(string.sub(text, 1, 1)) list = xtemplates[chr] if list then for i = 1, #list do match = if match[1] then return unpack(match) end end end return nilend
-- Helper function to test for truthy and falsy values-- @todo Somehow internationalize itlocal function truthy(value) if not value or value
0 or value
'false' or value
'non' then return false end return trueend
-- Helper function to match from a list regular expressions-- Like so: match pre..list[1]..post or pre..list[2]..post or ...local function matchAny(text, pre, list, post, init) local match = for i = 1, #list do match = if match[1] then return unpack(match) end end return nilend
-- Like matchAny but for Category/File links with less overheadlocal function matchAnyLink(text, list) local matchif not string.find(text, ':', 1, true) then return false end for _, v in ipairs(list) do match = string.match(text, '%[%[%s*' .. v .. '%s*:.*%]%]') if match then break end end return matchend
-- Helper function to escape a string for use in regexeslocal function escapeString(str) return string.gsub(str, '[%^%$%(%)%.%[%]%*%+%-%?%%]', '%%%0')end
-- Helper function to remove a string from a textlocal function removeString(text, str) local pattern = escapeString(str) if #pattern > 9999 then -- strings longer than 10000 bytes can't be put into regexes pattern = escapeString(mw.ustring.sub(str, 1, 999)) .. '.-' .. escapeString(mw.ustring.sub(str, -999)) end return string.gsub(text, pattern, )end
-- Helper function to convert a comma-separated list of numbers or min-max ranges into a list of booleans-- @param flags Comma-separated list of numbers or min-max ranges, for example '1,3-5'-- @return Map from integers to booleans, for example -- @return Boolean indicating wether the flags should be treated as a blacklist or notlocal function parseFlags(value) local flags = local blacklist = false
if not value then return nil, false end
if type(value)
elseif type(value)
'-' then blacklist = true value = string.sub(value, 2) end local ranges = mw.text.split(value, ',') -- split ranges: '1,3-5' to for _, range in pairs(ranges) do range = mw.text.trim(range) local min, max = string.match(range, '^(%d+)%s*%-%s*(%d+)$') -- '3-5' to min=3 max=5 if not max then min, max = string.match(range, '^((%d+))$') end -- '1' to min=1 max=1 if max then for p = min, max do flags[p] = true end else flags[range] = true -- if we reach this point, the string had the form 'a,b,c' rather than '1,2,3' end end
-- List has the form -- Convert it to -- But if ANY value is set to false, treat the list as a blacklist elseif type(value)
false then blacklist = true end flags[i] = true end end
return flags, blacklistend
-- Helper function to see if a value matches any of the given flagslocal function matchFlag(value, flags) if not value then return false end value = tostring(value) local lang = mw.language.getContentLanguage for flag in pairs(flags) do if value
flag or lang:ucfirst(value)
-- Helper function to convert template arguments into an array of options fit for getlocal function parseArgs(frame) local args = for key, value in pairs(frame:getParent.args) do args[key] = value end for key, value in pairs(frame.args) do args[key] = value end -- args from Lua calls have priority over parent args from template return argsend
-- Error handling function-- Throws a Lua error or returns an empty string if error reporting is disabledlocal function throwError(key, value) local TNT = require('Module:TNT') local ok, message = pcall(TNT.format, 'I18n/Module:Transcluder.tab', 'error-' .. key, value) if not ok then message = key end error(message, 2)end
-- Error handling function-- Returns a wiki friendly error or an empty string if error reporting is disabledlocal function getError(key, value) local TNT = require('Module:TNT') local ok, message = pcall(TNT.format, 'I18n/Module:Transcluder.tab', 'error-' .. key, value) if not ok then message = key end message = mw.html.create('div'):addClass('error'):wikitext(message) return messageend
-- Helper function to get the local name of a namespace and all its aliases-- @param name Canonical name of the namespace, for example 'File'-- @return Local name of the namespace and all aliases, for example local function getNamespaces(name) local sitens = mw.site.namespaces[name] local namespaces = mw.clone(sitens.aliases) local name = sitens.name local canonicalName = sitens.canonicalName table.insert(namespaces, name) if name ~= canonicalName then table.insert(namespaces, canonicalName) end return namespacesend
-- Get the page wikitext, following redirects-- Also returns the page name, or the target page name if a redirect was followed, or false if no page was found-- For file pages, returns the content of the file description pagelocal function getText(page, noFollow) local title = mw.title.new(page) if not title then return false, false end
local target = title.redirectTarget if target and not noFollow then title = target end
local text = title:getContent if not text then return false, title.prefixedText end
-- Remove
-- Keep
return text, title.prefixedTextend
-- Get the requested files from the given wikitext.-- @param text Required. Wikitext to parse.-- @param flags Range of files to return, for example 2 or '1,3-5'. Omit to return all files.-- @return Sequence of strings containing the wikitext of the requested files.-- @return Original wikitext minus requested files.local function getFiles(text, flags) local files = local flags, blacklist = parseFlags(flags) local fileNamespaces = getNamespaces('File') local name local count = 0 for file in string.gmatch(text, '%b[]') do if matchAnyLink(file, fileNamespaces) then name = string.match(file, '%[%[[^:]-:([^]|]+)') count = count + 1 if not blacklist and (not flags or flags[count] or matchFlag(name, flags)) or blacklist and flags and not flags[count] and not matchFlag(name, flags) then table.insert(files, file) else text = removeString(text, file) end end end
return files, textend
-- Get the requested tables from the given wikitext.-- @param text Required. Wikitext to parse.-- @param flags Range of tables to return, for example 2 or '1,3-5'. Omit to return all tables.-- @return Sequence of strings containing the wikitext of the requested tables.-- @return Original wikitext minus requested tables.local function getTables(text, flags) local tables = local flags, blacklist = parseFlags(flags) local id local count = 0 for t in string.gmatch('\n' .. text, '\n%b') do if string.sub(t, 1, 3)