Module:Icon list
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Icon list/doc
local p = {}
local lib = require('Module:Feature')
local Icon = require('Module:Icon')._main
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
parentFirst = true,
removeBlanks = false,
wrapper = { 'Template:Icon list' }
})
return p._main(args)
end
function p._main(args)
local input = args[1] or ''
local itemDelim = args.delim or ';'
local items = lib.split(input, itemDelim)
if next(items) == nil then
return mw.html.create('span')
else
return p.buildList(items, args)
end
end
local function splitNote(entry, notePattern)
if notePattern then
local item, note = entry:match(notePattern)
if item == nil then -- will be nil if note is not present
return entry
end
return item, note
end
return entry
end
local function splitParams(entry, paramDelim)
if entry:find('{.-}') then
local params = string.match(entry, '{(.-)}')
entry = entry:gsub('{.-}', '')
params = lib.split(params, paramDelim)
local returns = {}
for i, param in ipairs(params) do
local name, val = string.match(param, '^%s*(.-)%s*=%s*(.-)%s*$')
if name ~= nil and name ~= '' and val ~= nil then --named params
returns[name] = val
elseif param ~= nil and param ~= '' then --unnamed params
table.insert(returns, param)
end
end
return entry, returns
end
return entry, {}
end
function p.buildList(items, args)
local countDelim = args.amount_delim or '*'
local qualityDelim = args.quality_delim or '/'
local paramDelim = args.param_delim or '$'
local noteDelim = args.note_delim or '»'
local textPrefixDelim = args.text_prefix_delim or '«'
-- put all text after the first noteDelim into the second capture
local notePattern
if lib.isNotEmpty(noteDelim) then
notePattern = '^(.-)' .. noteDelim .. '(.*)$'
end
local display = args.display or 'stacked'
local remove = args.remove or ''
local useColumns = args.col == 'true' and true or false
local itemStrings = {}
for i, str in ipairs(items) do
if not lib.isEmpty(str) then
for num, entry in ipairs(lib.split(str, '//')) do
local entry, iconArgs = splitParams(entry, paramDelim) --check for entry-specific params
local pre, note = splitNote(entry, notePattern) --check for entry-specific note
local pre_parts = lib.split(pre, qualityDelim) --check for entry-specific note
local item = pre_parts[1]
local quality = pre_parts[2]
local item_parts = lib.split(item, countDelim) --check for entry-specific amount
local text_prefix_parts = lib.split(item_parts[1], textPrefixDelim) -- check for entry-specific prefix
local textPrefix = text_prefix_parts[2]
-- prefix is a text modifier only, so the link should not include it
local name = text_prefix_parts[1]
local amount = item_parts[2]
--set icon arguments without replacing those set by entry-specific params
iconArgs.name = iconArgs[1] or iconArgs.name or name
iconArgs.amount = iconArgs.amount or iconArgs[2] or amount or args.amount or args[2]
iconArgs.note = iconArgs.note or note
iconArgs.q = iconArgs.quality or quality or args.quality
iconArgs.text = iconArgs.text or args.text
iconArgs.textPrefix = iconArgs.textPrefix or args.textPrefix or textPrefix
iconArgs.size = iconArgs.size or args.size
iconArgs.link = iconArgs.link or args.link or link
iconArgs.ext = iconArgs.ext or args.ext
iconArgs.notext = iconArgs.notext or args.notext
iconArgs.nolink = iconArgs.nolink or args.nolink
iconArgs.prefix = iconArgs.prefix or args.prefix
iconArgs.suffix = iconArgs.suffix or args.suffix
local icon = Icon(iconArgs)
if remove == 'text' then
iconArgs.notext = true
icon = Icon(iconArgs)
elseif remove == 'link' then
iconArgs.nolink = true
icon = Icon(iconArgs)
end
table.insert(itemStrings, tostring(icon))
end
end
end
if display == 'stacked' then
return p.displayStacked(itemStrings, useColumns)
elseif display == 'ul' or display == 'bullet' then
return p.displayBullet(itemStrings, useColumns)
elseif display == 'checkbox' then
return p.displayCheckbox(itemStrings, useColumns, args.checklistId)
elseif display == 'inline' then
return p.displayInline(itemStrings)
elseif display == 'inline and' then
return p.displayInlineAnd(itemStrings)
elseif display == 'inline or' then
return p.displayInlineOr(itemStrings)
else
return p.displayStacked(itemStrings, useColumns)
end
end
function p.createColumns(items, useColumns)
local columnContainer = mw.html.create('div')
if useColumns then
columnContainer:css({
['column-gap'] = '1em',
['column-width'] = '220px',
['-moz-column-count'] = 'auto',
['-webkit-column-count'] = 'auto',
['column-count'] = 'auto'
})
end
for _, item in ipairs(items) do
columnContainer:node(item)
end
return columnContainer
end
function p.displayStacked(itemStrings, useColumns)
local itemContainers = {}
for _, itemString in ipairs(itemStrings) do
table.insert(itemContainers, mw.html.create('div'):wikitext(itemString))
end
if useColumns then
return tostring(p.createColumns(itemContainers, useColumns))
else
local container = mw.html.create('div'):addClass('icon-list-stacked')
for _, itemContainer in ipairs(itemContainers) do
container:node(itemContainer)
end
return tostring(container)
end
end
function p.displayBullet(itemStrings, useColumns)
local list = mw.html.create('ul')
for _, itemString in ipairs(itemStrings) do
list:tag('li'):wikitext(itemString)
end
if useColumns then
return tostring(p.createColumns({list}, useColumns))
else
return tostring(list)
end
end
function p.displayCheckbox(itemStrings, useColumns, checklistId)
local container = mw.html.create('div')
:attr('data-checklist', checklistId) -- Use the provided checklist identifier
:addClass('icon-list-container icon-list-checklist')
local list = mw.html.create('div') -- Use 'div' for block-level stacking
for _, itemString in ipairs(itemStrings) do
local itemData = mw.text.split(itemString, '>')
local itemName = itemData[2]:match('title="([^"]+)"')
local listItem = mw.html.create('div') -- Use 'div' for stacking
:attr('data-item', itemName)
:addClass('custom-icon')
:wikitext(itemString)
list:node(listItem)
end
container:node(list)
if useColumns then
return tostring(p.createColumns({container}, useColumns))
else
return tostring(container)
end
end
function p.displayInline(itemStrings)
local container = mw.html.create('span')
container:addClass('icon-list-inline')
for _, itemString in ipairs(itemStrings) do
container:wikitext(itemString .. ' ')
end
return tostring(container)
end
function p.displayInlineAnd(itemStrings)
local container = mw.html.create('span')
container:addClass('icon-list-inline-and')
for i, itemString in ipairs(itemStrings) do
if i == #itemStrings then
container:wikitext('and ' .. itemString)
else
container:wikitext(itemString .. ', ')
end
end
return tostring(container)
end
function p.displayInlineOr(itemStrings)
local container = mw.html.create('span')
container:addClass('icon-list-inline-or')
for i, itemString in ipairs(itemStrings) do
if i == #itemStrings then
container:wikitext('or ' .. itemString)
else
container:wikitext(itemString .. ', ')
end
end
return tostring(container)
end
return p