blob: f24c0b6d9ed3af191438f98d90238a2759d79cfd [file] [log] [blame]
Jakub Josef52c3f122017-08-09 13:14:07 +02001/* 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";
21function 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}
31var AnsiUp = (function () {
32 function AnsiUp() {
33 this.VERSION = "2.0.2";
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.bright && 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 (fg === null && fragment.bright)
70 fg = instance.ansi_colors[1][7];
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" + class_string + style_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.bright = 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 { bright: this.bright, 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.bright = false;
272 }
273 else if (num === 1) {
274 this.bright = true;
275 }
276 else if (num === 22) {
277 this.bright = 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 var bidx = this.bright ? 1 : 0;
287 this.fg = this.ansi_colors[bidx][(num - 30)];
288 }
289 else if ((num >= 90) && (num < 98)) {
290 this.fg = this.ansi_colors[1][(num - 90)];
291 }
292 else if ((num >= 40) && (num < 48)) {
293 this.bg = this.ansi_colors[0][(num - 40)];
294 }
295 else if ((num >= 100) && (num < 108)) {
296 this.bg = this.ansi_colors[1][(num - 100)];
297 }
298 else if (num === 38 || num === 48) {
299 if (sgr_cmds.length > 0) {
300 var is_foreground = (num === 38);
301 var mode_cmd = sgr_cmds.shift();
302 if (mode_cmd === '5' && sgr_cmds.length > 0) {
303 var palette_index = parseInt(sgr_cmds.shift(), 10);
304 if (palette_index >= 0 && palette_index <= 255) {
305 if (is_foreground)
306 this.fg = this.palette_256[palette_index];
307 else
308 this.bg = this.palette_256[palette_index];
309 }
310 }
311 if (mode_cmd === '2' && sgr_cmds.length > 2) {
312 var r = parseInt(sgr_cmds.shift(), 10);
313 var g = parseInt(sgr_cmds.shift(), 10);
314 var b = parseInt(sgr_cmds.shift(), 10);
315 if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
316 var c = { rgb: [r, g, b], class_name: 'truecolor' };
317 if (is_foreground)
318 this.fg = c;
319 else
320 this.bg = c;
321 }
322 }
323 }
324 }
325 }
326 return this.with_state(orig_txt);
327 var _a;
328 };
329 return AnsiUp;
330}());
331//# sourceMappingURL=ansi_up.js.map
332 Object.defineProperty(exports, "__esModule", { value: true });
333 exports.default = AnsiUp;
334}));