Moduł:transkrypcja-mk/Wikisłownik

Z Wikisłownika – wolnego słownika wielojęzycznego

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

local p = {}

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

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

local transliterationMk = {
	["а"] = "a",
    ["б"] = "b",
    ["в"] = "w",
    ["г"] = "g",
    ["д"] = "d",
    -- Ѓ
    ["ѓ"] = "dź",
    ["ѓа"] = "dzia",
    ["ѓе"] = "gie",
    ["ѓи"] = "gi",
    ["ѓо"] = "dzio",
    ["ѓу"] = "dziu",
    -- koniec
    ["е"] = "e",
    ["ж"] = "ż",
    ["з"] = "z",
    ["ѕ"] = "dz",
    ["и"] = "i",
    ["ј"] = "j",
    ["к"] = "k",
    ["л"] = "ł",
    ["ли"] = "li",
    ["љ"] = "l",
    ["м"] = "m",
    ["н"] = "n",
    -- њ
    ["њ"] = "ń",
    ["ња"] = "nia",
    ["ње"] = "nie",
    ["њи"] = "nii",
    ["њо"] = "nio",
    ["њу"] = "niu",
    --
    ["о"] = "o",
    ["п"] = "p",
    ["р"] = "r",
    ["с"] = "s",
    ["т"] = "t",
    -- Ќ
    ["ќ"] = "ć",
    ["ќа"] = "cia",
    ["ќе"] = "kie",
    ["ќи"] = "ki",
    ["ќо"] = "cio",
    ["ќу"] = "ciu",
    -- koniec
    ["у"] = "u",
    ["ф"] = "f",
    ["х"] = "h",
    ["ц"] = "c",
    ["ч"] = "cz",
    ["џ"] = "dż",
    ["ш"] = "sz",
}

local transliterations = {
    ["mk"] = transliterationMk
}

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