NSString+ANSI.mm 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Created by Kent Karlsson on 3/11/16.
  2. // Copyright (c) 2016 Bit Bar. All rights reserved.
  3. // Copyright (c) 2017 GitHub, Inc.
  4. // Use of this source code is governed by the MIT license that can be
  5. // found in the LICENSE file.
  6. #import <Cocoa/Cocoa.h>
  7. #include "content/public/common/color_parser.h"
  8. #include "shell/browser/ui/cocoa/NSString+ANSI.h"
  9. #include "skia/ext/skia_utils_mac.h"
  10. @implementation NSMutableDictionary (ANSI)
  11. - (NSMutableDictionary*)modifyAttributesForANSICodes:(NSString*)codes {
  12. BOOL bold = NO;
  13. NSFont* font = self[NSFontAttributeName];
  14. NSArray* codeArray = [codes componentsSeparatedByString:@";"];
  15. for (NSString* codeString in codeArray) {
  16. int code = codeString.intValue;
  17. SkColor color;
  18. switch (code) {
  19. case 0:
  20. [self removeAllObjects];
  21. // remove italic and bold from font here
  22. if (font)
  23. self[NSFontAttributeName] = font;
  24. break;
  25. case 1:
  26. case 22:
  27. bold = (code == 1);
  28. break;
  29. // case 3: italic
  30. // case 23: italic off
  31. // case 4: underlined
  32. // case 24: underlined off
  33. case 30:
  34. content::ParseHexColorString(bold ? "#7f7f7f" : "#000000", &color);
  35. self[NSForegroundColorAttributeName] =
  36. skia::SkColorToCalibratedNSColor(color);
  37. break;
  38. case 31:
  39. content::ParseHexColorString(bold ? "#cd0000" : "#ff0000", &color);
  40. self[NSForegroundColorAttributeName] =
  41. skia::SkColorToCalibratedNSColor(color);
  42. break;
  43. case 32:
  44. content::ParseHexColorString(bold ? "#00cd00" : "#00ff00", &color);
  45. self[NSForegroundColorAttributeName] =
  46. skia::SkColorToCalibratedNSColor(color);
  47. break;
  48. case 33:
  49. content::ParseHexColorString(bold ? "#cdcd00" : "#ffff00", &color);
  50. self[NSForegroundColorAttributeName] =
  51. skia::SkColorToCalibratedNSColor(color);
  52. break;
  53. case 34:
  54. content::ParseHexColorString(bold ? "#0000ee" : "#5c5cff", &color);
  55. self[NSForegroundColorAttributeName] =
  56. skia::SkColorToCalibratedNSColor(color);
  57. break;
  58. case 35:
  59. content::ParseHexColorString(bold ? "#cd00cd" : "#ff00ff", &color);
  60. self[NSForegroundColorAttributeName] =
  61. skia::SkColorToCalibratedNSColor(color);
  62. break;
  63. case 36:
  64. content::ParseHexColorString(bold ? "#00cdcd" : "#00ffff", &color);
  65. self[NSForegroundColorAttributeName] =
  66. skia::SkColorToCalibratedNSColor(color);
  67. break;
  68. case 37:
  69. content::ParseHexColorString(bold ? "#e5e5e5" : "#ffffff", &color);
  70. self[NSForegroundColorAttributeName] =
  71. skia::SkColorToCalibratedNSColor(color);
  72. break;
  73. case 39:
  74. [self removeObjectForKey:NSForegroundColorAttributeName];
  75. break;
  76. case 40:
  77. content::ParseHexColorString("#7f7f7f", &color);
  78. self[NSBackgroundColorAttributeName] =
  79. skia::SkColorToCalibratedNSColor(color);
  80. break;
  81. case 41:
  82. content::ParseHexColorString("#cd0000", &color);
  83. self[NSBackgroundColorAttributeName] =
  84. skia::SkColorToCalibratedNSColor(color);
  85. break;
  86. case 42:
  87. content::ParseHexColorString("#00cd00", &color);
  88. self[NSBackgroundColorAttributeName] =
  89. skia::SkColorToCalibratedNSColor(color);
  90. break;
  91. case 43:
  92. content::ParseHexColorString("#cdcd00", &color);
  93. self[NSBackgroundColorAttributeName] =
  94. skia::SkColorToCalibratedNSColor(color);
  95. break;
  96. case 44:
  97. content::ParseHexColorString("#0000ee", &color);
  98. self[NSBackgroundColorAttributeName] =
  99. skia::SkColorToCalibratedNSColor(color);
  100. break;
  101. case 45:
  102. content::ParseHexColorString("cd00cd", &color);
  103. self[NSBackgroundColorAttributeName] =
  104. skia::SkColorToCalibratedNSColor(color);
  105. break;
  106. case 46:
  107. content::ParseHexColorString("#00cdcd", &color);
  108. self[NSBackgroundColorAttributeName] =
  109. skia::SkColorToCalibratedNSColor(color);
  110. break;
  111. case 47:
  112. content::ParseHexColorString("#e5e5e5", &color);
  113. self[NSBackgroundColorAttributeName] =
  114. skia::SkColorToCalibratedNSColor(color);
  115. break;
  116. case 49:
  117. [self removeObjectForKey:NSBackgroundColorAttributeName];
  118. break;
  119. default:
  120. break;
  121. }
  122. }
  123. return self;
  124. }
  125. @end
  126. @implementation NSString (ANSI)
  127. - (BOOL)containsANSICodes {
  128. return [self rangeOfString:@"\033["].location != NSNotFound;
  129. }
  130. - (NSMutableAttributedString*)attributedStringParsingANSICodes {
  131. NSMutableAttributedString* result = [[NSMutableAttributedString alloc] init];
  132. NSMutableDictionary* attributes([[NSMutableDictionary alloc] init]);
  133. NSArray* parts = [self componentsSeparatedByString:@"\033["];
  134. [result appendAttributedString:[[NSAttributedString alloc]
  135. initWithString:parts.firstObject
  136. attributes:nil]];
  137. for (NSString* part in
  138. [parts subarrayWithRange:NSMakeRange(1, parts.count - 1)]) {
  139. if (part.length == 0)
  140. continue;
  141. NSArray* sequence = [part componentsSeparatedByString:@"m"];
  142. NSString* text = sequence.lastObject;
  143. if (sequence.count < 2) {
  144. [result appendAttributedString:[[NSAttributedString alloc]
  145. initWithString:text
  146. attributes:attributes]];
  147. } else if (sequence.count >= 2) {
  148. text = [[sequence subarrayWithRange:NSMakeRange(1, sequence.count - 1)]
  149. componentsJoinedByString:@"m"];
  150. [attributes modifyAttributesForANSICodes:sequence[0]];
  151. [result appendAttributedString:[[NSAttributedString alloc]
  152. initWithString:text
  153. attributes:attributes]];
  154. }
  155. }
  156. return result;
  157. }
  158. @end