UNPKG

4.26 kBJavaScriptView Raw
1'use strict'
2
3module.exports = ansiHTML
4
5// Reference to https://github.com/sindresorhus/ansi-regex
6var _regANSI = /(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/
7
8var _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}
20var _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}
30var _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}
38var _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 */
53function 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 */
95ansiHTML.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 */
137ansiHTML.reset = function () {
138 _setTags(_defColors)
139}
140
141/**
142 * Expose tags, including open and close.
143 * @type {Object}
144 */
145ansiHTML.tags = {}
146
147if (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
159function _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
176ansiHTML.reset()