[6a3a178] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | module.exports = ansiHTML
|
---|
| 4 |
|
---|
| 5 | // Reference to https://github.com/sindresorhus/ansi-regex
|
---|
| 6 | var _regANSI = /(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/
|
---|
| 7 |
|
---|
| 8 | var _defColors = {
|
---|
| 9 | reset: ['fff', '000'], // [FOREGROUD_COLOR, BACKGROUND_COLOR]
|
---|
| 10 | black: '000',
|
---|
| 11 | red: 'ff0000',
|
---|
| 12 | green: '209805',
|
---|
| 13 | yellow: 'e8bf03',
|
---|
| 14 | blue: '0000ff',
|
---|
| 15 | magenta: 'ff00ff',
|
---|
| 16 | cyan: '00ffee',
|
---|
| 17 | lightgrey: 'f0f0f0',
|
---|
| 18 | darkgrey: '888'
|
---|
| 19 | }
|
---|
| 20 | var _styles = {
|
---|
| 21 | 30: 'black',
|
---|
| 22 | 31: 'red',
|
---|
| 23 | 32: 'green',
|
---|
| 24 | 33: 'yellow',
|
---|
| 25 | 34: 'blue',
|
---|
| 26 | 35: 'magenta',
|
---|
| 27 | 36: 'cyan',
|
---|
| 28 | 37: 'lightgrey'
|
---|
| 29 | }
|
---|
| 30 | var _openTags = {
|
---|
| 31 | '1': 'font-weight:bold', // bold
|
---|
| 32 | '2': 'opacity:0.5', // dim
|
---|
| 33 | '3': '<i>', // italic
|
---|
| 34 | '4': '<u>', // underscore
|
---|
| 35 | '8': 'display:none', // hidden
|
---|
| 36 | '9': '<del>' // delete
|
---|
| 37 | }
|
---|
| 38 | var _closeTags = {
|
---|
| 39 | '23': '</i>', // reset italic
|
---|
| 40 | '24': '</u>', // reset underscore
|
---|
| 41 | '29': '</del>' // reset delete
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | ;[0, 21, 22, 27, 28, 39, 49].forEach(function (n) {
|
---|
| 45 | _closeTags[n] = '</span>'
|
---|
| 46 | })
|
---|
| 47 |
|
---|
| 48 | /**
|
---|
| 49 | * Converts text with ANSI color codes to HTML markup.
|
---|
| 50 | * @param {String} text
|
---|
| 51 | * @returns {*}
|
---|
| 52 | */
|
---|
| 53 | function ansiHTML (text) {
|
---|
| 54 | // Returns the text if the string has no ANSI escape code.
|
---|
| 55 | if (!_regANSI.test(text)) {
|
---|
| 56 | return text
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | // Cache opened sequence.
|
---|
| 60 | var ansiCodes = []
|
---|
| 61 | // Replace with markup.
|
---|
| 62 | var ret = text.replace(/\033\[(\d+)*m/g, function (match, seq) {
|
---|
| 63 | var ot = _openTags[seq]
|
---|
| 64 | if (ot) {
|
---|
| 65 | // If current sequence has been opened, close it.
|
---|
| 66 | if (!!~ansiCodes.indexOf(seq)) { // eslint-disable-line no-extra-boolean-cast
|
---|
| 67 | ansiCodes.pop()
|
---|
| 68 | return '</span>'
|
---|
| 69 | }
|
---|
| 70 | // Open tag.
|
---|
| 71 | ansiCodes.push(seq)
|
---|
| 72 | return ot[0] === '<' ? ot : '<span style="' + ot + ';">'
|
---|
| 73 | }
|
---|
| 74 |
|
---|
| 75 | var ct = _closeTags[seq]
|
---|
| 76 | if (ct) {
|
---|
| 77 | // Pop sequence
|
---|
| 78 | ansiCodes.pop()
|
---|
| 79 | return ct
|
---|
| 80 | }
|
---|
| 81 | return ''
|
---|
| 82 | })
|
---|
| 83 |
|
---|
| 84 | // Make sure tags are closed.
|
---|
| 85 | var l = ansiCodes.length
|
---|
| 86 | ;(l > 0) && (ret += Array(l + 1).join('</span>'))
|
---|
| 87 |
|
---|
| 88 | return ret
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | /**
|
---|
| 92 | * Customize colors.
|
---|
| 93 | * @param {Object} colors reference to _defColors
|
---|
| 94 | */
|
---|
| 95 | ansiHTML.setColors = function (colors) {
|
---|
| 96 | if (typeof colors !== 'object') {
|
---|
| 97 | throw new Error('`colors` parameter must be an Object.')
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | var _finalColors = {}
|
---|
| 101 | for (var key in _defColors) {
|
---|
| 102 | var hex = colors.hasOwnProperty(key) ? colors[key] : null
|
---|
| 103 | if (!hex) {
|
---|
| 104 | _finalColors[key] = _defColors[key]
|
---|
| 105 | continue
|
---|
| 106 | }
|
---|
| 107 | if ('reset' === key) {
|
---|
| 108 | if (typeof hex === 'string') {
|
---|
| 109 | hex = [hex]
|
---|
| 110 | }
|
---|
| 111 | if (!Array.isArray(hex) || hex.length === 0 || hex.some(function (h) {
|
---|
| 112 | return typeof h !== 'string'
|
---|
| 113 | })) {
|
---|
| 114 | throw new Error('The value of `' + key + '` property must be an Array and each item could only be a hex string, e.g.: FF0000')
|
---|
| 115 | }
|
---|
| 116 | var defHexColor = _defColors[key]
|
---|
| 117 | if (!hex[0]) {
|
---|
| 118 | hex[0] = defHexColor[0]
|
---|
| 119 | }
|
---|
| 120 | if (hex.length === 1 || !hex[1]) {
|
---|
| 121 | hex = [hex[0]]
|
---|
| 122 | hex.push(defHexColor[1])
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | hex = hex.slice(0, 2)
|
---|
| 126 | } else if (typeof hex !== 'string') {
|
---|
| 127 | throw new Error('The value of `' + key + '` property must be a hex string, e.g.: FF0000')
|
---|
| 128 | }
|
---|
| 129 | _finalColors[key] = hex
|
---|
| 130 | }
|
---|
| 131 | _setTags(_finalColors)
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | /**
|
---|
| 135 | * Reset colors.
|
---|
| 136 | */
|
---|
| 137 | ansiHTML.reset = function () {
|
---|
| 138 | _setTags(_defColors)
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 | /**
|
---|
| 142 | * Expose tags, including open and close.
|
---|
| 143 | * @type {Object}
|
---|
| 144 | */
|
---|
| 145 | ansiHTML.tags = {}
|
---|
| 146 |
|
---|
| 147 | if (Object.defineProperty) {
|
---|
| 148 | Object.defineProperty(ansiHTML.tags, 'open', {
|
---|
| 149 | get: function () { return _openTags }
|
---|
| 150 | })
|
---|
| 151 | Object.defineProperty(ansiHTML.tags, 'close', {
|
---|
| 152 | get: function () { return _closeTags }
|
---|
| 153 | })
|
---|
| 154 | } else {
|
---|
| 155 | ansiHTML.tags.open = _openTags
|
---|
| 156 | ansiHTML.tags.close = _closeTags
|
---|
| 157 | }
|
---|
| 158 |
|
---|
| 159 | function _setTags (colors) {
|
---|
| 160 | // reset all
|
---|
| 161 | _openTags['0'] = 'font-weight:normal;opacity:1;color:#' + colors.reset[0] + ';background:#' + colors.reset[1]
|
---|
| 162 | // inverse
|
---|
| 163 | _openTags['7'] = 'color:#' + colors.reset[1] + ';background:#' + colors.reset[0]
|
---|
| 164 | // dark grey
|
---|
| 165 | _openTags['90'] = 'color:#' + colors.darkgrey
|
---|
| 166 |
|
---|
| 167 | for (var code in _styles) {
|
---|
| 168 | var color = _styles[code]
|
---|
| 169 | var oriColor = colors[color] || '000'
|
---|
| 170 | _openTags[code] = 'color:#' + oriColor
|
---|
| 171 | code = parseInt(code)
|
---|
| 172 | _openTags[(code + 10).toString()] = 'background:#' + oriColor
|
---|
| 173 | }
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | ansiHTML.reset()
|
---|