Uwaga
Serwis Wedariusz jest portalem tematycznym prowadzonym przez Grupę Wedamedia. Aby zostać wedapedystą, czyli Użytkownikiem z prawem do tworzenia i edycji artykułów, wystarczy zarejestrować się na witrynie poprzez złożenie wniosku o utworzenie konta, co można zrobić tutaj. Liczymy na Waszą pomoc oraz wsparcie merytoryczne przy rozwoju także naszych innych serwisów tematycznych.

Moduł:ortografieBE

Z Wedariusz, słownik
Przejdź do nawigacji Przejdź do wyszukiwania

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:ortografieBE/opis

local p = {}

local insert = table.insert
local lower  = mw.ustring.lower

local title = mw.title.getCurrentTitle()
local ns    = title:inNamespace( 0 )

local errCategory = ns
	and '[[Kategoria:Błąd w zapisie w ortografiach alternatywnych|białoruski]]'
	or  ''

local errStrings = {
	unrecognizedChar = 'Nierozpoznany znak „$1”',
	conversionError  = 'Błąd w konwersji znaku „$1”'
}

-- [[w:pl:Łacinka białoruska]]
local equiv = {
	vowels = {
		-- { na początku wyrazu/po samogłosce, po spółgłosce/po apostrofie, "ь", "д", "ж", "р", "т", "ч", "ш", po "л" }
		['а'] = { 'a',  'a',  nil,  'a' }, ['А'] = { 'A',  'A',  nil,  'A' },
		['э'] = { 'e',  'e',  nil,  'e' }, ['Э'] = { 'E',  'E',  nil,  'E' },
		['і'] = { 'i',  'i',  'ji', 'i' }, ['І'] = { 'I',  'I',  'Ji', 'I' },
		['о'] = { 'o',  'o',  nil,  'o' }, ['О'] = { 'O',  'O',  nil,  'O' },
		['у'] = { 'u',  'u',  nil,  'u' }, ['У'] = { 'U',  'U',  nil,  'U' },
		['ы'] = { nil,  'y',  nil,  'y' }, ['Ы'] = { nil,  'Y',  nil,  'Y' },
		['я'] = { 'ja', 'ia', 'ja', 'a' }, ['Я'] = { 'Ja', 'Ia', 'Ja', 'A' },
		['е'] = { 'je', 'ie', 'je', 'e' }, ['Е'] = { 'Je', 'Ie', 'Je', 'E' },
		['ё'] = { 'jo', 'io', 'jo', 'o' }, ['Ё'] = { 'Jo', 'Io', 'Jo', 'O' },
		['ю'] = { 'ju', 'iu', 'ju', 'u' }, ['Ю'] = { 'Ju', 'Iu', 'Ju', 'U' }
	},
	consonants = {
		-- { normalnie, przed "ь"/przed "я", "е", "ё", "ю", "і" (tylko dla "л") }
		['б'] = { 'b' },        ['Б'] = { 'B' },
		['в'] = { 'v' },        ['В'] = { 'V' },
		['г'] = { 'h' },        ['Г'] = { 'H' }, -- g/G jeżeli "obcy=tak"
		['д'] = { 'd' },        ['Д'] = { 'D' },
		['ж'] = { 'ž' },        ['Ж'] = { 'Ž' },
		['з'] = { 'z',  'ź' },  ['З'] = { 'Z',  'Ź' },
		['й'] = { 'j' },        ['Й'] = { 'J' },
		['к'] = { 'k' },        ['К'] = { 'K' },
		['л'] = { 'ł',  'l' },  ['Л'] = { 'Ł',  'L' },
		['м'] = { 'm' },        ['М'] = { 'M' },
		['н'] = { 'n',  'ń' },  ['Н'] = { 'N',  'Ń' },
		['п'] = { 'p' },        ['П'] = { 'P' },
		['р'] = { 'r' },        ['Р'] = { 'R' },
		['с'] = { 's',  'ś' },  ['С'] = { 'S',  'Ś' },
		['т'] = { 't' },        ['Т'] = { 'T' },
		['ў'] = { 'ŭ' },        ['Ў'] = { 'Ŭ' },
		['ф'] = { 'f' },        ['Ф'] = { 'F' },
		['х'] = { 'ch' },       ['Х'] = { 'Ch' },
		['ц'] = { 'c',  'ć' },  ['Ц'] = { 'C',  'Ć' },
		['ч'] = { 'č' },        ['Ч'] = { 'Č' },
		['ш'] = { 'š' },        ['Ш'] = { 'Š' },
		['ь'] = { '' },
		["'"] = { '' },         ['’'] = { '' }
	},
	common = {
		[' '] = true, ['.'] = true, [','] = true,
		['-'] = true, ['–'] = true, ['—'] = true
	}
}

