Documentation for this module may be created at မဝ်ဂျူ:vi-sortkey/doc

local export = {}

local m_str_utils = require("Module:string utilities")

local gsub = m_str_utils.gsub
local lower = m_str_utils.lower
local toNFC = mw.ustring.toNFC
local toNFD = mw.ustring.toNFD
local u = m_str_utils.char
local upper = m_str_utils.upper

local a, b = u(0xF000), u(0xF001)

local diacritics = {
	--[===[--Order given by Stephen G. Brown
	[u(0x0301)] = c, -- acute
	[u(0x0300)] = d, -- grave
	[u(0x0309)] = e, -- hook
	[u(0x0303)] = f, -- tilde
	[u(0x0323)] = g -- dot above]===]
	-- Order given by Fumiko Take
	[u(0x0300)] = "!", -- grave
	[u(0x0309)] = "#", -- hook
	[u(0x0303)] = "$", -- tilde
	[u(0x0301)] = "%", -- acute
	[u(0x0323)] = "&" -- dot above
}

local oneChar = { -- separate letters
	["ă"] = "a" .. a, ["â"] = "a" .. b, ["đ"] = "d" .. a, ["ê"] = "e" .. a, ["ô"] = "o" .. a, ["ơ"] = "o" .. b, ["ư"] = "u" .. a
}

function export.makeSortKey(text, lang, sc)
	text = gsub(lower(toNFD(text)), ".", diacritics)
	
	text = gsub(text, "([!-&])([^%s]+)", "%2%1")
	
	return upper(gsub(toNFC(text), ".", oneChar))
end

local vi = require("Module:languages").getByCode("vi")
local function tag(text)
	return require("Module:script utilities").tag_text(text, vi)
end

local showsubst = {
	[a] = "₂", [b] = "₃", ["!"] = "²", ["#"] = "³", ["$"] = "⁴", ["%"] = "⁵", ["&"] = "⁶"
}

function export.showSortkey(frame)
	local output = {}
	
	for _, word in ipairs(frame.args) do
		local sc = vi:findBestScript(word):getCode()
		local sortkey = gsub(export.makeSortKey(word, "vi", sc), ".", showsubst)
		sortkey = gsub(sortkey, "([^0-9²³⁴⁵⁶])$", "%1¹")
		sortkey = gsub(sortkey, "([^0-9²³⁴⁵⁶])(%s)", "%1¹%2")
		local example = "\n* <code>" .. sortkey .. "</code>\n: " .. tag(word)
		table.insert(output, example)
	end
	
	return table.concat(output)
end

function export.showSorting(frame)
	local terms = {}
	
	for _, term in ipairs(frame.args) do
		table.insert(terms, term)
	end
	
	local makeSortKey = require("Module:fun").memoize(export.makeSortKey)
	local function comp(term1, term2)
		return makeSortKey(term1) < makeSortKey(term2)
	end
	
	table.sort(terms, comp)
	
	for i, term in pairs(terms) do
		local sc = vi:findBestScript(term):getCode()
		local sortkey = gsub(export.makeSortKey(term, "vi", sc), ".", showsubst)
		sortkey = gsub(sortkey, "([^0-9²³⁴⁵⁶])$", "%1¹")
		sortkey = gsub(sortkey, "([^0-9²³⁴⁵⁶])(%s)", "%1¹%2")
		terms[i] = "\n* " .. tag(term) .. " (<code>" .. sortkey .. "</code>)"
	end
	
	return table.concat(terms)
end

return export