Jump to content

Module:Greek numeral

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Salix alba (talk | contribs) at 05:55, 2 September 2017 (change ypsilon to upsilon as former caused math render error). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

-- Convert standard numbers to greek numerals, and vice versa, along with basic math operations (powers, multiplication, division etc)
-- Gts-tg@el wiki, Aug. 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	(final variation)
	["τ"]  = 300,  -- ταῦ / ταυ
	["υ"]  = 400,  -- ύψιλον / ypsilon
	["φ"]  = 500,  -- φί / phi
	["χ"]  = 600,  -- χί / chi
	["ψ"]  = 700,  -- ψί / psi
	["ω"]  = 800,  -- ὠμέγα / omega
	["ϡ"]  = 900,  -- σαμπί / sampi
}

-- used for math graph template
local numeral_latin_transliteration = {
	["α"]  = 'alpha',
	["β"]  = 'beta',
	["γ"]  = 'gamma',
	["δ"]  = 'delta',
	["ε"]  = 'epsilon',
	["Ϛ"]  = 'digamma',
	["ζ"]  = 'zeta',
	["η"]  = 'heta',
	["θ"]  = 'theta',
	["ι"]  = 'iota',
	["κ"]  = 'kappa',
	["λ"]  = 'lamda',
	["μ"]  = 'mu',
	["ν"]  = 'nu',
	["ξ"]  = 'xi',
	["ο"]  = 'omicron',
	["π"]  = 'pi',
	["ϟ"]  = 'koppa',
	["ρ"]  = 'rho',
	["σ"]  = 'sigma',
	["ς"]  = 'sigma', --(final variation)
	["τ"]  = 'ταυ',
	["υ"]  = 'upsilon',
	["φ"]  = 'phi',
	["χ"]  = 'chi',
	["ψ"]  = 'psi',
	["ω"]  = 'omega',
	["ϡ"]  = 'sampi',
}

-- return number corresponding to letter
-- params: letter (string)
-- return: number
local function value(letter)
	if letter ~= 'Ϛ' and letter ~= 'ϟ' and letter ~= 'ϡ' then
		letter = mw.ustring.lower(letter) 
    end
	
    return greek_numerals[letter]
end

-- letter value * 1000
-- params: letter (string), total (number)
-- return: number
local function thousandth(letter, total)
	
	total = total - value(letter) -- remove previous addition as simple number
    total = total + ( value(letter) * 1000 )
    
    return total
end

-- reverse table (index to values, values to index)
-- params: tbl (table)
-- return: table
local function reverse_table(tbl)
   
	local reversedTable = {}

	for letter, value in pairs(tbl) do
        reversedTable[value] = letter
    end
    
	return reversedTable
	    
end

-- special notation for numbers > 9999
local function mu_notation(greek_number, indexes)
  local result = ''
  
  -- digits great than 9999
  for index, value in pairs(indexes) do
  	 --mw.log(index)
     result = result .. '\\' .. numeral_latin_transliteration[value]
     
     greek_number = greek_number:gsub(value, "")
  end
  
  greek_number = greek_number:gsub('nil', "")
  greek_number = greek_number:gsub('͵', "")
  
  result = '<math>\\stackrel{' .. result .. '}{\\Mu}</math>' .. '͵' .. greek_number
  
  return result	
end

-- convert standard number to greek
-- params: frame (obj)
-- return: string
function p.to_greek(frame)
	local number = frame.args[1]
	local tbl = null
	local result = ''
	local big_values = {}
	
	tbl = reverse_table(greek_numerals)
	
 	if tbl[number] ~= null then 
 		result = tbl[number]
 	else
 		local str_number = tostring(number)
 		local highest_numeric_position = #str_number
 		local i = 0
 		local index = ''
 		
 		-- break up number digits
 		for char in str_number:gmatch"." do
 		   i = i + 1
 		   index = tonumber(char .. mw.ustring.rep('0', highest_numeric_position-i))
 		   if index ~= 0 then
 		   	
 		   	   -- , notation up to 9.999
 		   	   if index > 900 then
 		   	   	  result = result .. '͵'
 		   	   	  index = index / 1000
 		   	   	  
 		   	   	  if index > 9 then
 		   	   	  	big_values[highest_numeric_position-i] = tbl[index]
 		   	   	  end
 		   	   end
 		   	
              result = result .. tostring(tbl[index])
           end   
        end
 		
 	end
 	
 	if tonumber(number) > 9999 then --special notation
 		result = mu_notation(result, big_values)
 		local frame = mw.getCurrentFrame()
 		result = frame:preprocess(result)
 	else
 		result = mw.ustring.upper(result)
 	end
 	
 	return result .. '´'
	
end

-- convert greek number to standard
-- greek number sample for testing: αωκα´ = 1821
-- params: frame (obj)
-- return: number
function p.to_standard(frame)
	local el_number = frame.args[1]
	local total = 0
	local thousand_flag = false
	local prev_letter = false
	
	if type(el_number) ~= 'string' then 
		return 'Error: value ' .. el_number .. ' is a ' .. type(el_number) .. ' and not a string'  
	end
	
	-- iterate through letters
	for letter in mw.ustring.gmatch(el_number, ".") do
	  
		    -- check if thousand marker exists
		    if letter == "´" then 
		    	thousand_flag = true
            else
        	    if thousand_flag == true then
                    total = thousandth(prev_letter, total) 	    	
        	    	thousand_flag = false
        	    else 
        	    	total = total + value(letter)
                end
            
        	    prev_letter = letter
        	end
    end
    
    if thousand_flag == true then
       total = thousandth(prev_letter, total)	
    end
	
	return total
end	

return p