local Romanizator = {
	output = {},
	chars  = {},
	currentPos = nil
}

function Romanizator:addChar( char )
	local lc = lower( char )
	
	if equiv.vowels[ char ] then
		insert( self.chars, {
			value   = char,
			type    = 'vowel',
			special = ( lc == 'я' or lc == 'е' or lc == 'ё' or lc == 'ю' or lc == 'і' ),
			conversion = equiv.vowels[ char ]
		} )
	elseif equiv.consonants[ char ] then
		insert( self.chars, {
			value = char,
			type  = 'consonant',
			special = ( lc == 'д' or lc == 'ж' or lc == 'р' or lc == 'т' or
				lc == 'ч' or lc == 'ш' or char == 'ь' or char == '\'' ),
			conversion = equiv.consonants[ char ]
		} )
	elseif equiv.common[ char ] then
		insert( self.chars, {
			value = char,
			type  = 'common'
		} )
	else
		return false
	end
	
	return true
end

function Romanizator:saveLatinChar( char, conversion )
	if lower( char.value ) == 'г' and self.isForeign then
		insert( self.output, lower( char.value ) == char.value and 'g' or 'G' )
	elseif not conversion then
		self.error = self.error or char.value
	else
		insert( self.output, conversion )
	end
end

function Romanizator:checkVowel( char )
	local prevChar = self.chars[ self.currentPos - 1 ]
	
	if
		self.currentPos == 1 or
		prevChar.type == 'vowel' or
		prevChar.type == 'common'
	then
		self:saveLatinChar( char, char.conversion[ 1 ] )
	elseif
		lower( prevChar.value ) == 'л'
	then
		self:saveLatinChar( char, char.conversion[ 4 ] )
	elseif
		char.special and
		prevChar.type == 'consonant' and
		prevChar.special and not
		( lower( char.value ) == 'і' and prevChar.value ~= 'ь' and prevChar.value ~= '\'' )
	then
		self:saveLatinChar( char, char.conversion[ 3 ] )
	else
		self:saveLatinChar( char, char.conversion[ 2 ] )
	end
end

function Romanizator:checkConsonant( char )
	local nextChar = self.chars[ self.currentPos + 1 ]
	
	if
		nextChar and char.conversion[ 2 ] and (
			nextChar.value == 'ь' or
			( lower( char.value ) == 'л' and nextChar.type == 'vowel' and nextChar.special )
		)
	then
		self:saveLatinChar( char, char.conversion[ 2 ] )
	else
		self:saveLatinChar( char, char.conversion[ 1 ] )
	end
end

function Romanizator:romanize()
	for i, char in ipairs( self.chars ) do
		self.currentPos = i
		
		if char.type == 'vowel' then
			self:checkVowel( char )
		elseif char.type == 'consonant' then
			self:checkConsonant( char )
		elseif char.type == 'common' then
			insert( self.output, char.value )
		end
	end
	
	if self.error then
		return string.gsub( errStrings.conversionError, '$1', self.error )
	else
		return table.concat( self.output, '' )
	end
end

function Romanizator:create( isForeign )
	local o = {}
	
	setmetatable( o, self )
	self.__index = self
	self.isForeign = isForeign
	
	return o
end

p.main = function( frame )
	local args  = frame.args
	local pargs = frame:getParent().args
	
	if pargs[ 1 ] then
		return string.gsub( args.label, '$1', pargs[ 1 ] )
	end
	
	local lacinka = Romanizator:create( pargs.obcy == 'tak' )
	local page    = pargs.text or title.text
	
	for codepoint in mw.ustring.gcodepoint( page ) do
		if not lacinka:addChar( mw.ustring.char( codepoint ) ) then
			return ( string.gsub(
				errStrings.unrecognizedChar, '$1', mw.ustring.char( codepoint )
			) ) .. errCategory
		end
	end
	
	local output = lacinka:romanize()
	
	if lacinka.error then
		return output .. errCategory
	else
		return ( string.gsub( args.label, '$1', output ) )
	end
end

return p