Difference between revisions of "Module:Img"

From Idlescape Wiki
Jump to navigation Jump to search
(Add optional parameter 'type' to force the module to search images only for the given type e.g. 'item' or 'ability')
(Add missing param 'link' to link to a different page and not to the image name, as described in /doc)
Line 287: Line 287:
 
         alt = _args['alt']
 
         alt = _args['alt']
 
     end
 
     end
     s = image(name, url, width, height, word, alt, nolink, nocap)
+
     s = image(_args['link'] or name, url, width, height, word, alt, nolink, nocap)
 
     return s
 
     return s
 
end
 
end
  
 
return p
 
return p

Revision as of 18:26, 4 June 2025


local p = {}

local findId = require('Module:FindId')

local dataModuleNames = {
    item = 'Module:Items/data',
    enchantment = 'Module:Enchantment/data',
    location = 'Module:Location/data',
    monster = 'Module:Monsters/data',
    ability = 'Module:Abilities/data',
    other = 'Module:OtherImages/data',
}

local idListType = {
    [1] = {
        [1] = 'item',
        [2] = 'itemImage',
        [3] = 'itemIcon'
    },
    [2] = {
        [1] = 'monster',
        [2] = 'image'
    },
    [3] = {
        [1] = 'enchantment',
        [2] = 'buffIcon'
    },
    [4] = {
        [1] = 'location',
        [2] = 'locationImage'
    },
    [5] = {
        [1] = 'ability',
        [2] = 'abilityImage'
    }
}

local loadedDataModules = {}

local alternativeNames = {
    ['fishing_(enchantment)'] = 23,
    ['cooking_(enchantment)'] = 24,
    ['crafting_(enchantment)'] = 25,
    ['runecrafting_(enchantment)'] = 27,
    ['farming_(enchantment)'] = 39,
    fishing = 0,
    cooking = 0,
    crafting = 0,
    farming = 0,
    runecrafting = 0
}

--
-- Loads data modules
--
-- @param dataType {string}
-- @return {data table}
--
function p.loadData (dataType)
    local moduleName = dataModuleNames[dataType]
    if loadedDataModules[moduleName] == nil then
        local status, module = pcall(mw.loadData, moduleName)
        if not status then
            status, module = pcall(require, moduleName)
        end
        if status then
            loadedDataModules[moduleName] = module
        else
            error("Failed to load module: " .. moduleName .. "\n" .. module)
        end
    end
    return loadedDataModules[moduleName]
end

--
-- Helps capitalize the first letter of each word
--
-- @param first {string}
-- @param rest {string}
-- @return {strings}
--
local function tchelper(first, rest)
    return first:upper() .. rest:lower()
end

--
-- Capitalize the first letter of a word in a string
--
-- @param s {string}
-- @return {string}
--
local function capitalize(s)
    s = s:gsub('(%a)([%w_\']*)', tchelper):gsub(' Of ',' of '):gsub(' The ',' the '):gsub('Ii+ ', string.upper):gsub('Ii+$', string.upper):gsub(" A(n?) ", " a%1 ")
    return s
end

--
-- Hyphenates name
--
-- @param name {string}
-- @return {string}
--
local function hyphenateName(name)
    local lName = name:lower()
    return lName:gsub('^%s*(.-)%s*$', '%1'):gsub('%s+', '_')
end

--
-- Generates a full url
--
-- @param url {string}
-- @return {string}
--
local function fullUrl(url)
    local newUrl = url
    if url:sub(1, 5) == 'https' then
        return newUrl
    end

    if url:sub(1, 1) ~= '/' then
        newUrl = '/' .. newUrl
    end

    newUrl = 'https://www.play.idlescape.com' .. newUrl
    return newUrl
end

--
-- Finds input's id and input's type
--
-- @param name {string}
-- @return {number}
-- @return {string}
local function findInputId(name)
    local id
    local inputType
    for index, value in ipairs(idListType) do
        id = findId._findId({name, value[1]})
        if type(id) == 'number' then
            inputType = value[1]
            return id , inputType
        end
    end
    return 0
end

--
-- Finds arg's image url
--
-- @param id {number}
-- @param inputType {string}
-- @return {string}
--
local function findImageUrl(id, inputType)
    local imageUrl
    for index, value in ipairs(idListType) do
        if value[1] == inputType then
            if inputType == 'item' then
                if p.loadData(inputType)[tostring(id)][value[3]] then
                    return fullUrl(p.loadData(inputType)[tostring(id)][value[3]])
                end
            end
            imageUrl = fullUrl(p.loadData(inputType)[tostring(id)][value[2]])
            return imageUrl
        end
    end
    return 0
end

local function pageUrl(name)
    return '/p/' .. name:gsub('^%s*(.-)%s*$', '%1'):gsub('%s+', '_'):gsub('\'', '%%27')
end

--
-- Generates string with page link and <img> tag
--
-- @param name {string}
-- @param url {string}
-- @param width {number}
-- @param height {number}
-- @param word {bool}
-- @param alt {string}
-- @param nolink {bool}
-- @param nocap {bool}
-- @return {string}
--
local function image(name, url, width, height, word, alt, nolink, nocap)
    name = nocap and name or capitalize(name)
    local s = ''
    url = ' src=\''.. url .. '\''
    alt = ' alt=\''.. alt .. '\''
    width = ' width=\'' .. width .. 'px\''
    height = ' height=\'' .. height .. 'px\''
    local img = '<img' .. url .. alt .. width .. height ..'>'
    if word then
        s = img .. ' ' .. name
    else
        s = img
    end
    if not nolink then
        s = '[[' .. name .. '|' .. s .. ']]'
    end
    if word then
        s = '<span style=\'white-space: nowrap;\'>' .. s .. '</span>'
    end
    return s
end

--
-- Finds otherimage
--
-- @param name {string}
-- @return {string}
--
local function findOtherImageUrl(name)
    local h_name = hyphenateName(name)
    for key, value in pairs(p.loadData('other')) do
        if h_name == key then
            return value
        end
    end
    return 0
end

--
-- Main img method accessed through #invoke
--
-- @param frame {table}
-- @return {string}
--
function p.img(frame)
    return p._img(frame:getParent().args)
end

--
-- img method to allow it to be called by other modules
--
-- @param _args {table}
-- @return {string}
--
function p._img(_args)
    local name = _args[1]
    local width = _args[2]
    local height = _args[3]
    local id
    local input_type = _args['type']
    local url
    local word = _args['word'] == '1'
    local alt
    local nolink = _args['nolink'] == '1'
    local nocap = _args['nocap'] == '1'
    local s
    local error
    if not width then
        width = 20
    end
    if not height then
        height = width
    end
    if not name then
        return 'Couldn\'t get name'
    end
    if alternativeNames[hyphenateName(name)] then
        id = alternativeNames[hyphenateName(name)]
        input_type = 'enchantment'
    elseif input_type then
        id = findId._findId({name, input_type})
    else
        id, input_type = findInputId(name)
    end
    if id == 0 then
        url = findOtherImageUrl(name)
    end
    if url == 0 then
        error = '<span class=\'rt-commentedText tooltip tooltip-dotted\' title=\'Given name does not exist in any of the data modules. Please check spelling or update data modules.\'>' .. name .. '</span>'
        return error
    end
    if not url then
        url = findImageUrl(id, input_type)
    end
    if url == 0 then
        return 'couldn\'t find image url.'
    end
    if not _args['alt'] then
        alt = name
    else
        alt = _args['alt']
    end
    s = image(_args['link'] or name, url, width, height, word, alt, nolink, nocap)
    return s
end

return p