Spaces:
Running
Running
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() | |