UNPKG

8.62 kBtext/coffeescriptView Raw
1
2#-----------------------------------------------------------------------------------------------------------
3rgb_hex_by_vt100_colorcode =
4 # Primary 3-bit 8 colors. Unique representation!
5 '0': '000000'
6 '1': '800000'
7 '2': '008000'
8 '3': '808000'
9 '4': '000080'
10 '5': '800080'
11 '6': '008080'
12 '7': 'c0c0c0'
13 # Equivalent "bright" versions of original 8 colors.
14 '8': '808080'
15 '9': 'ff0000'
16 '10': '00ff00'
17 '11': 'ffff00'
18 '12': '0000ff'
19 '13': 'ff00ff'
20 '14': '00ffff'
21 '15': 'ffffff'
22 # Strictly ascending.
23 '16': '000000'
24 '17': '00005f'
25 '18': '000087'
26 '19': '0000af'
27 '20': '0000d7'
28 '21': '0000ff'
29 '22': '005f00'
30 '23': '005f5f'
31 '24': '005f87'
32 '25': '005faf'
33 '26': '005fd7'
34 '27': '005fff'
35 '28': '008700'
36 '29': '00875f'
37 '30': '008787'
38 '31': '0087af'
39 '32': '0087d7'
40 '33': '0087ff'
41 '34': '00af00'
42 '35': '00af5f'
43 '36': '00af87'
44 '37': '00afaf'
45 '38': '00afd7'
46 '39': '00afff'
47 '40': '00d700'
48 '41': '00d75f'
49 '42': '00d787'
50 '43': '00d7af'
51 '44': '00d7d7'
52 '45': '00d7ff'
53 '46': '00ff00'
54 '47': '00ff5f'
55 '48': '00ff87'
56 '49': '00ffaf'
57 '50': '00ffd7'
58 '51': '00ffff'
59 '52': '5f0000'
60 '53': '5f005f'
61 '54': '5f0087'
62 '55': '5f00af'
63 '56': '5f00d7'
64 '57': '5f00ff'
65 '58': '5f5f00'
66 '59': '5f5f5f'
67 '60': '5f5f87'
68 '61': '5f5faf'
69 '62': '5f5fd7'
70 '63': '5f5fff'
71 '64': '5f8700'
72 '65': '5f875f'
73 '66': '5f8787'
74 '67': '5f87af'
75 '68': '5f87d7'
76 '69': '5f87ff'
77 '70': '5faf00'
78 '71': '5faf5f'
79 '72': '5faf87'
80 '73': '5fafaf'
81 '74': '5fafd7'
82 '75': '5fafff'
83 '76': '5fd700'
84 '77': '5fd75f'
85 '78': '5fd787'
86 '79': '5fd7af'
87 '80': '5fd7d7'
88 '81': '5fd7ff'
89 '82': '5fff00'
90 '83': '5fff5f'
91 '84': '5fff87'
92 '85': '5fffaf'
93 '86': '5fffd7'
94 '87': '5fffff'
95 '88': '870000'
96 '89': '87005f'
97 '90': '870087'
98 '91': '8700af'
99 '92': '8700d7'
100 '93': '8700ff'
101 '94': '875f00'
102 '95': '875f5f'
103 '96': '875f87'
104 '97': '875faf'
105 '98': '875fd7'
106 '99': '875fff'
107 '100': '878700'
108 '101': '87875f'
109 '102': '878787'
110 '103': '8787af'
111 '104': '8787d7'
112 '105': '8787ff'
113 '106': '87af00'
114 '107': '87af5f'
115 '108': '87af87'
116 '109': '87afaf'
117 '110': '87afd7'
118 '111': '87afff'
119 '112': '87d700'
120 '113': '87d75f'
121 '114': '87d787'
122 '115': '87d7af'
123 '116': '87d7d7'
124 '117': '87d7ff'
125 '118': '87ff00'
126 '119': '87ff5f'
127 '120': '87ff87'
128 '121': '87ffaf'
129 '122': '87ffd7'
130 '123': '87ffff'
131 '124': 'af0000'
132 '125': 'af005f'
133 '126': 'af0087'
134 '127': 'af00af'
135 '128': 'af00d7'
136 '129': 'af00ff'
137 '130': 'af5f00'
138 '131': 'af5f5f'
139 '132': 'af5f87'
140 '133': 'af5faf'
141 '134': 'af5fd7'
142 '135': 'af5fff'
143 '136': 'af8700'
144 '137': 'af875f'
145 '138': 'af8787'
146 '139': 'af87af'
147 '140': 'af87d7'
148 '141': 'af87ff'
149 '142': 'afaf00'
150 '143': 'afaf5f'
151 '144': 'afaf87'
152 '145': 'afafaf'
153 '146': 'afafd7'
154 '147': 'afafff'
155 '148': 'afd700'
156 '149': 'afd75f'
157 '150': 'afd787'
158 '151': 'afd7af'
159 '152': 'afd7d7'
160 '153': 'afd7ff'
161 '154': 'afff00'
162 '155': 'afff5f'
163 '156': 'afff87'
164 '157': 'afffaf'
165 '158': 'afffd7'
166 '159': 'afffff'
167 '160': 'd70000'
168 '161': 'd7005f'
169 '162': 'd70087'
170 '163': 'd700af'
171 '164': 'd700d7'
172 '165': 'd700ff'
173 '166': 'd75f00'
174 '167': 'd75f5f'
175 '168': 'd75f87'
176 '169': 'd75faf'
177 '170': 'd75fd7'
178 '171': 'd75fff'
179 '172': 'd78700'
180 '173': 'd7875f'
181 '174': 'd78787'
182 '175': 'd787af'
183 '176': 'd787d7'
184 '177': 'd787ff'
185 '178': 'd7af00'
186 '179': 'd7af5f'
187 '180': 'd7af87'
188 '181': 'd7afaf'
189 '182': 'd7afd7'
190 '183': 'd7afff'
191 '184': 'd7d700'
192 '185': 'd7d75f'
193 '186': 'd7d787'
194 '187': 'd7d7af'
195 '188': 'd7d7d7'
196 '189': 'd7d7ff'
197 '190': 'd7ff00'
198 '191': 'd7ff5f'
199 '192': 'd7ff87'
200 '193': 'd7ffaf'
201 '194': 'd7ffd7'
202 '195': 'd7ffff'
203 '196': 'ff0000'
204 '197': 'ff005f'
205 '198': 'ff0087'
206 '199': 'ff00af'
207 '200': 'ff00d7'
208 '201': 'ff00ff'
209 '202': 'ff5f00'
210 '203': 'ff5f5f'
211 '204': 'ff5f87'
212 '205': 'ff5faf'
213 '206': 'ff5fd7'
214 '207': 'ff5fff'
215 '208': 'ff8700'
216 '209': 'ff875f'
217 '210': 'ff8787'
218 '211': 'ff87af'
219 '212': 'ff87d7'
220 '213': 'ff87ff'
221 '214': 'ffaf00'
222 '215': 'ffaf5f'
223 '216': 'ffaf87'
224 '217': 'ffafaf'
225 '218': 'ffafd7'
226 '219': 'ffafff'
227 '220': 'ffd700'
228 '221': 'ffd75f'
229 '222': 'ffd787'
230 '223': 'ffd7af'
231 '224': 'ffd7d7'
232 '225': 'ffd7ff'
233 '226': 'ffff00'
234 '227': 'ffff5f'
235 '228': 'ffff87'
236 '229': 'ffffaf'
237 '230': 'ffffd7'
238 '231': 'ffffff'
239 # Gray-scale range
240 '232': '080808'
241 '233': '121212'
242 '234': '1c1c1c'
243 '235': '262626'
244 '236': '303030'
245 '237': '3a3a3a'
246 '238': '444444'
247 '239': '4e4e4e'
248 '240': '585858'
249 '241': '626262'
250 '242': '6c6c6c'
251 '243': '767676'
252 '244': '808080'
253 '245': '8a8a8a'
254 '246': '949494'
255 '247': '9e9e9e'
256 '248': 'a8a8a8'
257 '249': 'b2b2b2'
258 '250': 'bcbcbc'
259 '251': 'c6c6c6'
260 '252': 'd0d0d0'
261 '253': 'dadada'
262 '254': 'e4e4e4'
263 '255': 'eeeeee'
264
265
266#-----------------------------------------------------------------------------------------------------------
267ansi_vt100_cc_matcher = /(?:\x1b\x5b)([\?=;0-9]*?)([ABCDHJKfhlmnpsu])/g
268
269#-----------------------------------------------------------------------------------------------------------
270@analyze = ( text ) ->
271 ### Parse ANSI control codes out of `text` and return a list of alternating text / opcode chunks; the
272 first element of the list and all elements with even indexes will represent (possibly empty) literal
273 texts, while elements with even indexes will be sub-lists representing control codes. Each control
274 code looks like `[ 'm', 38, 5, 199 ]` or `[ 'm', 0 ]`, with the opcode letter coming first, followed
275 by the integer parameters.
276
277 Adapted from https://github.com/atdt/escapes.js/blob/master/escapes.js ###
278 R = []
279 #.........................................................................................................
280 loop
281 position = ansi_vt100_cc_matcher.lastIndex
282 match = ansi_vt100_cc_matcher.exec text
283 if match isnt null
284 R.push text.slice position, match.index
285 parameters = [ match[ 2 ], ]
286 parameters.push parseInt x, 10 for x in match[ 1 ].split ';'
287 R.push parameters
288 break if ansi_vt100_cc_matcher.lastIndex is 0
289 #.........................................................................................................
290 R.push text.slice position if position < text.length
291 return R
292
293#-----------------------------------------------------------------------------------------------------------
294@as_html = ( text, options ) ->
295 return ( @_as_html text, options ).join ''
296
297#-----------------------------------------------------------------------------------------------------------
298@_as_html = ( text, options ) ->
299 is_ansicode = yes
300 R = []
301 open_span_count = 0
302 css_prefix = if options? and options[ 'css-prefix' ]? then options[ 'css-prefix' ] else 'ansi'
303 vt100_reset = css_prefix.concat '-m-0'
304 vt100_clear = css_prefix.concat '-K'
305 #.........................................................................................................
306 for chunk in @analyze text
307 is_ansicode = not is_ansicode
308 if is_ansicode
309 css_class = css_prefix.concat '-', chunk.join '-'
310 if css_class is vt100_reset or css_class is vt100_clear
311 R.push '</span>'
312 open_span_count -= 1
313 else
314 R.push "<span class='#{css_class}'>"
315 open_span_count += 1
316 continue
317 else
318 ### TAINT must escape ###
319 R.push chunk
320 #.........................................................................................................
321 if open_span_count > 0 and ( options? and options[ 'close-spans' ] )
322 R.push '</span>' for n in [ 0 ... open_span_count ]
323 #.........................................................................................................
324 return R
325
326#-----------------------------------------------------------------------------------------------------------
327@get_css_source = ( options ) ->
328 R = []
329 css_prefix = if options? and options[ 'css-prefix' ]? then options[ 'css-prefix' ] else 'ansi'
330 for color_code, rgb_hex of rgb_hex_by_vt100_colorcode
331 R.push ".#{css_prefix}-m-38-5-#{color_code} { color: #{rgb_hex}; }"
332 #.........................................................................................................
333 return R.join '\n'
334
335
336