Module:Hani-sortkey/data/serializer


local insert = table.insert

local export = {}

local byte_lookup = {
	[0x07] = "\\a",
	[0x08] = "\\b",
	[0x09] = "\\t",
	[0x0A] = "\\n",
	[0x0B] = "\\v",
	[0x0C] = "\\f",
	[0x0D] = "\\r",
	[0x22] = "\\\"",
	[0x5C] = "\\\\",
}

local _char = string.char
local function char(ch)
	return byte_lookup[ch] or
		(ch < 0x20 or ch >= 0x7F) and "\\" .. ("%03d"):format(ch) or
		_char(ch)
end

function export.main(checker)
	local keys = require("Module:Hani-sortkey/data")
	local radicals = require("Module:Hani-sortkey/data/core").radicals
	local ret, val = {}
	
	for i = 1, 0x323AF do
		if keys[i] then
			for r, as in keys[i]:gmatch("(%d+)%.(.*)") do
				insert(ret, char(tonumber(r)))
				-- Negative additional stroke counts are subtractive (i.e. -1 becomes -9, -2 becomes -8 etc.), so that lower values sort before higher ones (i.e. -3, -2, -1 ...).
				as = tonumber(as)
				insert(ret, char(as < 0 and 0 - as or as + 10))
			end
		end
	end
	
	-- Compress the result.
	for i = 1, #ret do
		local ch = ret[i]
		if ch:match("^\\%d%d%d$") then
			local nxt = ret[i + 1]
			if not (nxt and nxt:sub(1, 1):match("%d")) then
				ret[i] = ("\\%d"):format(ch:sub(2))
			end
		end
	end
	
	return table.concat(ret)
end

return export