Terraria Wiki

  • Discussions are now available on the Terraria Wiki.
  • Miss the old Hydra Skin? Try out our Hydralize gadget! Visit the preferences page while logged in and turn on the gadget.

READ MORE

Terraria Wiki
(tweak i18n.)
(move plural processing outside from module.)
Line 2: Line 2:
 
------- l10n info --------------
 
------- l10n info --------------
 
local l10n_info = mw.loadData('Module:Item/l10n')
 
local l10n_info = mw.loadData('Module:Item/l10n')
 
-- 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(without auto translation), _arg2 is custom text(without auto translation) or plural postfix, may be s/es/ies/ves (for english).
 
-- the retruned result will be auto translated.
 
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,
 
 
-- example: 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,
 
 
-- default function for all laguages not defined.
 
['others'] = function(_arg1, _arg2)
 
-- no plural form process.
 
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. --------------
 
------- The following is not related to l10n. --------------
Line 75: Line 7:
 
local trim = mw.text.trim
 
local trim = mw.text.trim
 
local cargo = mw.ext.cargo
 
local cargo = mw.ext.cargo
local module_exclusive = require('Module:Exclusive')
+
local eicons = require('Module:Exclusive').simpleEicons
local eicons = module_exclusive.simpleEicons
 
   
 
local currentFrame
 
local currentFrame
Line 98: Line 29:
 
end
 
end
 
return value
 
return value
end
 
 
local function getText(_arg1, _arg2)
 
if not _arg2 then
 
return currentFrame:expandTemplate{ title = 'tr', args = {_arg1, lang=lang} } -- auto translate
 
end
 
local plural_function = plural[lang] or plural['others'] or function() end
 
return currentFrame:expandTemplate{ title = 'tr', args = {plural_function(_arg1, _arg2) or _arg2, lang=lang} } -- auto translate
 
 
end
 
end
   
Line 308: Line 231:
 
local _link, _eicons_link = getArg('link'), nil
 
local _link, _eicons_link = getArg('link'), nil
 
if _link then -- override _nolink = y
 
if _link then -- override _nolink = y
_eicons_link = _link
+
_eicons_link = _link -- _eicontr does not affect _link
 
else
 
else
 
if _nolink then
 
if _nolink then
 
_link = ''
 
_link = ''
if l10n('auto_translate_eicons_pagename') then
+
if getArg('eicontr') then
_eicons_link = frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
+
_eicons_link = getArg('trname') or frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
 
else
 
else
 
_eicons_link = _arg1
 
_eicons_link = _arg1
Line 319: Line 242:
 
else
 
else
 
-- no link=<link> input, use _arg1 with auto link translation.
 
-- no link=<link> input, use _arg1 with auto link translation.
_link = frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
+
_link = getArg('trname') or frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
if l10n('auto_translate_eicons_pagename') then
+
if getArg('eicontr') then
 
_eicons_link = _link -- reuse
 
_eicons_link = _link -- reuse
 
else
 
else
Line 329: Line 252:
 
-- now _link == '' means nolink.
 
-- now _link == '' means nolink.
   
local text = getText(_arg1, getArg(2))
+
local text = getArg(2) or ''
   
 
local class = 'item-link'
 
local class = 'item-link'

Revision as of 17:49, 17 May 2019

Lua logo Documentation The documentation below is transcluded from Module:Item/doc. (edit | history)

This module is intended to provide functionality to the {{item}} template.


------- l10n info --------------
local l10n_info = mw.loadData('Module:Item/l10n')

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

local trim = mw.text.trim
local cargo = mw.ext.cargo
local eicons = require('Module:Exclusive').simpleEicons

local currentFrame
local args_table
local lang
local l10n_table
local image_for_cargo

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

-- 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 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("&#39;", "\\'").."'",
		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 = '[[File:' .. image .. '|link='.. link .. '|' .. text
	if size or scale or maxsize then
		local basescale, width, height = parseSize(size) -- width,height: number or nil
		scale = (tonumber(scale) or 1) * (tonumber(basescale) or 1)
		if scale == 0 or scale == 1 then
			scale = nil
		end
		local maxwidth, maxheight = parseMaxSize(maxsize)
		width, height = getImageSize(image, width, height, scale, maxwidth, maxheight) -- can be 0
		if width or height then
			return 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
		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)
	_type = _type:lower()
	local id_text, needcargo
	if _type == 'item' then -- a shortcut for faster
		id_text = l10n('id_text_item')
		needcargo = true
	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')
		needcargo = true
	end
	return id_text, needcargo
end

-----------------------------------------------------------------
-- main return object
return {
	
go = function(frame, args)
	-- init cache
	currentFrame = frame
	args_table = args or frame.args
	lang = getArg('lang') or 'en'
	l10n_table = l10n_info[lang] or l10n_info['en']

	local _arg1 = getArg(1) or ''
	local _nolink = getArg('nolink')

	-- link target and eicons target
	local _link, _eicons_link = getArg('link'), nil
	if _link then -- override _nolink = y
		_eicons_link = _link -- _eicontr does not affect _link
	else
		if _nolink then 
			_link = ''
			if getArg('eicontr') then
				_eicons_link = getArg('trname') or frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
			else
				_eicons_link = _arg1
			end
		else
			-- no link=<link> input, use _arg1 with auto link translation.
			_link = getArg('trname') or frame:expandTemplate{ title = 'tr', args = {_arg1, link = 'y', lang=lang} }
			if getArg('eicontr') then
				_eicons_link = _link -- reuse
			else
				_eicons_link = _arg1
			end
		end
	end
	-- now _link == '' means nolink.

	local text = getArg(2) or ''

	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, text_output
	if output_image then
		image_output = images(getArg('image') or (_arg1 .. '.' .. (getArg('ext') or 'png')), _link, text, getArg('size'), getArg('scale'), getArg('maxsize'))
	else
		image_output = ''
	end
	if output_text then
		local _note, _note2, _id = getArg('note'), getArg('note2'), 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 = '[['.._link..'|'..text..']]'
			end
		end

		local _icon, icon = getArg('icons'), nil
		if _icon == 'n' or _icon == 'no' or _icon == 'off' then
			icon = ''
		else
			icon = eicons(_eicons_link, lang, (_id or _note2 or _wrap or getArg('small')) and 'y')
		end

		local content = '<span>' .. text .. '</span>' -- 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
			-- eicons in the same line
			if icon ~= '' then
				class = class .. ' -w'
				content = content .. icon
			end
			-- note in next line
			if _note then
				class = class .. ' -w'
				content = content .. '<span class="note">' .. _note .. '</span>'
			end
		else
			-- note first
			if _note then
				content = content .. '<span class="note">' .. _note .. '</span>'
			end
			if icon ~= '' then
				content = content .. icon
			end
			if _note2 then
				class = class .. ' -w'
				content = content .. '<div class="note">' .. _note2 .. '</div>'
			end
			if _id then
				class = class .. ' -w'
				local id_text, needcargo = getIdText(getArg('type') or 'item')
				if needcargo and image_for_cargo then
					frame:expandTemplate{ title = 'Item/cargo', args = {name=_arg1, image=image_for_cargo, id=_id} }
				end
				content = content .. '<div class="id">' .. id_text .. _id .. '</div>'
			end
		end
		text_output = '<span>' .. content .. '</span>'
	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
	
	if getArg('anchor') then
		text_output = text_output .. '<div class="anchor" id="' .. frame:callParserFunction('anchorencode', _arg1) .. '"></div>'
	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)
	else
		return mw.text.tag('span', attr, image_output .. text_output)
	end
end,
	
}