This module will transliterate ภาษาโรมาเนีย text. The module should preferably not be called directly from templates or other modules. To use it from a template, use {{xlit}}. Within a module, use Module:languages#Language:transliterate.

For testcases, see Module:ro-translit/testcases.

tr(text, lang, sc)
Transliterates a given piece of text written in the script specified by the code sc, and language specified by the code lang.
When the transliteration fails, returns nil.

local concat = table.concat
local explode = require("Module:string utilities").explode_utf8
local insert = table.insert
local gsub = mw.ustring.gsub
local match = mw.ustring.match
local uupper = string.uupper

-- Note: ё, ъ and щ only exist in borrowings.
local letters = {
	["а"] = "a", ["б"] = "b", ["в"] = "v", ["г"] = "g", ["д"] = "d", ["е"] = "e", ["ё"] = "io", ["ж"] = "j", ["ӂ"] = "gi", ["з"] = "z", ["и"] = "i", ["й"] = "i", ["к"] = "c", ["л"] = "l", ["м"] = "m", ["н"] = "n", ["о"] = "o", ["п"] = "p", ["р"] = "r", ["с"] = "s", ["т"] = "t", ["у"] = "u", ["ф"] = "f", ["х"] = "h", ["ц"] = "ț", ["ч"] = "ci", ["ш"] = "ș", ["щ"] = "șc", ["ъ"] = "ă", ["ы"] = "î", ["ь"] = "i", ["э"] = "ă", ["ю"] = "iu", ["я"] = "ia"
}

local vowel = {
	["а"] = true, ["е"] = true, ["ё"] = true, ["и"] = true, ["й"] = true, ["о"] = true, ["у"] = true, ["ъ"] = true, ["ы"] = true, ["ь"] = true, ["э"] = true, ["ю"] = true, ["я"] = true
}

local i_vowel_prev = {
	["и"] = true, ["й"] = true, ["ь"] = true
}

local ei_vowel_nxt = {
	["е"] = true, ["ё"] = true, ["и"] = true, ["ь"] = true, ["ю"] = true, ["я"] = true
}

local soft_cons = {
	["ӂ"] = "g", ["ч"] = "c"
}

local ea_cons = {
	["ж"] = true, ["ӂ"] = true, ["л"] = true, ["н"] = true, ["р"] = true, ["т"] = true, ["ш"] = true
}

local function is_letter(this)
	return this and match(this, "%w") and true or false
end

local export = {}

function export.tr(text, lang, sc)
	-- Only support modern Cyrillic (for now).
	if sc ~= "Cyrl" then
		return nil
	end
	
	local caps = {}
	text = gsub(text, "()(%u)", function(pos, this)
		caps[pos] = true
		return this:ulower()
	end)
	
	text = explode(text)
	
	local output, i, prev, this, nxt = {}, 0
	while i <= #text do
		prev, this, nxt = text[i - 1], text[i], text[i + 1]
		if soft_cons[this] then
			if ei_vowel_nxt[nxt] then
				this = soft_cons[this]
			elseif nxt == "а" then
				this = soft_cons[this] .. "e"
			end
		elseif this == "ё" and i_vowel_prev[prev] then
			this = "o"
		elseif this == "г" and ei_vowel_nxt[nxt] then
			this = "gh"
		elseif this == "и" and prev == "и" and not is_letter(nxt) then
			this = "ii"
		elseif this == "к" then
			if ei_vowel_nxt[nxt] then
				this = "ch"
			elseif nxt == "з" or nxt == "с" then
				this = "x"
				i = i + 1
			end
		elseif this == "ю" and i_vowel_prev[prev] then
			this = "u"
		elseif this == "я" then
			if i_vowel_prev[prev] then
				this = "a"
			elseif ea_cons[prev] then
				this = "ea"
			end
		end
		this = letters[this] or this
		insert(output, caps[i] and gsub(this, "^.", uupper) or this)
		i = i + 1
	end
	
	return concat(output)
end

return export