Toggle menu
14
236
69
27.2K
Kenshi Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 01:27, 21 February 2025 by Prd (talk | contribs) (Created page with "local p = {} local unicode_convert = require('Module:Unicode convert') local numcr2namecr = mw.loadData('Module:Numcr2namecr') local yesno = require('Module:Yesno') local GB18030_cache = {} -- Input e.g. " A B FF ", output "10 11 255" local function hex2dec_words(s) local x = mw.text.split(mw.text.trim(s or ''), '%s+') if #x == 1 and x[1] == '' then return '' end for i = 1, #x do x[i] = tonumber(x[i], 16) or 0 end return table.concat(x, ' ') end -- Wrapper t...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Template:High-use This module implements {{charmap}}.



local p = {}
local unicode_convert = require('Module:Unicode convert')
local numcr2namecr = mw.loadData('Module:Numcr2namecr')
local yesno = require('Module:Yesno')
local GB18030_cache = {}

-- Input e.g. "  A  B  FF  ", output "10 11 255"
local function hex2dec_words(s)
	local x = mw.text.split(mw.text.trim(s or ''), '%s+')
	if #x == 1 and x[1] == '' then return '' end
	for i = 1, #x do
		x[i] = tonumber(x[i], 16) or 0
	end
	return table.concat(x, ' ')
end

-- Wrapper to let us replace Template:UTF-8 and Template:UTF-16
local function template(title, args)
	if title == 'UTF-8' then
		return unicode_convert.getUTF8{ args = args }
	elseif title == 'UTF-16' then
		return unicode_convert.getUTF16{ args = args }
	elseif title == 'hex2dec' then
		return tostring(tonumber(args[1], 16))
	elseif title == 'charmap/numcharref' then
		local format = args['base'] == 'dec' and '&amp;#%d;<wbr>' or '&amp;#x%02X;<wbr>'
		return format:format(tonumber(args[1], 16))
	elseif title == 'charmap/showchar' then
		return '&#x' .. mw.text.trim(args[1]) .. ';'
	elseif title == 'GB18030' then
		if GB18030_cache[args[1]] then
			if args['base'] == 'dec' then
				return mw.getCurrentFrame():expandTemplate{
					title = 'GB18030/decimal', args = { GB18030_cache[args[1]] }}
			else return GB18030_cache[args[1]] end
		elseif os.clock() > 7 then
			return "''currently unavailable''"
		else
			GB18030_cache[args[1]] = mw.getCurrentFrame():expandTemplate{title = 'GB18030', args = {args[1]}}
			if args['base'] == 'dec' then
				return hex2dec_words(GB18030_cache[args[1]])
			else return GB18030_cache[args[1]] end
		end
	else
		return mw.getCurrentFrame():expandTemplate{ title = title, args = args }
	end
end

local function _multiUTF(args)
	local code = args[1] or ''
	local encoding = args[2] or 'UTF-8'
	local output = ''
	local pstp_sep = encoding:sub(1, 8) == 'charmap/' and '' or ' '
	local words = mw.text.split(mw.text.trim(code), '%s')
	
	if not (encoding == 'charmap/showchar' or encoding == 'hex2dec') then
		output = '|| '
		for i = 1, #words do
			output = output .. template(encoding, {words[i], base = 'dec'})
			if i == 4 then break end
			output = output .. pstp_sep
		end
		output = output .. '|| '
	end
	
	for i = 1, #words do
		output = output .. template(encoding, {words[i]})
		if i == 4 then break end
		output = output .. pstp_sep
	end
	
	return output
end

local function paramCoalesce(args, arg1, arg2)
	if args[arg1] ~= nil and args[arg1] ~= '' then return args[arg1] end
	if arg2 ~= nil and args[arg2] ~= nil and args[arg2] ~= '' then return args[arg2] end
	return nil
end

p.alt = function(frame, n)
	n = n or frame.args[1]
	local args = frame:getParent().args
	if args['map' .. n] == '' or args['map' .. n] == nil then return ''	end
	
	local output = '|-\n| ' .. args['map' .. n]
	local codes = {}
	for i = 1, 10 do
		if args['name' .. i] and args['name' .. i] ~= '' then
			local x = args['map' .. n .. 'char' .. i] or ''
			output = output .. ' || ' .. hex2dec_words(x) .. ' || ' .. frame:callParserFunction('uc', x)
		end
	end
	return output .. '\n'
end

p.head = function(frame)
	local output = '|- style="text-align:center;"\n'
	codes = {} -- May contain nils if bad input
	infos = {} -- boolean array
	names = {} -- string array
	args = frame:getParent().args
	for i = 1, 10 do
		if args['name' .. i] and args['name' .. i] ~= '' then
			-- The parser function uc: preserves strip markers.
			codes[1 + #names] = frame:callParserFunction('uc', mw.text.trim(args[i]))
			infos[1 + #names] = paramCoalesce(args, 'Info' .. i, 'Info') == 'yes'
			names[1 + #names] = frame:callParserFunction('uc', args['name' .. i])
		end
	end
	
	if #names > 0 then
		output = output .. "! " .. frame:preprocess('<templatestyles src="Module:Charmap/sandbox/styles.css"/>') ..
			(next(codes) == nil and 'Character' or 'Unicode') .. " name"
		for i, n in ipairs(names) do
			-- Display the character in smallcaps
			output = output .. '\n| colspan="2" class="smallcaps-cm" | ' .. n
		end
	end

	output = output .. '\n|-\n! style="text-align:left;" | Encodings || decimal || hex' ..
		string.rep('|| dec || hex', #names - 1) ..
		'\n|-\n| [[Unicode]]'
	for i, n in ipairs(names) do
		local code = codes[i] or '';
		-- padleft, get to form U+XXXX or U+XXXX+XXXX.
		code = (#code >= 4) and code:gsub(' ', '+') or ('0000' .. (code or '')):sub(-4)
		output = output .. ' || ' .. _multiUTF{codes[i] or '0', 'hex2dec'} .. ' || ' ..
			(infos[i] and '[http://www.fileformat.info/info/unicode/char/%s/index.htm U+%s]' or 'U+%s'):format(code, code)
	end
	
	output = output .. '\n|-\n| [[UTF-8]]'
	for i, n in ipairs(names) do
		output = output .. _multiUTF{codes[i]}
	end
	
	local outsideBMP = false -- Do we need to show surrogate pairs?
	for i, n in ipairs(names) do
		if (tonumber(codes[i] or '', 16) or 0) > 0xFFFF then
			outsideBMP = true
			break
		end
	end
	
	if outsideBMP then
		output = output .. '\n|-\n| [[UTF-16]]'
		for i, n in ipairs(names) do
			output = output .. _multiUTF{codes[i], 'UTF-16'}
		end
	end
	
	if yesno(args['IncludeGB']) then
		output = output .. '\n|-\n| [[GB 18030]]'
		for i, n in ipairs(names) do
			output = output .. _multiUTF{codes[i], 'GB18030'}
		end
	end
	
	if #names > 4 then
		output = output .. '\n|- class="template-charmap-numchr"\n| [[Numeric character reference]]'
	else
		output = output .. '\n|-\n| [[Numeric character reference]]'
	end
	for i, n in ipairs(names) do
		output = output .. _multiUTF{codes[i], 'charmap/numcharref'}
	end
	
	return output
end

p.named = function(frame, n)
	n = n or frame.args[1]
	local args = frame:getParent().args
	local refchars = {}
	local empty = true;
	local namedref = (n == 'html') and '[[List of XML and HTML character entity references|Named character reference]]' or
		args['namedref' .. n] or '';
	for i = 1, 10 do
		if args['name' .. i] and args['name' .. i] ~= '' then
			local x = (n == 'html') and
				(numcr2namecr[tonumber(args[i], 16)] or '') or
				args['ref' .. n .. 'char' .. i] or ''
			empty = empty and #x == 0
			refchars[1 + #refchars] = x
		end
	end
	if empty then return '' end
	return '|- style="text-align:center"\n| ' .. namedref ..
		(' || colspan="2" | %s'):rep(#refchars):format(unpack(refchars)) .. '\n'
end

-- Draw a preview block, possibly with multiple styles
function preview(args, i)
	local result = ''
	for j = 1, math.huge do
		local label = paramCoalesce(args, 'style' .. i .. '-' .. j .. 'label', 'style' .. j .. 'label')
		if not label then break end
		local div = mw.html.create('div'):tag('div')
		div:tag('span'):wikitext(label)
		div:tag('span')
			:cssText(args['style' .. j]):cssText(args['style' .. i .. '-' .. j])
			:wikitext(paramCoalesce(args, 'image' .. i .. '-' .. j, 'image' .. i) or
				_multiUTF{args[i] or '20', 'charmap/showchar'})
		result = result .. tostring(div)
	end
	-- Setting the font-size on the cell changes its padding.
	local size = (result == '') and (paramCoalesce(args, 'size' .. i, 'size') or '150%') or '100%'
	local cell =  ' || colspan="2" style="font-size:' .. size .. '" | '
	if result == '' then
		return cell .. (paramCoalesce(args, 'image' .. i) or _multiUTF{args[i] or '20', 'charmap/showchar'})
	else
		return cell .. '<div>' .. result .. '</div>'
	end
end

p.main = function(frame)
	-- text-align:center: ''
	local output = {'{| class="wikitable template-charmap" style="text-align:right"\n',
		'|+Character information\n',
		'|- style="text-align:center"\n', -- Otherwise mobile site tries aligning preview cells right
		'! scope="row" | Preview'}
	local args = frame:getParent().args
	for i = 1, 10 do
		--  Header row with the symbol in a large font or an image
		if args['name' .. i] and args['name' .. i] ~= '' then
			output[1 + #output] = preview(args, i)
		end
	end
	output[1 + #output] = '\n' .. p.head(frame) .. '\n' .. p.named(frame, 'html')
	for i = 1, 10 do
		output[1 + #output] = p.alt(frame, i)
	end
	for i = 1, 5 do
		output[1 + #output] = p.named(frame, i)
	end
	return table.concat(output) .. '|}'
end

return p