123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- "use strict";
- // This file was originally written by @drudru (https://github.com/drudru/ansi_up), MIT, 2011
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- var ANSI_COLORS = [[{ color: "0, 0, 0", "class": "ansi-black" }, { color: "187, 0, 0", "class": "ansi-red" }, { color: "0, 187, 0", "class": "ansi-green" }, { color: "187, 187, 0", "class": "ansi-yellow" }, { color: "0, 0, 187", "class": "ansi-blue" }, { color: "187, 0, 187", "class": "ansi-magenta" }, { color: "0, 187, 187", "class": "ansi-cyan" }, { color: "255,255,255", "class": "ansi-white" }], [{ color: "85, 85, 85", "class": "ansi-bright-black" }, { color: "255, 85, 85", "class": "ansi-bright-red" }, { color: "0, 255, 0", "class": "ansi-bright-green" }, { color: "255, 255, 85", "class": "ansi-bright-yellow" }, { color: "85, 85, 255", "class": "ansi-bright-blue" }, { color: "255, 85, 255", "class": "ansi-bright-magenta" }, { color: "85, 255, 255", "class": "ansi-bright-cyan" }, { color: "255, 255, 255", "class": "ansi-bright-white" }]];
- var Anser = function () {
- _createClass(Anser, null, [{
- key: "escapeForHtml",
- /**
- * Anser.escapeForHtml
- * Escape the input HTML.
- *
- * This does the minimum escaping of text to make it compliant with HTML.
- * In particular, the '&','<', and '>' characters are escaped. This should
- * be run prior to `ansiToHtml`.
- *
- * @name Anser.escapeForHtml
- * @function
- * @param {String} txt The input text (containing the ANSI snippets).
- * @returns {String} The escaped html.
- */
- value: function escapeForHtml(txt) {
- return new Anser().escapeForHtml(txt);
- }
- /**
- * Anser.linkify
- * Adds the links in the HTML.
- *
- * This replaces any links in the text with anchor tags that display the
- * link. The links should have at least one whitespace character
- * surrounding it. Also, you should apply this after you have run
- * `ansiToHtml` on the text.
- *
- * @name Anser.linkify
- * @function
- * @param {String} txt The input text.
- * @returns {String} The HTML containing the <a> tags (unescaped).
- */
- }, {
- key: "linkify",
- value: function linkify(txt) {
- return new Anser().linkify(txt);
- }
- /**
- * Anser.ansiToHtml
- * This replaces ANSI terminal escape codes with SPAN tags that wrap the
- * content.
- *
- * This function only interprets ANSI SGR (Select Graphic Rendition) codes
- * that can be represented in HTML.
- * For example, cursor movement codes are ignored and hidden from output.
- * The default style uses colors that are very close to the prescribed
- * standard. The standard assumes that the text will have a black
- * background. These colors are set as inline styles on the SPAN tags.
- *
- * Another option is to set `use_classes: true` in the options argument.
- * This will instead set classes on the spans so the colors can be set via
- * CSS. The class names used are of the format `ansi-*-fg/bg` and
- * `ansi-bright-*-fg/bg` where `*` is the color name,
- * i.e black/red/green/yellow/blue/magenta/cyan/white.
- *
- * @name Anser.ansiToHtml
- * @function
- * @param {String} txt The input text.
- * @param {Object} options The options passed to the ansiToHTML method.
- * @returns {String} The HTML output.
- */
- }, {
- key: "ansiToHtml",
- value: function ansiToHtml(txt, options) {
- return new Anser().ansiToHtml(txt, options);
- }
- /**
- * Anser.ansiToJson
- * Converts ANSI input into JSON output.
- *
- * @name Anser.ansiToJson
- * @function
- * @param {String} txt The input text.
- * @param {Object} options The options passed to the ansiToHTML method.
- * @returns {String} The HTML output.
- */
- }, {
- key: "ansiToJson",
- value: function ansiToJson(txt, options) {
- return new Anser().ansiToJson(txt, options);
- }
- /**
- * Anser.ansiToText
- * Converts ANSI input into text output.
- *
- * @name Anser.ansiToText
- * @function
- * @param {String} txt The input text.
- * @returns {String} The text output.
- */
- }, {
- key: "ansiToText",
- value: function ansiToText(txt) {
- return new Anser().ansiToText(txt);
- }
- /**
- * Anser
- * The `Anser` class.
- *
- * @name Anser
- * @function
- * @returns {Anser}
- */
- }]);
- function Anser() {
- _classCallCheck(this, Anser);
- this.fg = this.bg = this.fg_truecolor = this.bg_truecolor = null;
- this.bright = 0;
- }
- /**
- * setupPalette
- * Sets up the palette.
- *
- * @name setupPalette
- * @function
- */
- _createClass(Anser, [{
- key: "setupPalette",
- value: function setupPalette() {
- this.PALETTE_COLORS = [];
- // Index 0..15 : System color
- for (var i = 0; i < 2; ++i) {
- for (var j = 0; j < 8; ++j) {
- this.PALETTE_COLORS.push(ANSI_COLORS[i][j].color);
- }
- }
- // Index 16..231 : RGB 6x6x6
- // https://gist.github.com/jasonm23/2868981#file-xterm-256color-yaml
- var levels = [0, 95, 135, 175, 215, 255];
- var format = function format(r, g, b) {
- return levels[r] + ", " + levels[g] + ", " + levels[b];
- };
- var r = void 0,
- g = void 0,
- b = void 0;
- for (var _r = 0; _r < 6; ++_r) {
- for (var _g = 0; _g < 6; ++_g) {
- for (var _b = 0; _b < 6; ++_b) {
- this.PALETTE_COLORS.push(format(_r, _g, _b));
- }
- }
- }
- // Index 232..255 : Grayscale
- var level = 8;
- for (var _i = 0; _i < 24; ++_i, level += 10) {
- this.PALETTE_COLORS.push(format(level, level, level));
- }
- }
- /**
- * escapeForHtml
- * Escapes the input text.
- *
- * @name escapeForHtml
- * @function
- * @param {String} txt The input text.
- * @returns {String} The escpaed HTML output.
- */
- }, {
- key: "escapeForHtml",
- value: function escapeForHtml(txt) {
- return txt.replace(/[&<>]/gm, function (str) {
- return str == "&" ? "&" : str == "<" ? "<" : str == ">" ? ">" : "";
- });
- }
- /**
- * linkify
- * Adds HTML link elements.
- *
- * @name linkify
- * @function
- * @param {String} txt The input text.
- * @returns {String} The HTML output containing link elements.
- */
- }, {
- key: "linkify",
- value: function linkify(txt) {
- return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) {
- return "<a href=\"" + str + "\">" + str + "</a>";
- });
- }
- /**
- * ansiToHtml
- * Converts ANSI input into HTML output.
- *
- * @name ansiToHtml
- * @function
- * @param {String} txt The input text.
- * @param {Object} options The options passed ot the `process` method.
- * @returns {String} The HTML output.
- */
- }, {
- key: "ansiToHtml",
- value: function ansiToHtml(txt, options) {
- return this.process(txt, options, true);
- }
- /**
- * ansiToJson
- * Converts ANSI input into HTML output.
- *
- * @name ansiToJson
- * @function
- * @param {String} txt The input text.
- * @param {Object} options The options passed ot the `process` method.
- * @returns {String} The JSON output.
- */
- }, {
- key: "ansiToJson",
- value: function ansiToJson(txt, options) {
- options = options || {};
- options.json = true;
- options.clearLine = false;
- return this.process(txt, options, true);
- }
- /**
- * ansiToText
- * Converts ANSI input into HTML output.
- *
- * @name ansiToText
- * @function
- * @param {String} txt The input text.
- * @returns {String} The text output.
- */
- }, {
- key: "ansiToText",
- value: function ansiToText(txt) {
- return this.process(txt, {}, false);
- }
- /**
- * process
- * Processes the input.
- *
- * @name process
- * @function
- * @param {String} txt The input text.
- * @param {Object} options An object passed to `processChunk` method, extended with:
- *
- * - `json` (Boolean): If `true`, the result will be an object.
- * - `use_classes` (Boolean): If `true`, HTML classes will be appended to the HTML output.
- *
- * @param {Boolean} markup
- */
- }, {
- key: "process",
- value: function process(txt, options, markup) {
- var _this = this;
- var self = this;
- var raw_text_chunks = txt.split(/\033\[/);
- var first_chunk = raw_text_chunks.shift(); // the first chunk is not the result of the split
- if (options === undefined || options === null) {
- options = {};
- }
- options.clearLine = /\r/.test(txt); // check for Carriage Return
- var color_chunks = raw_text_chunks.map(function (chunk) {
- return _this.processChunk(chunk, options, markup);
- });
- if (options && options.json) {
- var first = self.processChunkJson("");
- first.content = first_chunk;
- first.clearLine = options.clearLine;
- color_chunks.unshift(first);
- if (options.remove_empty) {
- color_chunks = color_chunks.filter(function (c) {
- return !c.isEmpty();
- });
- }
- return color_chunks;
- } else {
- color_chunks.unshift(first_chunk);
- }
- return color_chunks.join("");
- }
- /**
- * processChunkJson
- * Processes the current chunk into json output.
- *
- * @name processChunkJson
- * @function
- * @param {String} text The input text.
- * @param {Object} options An object containing the following fields:
- *
- * - `json` (Boolean): If `true`, the result will be an object.
- * - `use_classes` (Boolean): If `true`, HTML classes will be appended to the HTML output.
- *
- * @param {Boolean} markup If false, the colors will not be parsed.
- * @return {Object} The result object:
- *
- * - `content` (String): The text.
- * - `fg` (String|null): The foreground color.
- * - `bg` (String|null): The background color.
- * - `fg_truecolor` (String|null): The foreground true color (if 16m color is enabled).
- * - `bg_truecolor` (String|null): The background true color (if 16m color is enabled).
- * - `clearLine` (Boolean): `true` if a carriageReturn \r was fount at end of line.
- * - `was_processed` (Bolean): `true` if the colors were processed, `false` otherwise.
- * - `isEmpty` (Function): A function returning `true` if the content is empty, or `false` otherwise.
- *
- */
- }, {
- key: "processChunkJson",
- value: function processChunkJson(text, options, markup) {
- // Are we using classes or styles?
- options = typeof options == "undefined" ? {} : options;
- var use_classes = options.use_classes = typeof options.use_classes != "undefined" && options.use_classes;
- var key = options.key = use_classes ? "class" : "color";
- var result = {
- content: text,
- fg: null,
- bg: null,
- fg_truecolor: null,
- bg_truecolor: null,
- clearLine: options.clearLine,
- decoration: null,
- was_processed: false,
- isEmpty: function isEmpty() {
- return !result.content;
- }
- };
- // Each "chunk" is the text after the CSI (ESC + "[") and before the next CSI/EOF.
- //
- // This regex matches four groups within a chunk.
- //
- // The first and third groups match code type.
- // We supported only SGR command. It has empty first group and "m" in third.
- //
- // The second group matches all of the number+semicolon command sequences
- // before the "m" (or other trailing) character.
- // These are the graphics or SGR commands.
- //
- // The last group is the text (including newlines) that is colored by
- // the other group"s commands.
- var matches = text.match(/^([!\x3c-\x3f]*)([\d;]*)([\x20-\x2c]*[\x40-\x7e])([\s\S]*)/m);
- if (!matches) return result;
- var orig_txt = result.content = matches[4];
- var nums = matches[2].split(";");
- // We currently support only "SGR" (Select Graphic Rendition)
- // Simply ignore if not a SGR command.
- if (matches[1] !== "" || matches[3] !== "m") {
- return result;
- }
- if (!markup) {
- return result;
- }
- var self = this;
- self.decoration = null;
- while (nums.length > 0) {
- var num_str = nums.shift();
- var num = parseInt(num_str);
- if (isNaN(num) || num === 0) {
- self.fg = self.bg = self.decoration = null;
- } else if (num === 1) {
- self.decoration = "bold";
- } else if (num === 2) {
- self.decoration = "dim";
- // Enable code 2 to get string
- } else if (num == 3) {
- self.decoration = "italic";
- } else if (num == 4) {
- self.decoration = "underline";
- } else if (num == 5) {
- self.decoration = "blink";
- } else if (num === 7) {
- self.decoration = "reverse";
- } else if (num === 8) {
- self.decoration = "hidden";
- // Enable code 9 to get strikethrough
- } else if (num === 9) {
- self.decoration = "strikethrough";
- } else if (num == 39) {
- self.fg = null;
- } else if (num == 49) {
- self.bg = null;
- // Foreground color
- } else if (num >= 30 && num < 38) {
- self.fg = ANSI_COLORS[0][num % 10][key];
- // Foreground bright color
- } else if (num >= 90 && num < 98) {
- self.fg = ANSI_COLORS[1][num % 10][key];
- // Background color
- } else if (num >= 40 && num < 48) {
- self.bg = ANSI_COLORS[0][num % 10][key];
- // Background bright color
- } else if (num >= 100 && num < 108) {
- self.bg = ANSI_COLORS[1][num % 10][key];
- } else if (num === 38 || num === 48) {
- // extend color (38=fg, 48=bg)
- var is_foreground = num === 38;
- if (nums.length >= 1) {
- var mode = nums.shift();
- if (mode === "5" && nums.length >= 1) {
- // palette color
- var palette_index = parseInt(nums.shift());
- if (palette_index >= 0 && palette_index <= 255) {
- if (!use_classes) {
- if (!this.PALETTE_COLORS) {
- self.setupPalette();
- }
- if (is_foreground) {
- self.fg = this.PALETTE_COLORS[palette_index];
- } else {
- self.bg = this.PALETTE_COLORS[palette_index];
- }
- } else {
- var klass = palette_index >= 16 ? "ansi-palette-" + palette_index : ANSI_COLORS[palette_index > 7 ? 1 : 0][palette_index % 8]["class"];
- if (is_foreground) {
- self.fg = klass;
- } else {
- self.bg = klass;
- }
- }
- }
- } else if (mode === "2" && nums.length >= 3) {
- // true color
- var r = parseInt(nums.shift());
- var g = parseInt(nums.shift());
- var b = parseInt(nums.shift());
- if (r >= 0 && r <= 255 && g >= 0 && g <= 255 && b >= 0 && b <= 255) {
- var color = r + ", " + g + ", " + b;
- if (!use_classes) {
- if (is_foreground) {
- self.fg = color;
- } else {
- self.bg = color;
- }
- } else {
- if (is_foreground) {
- self.fg = "ansi-truecolor";
- self.fg_truecolor = color;
- } else {
- self.bg = "ansi-truecolor";
- self.bg_truecolor = color;
- }
- }
- }
- }
- }
- }
- }
- if (self.fg === null && self.bg === null && self.decoration === null) {
- return result;
- } else {
- var styles = [];
- var classes = [];
- var data = {};
- result.fg = self.fg;
- result.bg = self.bg;
- result.fg_truecolor = self.fg_truecolor;
- result.bg_truecolor = self.bg_truecolor;
- result.decoration = self.decoration;
- result.was_processed = true;
- return result;
- }
- }
- /**
- * processChunk
- * Processes the current chunk of text.
- *
- * @name processChunk
- * @function
- * @param {String} text The input text.
- * @param {Object} options An object containing the following fields:
- *
- * - `json` (Boolean): If `true`, the result will be an object.
- * - `use_classes` (Boolean): If `true`, HTML classes will be appended to the HTML output.
- *
- * @param {Boolean} markup If false, the colors will not be parsed.
- * @return {Object|String} The result (object if `json` is wanted back or string otherwise).
- */
- }, {
- key: "processChunk",
- value: function processChunk(text, options, markup) {
- var _this2 = this;
- var self = this;
- options = options || {};
- var jsonChunk = this.processChunkJson(text, options, markup);
- if (options.json) {
- return jsonChunk;
- }
- if (jsonChunk.isEmpty()) {
- return "";
- }
- if (!jsonChunk.was_processed) {
- return jsonChunk.content;
- }
- var use_classes = options.use_classes;
- var styles = [];
- var classes = [];
- var data = {};
- var render_data = function render_data(data) {
- var fragments = [];
- var key = void 0;
- for (key in data) {
- if (data.hasOwnProperty(key)) {
- fragments.push("data-" + key + "=\"" + _this2.escapeForHtml(data[key]) + "\"");
- }
- }
- return fragments.length > 0 ? " " + fragments.join(" ") : "";
- };
- if (jsonChunk.fg) {
- if (use_classes) {
- classes.push(jsonChunk.fg + "-fg");
- if (jsonChunk.fg_truecolor !== null) {
- data["ansi-truecolor-fg"] = jsonChunk.fg_truecolor;
- jsonChunk.fg_truecolor = null;
- }
- } else {
- styles.push("color:rgb(" + jsonChunk.fg + ")");
- }
- }
- if (jsonChunk.bg) {
- if (use_classes) {
- classes.push(jsonChunk.bg + "-bg");
- if (jsonChunk.bg_truecolor !== null) {
- data["ansi-truecolor-bg"] = jsonChunk.bg_truecolor;
- jsonChunk.bg_truecolor = null;
- }
- } else {
- styles.push("background-color:rgb(" + jsonChunk.bg + ")");
- }
- }
- if (jsonChunk.decoration) {
- if (use_classes) {
- classes.push("ansi-" + jsonChunk.decoration);
- } else if (jsonChunk.decoration === "bold") {
- styles.push("font-weight:bold");
- } else if (jsonChunk.decoration === "dim") {
- styles.push("opacity:0.5");
- } else if (jsonChunk.decoration === "italic") {
- styles.push("font-style:italic");
- // underline and blink are treated bellow
- } else if (jsonChunk.decoration === "reverse") {
- styles.push("filter:invert(100%)");
- } else if (jsonChunk.decoration === "hidden") {
- styles.push("visibility:hidden");
- } else if (jsonChunk.decoration === "strikethrough") {
- styles.push("text-decoration:line-through");
- } else {
- styles.push("text-decoration:" + jsonChunk.decoration);
- }
- }
- if (use_classes) {
- return "<span class=\"" + classes.join(" ") + "\"" + render_data(data) + ">" + jsonChunk.content + "</span>";
- } else {
- return "<span style=\"" + styles.join(";") + "\"" + render_data(data) + ">" + jsonChunk.content + "</span>";
- }
- }
- }]);
- return Anser;
- }();
- ;
- module.exports = Anser;
|