-- Denna modul används för att transkribera ryska.
--
-- För att transkribera bulgariska, ukrainska och
-- vitryska/belarusiska kan ett liknande system användas.
-- Det hanteras dock av särskilda moduler. Se:
--
-- Modul:translit/be
-- Modul:translit/bg
-- Modul:translit/uk
--
-- Systemet för transkribering följer det som anges i
-- "Svenska skrivregler" (2017), fjärde upplagan, red. Ola Karlsson
-- En kopia av avsnittet finns i skrivande stund här:
-- https://www.isof.se/download/18.648bef4b18093ee2f03ee80/1652364347434/Kyrillisk%20tabell%20SS2017.pdf
--
-- Notera att detta sätt är specifikt för att transkribera
-- till svenska. Transkribering till andra språk sker enligt
-- andra mönster. Exempelvis ska Горбачёв bli just Gorbatjóv.
-- På andra språk skulle det kunna bli Gorbachev, Gorbatschow,
-- Gorbatchev, Gorbatsjov, osv.
--
-- En vanlig fallgrop är att "ё" bara transkriberas korrekt när
-- de två punkterna är med. På ryska utelämnas de ofta när sammanhanget gör det
-- uppenbart. Alltså är det vanligt att "Пётр" istället stavas "Пeтр", vilket
-- denna modul följaktligen tolkar som "Petr" istället för "Pjotr".
--
-- Denna modul är gjord för att returnera latinska tecken med accenterna
-- utskrivna. Därför blir Горбачёв till Gorbatjóv, inte Gorbatjov.
--
-- TODO: Placera i en dold kategori för att markera de ord som inte har
-- tillräckligt många accenttecken
--
-- Denna modul används av följande mall:
-- {{tr}}
--
-- Modulen är författad av (och underhålls av) [[Användare:Gabbe]]
local export = {}
local Q = require("Modul:queue")
local multibyte_char_pattern = ".[\128-\191]*"
local latin_by_cyrillic = { ["А"]="A", ["а"]="a", ["Б"]="B", ["б"]="b", ["В"]="V", ["в"]="v",
["Г"]="G", ["г"]="g", ["Д"]="D", ["д"]="d", ["Е"]="E", ["е"]="e", ["Ё"]="Jo",
["ё"]="jo", ["Ж"]="Zj", ["ж"]="zj", ["З"]="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", ["Х"]="Ch", ["х"]="ch", ["Ц"]="Ts", ["ц"]="ts",
["Ч"]="Tj", ["ч"]="tj", ["Ш"]="Sj", ["ш"]="sj", ["Щ"]="Sjtj", ["щ"]="sjtj",
["Ъ"]="", ["ъ"]="", ["Ы"]="Y", ["ы"]="y", ["Ь"]="J", ["ь"]="j", ["Э"]="E",
["э"]="e", ["Ю"]="Ju", ["ю"]="ju", ["Я"]="Ja", ["я"]="ja" }
local function addAccentToYoInPolysyllabicWords(text)
local yo_without_accent = "ё"
local yo_with_accent = "ё́"
local whitespace_and_punctuation_pattern = "[%s%p]"
local removeAccentsFromYoToAvoidDoubleAccent = function(text)
return string.gsub(text, yo_with_accent, yo_without_accent)
end
local splitStringAndKeepSeparator = function(text, separator_pattern)
local t = {}
local i = 1
local accent = "́"
for c in string.gmatch(text, multibyte_char_pattern) do
if mw.ustring.find(c, separator_pattern) then
if (t[1] ~= nil) then
i = i + 1
end
t[i] = c
else
if not t[i] then
t[i] = c
else
t[i] = t[i] .. c
end
end
end
return t
end
local addAccentToYoIfPolysyllabic = function(words_and_punctuations)
local isPolysyllabic = function(word)
local vowels = "АЕЁИОУЭЮЫЯаеёиоуэюыя"
local neither_whitespace_nor_punctuation = "[^%s%p]"
local at_least_two_vowels_pattern = "[" .. vowels .. "]" .. neither_whitespace_nor_punctuation .. "*[" .. vowels .. "]"
return not not mw.ustring.find(word, at_least_two_vowels_pattern)
end
for i, word_or_punctuation in ipairs(words_and_punctuations) do
if isPolysyllabic(word_or_punctuation) then
words_and_punctuations[i] = string.gsub(word_or_punctuation, yo_without_accent, yo_with_accent)
end
end
return words_and_punctuations
end
text = removeAccentsFromYoToAvoidDoubleAccent(text)
local words_and_punctuations = splitStringAndKeepSeparator(text, whitespace_and_punctuation_pattern)
words_and_punctuations = addAccentToYoIfPolysyllabic(words_and_punctuations)
mw.logObject(words_and_punctuations)
text = table.concat(words_and_punctuations, "")
return text
end
function export.tr (text)
local cyrillic_q = Q()
local latin_q = Q()
text = addAccentToYoInPolysyllabicWords(text)
for c in string.gmatch(text, multibyte_char_pattern) do
Q.enqueue(cyrillic_q, c)
end
repeat
local x = Q.dequeue(cyrillic_q)
local y = Q.peekFirst(cyrillic_q)
local z = Q.peekSecond(cyrillic_q)
local u = Q.peekLast(latin_q)
local accent = "́"
if not latin_by_cyrillic[x] then
Q.enqueue(latin_q, x)
elseif (Q.isEmpty(latin_q) or u == " ") and x == "Е" then
Q.enqueue(latin_q, "Je")
elseif (Q.isEmpty(latin_q) or u == " ") and x == "е" then
Q.enqueue(latin_q, "je")
elseif x == "ь" then
if y == "и" then
Q.enqueue(latin_q, "ji")
Q.dequeue(cyrillic_q)
end
elseif x == "Ь" then
if y == "и" then
Q.enqueue(latin_q, "Ji")
Q.dequeue(cyrillic_q)
elseif y == "И" then
Q.enqueue(latin_q, "JI")
Q.dequeue(cyrillic_q)
end
elseif mw.ustring.find(x, "[стзСТЗ]") then
Q.enqueue(latin_q, latin_by_cyrillic[x])
if y == "ь" then
if z == "е" then
Q.enqueue(latin_q, "ie")
Q.dequeue(cyrillic_q)
Q.dequeue(cyrillic_q)
elseif z == "ё" then
Q.enqueue(latin_q, "io")
Q.dequeue(cyrillic_q)
Q.dequeue(cyrillic_q)
elseif z == "ю" then
Q.enqueue(latin_q, "iu")
Q.dequeue(cyrillic_q)
Q.dequeue(cyrillic_q)
elseif z == "я" then
Q.enqueue(latin_q, "ia")
Q.dequeue(cyrillic_q)
Q.dequeue(cyrillic_q)
end
elseif y == "ё" then
Q.enqueue(latin_q, "io")
Q.dequeue(cyrillic_q)
elseif y == "ю" then
Q.enqueue(latin_q, "iu")
Q.dequeue(cyrillic_q)
elseif y == "я" then
Q.enqueue(latin_q, "ia")
Q.dequeue(cyrillic_q)
end
elseif mw.ustring.find(x, "[шщчжШЩЧЖ]") then
Q.enqueue(latin_q, latin_by_cyrillic[x])
if y == "ё" then
Q.enqueue(latin_q, "o")
Q.dequeue(cyrillic_q)
end
elseif x == "е" then
if mw.ustring.find(u, "[aeouiyAEOUIY]") or u == accent then
Q.enqueue(latin_q, "je")
else
Q.enqueue(latin_q, "e")
end
else
Q.enqueue(latin_q, latin_by_cyrillic[x])
end
until Q.isEmpty(cyrillic_q)
local tbl = {}
repeat
local x = Q.dequeue(latin_q)
local y = Q.peekFirst(latin_q) or ""
local accent = "́"
if y == accent then
x = mw.ustring.toNFC(x .. y)
Q.dequeue(latin_q)
end
table.insert(tbl, x)
until Q.isEmpty(latin_q)
text = table.concat(tbl, "")
return text
end
return export