Module:Item

-- l10n text, need to be translated. local l10n = { ['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: ', },	['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：', },	['de'] = { ['id_text_item'] = 'Interne Gegenstands-ID: ', ['id_text_tile'] = 'Interne Feld-ID: ', ['id_text_wall'] = 'Interne Wand-ID: ', ['id_text_npc'] = 'Interne NSC-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: ', },	['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: ', }, }

-- l10n function to get plural form, it may be different for each language. If function for target language does not exist, the EN version is used. -- about the function itself: -- return plural form, nil if no pluralism processing occurs. -- _arg1 is the original text(after auto translation), _arg2 is custom text or plural postfix, may be s/es/ies/ves (for english). local plural = { -- for English (en) ['en'] = function(_arg1, _arg2) -- intuitive pluralism -- The comparisons are performed in order, so putting the more common ones in front gives the best performance. if _arg2 == 's' then local suffix1 = _arg1:sub(-1) -- cache for better performance. local suffix2 = _arg1:sub(-2) -- cache for better performance. if suffix1 == 'y' then if suffix2 == 'ay' or suffix2 == 'ey' or suffix2 == 'iy' or suffix2 == 'oy' or suffix2 == 'uy' then return _arg1 .. 's'                -- eg. ray->rays else return _arg1:sub(1, -2) .. 'ies'   -- eg. firefly->fireflies end end if suffix2 == 'fe' and string.lower(_arg1) ~= 'safe' then return _arg1:sub(1, -3) .. 'ves'       -- eg. knife->knives end if suffix1 == 'f' and suffix2 ~= 'ff' then return _arg1:sub(1, -2) .. 'ves'       -- eg. wolf->wolves, leaf->leaves, but buff->buffs else return _arg1 .. 's'			end end

if _arg2 == 'es' then return _arg1 .. 'es' end

if _arg2 == 'ies' then return _arg1:sub(1, -2) .. 'ies' end

if _arg2 == 'ves' then if _arg1:sub(-2) == 'fe' then return _arg1:sub(1, -3) .. 'ves'   --replace last 2 letters, e.g. knife->knives end if _arg1:sub(-1) == 'f' or _arg1:sub(-2) ~= 'ff' then return _arg1:sub(1, -2) .. 'ves'   --replace last letter, e.g. wolf-wolves, leaf->leaves, but buff->buffs end end end,

-- for Chinese (zh) ['zh'] = function(_arg1, _arg2) -- there is no plural form in chinese. if _arg2 == 's' or _arg2 == 'es' or _arg2 == 'ies' or _arg2 == 'ves' then return _arg1 end return nil end,

-- for German (de) !! may need to be improved !! ['de'] = function(_arg1, _arg2) if _arg2 == 's' or _arg2 == 'es' or _arg2 == 'ies' or _arg2 == 'ves' then return _arg1 end return nil end,

-- for Italian (it) !! may need to be improved !! ['it'] = function(_arg1, _arg2) if _arg2 == 's' or _arg2 == 'es' or _arg2 == 'ies' or _arg2 == 'ves' then return _arg1 end return nil end,

}

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

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

local currentFrame -- cache

-- 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		table.insert(arr,trim(string.sub(str,pos,st-1))) -- Attach chars left of current divider pos = sp + 1 -- Jump past current divider end table.insert(arr, trim(string.sub(str,pos))) -- Attach chars right of last divider return arr end

local escape = function(str) return str:gsub("'", "\\'"):gsub("&#39;", "\\'") end local enclose = function(str) return "'" .. escape(str) .. "'" end

local function getText(_arg1, _arg2, lang, frame) _arg1 = frame:expandTemplate{ title = 'tr', args = {_arg1, lang=lang} } -- auto translate if not _arg2 then return _arg1 end local plural_function = plural[lang] or plural['en'] or function end return plural_function(_arg1, _arg2) or _arg2 end

local function parseSize(size) local basescale, width, height if size then 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 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='..enclose(image),		orderBy = "cached DESC",		limit = 1,	}) for _, row in ipairs(result) do		return tonumber(row['width']), tonumber(row['height']), row['cached'] end return nil, nil, nil 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)) end if width and width ~= 0 and height and height ~= 0 then currentFrame:callParserFunction('#cargo_store:_table=Imageinfo',{			image = image,			width = width,			height = height,			cached = os.time,		}) 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 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 nil,nil 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 getScale(scale, basescale) scale = (tonumber(scale) or 1) * (tonumber(basescale) or 1) if scale == 0 or scale == 1 then scale = nil end return scale end

