toRomanNumeralString method

String? toRomanNumeralString({
  1. RomanNumeralsConfig? config,
})

Create Roman numeral String from this int. Rules for creation are read from the optional config.

Implementation

String? toRomanNumeralString({RomanNumeralsConfig? config}) {
  config ??= RomanNumerals.romanNumeralsConfig;

  if (!isValidRomanNumeralValue(config: config)) {
    return null;
  }

  // Handle zero with a special case.
  final nulla = config.nulla;
  if (this == 0) {
    if (nulla != null) {
      return nulla.substring(0, 1).toUpperCase();
    }
    return null;
  }

  Map<int, String> useMap;
  switch (config.configType) {
    case RomanNumeralsType.common:
      useMap = {
        ..._sharedRomanNumbersToLetters,
        ..._commonRomanNumbersToLetters
      };
      break;
    case RomanNumeralsType.apostrophus:
      useMap = {};
      final aConfig = config as ApostrophusRomanNumeralsConfig;
      if (aConfig.compact) {
        useMap = _compactApostrophusRomanNumbersToLetters;
      } else {
        useMap = _apostrophusRomanNumbersToLetters;
      }
      break;
    case RomanNumeralsType.vinculum:
      useMap = {
        ..._sharedRomanNumbersToLetters,
        ..._vinculumRomanNumbersToLetters
      };
      break;
  }
  List<int> nRevMap = useMap.keys.toList();
  nRevMap.sort((a, b) => b.compareTo(a));

  var curString = '';
  var accum = this;
  var nIndex = 0;
  while (accum > 0) {
    var divisor = nRevMap[nIndex];
    var units = accum ~/ divisor;

    /**
     - When we have any amount of quotient > 0, add the current numeral to the return-string,
        subtract the amount from the accumulator, and continue.
     - When the quotient is zero, then increment the index of the number-value array to the next number.
     */
    if (units > 0) {
      var got = useMap[divisor];
      if (got != null) {
        curString += got;
        accum -= divisor;
      }
    } else {
      nIndex += 1;
    }
  }
  return curString;
}