wrapText static method
Wraps the text so that it stays within email's 76 characters per line convention.
text the text that should be wrapped.
Set wrapAtWordBoundary to true in case the text should be wrapped
at word boundaries / spaces.
Implementation
static String wrapText(String text, {bool wrapAtWordBoundary = false}) {
if (text.length <= MailConventions.textLineMaxLength) {
return text;
}
final buffer = StringBuffer();
final runes = text.runes;
int? lastRune;
int? lastSpaceIndex;
var currentLineLength = 0;
var currentLineStartIndex = 0;
for (var runeIndex = 0; runeIndex < runes.length; runeIndex++) {
final rune = runes.elementAt(runeIndex);
if (rune == AsciiRunes.runeLineFeed &&
lastRune == AsciiRunes.runeCarriageReturn) {
buffer.write(text.substring(currentLineStartIndex, runeIndex + 1));
currentLineLength = 0;
currentLineStartIndex = runeIndex + 1;
lastSpaceIndex = null;
} else {
if (wrapAtWordBoundary &&
(rune == AsciiRunes.runeSpace || rune == AsciiRunes.runeTab)) {
lastSpaceIndex = runeIndex;
}
currentLineLength++;
if (currentLineLength >= MailConventions.textLineMaxLength) {
// edge case: this could be in the middle of a \r\n sequence:
if (rune == AsciiRunes.runeCarriageReturn &&
runeIndex < runes.length - 1 &&
runes.elementAt(runeIndex + 1) == AsciiRunes.runeLineFeed) {
lastRune = rune;
continue; // the break will be handled in the next loop iteration
}
var endIndex = (wrapAtWordBoundary && lastSpaceIndex != null)
? lastSpaceIndex
: runeIndex;
if (endIndex < runes.length - 1) {
endIndex++;
}
buffer
..write(text.substring(currentLineStartIndex, endIndex))
..write('\r\n');
currentLineLength = 0;
currentLineStartIndex = endIndex;
lastSpaceIndex = null;
}
}
lastRune = rune;
}
if (currentLineStartIndex < text.length) {
buffer.write(text.substring(currentLineStartIndex));
}
return buffer.toString();
}