Modul:Roman
Qiyofa
-- 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
-- This function contains the core logic for converting numbers to Roman numerals.
-- It is designed to be called by both p.main (for #invoke) and p.toRoman (for module-to-module calls).
local function _getRomanNumerals(num_input)
-- Get input and exit displaying nothing if the input is empty.
if num_input == nil then return end
local num = tonumber(num_input)
if not num or num < 0 or num == math.huge then
error('Invalid number ' .. tostring(num_input), 2) -- tostring qo'shildi
elseif num == 0 then
return 'N'
end
-- Return a message for numbers too big to be expressed in Roman numerals.
if num >= 5000000 then
-- Agar _main dan chaqirilmasa, args[2] mavjud bo'lmaydi.
-- Shuning uchun aniq N/A qaytaramiz.
return 'N/A'
end
local ret = ''
-- Find the Roman numerals for the large part of numbers.
-- 23 April 2016 - tweaked to >= 4000 to accept big Roman 'IV'
-- The if statement is not strictly necessary, but makes the algorithm
-- more efficient for smaller numbers.
if num >= 4000 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 less than the big Roman threshold.
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
-- The fractional part logic is typically not needed for century/year conversion
-- but if you want to enable it for p.main, you would pass a 'fraction' arg.
-- For direct module calls (p.toRoman), we assume no fractions.
-- if args.fraction == 'yes' then ... end
return ret
end
-- The main entry point for #invoke.
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
-- Check if frame.args are explicitly provided to #invoke (e.g., {{#invoke:Roman|main|123}})
-- If not, fall back to parent frame's args (e.g., {{Roman|123}})
if next(frame.args) then -- next(table) returns nil if table is empty
origArgs = frame.args
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
-- exit if not given anything
if args == nil or next(args) == nil then return '' end -- next(args) == nil tekshiruvi yaxshiroq
-- Given mathematical expression, simplify to a number
-- mw.ext.ParserFunctions.expr is not always available in all Lua environments.
-- This part might need adjustment depending on your Wiki's setup.
if type(args[1]) == 'string' and mw.ext and mw.ext.ParserFunctions and mw.ext.ParserFunctions.expr then
local success, result = pcall(mw.ext.ParserFunctions.expr, args[1])
if success then
args[1] = result
else
-- Agar expr xato bersa, asl stringni saqlab qolamiz va _getRomanNumerals ichida tonumber xato beradi
-- yoki siz bu yerda boshqacha ishlov berishingiz mumkin.
-- Hozircha shunchaki asl qiymatni qoldiramiz.
end
end
-- p.main _getRomanNumerals funksiyasiga args[1] ni beradi
return _getRomanNumerals(args[1])
end
-- The new entry point for direct module-to-module calls (e.g., from Module:Wikidata/date).
-- This function converts a given number directly to Roman numerals.
function p.toRoman(number_input)
-- We simply call our core logic function with the provided number.
return _getRomanNumerals(number_input)
end
return p