local export = {}

local toNFD = mw.ustring.toNFD

local noDecompose = {
	["ё"] = true, ["Ё"] = true,
	["й"] = true, ["Й"] = true,
}

local twoChars = {
	["де"] = "ʒe", ["Де"] = "Ʒe", ["ДЕ"] = "ƷE",
	["дё"] = "ʒo", ["Дё"] = "Ʒo", ["ДЁ"] = "ƷO",
	["ди"] = "ʒi", ["Ди"] = "Ʒi", ["ДИ"] = "ƷI",
	["дю"] = "ʒu", ["Дю"] = "Ʒu", ["ДЮ"] = "ƷU",
	["дя"] = "ʒa", ["Дя"] = "Ʒa", ["ДЯ"] = "ƷA",
	["дь"] = "ʒ", ["Дь"] = "Ʒ", ["ДЬ"] = "Ʒ",
	["нг"] = "ӈ", ["Нг"] = "Ӈ", ["НГ"] = "Ӈ",
}

local tab = {
	["а"] = "a", ["А"] = "A",
	["б"] = "b", ["Б"] = "B",
	["в"] = "w", ["В"] = "W",
	["г"] = "g", ["Г"] = "G",
	["д"] = "d", ["Д"] = "D",
	["е"] = "je", ["Е"] = "Je",
	["ё"] = "jo", ["Ё"] = "Jo",
	["ж"] = "ž", ["Ж"] = "Ž",
	["з"] = "z", ["З"] = "Z",
	["и"] = "i", ["И"] = "I",
	["й"] = "j", ["Й"] = "J",
	["к"] = "k", ["К"] = "K",
	["л"] = "l", ["Л"] = "L",
	["м"] = "m", ["М"] = "M",
	["н"] = "n", ["Н"] = "N",
	["ӈ"] = "ŋ", ["Ӈ"] = "Ŋ",
	["о"] = "o", ["О"] = "O",
	["п"] = "p", ["П"] = "P",
	["р"] = "r", ["Р"] = "R",
	["с"] = "s", ["С"] = "S",
	["т"] = "t", ["Т"] = "T",
	["у"] = "u", ["У"] = "U",
	["ф"] = "f", ["Ф"] = "F",
	["х"] = "h", ["Х"] = "H",
	["ц"] = "c", ["Ц"] = "C",
	["ч"] = "č", ["Ч"] = "Č",
	["ш"] = "š", ["Ш"] = "Š",
	["щ"] = "š", ["Щ"] = "Š",
	["ъ"] = "ʺ", ["Ъ"] = "ʺ",
	["ы"] = "y", ["Ы"] = "Y",
	["ь"] = "ʹ", ["Ь"] = "ʹ",
	["э"] = "e", ["Э"] = "E",
	["ю"] = "ju", ["Ю"] = "Ju",
	["я"] = "ja", ["Я"] = "Ja",
}


function export.tr(text, lang, sc)
	-- Decompose (except ё/Ё and й/Й) to simplify conversion of letters with macrons.
	text = text:gsub("[%z\1-\127\194-\244][\128-\191]*", function(m)
		if not noDecompose[m] then
			return toNFD(m)
		end
	end)
	
	for digraph, replacement in pairs(twoChars) do
		text = text:gsub(digraph, replacement)
	end
	
	return mw.ustring.toNFC((text:gsub("[%z\1-\127\194-\244][\128-\191]*", tab)))
end

return export