177 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'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()
 |