interpolateString function Value interpolation

String Function(num) interpolateString(
  1. String a,
  2. String b
)

Returns an interpolator between the two strings a and b.

The string interpolator finds numbers embedded in a and b, where each number is of the form understood by Dart. A few examples of numbers that will be detected within a string: -1, 42, 3.14159, and 6.0221413e+23.

For each number embedded in b, the interpolator will attempt to find a corresponding number in a. If a corresponding number is found, a numeric interpolator is created using interpolateNumber. The remaining parts of the string b are used as a template: the static parts of the string b remain constant for the interpolation, with the interpolated numeric values embedded in the template.

For example, if a is "300 12px sans-serif", and b is "500 36px Comic-Sans", two embedded numbers are found. The remaining static parts (of string b) are a space between the two numbers (" "), and the suffix ("px Comic-Sans"). The result of the interpolator at t = 0.5 is "400 24px Comic-Sans".

Implementation

String Function(num) interpolateString(String a, String b) {
  var bi = 0,
      am = _re.allMatches(a).iterator,
      bm = _re.allMatches(b).iterator,
      i = -1,
      s = <String?>[],
      q = <(int, num Function(num))>[];
  late String bs;

  while (am.moveNext() && bm.moveNext()) {
    var ami = am.current, bmi = bm.current;
    if (bmi.start > bi) {
      bs = b.substring(bi, bmi.start);
      if (_elementAtOrNull(s, i) != null) {
        s[i] = s[i]! + bs; // coalesce with previous string
      } else {
        i++;
        s.add(bs);
      }
    }
    String ams, bms;
    if ((ams = ami[0]!) == (bms = bmi[0]!)) {
      if (_elementAtOrNull(s, i) != null) {
        s[i] = s[i]! + bms; // coalesce with previous string
      } else {
        i++;
        s.add(bms);
      }
    } else {
      // interpolate non-matching numbers
      i++;
      s.add(null);
      q.add((i, interpolateNumber(num.parse(ams), num.parse(bms))));
    }
    bi = bmi.end;
  }

  // Add remains of b.
  if (bi < b.length) {
    bs = b.substring(bi);
    if (_elementAtOrNull(s, i) != null) {
      s[i] = s[i]! + bs; // coalesce with previous string
    } else {
      i++;
      s.add(bs);
    }
  }

  // Special optimization for only a single match.
  // Otherwise, interpolate each of the numbers and rejoin the string.
  return s.length < 2
      ? (q.isNotEmpty ? _one(q[0].$2) : _zero(b))
      : (t) {
          (int, num Function(num)) o;
          for (int i = 0; i < q.length; ++i) {
            s[(o = q[i]).$1] = o.$2(t).toString();
          }
          return s.join("");
        };
}