Module:vi-sortkey

local export = {}

local U = mw.ustring.char

local breve = U(0x306)
local circum = U(0x302)
local horn = U(0x31B)

local grave = U(0x300)
local hook = U(0x309)
local tilde = U(0x303)
local acute = U(0x301)
local dot = U(0x323)

--[[
local diacritics = breve .. circum .. horn .. grave .. hook .. tilde .. acute .. dot
local diacritic = "[" .. diacritics .. "]"
--]]

-- Determines sort order of diacritics. The full-size numbers are placed at the
-- end of the syllable, the subscript numbers immediately after the vowel.
local replacements = {
	--[[	Diacritics that form separate vowel letters. ]]
	[breve] = "₁",
	[circum] = "₂",
	[horn] = "₃",
	
	--[[	Tonal diacritics ]]
--[[ Order given by Stephen G. Brown
	[acute] = 1,
	[grave] = 2,
	[hook] = 3,
	[tilde] = 4,
	[dot] = 5,
]]
-- Order given by Fumiko Take
	[grave] = 1,
	[hook] = 2,
	[tilde] = 3,
	[acute] = 4,
	[dot] = 5,
	
	["đ"] = "d₁",
	["-"] = " ",
}
	
local vi = require("Module:languages").getByCode("vi")
local function tag(text)
	return require("Module:script utilities").tag_text(text, vi)
end

function export.makeSortKey(text, lang, sc)
	if lang and lang ~= "vi" then
		return text
	end
	
	if not sc then
		sc = text and require("Module:scripts").findBestScript(text, vi):getCode()
	end
	
	if sc then
		if sc == "Hani" then
			return require("Module:zh-sortkey").makeSortKey(text, lang, sc)
		elseif sc ~= "Latn" then
			return text
		end
	end
	
	if not text then
		return nil
	end
	
	local sortkey = text
	
	--[=[
		[[Module:languages]] currently converts text to lowercase
		before applying changes, then to uppercase before outputting
		the result.
	]=]
	if mw.title.getCurrentTitle().nsText == "Module" then
		sortkey = mw.ustring.lower(text)
	end
	
	sortkey = mw.ustring.toNFD(sortkey)
	
	sortkey = sortkey:gsub("[%z\1-\127\194-\244][\128-\191]*", replacements) -- pattern for UTF-8 character
	
	sortkey = mw.ustring.gsub(sortkey, "([0-4])([₀-₃])", "%2%1")
	
	-- move tone number to end of syllable
	sortkey = mw.ustring.gsub(sortkey, '([1-5])([^%s]+)', '%2%1')
	
	return sortkey
end

function export.showSortkey(frame)
	local output = {}
	
	for _, word in ipairs(frame.args) do
		local example = "\n* <code>" .. export.makeSortKey(word) .. "</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
		terms[i] = "\n* " .. tag(term) .. " (<code>" .. makeSortKey(term) .. "</code>)"
	end
	
	return table.concat(terms)
end

return export