ansi_up.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /* ansi_up.js
  2. * author : Dru Nelson
  3. * license : MIT
  4. * http://github.com/drudru/ansi_up
  5. */
  6. (function (root, factory) {
  7. if (typeof define === 'function' && define.amd) {
  8. // AMD. Register as an anonymous module.
  9. define(['exports'], factory);
  10. } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
  11. // CommonJS
  12. factory(exports);
  13. } else {
  14. // Browser globals
  15. var exp = {};
  16. factory(exp);
  17. root.AnsiUp = exp.default;
  18. }
  19. }(this, function (exports) {
  20. "use strict";
  21. function rgx(tmplObj) {
  22. var subst = [];
  23. for (var _i = 1; _i < arguments.length; _i++) {
  24. subst[_i - 1] = arguments[_i];
  25. }
  26. var regexText = tmplObj.raw[0];
  27. var wsrgx = /^\s+|\s+\n|\s+#[\s\S]+?\n/gm;
  28. var txt2 = regexText.replace(wsrgx, '');
  29. return new RegExp(txt2, 'm');
  30. }
  31. var AnsiUp = (function () {
  32. function AnsiUp() {
  33. this.VERSION = "3.0.0";
  34. this.ansi_colors = [
  35. [
  36. { rgb: [0, 0, 0], class_name: "ansi-black" },
  37. { rgb: [187, 0, 0], class_name: "ansi-red" },
  38. { rgb: [0, 187, 0], class_name: "ansi-green" },
  39. { rgb: [187, 187, 0], class_name: "ansi-yellow" },
  40. { rgb: [0, 0, 187], class_name: "ansi-blue" },
  41. { rgb: [187, 0, 187], class_name: "ansi-magenta" },
  42. { rgb: [0, 187, 187], class_name: "ansi-cyan" },
  43. { rgb: [255, 255, 255], class_name: "ansi-white" }
  44. ],
  45. [
  46. { rgb: [85, 85, 85], class_name: "ansi-bright-black" },
  47. { rgb: [255, 85, 85], class_name: "ansi-bright-red" },
  48. { rgb: [0, 255, 0], class_name: "ansi-bright-green" },
  49. { rgb: [255, 255, 85], class_name: "ansi-bright-yellow" },
  50. { rgb: [85, 85, 255], class_name: "ansi-bright-blue" },
  51. { rgb: [255, 85, 255], class_name: "ansi-bright-magenta" },
  52. { rgb: [85, 255, 255], class_name: "ansi-bright-cyan" },
  53. { rgb: [255, 255, 255], class_name: "ansi-bright-white" }
  54. ]
  55. ];
  56. this.htmlFormatter = {
  57. transform: function (fragment, instance) {
  58. var txt = fragment.text;
  59. if (txt.length === 0)
  60. return txt;
  61. if (instance._escape_for_html)
  62. txt = instance.old_escape_for_html(txt);
  63. if (!fragment.bold && fragment.fg === null && fragment.bg === null)
  64. return txt;
  65. var styles = [];
  66. var classes = [];
  67. var fg = fragment.fg;
  68. var bg = fragment.bg;
  69. if (fragment.bold)
  70. styles.push('font-weight:bold');
  71. if (!instance._use_classes) {
  72. if (fg)
  73. styles.push("color:rgb(" + fg.rgb.join(',') + ")");
  74. if (bg)
  75. styles.push("background-color:rgb(" + bg.rgb + ")");
  76. }
  77. else {
  78. if (fg) {
  79. if (fg.class_name !== 'truecolor') {
  80. classes.push(fg.class_name + "-fg");
  81. }
  82. else {
  83. styles.push("color:rgb(" + fg.rgb.join(',') + ")");
  84. }
  85. }
  86. if (bg) {
  87. if (bg.class_name !== 'truecolor') {
  88. classes.push(bg.class_name + "-bg");
  89. }
  90. else {
  91. styles.push("background-color:rgb(" + bg.rgb.join(',') + ")");
  92. }
  93. }
  94. }
  95. var class_string = '';
  96. var style_string = '';
  97. if (classes.length)
  98. class_string = " class=\"" + classes.join(' ') + "\"";
  99. if (styles.length)
  100. style_string = " style=\"" + styles.join(';') + "\"";
  101. return "<span" + style_string + class_string + ">" + txt + "</span>";
  102. },
  103. compose: function (segments, instance) {
  104. return segments.join("");
  105. }
  106. };
  107. this.textFormatter = {
  108. transform: function (fragment, instance) {
  109. return fragment.text;
  110. },
  111. compose: function (segments, instance) {
  112. return segments.join("");
  113. }
  114. };
  115. this.setup_256_palette();
  116. this._use_classes = false;
  117. this._escape_for_html = true;
  118. this.bold = false;
  119. this.fg = this.bg = null;
  120. this._buffer = '';
  121. }
  122. Object.defineProperty(AnsiUp.prototype, "use_classes", {
  123. get: function () {
  124. return this._use_classes;
  125. },
  126. set: function (arg) {
  127. this._use_classes = arg;
  128. },
  129. enumerable: true,
  130. configurable: true
  131. });
  132. Object.defineProperty(AnsiUp.prototype, "escape_for_html", {
  133. get: function () {
  134. return this._escape_for_html;
  135. },
  136. set: function (arg) {
  137. this._escape_for_html = arg;
  138. },
  139. enumerable: true,
  140. configurable: true
  141. });
  142. AnsiUp.prototype.setup_256_palette = function () {
  143. var _this = this;
  144. this.palette_256 = [];
  145. this.ansi_colors.forEach(function (palette) {
  146. palette.forEach(function (rec) {
  147. _this.palette_256.push(rec);
  148. });
  149. });
  150. var levels = [0, 95, 135, 175, 215, 255];
  151. for (var r = 0; r < 6; ++r) {
  152. for (var g = 0; g < 6; ++g) {
  153. for (var b = 0; b < 6; ++b) {
  154. var col = { rgb: [levels[r], levels[g], levels[b]], class_name: 'truecolor' };
  155. this.palette_256.push(col);
  156. }
  157. }
  158. }
  159. var grey_level = 8;
  160. for (var i = 0; i < 24; ++i, grey_level += 10) {
  161. var gry = { rgb: [grey_level, grey_level, grey_level], class_name: 'truecolor' };
  162. this.palette_256.push(gry);
  163. }
  164. };
  165. AnsiUp.prototype.old_escape_for_html = function (txt) {
  166. return txt.replace(/[&<>]/gm, function (str) {
  167. if (str === "&")
  168. return "&amp;";
  169. if (str === "<")
  170. return "&lt;";
  171. if (str === ">")
  172. return "&gt;";
  173. });
  174. };
  175. AnsiUp.prototype.old_linkify = function (txt) {
  176. return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) {
  177. return "<a href=\"" + str + "\">" + str + "</a>";
  178. });
  179. };
  180. AnsiUp.prototype.detect_incomplete_ansi = function (txt) {
  181. return !(/.*?[\x40-\x7e]/.test(txt));
  182. };
  183. AnsiUp.prototype.detect_incomplete_link = function (txt) {
  184. var found = false;
  185. for (var i = txt.length - 1; i > 0; i--) {
  186. if (/\s|\x1B/.test(txt[i])) {
  187. found = true;
  188. break;
  189. }
  190. }
  191. if (!found) {
  192. if (/(https?:\/\/[^\s]+)/.test(txt))
  193. return 0;
  194. else
  195. return -1;
  196. }
  197. var prefix = txt.substr(i + 1, 4);
  198. if (prefix.length === 0)
  199. return -1;
  200. if ("http".indexOf(prefix) === 0)
  201. return (i + 1);
  202. };
  203. AnsiUp.prototype.ansi_to = function (txt, formatter) {
  204. var pkt = this._buffer + txt;
  205. this._buffer = '';
  206. var raw_text_pkts = pkt.split(/\x1B\[/);
  207. if (raw_text_pkts.length === 1)
  208. raw_text_pkts.push('');
  209. this.handle_incomplete_sequences(raw_text_pkts);
  210. var first_chunk = this.with_state(raw_text_pkts.shift());
  211. var blocks = new Array(raw_text_pkts.length);
  212. for (var i = 0, len = raw_text_pkts.length; i < len; ++i) {
  213. blocks[i] = (formatter.transform(this.process_ansi(raw_text_pkts[i]), this));
  214. }
  215. if (first_chunk.text.length > 0)
  216. blocks.unshift(formatter.transform(first_chunk, this));
  217. return formatter.compose(blocks, this);
  218. };
  219. AnsiUp.prototype.ansi_to_html = function (txt) {
  220. return this.ansi_to(txt, this.htmlFormatter);
  221. };
  222. AnsiUp.prototype.ansi_to_text = function (txt) {
  223. return this.ansi_to(txt, this.textFormatter);
  224. };
  225. AnsiUp.prototype.with_state = function (text) {
  226. return { bold: this.bold, fg: this.fg, bg: this.bg, text: text };
  227. };
  228. AnsiUp.prototype.handle_incomplete_sequences = function (chunks) {
  229. var last_chunk = chunks[chunks.length - 1];
  230. if ((last_chunk.length > 0) && this.detect_incomplete_ansi(last_chunk)) {
  231. this._buffer = "\x1B[" + last_chunk;
  232. chunks.pop();
  233. chunks.push('');
  234. }
  235. else {
  236. if (last_chunk.slice(-1) === "\x1B") {
  237. this._buffer = "\x1B";
  238. console.log("raw", chunks);
  239. chunks.pop();
  240. chunks.push(last_chunk.substr(0, last_chunk.length - 1));
  241. console.log(chunks);
  242. console.log(last_chunk);
  243. }
  244. if (chunks.length === 2 &&
  245. chunks[1] === "" &&
  246. chunks[0].slice(-1) === "\x1B") {
  247. this._buffer = "\x1B";
  248. last_chunk = chunks.shift();
  249. chunks.unshift(last_chunk.substr(0, last_chunk.length - 1));
  250. }
  251. }
  252. };
  253. AnsiUp.prototype.process_ansi = function (block) {
  254. if (!this._sgr_regex) {
  255. this._sgr_regex = (_a = ["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "], _a.raw = ["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "], rgx(_a));
  256. }
  257. var matches = block.match(this._sgr_regex);
  258. if (!matches) {
  259. return this.with_state(block);
  260. }
  261. var orig_txt = matches[4];
  262. if (matches[1] !== '' || matches[3] !== 'm') {
  263. return this.with_state(orig_txt);
  264. }
  265. var sgr_cmds = matches[2].split(';');
  266. while (sgr_cmds.length > 0) {
  267. var sgr_cmd_str = sgr_cmds.shift();
  268. var num = parseInt(sgr_cmd_str, 10);
  269. if (isNaN(num) || num === 0) {
  270. this.fg = this.bg = null;
  271. this.bold = false;
  272. }
  273. else if (num === 1) {
  274. this.bold = true;
  275. }
  276. else if (num === 22) {
  277. this.bold = false;
  278. }
  279. else if (num === 39) {
  280. this.fg = null;
  281. }
  282. else if (num === 49) {
  283. this.bg = null;
  284. }
  285. else if ((num >= 30) && (num < 38)) {
  286. this.fg = this.ansi_colors[0][(num - 30)];
  287. }
  288. else if ((num >= 40) && (num < 48)) {
  289. this.bg = this.ansi_colors[0][(num - 40)];
  290. }
  291. else if ((num >= 90) && (num < 98)) {
  292. this.fg = this.ansi_colors[1][(num - 90)];
  293. }
  294. else if ((num >= 100) && (num < 108)) {
  295. this.bg = this.ansi_colors[1][(num - 100)];
  296. }
  297. else if (num === 38 || num === 48) {
  298. if (sgr_cmds.length > 0) {
  299. var is_foreground = (num === 38);
  300. var mode_cmd = sgr_cmds.shift();
  301. if (mode_cmd === '5' && sgr_cmds.length > 0) {
  302. var palette_index = parseInt(sgr_cmds.shift(), 10);
  303. if (palette_index >= 0 && palette_index <= 255) {
  304. if (is_foreground)
  305. this.fg = this.palette_256[palette_index];
  306. else
  307. this.bg = this.palette_256[palette_index];
  308. }
  309. }
  310. if (mode_cmd === '2' && sgr_cmds.length > 2) {
  311. var r = parseInt(sgr_cmds.shift(), 10);
  312. var g = parseInt(sgr_cmds.shift(), 10);
  313. var b = parseInt(sgr_cmds.shift(), 10);
  314. if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
  315. var c = { rgb: [r, g, b], class_name: 'truecolor' };
  316. if (is_foreground)
  317. this.fg = c;
  318. else
  319. this.bg = c;
  320. }
  321. }
  322. }
  323. }
  324. }
  325. return this.with_state(orig_txt);
  326. var _a;
  327. };
  328. return AnsiUp;
  329. }());
  330. //# sourceMappingURL=ansi_up.js.map
  331. Object.defineProperty(exports, "__esModule", { value: true });
  332. exports.default = AnsiUp;
  333. }));