Module:Autolink

来自Minecraft基岩版开发Wiki

Autolink,即自动链接,用于给模板的参数中的英文转换为对应的中文并显示出来,正如Module:Reverselink能将中文参数转换为英文并提供给模板以显示图片。

本模块主要用于:

本模块使用以下子页面作为具体参数:

local p = {}

local block = mw.loadData( 'Module:Autolink/Block' )
local item = mw.loadData( 'Module:Autolink/Item' )
local other = mw.loadData( 'Module:Autolink/Other' )
local earth = mw.loadData( 'Module:Autolink/Earth' )
local glossary = mw.loadData( 'Module:Autolink/Glossary' )
local colors = {
	['black '] = '黑色',
	['blue '] = '蓝色',
	['brown '] = '棕色',
	['cyan '] = '青色',
	['gray '] = '灰色',
	['green '] = '绿色',
	['light blue '] = '淡蓝色',
	['light gray '] = '淡灰色',
	['lime '] = '黄绿色',
	['magenta '] = '品红色',
	['orange '] = '橙色',
	['pink '] = '粉红色',
	['purple '] = '紫色',
	['red '] = '红色',
	['silver '] = '淡灰色',
	['white '] = '白色',
	['yellow '] = '黄色',
}

local function Set(list)
	local set = {}
	for _, l in ipairs(list) do set[l] = true end
	return set
end

local coloredItems = Set { 'wool', 'stained glass pane', 'carpet', 'banner', 'concrete',
	'concrete powder', 'stained glass', 'balloon', 'sparkler', 'glow stick' }

-- used by templates, called via #invoke
function p.link( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = require( 'Module:ProcessArgs' ).merge( true )
	end
	return p.invlink( args[1] , args[2] , args[3] )
end

function p.invlink( str, mode, type )
	local arg = str:gsub('-', ' '):lower()
	-- check for spawn egg
	if arg:find(' spawn egg$') then
		local mob = other['EntitySprite'][arg:sub(0, -11)]
		if mob == nil then
			error('missing mob entry: ' .. arg:sub(0, -11))
		end
		local index = mob:find('|')
		if index then
			mob = mob:sub(index + 1)
		end
		return p.mode('刷怪蛋|' .. mob .. '刷怪蛋', mode)
	end

	if arg:find(' pe$') or arg:find(' be$') then
		arg = arg:sub(0, -4)
	elseif arg:find(' lce$') then
		arg = arg:sub(0, -5)
	end

	-- check for 'spawn'
	if arg:find('^spawn ') then
		local mob = other['EntitySprite'][arg:sub(7)]
		if mob then
			local index = mob:find('|')
			if index then
				mob = mob:sub(index + 1)
			end
			local name = '刷怪蛋|生成' .. mob
			return p.mode(name, mode)
		end
	end

	-- check for color prefix
	local color
	for k, v in pairs( colors ) do
		if arg:find(k) == 1 then
			local i = arg:sub(k:len() + 1)
			if coloredItems[i] then
				color = v
				arg = i
				break
			end
		end
	end

	local result
	if type then
		if type == 'ItemSprite' then
			result = earth[type][arg] or item[arg]
		elseif earth[type] then
			result = earth[type][arg]
		elseif other[type] then
			result = other[type][arg]
		elseif glossary[type] then
			result = glossary[type][arg]
		end
	end
	if result == nil then
		result = block[arg] or item[arg]
	end
	if result == nil and arg:sub(-1) == 's' then
		local singular = arg:sub(0, -2)
		result = block[singular] or item[singular]
	end
	if result == nil then
		for _, list in pairs( other ) do
			result = list[arg]
			if result then
				break
			end
		end
		if result == nil then
			for _, list in pairs( glossary ) do
				result = list[arg]
				if result then
					break
				end
			end
				result = result or str
		end
	end

	if color then
		result = result .. '|' .. color .. result
	end

	return p.mode(result, mode)
end

function p.mode( str, mode, suffix )
	if suffix then
		if str:find('|') then
			str = str .. suffix
		else
			str = str .. '|' .. str .. suffix
		end
	end
	local index = str:find('|')
	-- return the translated part
	if index then
		if mode == 'nolink' then
			return str:sub(index + 1)
		end
		-- return the page link part
		if mode == 'linkonly' then
			return str:sub(1, index - 1)
		end
	end
	return str
end

-- list out all entries with the type
function p.list( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = require( 'Module:ProcessArgs' ).merge( true )
	end
	local type = args[1]
	type = type:lower()
	local sprite = nil
	local list = nil
	if type == 'block' then
		list = block
		sprite = 'BlockSprite'
	elseif type == 'item' then
		list = item
		sprite = 'ItemSprite'
	elseif type == 'biome' then
		list = other['BiomeSprite']
		sprite = 'BiomeSprite'
	elseif type == 'effect' then
		list = other['EffectSprite']
		sprite = 'EffectSprite'
	elseif type == 'entity' then
		list = other['EntitySprite']
		sprite = 'EntitySprite'
	elseif type == 'env' then
		list = other['EnvSprite']
		sprite = 'EnvSprite'
	elseif type == 'enchantment' then
		list = other['EnchantmentSprite']
		sprite = 'EnchantmentSprite'
	elseif type == 'vanilla' then
		list = other['VanillaSprite']
		sprite = 'VanillaSprite'
	elseif type == 'addon' then
		list = glossary['AddonSprite']
		sprite = 'AddonSprite'
	elseif type == 'modpe' then
		list = glossary['ModPESprite']
		sprite = 'ModPESprite'
	elseif type == 'innercore' then
		list = glossary['InnerCoreSprite']
		sprite = 'InnerCoreSprite'
	elseif type == 'tech' then
		list = glossary['TechnicSprite']
		sprite = 'TechnicSprite'
	end
	if list == nil then
		return ''
	end

	local spriteids = mw.loadData( 'Module:' .. sprite ).ids

	local result = ''
	local t = {}

	for k, _ in pairs(list) do
		table.insert(t, k)
	end

	table.sort(t)

	local limit = 50
	local count = 0

	local frame = mw.getCurrentFrame()

	local itemlist = nil
	local header = mw.html.create('tr')
	header:tag('th'):wikitext('图标')
	header:tag('th'):wikitext('英文名称')
	header:tag('th'):wikitext('中文名称')

	for _, v in ipairs(t) do
		if count == 0 then
			if itemlist ~= nil then
				result = result .. tostring(itemlist)
			end
			itemlist = mw.html.create('table')
				:css{
					float = 'left',
					margin = '2px',
					border = '1px solid silver',
					['text-align'] = 'center',
					['background-color'] = '#fff'
				}
				:node(header)
		end

		local row = mw.html.create('tr')
		if spriteids[v] or spriteids[mw.ustring.lower( v ):gsub( '[%s%+]', '-' )] then
			row:tag('td'):wikitext(frame:expandTemplate{ title = sprite, args = { v } })
		else
			row:tag('td')
		end
		local words = {}
		v:gsub('[^%s]+', function(w) table.insert(words, w) end)
		for k, w in ipairs(words) do
			if w ~= 'of' and w ~= 'or' and w ~= 'and' and w ~= 'the' and w ~= 'o\'' then
				words[k] = w:gsub('(%l)(.+)', function(a, b) return a:upper() .. b end)
			end
		end
		row:tag('td'):wikitext(tostring(table.concat(words, ' ')))
		row:tag('td'):wikitext(p.mode(list[v], 'nolink'))
		itemlist:node(row)
		count = count + 1
		if count == limit then
			count = 0
		end
	end

	result = result .. tostring(itemlist)
	return result
end

return p