Neidio i'r cynnwys

Modiwl:string/char

Oddiwrth Wiciadur, y geiriadur rhydd.

Documentation for this module may be created at Modiwl:string/char/doc

local math_module = "Module:math"

local char = string.char
local concat = table.concat
local error = error
local pcall = pcall
local select = select
local tonumber = tonumber
local type = type

local function to_hex(...)
	to_hex = require(math_module).to_hex
	return to_hex(...)
end

local function utf8_char(v, arg)
	local cp = tonumber(v)
	if cp == nil then
		error(format("bad argument #%d to 'char' (number expected; got %s)", arg, type(v)), 2)
	elseif cp < 0 then
		-- Throw error (see below).
	elseif cp < 0x80 then
		return char(cp)
	elseif cp < 0x800 then
		return char(
			0xC0 + cp / 0x40,
			0x80 + cp % 0x40
		)
	elseif cp < 0x10000 then
		-- Don't return "?" for surrogates, like mw.ustring.char does, as they have legitimate uses (e.g. in JSON).
		return char(
			0xE0 + cp / 0x1000,
			0x80 + cp / 0x40 % 0x40,
			0x80 + cp % 0x40
		)
	elseif cp < 0x110000 then
		return char(
			0xF0 + cp / 0x40000,
			0x80 + cp / 0x1000 % 0x40,
			0x80 + cp / 0x40 % 0x40,
			0x80 + cp % 0x40
		)
	end
	-- Throw error: to_hex can only return integers, so don't show the bad codepoint if the input is strange.
	local success, result = pcall(to_hex, cp, true)
	error(format("bad argument #%d to 'string/char' (codepoint between 0x0 and 0x10FFFF expected%s)", arg, success and "; got " .. result or ""), 2)
end

return function(cp, ...)
	if ... == nil then
		return utf8_char(cp, 1)
	end
	local ret = {cp, ...}
	for i = 1, select("#", cp, ...) do
		ret[i] = utf8_char(ret[i], i)
	end
	return concat(ret)
end