ansiToTextSpan function
Converts a string that contains ANSI/ASCII escape codes (SGR sequences) into a TextSpan. Only the most frequently‑used codes are handled (colors, bold, italic, underline, reset). Unknown codes are ignored.
Example:
RichText(
text: ansiToTextSpan('\x1B[31mHello \x1B[1;34mWorld\x1B[0m!'),
)
Implementation
TextSpan ansiToTextSpan(String source, {TextStyle? baseStyle}) {
source = _normalizeControlChars(source);
// 1⃣ Remove cursor‑movement / clear‑screen sequences we can’t show.
source = _stripNonSgrCsi(source);
// 2⃣ Parse the remaining SGR codes exactly as before.
final sgr = RegExp(r'(\x1B|\u001B)\[([0-9;]*)m');
final List<InlineSpan> spans = [];
TextStyle current = baseStyle ?? const TextStyle();
int last = 0;
for (final m in sgr.allMatches(source)) {
if (m.start > last) {
spans.add(
TextSpan(text: source.substring(last, m.start), style: current),
);
}
final params = m[2]!.isEmpty
? <int>[0]
: m[2]!.split(';').where((s) => s.isNotEmpty).map(int.parse).toList();
_applySgr(params, (t) => current = t(current)); // mutates `current`
last = m.end;
}
if (last < source.length) {
spans.add(TextSpan(text: source.substring(last), style: current));
}
return TextSpan(style: baseStyle, children: spans);
}