« Module:Romain » : différence entre les versions

Une page de Wikiquote, le recueil des citations libres.
Contenu supprimé Contenu ajouté
Ajout fonction fromRoman, et les fonctions permettant d'utiliser le module depuis un modèle
Aucun résumé des modifications
Ligne 21 : Ligne 21 :




function p.toRoman(num, default)
function p.toRoman( num, default )
num = tonumber(num)
num = tonumber( num )
if not num or num < 1 or num == math.huge then
if not num or num < 1 or num == math.huge then
return
return
Ligne 87 : Ligne 87 :
end
end


-- compatibilité avec [[en:Module:Roman]]
-- compatibility with [[en:Module:Roman]]
function p._main(args)
function p._main(args)
return p.toRoman( args[1] )
return p.toRoman( args[1] )
Ligne 96 : Ligne 96 :
end
end


-- functions to call the module from a template (takes the #invoke first arg or the template first arg)
function p.nombreEnRomain( frame )
function p.nombreEnRomain( frame )
local num
local num

Version du 8 août 2016 à 19:56

La documentation pour ce module peut être créée à Module:Romain/Documentation

local p = {}

-- barre horizontale au-dessus des nombres élevés
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


function p.toRoman( num, default )
    num = tonumber( num )
    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 default 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.fromRoman( str, default )
	str = str:upper()
	if not str:find( '^[MDCLXVI]+$' ) then
		if default then
			return default
		else
			error( 'fromRoman expect a string containing only M, D, C, L, X, V or I letters' )
		end
	end
	local smallRomans = { I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000 }
	local result = 0
	local old, n = 0
	for i = str:len(), 1, -1  do
		n = smallRomans[ str:sub( i, i ) ]
		if n < old then
			result = result - n
		else
			result = result + n
			old = n
		end
	end
	return result
end

-- compatibility with [[en:Module:Roman]]
function p._main(args)
	return p.toRoman( args[1] )
end

function p.main( frame )
	return p.nombreEnRomain( frame )
end

-- functions to call the module from a template (takes the #invoke first arg or the template first arg)
function p.nombreEnRomain( frame )
	local num
	if frame == mw.getCurrentFrame() then
		num = frame.args[1] or frame:getParent().args[1]
	else
		num = frame
	end
	return p.toRoman( mw.text.trim( num ) )
end

function p.nombreDepuisRomain( frame )
	local num
	if frame == mw.getCurrentFrame() then
		num = frame.args[1] or frame:getParent().args[1]
	else
		num = frame
	end
	return p.fromRoman( mw.text.trim( num ) )
end
	
return p