segmentizeFurigana static method

List<RubyTextData>? segmentizeFurigana(
  1. {required String reading,
  2. required String readingNormalized,
  3. required List<FuriganaDistributionGroup> groups,
  4. required int groupsStart}
)

Given the groups generated from distributeFurigana, segment the furigana.

Implementation

static List<RubyTextData>? segmentizeFurigana({
  required String reading,
  required String readingNormalized,
  required List<FuriganaDistributionGroup> groups,
  required int groupsStart,
}) {
  int groupCount = groups.length - groupsStart;

  if (groupCount <= 0) {
    return reading.isEmpty ? [] : null;
  }

  FuriganaDistributionGroup group = groups[groupsStart];
  bool isKana = group.isKana;
  String text = group.text;

  if (isKana) {
    String? textNormalized = group.textNormalized;
    if (readingNormalized.startsWith(textNormalized!)) {
      List<RubyTextData>? segments = segmentizeFurigana(
        reading: reading.substring(text.length),
        readingNormalized: readingNormalized.substring(text.length),
        groups: groups,
        groupsStart: groupsStart + 1,
      );

      if (segments != null) {
        if (reading.startsWith(text)) {
          segments.insert(0, RubyTextData(text));
        } else {
          segments.insertAll(
              0, getFuriganaKanaSegments(text: text, reading: reading));
        }

        return segments;
      }
    }

    return null;
  } else {
    List<RubyTextData>? result;

    for (int i = reading.length; i >= text.length; --i) {
      List<RubyTextData>? segments = segmentizeFurigana(
        reading: reading.substring(i),
        readingNormalized: readingNormalized.substring(i),
        groups: groups,
        groupsStart: groupsStart + 1,
      );

      if (segments != null) {
        if (result != null) {
          return null;
        }

        String segmentReading = reading.substring(0, i);
        segments.insert(0, RubyTextData(text, ruby: segmentReading));
        result = segments;
      }

      if (groupCount == 1) {
        break;
      }
    }

    return result;
  }
}