local function imagecode(image, link, text, size, scale, maxsize) local image_output = '' else return image_output .. ']]'		end else return image_output .. ']]'	end end

local image_for_cargo local function images(image, link, text, size, scale, maxsize) if not image:find('/') then image_for_cargo = image 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, lang) _type = _type:lower local id_text, needcargo if _type == 'item' then -- a shortcut for faster id_text = l10n[lang]['id_text_item'] or l10n['en']['id_text_item'] needcargo = true elseif _type == 'tile' then id_text = l10n[lang]['id_text_tile'] or l10n['en']['id_text_tile'] elseif _type == 'wall' then id_text = l10n[lang]['id_text_wall'] or l10n['en']['id_text_wall'] elseif _type == 'npc' then id_text = l10n[lang]['id_text_npc'] or l10n['en']['id_text_npc'] elseif _type == 'mount' then id_text = l10n[lang]['id_text_mount'] or l10n['en']['id_text_mount'] elseif _type == 'buff' or _type == 'debuff' then id_text = l10n[lang]['id_text_buff'] or l10n['en']['id_text_buff'] elseif _type == 'projectile' then id_text = l10n[lang]['id_text_projectile'] or l10n['en']['id_text_projectile'] elseif _type == 'armor' then id_text = l10n[lang]['id_text_armor'] or l10n['en']['id_text_armor'] else id_text = l10n[lang]['id_text_item'] or l10n['en']['id_text_item'] needcargo = true end return id_text, needcargo end

- -- main return object return { go = function(frame, args) currentFrame = frame -- cache if args then for k, v in pairs(args) do			if v == '' then args[k] = nil end end end

local getArg = function(key) if args then return args[key] else local value = frame.args[key] if not value then return nil end value = trim(value) if value == '' then return nil else return value end end end

local lang = getArg('lang') or 'en' -- cache lang setting.

local _arg1 = getArg(1) or ''

local _nolink = getArg('nolink')

-- link target and eicons target, eicons target should not be translated. local _link, _eicons_link _link = getArg('link') -- get link= input if _link then -- override _nolink = y		_eicons_link = _link else _eicons_link = _arg1 if _nolink then _link = '' else -- no link= input, use _arg1 with auto link translation. _link = frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} } end end -- now _link == '' means nolink.

local _arg2 = getArg(2) local text = getText(_arg1, _arg2, lang, frame) -- text will be auto translated.

local class = 'item-link'

local output_image, output_text, output_table = true, true, 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 end end

local image_output = '' if output_image then image_output = images(getArg('image') or (_arg1 .. '.' .. (getArg('ext') or 'png')), _link, text, getArg('size'), getArg('scale'), getArg('maxsize')) end

local text_output = '' if output_text then local _note = getArg('note') local _note2 = getArg('note2') local _id = getArg('id')

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

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

local _icon = getArg('icons') local icon = '' if not (_icon == 'n' or _icon == 'no' or _icon == 'off') then local args = { _eicons_link } if _id or _note2 or _wrap or getArg('small') then args['small'] = 'y'			end icon = frame:expandTemplate{ title = 'eicons', args = args } -- eicons will do auto translate. end

local content = mw.text.tag('span', nil, text) -- '-w' class means 'wrapmode', optimized for multiple lines of text. But it should be disabled for single line text. if _wrap then if icon ~= '' then class = class .. ' -w' content = content .. icon end if _note then class = class .. ' -w' content = content .. mw.text.tag('span',{class='note'}, _note) end else if _note then content = content .. mw.text.tag('span',{class='note'}, _note) end if icon ~= '' then content = content .. icon end if _note2 then class = class .. ' -w' content = content .. mw.text.tag('div',{class='note'}, _note2) end if _id then class = class .. ' -w' local id_text, needcargo = getIdText(getArg('type') or 'item', lang) if needcargo and output_image and image_for_cargo then frame:expandTemplate{ title = 'Item/cargo', args = {name=_arg1, image=image_for_cargo, id=_id} } end content = content .. mw.text.tag('div', {class='id'}, id_text .. _id) end end text_output = mw.text.tag{name='span', content=content} end

local _class = getArg('class') local _css = 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) else return mw.text.tag('span', attr, image_output .. text_output .. anchor) end end, getText = getText,

}