|
|
(16 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
| local p = {} | | local p = {} |
| | |
| | --- Trims and parses the args into a table, then returns the table |
| | function p.normalise(args) |
| | |
| | for k, v in pairs(args) do |
| | v = mw.text.trim(tostring(v)) |
| | if v ~= '' then |
| | args[k] = v |
| | end |
| | end |
| | |
| | return args |
| | end |
|
| |
|
| --- Trims and parses the args into a table, then returns the table | | --- Trims and parses the args into a table, then returns the table |
Line 28: |
Line 41: |
| return icon | | return icon |
| else | | else |
| return 'NoImage.png' | | return 'NoIcon.png' |
| end | | end |
| | end |
| | |
| | function p.itemId(name) |
| | return name:gsub('%s+', '') .. 'Item' |
| end | | end |
|
| |
|
Line 44: |
Line 61: |
| end | | end |
| return set[item] ~= nil | | return set[item] ~= nil |
| end
| |
|
| |
| --- Build HTML code for an icon image.
| |
| -- @param name string
| |
| -- @param size string|nil One of: <code>"iconNormal"</code> (64px) or <code>"iconRecipe"</code> (44px). Default: <code>"iconNormal"</code>
| |
| -- @param bg string|nil
| |
| -- @param border string|nil
| |
| -- @param too_expensive boolean|nil
| |
| -- @author User:Avaren
| |
| function p.build_icon(name, link, size, bg, border, too_expensive)
| |
| local L = require('Module:Localization') -- local import
| |
|
| |
| if not size then
| |
| size = 'iconNormal'
| |
| end
| |
| local icon_bg
| |
| if bg then
| |
| icon_bg = bg
| |
| end
| |
| local icon_border
| |
| if border then
| |
| icon_border = border
| |
| end
| |
|
| |
| local item_data = mw.loadData('Module:ItemData')
| |
| local item = item_data.items[name]
| |
| local image
| |
| if item then
| |
| if item['group'] == L.t('Skill Books') then
| |
| image = 'SkillBook.png'
| |
| icon_bg = 'iconGold'
| |
| elseif item['group'] == L.t('Skill Scrolls') then
| |
| image = 'Skill Scroll'
| |
| icon_bg = 'iconGold'
| |
| -- Attempt to generate skill page
| |
| elseif in_array(L.t('Basic Research'), item['tagGroups']) then
| |
| image = string.sub(item['untranslated'], 1, -7):gsub('%s+', '') .. '_Icon.png'
| |
| icon_bg = 'paperBasic'
| |
| elseif in_array(L.t('Advanced Research'), item['tagGroups']) then
| |
| image = string.sub(item['untranslated'], 1, -10):gsub('%s+', '') .. '_Icon.png'
| |
| icon_bg = 'paperAdvanced'
| |
| elseif in_array(L.t('Modern Research'), item['tagGroups']) then
| |
| image = string.sub(item['untranslated'], 1, -8):gsub('%s+', '') .. '_Icon.png'
| |
| icon_bg = 'paperModern'
| |
| else
| |
| image = p.checkImage(item['untranslated'], too_expensive)
| |
| end
| |
| if not icon_bg then
| |
| if item['group'] == L.t('Food') then
| |
| icon_bg = 'iconGreen'
| |
| elseif item['carried'] == L.t('Hands') then
| |
| icon_bg = 'iconBrown'
| |
| end
| |
| end
| |
| else
| |
| image = p.checkImage(name, too_expensive)
| |
| end
| |
|
| |
| if not icon_bg then
| |
| icon_bg = 'iconBlue'
| |
| end
| |
|
| |
| if border then
| |
| icon_border = border
| |
| else
| |
| icon_border = 'borderBlue'
| |
| end
| |
|
| |
| if size == 'iconNormal' then
| |
| icon_container = 'iconContainer'
| |
| else
| |
| icon_container = 'iconContainerSmall'
| |
| end
| |
|
| |
| if not link then
| |
| link = ''
| |
| else
| |
| link = '|link='..link
| |
| end
| |
|
| |
| local file = '[[File:' .. image .. '|frameless|class=' .. size .. ' ' .. icon_bg .. link ..']]'
| |
| return '<div class="' .. icon_container .. '"><div class="iconStack">' .. file .. '</div><div class="iconBorder ' .. icon_border .. '" style="position:absolute;"></div></div>'
| |
| end
| |
|
| |
| --- Get HTML code for an icon image.
| |
| -- @author User:Avaren
| |
| function p.Icon(frame)
| |
| args = p.normaliseArgs(frame)
| |
| return p.build_icon(args.name, args.link, args.size, args.bg, args.border, args.too_expensive)
| |
| end | | end |
|
| |
|
Line 150: |
Line 78: |
| end | | end |
| return count | | return count |
| end
| |
|
| |
| --- Check if <code>value</code> is not <code>nil</code> and return it or if it is <code>nil</code> fall back to <code>default</code>.
| |
| -- @param value Value to check
| |
| -- @param default Value to fall back to
| |
| -- @return <code>value</code> if it is not <code>nil</code>
| |
| -- @return <code>default</code> if <code>value</code> is <code>nil</code>
| |
| -- @author User:Demian
| |
| -- @see valueOrDash
| |
| -- @see formatNilToYesNo
| |
| -- @see formatBoolToYesNo
| |
| function p.valueOrDefault(value, default)
| |
| return nil == value and default or value
| |
| end
| |
|
| |
| --- Check if <code>value</code> is not <code>nil</code> and return it or if it is <code>nil</code> fall back to the em-dash (—).
| |
| --
| |
| -- The em-dash (—) is commonly used represent a missing, not applicable (N/A), or a negative ("no") value with just a single character.
| |
| -- @param value Value to check
| |
| -- @return <code>value</code> if it is not <code>nil</code>
| |
| -- @return #string "—" if <code>value</code> is <code>nil</code>
| |
| -- @author User:Demian
| |
| -- @see valueOrDefault
| |
| function p.valueOrDash(value)
| |
| return nil == value and "—" or value
| |
| end
| |
|
| |
| --- Check if <code>value</code> is not <code>nil</code> and return "Yes" or "No".
| |
| -- @param value Value to check
| |
| -- @return #string "Yes" if <code>value</code> is not <code>nil</code>
| |
| -- @return #string "No" if <code>value</code> is <code>nil</code>
| |
| -- @author User:Demian
| |
| -- @see valueOrDefault
| |
| -- @usage formatNilToYesNo("Hello") == "Yes"
| |
| -- @usage formatNilToYesNo(nil) == "No"
| |
| function p.formatNilToYesNo(value)
| |
| -- TODO: Support i18n.
| |
| return nil == value and "No" or "Yes"
| |
| end
| |
|
| |
| --- Check if <code>value</code> <em>evaluates</em> as <code>true</code> and return "Yes" or "No".
| |
| -- @param value Value to evaluate. Does not have to be a bool.
| |
| -- @return #string "Yes" if <code>value</code> evaluates as <code>true</code>
| |
| -- @return #string "No" if <code>value</code> evaluates as <code>false</code>
| |
| -- @author User:Demian
| |
| -- @see valueOrDefault
| |
| -- @usage formatBoolToYesNo("") == true
| |
| -- @usage formatBoolToYesNo(123) == true
| |
| -- @usage formatBoolToYesNo(nil) == false
| |
| function p.formatBoolToYesNo(value)
| |
| -- TODO: Support i18n.
| |
| return value and "Yes" or "No"
| |
| end
| |
|
| |
| --- Format the input values into a string representing the range between the values.
| |
| --
| |
| -- Returning an an empty string intended to ease concatenation with other strings.
| |
| -- The en-dash (–) (instead of the hyphen-minus "-") is the appropriate character to signify a range of values.
| |
| -- @param #number min Minimum value (left side)
| |
| -- @param #number max Maximum value (right side)
| |
| -- @param #number default Default value in case of an error (only value).
| |
| -- @param #string valueFormat Format string used with <code>string.format</code>.
| |
| -- @return #string "<code>min</code>–<code>max</code>" if <code>min < max</code>
| |
| -- @return #string "<code>default</code>" formatted with <code>valueFormat</code> if <code>min == max</code> or <code>min > max</code> and <code>default ~= nil</code>
| |
| -- @return #string "" (empty string) if either <code>min</code> <strong>or</strong> <code>max</code> do not convert to a numerical value
| |
| -- @return #nil <code>nil</code> if <code>min == max</code> or <code>min > max</code> and <code>default == nil</code>
| |
| -- @author User:Demian
| |
| function p.toRangeString(min, max, default, valueFormat)
| |
| min = tonumber(p.valueOrDefault(min, nil))
| |
| max = tonumber(p.valueOrDefault(max, nil))
| |
| default = tonumber(p.valueOrDefault(default, nil))
| |
|
| |
| if nil ~= min and nil ~= max then
| |
| if min < max then
| |
| return string.format(string.format("%s–%s", valueFormat, valueFormat), min, max)
| |
| elseif nil == default then
| |
| return nil
| |
| else
| |
| return string.format(valueFormat, default)
| |
| end
| |
| end
| |
|
| |
| return ""
| |
| end
| |
|
| |
| --- Get all keys from <code>tbl</code> and sort them in alphabetical order.
| |
| -- @param #table tbl Table to get keys from
| |
| -- @return #table Input table keys in alphabetical order.
| |
| -- @author User:Demian
| |
| -- @see getSortedValues
| |
| function p.getSortedKeys(tbl)
| |
| local sorted = {}
| |
|
| |
| for key in pairs(tbl) do
| |
| table.insert(sorted, key)
| |
| end
| |
|
| |
| table.sort(sorted)
| |
|
| |
| return sorted
| |
| end
| |
|
| |
| --- Get all values from <code>tbl</code> and sort them in alphabetical order.
| |
| -- @param #table tbl Table to get values from
| |
| -- @return #table Input table values in alphabetical order.
| |
| -- @author User:Demian
| |
| -- @see getSortedKeys
| |
| function p.getSortedValues(tbl)
| |
| local sorted = {}
| |
|
| |
| for _, value in ipairs(tbl) do
| |
| table.insert(sorted, value)
| |
| end
| |
|
| |
| table.sort(sorted)
| |
|
| |
| return sorted
| |
| end
| |
|
| |
| --- Split <code>str</code> by the given character.
| |
| -- @param #string str String to split
| |
| -- @param #string separator String that separates values in <code>str</code>. May optionally be surrounded by 1 <em>whitespace</em> character by default.
| |
| -- @return #table Table of strings that were split from <code>str</code>.
| |
| -- @author User:Demian
| |
| -- @usage splitString("hello, world", ",") == {"hello", "world"}
| |
| function p.splitString(str, separator)
| |
| local tbl = {}
| |
|
| |
| for token in string.gmatch(str, string.format("%%s?([^%s]+)%%s?", separator)) do
| |
| table.insert(tbl, token)
| |
| end
| |
|
| |
| return tbl
| |
| end
| |
|
| |
| --- Sort items in the given list of values <code>str</code> separated with <code>separator</code> and return them as a single string.
| |
| -- @param #string str String with values separated by <code>separator</code>
| |
| -- @param #string separator String that separates values in <code>str</code>
| |
| -- @param #string joiner String used to join sorted values from <code>str</code>.
| |
| -- @return #string <code>str</code> with items sorted in alphabetical order.
| |
| -- @author User:Demian
| |
| -- @usage sortListString("Dog,Ape, Cat", ",", ";") == "Ape;Cat;Dog"
| |
| function p.sortListString(str, separator, joiner)
| |
| -- Split string by commas.
| |
| -- Sort items.
| |
| -- Rejoin into string.
| |
| return table.concat(p.getSortedValues(p.splitString(str, separator)), joiner)
| |
| end
| |
|
| |
| --- Check if a page with the title "<code>name</code> (<code>disambiguationTitle</code>)" exists in the database and return that page title, otherwise return "<code>name</code>".
| |
| --
| |
| -- Use sparingly as this uses a comparatively slow MediaWiki function p.to check if a page exists.
| |
| --
| |
| -- Using this function p.will create a new entry in the <code>Special:WantedPages</code> list.
| |
| -- Be careful when calling this function p.and do not pass garbage into its parameters so you do not clog up that list.
| |
| -- This is a long-standing issue with MediaWiki that has not yet been solved, and may not be possible to solve without an architectural change to the software.
| |
| -- @param #string name Name of a page.
| |
| -- @param #string disambiguationTitle Disambiguation clarifier in a page title.
| |
| -- @return #string "<code>name</code> (<code>disambiguationTitle</code>)"
| |
| -- @return #string "<code>name</code>"
| |
| -- @author User:Demian
| |
| function p.getDirectPageName(name, disambiguationTitle)
| |
| -- Try to get the actual end page instead of the disambiguation page if it exists.
| |
| -- E.g. Salmon has "Salmon (animal)" and "Salmon (item)" as well as the "Salmon" disambiguation page between these two.
| |
| local directPage = string.format("%s (%s)", name, disambiguationTitle)
| |
| return mw.title.new(directPage).exists and directPage or name
| |
| end
| |
|
| |
| --- Create a wikilink with [[square brackets]] from parameters.
| |
| -- @param #string pageName The actual name of a page to create a link to
| |
| -- @param #string displayText Text to display as a clickable link instead of the page name. If <code>nil</code>, <code>pageName</code> is displayed instead.
| |
| -- @param #bool twoLineDisplayText Force the <em>last word</em> of <code>displayText</code> on the next line
| |
| -- @return #string "[[<code>name</code>|<code>displayText</code>]]" if <code>displayText</code> is not <code>nil</code>
| |
| -- @return #string "[[<code>name</code>]]" if <code>displayText</code> is <code>nil</code> or the same string as <code>name</code>
| |
| -- @author User:Demian
| |
| function p.formatWikilink(pageName, displayText, twoLineDisplayText)
| |
| local finalDisplayText = p.valueOrDefault(displayText, pageName)
| |
|
| |
| if twoLineDisplayText then
| |
| local lastSpaceIdx = string.find(finalDisplayText, " [^ ]*$")
| |
|
| |
| if nil ~= lastSpaceIdx then
| |
| finalDisplayText = string.format("%s<br>%s", string.sub(finalDisplayText, 0, lastSpaceIdx-1), string.sub(finalDisplayText, lastSpaceIdx+1))
| |
| end
| |
| end
| |
|
| |
| if pageName == finalDisplayText then
| |
| return string.format("[[%s]]", pageName)
| |
| else
| |
| return string.format("[[%s|%s]]", pageName, finalDisplayText)
| |
| end
| |
| end | | end |
|
| |
|
| return p | | return p |
This module provides utility functions used from other modules.
Add the following line of code at the top of your file.
local Utils = require("Module:Utils")
-- You may then call functions from this module in your script. For example:
local tableLength = Utils.tableLen(myTable)
local p = {}
--- Trims and parses the args into a table, then returns the table
function p.normalise(args)
for k, v in pairs(args) do
v = mw.text.trim(tostring(v))
if v ~= '' then
args[k] = v
end
end
return args
end
--- Trims and parses the args into a table, then returns the table
-- @author User:Avaren
function p.normaliseArgs(frame)
local origArgs = frame:getParent().args
local args = {}
for k, v in pairs(origArgs) do
v = mw.text.trim(tostring(v))
if v ~= '' then
args[k] = v
end
end
return args
end
--- Get path to icon file.
-- @author User:Avaren
function p.checkImage(name, too_expensive)
local icon = name:gsub('%s+', '') .. '_Icon.png'
if too_expensive then
return icon
end
if mw.title.makeTitle('File', icon).file.exists then
return icon
else
return 'NoIcon.png'
end
end
function p.itemId(name)
return name:gsub('%s+', '') .. 'Item'
end
--- Check if <code>item</code> is in given <code>array</code>.
-- @param item Item to look for
-- @param #table array Table to check
-- @return #bool <code>true</code> if <code>item</code> is in <code>array</code>
-- @author User:Avaren
local function in_array(item, array)
-- Should only use on short arrays
local set = {}
for _, l in ipairs(array) do
set[l] = true
end
return set[item] ~= nil
end
--- Calculate the length of a table by iterating over every item in it.
--
-- <code>mw.LoadData</code> prevents <code>#tbl</code> from working correctly.
-- @param #table tbl Table to calculate the length of
-- @return #number Length of the table.
-- @author User:Avaren
function p.tableLen(tbl)
local count = 0
for _, v in ipairs(tbl) do
if v == nil then
return count
end
count = count + 1
end
return count
end
return p