Skip to content

Instantly share code, notes, and snippets.

@a-raccoon
Last active February 28, 2021 00:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save a-raccoon/7401093 to your computer and use it in GitHub Desktop.
Save a-raccoon/7401093 to your computer and use it in GitHub Desktop.
Roman Numeral Functions for AutoHotkey by Raccoon © MCMXCIX, MMIX
; Begin "roman.ahk" library include.
; Roman Numeral Functions for AutoHotkey by Raccoon © MCMXCIX, MMIX
;
; Converted from an original script written for mIRC 5.6 in 1999.
; Last Updated and Tested with AutoHotkey 1.0.47.06 on 14-July-2009
;
; This library is free to use and modify provided my name is left in comments.
;
; For best results, save this file in your \AutoHotkey\Lib directory.
; This allows you to use the following functions in any of your AHK scripts.
;
; Functions:
; roman(value) - returns a roman numeral or a decimal value.
; decimal2roman(value) - returns a roman numeral.
; roman2decimal(value) - returns a decimal value.
;
; Running roman.ahk as a script directly will call the function:
; _roman_numeral_converter() - a convenient converter dialog.
;
; Note: The Roman-To-Decimal conversion does not reject roman numerals that
; fail to adhere to strict rules of convention. While it WILL correctly
; convert all 'proper' roman numerals, it will also convert 'vulgar' ones.
; For example, 1999 is properly expressed as MCMXCIX, but the function will
; also recognize MIM as 1999. I prefer this over an error message.
; If you must tell that a roman numeral is 'proper', then do the following:
; if (x = roman(roman(x))) - this will invalidate a 'vulgar' numeral.
; The Decimal-To-Roman conversion will only output 'proper' numerals.
;
; PS ... Roman Numerals are only good up to 3999 or 4999 depending on who you ask.
If (A_ScriptName = "roman.ahk") ; Launch a convenient converter dialog if
_Roman_Numeral_Converter() ; this script is run directly, not included.
Roman(val) ; by Raccoon © MMIX-July
; Function automatically determines if value is arabic or roman.
{
if val is Integer ; Is Number?
return Decimal2Roman(val)
return Roman2Decimal(val)
}
Decimal2Roman(val) ; by Raccoon © MMIX-July
; Converts arabic decimal values into roman numerals.
{
Static roman := "M CM D CD C XC L XL X IX V IV I"
Static arabic := "1000 900 500 400 100 90 50 40 10 9 5 4 1"
StringSplit, r, roman, %A_Space%
StringSplit, a, arabic, %A_Space%
if (val > 5000) ; if roman() is passed a very large number, it could return a very large string of "M"s.
return ">MMMMM" ; so we disallow any values larger than 5000. (Until we add some higher numerals?)
s=
Loop % r0 ; loop through each numeral in array. (r0=13)
{
x := val // a%A_Index% ; how many thousands (M's) are needed?
s .= Str(r%A_Index%,x) ; 3? ok, lets create MMM and add it to our string.
val -= x * a%A_Index% ; now we subtract 3000 from 3888 to get 888 left.
}
return s
}
Roman2Decimal(str) ; by Raccoon © MMIX-July
; Converts roman numerals into arabic decimal values.
{
Static roman := "MDCLXVI"
Static arabic := "1000 500 100 50 10 5 1"
StringSplit, a, arabic, %A_Space%
val := 0
Loop, Parse, str ; loop through each character in the string.
{
n := InStr(roman,A_LoopField) ; position of numeral in array.
if (n = 0) ; no match. (ignore invalid characters as if not there ;)
continue ; ... back to top of loop.
y := x ; we are working with the previous numeral's value.
x := a%n% ; x is the current numeral's value, y is the previous numeral's value.
if (x <= y) ; eg, I comes after V (such as VI or 6)
val += y ; so it's safe to add 5 right now.
else ; eg, V comes after I (such as IV or 4) | this occures on the first iteration,
val -= y ; so you have to subtract the 1. | but y is 0 so nothing is subtracted.
}
val += x ; the last numeral always gets added to the total value.
return val
}
Str(str,n) ; by Raccoon © MMIX-July
; This function really belongs in AutoHotkey. DAMMIT!
{
Loop % n
s .= str
return s
}
_Roman_Numeral_Converter() ; by Raccoon © MMIX-July
; This function provides a convenient converter dialog for this script.
{
val := A_Year
Loop
{
InputBox, val, Roman Numeral Converter by Raccoon © MMIX
, Enter a Decimal Value or a Roman Numeral.`nExample: %val%
, , , 140, , , , , % val:=roman(val)
if (ErrorLevel > 0)
break
}
}
; End of "roman.ahk" library include.
@axmachina
Copy link

Really nice peace of code, thanks! ;D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment