Modul:Roman

Från Järnvägsdata
Version från den 14 mars 2018 kl. 23.04 av Jan Karlsson (diskussion | bidrag) (1 version importerades)
(skillnad) ← Äldre version | Nuvarande version (skillnad) | Nyare version → (skillnad)

-- This module implements Mall:Roman.

local p = {}

-- This function implements the Mall:Overline template. local function overline( s )

   return mw.ustring.format( '%s', s )

end

-- Gets the Roman numerals for a given numeral table. Returns both the string of -- numerals and the value of the number after it is finished being processed. local function getLetters( num, t )

   local ret = {}
   for _, v in ipairs( t ) do
       local val, letter = unpack( v )
       while num >= val do
           num = num - val
           table.insert( ret, letter )
       end
   end
   return table.concat( ret ), num

end

-- The main control flow of the module. local function _main( args )

   -- Get input and exit displaying nothing if the input is bad.
   local num = tonumber( args[ 1 ] )
   if not num or num < 1 or num == math.huge then
       return
   end
   num = math.floor( num )

   -- Return a message for numbers too big to be expressed in Roman numerals.
   if num >= 5000000 then
       return args[ 2 ] or 'N/A'
   end

   local ret = 
   -- Find the Roman numerals for the large part of numbers 5000 and bigger.
   -- The if statement is not strictly necessary, but makes the algorithm 
   -- more efficient for smaller numbers.
   if num >= 5000 then
       local bigRomans = {
           { 1000000, 'M' },
           { 900000, 'CM' }, { 500000, 'D' }, { 400000, 'CD' }, { 100000, 'C' },
           { 90000, 'XC' }, { 50000, 'L' }, { 40000, 'XL' }, { 10000, 'X' },
           { 5000, 'V' }
       }
       local bigLetters
       bigLetters, num = getLetters( num, bigRomans )
       ret = overline( bigLetters )
   end

   -- Find the Roman numerals for numbers 4999 or less.
   local smallRomans = {
       {1000, "M"},
       {900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"},
       {90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"},
       {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"} 
   }
   local smallLetters = getLetters( num, smallRomans )
   ret = ret .. smallLetters

   return ret

end

function p.main( frame )

   -- If called via #invoke, use the args passed into the invoking
   -- template, or the args passed to #invoke if any exist. Otherwise
   -- assume args are being passed directly in from the debug console
   -- or from another Lua module.
   local origArgs
   if frame == mw.getCurrentFrame() then
       origArgs = frame:getParent().args
       for k, v in pairs( frame.args ) do
           origArgs = frame.args
           break
       end
   else
       origArgs = frame
   end
   -- Trim whitespace and remove blank arguments.
   local args = {}
   for k, v in pairs( origArgs ) do
       if type( v ) == 'string' then
           v = mw.text.trim( v )
       end
       if v ~=  then
           args[k] = v
       end
   end
   return _main( args )

end

return p