composeKoreanJamo function

String composeKoreanJamo(
  1. String input
)

Composes modern conjoining Jamo using the pinned g2pkc helper semantics.

A standalone modern vowel first receives the silent onset , matching upstream's non-overlapping regular-expression substitution. Consecutive standalone vowels therefore receive an onset only at alternating positions. Compatibility and archaic Jamo are otherwise preserved.

Implementation

String composeKoreanJamo(String input) {
  final source = input.runes.toList(growable: false);
  final expanded = <int>[];
  var sourceIndex = 0;
  while (sourceIndex < source.length) {
    final scalar = source[sourceIndex];
    if (sourceIndex == 0 && _isModernVowel(scalar)) {
      expanded
        ..add(_silentLead)
        ..add(scalar);
      sourceIndex++;
      continue;
    }
    if (!_isModernLead(scalar) &&
        sourceIndex + 1 < source.length &&
        _isModernVowel(source[sourceIndex + 1])) {
      expanded
        ..add(scalar)
        ..add(_silentLead)
        ..add(source[sourceIndex + 1]);
      sourceIndex += 2;
      continue;
    }
    expanded.add(scalar);
    sourceIndex++;
  }

  final output = StringBuffer();
  var index = 0;
  while (index < expanded.length) {
    final lead = expanded[index];
    if (_isModernLead(lead) &&
        index + 1 < expanded.length &&
        _isModernVowel(expanded[index + 1])) {
      final vowel = expanded[index + 1];
      var tail = 0;
      var consumed = 2;
      if (index + 2 < expanded.length && _isModernTail(expanded[index + 2])) {
        tail = expanded[index + 2] - _tailBase;
        consumed = 3;
      }
      final syllable =
          _hangulBase +
          (lead - _leadBase) * _vowelCount * _tailCount +
          (vowel - _vowelBase) * _tailCount +
          tail;
      output.writeCharCode(syllable);
      index += consumed;
      continue;
    }
    output.writeCharCode(lead);
    index++;
  }
  return output.toString();
}