split method
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;
}