Moduł:transkrypcja-ru/PWN

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:transkrypcja-ru/PWN/opis

local p = {}

local errcat = '[[Kategoria:Błąd w transkrypcji]]'

local commonTransliteration = {
    ["-"] = "-",
    ["–"] = "–",
    ["—"] = "—",
    ["="] = "=",
    [","] = ",",
    ["."] = ".",
    ["/"] = "/",
    [";"] = ";",
    ["'"] = "'",
    ["["] = "[",
    ["]"] = "]",
    ["\\"] = "\\",
    ["`"] = "`",
    ["~"] = "~",
    ["!"] = "!",
    ["@"] = "@",
    ["#"] = "#",
    ["$"] = "$",
    ["%"] = "%",
    ["^"] = "^",
    ["&"] = "&",
    ["*"] = "*",
    ["("] = "(",
    [")"] = ")",
    ["_"] = "_",
    ["+"] = "+",
    ["{"] = "{",
    ["}"] = "}",
    ["|"] = "|",
    [":"] = ":",
    ["\""] = "\"",
    ["<"] = "<",
    [">"] = ">",
    ["?"] = "?" ,
    [" "] = " "
}

local transliterationRu = {
    ["а"] = "a",
    ["б"] = "b",
    ["в"] = "w",
    ["г"] = "g",
    ["д"] = "d",
    -- Е > E
    ["же"] = "że",
    ["ле"] = "le",
    ["це"] = "ce",
    ["че"] = "cze",
    ["ше"] = "sze",
    ["ще"] = "szcze",
    -- koniec
    -- Е > IE
    ["бе"] = "bie",
    ["ве"] = "wie",
    ["ге"] = "gie",
    ["де"] = "die",
    ["зе"] = "zie",
    ["йе"] = "jie",
    ["ке"] = "kie",
    ["ме"] = "mie",
    ["не"] = "nie",
    ["пе"] = "pie",
    ["ре"] = "rie",
    ["се"] = "sie",
    ["те"] = "tie",
    ["фе"] = "fie",
    ["хе"] = "chie",
    -- koniec
    -- Е > JE
    ["е"] = "je",
    ["ъе"] = "je",
    ["ие"] = "ije",
    ["ое"] = "oje",
    ["уе"] = "uje",
    ["ые"] = "yje",
    ["юе"] = "juje",
    ["яе"] = "jaje",
    -- koniec
    -- Ё > O
    ["жё"] = "żo",
    ["лё"] = "lo",
    ["чё"] = "czo",
    ["шё"] = "szo",
    ["щё"] = "szczo",
    -- koniec
    -- Ё > JO
    ["ё"] = "jo",
    ["ъё"] = "jo",
    ["ьё"] = "jo",
    ["иё"] = "ijo",
    ["её"] = "jejo",
    ["оё"] = "ojo",
    ["уё"] = "ujo",
    ["ыёё"] = "yjo",
    ["юё"] = "jujo",
    ["яё"] = "jajo",
    -- koniec
    -- Ё > IO
    ["бё"] = "bio",
    ["вё"] = "wio",
    ["гё"] = "gio",
    ["дё"] = "dio",
    ["зё"] = "zio",
    ["йё"] = "jio",
    ["кё"] = "kio",
    ["мё"] = "mio",
    ["нё"] = "nio",
    ["пё"] = "pio",
    ["рё"] = "rio",
    ["сё"] = "sio",
    ["тё"] = "tio",
    ["фё"] = "fio",
    ["хё"] = "chio",
    ["цё"] = "cio",
    -- koniec
    ["ж"] = "ż",
    ["з"] = "z",
    -- И > Y
    ["жи"] = "ży",
    ["ци"] = "cy",
    ["ши"] = "szy",
    -- koniec
    ["и"] = "i",
    ["й"] = "j",
    ["к"] = "k",
    ["л"] = "ł",
    -- Л > L
    ["ле"] = "le",
    ["лё"] = "lo",
    ["ли"] = "li",
    ["ль"] = "l",
    -- koniec
    ["м"] = "m",
    ["н"] = "n",
    ["о"] = "o",
    ["п"] = "p",
    ["р"] = "r",
    ["с"] = "s",
    ["т"] = "t",
    ["у"] = "u",
    ["ф"] = "f",
    ["х"] = "ch",
    ["ц"] = "c",
    ["ч"] = "cz",
    ["ш"] = "sz",
    ["щ"] = "szcz",
    ["ъ"] = "",
    ["ы"] = "y",
    -- Ь > ∅
    ["ль"] = "l",
    ["жь"] = "ż",
    ["чь"] = "cz",
    ["шь"] = "sz",
    ["щь"] = "szcz",
    ["ьа"] = "a",
    ["ьё"] = "jo",
    ["ьи"] = "ji",
    ["ьо"] = "o",
    ["ьу"] = "u",
    -- koniec
    ["ь"] = "´",
    ["э"] = "e",
    -- Ю > JU
    ["ъю"] = "ju",
    ["ью"] = "ju",
    ["ию"] = "iju",
    ["ею"] = "jeju",
    ["ёю"] = "jeju",
    ["ою"] = "oju",
    ["ую"] = "uju",
    ["ыю"] = "yju",
    ["яю"] = "jaju",
    -- koniec
    -- Ю > U
    ["лю"] = "lu",
    -- koniec
    -- Ю > IU
    ["бю"] = "biu",
    ["вю"] = "wiu",
    ["гю"] = "giu",
    ["дю"] = "diu",
    ["жю"] = "żiu",
    ["зю"] = "ziu",
    ["йю"] = "jiu",
    ["кю"] = "kiu",
    ["мю"] = "miu",
    ["ню"] = "niu",
    ["пю"] = "piu",
    ["рю"] = "riu",
    ["сю"] = "siu",
    ["тю"] = "tiu",
    ["фю"] = "fiu",
    ["хю"] = "chiu",
    ["цю"] = "ciu",
    ["чю"] = "cziu",
    ["шю"] = "sziu",
    ["щю"] = "szcziu",
    -- koniec
    ["ю"] = "ju",
    -- Я > JA
    ["ъя"] = "ja",
    ["ья"] = "ja",
    ["ия"] = "ija",
    ["ея"] = "jeja",
    ["ёя"] = "jeja",
    ["оя"] = "oja",
    ["уя"] = "aja",
    ["ыя"] = "yja",
    ["юя"] = "juja",
    -- koniec
    -- Я > A
    ["ля"] = "la",
    -- koniec
    -- Я > IA
    ["бя"] = "bia",
    ["вя"] = "wia",
    ["гя"] = "gia",
    ["дя"] = "dia",
    ["жя"] = "żia",
    ["зя"] = "zia",
    ["йя"] = "jia",
    ["кя"] = "kia",
    ["мя"] = "mia",
    ["ня"] = "nia",
    ["пя"] = "pia",
    ["ря"] = "ria",
    ["ся"] = "sia",
    ["тя"] = "tia",
    ["фя"] = "fia",
    ["хя"] = "chia",
    ["ця"] = "cia",
    ["чя"] = "czia",
    ["шя"] = "szia",
    ["щя"] = "szczia",
    -- koniec
    ["я"] = "ja",
    ["’"] = "’"
}

