模块:L10ndatatable

来自Terraria Wiki
跳到导航 跳到搜索
亦可参看英文模块:Module:L10ndatatable。那边可能有更完整或更正确的信息。

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


local trim = mw.text.trim

---Split the `str` on each `div` in it and return the result as a table.
---Original version credit: http://richard.warburton.it. This version trims each substring.
---@param div string
---@param str string
---@return table|boolean
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 proc(s, info, keys, keylist)
	s = s:match('^{{l10n/register(.+)}}$')
	s = s:gsub('<esc>.-</esc>', function(t) return t:gsub('|', '|') end)
	s = s:gsub('%b[]', function(t) return t:gsub('|', '|') end)
	s = s:gsub('%b{}', function(t) return t:gsub('|', '|') end)

	local args = {}
	local ns, lang
	for i, v in ipairs(explode('|', s)) do
		st, sp = v:find('=')
		if st then
			-- named parameters
			local key = trim(v:sub(1, st-1))
			args[key] = trim(v:sub(sp+1))
			if not keys[key] then
				keys[key] = true
				keylist[#keylist+1] = key
			end
		else
			v = trim(v)
			if v~= '' then
				-- unnamed
				if ns then
					lang = v
				else
					ns = v
				end
			end
		end
	end
	info[lang] = args
	return (lang == 'en') and ns or nil
end

local function encode(str)
	str = str:gsub('%[', '[')
	str = str:gsub('%]', ']')
	str = str:gsub('{', '{')
	str = str:gsub('}', '}')
	str = str:gsub('|', '|')
	return str
end

local function render(info, keylist)

	local langs = {}
	local rows = {}

	for k,v in pairs(info.en) do
		rows[k] = { en = encode(v) }
	end
	info.en = nil

	for lang,inf in pairs(info) do
		langs[#langs+1] = lang
		for k,v in pairs(inf) do
			if not rows[k] then
				rows[k] = {}
			end
			rows[k][lang] = encode(v)
		end
	end


	table.sort(langs)
	local trows = {'<tr>'}
	for i,key in ipairs(keylist) do
		rowinfo = rows[key]
		local tcells = {'<td><code>'..key..'</code></td>'}
		if rowinfo['en'] then
			tcells[#tcells+1] = '<td class="en l">' .. rowinfo['en'] .. '</td>'
		else
			tcells[#tcells+1] = '<td class="en l note-text">-</td>'
		end
		for i, lang in ipairs(langs) do
			if rowinfo[lang] then
				tcells[#tcells+1] = '<td class="'..lang..' l"><div>' .. rowinfo[lang] .. '</div></td>'
			else
				tcells[#tcells+1] = '<td class="'..lang..' l note-text"><div>' .. (rowinfo['en'] or '-') .. '</div></td>'
			end
		end
		trows[#trows+1] = table.concat(tcells)
	end
	trows[#trows+1] = '</tr>'

	return table.concat(langs, '$'), table.concat(trows, '</tr><tr>')
end


---------------------------

local p = {}


p.go=function(frame)
	str = frame.args[1]

	-- remove html comment:
	str = mw.ustring.gsub(str, '&#60;!%-%-.-%-%-&#62;', '' )

	-- <onlyinclude>, <noinclude> and <includeonly>
	local t = ''
	str:gsub('&#60;onlyinclude&#62;(.-)&#60;/onlyinclude&#62;', function(x) t = t..x end)
	if t ~= '' then
		str = t
	else
		str = str:gsub('&#60;noinclude&#62;(.-)&#60;/noinclude&#62;', '')
		str = str:gsub('&#60;includeonly&#62;(.-)&#60;/includeonly&#62;', '%1')
	end
	-- strip <onlyinclude> <noinclude> <includeonly> tags. @todo: If these tags is within <nowiki>?
	str = str:gsub('&#60;/?onlyinclude&#62;', '')
	str = str:gsub('&#60;/?noinclude&#62;', '')
	str = str:gsub('&#60;/?includeonly&#62;', '')

	str = str:gsub('&#1[0-3];', '')
	str = str:gsub('&#9;', '')
	str = str:gsub('&#91;', '[')
	str = str:gsub('&#93;', ']')
	str = str:gsub('&#123;', '{')
	str = str:gsub('&#125;', '}')
	-- standardize template name:
	str = str:gsub('{{%s*[lL]10n/register', '{{l10n/register')
	-- start from first "{{l10n/register"
	str = str:match('{{l10n/register.+')
	
	local info = {}
	local keys = {}
	local keylist = {}
	local namespace

	for i,v in ipairs(explode('{{l10n/register', str or '')) do
		local s = '{{l10n/register' .. v
		s = s:match('%b{}'); -- {{l10n/register| ... }}
		if s then
			namespace = proc(s, info, keys, keylist) or namespace
		end
	end

	if not info['en'] then
		return '<span class="error">Lack of en l10n info.</span>'
	end

	local langlist, trows = render(info, keylist)

	mw.ext.VariablesLua.vardefine( 'l10ndatatable:namespace', namespace )
	mw.ext.VariablesLua.vardefine( 'l10ndatatable:langs', langlist )
	mw.ext.VariablesLua.vardefine( 'l10ndatatable:rows', trows )
end


return p