Editing Module:DependencyListGive feedback
Jump to navigation
Jump to search
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local libraryUtil = require('libraryUtil') | local libraryUtil = require( 'libraryUtil' ) | ||
local arr = require('Module:Array') | local arr = require( 'Module:Array' ) | ||
local yn = require('Module:Yesno') | local yn = require( 'Module:Yesno' ) | ||
local param = require('Module:Paramtest') | local param = require( 'Module:Paramtest' ) | ||
local dpl = require('Module:DPLlua') | local dpl = require( 'Module:DPLlua' ) | ||
local tooltip = require('Module:Tooltip') | local tooltip = require( 'Module:Tooltip' ) | ||
local moduleIsUsed = false | |||
local COLLAPSE_LIST_LENGTH_THRESHOLD = 5 | local COLLAPSE_LIST_LENGTH_THRESHOLD = 5 | ||
local MAX_DYNAMIC_REQUIRE_LIST_LENGTH = 30 | local MAX_DYNAMIC_REQUIRE_LIST_LENGTH = 30 | ||
| Line 12: | Line 12: | ||
local builtins = { | local builtins = { | ||
["libraryUtil"] = { | |||
link = "mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#libraryUtil", | |||
categories = {}, | |||
}, | |||
["strict"] = { | |||
link = "mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#strict", | |||
categories = { "Strict mode modules" }, | |||
}, | |||
} | } | ||
-- Used in case 'require( varName )' is found. Attempts to find a string value stored in 'varName'. | --- Used in case 'require( varName )' is found. Attempts to find a string value stored in 'varName'. | ||
local function substVarValue( | ---@param content string The content of the module to search in | ||
---@param varName string | |||
---@return string | |||
local function substVarValue( content, varName ) | |||
local res = content:match( varName .. '%s*=%s*(%b""%s-%.*)' ) or content:match( varName .. "%s*=%s*(%b''%s-%.*)" ) or '' | |||
if res:find( '^(["\'])[Mm]odule:[%S]+%1' ) and not res:find( '%.%.' ) and not res:find( '%%%a' ) then | |||
return mw.text.trim( res ) | |||
else | |||
return '' | |||
end | |||
end | end | ||
local function extractModuleName( capture, | ---@param capture string | ||
---@param content string The content of the module to search in | |||
---@return string | |||
local function extractModuleName( capture, content ) | |||
capture = capture:gsub( '^%(%s*(.-)%s*%)$', '%1' ) | |||
if capture:find( '^(["\']).-%1$' ) then -- Check if it is already a pure string | |||
return capture | |||
elseif capture:find( '^[%a_][%w_]*$' ) then -- Check if if is a single variable | |||
return substVarValue( content, capture ) | |||
end | |||
return capture | |||
end | end | ||
---@param str string | |||
---@return string | |||
local function formatPageName( str ) | local function formatPageName( str ) | ||
local name = mw.text.trim(str) | |||
:gsub( '^([\'\"])(.-)%1$', '%2' ) -- Only remove quotes at start and end of string if both are the same type | |||
:gsub( '_', ' ' ) | |||
:gsub( '^.', string.upper ) | |||
:gsub( '^([^:]-:)(.)', function(a,b) return a..string.upper(b) end ) | |||
return name | |||
end | end | ||
---@param str string | |||
---@param allowBuiltins? boolean | |||
---@return string | |||
local function formatModuleName( str, allowBuiltins ) | local function formatModuleName( str, allowBuiltins ) | ||
if allowBuiltins then | |||
local name = mw.text.trim(str) | |||
-- Only remove quotes at start and end of string if both are the same type | |||
:gsub([[^(['"])(.-)%1$]], '%2') | |||
if builtins[name] then | |||
return name | |||
end | |||
end | |||
local module = formatPageName( str ) | |||
if not string.find( module, '^[Mm]odule:' ) then | |||
module = 'Module:' .. module | |||
end | |||
return module | |||
end | end | ||
local function dualGmatch( str, pat1, pat2 ) | local function dualGmatch( str, pat1, pat2 ) | ||
local f1 = string.gmatch( str, pat1 ) | |||
if pat2 then | |||
local f2 = string.gmatch( str, pat2 ) | |||
return function() | |||
return f1() or f2() | |||
end | |||
else | |||
return f1 | |||
end | |||
end | end | ||
local function isDynamicPath( str ) | local function isDynamicPath( str ) | ||
return string.find( str, '%.%.' ) or string.find( str, '%%%a' ) | |||
end | end | ||
-- Used in case a construct like 'require( "Module:wowee/" .. isTheBest )' is found. | --- Used in case a construct like 'require( "Module:wowee/" .. isTheBest )' is found. | ||
-- Will return a list of pages which satisfy this pattern where 'isTheBest' can take any value. | --- Will return a list of pages which satisfy this pattern where 'isTheBest' can take any value. | ||
---@param query string | |||
---@return string[] | |||
local function getDynamicRequireList( query ) | local function getDynamicRequireList( query ) | ||
if query:find( '%.%.' ) then | |||
query = mw.text.split( query, '..', true ) | |||
query = arr.map( query, function(x) return mw.text.trim(x) end ) | |||
query = arr.map( query, function(x) return (x:match('^[\'\"](.-)[\'\"]$') or '%') end ) | |||
query = table.concat( query ) | |||
else | |||
local _, _query = query:match( '(["\'])(.-)%1' ) | |||
query = _query:gsub( '%%%a', '%%' ) | |||
end | |||
query = query:gsub( '^[Mm]odule:', '' ) | |||
if query:find( '^[Ee]xchange/' ) or query:find( '^[Dd]ata/' ) then | |||
return { 'Module:' .. query } -- This format will later be used by formatDynamicQueryLink() | |||
end | |||
if dynamicRequireListQueryCache[ query ] then | |||
return dynamicRequireListQueryCache[ query ] | |||
end | |||
local list = dpl.ask{ | |||
namespace = 'Module', | |||
titlematch = query, | |||
nottitlematch = '%/doc|'..query..'/%', | |||
distinct = 'strict', | |||
ignorecase = true, | |||
ordermethod = 'title', | |||
count = MAX_DYNAMIC_REQUIRE_LIST_LENGTH + 1, | |||
skipthispage = 'no', | |||
allowcachedresults = true, | |||
cacheperiod = 604800 -- One week | |||
} | |||
if #list > MAX_DYNAMIC_REQUIRE_LIST_LENGTH then | |||
list = { 'Module:' .. query } | |||
end | |||
dynamicRequireListQueryCache[ query ] = list | |||
return list | |||
end | end | ||
--- Returns a list of modules loaded and required by module 'moduleName'. | --- Returns a list of modules loaded and required by module 'moduleName'. | ||
local function | ---@param moduleName string | ||
---@param searchForUsedTemplates? boolean | |||
---@return table<string, string[]> | |||
local function getRequireList( moduleName, searchForUsedTemplates ) | |||
local content = mw.title.new( moduleName ):getContent() | |||
local requireList = arr{} | |||
local loadDataList = arr{} | |||
local loadJsonDataList = arr{} | |||
local usedTemplateList = arr{} | |||
local dynamicRequirelist = arr{} | |||
local dynamicLoadDataList = arr{} | |||
local dynamicLoadJsonDataList = arr{} | |||
local extraCategories = arr{} | |||
assert( content ~= nil, string.format( '%s does not exist', moduleName ) ) | |||
content = content:gsub( '%-%-%[(=-)%[.-%]%1%]', '' ):gsub( '%-%-[^\n]*', '' ) -- Strip comments | |||
local function getList( pat1, pat2, list, dynList ) | |||
for match in dualGmatch( content, pat1, pat2 ) do | |||
match = mw.text.trim( match ) | |||
local name = extractModuleName( match, content ) | |||
if isDynamicPath( name ) then | |||
dynList:insert( getDynamicRequireList( name ), true ) | |||
elseif name ~= '' then | |||
name = formatModuleName( name, true ) | |||
table.insert( list, name ) | |||
if builtins[name] then | |||
extraCategories = extraCategories:insert( builtins[name].categories, true ) | |||
end | |||
end | |||
end | |||
end | |||
getList( 'require%s*(%b())', 'require%s*((["\'])%s*[Mm]odule:.-%2)', requireList, dynamicRequirelist ) | |||
getList( 'mw%.loadData%s*(%b())', 'mw%.loadData%s*((["\'])%s*[Mm]odule:.-%2)', loadDataList, dynamicLoadDataList ) | |||
getList( 'mw%.loadJsonData%s*(%b())', 'mw%.loadJsonData%s*((["\'])%s*[Mm]odule:.-%2)', loadJsonDataList, dynamicLoadJsonDataList ) | |||
getList( 'pcall%s*%(%s*require%s*,([^%),]+)', nil, requireList, dynamicRequirelist ) | |||
getList( 'pcall%s*%(%s*mw%.loadData%s*,([^%),]+)', nil, loadDataList, dynamicLoadDataList ) | |||
getList( 'pcall%s*%(%s*mw%.loadJsonData%s*,([^%),]+)', nil, loadJsonDataList, dynamicLoadJsonDataList ) | |||
if searchForUsedTemplates then | |||
for preprocess in string.gmatch( content, ':preprocess%s*(%b())' ) do | |||
local function recursiveGMatch( str, pat ) | |||
local list = {} | |||
local i = 0 | |||
repeat | |||
for match in string.gmatch( list[i] or str, pat ) do | |||
table.insert( list, match ) | |||
end | |||
i = i + 1 | |||
until i > #list or i > 100 | |||
i = 0 | |||
return function() | |||
i = i + 1 | |||
return list[i] | |||
end | |||
end | |||
for template in recursiveGMatch( preprocess, '{(%b{})}' ) do | |||
local name = string.match( template, '{(.-)[|{}]' ) | |||
if name ~= '' then | |||
if name:find( ':' ) then | |||
local ns = name:match( '^(.-):' ) | |||
if arr.contains( {'', 'template', 'calculator', 'user'}, ns:lower() ) then | |||
table.insert( usedTemplateList, name ) | |||
elseif ns == ns:upper() then | |||
table.insert( usedTemplateList, ns ) -- Probably a magic word | |||
end | |||
else | |||
if name:match( '^%u+$' ) or name == '!' then | |||
table.insert( usedTemplateList, name ) -- Probably a magic word | |||
else | |||
table.insert( usedTemplateList, 'Template:'..name ) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
end | |||
requireList = requireList .. dynamicRequirelist | |||
requireList = requireList:unique() | |||
loadDataList = loadDataList .. dynamicLoadDataList | |||
loadDataList = loadDataList:unique() | |||
loadJsonDataList = loadJsonDataList .. dynamicLoadJsonDataList | |||
usedTemplateList = usedTemplateList:unique() | |||
extraCategories = extraCategories:unique() | |||
table.sort( requireList ) | |||
table.sort( loadDataList ) | |||
table.sort( loadJsonDataList ) | |||
table.sort( usedTemplateList ) | |||
table.sort( extraCategories ) | |||
return { | |||
requireList = requireList, | |||
loadDataList = loadDataList, | |||
loadJsonDataList = loadJsonDataList, | |||
usedTemplateList = usedTemplateList, | |||
extraCategories = extraCategories | |||
} | |||
end | end | ||
-- Returns a list with module and function names used in all '{{#Invoke:moduleName|funcName}}' found on page 'templateName'. | --- Returns a list with module and function names used in all '{{#Invoke:moduleName|funcName}}' found on page 'templateName'. | ||
local function getInvokeCallList( | ---@param templateName string | ||
---@return table<string, string>[] | |||
local function getInvokeCallList( templateName ) | |||
local content = mw.title.new( templateName ):getContent() | |||
local invokeList = {} | |||
assert( content ~= nil, string.format( '%s does not exist', templateName ) ) | |||
for moduleName, funcName in string.gmatch( content, '{{[{|safeubt:}]-#[Ii]nvoke:([^|]+)|([^}|]+)[^}]*}}' ) do | |||
moduleName = formatModuleName( moduleName ) | |||
funcName = mw.text.trim( funcName ) | |||
if string.find( funcName, '^{{{' ) then | |||
funcName = funcName .. '}}}' | |||
end | |||
table.insert( invokeList, {moduleName=moduleName, funcName=funcName} ) | |||
end | |||
-- For form calcs invoking the module directly | |||
for config in dualGmatch( content, '<pre%s+class%s*=%s*["\']jcConfig["\'](.-)</pre>', '{{[Ff]orm calculator%s*|(.+)}}' ) do | |||
local moduleName = string.match( config, 'module%s*=%s*(.-)[\n|]' ) | |||
if param.has_content( moduleName ) then | |||
moduleName = formatModuleName( moduleName ) | |||
local funcName = string.match( config, 'modulefunc%s*=%s*(.-)[\n|]' ) or 'main' | |||
table.insert( invokeList, {moduleName=moduleName, funcName=funcName} ) | |||
end | |||
end | |||
invokeList = arr.unique( invokeList, function(x) return x.moduleName..x.funcName end ) | |||
table.sort( invokeList, function(x, y) return x.moduleName..x.funcName < y.moduleName..y.funcName end ) | |||
return invokeList | |||
end | end | ||
local function | ---@param pageName string | ||
---@param addCategories boolean | |||
---@return string | |||
local function messageBoxUnused( pageName, addCategories ) | |||
local html = mw.html.create( 'table' ):addClass( 'messagebox obsolete plainlinks' ) | |||
html:tag( 'td' ) | |||
:attr( 'width', '40xp' ) | |||
:wikitext( '[[File:Willow logs (historical).png|center|30px|link=]]' ) | |||
:done() | |||
:tag( 'td' ) | |||
:wikitext( "'''This module is unused.'''" ) | |||
:tag( 'div' ) | |||
:css{ ['font-size']='0.85em', ['line-height']='1.45em' } | |||
:wikitext( string.format( 'This module is neither invoked by a template nor required/loaded by another module. If this is in error, make sure to add <code>{{[[Template:Documentation|Documentation]]}}</code>/<code>{{[[Template:No documentation|No documentation]]}}</code> to the calling template\'s or parent\'s module documentation.', pageName ) ) | |||
:wikitext( addCategories and '[[Category:Unused modules]]' or '' ) | |||
:done() | |||
:done() | |||
return tostring( html ) | |||
end | end | ||
local function collapseList( list, id, listType ) | local function collapseList( list, id, listType ) | ||
local text = string.format( '%d %s', #list, listType ) | |||
local button = tooltip._span{ name=id, alt=text } | |||
list = arr.map( list, function(x) return '\n# '..x end ) | |||
local content = tooltip._div{ name=id, content='\n'..table.concat( list )..'\n\n' } | |||
return { tostring( button ) .. tostring( content ) } | |||
end | end | ||
-- Creates a link to [[Special:Search]] showing all pages found by getDynamicRequireList() in case it found more than MAX_DYNAMIC_REQUIRE_LIST_LENGTH pages. | --- Creates a link to [[Special:Search]] showing all pages found by getDynamicRequireList() in case it found more than MAX_DYNAMIC_REQUIRE_LIST_LENGTH pages. | ||
-- | ---@param query string @This will be in a format like 'Module:Wowee/%' or 'Module:Wowee/%/data' | ||
---@return string | |||
local function formatDynamicQueryLink( query ) | local function formatDynamicQueryLink( query ) | ||
local prefix = query:match( '^([^/]+)' ) | |||
local linkText = query:gsub( '%%', '< ... >' ) | |||
query = query:gsub( '^Module:', '' ) | |||
query = query:gsub( '([^/]+)/?', function ( match ) | |||
if match == '%' then | |||
return '\\/[^\\/]+' | |||
else | |||
return '\\/"' .. match .. '"' | |||
end | |||
end ) | |||
query = query:gsub( '^\\/', '' ) | |||
query = string.format( | |||
'intitle:/%s%s/i -intitle:/%s\\/""/i -intitle:doc prefix:"%s"', | |||
query, | |||
query:find( '"$' ) and '' or '""', | |||
query, | |||
prefix | |||
) | |||
return string.format( '<span class="plainlinks">[%s %s]</span>', tostring( mw.uri.fullUrl( 'Special:Search', { search = query } ) ), linkText ) | |||
end | end | ||
local function | ---@param templateName string | ||
---@param addCategories boolean | |||
---@param invokeList table<string, string>[] @This is the list returned by getInvokeCallList() | |||
---@return string | |||
local function formatInvokeCallList( templateName, addCategories, invokeList ) | |||
local category = addCategories and '[[Category:Lua-based templates]]' or '' | |||
local res = {} | |||
for _, item in ipairs( invokeList ) do | |||
table.insert( res, string.format( | |||
"<div class='seealso'>'''%s''' invokes function '''%s''' in [[%s]] using [[RuneScape:Lua|Lua]].</div>", | |||
templateName, | |||
item.funcName, | |||
item.moduleName | |||
) ) | |||
end | |||
if #invokeList > 0 then | |||
table.insert( res, category ) | |||
end | |||
return table.concat( res ) | |||
end | end | ||
local function | ---@param moduleName string | ||
---@param addCategories boolean | |||
---@param whatLinksHere string @A list generated by a dpl of pages in the Template or Calculator namespace which link to moduleName. | |||
---@return string | |||
local function formatInvokedByList( moduleName, addCategories, whatLinksHere ) | |||
local function lcfirst( str ) | |||
return string.gsub( str, '^[Mm]odule:.', string.lower ) | |||
end | |||
local templateData = arr.map( whatLinksHere, function(x) return {templateName=x, invokeList=getInvokeCallList(x)} end ) | |||
templateData = arr.filter( templateData, function(x) | |||
return arr.any( x.invokeList, function(y) | |||
return lcfirst(y.moduleName) == lcfirst(moduleName) | |||
end ) | |||
end ) | |||
local invokedByList = {} | |||
for _, template in ipairs( templateData ) do | |||
for _, invoke in ipairs( template.invokeList ) do | |||
table.insert( invokedByList, string.format( "function '''%s''' is invoked by [[%s]]", invoke.funcName, template.templateName ) ) | |||
end | |||
end | |||
table.sort( invokedByList) | |||
local res = {} | |||
if #invokedByList > COLLAPSE_LIST_LENGTH_THRESHOLD then | |||
table.insert( res, string.format( | |||
"<div class='seealso'>'''%s''' is invoked by %s.</div>", | |||
moduleName, | |||
collapseList( invokedByList, 'invokedBy', 'templates' )[1] | |||
) ) | |||
else | |||
for _, item in ipairs( invokedByList ) do | |||
table.insert( res, string.format( | |||
"<div class='seealso'>'''%s's''' %s.</div>", | |||
moduleName, | |||
item | |||
) ) | |||
end | |||
end | |||
if #templateData > 0 then | |||
moduleIsUsed = true | |||
table.insert( res, (addCategories and '[[Category:Template invoked modules]]' or '') ) | |||
end | |||
return table.concat( res ) | |||
end | |||
---@param moduleName string | |||
end | ---@param addCategories boolean | ||
---@param whatLinksHere string @A list generated by a dpl of pages in the Module namespace which link to moduleName. | |||
---@return string | |||
local function formatRequiredByList( moduleName, addCategories, whatLinksHere ) | |||
local childModuleData = arr.map( whatLinksHere, function ( title ) | |||
local lists = getRequireList( title ) | |||
return {name=title, requireList=lists.requireList, loadDataList=lists.loadDataList .. lists.loadJsonDataList} | |||
end ) | |||
local function | local requiredByList = arr.map( childModuleData, function ( item ) | ||
if arr.any( item.requireList, function(x) return x:lower()==moduleName:lower() end ) then | |||
if item.name:find( '%%' ) then | |||
return formatDynamicQueryLink( item.name ) | |||
else | |||
return '[[' .. item.name .. ']]' | |||
end | |||
end | |||
end ) | |||
local loadedByList = arr.map( childModuleData, function ( item ) | |||
if arr.any( item.loadDataList, function(x) return x:lower()==moduleName:lower() end ) then | |||
if item.name:find( '%%' ) then | |||
return formatDynamicQueryLink( item.name ) | |||
else | |||
return '[[' .. item.name .. ']]' | |||
end | |||
end | |||
end ) | |||
if #requiredByList > 0 or #loadedByList > 0 then | |||
moduleIsUsed = true | |||
end | |||
if #requiredByList > COLLAPSE_LIST_LENGTH_THRESHOLD then | |||
requiredByList = collapseList( requiredByList, 'requiredBy', 'modules' ) | |||
end | |||
if #loadedByList > COLLAPSE_LIST_LENGTH_THRESHOLD then | |||
loadedByList = collapseList( loadedByList, 'loadedBy', 'modules' ) | |||
end | |||
local res = {} | |||
for _, requiredByModuleName in ipairs( requiredByList ) do | |||
end | table.insert( res, string.format( | ||
"<div class='seealso'>'''%s''' is required by %s.</div>", | |||
moduleName, | |||
requiredByModuleName | |||
) ) | |||
end | |||
if #requiredByList > 0 then | |||
table.insert( res, (addCategories and '[[Category:Modules required by modules]]' or '') ) | |||
end | |||
for _, loadedByModuleName in ipairs( loadedByList ) do | |||
table.insert( res, string.format( | |||
"<div class='seealso'>'''%s''' is loaded by %s.</div>", | |||
moduleName, | |||
loadedByModuleName | |||
) ) | |||
end | |||
if #loadedByList > 0 then | |||
table.insert( res, (addCategories and '[[Category:Module data]]' or '') ) | |||
end | |||
return table.concat( res ) | |||
end | end | ||
local function | local function formatImportList( currentPageName, moduleList, id, message, category ) | ||
if #moduleList > COLLAPSE_LIST_LENGTH_THRESHOLD then | |||
moduleList = collapseList( moduleList, id, 'modules' ) | |||
end | |||
local res = arr.map( moduleList, function( moduleName ) | |||
return '<div class="seealso">' .. string.format( message, currentPageName, moduleName ) .. '</div>' | |||
end ) | |||
if #moduleList > 0 and category then | |||
table.insert( res, string.format( '[[Category:%s]]', category ) ) | |||
end | |||
return table.concat( res ) | |||
end | end | ||
local function | local function formatUsedTemplatesList( currentPageName, addCategories, usedTemplateList ) | ||
local res = {} | |||
if #usedTemplateList > COLLAPSE_LIST_LENGTH_THRESHOLD then | |||
usedTemplateList = collapseList( usedTemplateList, 'usedTemplates', 'templates' ) | |||
end | |||
for _, templateName in ipairs( usedTemplateList ) do | |||
table.insert( res, string.format( | |||
"<div class='seealso'>'''%s''' transcludes %s using <samp>frame:preprocess()</samp>.</div>", | |||
currentPageName, | |||
templateName | |||
) ) | |||
end | |||
return table.concat( res ) | |||
end | end | ||
function p.main( frame ) | |||
local args = frame:getParent().args | |||
return p._main( args[1], args.category, args.isUsed ) | |||
end | end | ||
---@param currentPageName string|nil | |||
---@param addCategories boolean|string|nil | |||
---@return string | |||
function p._main( currentPageName, addCategories, isUsed ) | |||
libraryUtil.checkType( 'Module:RequireList._main', 1, currentPageName, 'string', true ) | |||
libraryUtil.checkTypeMulti( 'Module:RequireList._main', 2, addCategories, {'boolean', 'string', 'nil'} ) | |||
libraryUtil.checkTypeMulti( 'Module:RequireList._main', 3, isUsed, {'boolean', 'string', 'nil'} ) | |||
local title = mw.title.getCurrentTitle() | |||
-- Leave early if not in module, template or calculator namespace or if module is part of exchange or data groups | |||
if param.is_empty( currentPageName ) and ( | |||
( not arr.contains( {'Module', 'Template', 'Calculator'}, title.nsText ) ) or | |||
( title.nsText == 'Module' and ( arr.contains( {'Exchange', 'Exchange historical', 'Data'}, title.text:match( '^(.-)/' ) ) ) ) | |||
) then | |||
return '' | |||
end | |||
currentPageName = param.default_to( currentPageName, title.fullText ) | |||
currentPageName = string.gsub( currentPageName, '/[Dd]oc$', '' ) | |||
currentPageName = formatPageName( currentPageName ) | |||
addCategories = yn( param.default_to( addCategories, title.subpageText~='doc' ) ) | |||
moduleIsUsed = yn( param.default_to( isUsed, false ) ) | |||
if title.text:lower():find( 'sandbox' ) then | |||
moduleIsUsed = true -- Don't show sandbox modules as unused | |||
end | |||
if currentPageName:find( '^Template:' ) or currentPageName:find( '^Calculator:' ) then | |||
local invokeList = getInvokeCallList( currentPageName ) | |||
return formatInvokeCallList(currentPageName, addCategories, invokeList) | |||
end | |||
local whatTemplatesLinkHere, whatModulesLinkHere = dpl.ask( { | |||
namespace = 'Template|Calculator', | |||
linksto = currentPageName, | |||
distinct = 'strict', | |||
ignorecase = true, | |||
ordermethod = 'title', | |||
allowcachedresults = true, | |||
cacheperiod = 604800 -- One week | |||
}, { | |||
namespace = 'Module', | |||
linksto = currentPageName, | |||
nottitlematch = '%/doc|Exchange/%|Exchange historical/%|Data/%|' .. currentPageName:gsub( 'Module:', '' ), | |||
distinct = 'strict', | |||
ignorecase = true, | |||
ordermethod = 'title', | |||
allowcachedresults = true, | |||
cacheperiod = 604800 -- One week | |||
} ) | |||
local lists = getRequireList( currentPageName, true ) | |||
local requireList = arr.map( lists.requireList, function ( moduleName ) | |||
if moduleName:find( '%%' ) then | |||
return formatDynamicQueryLink( moduleName ) | |||
elseif builtins[moduleName] then | |||
return '[[' .. builtins[moduleName].link .. '|' .. moduleName .. ']]' | |||
else | |||
return '[[' .. moduleName .. ']]' | |||
end | |||
end ) | |||
local loadDataList = arr.map( lists.loadDataList, function ( moduleName ) | |||
end | if moduleName:find( '%%' ) then | ||
return formatDynamicQueryLink( moduleName ) | |||
else | |||
return '[[' .. moduleName .. ']]' | |||
end | |||
end ) | |||
function | local loadJsonDataList = arr.map( lists.loadJsonDataList, function ( moduleName ) | ||
if moduleName:find( '%%' ) then | |||
return formatDynamicQueryLink( moduleName ) | |||
end | else | ||
return '[[' .. moduleName .. ']]' | |||
end | |||
end ) | |||
local usedTemplateList = arr.map( lists.usedTemplateList, function( templateName ) | |||
if string.find( templateName, ':' ) then -- Real templates are prefixed by a namespace, magic words are not | |||
return '[['..templateName..']]' | |||
else | |||
return "'''{{"..templateName.."}}'''" -- Magic words don't have a page so make them bold instead | |||
end | |||
end ) | |||
local res = {} | |||
table.insert( res, formatInvokedByList( currentPageName, addCategories, whatTemplatesLinkHere ) ) | |||
table.insert( res, formatImportList( currentPageName, requireList, 'require', "'''%s''' requires %s.", addCategories and 'Modules requiring modules' ) ) | |||
table.insert( res, formatImportList( currentPageName, loadDataList, 'loadData', "'''%s''' loads data from %s.", addCategories and 'Modules using data' ) ) | |||
table.insert( res, formatImportList( currentPageName, loadJsonDataList, 'loadJsonData', "'''%s''' loads data from %s.", addCategories and 'Modules using data' ) ) | |||
table.insert( res, formatUsedTemplatesList( currentPageName, addCategories, usedTemplateList ) ) | |||
table.insert( res, formatRequiredByList( currentPageName, addCategories, whatModulesLinkHere ) ) | |||
if addCategories then | |||
local extraCategories = arr.map( lists.extraCategories, function( categoryName ) | |||
return "[[Category:" .. categoryName .. "]]" | |||
end ) | |||
table.insert( res, table.concat( extraCategories ) ) | |||
end | |||
if not moduleIsUsed then | |||
table.insert( res, 1, messageBoxUnused( currentPageName:gsub( 'Module:', '' ), addCategories ) ) | |||
end | |||
return table.concat( res ) | |||
end | end | ||
return p | return p | ||