46 lines
1.2 KiB
Python
46 lines
1.2 KiB
Python
"""Compatibility shim for Sphinx's LaTeX writer.
|
|
|
|
Some environments provide a broken or incomplete ``roman-numerals`` package
|
|
that does not expose the ``roman_numerals`` module expected by Sphinx. The
|
|
LaTeX writer only needs a small subset of the functionality: a ``RomanNumeral``
|
|
class with ``to_lowercase()``.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
class RomanNumeral:
|
|
def __init__(self, value: int) -> None:
|
|
if not isinstance(value, int):
|
|
raise TypeError('RomanNumeral expects an integer')
|
|
if value < 1:
|
|
raise ValueError('RomanNumeral expects a positive integer')
|
|
self.value = value
|
|
|
|
def to_lowercase(self) -> str:
|
|
return _to_roman(self.value).lower()
|
|
|
|
|
|
def _to_roman(value: int) -> str:
|
|
numerals = [
|
|
(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'),
|
|
]
|
|
result = []
|
|
remaining = value
|
|
for arabic, roman in numerals:
|
|
while remaining >= arabic:
|
|
result.append(roman)
|
|
remaining -= arabic
|
|
return ''.join(result)
|