LogBox.fromText constructor
LogBox.fromText(
- Log log,
- LogTheme theme,
- String text, {
- required int? maxLines,
- String? verticalFiller,
- LogConstraints constraints = const LogConstraints.unlimited(),
- LogTextAlign textAlign = LogTextAlign.left,
- LogVerticalAlign verticalAlign = LogVerticalAlign.top,
- String? debugName,
Implementation
factory LogBox.fromText(
Log log,
LogTheme theme,
String text, {
required int? maxLines,
String? verticalFiller,
LogConstraints constraints = const LogConstraints.unlimited(),
LogTextAlign textAlign = LogTextAlign.left,
LogVerticalAlign verticalAlign = LogVerticalAlign.top,
String? debugName,
}) {
final lines = text.split('\n');
final parsers = lines.map(ansi.Parser.new).toList(growable: false);
var boxWidth = parsers.fold(0, (w, parser) => math.max(w, parser.length));
boxWidth = constraints.apply(boxWidth);
if (boxWidth == 0) {
return LogBox.empty(debugName: debugName);
}
// Место под символ переноса нужно только строкам, которые реально
// переносятся, — иначе односимвольное сообщение выродилось бы в пробел.
final needsWrap = parsers.any((parser) => parser.length > boxWidth);
final textWidth = boxWidth - theme.main.lineBreak.length;
if (needsWrap && textWidth <= 0) {
return LogBox.raw(
boxWidth,
[' ' * boxWidth],
debugName: debugName,
);
}
final boxLines = <String>[];
for (final parser in parsers) {
if (parser.length <= boxWidth) {
boxLines.add(
parser.applyConstraints(
log,
theme,
LogConstraints.exact(boxWidth),
textAlign: textAlign,
),
);
continue;
}
var start = 0;
final end = parser.length;
while (start < end) {
final remaining = end - start;
if (remaining <= textWidth) {
boxLines.add(
'${fixDanglingSurrogates(parser.substring(start)).applyConstraints(
log,
theme,
LogConstraints.exact(textWidth),
textAlign: textAlign,
)}${' ' * theme.main.lineBreak.length}',
);
start = end;
} else if (maxLines == null || maxLines > boxLines.length + 1) {
boxLines.add(
'${fixDanglingSurrogates(parser.substring(start, maxLength: textWidth))}'
'${theme.styledLineBreak}',
);
start += textWidth;
} else {
// Последняя (обрезанная) строка не содержит символа переноса и
// занимает полную ширину бокса — иначе была бы на колонку уже.
boxLines.add(
parser.terminatedSubstring(
theme.main.ellipsis,
theme.data.ellipsisStyle,
start,
maxLength: boxWidth,
),
);
start += boxWidth;
break;
}
}
}
String? boxVerticalFiller;
if (verticalFiller != null) {
final parser = ansi.Parser(verticalFiller);
boxVerticalFiller = parser.applyConstraints(
log,
theme,
LogConstraints.exact(boxWidth),
textAlign: textAlign,
// См. комментарий в фабрике LogBox: без многоточия на филлерах.
showEllipsis: false,
);
}
return LogBox(
log,
theme,
boxLines,
constraints: constraints,
textAlign: textAlign,
verticalFiller: boxVerticalFiller,
verticalAlign: verticalAlign,
debugName: debugName,
);
}