You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
4.2 KiB
176 lines
4.2 KiB
'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()
|
|
|