মডিউল:cau-nec-translit
এই মডিউলের জন্য মডিউল:cau-nec-translit/নথি-এ নথিপত্র তৈরি করা হয়ে থাকতে পারে
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 CyrlConsonant = "бвгджзклмнпрстфхцчшщБВГДЖЗКЛМНПРСТФХЦЧШЩ"
local CyrlVowel = "аеёиоуыэюяАЕЁИОУЫЭЮЯ"
local ACUTE, CIRC, TILDE, MACRON, BREVE, DOTABOVE, DIAER, CARON, DOTBELOW = u(0x301), u(0x302), u(0x303), u(0x304), u(0x306), u(0x307), u(0x308), u(0x30C), u(0x323)
local accent = "[" .. ACUTE .. CIRC .. TILDE .. MACRON .. BREVE .. DOTABOVE .. DIAER .. CARON .. DOTBELOW .. "]"
local br = u(0xF000)
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ʼ", ["сӏ"] = "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"
}
}
-- Chechen and Ingush
elseif lang == "ce" or lang == "inh" then
return {
{
["ккх"] = "qq", ["рхӏ"] = "rh"
},
{
["гӏ"] = "ğ", ["кх"] = "q", ["къ"] = "qʼ", ["кӏ"] = "kʼ", ["пӏ"] = "pʼ", ["тӏ"] = "tʼ", ["хь"] = "ḥʳ", ["хӏ"] = "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
local function double_with_j(vowel, acute, nasal)
local ret = vowel .. (nasal ~= "" and TILDE or nasal)
return ret .. acute .. lower(ret)
end
function export.tr(text, lang, sc)
local subs = getSubs(lang)
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 = gsub(text, "[IlІӀ]", "ӏ")
-- Convert dialectal nasal ᵸ written as Latin ᴴ.
text = gsub(text, "ᴴ", "ᵸ")
-- Decompose precomposed characters, except for ё and й.
text = gsub(text, "[^ёЁйЙ]", 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 .. lower(a) .. b .. br end
text = gsub(text, "([" .. CyrlConsonant .. "])" .. MACRON .. "([ъь])" .. MACRON, macronToDouble)
text = gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ])" .. MACRON .. "(ӏ)" .. MACRON, macronToDouble)
text = gsub(text, "([" .. CyrlConsonant .. "])" .. MACRON, macronToDouble)
-- Remove any double hard/soft signs or palochkas this creates.
text = gsub(text, "([ъьӏЪЬӀ])" .. "([ъьӏ])", function(a, b) if b == 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 = gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ]" .. br .. "?[ӏӀ]?" .. br .. "?)в", "%1ʷ")
else
text = gsub(gsub(text, "^е", "jе"), "^Е", "Jе")
text = gsub(text, "([" .. CyrlVowel .. "%s%p]" .. MACRON .. "?ь?ӏ?ᵸ?)е", "%1jе")
text = gsub(text, "([%s%p])Е", "%1Jе")
text = gsub(text, "у([аиоуыэ])", "w%1")
text = gsub(text, "У([аиоуыэ])", "W%1")
text = gsub(text, "([" .. CyrlVowel .. "]" .. MACRON .. "?ь?ӏ?ᵸ?)у", "%1w")
text = gsub(text, "([" .. CyrlConsonant .. "ъьЪЬ]" .. br .. "?)в", "%1ʷ")
end
-- Add "j" before iotated vowels, and substitute non-iotated equivalents.
text = gsub(gsub(text, "ё", "jо"), "Ё", "Jо")
text = gsub(gsub(text, "ю", "jу"), "Ю", "Jу")
text = gsub(gsub(text, "я", "jа"), "Я", "Jа")
-- Process vowel modifiers.
text = gsub(text, "([" .. CyrlVowel .. "])(" .. MACRON .. "?)(" .. ACUTE .. "?)(ь?)(" .. MACRON .. "?)(ӏ?)(ᵸ?)", function(vowel, macron1, acute, soft, macron2, palochka, nasal)
local ret = vowel ..
(soft ~= "" and DIAER or soft) ..
(palochka ~= "" and lang == "aqc" and DOTBELOW or "") ..
(nasal ~= "" and TILDE or nasal)
if macron1 ~= "" then
ret = ret .. acute .. lower(ret)
else
ret = ret .. acute
end
return ret .. (lang ~= "aqc" and palochka or "")
end)
if lang == "ce" or lang == "inh" then
text = gsub(text, "([иИ])(" .. ACUTE .. "?" .. ")й(ᵸ?)", double_with_j)
text = gsub(text, "([уУ]" .. DIAER .. ")(" .. ACUTE .. "?" .. ")й(ᵸ?)", double_with_j)
end
-- 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[gsub(k, "^.", upper)] = gsub(v, "^.", "Ɂ")
else
t[gsub(k, "^.", upper)] = gsub(v, "^.", upper)
end
end
for letter, replacement in pairs(t) do
text = text:gsub(letter, replacement)
end
end
-- Reposition apostrophes, remove temporary breaking characters, then decompose.
text = toNFD(gsub(gsub(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ƏƔɁʻˀ", ".[\128-\191]*") do
text = gsub(text, "(ᵏ?)" .. letter .. "(" .. accent .. "?" .. accent .. "?" .. accent .. "?)([ʰʲˡʳˢʷˣˠ]?[ʲʷ]?ʼ?)" .. "%1" .. lower(letter) .. "%2%3", "%1" .. letter .. "%2" .. lower(letter) .. "%2%3")
end
-- Remove consecutive j/ʲ and w/ʷ.
text = gsub(gsub(text, "ʲ?([Jj])ʲ?", "%1"), "ʷ?([Ww])ʷ?", "%1")
-- Substitute i for dotted dotless i if not followed by an acute or tilde, then recompose.
return toNFC(gsub(gsub(text, "ı" .. "(" .. DOTBELOW .. "?)" .. DOTABOVE .. "([^" .. ACUTE .. TILDE .. "])", "i%1%2"), "ı" .. "(" .. DOTBELOW .. "?)" .. DOTABOVE .. "$", "i%1"))
end
return export