react-scripts
Version:
Configuration and scripts for Create React App.
169 lines (153 loc) • 4.02 kB
JavaScript
module.exports = ansiHTML;
// Reference to https://github.com/sindresorhus/ansi-regex
var re_ansi = /(?:(?:\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.8', // 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 (!re_ansi.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)) {
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 = {
get open() {
return _openTags;
},
get close() {
return _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();