Test page

l10n info --------------

local l10n\_info = {
 ['en'] = {
 ['id\_text\_item'] = 'Internal Item ID: ',
 ['id\_text\_tile'] = 'Internal Tile ID: ',
 ['id\_text\_wall'] = 'Internal Wall ID: ',
 ['id\_text\_npc'] = 'Internal NPC ID: ',
 ['id\_text\_mount'] = 'Internal Mount ID: ',
 ['id\_text\_buff'] = 'Internal Buff ID: ',
 ['id\_text\_projectile'] = 'Internal Projectile ID: ',
 ['id\_text\_armor'] = 'Internal Armor ID: ',
 },
 ['de'] = {
 ['id\_text\_item'] = 'Interne Gegenstands-ID: ',
 ['id\_text\_tile'] = 'Interne Feld-ID: ',
 ['id\_text\_wall'] = 'Interne Wand-ID: ',
 ['id\_text\_npc'] = 'Interne NPC-ID: ',
 ['id\_text\_mount'] = 'Interne Reittier-ID: ',
 ['id\_text\_buff'] = 'Interne Statuseffekt-ID: ',
 ['id\_text\_projectile'] = 'Interne Projektil-ID: ',
 ['id\_text\_armor'] = 'Interne Projektil-ID: ',
 },
 ['fr'] = {
 ['id\_text\_item'] = 'ID interne de l\'objet : ',
 ['id\_text\_tile'] = 'ID interne de la tuile : ',
 ['id\_text\_wall'] = 'ID interne du mur : ',
 ['id\_text\_npc'] = 'ID interne du PNJ : ',
 ['id\_text\_mount'] = 'ID interne de la monture : ',
 ['id\_text\_buff'] = 'ID interne du buff : ',
 ['id\_text\_projectile'] = 'ID interne du projectile : ',
 ['id\_text\_armor'] = 'ID interne de l\'armure : ',
 },
 ['hu'] = {
 ['id\_text\_item'] = 'Tárgyi adatértéke: ',
 ['id\_text\_tile'] = 'Kockabeli adatértéke: ',
 ['id\_text\_wall'] = 'Fali adatértéke: ',
 ['id\_text\_npc'] = 'Ellenféli adatértéke: ',
 ['id\_text\_mount'] = 'Hátasbeli adatértéke: ',
 ['id\_text\_buff'] = 'Hatásbeli adatértéke: ',
 ['id\_text\_projectile'] = 'Lövedéki adatértéke: ',
 ['id\_text\_armor'] = 'Páncélbeli adatértéke: ',
 },
 ['it'] = {
 ['id\_text\_item'] = 'ID Oggetto Interno: ',
 ['id\_text\_tile'] = 'ID Tile Interno: ',
 ['id\_text\_wall'] = 'ID Muro Interno: ',
 ['id\_text\_npc'] = 'ID PNG Interno: ',
 ['id\_text\_mount'] = 'ID Montatura Interna: ',
 ['id\_text\_buff'] = 'ID Buff Interno: ',
 ['id\_text\_projectile'] = 'ID Proiettile Interno: ',
 ['id\_text\_armor'] = 'ID Armatura Interna: ',
 },
 ['ru'] = {
 ['id\_text\_item'] = 'Внутренний ID предмета: ',
 ['id\_text\_tile'] = 'Внутренний ID тайла: ',
 ['id\_text\_wall'] = 'Внутренний ID стены: ',
 ['id\_text\_npc'] = 'Внутренний ID существа: ',
 ['id\_text\_mount'] = 'Внутренний ID сред. передвиж.: ',
 ['id\_text\_buff'] = 'Внутренний ID бафа: ',
 ['id\_text\_projectile'] = 'Внутренний ID снаряда: ',
 ['id\_text\_armor'] = 'Внутренний ID брони: ',
 },
 ['zh'] = {
 ['id\_text\_item'] = '内部物品 ID：',
 ['id\_text\_tile'] = '内部图格 ID：',
 ['id\_text\_wall'] = '内部墙 ID：',
 ['id\_text\_npc'] = '内部 NPC ID：',
 ['id\_text\_mount'] = '内部坐骑 ID：',
 ['id\_text\_buff'] = '内部增益 ID：',
 ['id\_text\_projectile'] = '内部射弹 ID：',
 ['id\_text\_armor'] = '内部盔甲 ID：',
 },
}

 The following is not related to l10n. --------------

local trim = mw.text.trim
local cargo = mw.ext.cargo

local currentFrame
local args\_table
local lang
local l10n\_table

local l10n = function(key)
 return l10n\_table[key] or l10n\_info['en'][key]
end

local getArg = function(key)
 local value = args\_table[key]
 if not value then
 return nil
 end
 value = trim(value)
 if value ==  *then*
 return nil
 end
 return value
end