local transliterations = {
    ["ru"] = transliterationRu,
}

local function sanitizeText( text )
    local result = text
    result = string.gsub( result, "&#39;", "'" )
    result = string.gsub( result, "&quot;", "\"" )
    result = string.gsub( result, "&amp;", "&" )
    return result
end

function p.transliterate( frame )
    local language = frame.args[1]
    local text = sanitizeText( frame.args[2] )
    local transliteration = transliterations[ language ]
    
    if transliteration == nil then
        return "Błędny kod języka: " .. language
    end
    
    -- Dla znaków, które należy transkrybować inaczej na końcu wyrazu
    local endOfTextMarker = '~'
    local result = {}
    
    for word in mw.text.gsplit( text, ' ', true ) do
	    word = word .. endOfTextMarker
	    local inputLength = mw.ustring.len( word )
	    local currentPos = 1
	    local partialResult = ''
	    local maxSeqLength = 1
	    
	    -- Wyznacz najdłuższą sekwencję w języku wejściowym
	    for seq, _ in pairs( transliteration ) do
	    	maxSeqLength = math.max( maxSeqLength, mw.ustring.len( seq ) )
	    end
	    
	    while currentPos <= inputLength do
	    	-- Zacznij od najdłuższej sekwencji, która jeszcze się zmieści
	    	local initialSeqLength = math.min( maxSeqLength, inputLength - currentPos + 1 )
	    	local textLower = mw.ustring.lower( word )
	    	
	    	-- Próbuj dopasować sekwencje od najdłuższej możliwej (czyli najszczegółowszej)
	    	for seqLength = initialSeqLength, 1, -1 do
	    		local unTrl = mw.ustring.sub( textLower, currentPos, currentPos + seqLength - 1 )
	    		local trl = transliteration[ unTrl ] or commonTransliteration[ unTrl ]
	    		
	    		-- Jeśli dopasowano, dopisz do wyniku i przesuń wskaźnik pozycji
	    		if trl ~= nil then
	    			-- Jeśli w oryginale była wielka litera, zmień pierwszą literę wyniku na wielką
	    			local firstChar = mw.ustring.sub( word, currentPos, currentPos )
	    			if firstChar ~= mw.ustring.lower( firstChar ) then
	    				local firstTrl = mw.ustring.sub( trl, 1, 1 )
	    				trl = mw.ustring.upper( firstTrl ) .. mw.ustring.sub( trl, 2 )
	    			end
	    			
	    			partialResult = partialResult .. trl
	    			currentPos = currentPos + seqLength
	    			break
	    		end
	    		
	    		-- Jeśli nie dopasowano, zwróć błąd tylko przy sekwencji długości 1 (nie ma już ratunku)
	    		if trl == nil and seqLength == 1 then
	    			return "Nieprawidłowy znak " .. unTrl .. " dla języka o kodzie " .. language .. "." .. (
	            		mw.title.getCurrentTitle():inNamespace( 0 ) and errcat or ''
	            	)
	    		end
	    	end
	    end
		
		if mw.ustring.sub( partialResult, -1 ) == endOfTextMarker then
			partialResult = mw.ustring.sub( partialResult, 1, -2 )
		end
		
		table.insert( result, partialResult )
    end
	
	return table.concat( result, ' ' )
end

return p