Extension:RomanNumbers

MediaWiki extensions manual
RomanNumbers
Release status: unmaintained
Implementation Parser extension , Parser function
Description Convert a roman number to an arabic one or vice versa.
Author(s) Massimiliano Salvemini
Latest version 3.0 (2021-11-17)
MediaWiki 1.31+
License GNU General Public License 2.0 or later
Download see code below

The RomanNumbers extension adds a parser function that converts one arabic number to a roman number or vice versa. If the argument is a string, it try to parse the string and convert it in an arabic number, while, if the argument is an arabic number, the parser converts it in a roman number.

The allowed range is from 1 to 9999 on the conversion arabic to roman, while when converting a roman number to an arabic one the conversion range is limited only by PHP variable's size. <roman>MCLVI</roman>

Examples edit

{{#tag:123}} returns CXXIII
{{#tag:MDXCII}} returns 1,592
{{#tag:MyDzXCII}} returns always 1,592 (unrecognized chars are skipped)
{{#tag:123MII}} returns always 1,002 (unrecognized chars are skipped)

Installation edit

Code edit

RomanNumbers.php
<?php

if (!defined('MEDIAWIKI'))
    die(' This file is a MediaWiki extension, it is not a valid entry point '
);

$wgExtensionCredits['parserhook'][] = array(
    'name' => 'RomanNumbers',
    'author' => array(
		'Massimiliano Salvemini',
		'Hakob Barseghyan'
		),
    'version' => '3.0',
    'license-name' => 'GPL-2.0-or-later',
    'url' => 'https://www.mediawiki.org/wiki/Extension:RomanNumbers', 
    'description' => 'Converts an Arabic number to a Roman number and vice versa'
);

$magicWords = [];
$magicWords['en'] = [ 'roman' => [ 0, 'roman' ] ];

class RomanNumbers {
  //Conversion: Roman Numeral to Integer
  public static function toArabic($roman) {
    static $conv = array(
        array("letter" => 'I', "number" => 1),
        array("letter" => 'V', "number" => 5),
        array("letter" => 'X', "number" => 10),
        array("letter" => 'L', "number" => 50),
        array("letter" => 'C', "number" => 100),
        array("letter" => 'D', "number" => 500),
        array("letter" => 'M', "number" => 1000),
        array("letter" => 0,   "number" => 0)
); 

$arabic = 0;
$state  = 0;
$sidx   = 0;
$len    = strlen($roman);

while ($len > 0) {
    $i = 0;
    $sidx = $len -1;

    while ($conv[$i]["number"] > 0) 
        {
            if (strtoupper($roman[$sidx]) == $conv[$i]["letter"]) 
        {
            if ($state > $conv[$i]["number"]) 
        {
        $arabic -= $conv[$i]["number"];
        }
    else 
        {
            $arabic += $conv[$i]["number"];
            $state   = $conv[$i]["number"];
        }
        }
    $i++;
        }
    $len--;
    }

return($arabic);
}

public static function toRoman($num) {
        if ($num < 0 || $num > 9999) return -1;
            $romanOnes = array(1=> "I",2=>"II",3=>"III",4=>"IV", 5=>"V", 6=>"VI", 7=>"VII", 8=>"VIII", 9=>"IX"   );
            $romanTens = array(1=> "X", 2=>"XX", 3=>"XXX", 4=>"XL", 5=>"L", 6=>"LX", 7=>"LXX",8=>"LXXX", 9=>"XC");
            $romanHund = array(1=> "C", 2=>"CC", 3=>"CCC", 4=>"CD", 5=>"D", 6=>"DC", 7=>"DCC",8=>"DCCC", 9=>"CM");
            $romanThou = array(1=> "M", 2=>"MM", 3=>"MMM", 4=>"MMMM", 5=>"MMMMM", 6=>"MMMMMM",7=>"MMMMMMM", 8=>"MMMMMMMM", 9=>"MMMMMMMMM");
            $ones = $num % 10;
            $tens = ($num - $ones) % 100;
            $hund = ($num - $tens - $ones) % 1000;
            $thou = ($num - $hund - $tens - $ones) % 10000;
            $tens = $tens / 10;
            $hund = $hund / 100;
            $thou = $thou / 1000;
            $romanNum = '';
        if ($thou) $romanNum .= $romanThou[$thou];
        if ($hund) $romanNum .= $romanHund[$hund];
        if ($tens) $romanNum .= $romanTens[$tens];
        if ($ones) $romanNum .= $romanOnes[$ones];
    return $romanNum;
    }
}

$wgHooks['ParserFirstCallInit'] = 'onParserFirstCallInit';

function onParserFirstCallInit($parser) {
    
    $parser->setFunctionHook( 'tag', 'wfRomanParse_Render' );
}


function wfRomanParse_Render(&$parser, $param1 = '') {
    return convertRomanNumber($param1);

}

$wgAjaxExportList[] = "convertRomanNumber";

function convertRomanNumber($num) {
    if (is_numeric($num)) {
        if (($num > 9999)||($num<1)) return "error";
        return RomanNumbers::toRoman($num);
    } 
    else
    return RomanNumbers::toArabic($num);
}