Módulo:Greek numeral

Fonte: Enciclopédia de conhecimento da Igreja de Deus
Saltar para a navegação Saltar para a pesquisa

A documentação para este módulo pode ser criada na página Módulo:Greek numeral/doc

-- Converte números padrões em numerais gregos e vice-versa
-- Gts-tg@el wiki, agosto de 2017
local p = {}
local greek_numerals = {
	["α"]  = 1,    -- ἄλφα / alpha
	["β"]  = 2,    -- βῆτα / beta 
	["γ"]  = 3,    -- γάμμα / gamma
	["δ"]  = 4,    -- δέλτα / delta
	["ε"]  = 5,    -- ἔψιλον / epsilon
	["Ϛ"]  = 6,    -- δίγαμμα / digamma
	["ζ"]  = 7,    -- ζῆτα / zeta
	["η"]  = 8,    -- ῆτα / heta
	["θ"]  = 9,    -- θῆτα / theta
	["ι"]  = 10,   -- ιῶτα / iota
	["κ"]  = 20,   -- κάππα / kappa
	["λ"]  = 30,   -- λάμδα / lamda
	["μ"]  = 40,   -- μῦ / mu
	["ν"]  = 50,   -- νῦ / nu
	["ξ"]  = 60,   -- ξί / xi
	["ο"]  = 70,   -- ὄμικρον / omikron
	["π"]  = 80,   -- πί / pi
	["ϟ"]  = 90,   -- κόππα / koppa
	["ρ"]  = 100,  -- ρό / rho
	["σ"]  = 200,  -- σίγμα / sigma
	["ς"]  = 200,  -- σίγμα / sigma (variação final)
	["τ"]  = 300,  -- ταῦ / ταυ
	["υ"]  = 400,  -- ύψιλον / ypsilon
	["φ"]  = 500,  -- φί / phi
	["χ"]  = 600,  -- χί / chi
	["ψ"]  = 700,  -- ψί / psi
	["ω"]  = 800,  -- ὠμέγα / omega
	["ϡ"]  = 900,  -- σαμπί / sampi
}
-- usado para predefinição de gráfico matemático
local numeral_latin_transliteration = {
	["α"]  = 'alpha',
	["β"]  = 'beta',
	["γ"]  = 'gamma',
	["δ"]  = 'delta',
	["ε"]  = 'epsilon',
	["Ϛ"]  = 'digamma',
	["ζ"]  = 'zeta',
	["η"]  = 'eta',
	["θ"]  = 'theta',
	["ι"]  = 'iota',
	["κ"]  = 'kappa',
	["λ"]  = 'lambda',
	["μ"]  = 'mu',
	["ν"]  = 'nu',
	["ξ"]  = 'xi',
	["ο"]  = 'omicron',
	["π"]  = 'pi',
	["ϟ"]  = 'koppa',
	["ρ"]  = 'rho',
	["σ"]  = 'sigma',
	["ς"]  = 'sigma', -- (variação final)
	["τ"]  = 'tau',
	["υ"]  = 'upsilon',
	["φ"]  = 'phi',
	["χ"]  = 'chi',
	["ψ"]  = 'psi',
	["ω"]  = 'omega',
	["ϡ"]  = 'sampi',
}
-- retorna o número correspondente à letra
-- parâmetros: letter (string)
-- retorno: número
local function value(letter)
	if letter ~= 'Ϛ' and letter ~= 'ϟ' and letter ~= 'ϡ' then
		letter = mw.ustring.lower(letter) 
				end
	
				return greek_numerals[letter]
end
-- valor de letter * 1000
-- parâmetros: letter (string), total (número)
-- retorno: número
local function thousandth(letter, total)
	
	if letter ~= false then
		total = total - value(letter) -- remove adição anterior como número simples
					total = total + ( value(letter) * 1000 )
				end
				
				return total
end
-- tabela reversa (índice para valores, valores para índice)
-- parâmetros: tbl (table)
-- retorno: tabela
local function reverse_table(tbl)
			
	local reversedTable = {}
	for letter, value in pairs(tbl) do
								reversedTable[value] = letter
				end
				
	return reversedTable
					
end
-- notação especial para números maiores que 9.999
local function mu_notation(greek_number, digits)
		local result  = ''
		local postfix = ''
		
		-- dígitos maiores que 9.999
		for index, digit in pairs(digits) do
			-- mw.log(digit)
					result = result .. '\\' .. numeral_latin_transliteration[digit]
					
					greek_number = greek_number:gsub(digit, "", 1)
		end
		
		if greek_number ~= '' then -- se nem todos os dígitos são múltiplos de miríades
					postfix =  "͵" .. greek_number .. "´"
		end
		
		result = '<math>\\stackrel{' .. result .. '}{\\Mu}</math>' .. postfix
		
		return result 
end
-- converte número padrão para numeral grego
-- parâmetros: frame (obj)
-- retorno: string
function p.to_greek(frame)
	local number = frame.args[1]
	local tbl = null
	local result = ''
	local big_values = {}
	local m_notation = false
	
	if tonumber(number) > 9999  then 
					m_notation = true
				end
	
	tbl = reverse_table(greek_numerals) -- reverso para [<número>] = '<letra>'
	
		if tbl[number] ~= null then 
			result = tbl[number] -- 'hit' direto
		else
			local str_number = tostring(number)
			local highest_numeric_position = #str_number
			local i = 0
			local index = ''
			
			for digit in str_number:gmatch"." do -- "quebra" os dígitos do número
				highest_numeric_position = highest_numeric_position - 1
				
				if tonumber(digit) > 0 then
								index = tonumber(digit .. mw.ustring.rep('0', highest_numeric_position))
								
					if highest_numeric_position >= 3 then
								
								match = false
								while match == false do
								
											if index < 1 then index = index * 10 end
												
											if tbl[index] == nil then
													index = index / 10000
											else
												result = result .. tostring(tbl[tonumber(index)])
												match = true
											end
								end
								
									if highest_numeric_position > 3 then table.insert(big_values, tbl[tonumber(index)]) end
									
						else
									result = result .. tostring(tbl[tonumber(index)])
						end
				end
			end
			--local d = require "Module:Debugging"
			--mw.log(result)
			--mw.log(d.dump(big_values))
		end
	
		if m_notation == true then -- notação especial
			
			result = mu_notation(result, big_values)
			local frame = mw.getCurrentFrame()
			result = frame:preprocess(result)
		else
			if tonumber(number) >= 1000 then result = ',' .. result end
			result = mw.ustring.upper(result) .. "´"
		end
		
		return result
	
end
-- converte número grego para padrão
-- amostra de número grego para teste: αωκα´ = 1821
-- parâmetros: frame (obj)
-- retorno: número
function p.to_standard(frame)
	local greek_number = frame.args[1]
	local total = 0
	local thousand_flag = false
	local prev_letter = false
	
	greek_number = greek_number:gsub("´", "")
	
	if type(greek_number) ~= 'string' then 
		return 'Erro: valor ' .. greek_number .. ' é ' .. type(greek_number) .. ' em vez da sequência (string) esperada'  
	end
	
	-- itera através de letras
	for letter in mw.ustring.gmatch(greek_number, ".") do
			
						-- verifica se o marcador de mil existe
						if letter == "." then 
							thousand_flag = true
												else
													if thousand_flag == true then
																				total = thousandth(letter, total)    
														thousand_flag = false
													end 
													
													total = total + value(letter)
													prev_letter = letter
									end
				end
				
				if thousand_flag == true then
							total = thousandth(prev_letter, total) 
				end
	
	return total
end 
return p