Module:Skill table
Module documentation
This documentation is transcluded from Template:No documentation/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:Skill table/doc. [edit]
Module:Skill table's function main is invoked by Template:Skill table.
Module:Skill table requires Module:Paramtest.
Module:Skill table requires Module:SCP.
Module:Skill table requires Module:Yesno.
local p = {}
local scp = require('Module:SCP')._main
local yesNo = require('Module:Yesno')
local paramTest = require('Module:Paramtest')
local trim = mw.text.trim
local split = mw.text.split
local ustring = mw.ustring
local listToText = mw.text.listToText
function plinkify(tbl)
if tbl == nil then
return nil
elseif type(tbl) == 'string' then
tbl = {tbl}
end
for i, v in ipairs(tbl) do
local name = ustring.gsub(v, '[^%[]*%[%[:?([^%|]+).*', '%1')
local fileName = ustring.match(name, '[^%#]+') -- Remove #foo from image name
if(not mw.title.new(fileName .. '.png', 'File'):getContent()) then -- If file doesnt exist, just use name
tbl[i] = '[[' .. name .. ']]'
else
tbl[i] = '[[File:' .. fileName .. '.png|link=' .. name .. '|frameless|35x35px]] [[' .. name .. ']]'
end
end
return table.concat(tbl, '<br/>')
end
-- val index in arr
function indexOf(tbl, val, doSearch)
for i, item in ipairs(tbl) do
if item == val then
return i
elseif doSearch and string.find(item, val) then
return i
end
end
return 0
end
function buildRow(page, skillName, images, columns)
local row = mw.html.create('tr')
-- First cell, image/icon
local image = getLastElement(page['Image']) or getLastElement(page['All Image']) or getLastElement(page['Parent Image'])
local icon = getLastElement(page['Icon'])
-- If images is set to icons, prefer icon over images. If its not icon, prefer image over icon
local pic = images == 'icons' and (icon or image) or (image or icon)
-- If images is set to icons, set smaller size, otherwise set larger size
local imageSize = images == 'icons' and '35x35px' or '120x120px'
if(pic) then
row:tag('td'):wikitext('[[' .. pic .. '|frameless|' .. imageSize .. '|center|link=' .. page[1] .. ' ]]')
else
row:tag('td'):wikitext('(?)')
end
-- Second cell, page name + verisoning (if applicable)
local title = split(page[1], '#')[1]
local subtitle = split(page[1], '#')[2]
row:tag('td'):wikitext(string.format("[[%s|%s]]%s", page[1], title, subtitle and ' <small>('..string.gsub(subtitle, '_', ' ')..')</small>' or ''))
-- Third cell (optional), members
if(columns['membersColumn']) then
if(page['Is members only'] or page['All Is members only'] or page['Parent Members']) then
row:tag('td'):wikitext('[[File:Member icon.png|link=|Members]]')
else
row:tag('td'):wikitext('[[File:Free-to-play icon.png|link=|Free-to-play]]')
end
end
-- Fourth cell, skill level requirement
local skillLevels = page[skillName .. ' level']
local skillStr = ''
if(type(skillLevels) == 'table') then
for i, skillLevel in ipairs(skillLevels) do
skillStr = skillStr .. scp(skillName, skillLevel, 'yes') .. '<br/>'
end
else
skillStr = scp(skillName, skillLevels, 'yes')
end
if skillStr == '' then skillstr = '(?)' end
row:tag('td'):wikitext(skillStr)
-- Fifth cell, skill experience yield
row:tag('td'):wikitext(concatenateTable(page[skillName..' experience']) or '(?)')
-- Sixth cell, materials
if(columns['materialsColumn']) then
row:tag('td'):wikitext(plinkify(page['Uses material']))
end
-- Seventh cell, tools
if(columns['toolsColumn'])then
row:tag('td'):wikitext(plinkify(page['Uses tool']))
end
-- Eighth cell, facilities
if(columns['facilitiesColumn']) then
row:tag('td'):wikitext(concatenateTable(page['Uses facility']))
end
-- Ninth cell, facilities
if type(page['Uses skill']) == 'table' then
-- Remove primary skill information displayed in previous cells
table.remove(page['Uses skill'], indexOf(page['Uses skill'], skillName, true))
elseif string.find(page['Uses skill'] or '', skillName) then
-- If the singular string is of primary skill, set to nil as there are no other skills to display
page['Uses skill'] = nil
else
-- Not a table, but also not just the original skill (somehow). Convert to table to avoid errors.
page['Uses skill'] = {page['Uses skill']}
end
-- Convert other skills information to be SCPs, these do not include levels because it would require further smw and pre-emptive knowledge otherwise grabbing all skills info
if page['Uses skill'] then
for i, skill in ipairs(page['Uses skill']) do
page['Uses skill'][i] = scp(skill, nil, 'yes')
end
end
if(columns['otherSkillsColumn']) then
row:tag('td'):wikitext(page['Uses skill'] and table.concat(page['Uses skill'], '<br/>') or '')
end
return row
end
function createHeader(skill, columns)
local tabl = mw.html.create('table'):addClass('wikitable sortable sticky-header align-center-1'):done()
local header = tabl:tag('tr')
header:tag('th'):attr('colspan', '2'):wikitext('Name')
if(columns['membersColumn']) then
tabl:addClass('align-center-3')
header:tag('th'):wikitext('[[File:Member icon.png|link=|Members]]')
end
header:tag('th'):wikitext(skill..' level')
header:tag('th'):wikitext(skill..' XP')
if(columns['materialsColumn']) then
header:tag('th'):wikitext('Materials used')
end
if(columns['toolsColumn']) then
header:tag('th'):wikitext('Tools used')
end
if(columns['facilitiesColumn']) then
header:tag('th'):wikitext('Facilities used')
end
if(columns['otherSkillsColumn']) then
header:tag('th'):wikitext('Skills involved')
end
return tabl
end
function shouldExclude(property, exclusionList)
for _, exclusion in ipairs(exclusionList) do
if((paramTest.has_content(exclusion)) and (ustring.find(string.lower(concatenateTable(property) or ''), string.lower(trim(exclusion))))) then
return true
end
end
return false
end
function tableConcat(mainTable, newTable, exclusionList)
for i = 1, #newTable, 1 do
-- Only add pages not using excluded materials
if(not((newTable[i]['Uses infobox'] == 'Pure') or (shouldExclude(newTable[i]['Uses material'], exclusionList)))) then
mainTable[#mainTable+1] = newTable[i]
end
end
return mainTable
end
function getLastElement(tbl)
return type(tbl) == 'table' and tbl[#tbl] or tbl
end
function concatenateTable(tbl)
return type(tbl) == 'table' and listToText(tbl, ', ', ' and ') or tbl
end
function loadData(strictExp, skillName, membersColumn, exclusionList, limit, batchSize, altQuery)
local allData = {}
local query = {
"[[" .. skillName .. " level::+]]" .. strictExp .. "[[" .. skillName .. " experience::>>0]]",
"?=#-",
"?Image#-",
"?All Image#-",
"?Is variant of.All Image#-=Parent Image",
"?Icon#-",
--"?All Icon#-",
--"?Is variant of.All Icon#-=Parent Icon",
"?Uses material",
"?Uses tool",
"?Uses facility",
"?Uses skill#-",
"?Uses infobox",
"?" .. skillName .. " level",
"?" .. skillName .. " experience",
limit = batchSize,
offset = 0,
}
-- Only fetch members data if the members column is going to be shown
if(membersColumn) then
table.insert(query, "?Is members only")
table.insert(query, "?All Is members only")
table.insert(query, "?Is variant of.All Is members only=Parent Members")
end
-- prepend AND append, to make sure the custom query gets applied to both sides of the OR
if(altQuery) then
query[1] = altQuery .. query[1] .. altQuery
end
for i = 0, limit, batchSize do
query.limit = batchSize
query.offset = i
local t1 = os.clock()
local smwData = mw.smw.ask(query)
local t2 = os.clock()
if(smwData == nil) then break end
mw.log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smwData, (t2 - t1) * 1000))
tableConcat(allData, smwData, exclusionList)
end
if(allData == nil) then
error("No results found for the specified query.")
end
return allData
end
function p._main(args)
-- Strict requests experience >0
local strictExp = (yesNo(args.strict) or false) and '' or ' OR '
local skillName = trim(args.skill)
local limit = paramTest.default_to(tonumber(args.limit), 5000) -- Acting as a real limiter
local batchSize = paramTest.default_to(tonumber(args.batchsize), 100)
--Table columns
local columns = {
membersColumn = yesNo(args.members or '', true),
materialsColumn = yesNo(args.materials or '', true),
toolsColumn = yesNo(args.tools or '', true),
facilitiesColumn = yesNo(args.facilities or '', true),
otherSkillsColumn = yesNo(args['other skills'] or '', true),
}
local exclusions = split(args['exclude material'] or '', ',')
local images = string.lower(args.images or '')
local data = loadData(strictExp, skillName, columns['membersColumn'], exclusions, limit, batchSize, args.query)
local ret = createHeader(skillName, columns)
for i, page in pairs(data) do
ret:node(buildRow(page, skillName, images, columns))
end
return ret
end
function p.main(frame)
local args = frame:getParent().args
--mw.logObject(args)
return p._main(args)
end
return p