| 'use strict' |
| |
| module.exports = ansiHTML |
| |
| // Reference to https://github.com/sindresorhus/ansi-regex |
| var _regANSI = /(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/ |
| |
| var _defColors = { |
| reset: ['fff', '000'], // [FOREGROUD_COLOR, BACKGROUND_COLOR] |
| black: '000', |
| red: 'ff0000', |
| green: '209805', |
| yellow: 'e8bf03', |
| blue: '0000ff', |
| magenta: 'ff00ff', |
| cyan: '00ffee', |
| lightgrey: 'f0f0f0', |
| darkgrey: '888' |
| } |
| var _styles = { |
| 30: 'black', |
| 31: 'red', |
| 32: 'green', |
| 33: 'yellow', |
| 34: 'blue', |
| 35: 'magenta', |
| 36: 'cyan', |
| 37: 'lightgrey' |
| } |
| var _openTags = { |
| '1': 'font-weight:bold', // bold |
| '2': 'opacity:0.5', // dim |
| '3': '<i>', // italic |
| '4': '<u>', // underscore |
| '8': 'display:none', // hidden |
| '9': '<del>' // delete |
| } |
| var _closeTags = { |
| '23': '</i>', // reset italic |
| '24': '</u>', // reset underscore |
| '29': '</del>' // reset delete |
| } |
| |
| ;[0, 21, 22, 27, 28, 39, 49].forEach(function (n) { |
| _closeTags[n] = '</span>' |
| }) |
| |
| /** |
| * Converts text with ANSI color codes to HTML markup. |
| * @param {String} text |
| * @returns {*} |
| */ |
| function ansiHTML (text) { |
| // Returns the text if the string has no ANSI escape code. |
| if (!_regANSI.test(text)) { |
| return text |
| } |
| |
| // Cache opened sequence. |
| var ansiCodes = [] |
| // Replace with markup. |
| var ret = text.replace(/\033\[(\d+)*m/g, function (match, seq) { |
| var ot = _openTags[seq] |
| if (ot) { |
| // If current sequence has been opened, close it. |
| if (!!~ansiCodes.indexOf(seq)) { // eslint-disable-line no-extra-boolean-cast |
| ansiCodes.pop() |
| return '</span>' |
| } |
| // Open tag. |
| ansiCodes.push(seq) |
| return ot[0] === '<' ? ot : '<span style="' + ot + ';">' |
| } |
| |
| var ct = _closeTags[seq] |
| if (ct) { |
| // Pop sequence |
| ansiCodes.pop() |
| return ct |
| } |
| return '' |
| }) |
| |
| // Make sure tags are closed. |
| var l = ansiCodes.length |
| ;(l > 0) && (ret += Array(l + 1).join('</span>')) |
| |
| return ret |
| } |
| |
| /** |
| * Customize colors. |
| * @param {Object} colors reference to _defColors |
| */ |
| ansiHTML.setColors = function (colors) { |
| if (typeof colors !== 'object') { |
| throw new Error('`colors` parameter must be an Object.') |
| } |
| |
| var _finalColors = {} |
| for (var key in _defColors) { |
| var hex = colors.hasOwnProperty(key) ? colors[key] : null |
| if (!hex) { |
| _finalColors[key] = _defColors[key] |
| continue |
| } |
| if ('reset' === key) { |
| if (typeof hex === 'string') { |
| hex = [hex] |
| } |
| if (!Array.isArray(hex) || hex.length === 0 || hex.some(function (h) { |
| return typeof h !== 'string' |
| })) { |
| throw new Error('The value of `' + key + '` property must be an Array and each item could only be a hex string, e.g.: FF0000') |
| } |
| var defHexColor = _defColors[key] |
| if (!hex[0]) { |
| hex[0] = defHexColor[0] |
| } |
| if (hex.length === 1 || !hex[1]) { |
| hex = [hex[0]] |
| hex.push(defHexColor[1]) |
| } |
| |
| hex = hex.slice(0, 2) |
| } else if (typeof hex !== 'string') { |
| throw new Error('The value of `' + key + '` property must be a hex string, e.g.: FF0000') |
| } |
| _finalColors[key] = hex |
| } |
| _setTags(_finalColors) |
| } |
| |
| /** |
| * Reset colors. |
| */ |
| ansiHTML.reset = function () { |
| _setTags(_defColors) |
| } |
| |
| /** |
| * Expose tags, including open and close. |
| * @type {Object} |
| */ |
| ansiHTML.tags = {} |
| |
| if (Object.defineProperty) { |
| Object.defineProperty(ansiHTML.tags, 'open', { |
| get: function () { return _openTags } |
| }) |
| Object.defineProperty(ansiHTML.tags, 'close', { |
| get: function () { return _closeTags } |
| }) |
| } else { |
| ansiHTML.tags.open = _openTags |
| ansiHTML.tags.close = _closeTags |
| } |
| |
| function _setTags (colors) { |
| // reset all |
| _openTags['0'] = 'font-weight:normal;opacity:1;color:#' + colors.reset[0] + ';background:#' + colors.reset[1] |
| // inverse |
| _openTags['7'] = 'color:#' + colors.reset[1] + ';background:#' + colors.reset[0] |
| // dark grey |
| _openTags['90'] = 'color:#' + colors.darkgrey |
| |
| for (var code in _styles) { |
| var color = _styles[code] |
| var oriColor = colors[color] || '000' |
| _openTags[code] = 'color:#' + oriColor |
| code = parseInt(code) |
| _openTags[(code + 10).toString()] = 'background:#' + oriColor |
| } |
| } |
| |
| ansiHTML.reset() |