You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.3 KiB
139 lines
4.3 KiB
4 years ago
|
const String ESC = '\x1b';
|
||
|
const String CSI = '$ESC[';
|
||
|
|
||
|
class TextFormat {
|
||
|
final List<TextFormat> children;
|
||
|
|
||
|
const TextFormat({required this.children});
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
return children.join('');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ANSIColorText extends TextFormat {
|
||
|
final ANSIColor? foreground;
|
||
|
final ANSIColor? background;
|
||
|
|
||
|
ANSIColorText({this.foreground, this.background, required List<TextFormat> children}) : super(children: children);
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
var result = '';
|
||
|
for (final child in children) {
|
||
|
result += foreground?.enabler ?? '';
|
||
|
result += background?.backgroundEnabler ?? '';
|
||
|
result += child.toString();
|
||
|
}
|
||
|
result += foreground?.disabler ?? '';
|
||
|
result += background?.backgroundDisabler ?? '';
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ANSIFormat extends TextFormat {
|
||
|
final bool? bold;
|
||
|
final bool? italic;
|
||
|
final bool? underline;
|
||
|
final bool? reverseColor;
|
||
|
|
||
|
ANSIFormat({this.bold, this.italic, this.underline, this.reverseColor, required List<TextFormat> children}) : super(children: children);
|
||
|
|
||
|
@override
|
||
|
String toString() {
|
||
|
var result = '';
|
||
|
for (final child in children) {
|
||
|
if (bold != null) {
|
||
|
result += bold! ? ANSIBold().enabler : ANSIBold().disabler;
|
||
|
}
|
||
|
if (italic != null) {
|
||
|
result += italic! ? ANSIItalic().enabler : ANSIItalic().disabler;
|
||
|
}
|
||
|
if (underline != null) {
|
||
|
result += underline! ? ANSIUnderline().enabler : ANSIUnderline().disabler;
|
||
|
}
|
||
|
if (reverseColor != null) {
|
||
|
result += reverseColor! ? ANSIReverseVideo().enabler : ANSIReverseVideo().disabler;
|
||
|
}
|
||
|
result += child.toString();
|
||
|
}
|
||
|
if (bold != null) {
|
||
|
result += bold! ? ANSIBold().disabler : ANSIBold().enabler;
|
||
|
}
|
||
|
if (italic != null) {
|
||
|
result += italic! ? ANSIItalic().disabler : ANSIItalic().enabler;
|
||
|
}
|
||
|
if (underline != null) {
|
||
|
result += underline! ? ANSIUnderline().disabler : ANSIUnderline().enabler;
|
||
|
}
|
||
|
if (reverseColor != null) {
|
||
|
result += reverseColor! ? ANSIReverseVideo().disabler : ANSIReverseVideo().enabler;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class Text extends TextFormat {
|
||
|
final String value;
|
||
|
const Text(this.value) : super(children: const []);
|
||
|
@override
|
||
|
String toString() {
|
||
|
return value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ANSIEscape {
|
||
|
final String enabler;
|
||
|
final String disabler;
|
||
|
|
||
|
const ANSIEscape({required this.enabler, required this.disabler});
|
||
|
}
|
||
|
|
||
|
class ANSIBold extends ANSIEscape {
|
||
|
const ANSIBold() : super(enabler: '${CSI}1m', disabler: '${CSI}22m');
|
||
|
}
|
||
|
|
||
|
class ANSIItalic extends ANSIEscape {
|
||
|
const ANSIItalic() : super(enabler: '${CSI}3m', disabler: '${CSI}23m');
|
||
|
}
|
||
|
|
||
|
class ANSIUnderline extends ANSIEscape {
|
||
|
const ANSIUnderline() : super(enabler: '${CSI}4m', disabler: '${CSI}24m');
|
||
|
}
|
||
|
|
||
|
class ANSIReverseVideo extends ANSIEscape {
|
||
|
const ANSIReverseVideo() : super(enabler: '${CSI}7m', disabler: '${CSI}27m');
|
||
|
}
|
||
|
|
||
|
class ANSIColor extends ANSIEscape {
|
||
|
const ANSIColor.index(int index, [bool bright = false]) : super(enabler: '$CSI${bright ? 9 : 3}${index}m', disabler: '${CSI}39m');
|
||
|
const ANSIColor.value(String value) : super(enabler: '$CSI${value}m', disabler: '${CSI}39m');
|
||
|
String get backgroundEnabler {
|
||
|
final noCSI = enabler.substring(CSI.length);
|
||
|
final nom = noCSI.substring(0, noCSI.length - 1);
|
||
|
final number = int.parse(nom);
|
||
|
return '$CSI${number + 10}m';
|
||
|
}
|
||
|
final String backgroundDisabler = '${CSI}49m';
|
||
|
}
|
||
|
|
||
|
class ANSIColors {
|
||
|
static const ANSIColor black = ANSIColor.index(0);
|
||
|
static const ANSIColor red = ANSIColor.index(1);
|
||
|
static const ANSIColor green = ANSIColor.index(2);
|
||
|
static const ANSIColor yellow = ANSIColor.index(3);
|
||
|
static const ANSIColor blue = ANSIColor.index(4);
|
||
|
static const ANSIColor magenta = ANSIColor.index(5);
|
||
|
static const ANSIColor cyan = ANSIColor.index(6);
|
||
|
static const ANSIColor white = ANSIColor.index(7);
|
||
|
static const ANSIColor brightBlack = ANSIColor.index(0, true);
|
||
|
static const ANSIColor brightRed = ANSIColor.index(1, true);
|
||
|
static const ANSIColor brightGreen = ANSIColor.index(2, true);
|
||
|
static const ANSIColor brightYellow = ANSIColor.index(3, true);
|
||
|
static const ANSIColor brightBlue = ANSIColor.index(4, true);
|
||
|
static const ANSIColor brightMagenta = ANSIColor.index(5, true);
|
||
|
static const ANSIColor brightCyan = ANSIColor.index(6, true);
|
||
|
static const ANSIColor brightWhite = ANSIColor.index(7, true);
|
||
|
}
|