Bước tới nội dung

Mô đun:cau-nec-translit

Từ điển mở Wiktionary
local export = {}

-- Structured like this to reduce size of loaded table.
local function getSubs(lang)
	--Aghul
	if lang == "agx" then
		return {
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ʻʳ", ["къ"] = "qq", ["кь"] = "qʼ", ["кӏ"] = "kʼ", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "q", ["хь"] = "x̂", ["хӏ"] = "ḥʳ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Akhvakh
	elseif lang == "akv" then
		return {
			{
				["гъӏ"] = "ğʰ", ["къӏ"] = "qˣʼ", ["кьӏ"] = "kˡʼ", ["лӏъ"] = "ᵏl", ["хъӏ"] = "qˣ"
			},
			{
				["гъ"] = "ɣ", ["гь"] = "h", ["гӏ"] = "ʻʳ", ["къ"] = "qxʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["ль"] = "ĺ", ["лӏ"] = "ᵏll", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "qx", ["хь"] = "x̂", ["хӏ"] = "ḥʳ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Andi
	elseif lang == "ani" then
		return {
			{
				["къкъ"] = "qxʼ", ["хъхъ"] = "qx"
			},
			{
				["гъӏ"] = "ğʼ", ["жъӏ"] = "žʼ", ["къӏ"] = "qxʼ", ["лъӏ"] = "llˢʼ", ["хъӏ"] = "qx", ["цъӏ"] = "ccʼ", ["чъӏ"] = "cčʼ"
			},
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "gʼ", ["къ"] = "qˣʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["ль"] = "lˢʼ", ["лӏ"] = "ᵏll", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "qˣ", ["хь"] = "x̂", ["хӏ"] = "xʼ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ˀ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Archi
	elseif lang == "aqc" then
		return {
			{
				["ккъӏ"] = "qq̣ʼ"
			},
			{
				["гъӏ"] = "ğ̣", ["ккъ"] = "qqʼ", ["къӏ"] = "q̣ʼ", ["хъӏ"] = "q̣", ["хьӏ"] = "x̣"
			},
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ˀ", ["къ"] = "qʼ", ["кь"] = "kˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lʰ", ["ль"] = "lˠ", ["лӏ"] = "ᵏl", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "q", ["хӏ"] = "ḥʳ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "w", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Avar
	elseif lang == "av" then
		return {
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ʻ", ["къ"] = "qxʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["лӏ"] = "ᵏll", ["тӏ"] = "tʼ", ["хъ"] = "qx", ["хь"] = "x̂", ["хӏ"] = "ḥʳ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "w", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Bagvalal
	elseif lang == "kva" then
		return {
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ˀ", ["къ"] = "qʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["лӏ"] = "ᵏll", ["сӏ"] = "sʼ", ["тӏ"] = "tʼ", ["хъ"] = "qx", ["хь"] = "x̂", ["хӏ"] = "ḥ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ", ["шӏ"] = "šʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Bezhta
	elseif lang == "kap" then
		return {
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ʻ", ["къ"] = "qxʼ", ["кь"] = "kˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["лӏ"] = "ᵏll", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "qx", ["хь"] = "x̂", ["хӏ"] = "ḥ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Botlikh
	elseif lang == "bph" then
		return {
			{
				["гъ"] = "ğ", ["гь"] = "h", ["къ"] = "qˣʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["лӏ"] = "ᵏll", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "qˣ", ["хь"] = "x̂", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "w", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ˀ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Budukh
	elseif lang == "bdk" then
		return {
			{
				["къг"] = "gʰ"
			},
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ʻ", ["къ"] = "qq", ["кь"] = "qʼ", ["кӏ"] = "kʼ", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "q", ["хь"] = "x̂", ["хӏ"] = "ḥ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ı", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja", ["ӏ"] = "ˀ"
			}
		}
	-- Chamalal
	elseif lang == "cji" then
		return {
			{
				["кӏкӏ"] = "kxʰʼ"
			},
			{
				["гъ"] = "ğ", ["гь"] = "h", ["гӏ"] = "ʻ", ["къ"] = "qxʼ", ["кь"] = "kkˡʼ", ["кӏ"] = "kʼ", ["лъ"] = "lˢ", ["лӏ"] = "ᵏll", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хъ"] = "qx", ["хь"] = "x̂", ["хӏ"] = "ḥ", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šš", ["ъ"] = "ʔ", ["ы"] = "ə", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja"
			}
		}
	-- Chechen
	elseif lang == "ce" then
		return {
			{
				["ккх"] = "qq", ["рхӏ"] = "rh"
			},
			{
				["гӏ"] = "ğ", ["ий"] = "ii", ["кх"] = "q", ["къ"] = "qʼ", ["кӏ"] = "kʼ", ["ов"] = "ow", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["ув"] = "uw", ["хь"] = "ḥʳ", ["хӏ"] = "h", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šč", ["ъ"] = "ʔ", ["ы"] = "y", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja", ["ӏ"] = "ˀ"
			}
		}
	-- Ingush
	elseif lang == "inh" then
		return {
			{
				["ккх"] = "qq", ["рхӏ"] = "rh"
			},
			{
				["гӏ"] = "ğ", ["ий"] = "ii", ["кх"] = "q", ["къ"] = "qʼ", ["кӏ"] = "kʼ", ["ов"] = "ow", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["ув"] = "uw", ["хь"] = "ḥʳ", ["хӏ"] = "h", ["цӏ"] = "cʼ", ["чӏ"] = "čʼ"
			},
			{
				["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "jo", ["ж"] = "ž", ["з"] = "z", ["и"] = "ı̇", ["й"] = "j", ["к"] = "k", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "x", ["ц"] = "c", ["ч"] = "č", ["ш"] = "š", ["щ"] = "šč", ["ъ"] = "ʔ", ["ы"] = "y", ["ь"] = "ʲ", ["э"] = "e", ["ю"] = "ju", ["я"] = "ja", ["ӏ"] = "ˀ"
			}
		}
	end
end

function export.tr(text, lang, sc)
	local subs = getSubs(lang)
	local UTF8_char = "[%z\1-\127\194-\244][\128-\191]*"
	local CyrlConsonant = "бвгджзклмнпрстфхцчшщБВГДЖЗКЛМНПРСТФХЦЧШЩ"
	local CyrlVowel = "аеёиоуыэюяАЕЁИОУЫЭЮЯ"
	local ACUTE, CIRC, TILDE, MACRON, BREVE, DOTABOVE, DIAER, CARON, DOTBELOW = mw.ustring.char(0x301), mw.ustring.char(0x302), mw.ustring.char(0x303), mw.ustring.char(0x304), mw.ustring.char(0x306), mw.ustring.char(0x307), mw.ustring.char(0x308), mw.ustring.char(0x30C), mw.ustring.char(0x323)
	local accent = "[" .. ACUTE .. CIRC .. TILDE .. MACRON .. BREVE .. DOTABOVE .. DIAER .. CARON .. DOTBELOW .. "]"
	local br = mw.ustring.char(0xF000)
	
	if not subs then
		return nil
	end
	
	-- Convert uppercase palochka to lowercase, along with any "false" palochkas (entered as Latin "I" or "l", or Cyrillic "І"). Lowercase palochka is found in tables above.
	text = mw.ustring.gsub(text, "[IlІӀ]", "ӏ")
	-- Convert dialectal nasal ᵸ written as Latin ᴴ.
	text = mw.ustring.gsub(text, "ᴴ", "ᵸ")
	
	-- Decompose precomposed characters, except for ё and й.
	text = mw.ustring.gsub(text, "[^ёЁйЙ]", mw.ustring.toNFD)
	
	-- Substitute double consonants for macrons over consonants. Add a temporary breaking character after, to prevent the creation of false multigraphs with following characters.
	local function macronToDouble(a, b) return a .. b .. mw.ustring.lower(a) .. b .. br end
	text = mw.ustring.gsub(text, "([" .. CyrlConsonant .. "])" .. MACRON .. "([ъь])" .. MACRON, macronToDouble)
	text = mw.ustring.gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ])" .. MACRON .. "(ӏ)" .. MACRON, macronToDouble)
	text = mw.ustring.gsub(text, "([" .. CyrlConsonant .. "])" .. MACRON, macronToDouble)
	
	-- Remove any double hard/soft signs or palochkas this creates.
	text = mw.ustring.gsub(text, "([ъьӏЪЬӀ])" .. "([ъьӏ])", function(a, b) if b == mw.ustring.lower(a) then return a else return a .. b end end)
	
	-- Contextual substitution of "j" before "е", "w" for "у" and ʷ for "в".
	if lang == "aqc" then
		text = mw.ustring.gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ]" .. br .. "?[ӏӀ]?" .. br .. "?)в", "%1ʷ")
	else
		text = mw.ustring.gsub(mw.ustring.gsub(text, "^е", "jе"), "^Е", "Jе")
		text = mw.ustring.gsub(text, "([" .. CyrlVowel .. "%s%p]" .. MACRON .. "?ь?ӏ?ᵸ?)е", "%1jе")
		text = mw.ustring.gsub(text, "([%s%p])Е", "%1Jе")
		text = mw.ustring.gsub(text, "у([аиоуыэ])", "w%1")
		text = mw.ustring.gsub(text, "У([аиоуыэ])", "W%1")
		text = mw.ustring.gsub(text, "([" .. CyrlVowel .. "]" .. MACRON .. "?ь?ӏ?ᵸ?)у", "%1w")
		text = mw.ustring.gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ]" .. br .. "?)в", "%1ʷ")
	end
	
	-- Add "j" before iotated vowels, and substitute non-iotated equivalents.
	text = mw.ustring.gsub(mw.ustring.gsub(text, "ё", "jо"), "Ё", "Jо")
	text = mw.ustring.gsub(mw.ustring.gsub(text, "ю", "jу"), "Ю", "Jу")
	text = mw.ustring.gsub(mw.ustring.gsub(text, "я", "jа"), "Я", "Jа")
	
	-- Process vowel modifiers.
	text = mw.ustring.gsub(text, "ᵸ", TILDE)
	text = mw.ustring.gsub(text, "([" .. CyrlVowel .. "])(" .. MACRON .. "?" .. ACUTE .. "?ь?" .. MACRON .. "?)ӏ", "%1" .. DOTBELOW .. "%2")
	text = mw.ustring.gsub(text, "([" .. CyrlVowel .. "]" .. DOTBELOW .. "?)" .. MACRON .. "(ь?)" .. MACRON .. "?(" .. TILDE .. "?)", function(a, b, c) return a .. b .. c .. mw.ustring.lower(a) .. b .. c end)
	text = mw.ustring.gsub(text, "([" .. CyrlVowel .. "]" .. DOTBELOW .. "?)" .. "ь", "%1" .. DIAER)
	
	-- Apply language-specific substitutions by iterating over each subtable. For each one, create a temporary table that stores each substitution in lowercase and uppercase variants. Then, iterate over all substitutions.
	for _,i in ipairs(subs) do
		local t = {}
		-- Create a temporary table, then iterate over all of them.
		for k, v in pairs(i) do
			t[k] = v
			if v == "ʔ" then
				t[mw.ustring.gsub(k, "^.", mw.ustring.upper)] = mw.ustring.gsub(v, "^.", "Ɂ")
			else
				t[mw.ustring.gsub(k, "^.", mw.ustring.upper)] = mw.ustring.gsub(v, "^.", mw.ustring.upper)
			end
		end
		for letter, replacement in pairs(t) do
			text = string.gsub(text, letter, replacement)
		end
	end
	
	-- Reposition apostrophes, remove temporary breaking characters, then decompose.
	text = mw.ustring.toNFD(mw.ustring.gsub(mw.ustring.gsub(mw.ustring.gsub(text, "ʼʲ", "ʲʼ"), "ʼʷ", "ʷʼ"), br, ""))
	
	-- When double letters both have a modifier letter and/or an apostrophe, only show on the first or second for readability purposes.
	for letter in string.gmatch("abcdefghijklmnopqrstuvwxyzəɣıʔABCDEFGHIJKLMNOPQRSTUVWXYZƏƔɁʻˀ", UTF8_char) do
		text = mw.ustring.gsub(text, "(ᵏ?)" .. letter .. "(" .. accent .. "?" .. accent .. "?" .. accent .. "?)([ʰʲˡʳˢʷˣˠ]?[ʲʷ]?ʼ?)" .. "%1" .. mw.ustring.lower(letter) .. "%2%3", "%1" .. letter .. "%2" .. mw.ustring.lower(letter) .. "%2%3")
	end
	
	-- Remove consecutive j/ʲ and w/ʷ.
	text = mw.ustring.gsub(mw.ustring.gsub(text, "ʲ?([Jj])ʲ?", "%1"), "ʷ?([Ww])ʷ?", "%1")
	
	-- Substitute i for dotted dotless i if not followed by an acute or tilde, then recompose.
	return mw.ustring.toNFC(mw.ustring.gsub(mw.ustring.gsub(text, "ı" .. "(" .. DOTBELOW .. "?)" .. DOTABOVE .. "([^" .. ACUTE .. TILDE .. "])", "i%1%2"), "ı" .. "(" .. DOTBELOW .. "?)" .. DOTABOVE .. "$", "i%1"))
end

return export