Module:Infobox
Helper functions for formatting infobox data and autocategorization based on it.
infobox.location(frame)(function)- Formats a location parameter. Complex logic in this function is supposed to both deduce which location is something happening in and which page should the page be categorized under. Location parameters that pass through this function are even allowed to be separated by bullet points and it'll parse them as separate locations. Location formats parsed by this function are: Invalid locations are trimmed and returned.
- Parameter:
frameScribunto frame object (table) - Returns: Formatted location (string)
infobox.itemtype(frame)(function)- Formats an item's type and weapon subtype.
- Parameter:
frameScribunto's frame object (table) - Returns: Formatted item type and weapon subtype (string)
infobox.act(frame)(function)- Formats a given enemy's ACT field in the infobox.
- Parameter:
frameScribunto frame object (table) - Returns: Formatted ACTs (string)
infobox.paramcat(frame)(function)- Used for appending the Enemies category if the
goldargument is supplied, and the Vendors category if thewaresargument is supplied (this is how we determine their respective categories should be applied). - Parameter:
frameScribunto frame object (table) - Returns: The same thing with the category added (string)
infobox.undertale(frame)(function)- Formats the parameter for linking back to Undertale Wiki. Used only on Deltarune Wiki.
- Parameter:
frameScribunto frame object (table) - Returns: Formatted returning character parameter (string)
infobox.sell(frame)(function)- Automatically deduces an item's selling value based on its buying value. Used only on Deltarune Wiki.
- Parameter:
frameScribunto frame object (table) - Returns: Item's selling value (string)
infobox.locationcats()(function)- Categorizes a location page under Category:Locations, as well as under a category named by itself, if it exists.
- Returns: Location's categories (string)
infobox.itemdata(frame)(function)- Stores item infobox data in item and item_type buckets.
- Parameter:
frameScribunto frame object (table) infobox.itemtable(frame)(function)- Generates a table listing of items of a certain type.
- Parameter:
frameScribunto frame object (table) - Returns: Table with items listed (string)
infobox.classification(frame)(function)- Formats the infobox field for Lightner/Darkner classification and categorizes the article. Only used on Deltarune Wiki.
- Parameter:
frameScribunto frame object (table) - Returns: List of all subject classifications (string)
category(t, c, sortkey)(function • local)- Adds a category into a specified string (represented as a table). Only works if the current page is in the main namespace.
- Parameters:
--- Helper functions for formatting infobox data and autocategorization based on
-- it.
-- @module infobox
-- @alias p
-- @require Module:User error
-- @require Module:Yesno
-- @author [[User:KockaAdmiralac|KockaAdmiralac]]
-- @author [[User:Jacky720|Jacky720]]
-- <nowiki>
require('strict')
local p = {}
-- Package imports.
local yesno = require('Module:Yesno')
local util = require('Module:Util')
local data = mw.loadData('Module:Infobox/data')
-- Package variables.
local title = mw.title.getCurrentTitle()
-- Private logic.
--- Adds a category into a specified string (represented as a table).
-- Only works if the current page is in the main namespace.
-- @function category
-- @param {table} t String to insert the category in
-- @param {table} c Category to insert
-- @param {string|nil} sortkey The sort key for this category
-- @local
local function category(t, c, sortkey)
if sortkey == nil and title.text == c then
sortkey = '*'
end
-- TODO: Get rid of hardcoded page name, because other language wikis need
-- to translate this and it's not obvious.
if title.namespace == 0 and title.text ~= 'Items' then
table.insert(t, '[[Category:')
table.insert(t, c)
if sortkey ~= nil and sortkey ~= '' then
table.insert(t, '|')
table.insert(t, sortkey)
end
table.insert(t, ']]')
end
end
local function multicategory(t, c)
for _, cat in ipairs(c) do
category(t, cat)
end
end
-- Package items.
--- Formats a location parameter.
-- Complex logic in this function is supposed to both deduce which location is
-- something happening in and which page should the page be categorized under.
-- Location parameters that pass through this function are even allowed to
-- be separated by bullet points and it'll parse them as separate locations.
-- Location formats parsed by this function are:
-- <pre>Card Castle → [[Card Castle]]</pre>
-- <pre>[[Card Castle]] → [[Card Castle]]</pre>
-- <pre>Card Castle (F1) → [[Card Castle#F1|Card Castle]] (F1)</pre>
-- <pre>[[Card Castle]] (F1) → [[Card Castle#F1|Card Castle]] (F1)</pre>
-- <pre>Card Castle#F1 → [[Card Castle#F1|Card Castle]] (F1)</pre>
-- <pre>[[Card Castle#F1]] → [[Card Castle#F1|Card Castle]] (F1)</pre>
-- <pre>[[Island Board (Original Game)]] → [[Island Board (Original Game)]]</pre>
-- Invalid locations are trimmed and returned.
-- @function p.location
-- @param {table} frame Scribunto frame object
-- @returns {string} Formatted location
function p.location(frame)
local str = {}
local index = 0
local categories = {}
local infotype = frame.args[2]
for _, location in ipairs(mw.text.split(frame.args[1], '*', true)) do
local trimmed = mw.text.trim(location)
if trimmed ~= '' then
index = index + 1
if index == 2 then
table.insert(str, 1, '* ')
end
local link, text = mw.ustring.match(trimmed, '^%[%[([^%]]+)%]%]%s*%(?([^)]*)%)?$')
if link == nil then
link, text = mw.ustring.match(trimmed, '([^%](]+)%s*%(?([^)]*)%)?$')
end
if link then
link = mw.text.trim(link)
if index > 1 then
table.insert(str, '\n* ')
end
local spl = mw.text.split(link, '#', true)
local name = spl[1]
local hash = spl[2]
if text and text ~= '' and not hash then
hash = text
end
local ldata = data.locations[name]
if ldata then
if ldata.link then
link = ldata.link
end
if ldata.categories then
multicategory(categories, ldata.categories)
end
if ldata.condcats and infotype and ldata.condcats[infotype] then
multicategory(categories, ldata.condcats[infotype])
end
if ldata.nolink then
table.insert(str, link)
else
table.insert(str, '[[')
table.insert(str, name)
if hash then
table.insert(str, '#')
table.insert(str, hash)
table.insert(str, '|')
table.insert(str, name)
table.insert(str, ']]')
table.insert(str, ' (')
table.insert(str, hash)
table.insert(str, ')')
else
table.insert(str, ']]')
end
end
else
table.insert(str, trimmed)
end
end
end
end
return table.concat(str) .. table.concat(categories)
end
--- Formats an item's type and weapon subtype.
-- @function p.itemtype
-- @param {table} frame Scribunto's frame object
-- @returns {string} Formatted item type and weapon subtype
function p.itemtype(frame)
local str = {}
for _, itemtype in ipairs(mw.text.split(frame.args[1], ',', true)) do
itemtype = mw.text.trim(itemtype)
if data.itemtypes[itemtype] then
if str[1] then
if str[1] ~= '* ' then
table.insert(str, 1, '* ')
end
table.insert(str, '\n* ')
end
table.insert(str, itemtype)
-- Categorize as Swords, Axes, Scarves, or Rings instead, based on equip parameter
if itemtype == 'Weapon' and data.weapontypes[frame.args[2]] then
category(str, data.weapontypes[frame.args[2]], frame.args[3])
else
category(str, data.itemtypes[itemtype], frame.args[3])
end
end
end
return table.concat(str)
end
--- Formats a given enemy's ACT field in the infobox.
-- @function p.act
-- @param {table} frame Scribunto frame object
-- @returns {string} Formatted ACTs
function p.act(frame)
local str = {}
local index = 0
local nocheck = frame.args[2]
nocheck = mw.text.trim(nocheck)
nocheck = mw.text.split(nocheck, '%s*,%s*')
for _, battle in ipairs(mw.text.split(frame.args[1], '*', true)) do
-- battle: A given battle's ACTs, passed to the function
-- e.g. "Cry (First box encounter)"
-- acts: The ACTs OTHER than Check
-- e.g. "Cry"
-- form: The form or battle with these ACTs
-- e.g. "First box encounter"
-- "nocheck" parameter (frame.args[2]) prevents auto-adding Check.
battle = mw.text.trim(battle)
if battle ~= '' then
index = index + 1
if index == 2 then
table.insert(str, 1, '* ')
end
if index > 1 then
table.insert(str, '\n* ')
end
local acts, form = mw.ustring.match(battle, '^([^(]*)%s*%(?([^)]*)%)?$')
if not yesno(nocheck[index] or nocheck[1], false) then
if acts ~= '' then
table.insert(str, 'Check, ')
else
table.insert(str, 'Check ')
end
end
table.insert(str, acts)
if form ~= '' then
table.insert(str, ' (')
table.insert(str, form)
table.insert(str, ')')
end
end
end
return table.concat(str)
end
--- Used for appending the Enemies category if the <code>gold</code> argument
-- is supplied, and the Vendors category if the <code>wares</code> argument
-- is supplied (this is how we determine their respective categories should
-- be applied).
-- @function p.paramcat
-- @param {table} frame Scribunto frame object
-- @returns {string} The same thing with the category added
function p.paramcat(frame)
local param = frame.args[1]
if param == nil or param == '' then
return
end
local str = {param}
category(str, frame.args[2])
return table.concat(str)
end
--- Formats the parameter for linking back to Undertale Wiki.
-- Used only on Deltarune Wiki.
-- @function p.undertale
-- @param {table} frame Scribunto frame object
-- @returns {string} Formatted returning character parameter
function p.undertale(frame)
local str = {}
local names = frame.args[1]
if names == nil or names == '' then
return
end
if yesno(names, false) then
if frame.args[2] == '' then
-- No name specified
names = title.text
else
names = frame.args[2]
end
end
-- Iterate over multiple names
local namesList = {}
for _, splitName in ipairs(mw.text.split(names, ',', true)) do
local name = mw.text.trim(splitName)
table.insert(namesList, string.format('[[ut:%s|%s]]', name, name))
end
table.insert(str, table.concat(namesList, ', '))
if frame.args[2] == '' then
-- Don't include category for NPC pages with separated infoboxes
category(str, 'Returning characters')
end
return table.concat(str)
end
--- Automatically deduces an item's selling value based on its buying value.
-- Used only on Deltarune Wiki.
-- @function p.sell
-- @param {table} frame Scribunto frame object
-- @returns {string} Item's selling value
function p.sell(frame)
local val = tonumber(frame.args[1])
if val then
return math.ceil(val / 2) .. ' D$'
end
end
--- Categorizes a location page under [[:Category:Locations]], as well as under
-- a category named by itself, if it exists.
-- @function p.locationcats
-- @returns {string} Location's categories
function p.locationcats()
local cats = {}
category(cats, 'Locations')
if data.locationcats[title.text] then
category(cats, title.text)
end
return table.concat(cats)
end
--- Stores item infobox data in item and item_type buckets.
-- @function p.itemdata
-- @param {table} frame Scribunto frame object
function p.itemdata(frame)
if title.namespace ~= 0 then
return
end
local args = frame:getParent().args
local item = args.name or args.title or title.text
bucket('item').put({
name = item,
description = args.flavortext,
effects = args.effects and mw.text.killMarkers(args.effects) or nil,
source = args.source,
buy = args.buy,
id = args.id and tonumber(mw.ustring.match(args.id, '^%d+')) or 999
})
if args.type ~= nil then
for _, itemtype in ipairs(mw.text.split(args.type, ',', true)) do
bucket('item_type').put({item = item, type = mw.text.trim(itemtype)})
end
end
end
--- Generates a table listing of items of a certain type.
-- @function p.itemtable
-- @param {table} frame Scribunto frame object
-- @returns {string} Table with items listed
function p.itemtable(frame)
local itemtype = frame.args[1]
local data = bucket('item_type')
.where('type', itemtype)
.join('item', 'item_type.item', 'item.name')
.select(
'item.page_name',
'item.name',
'item.description',
'item.effects',
'item.source',
'item.buy',
'item.id'
)
.orderBy('item.id')
.run()
local itemtable = mw.html.create('table')
:attr('class', 'wikitable items-table')
:tag('tr')
:tag('th')
:wikitext('Name')
:done()
:tag('th')
:wikitext('Description')
:done()
:tag('th')
:wikitext('Effects')
:done()
:tag('th')
:wikitext('Source')
:done()
:tag('th')
:wikitext('Buy')
:done()
:done()
for _, item in ipairs(data) do
itemtable:tag('tr')
:tag('td')
:wikitext(table.concat({'[[', item['item.page_name'], '|', item['item.name'], ']]'}))
:done()
:tag('td')
:newline()
:wikitext(item['item.description'] or '')
-- See [[Module:Soundtrack]] for why we need the second newline.
:newline()
:done()
:tag('td')
:newline()
:wikitext(item['item.effects'] or 'N/A')
:newline()
:done()
:tag('td')
:newline()
:wikitext(p.location({args = {item['item.source'] or ''}}))
:newline()
:done()
:tag('td')
:newline()
:wikitext(item['item.buy'] or 'N/A')
:newline()
:done()
:done()
end
return tostring(itemtable:done())
end
--- Formats the infobox field for Lightner/Darkner classification and
-- categorizes the article. Only used on Deltarune Wiki.
-- @function p.classification
-- @param {table} frame Scribunto frame object
-- @returns {string} List of all subject classifications
function p.classification(frame)
local out = {}
for cat in mw.text.gsplit(frame.args[1], ',', true) do
local trimmedCat = mw.text.trim(cat)
if trimmedCat == 'Lightner' or trimmedCat == 'Darkner' then
table.insert(out, string.format('\n* [[%s]]', trimmedCat))
category(out, trimmedCat .. 's')
end
end
return table.concat(out)
end
function p.leitmotif(frame)
local formattedList = {}
for _, leitmotif in ipairs(util.parseCommaList(frame.args[1])) do
table.insert(formattedList, string.format(
'[[Leitmotifs#%s|%s]]',
leitmotif, leitmotif
))
end
return util.formatBulletList(formattedList)
end
return p
-- </nowiki>