spell function

String? spell(
  1. String word, {
  2. String? language,
  3. Map<String, dynamic>? chars,
  4. bool vertical = true,
  5. List<String>? variants,
  6. int? seed,
  7. Random? rng,
})

Spells a single word as a SignWriting sign by joining its characters' signs (vertically by default), or returns null if any character is unmappable.

Provide either language or a pre-loaded chars map. When a character has multiple variants, one is chosen using rng (or a seed). NOTE: Dart's RNG does not match Python's, so seeded multi-variant output differs from the Python package; single-variant spellings are identical.

Implementation

String? spell(
  String word, {
  String? language,
  Map<String, dynamic>? chars,
  bool vertical = true,
  List<String>? variants,
  int? seed,
  Random? rng,
}) {
  if (chars == null) {
    if (language == null) {
      throw ArgumentError('Either language or chars must be provided');
    }
    chars = getChars(language);
  }
  rng ??= seed != null ? Random(seed) : Random();

  final sl = <String>[];
  int caret = 0;
  while (caret < word.length) {
    bool found = false;
    for (final entry in chars.entries) {
      final c = entry.key;
      final end = caret + c.length;
      if (end <= word.length && word.substring(caret, end).toLowerCase() == c) {
        final signs = variantSigns(entry.value, variants: variants);
        // Only draw from the rng when there is an actual choice to make.
        sl.add(signs.length == 1 ? signs[0] : signs[rng.nextInt(signs.length)]);
        caret = end;
        found = true;
        break;
      }
    }
    if (!found) return null;
  }

  return vertical
      ? joinSignsVertical(sl, spacing: 5)
      : joinSignsHorizontal(sl, spacing: 5);
}