local function parse(str)
 local args = {}
 for s in string.gmatch(str, '%b@^') do
 local k,v = string.match(s, '^@(.-):(.\*)^$')
 args[k] = v
 end
 args[1] = args['name']
 args[2] = args['text']
 return args
end

-- credit: http://richard.warburton.it
-- this version is with trim.
local function explode(div,str)
 if (div==*) then return false end*
 local pos,arr = 0,{}
 -- for each divider found
 for st,sp in function() return string.find(str,div,pos,true) end do
 arr[#arr + 1] = trim(string.sub(str,pos,st-1)) -- Attach chars left of current divider
 pos = sp + 1 -- Jump past current divider
 end
 arr[#arr + 1] = trim(string.sub(str,pos)) -- Attach chars right of last divider
 return arr
end

local function parseSize(size)
 if not size then return end
 local basescale, width, height
 size, basescale = unpack(explode('\*', size))
 if size ~=  *then*
 width, height = unpack(explode('x', string.gsub(size, 'px', *)))*
 width, height = tonumber(width), tonumber(height)
 if width == 0 then width = nil end
 if height == 0 then height = nil end
 end
 return basescale, width, height
end

local function getInfoFromCargo(image)
 -- try to get from cargo cache
 local result = mw.ext.cargo.query('Imageinfo', 'width, height, cached', {
 where = 'image='.. "'"..image:gsub("'", "\\'"):gsub("'", "\\'").."'",
 orderBy = "cached DESC",
 limit = 1,
 })
 for \_, row in ipairs(result) do
 return tonumber(row['width']), tonumber(row['height']), row['cached']
 end
end

local function storeInfoToCargo(image)
 local width, height
 width = tonumber(currentFrame:callParserFunction( '#imgw', image))
 if width and width ~= 0 then -- save one expensive call when the file is not a valid image.
 height = tonumber(currentFrame:callParserFunction( '#imgh', image))
 if height and height ~= 0 then
 currentFrame:callParserFunction('#cargo\_store:\_table=Imageinfo',{
 image = image,
 width = width,
 height = height,
 cached = os.time(),
 })
 end
 end
 return width, height
end

local function getSizeInfo(image)
 local width, height, cached = getInfoFromCargo(image)
 -- cache missed, init cache
 if not cached then
 width, height = storeInfoToCargo(image)
 end
 if width == 0 then width = nil end
 if height == 0 then height = nil end
 return width, height
end

local function getImageSize(image, width, height, scale, maxwidth, maxheight)
 -- get size info from image file itself (may be expensive)
 local w, h = getSizeInfo(image) -- store data to cache

 if not width and not height and (scale or maxwidth or maxheight) then
 width, height = w, h
 end

 -- apply scale to width/height if needed
 if scale then
 if width then width = width \* scale end
 if height then height = height \* scale end
 end

 -- apply maxwidth/maxheight.
 if maxwidth then
 if width then
 if width > maxwidth then width = maxwidth end
 else
 if height then width = maxwidth end
 end
 end
 if maxheight then
 if height then
 if height > maxheight then height = maxheight end
 else
 if width then height = maxheight end
 end
 end

 -- rounding
 if width then width = math.ceil(width) end
 if height then height = math.ceil(height) end

 return width, height
end

local function parseMaxSize(maxsize)
 if not maxsize then return end
 local maxwidth, maxheight = unpack(explode('x', string.gsub(maxsize, 'px', *)))*
 maxwidth, maxheight = tonumber(maxwidth), tonumber(maxheight)
 if maxwidth == 0 then maxwidth = nil end
 if maxheight == 0 then maxheight = nil end
 return maxwidth, maxheight
end

local function imagecode(image, link, text, size, scale, maxsize)
 local image\_output = '' .. (width or ) .. 'x' .. (height or ) .. 'px'
 else
 return image\_output .. ']]'
 end
 else
 return image\_output .. ']]'
 end
end

local function images(image, link, text, size, scale, maxsize)

 if not image:find('/') then
 return imagecode(image, link, text, size, scale, maxsize)
 end

 image = explode('/', image)
 local result =
 if size and size:find('/') then
 size = explode('/', size)
 for i, v in ipairs(image) do
 result = result .. imagecode(v, link, text, size[i], scale, maxsize)
 end
 else
 for i, v in ipairs(image) do
 result = result .. imagecode(v, link, text, size, scale, maxsize)
 end
 end
 return result
end

local getIdText = function(\_type)
 local id\_text
 if \_type == 'item' then -- a shortcut for faster
 id\_text = l10n('id\_text\_item')
 elseif \_type == 'tile' then
 id\_text = l10n('id\_text\_tile')
 elseif \_type == 'wall' then
 id\_text = l10n('id\_text\_wall')
 elseif \_type == 'npc' then
 id\_text = l10n('id\_text\_npc')
 elseif \_type == 'mount' then
 id\_text = l10n('id\_text\_mount')
 elseif \_type == 'buff' or \_type == 'debuff' then
 id\_text = l10n('id\_text\_buff')
 elseif \_type == 'projectile' then
 id\_text = l10n('id\_text\_projectile')
 elseif \_type == 'armor' then
 id\_text = l10n('id\_text\_armor')
 else
 id\_text = l10n('id\_text\_item')
 end
 return id\_text
end

-- main return object
return {
parse = parse,
go = function(frame, args)
 -- init cache
 currentFrame = frame
 args\_table = args or parse(frame.args[1])
 lang = getArg('lang') or 'en'
 l10n\_table = l10n\_info[lang] or l10n\_info['en']

 local \_arg1 = getArg(1) or
 local \_nolink = getArg('nolink')
 local \_link = \_nolink and  *or getArg('link') or frame:expandTemplate{ title = 'tr', args = {\_arg1, link='y', lang=lang} } -- now: \_link ==*  means nolink.

 local text = getArg(2) or

 local hovertext
 if \_arg1 ~=  *then*
 hovertext = frame:expandTemplate{ title = 'tr', args = {\_arg1} }
 elseif text ~=  *then*
 hovertext = text
 else
 hovertext = \_link
 end

 local class = 'i'

 local output\_image, output\_text, output\_table, output\_htmltable = true, true, false, false
 local \_mode = getArg('mode')
 if \_mode then
 if \_mode == 'image' or \_mode == 'imageonly' or \_mode =='onlyimage' then
 output\_text = false
 elseif \_mode == 'text' or \_mode == 'noimage' then
 output\_image = false
 elseif \_mode == 'table' or \_mode == '2-cell' then
 output\_table = true
 elseif \_mode == 'htmltable' or \_mode == 'html-2-cell' then
 output\_htmltable = true
 end
 end

 local image\_output, text\_output
 if output\_image then
 local image\_arg = string.gsub(\_arg1, ":%s\*", " ")
 if \_arg1 == '1/2 Second Timer' then
 image\_arg = '1 2 Second Timer'
 elseif \_arg1 == '1/4 Second Timer' then
 image\_arg = '1 4 Second Timer'
 end
 image\_arg = getArg('image') or image\_arg .. '.' .. (getArg('ext') or 'png')
 image\_output = images(image\_arg, \_link, hovertext, getArg('size'), getArg('scale'), getArg('maxsize'))
 else
 image\_output =
 end
 if output\_text then
 local \_note, \_note2, \_showid, \_id = getArg('note'), getArg('note2'), getArg('showid'), getArg('id')

 if \_id and not \_showid then
 \_showid = true
 end
 if \_showid and (\_showid == 'n' or \_showid == 'no') then
 \_showid = false
 end

 local \_wrap
 if \_showid or \_note2 then
 \_wrap = false
 else
 \_wrap = getArg('wrap')
 end

 if \_link ~=  *then*
 if text == \_link then
 text = ''..text..''
 else
 text = ''..text..''
 end
 else
 text = ''..text..''
 end

 local content = text -- item name link text first.
 -- '-w' class means 'wrapmode', optimized for multiple lines of text. But it should be disabled for single line text.
 if \_wrap then
 -- note in next line
 if \_note then
 class = class .. ' -w'
 content = content .. '' .. \_note .. ''
 end
 else
 -- note first
 if \_note then
 content = content .. '' .. \_note .. ''
 end
 if \_note2 then
 class = class .. ' -w'

 content = content .. '

' .. \_note2 .. ''

 end
 if \_showid then
 class = class .. ' -w'
 local idtype = (getArg('type') or 'item'):lower()
 if not \_id then
 \_id = frame:expandTemplate{ title = idtype .. 'IdFromName', args = {\_arg1} }
 end
 local id\_text = getIdText(idtype)

 content = content .. '

' .. id\_text .. \_id .. ''

 end
 end
 text\_output = '' .. content .. ''
 else
 text\_output =
 end

 local \_class, \_css = getArg('class'), getArg('css')
 if \_class then
 class = class .. ' ' .. \_class
 end
 local attr = {class = class}
 if \_css then
 attr.style = \_css
 end

 local anchor =
 if getArg('anchor') then
 anchor = mw.text.tag('div', {id=frame:callParserFunction('anchorencode', \_arg1), class='anchor'}, *)*
 end
 if output\_table then
 attr.class = class .. ' block aligncenter'
 local result = mw.text.tag('span', attr, image\_output) .. '||'
 attr.class = class .. ' block alignleft'
 return result .. mw.text.tag('span', attr, text\_output .. anchor)
 elseif output\_htmltable then
 attr.class = class .. ' block aligncenter'

 local result = mw.text.tag('span', attr, image\_output) .. ''

 attr.class = class .. ' block alignleft'
 return result .. mw.text.tag('span', attr, text\_output .. anchor)
 else
 return mw.text.tag('span', attr, image\_output .. text\_output .. anchor)
 end
end,

}