split method

List<Chunk> split(
  1. String pattern
)

Split {@code

Implementation

List<Chunk> split(String pattern) {
  var p = 0;
  final n = pattern.length;
  final chunks = <Chunk>[];
  // find all start and stop indexes first, then collect
  final starts = <int>[];
  final stops = <int>[];
  while (p < n) {
    if (p == pattern.indexOf(escape + start, p)) {
      p += escape.length + start.length;
    } else if (p == pattern.indexOf(escape + stop, p)) {
      p += escape.length + stop.length;
    } else if (p == pattern.indexOf(start, p)) {
      starts.add(p);
      p += start.length;
    } else if (p == pattern.indexOf(stop, p)) {
      stops.add(p);
      p += stop.length;
    } else {
      p++;
    }
  }

//		System.out.println("");
//		System.out.println(starts);
//		System.out.println(stops);
  if (starts.length > stops.length) {
    throw ArgumentError('unterminated tag in pattern: ' + pattern);
  }

  if (starts.length < stops.length) {
    throw ArgumentError('missing start tag in pattern: ' + pattern);
  }

  final ntags = starts.length;
  for (var i = 0; i < ntags; i++) {
    if (starts[i] >= stops[i]) {
      throw ArgumentError(
          'tag delimiters out of order in pattern: ' + pattern);
    }
  }

  // collect into chunks now
  if (ntags == 0) {
    final text = pattern.substring(0, n);
    chunks.add(TextChunk(text));
  }

  if (ntags > 0 && starts[0] > 0) {
    // copy text up to first tag into chunks
    final text = pattern.substring(0, starts[0]);
    chunks.add(TextChunk(text));
  }
  for (var i = 0; i < ntags; i++) {
    // copy inside of <tag>
    final tag = pattern.substring(starts[i] + start.length, stops[i]);
    var ruleOrToken = tag;
    String? label;
    final colon = tag.indexOf(':');
    if (colon >= 0) {
      label = tag.substring(0, colon);
      ruleOrToken = tag.substring(colon + 1, tag.length);
    }
    chunks.add(TagChunk(ruleOrToken, label: label));
    if (i + 1 < ntags) {
      // copy from end of <tag> to start of next
      final text = pattern.substring(stops[i] + stop.length, starts[i + 1]);
      chunks.add(TextChunk(text));
    }
  }
  if (ntags > 0) {
    final afterLastTag = stops[ntags - 1] + stop.length;
    if (afterLastTag < n) {
      // copy text from end of last tag to end
      final text = pattern.substring(afterLastTag, n);
      chunks.add(TextChunk(text));
    }
  }

  // strip out the escape sequences from text chunks but not tags
  for (var i = 0; i < chunks.length; i++) {
    final c = chunks[i];
    if (c is TextChunk) {
      final tc = c;
      final unescaped = tc.text.replaceAll(escape, '');
      if (unescaped.length < tc.text.length) {
        chunks[i] = TextChunk(unescaped);
      }
    }
  }

  return chunks;
}