Aller au contenu

Module:Infobox

De Wiki Undertale FR

Helper functions for formatting infobox data and autocategorization based on it.

Documentation

Package items

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: frame Scribunto frame object (table)
Returns: Formatted location (string)
infobox.itemtype(frame) (function)
Formats an item's type and weapon subtype.
Parameter: frame Scribunto's frame object (table)
Returns: Formatted item type and weapon subtype (string)
infobox.mechanics(frame) (function)
Formats a game mechanic type.
Parameter: frame Scribunto frame object (table)
Returns: Formatted game mechanic type (string)
infobox.act(frame) (function)
Formats a given enemy's ACT field in the infobox.
Parameter: frame Scribunto frame object (table)
Returns: Formatted ACTs (string)
infobox.gold(Scribunto) (function)
Used for appending the Enemies category if the gold argument is supplied (this is how we determine whether a character is an enemy).
Parameter: Scribunto frame object (table)
Returns: The same thing with tne Enemies category added (string)
infobox.undertale(frame) (function)
Formats the parameter for linking back to Undertale Wiki. Used only on Deltarune Wiki.
Parameter: frame Scribunto frame object (table)
Returns: Formatted returning character parameter (string)
infobox.na(Scribunto) (function)
Displays N/A if a parameter is not supplied.
Parameter: Scribunto frame object (table)
Returns: "N/A" if the parameter is not supplied, the parameter value otherwise (string)
infobox.alternative(frame) (function)
Used in Template:Items when an item has multiple infoboxes on its article.
Parameter: frame Scribunto frame object (table)
Returns: A slash, then the alternative item name (string)
infobox.sell(frame) (function)
Automatically deduces an item's selling value based on its buying value. Used only on Deltarune Wiki.
Parameter: frame Scribunto frame object (table)
Returns: Item's selling value (string)
infobox.locationcats(frame) (function)
Categorizes a location page under Category:Locations, as well as under a category named by itself, if it exists.
Parameter: frame Scribunto frame object (table)
Returns: Location's categories (string)
infobox.itemdata(frame) (function)
Stores item infobox data in item and item_type buckets.
Parameter: frame Scribunto frame object (table)
infobox.itemtable(frame) (function)
Generates a table listing of items of a certain type.
Parameter: frame Scribunto frame object (table)
Returns: Table with items listed (string)

Private items

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:
  • t String to insert the category in (table)
  • c Category to insert (table)
  • sortkey The sort key for this category (string|nil)
--- 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 userError = require('Module:User error')
local yesno = require('Module:Yesno')
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 title.namespace == 0 and title.text ~= 'Objets' 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 &rarr; [[Card Castle]]</pre>
--  <pre>[[Card Castle]] &rarr; [[Card Castle]]</pre>
--  <pre>Card Castle (F1) &rarr; [[Card Castle#F1|Card Castle]] (F1)</pre>
--  <pre>[[Card Castle]] (F1) &rarr; [[Card Castle#F1|Card Castle]] (F1)</pre>
--  <pre>Card Castle#F1 &rarr; [[Card Castle#F1|Card Castle]] (F1)</pre>
--  <pre>[[Card Castle#F1]] &rarr; [[Card Castle#F1|Card Castle]] (F1)</pre>
--  <pre>[[Island Board (Original Game)]] &rarr; [[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 game mechanic type.
--  @function           p.mechanics
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Formatted game mechanic type
function p.mechanics(frame)
    local mtype = frame.args[1]
    if not mtype or not data.mechanics[mtype] then
        return userError(
            'Mechanic type invalid or not specified',
            'Pages avec des erreurs utilisateur'
        )
    end
    local data = data.mechanics[mtype]
    local str = {data.name}
    category(str, data.category)
    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, 'Examiner, ')
                else
                    table.insert(str, 'Examiner ')
                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 (this is how we determine whether a character is an enemy).
--  @function           p.gold
--  @param              {table} Scribunto frame object
--  @returns            {string} The same thing with tne Enemies category added
function p.gold(frame)
    local str = {frame.args[1]}
    category(str, 'Ennemis')
    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 index = 0
    local names = frame.args[1]
    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
    for _, name in ipairs(mw.text.split(names, ',', true)) do
        local trimmed = mw.text.trim(name)
        index = index + 1
        if index > 1 then
            table.insert(str, ', ')
        end
        table.insert(str, '[[ut:')
        table.insert(str, name)
        table.insert(str, '|')
        table.insert(str, name)
        table.insert(str, ']]')
    end
    
    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

--- Displays N/A if a parameter is not supplied.
--  @function           p.na
--  @param              {table} Scribunto frame object
--  @returns            {string} "N/A" if the parameter is not supplied, the
--                               parameter value otherwise
function p.na(frame)
    local val = mw.text.trim(frame.args[1])
    if val == '' then
        return 'N/A'
    else
        return val
    end
end

--- Used in [[Template:Items]] when an item has multiple infoboxes on its
--  article.
--  @function           p.alternative
--  @param              {table} frame Scribunto frame object
--  @returns            {string} A slash, then the alternative item name
function p.alternative(frame)
    local val = mw.text.trim(frame.args[1])
    if val ~= '' then
        return table.concat({'/', val})
    end
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
--  @param              {table} frame Scribunto frame object
--  @returns            {string} Location's categories
function p.locationcats(frame)
    local cats = {}
    category(cats, 'Lieux')
    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.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
	})
	for _, itemtype in ipairs(mw.text.split(args.type, ',', true)) do
		bucket('item_type').put({item = item, type = mw.text.trim(itemtype)})
	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('Nom')
			:done()
			:tag('th')
				:wikitext('Description')
			:done()
			:tag('th')
				:wikitext('Effets')
			:done()
			:tag('th')
				:wikitext('Origine')
			:done()
			:tag('th')
				:wikitext('Prix à l\'achat')
			: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 'Aucun')
				:newline()
			:done()
			:tag('td')
				:newline()
				:wikitext(p.location({args = {item['item.source'] or ''}}))
				:newline()
			:done()
			:tag('td')
				:newline()
				:wikitext(item['item.buy'] or 'Aucun')
				:newline()
			:done()
		:done()
	end
	return tostring(itemtable:done())
end

return p
--  </nowiki>