모듈:Unicode data

local p = {}
local floor = math.floor
local function errorf(level, ...)
	if type(level) == "number" then
		return error(string.format(...), level + 1)
	else -- level is actually the format string.
		return error(string.format(level, ...), 2)
	end
end
local function binary_range_search(codepoint, ranges)
	local low, mid, high
	low, high = 1, ranges.length or require "Module:TableTools".length(ranges)
	while low " }, -- C0 control characters
	{     0x7F,     0x9F, "" }, -- DEL and C1 control characters
	{   0x3400,   0x4DBF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension A
	{   0x4E00,   0x9FFF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph
	{   0xAC00,   0xD7A3, function (codepoint) -- Hangul Syllables
		local Hangul_data = loader.Hangul
		local syllable_index = codepoint - 0xAC00
		return ("HANGUL SYLLABLE %s%s%s"):format(
			Hangul_data.leadsfloor(syllable_index / Hangul_data.final_count),
			Hangul_data.vowelsfloor((syllable_index % Hangul_data.final_count)
				/ Hangul_data.trail_count),
			Hangul_data.trailssyllable_index % Hangul_data.trail_count
		)
	end },
	-- High Surrogates, High Private Use Surrogates, Low Surrogates
	{   0xD800,   0xDFFF, "" },
	{   0xE000,   0xF8FF, "" }, -- Private Use
	-- CJK Compatibility Ideographs
	{   0xF900,   0xFA6D, "CJK COMPATIBILITY IDEOGRAPH-%04X" },
	{   0xFA70,   0xFAD9, "CJK COMPATIBILITY IDEOGRAPH-%04X" },
	{  0x17000,  0x187F7, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph
	{  0x18800,  0x18AFF, function (codepoint)
		return ("TANGUT COMPONENT-%03d"):format(codepoint - 0x187FF)
	end },
	{  0x18D00,  0x18D08, "TANGUT IDEOGRAPH-%04X" }, -- Tangut Ideograph Supplement
	{  0x1B170,  0x1B2FB, "NUSHU CHARACTER-%04X" }, -- Nushu
	{  0x20000,  0x2A6DF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension B
	{  0x2A700,  0x2B739, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension C
	{  0x2B740,  0x2B81D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension D
	{  0x2B820,  0x2CEA1, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension E
	{  0x2CEB0,  0x2EBE0, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension F
	-- CJK Compatibility Ideographs Supplement (Supplementary Ideographic Plane)
	{  0x2F800,  0x2FA1D, "CJK COMPATIBILITY IDEOGRAPH-%04X" },
	{  0xE0100,  0xE01EF, function (codepoint) -- Variation Selectors Supplement
		return ("VARIATION SELECTOR-%d"):format(codepoint - 0xE0100 + 17)
	end},
	{  0x30000,  0x3134A, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension G
	{  0x31350,  0x323AF, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension H
	{  0x2EBF0,  0x2EE5D, "CJK UNIFIED IDEOGRAPH-%04X" }, -- CJK Ideograph Extension I
	{  0xF0000,  0xFFFFD, "" }, -- Plane 15 Private Use
	{ 0x100000, 0x10FFFD, "" }  -- Plane 16 Private Use
}
name_hooks.length = #name_hooks
local name_range_cache
local function generate_name(data, codepoint)
	if type(data) == "string" then
		return data:format(codepoint)
	else
		return data(codepoint)
	end
end
--
-- Checks that the code point is a number and in range.
-- Does not check whether code point is an integer.
-- Not used
local function check_codepoint(funcName, argIdx, val)
	require 'libraryUtil'.checkType(funcName, argIdx, val, 'number')
	if codepoint = 0xFFFE)
end
-- https://www.unicode.org/versions/Unicode11.0.0/ch04.pdf, section 4.8
function p.lookup_name(codepoint)
	if p.is_noncharacter(codepoint) then
		return (""):format(codepoint)
	end
	if name_range_cache -- Check if previously used "name hook" applies to this code point.
			and codepoint >= name_range_cache1
			and codepoint "):format(codepoint)
	end
end
--
-- No image data modules on Wikipedia yet.
function p.lookup_image(codepoint)
	local data = loader('images/%03X'):format(codepoint / 0x1000)
	
	if data then
		return datacodepoint
	end
end
--
local planes = {
	 0 = "Basic Multilingual Plane";
	 1 = "Supplementary Multilingual Plane";
	 2 = "Supplementary Ideographic Plane";
	 3 = "Tertiary Ideographic Plane";
	14 = "Supplementary Special-purpose Plane";
	15 = "Supplementary Private Use Area-A";
	16 = "Supplementary Private Use Area-B";
}
-- Load Module:Unicode data/blocks if needed and assign it to this variable.
local blocks
local function block_iter(blocks, i)
	i = i + 1
	local data = blocksi
	if data then
		 -- Unpack doesn't work on tables loaded with mw.loadData.
		return i, data1, data2, data3
	end
end
-- An ipairs-type iterator generator for the list of blocks.
function p.enum_blocks()
	local blocks = loader.blocks
	return block_iter, blocks, 0
end
function p.lookup_plane(codepoint)
	local i = floor(codepoint / 0x10000)
	return planesi or ("Plane %u"):format(i)
end
function p.lookup_block(codepoint)
	local blocks = loader.blocks
	local range = binary_range_search(codepoint, blocks)
	if range then
		return range3
	else
		return "No Block"
	end
end
function p.get_block_info(name)
	for i, block in ipairs(loader.blocks) do
		if block3 == name then
			return block
		end
	end
end
function p.is_valid_pagename(pagename)
	local has_nonws = false
	for cp in mw.ustring.gcodepoint(pagename) do
		if (cp == 0x0023) -- #
		or (cp == 0x005B) -- 
		or (cp == 0x005D) -- 
		or (cp == 0x007B) -- {
		or (cp == 0x007C) -- |
		or (cp == 0x007D) -- }
		or (cp == 0x180E) -- MONGOLIAN VOWEL SEPARATOR
		or ((cp >= 0x2000) and (cp = from then
			table.insert(result, item)
		end
	end
	return unpack(result)
end
local function compare_ranges(range1, range2)
	return range11  rangesindex2 then
				dots_range = {
					rangesindex2 + 1,
					rangesindex + 1 and rangesindex + 11 - 1 or 0x10FFFF,
					unpack(dots)
				}
			else -- codepoint  false, return offending charactor's position as second return value; nil else
end
-- Checks that a string contains only characters belonging to right-to-left
-- scripts, or characters of ignorable scripts.
function p.is_rtl(str)
	require "libraryUtil".checkType("get_best_script", 1, str, "string")
	str = mw.text.decode(str, true)
	
	-- Search for the leading bytes that introduce the UTF-8 encoding of the
	-- code points U+0580-U+10FFFF. If they are not found, the string can only
	-- have characters from a left-to-right script, because the first code point
	-- in a right-to-left script is U+0591, in the Hebrew block.
	if not str:find "\214-\244" then
		return false
	end
	
	local result = false
	local rtl = loader.scripts.rtl
	for codepoint in mw.ustring.gcodepoint(str) do
		local script = lookup_script(codepoint)
		
		if rtlscript then
			result = true
		elseif not (script == "Zyyy" or script == "Zinh"
				or script == "Zzzz") then
			return false
		end
	end
	
	return result
end
----------------------------------------------------------------------------------
external entry from an  to determine if a string of text is rtl.  Strips html and html-like tags so
that those tags don't corrupt the is-rtl-is-not-rtl determination; this added for the cases where the rtl text
has  tags.
function p.is_rtl_frame (frame)
	local str = frame.args1;													-- get the string from the  frame
	str = str:gsub ('%b', );												-- strip any html and html-like tags
	return p.is_rtl (str);														-- return if whatever remains rtl; false else
end
local function get_codepoint(args, arg)
	local codepoint_string = argsarg
		or errorf(2, "Parameter %s is required", tostring(arg))
	local codepoint = tonumber(codepoint_string, 16)
		or errorf(2, "Parameter %s is not a code point in hexadecimal base",
			tostring(arg))
	if not (0  from being
		-- interpreted as HTML tags.
		result = result:gsub("<", "<")
	end
	return result
end
function p.is(frame)
	local func = get_func(frame.args, 1, "is_")
	
	-- is_Latin and is_valid_pagename take strings.
	if func == p.is_Latin or func == p.is_valid_pagename or func == p.is_rtl then
		return (func(frame.args2))
	else -- The rest take code points.
		local codepoint = get_codepoint(frame.args, 2)
		return (func(codepoint)) -- Adjust to one result.
	end
end
--
-- No Cantonese data modules on Wikipedia yet.
function p.lookup_kCantonese(codepoint)
	local data = loader('Unihan/kCantonese/%02X'):format(floor(codepoint / 0x1000))
	if data then
		return datacodepoint
	end
end
--
return p