Jump to content

Module:Roman

विकिपीडिया से
en>Andy M. Wang (handle 0 as 'N' per Roman numerals#Zero) के द्वारा 01:41, 23 अप्रैल 2016 के बदलाव

-- This module implements {{Roman}}.

local p = {}

-- This function implements the {{overline}} template.
local function overline( s )
    return mw.ustring.format( '<span style="text-decoration:overline;">%s</span>', 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 < 0 or num == math.huge then
        return
    elseif num == 0 then
    	return 'N'
    end

    -- Not handling non-integers right now
    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' },
            {   9000, 'IX' }, {   5000, 'V' }, {   4000, 'IV' },
        }
        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