Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added 256-color xterm-style ANSI code support, e.g. ESC[38;5;121m. Ad…

…ded tests for same, as well as some more tests for existing ANSI color codes.
  • Loading branch information...
commit d6545d983c5c0782c5a97a4ebd9821e9acfe10f7 1 parent 3f78401
Tyler Berry authored
22 filters/J3ANSIFormattingFilter.h
View
@@ -35,6 +35,7 @@ typedef enum J3ANSICode
J3ANSIForegroundMagenta = 35,
J3ANSIForegroundCyan = 36,
J3ANSIForegroundWhite = 37,
+ J3ANSIForeground256 = 38,
J3ANSIForegroundDefault = 39,
J3ANSIBackgroundBlack = 40,
J3ANSIBackgroundRed = 41,
@@ -44,9 +45,30 @@ typedef enum J3ANSICode
J3ANSIBackgroundMagenta = 45,
J3ANSIBackgroundCyan = 46,
J3ANSIBackgroundWhite = 47,
+ J3ANSIBackground256 = 48,
J3ANSIBackgroundDefault = 49
} J3ANSICode;
+typedef enum J3ANSI256ColorCode
+{
+ J3ANSI256Black = 0,
+ J3ANSI256Red = 1,
+ J3ANSI256Green = 2,
+ J3ANSI256Yellow = 3,
+ J3ANSI256Blue = 4,
+ J3ANSI256Magenta = 5,
+ J3ANSI256Cyan = 6,
+ J3ANSI256White = 7,
+ J3ANSI256BrightBlack = 8,
+ J3ANSI256BrightRed = 9,
+ J3ANSI256BrightGreen = 10,
+ J3ANSI256BrightYellow = 11,
+ J3ANSI256BrightBlue = 12,
+ J3ANSI256BrightMagenta = 13,
+ J3ANSI256BrightCyan = 14,
+ J3ANSI256BrightWhite = 15,
+} J3ANSI256ColorCode;
+
@interface J3ANSIFormattingFilter : J3Filter
{
BOOL inCode;
94 filters/J3ANSIFormattingFilter.m
View
@@ -92,6 +92,21 @@ - (NSArray *) attributeNamesForANSICode
NSArray *codeComponents = [[ansiCode substringFromIndex: 2] componentsSeparatedByString: @";"];
NSMutableArray *names = [NSMutableArray arrayWithCapacity: [codeComponents count]];
+ if ([codeComponents count] == 3
+ && [[codeComponents objectAtIndex: 1] intValue] == 5)
+ {
+ if ([[codeComponents objectAtIndex: 0] intValue] == J3ANSIBackground256)
+ {
+ [names addObject: NSBackgroundColorAttributeName];
+ return names;
+ }
+ else if ([[codeComponents objectAtIndex: 0] intValue] == J3ANSIForeground256)
+ {
+ [names addObject: NSForegroundColorAttributeName];
+ return names;
+ }
+ }
+
for (NSString *code in codeComponents)
{
switch ([code intValue])
@@ -144,6 +159,85 @@ - (NSArray *) attributeValuesForANSICodeInString: (NSAttributedString *) string
NSArray *codeComponents = [[ansiCode substringFromIndex: 2] componentsSeparatedByString: @";"];
NSMutableArray *values = [NSMutableArray arrayWithCapacity: [codeComponents count]];
+ if ([codeComponents count] == 3
+ && [[codeComponents objectAtIndex: 1] intValue] == 5)
+ {
+ if ([[codeComponents objectAtIndex: 0] intValue] == J3ANSIBackground256
+ || [[codeComponents objectAtIndex: 0] intValue] == J3ANSIForeground256)
+ {
+ int value = [[codeComponents objectAtIndex: 2] intValue];
+
+ if (value < 16)
+ {
+ switch (value)
+ {
+ case J3ANSI256Black:
+ case J3ANSI256BrightBlack:
+ [values addObject: [NSColor darkGrayColor]];
+ break;
+
+ case J3ANSI256Red:
+ case J3ANSI256BrightRed:
+ [values addObject: [NSColor redColor]];
+ break;
+
+ case J3ANSI256Green:
+ case J3ANSI256BrightGreen:
+ [values addObject: [NSColor greenColor]];
+ break;
+
+ case J3ANSI256Yellow:
+ case J3ANSI256BrightYellow:
+ [values addObject: [NSColor yellowColor]];
+ break;
+
+ case J3ANSI256Blue:
+ case J3ANSI256BrightBlue:
+ [values addObject: [NSColor blueColor]];
+ break;
+
+ case J3ANSI256Magenta:
+ case J3ANSI256BrightMagenta:
+ [values addObject: [NSColor magentaColor]];
+ break;
+
+ case J3ANSI256Cyan:
+ case J3ANSI256BrightCyan:
+ [values addObject: [NSColor cyanColor]];
+ break;
+
+ case J3ANSI256White:
+ case J3ANSI256BrightWhite:
+ [values addObject: [NSColor whiteColor]];
+ break;
+ }
+ }
+ else if (value > 15 && value < 232)
+ {
+ int adjustedValue = value - 16;
+ int red = adjustedValue / 36;
+ int green = (adjustedValue % 36) / 6;
+ int blue = (adjustedValue % 36) % 6;
+
+ NSColor *cubeColor = [NSColor colorWithCalibratedRed: 1. / 6. * red
+ green: 1. / 6. * green
+ blue: 1. / 6. * blue
+ alpha: 1.0];
+ [values addObject: cubeColor];
+ }
+ else if (value > 231 && value < 256)
+ {
+ int adjustedValue = value - 231;
+
+ NSColor *grayscaleColor = [NSColor colorWithCalibratedWhite: 1. / 25. * adjustedValue
+ alpha: 1.0];
+ [values addObject: grayscaleColor];
+ }
+
+ return values;
+ }
+ }
+
for (NSString *code in codeComponents)
{
switch ([code intValue])
202 tests/J3ANSIFormattingFilterTests.m
View
@@ -204,6 +204,107 @@ - (void) testForegroundColor
[self assertString: output hasValue: [J3Formatter testingForeground] forAttribute: NSForegroundColorAttributeName atIndex: 4 message: @"e"];
}
+- (void) testStandardForegroundColors
+{
+ NSAttributedString *input = [self constructAttributedStringForString: @"\x1B[30ma\x1B[31mb\x1B[32mc\x1B[33md\x1B[34me\x1B[35mf\x1B[36mg\x1B[37mh"];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ [self assertString: output hasValue: [NSColor darkGrayColor] forAttribute: NSForegroundColorAttributeName atIndex: 0 message: @"a"];
+ [self assertString: output hasValue: [NSColor redColor] forAttribute: NSForegroundColorAttributeName atIndex: 1 message: @"b"];
+ [self assertString: output hasValue: [NSColor greenColor] forAttribute: NSForegroundColorAttributeName atIndex: 2 message: @"c"];
+ [self assertString: output hasValue: [NSColor yellowColor] forAttribute: NSForegroundColorAttributeName atIndex: 3 message: @"d"];
+ [self assertString: output hasValue: [NSColor blueColor] forAttribute: NSForegroundColorAttributeName atIndex: 4 message: @"e"];
+ [self assertString: output hasValue: [NSColor magentaColor] forAttribute: NSForegroundColorAttributeName atIndex: 5 message: @"f"];
+ [self assertString: output hasValue: [NSColor cyanColor] forAttribute: NSForegroundColorAttributeName atIndex: 6 message: @"g"];
+ [self assertString: output hasValue: [NSColor whiteColor] forAttribute: NSForegroundColorAttributeName atIndex: 7 message: @"h"];
+}
+
+- (void) testXTerm256ForegroundColor
+{
+ for (unsigned i = 0; i < 16; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[38;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ NSColor *targetColor;
+
+ switch (i)
+ {
+ case J3ANSI256Black:
+ case J3ANSI256BrightBlack:
+ targetColor = [NSColor darkGrayColor];
+ break;
+
+ case J3ANSI256Red:
+ case J3ANSI256BrightRed:
+ targetColor = [NSColor redColor];
+ break;
+
+ case J3ANSI256Green:
+ case J3ANSI256BrightGreen:
+ targetColor = [NSColor greenColor];
+ break;
+
+ case J3ANSI256Yellow:
+ case J3ANSI256BrightYellow:
+ targetColor = [NSColor yellowColor];
+ break;
+
+ case J3ANSI256Blue:
+ case J3ANSI256BrightBlue:
+ targetColor = [NSColor blueColor];
+ break;
+
+ case J3ANSI256Magenta:
+ case J3ANSI256BrightMagenta:
+ targetColor = [NSColor magentaColor];
+ break;
+
+ case J3ANSI256Cyan:
+ case J3ANSI256BrightCyan:
+ targetColor = [NSColor cyanColor];
+ break;
+
+ case J3ANSI256White:
+ case J3ANSI256BrightWhite:
+ targetColor = [NSColor whiteColor];
+ }
+
+ [self assertString: output hasValue: targetColor forAttribute: NSForegroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+
+ for (unsigned i = 16; i < 232; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[38;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ int adjustedValue = i - 16;
+ int red = adjustedValue / 36;
+ int green = (adjustedValue % 36) / 6;
+ int blue = (adjustedValue % 36) % 6;
+
+ NSColor *cubeColor = [NSColor colorWithCalibratedRed: 1. / 6. * red
+ green: 1. / 6. * green
+ blue: 1. / 6. * blue
+ alpha: 1.0];
+
+ [self assertString: output hasValue: cubeColor forAttribute: NSForegroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+
+ for (unsigned i = 232; i < 256; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[38;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ int adjustedValue = i - 231;
+
+ NSColor *grayscaleColor = [NSColor colorWithCalibratedWhite: 1. / 25. * adjustedValue
+ alpha: 1.0];
+
+ [self assertString: output hasValue: grayscaleColor forAttribute: NSForegroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+}
+
- (void) testBackgroundColor
{
NSAttributedString *input = [self constructAttributedStringForString: @"a\x1B[46mbc\x1B[45md\x1B[49me"];
@@ -216,6 +317,107 @@ - (void) testBackgroundColor
[self assertString: output hasValue: [J3Formatter testingBackground] forAttribute: NSBackgroundColorAttributeName atIndex: 4 message: @"e"];
}
+- (void) testStandardBackgroundColors
+{
+ NSAttributedString *input = [self constructAttributedStringForString: @"\x1B[40ma\x1B[41mb\x1B[42mc\x1B[43md\x1B[44me\x1B[45mf\x1B[46mg\x1B[47mh"];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ [self assertString: output hasValue: [NSColor darkGrayColor] forAttribute: NSBackgroundColorAttributeName atIndex: 0 message: @"a"];
+ [self assertString: output hasValue: [NSColor redColor] forAttribute: NSBackgroundColorAttributeName atIndex: 1 message: @"b"];
+ [self assertString: output hasValue: [NSColor greenColor] forAttribute: NSBackgroundColorAttributeName atIndex: 2 message: @"c"];
+ [self assertString: output hasValue: [NSColor yellowColor] forAttribute: NSBackgroundColorAttributeName atIndex: 3 message: @"d"];
+ [self assertString: output hasValue: [NSColor blueColor] forAttribute: NSBackgroundColorAttributeName atIndex: 4 message: @"e"];
+ [self assertString: output hasValue: [NSColor magentaColor] forAttribute: NSBackgroundColorAttributeName atIndex: 5 message: @"f"];
+ [self assertString: output hasValue: [NSColor cyanColor] forAttribute: NSBackgroundColorAttributeName atIndex: 6 message: @"g"];
+ [self assertString: output hasValue: [NSColor whiteColor] forAttribute: NSBackgroundColorAttributeName atIndex: 7 message: @"h"];
+}
+
+- (void) testXTerm256BackgroundColor
+{
+ for (unsigned i = 0; i < 16; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[48;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ NSColor *targetColor;
+
+ switch (i)
+ {
+ case J3ANSI256Black:
+ case J3ANSI256BrightBlack:
+ targetColor = [NSColor darkGrayColor];
+ break;
+
+ case J3ANSI256Red:
+ case J3ANSI256BrightRed:
+ targetColor = [NSColor redColor];
+ break;
+
+ case J3ANSI256Green:
+ case J3ANSI256BrightGreen:
+ targetColor = [NSColor greenColor];
+ break;
+
+ case J3ANSI256Yellow:
+ case J3ANSI256BrightYellow:
+ targetColor = [NSColor yellowColor];
+ break;
+
+ case J3ANSI256Blue:
+ case J3ANSI256BrightBlue:
+ targetColor = [NSColor blueColor];
+ break;
+
+ case J3ANSI256Magenta:
+ case J3ANSI256BrightMagenta:
+ targetColor = [NSColor magentaColor];
+ break;
+
+ case J3ANSI256Cyan:
+ case J3ANSI256BrightCyan:
+ targetColor = [NSColor cyanColor];
+ break;
+
+ case J3ANSI256White:
+ case J3ANSI256BrightWhite:
+ targetColor = [NSColor whiteColor];
+ }
+
+ [self assertString: output hasValue: targetColor forAttribute: NSBackgroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+
+ for (unsigned i = 16; i < 232; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[48;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ int adjustedValue = i - 16;
+ int red = adjustedValue / 36;
+ int green = (adjustedValue % 36) / 6;
+ int blue = (adjustedValue % 36) % 6;
+
+ NSColor *cubeColor = [NSColor colorWithCalibratedRed: 1. / 6. * red
+ green: 1. / 6. * green
+ blue: 1. / 6. * blue
+ alpha: 1.0];
+
+ [self assertString: output hasValue: cubeColor forAttribute: NSBackgroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+
+ for (unsigned i = 232; i < 256; i++)
+ {
+ NSAttributedString *input = [self constructAttributedStringForString: [NSString stringWithFormat: @"\x1B[48;5;%dm%d", i, i]];
+ NSAttributedString *output = [queue processAttributedString: input];
+
+ int adjustedValue = i - 231;
+
+ NSColor *grayscaleColor = [NSColor colorWithCalibratedWhite: 1. / 25. * adjustedValue
+ alpha: 1.0];
+
+ [self assertString: output hasValue: grayscaleColor forAttribute: NSBackgroundColorAttributeName atIndex: 0 message: [NSString stringWithFormat: @"%d", i]];
+ }
+}
+
- (void) testForegroundAndBackgroundColorAsCompoundCode
{
NSAttributedString *input = [self constructAttributedStringForString: @"a\x1B[36;46mbc\x1B[45;35md\x1B[39;49me"];
Please sign in to comment.
Something went wrong with that request. Please try again.