@softwarefactory-project/re-ansi 0.2.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,9 +7,11 @@ Ansi code to HTML
7
7
  re-ansi supports:
8
8
 
9
9
  * Cursor movement: `\n`, line erase and `\r` line erase
10
- * SGR parameter: italic and bold
10
+ * SGR parameter: italic, bold, underline and line-through
11
11
  * 3/4 bits [color code][ansi-color-code]
12
12
 
13
+ re-ansi removes styles on new lines, so that a `<br />` can't be nested inside `<span style>` elements.
14
+
13
15
  For details, see the `AnsiCode.parse` function.
14
16
 
15
17
  ## Install
@@ -79,17 +81,32 @@ Make sure to read about [React][reason-react] and [Reason][rescript-lang] too.
79
81
 
80
82
  ## Changes
81
83
 
84
+ ### 0.5.0
85
+
86
+ - Add support for `[m` and `[K`.
87
+
88
+ ### 0.4.0
89
+
90
+ - Add support for underline and line-through text decoration.
91
+ - Add support for lighter font style.
92
+ - Add initial support for color reset.
93
+
94
+ ### 0.3.0
95
+
96
+ - Add unique keys to react list elements.
97
+ - Create a href elements for http links.
98
+
82
99
  ### 0.2.1
83
100
 
84
- - Fix Ansi.parse to return the full document instead of the last line
101
+ - Fix Ansi.parse to return the full document instead of the last line.
85
102
 
86
103
  ### 0.2.0
87
104
 
88
- - Fix a recursion limit in Ansi.parse for log bigger than 10MB
105
+ - Fix a recursion limit in Ansi.parse for log bigger than 10MB.
89
106
 
90
107
  ### 0.1.3
91
108
 
92
- - Initial release
109
+ - Initial release.
93
110
 
94
111
  [ansi-color-code]: https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit
95
112
  [reason-react]: https://reasonml.github.io/reason-react/docs/en/components
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwarefactory-project/re-ansi",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
4
4
  "description": "ANSI code to HTML",
5
5
  "files": ["README.md", "LICENSE", "bsconfig.json", "src"],
6
6
  "main": "./src/Ansi.bs.js",
package/src/Ansi.bs.js CHANGED
@@ -23,8 +23,10 @@ function fourBitColors(code) {
23
23
  case 6 :
24
24
  return "cyan";
25
25
  case 8 :
26
+ console.log("Unknown color value:", code);
27
+ return ;
26
28
  case 9 :
27
- break;
29
+ return "initial";
28
30
  case 10 :
29
31
  return "grey";
30
32
  case 11 :
@@ -43,10 +45,9 @@ function fourBitColors(code) {
43
45
  case 17 :
44
46
  return "white";
45
47
  default:
46
-
48
+ console.log("Unknown color value:", code);
49
+ return ;
47
50
  }
48
- console.log("Unknown color value:", code);
49
-
50
51
  }
51
52
 
52
53
  function combine(css1, css2) {
@@ -65,6 +66,12 @@ function addStyle(fontStyle) {
65
66
  };
66
67
  }
67
68
 
69
+ function addDecoration(textDecoration) {
70
+ return {
71
+ textDecoration: textDecoration
72
+ };
73
+ }
74
+
68
75
  function int_of_cp(c) {
69
76
  return c - 48 | 0;
70
77
  }
@@ -129,18 +136,29 @@ function getFontStyle(fontMode) {
129
136
  return /* FontStyle */{
130
137
  _0: addWeight("bold")
131
138
  };
139
+ case 2 :
140
+ return /* FontStyle */{
141
+ _0: addWeight("lighter")
142
+ };
132
143
  case 3 :
133
144
  return /* FontStyle */{
134
145
  _0: addStyle("italic")
135
146
  };
136
- case 2 :
137
147
  case 4 :
138
- case 5 :
139
- case 6 :
140
- return ;
148
+ return /* FontStyle */{
149
+ _0: addDecoration("underline")
150
+ };
141
151
  case 0 :
142
152
  case 7 :
143
153
  return /* Regular */0;
154
+ case 5 :
155
+ case 6 :
156
+ case 8 :
157
+ return ;
158
+ case 9 :
159
+ return /* FontStyle */{
160
+ _0: addDecoration("line-through")
161
+ };
144
162
  default:
145
163
  return ;
146
164
  }
@@ -163,480 +181,539 @@ var FontCss = {
163
181
  get: get$1
164
182
  };
165
183
 
184
+ var linkRe = /^(http(s)?:\/\/[^\s]+)/;
185
+
186
+ function get$2(txt) {
187
+ return Belt_Option.getWithDefault(Belt_Option.flatMap(Caml_option.null_to_opt(linkRe.exec(txt)), (function (res) {
188
+ return Belt_Option.flatMap(res.length !== 3 ? undefined : Caml_option.nullable_to_opt(res[0]), (function (url) {
189
+ return [
190
+ url.length,
191
+ {
192
+ TAG: /* HRef */0,
193
+ _0: url
194
+ }
195
+ ];
196
+ }));
197
+ })), [
198
+ 1,
199
+ undefined
200
+ ]);
201
+ }
202
+
203
+ var HttpLink = {
204
+ linkRe: linkRe,
205
+ get: get$2
206
+ };
207
+
166
208
  function parse(txt, pos) {
167
209
  var match = txt.codePointAt(pos);
210
+ var exit = 0;
168
211
  if (match === undefined) {
169
212
  return [
170
213
  0,
171
214
  undefined
172
215
  ];
173
216
  }
174
- var switcher = match - 13 | 0;
175
- if (switcher > 14 || switcher < 0) {
176
- if (switcher !== -3) {
177
- return [
178
- 0,
179
- undefined
180
- ];
181
- } else {
217
+ if (match >= 14) {
218
+ if (match !== 27) {
219
+ if (match !== 104) {
220
+ return [
221
+ 0,
222
+ undefined
223
+ ];
224
+ }
225
+ var func = function (param, param$1) {
226
+ return param$1.slice(pos, param);
227
+ };
228
+ return get$2(Curry._2(func, 512, txt));
229
+ }
230
+ exit = 1;
231
+ } else {
232
+ if (match === 10) {
182
233
  return [
183
234
  1,
184
235
  /* CarriageReturn */2
185
236
  ];
186
237
  }
187
- }
188
- if (!(switcher > 13 || switcher < 1)) {
189
- return [
190
- 0,
191
- undefined
192
- ];
193
- }
194
- var cps = function (_idx, _acc) {
195
- while(true) {
196
- var acc = _acc;
197
- var idx = _idx;
198
- var match = idx > 10;
199
- var match$1 = txt.codePointAt(pos + idx | 0);
200
- if (match) {
201
- return acc;
202
- }
203
- if (match$1 === undefined) {
204
- return acc;
205
- }
206
- if (match$1 === 109) {
207
- return acc;
208
- }
209
- _acc = Belt_List.add(acc, match$1);
210
- _idx = idx + 1 | 0;
211
- continue ;
212
- };
213
- };
214
- var codePoints = Belt_List.reverse(cps(1, /* [] */0));
215
- var length = Belt_List.length(codePoints) + 2 | 0;
216
- var exit = 0;
217
- var colorMode;
218
- var colorValue;
219
- var xs;
220
- var colorMode$1;
221
- var colorValue$1;
222
- var style;
223
- var style$1;
224
- var cm1;
225
- var cv1;
226
- var cm2;
227
- var cv2;
228
- var xs$1;
229
- if (!codePoints) {
230
- return [
231
- 1,
232
- undefined
233
- ];
234
- }
235
- var match$1 = codePoints.hd;
236
- if (match$1 !== 10) {
237
- if (match$1 !== 91) {
238
+ if (match < 13) {
238
239
  return [
239
- 1,
240
+ 0,
240
241
  undefined
241
242
  ];
242
243
  }
243
- var match$2 = codePoints.tl;
244
- if (!match$2) {
244
+ exit = 1;
245
+ }
246
+ if (exit === 1) {
247
+ var cps = function (_idx, _acc) {
248
+ while(true) {
249
+ var acc = _acc;
250
+ var idx = _idx;
251
+ var match = idx > 10;
252
+ var match$1 = txt.codePointAt(pos + idx | 0);
253
+ if (match) {
254
+ return acc;
255
+ }
256
+ if (match$1 === undefined) {
257
+ return acc;
258
+ }
259
+ if (match$1 === 109) {
260
+ return acc;
261
+ }
262
+ _acc = Belt_List.add(acc, match$1);
263
+ _idx = idx + 1 | 0;
264
+ continue ;
265
+ };
266
+ };
267
+ var codePoints = Belt_List.reverse(cps(1, /* [] */0));
268
+ var length = Belt_List.length(codePoints) + 2 | 0;
269
+ var exit$1 = 0;
270
+ var colorMode;
271
+ var colorValue;
272
+ var xs;
273
+ var colorMode$1;
274
+ var colorValue$1;
275
+ var style;
276
+ var style$1;
277
+ var cm1;
278
+ var cv1;
279
+ var cm2;
280
+ var cv2;
281
+ var xs$1;
282
+ if (!codePoints) {
245
283
  return [
246
284
  1,
247
285
  undefined
248
286
  ];
249
287
  }
250
- var style$2 = match$2.hd;
251
- var exit$1 = 0;
252
- if (style$2 !== 48) {
253
- if (style$2 !== 49) {
254
- exit$1 = 4;
255
- } else {
256
- var match$3 = match$2.tl;
257
- if (match$3) {
258
- var match$4 = match$3.tl;
259
- if (match$4 && !match$4.tl) {
260
- colorMode = match$3.hd;
261
- colorValue = match$4.hd;
262
- xs = codePoints;
263
- exit = 1;
264
- } else {
265
- exit$1 = 4;
266
- }
267
- } else {
268
- exit$1 = 4;
269
- }
288
+ var match$1 = codePoints.hd;
289
+ if (match$1 !== 10) {
290
+ if (match$1 !== 91) {
291
+ return [
292
+ 1,
293
+ undefined
294
+ ];
270
295
  }
271
- } else {
272
- var match$5 = match$2.tl;
273
- if (!match$5) {
296
+ var match$2 = codePoints.tl;
297
+ if (!match$2) {
274
298
  return [
275
299
  length,
276
300
  /* Clear */0
277
301
  ];
278
302
  }
279
- var style$3 = match$5.hd;
303
+ var style$2 = match$2.hd;
280
304
  var exit$2 = 0;
281
- if (style$3 !== 48) {
282
- if (style$3 === 75) {
305
+ var exit$3 = 0;
306
+ var match$3 = match$2.tl;
307
+ if (match$3) {
308
+ if (match$3.hd === 75) {
283
309
  return [
284
310
  4,
285
311
  /* EraseLine */1
286
312
  ];
287
313
  }
288
- exit$2 = 5;
314
+ exit$3 = 6;
289
315
  } else {
290
- if (!match$5.tl) {
291
- return [
292
- length,
293
- /* Clear */0
294
- ];
295
- }
296
- exit$2 = 5;
316
+ exit$3 = 6;
297
317
  }
298
- if (exit$2 === 5) {
299
- var match$6 = match$5.tl;
300
- if (match$6 && match$6.hd === 59) {
301
- var match$7 = match$6.tl;
302
- if (!match$7) {
303
- return [
304
- 1,
305
- undefined
306
- ];
307
- }
308
- var match$8 = match$7.tl;
309
- if (match$8) {
310
- var match$9 = match$8.tl;
311
- var colorValue$2 = match$8.hd;
312
- var colorMode$2 = match$7.hd;
313
- if (match$9) {
314
- if (match$9.hd !== 59) {
315
- exit$1 = 4;
318
+ if (exit$3 === 6) {
319
+ var switcher = style$2 - 48 | 0;
320
+ if (switcher === 0 || switcher === 1) {
321
+ if (switcher !== 0) {
322
+ var match$4 = match$2.tl;
323
+ if (match$4) {
324
+ var match$5 = match$4.tl;
325
+ if (match$5 && !match$5.tl) {
326
+ colorMode = match$4.hd;
327
+ colorValue = match$5.hd;
328
+ xs = codePoints;
329
+ exit$1 = 2;
316
330
  } else {
317
- var match$10 = match$9.tl;
318
- if (!match$10) {
331
+ exit$2 = 5;
332
+ }
333
+ } else {
334
+ exit$2 = 5;
335
+ }
336
+ } else {
337
+ var match$6 = match$2.tl;
338
+ if (!match$6) {
339
+ return [
340
+ length,
341
+ /* Clear */0
342
+ ];
343
+ }
344
+ var style$3 = match$6.hd;
345
+ var exit$4 = 0;
346
+ if (style$3 !== 48) {
347
+ exit$4 = 7;
348
+ } else {
349
+ if (!match$6.tl) {
350
+ return [
351
+ length,
352
+ /* Clear */0
353
+ ];
354
+ }
355
+ exit$4 = 7;
356
+ }
357
+ if (exit$4 === 7) {
358
+ var match$7 = match$6.tl;
359
+ if (match$7 && match$7.hd === 59) {
360
+ var match$8 = match$7.tl;
361
+ if (!match$8) {
319
362
  return [
320
363
  1,
321
364
  undefined
322
365
  ];
323
366
  }
324
- var cm2$1 = match$10.hd;
325
- var match$11 = match$10.tl;
326
- if (match$11) {
327
- if (match$11.tl) {
328
- if (cm2$1 !== 49) {
329
- exit$1 = 4;
367
+ var match$9 = match$8.tl;
368
+ if (match$9) {
369
+ var match$10 = match$9.tl;
370
+ var colorValue$2 = match$9.hd;
371
+ var colorMode$2 = match$8.hd;
372
+ if (match$10) {
373
+ if (match$10.hd !== 59) {
374
+ exit$2 = 5;
330
375
  } else {
331
- var match$12 = match$10.tl;
332
- var match$13 = match$12.tl;
333
- if (match$13.tl) {
376
+ var match$11 = match$10.tl;
377
+ if (!match$11) {
334
378
  return [
335
379
  1,
336
380
  undefined
337
381
  ];
338
382
  }
339
- style$1 = style$3;
340
- cm1 = colorMode$2;
341
- cv1 = colorValue$2;
342
- cm2 = match$12.hd;
343
- cv2 = match$13.hd;
344
- xs$1 = codePoints;
345
- exit = 3;
383
+ var cm2$1 = match$11.hd;
384
+ var match$12 = match$11.tl;
385
+ if (match$12) {
386
+ if (match$12.tl) {
387
+ if (cm2$1 !== 49) {
388
+ exit$2 = 5;
389
+ } else {
390
+ var match$13 = match$11.tl;
391
+ var match$14 = match$13.tl;
392
+ if (match$14.tl) {
393
+ return [
394
+ 1,
395
+ undefined
396
+ ];
397
+ }
398
+ style$1 = style$3;
399
+ cm1 = colorMode$2;
400
+ cv1 = colorValue$2;
401
+ cm2 = match$13.hd;
402
+ cv2 = match$14.hd;
403
+ xs$1 = codePoints;
404
+ exit$1 = 4;
405
+ }
406
+ } else {
407
+ style$1 = style$3;
408
+ cm1 = colorMode$2;
409
+ cv1 = colorValue$2;
410
+ cm2 = cm2$1;
411
+ cv2 = match$12.hd;
412
+ xs$1 = codePoints;
413
+ exit$1 = 4;
414
+ }
415
+ } else {
416
+ exit$2 = 5;
417
+ }
346
418
  }
347
419
  } else {
348
- style$1 = style$3;
349
- cm1 = colorMode$2;
350
- cv1 = colorValue$2;
351
- cm2 = cm2$1;
352
- cv2 = match$11.hd;
353
- xs$1 = codePoints;
354
- exit = 3;
420
+ colorMode$1 = colorMode$2;
421
+ colorValue$1 = colorValue$2;
422
+ style = style$3;
423
+ exit$1 = 3;
355
424
  }
356
425
  } else {
357
- exit$1 = 4;
426
+ exit$2 = 5;
358
427
  }
428
+ } else {
429
+ exit$2 = 5;
359
430
  }
360
- } else {
361
- colorMode$1 = colorMode$2;
362
- colorValue$1 = colorValue$2;
363
- style = style$3;
364
- exit = 2;
365
431
  }
366
- } else {
367
- exit$1 = 4;
432
+
368
433
  }
369
434
  } else {
370
- exit$1 = 4;
371
- }
372
- }
373
-
374
- }
375
- if (exit$1 === 4) {
376
- var match$14 = match$2.tl;
377
- if (!match$14) {
378
- return [
379
- length,
380
- Belt_Option.flatMap(get$1(style$2), (function (style) {
381
- return /* Style */{
382
- _0: style
383
- };
384
- }))
385
- ];
386
- }
387
- var colorValue$3 = match$14.hd;
388
- var exit$3 = 0;
389
- var match$15 = match$14.tl;
390
- if (match$15) {
391
- if (match$15.hd !== 59) {
392
- exit$3 = 5;
393
- } else {
394
- var match$16 = match$15.tl;
395
- if (!match$16) {
435
+ if (switcher === 27) {
396
436
  return [
397
- 1,
398
- undefined
437
+ 3,
438
+ /* EraseLine */1
399
439
  ];
400
440
  }
401
- if (match$16.tl) {
402
- exit$3 = 5;
403
- } else {
404
- colorMode$1 = style$2;
405
- colorValue$1 = colorValue$3;
406
- style = match$16.hd;
407
- exit = 2;
408
- }
441
+ exit$2 = 5;
409
442
  }
410
- } else {
411
- colorMode = style$2;
412
- colorValue = colorValue$3;
413
- xs = codePoints;
414
- exit = 1;
415
443
  }
416
- if (exit$3 === 5) {
417
- if (colorValue$3 !== 59) {
418
- return [
419
- 1,
420
- undefined
421
- ];
422
- }
423
- var match$17 = match$14.tl;
424
- var match$18 = match$17.tl;
425
- if (!match$18) {
444
+ if (exit$2 === 5) {
445
+ var match$15 = match$2.tl;
446
+ if (!match$15) {
426
447
  return [
427
- 1,
428
- undefined
448
+ length,
449
+ Belt_Option.flatMap(get$1(style$2), (function (style) {
450
+ return {
451
+ TAG: /* Style */1,
452
+ _0: style
453
+ };
454
+ }))
429
455
  ];
430
456
  }
431
- var match$19 = match$18.tl;
432
- var colorValue$4 = match$18.hd;
433
- var colorMode$3 = match$17.hd;
434
- if (match$19) {
435
- if (match$19.hd !== 59) {
436
- return [
437
- 1,
438
- undefined
439
- ];
457
+ var colorValue$3 = match$15.hd;
458
+ var exit$5 = 0;
459
+ var match$16 = match$15.tl;
460
+ if (match$16) {
461
+ if (match$16.hd !== 59) {
462
+ exit$5 = 6;
463
+ } else {
464
+ var match$17 = match$16.tl;
465
+ if (!match$17) {
466
+ return [
467
+ 1,
468
+ undefined
469
+ ];
470
+ }
471
+ if (match$17.tl) {
472
+ exit$5 = 6;
473
+ } else {
474
+ colorMode$1 = style$2;
475
+ colorValue$1 = colorValue$3;
476
+ style = match$17.hd;
477
+ exit$1 = 3;
478
+ }
440
479
  }
441
- var match$20 = match$19.tl;
442
- if (!match$20) {
480
+ } else {
481
+ colorMode = style$2;
482
+ colorValue = colorValue$3;
483
+ xs = codePoints;
484
+ exit$1 = 2;
485
+ }
486
+ if (exit$5 === 6) {
487
+ if (colorValue$3 !== 59) {
443
488
  return [
444
489
  1,
445
490
  undefined
446
491
  ];
447
492
  }
448
- var cm2$2 = match$20.hd;
449
- var match$21 = match$20.tl;
450
- if (!match$21) {
493
+ var match$18 = match$15.tl;
494
+ var match$19 = match$18.tl;
495
+ if (!match$19) {
451
496
  return [
452
497
  1,
453
498
  undefined
454
499
  ];
455
500
  }
456
- if (match$21.tl) {
457
- if (cm2$2 !== 49) {
501
+ var match$20 = match$19.tl;
502
+ var colorValue$4 = match$19.hd;
503
+ var colorMode$3 = match$18.hd;
504
+ if (match$20) {
505
+ if (match$20.hd !== 59) {
458
506
  return [
459
507
  1,
460
508
  undefined
461
509
  ];
462
510
  }
463
- var match$22 = match$20.tl;
464
- var match$23 = match$22.tl;
465
- if (match$23.tl) {
511
+ var match$21 = match$20.tl;
512
+ if (!match$21) {
466
513
  return [
467
514
  1,
468
515
  undefined
469
516
  ];
470
517
  }
471
- style$1 = style$2;
472
- cm1 = colorMode$3;
473
- cv1 = colorValue$4;
474
- cm2 = match$22.hd;
475
- cv2 = match$23.hd;
476
- xs$1 = codePoints;
477
- exit = 3;
518
+ var cm2$2 = match$21.hd;
519
+ var match$22 = match$21.tl;
520
+ if (!match$22) {
521
+ return [
522
+ 1,
523
+ undefined
524
+ ];
525
+ }
526
+ if (match$22.tl) {
527
+ if (cm2$2 !== 49) {
528
+ return [
529
+ 1,
530
+ undefined
531
+ ];
532
+ }
533
+ var match$23 = match$21.tl;
534
+ var match$24 = match$23.tl;
535
+ if (match$24.tl) {
536
+ return [
537
+ 1,
538
+ undefined
539
+ ];
540
+ }
541
+ style$1 = style$2;
542
+ cm1 = colorMode$3;
543
+ cv1 = colorValue$4;
544
+ cm2 = match$23.hd;
545
+ cv2 = match$24.hd;
546
+ xs$1 = codePoints;
547
+ exit$1 = 4;
548
+ } else {
549
+ style$1 = style$2;
550
+ cm1 = colorMode$3;
551
+ cv1 = colorValue$4;
552
+ cm2 = cm2$2;
553
+ cv2 = match$22.hd;
554
+ xs$1 = codePoints;
555
+ exit$1 = 4;
556
+ }
478
557
  } else {
479
- style$1 = style$2;
480
- cm1 = colorMode$3;
481
- cv1 = colorValue$4;
482
- cm2 = cm2$2;
483
- cv2 = match$21.hd;
484
- xs$1 = codePoints;
485
- exit = 3;
558
+ colorMode$1 = colorMode$3;
559
+ colorValue$1 = colorValue$4;
560
+ style = style$2;
561
+ exit$1 = 3;
486
562
  }
487
- } else {
488
- colorMode$1 = colorMode$3;
489
- colorValue$1 = colorValue$4;
490
- style = style$2;
491
- exit = 2;
492
563
  }
564
+
493
565
  }
494
566
 
495
- }
496
-
497
- } else {
498
- var match$24 = codePoints.tl;
499
- if (!match$24) {
500
- return [
501
- 1,
502
- undefined
503
- ];
504
- }
505
- if (match$24.hd !== 27) {
506
- return [
507
- 1,
508
- undefined
509
- ];
510
- }
511
- var match$25 = match$24.tl;
512
- if (!match$25) {
513
- return [
514
- 1,
515
- undefined
516
- ];
517
- }
518
- if (match$25.hd !== 91) {
519
- return [
520
- 1,
521
- undefined
522
- ];
523
- }
524
- var match$26 = match$25.tl;
525
- if (!match$26) {
526
- return [
527
- 1,
528
- undefined
529
- ];
530
- }
531
- if (match$26.hd !== 49) {
532
- return [
533
- 1,
534
- undefined
535
- ];
536
- }
537
- var match$27 = match$26.tl;
538
- if (!match$27) {
539
- return [
540
- 1,
541
- undefined
542
- ];
543
- }
544
- if (match$27.hd !== 65) {
545
- return [
546
- 1,
547
- undefined
548
- ];
549
- }
550
- var match$28 = match$27.tl;
551
- if (!match$28) {
552
- return [
553
- 1,
554
- undefined
555
- ];
556
- }
557
- if (match$28.hd !== 27) {
558
- return [
559
- 1,
560
- undefined
561
- ];
562
- }
563
- var match$29 = match$28.tl;
564
- if (!match$29) {
565
- return [
566
- 1,
567
- undefined
568
- ];
569
- }
570
- if (match$29.hd !== 91) {
571
- return [
572
- 1,
573
- undefined
574
- ];
575
- }
576
- var match$30 = match$29.tl;
577
- if (match$30 && match$30.hd === 74) {
578
- return [
579
- 9,
580
- /* EraseLine */1
581
- ];
582
567
  } else {
583
- return [
584
- 1,
585
- undefined
586
- ];
587
- }
588
- }
589
- switch (exit) {
590
- case 1 :
568
+ var match$25 = codePoints.tl;
569
+ if (!match$25) {
591
570
  return [
592
- length,
593
- Belt_Option.flatMap(get(colorMode, colorValue + (
594
- Belt_List.length(xs) === 4 ? 10 : 0
595
- ) | 0), (function (colorCss) {
596
- return /* Style */{
597
- _0: colorCss
598
- };
599
- }))
571
+ 1,
572
+ undefined
600
573
  ];
601
- case 2 :
574
+ }
575
+ if (match$25.hd !== 27) {
602
576
  return [
603
- length,
604
- Belt_Option.flatMap(get(colorMode$1, colorValue$1), (function (colorCss) {
605
- var fontCss = get$1(style);
606
- if (fontCss !== undefined) {
607
- return /* Style */{
608
- _0: Object.assign({}, colorCss, Caml_option.valFromOption(fontCss))
609
- };
610
- } else {
611
- return /* Style */{
612
- _0: colorCss
613
- };
614
- }
615
- }))
577
+ 1,
578
+ undefined
616
579
  ];
617
- case 3 :
580
+ }
581
+ var match$26 = match$25.tl;
582
+ if (!match$26) {
618
583
  return [
619
- length,
620
- Belt_Option.flatMap(get(cm1, cv1), (function (colorCss1) {
621
- return Belt_Option.flatMap(get(cm2, cv2 + (
622
- Belt_List.length(xs$1) === 9 ? 10 : 0
623
- ) | 0), (function (colorCss2) {
624
- var css = Object.assign({}, colorCss1, colorCss2);
625
- var fontCss = get$1(style$1);
626
- if (fontCss !== undefined) {
627
- return /* Style */{
628
- _0: Object.assign({}, css, Caml_option.valFromOption(fontCss))
629
- };
630
- } else {
631
- return /* Style */{
632
- _0: css
633
- };
634
- }
635
- }));
636
- }))
584
+ 1,
585
+ undefined
586
+ ];
587
+ }
588
+ if (match$26.hd !== 91) {
589
+ return [
590
+ 1,
591
+ undefined
592
+ ];
593
+ }
594
+ var match$27 = match$26.tl;
595
+ if (!match$27) {
596
+ return [
597
+ 1,
598
+ undefined
599
+ ];
600
+ }
601
+ if (match$27.hd !== 49) {
602
+ return [
603
+ 1,
604
+ undefined
605
+ ];
606
+ }
607
+ var match$28 = match$27.tl;
608
+ if (!match$28) {
609
+ return [
610
+ 1,
611
+ undefined
612
+ ];
613
+ }
614
+ if (match$28.hd !== 65) {
615
+ return [
616
+ 1,
617
+ undefined
618
+ ];
619
+ }
620
+ var match$29 = match$28.tl;
621
+ if (!match$29) {
622
+ return [
623
+ 1,
624
+ undefined
637
625
  ];
638
-
626
+ }
627
+ if (match$29.hd !== 27) {
628
+ return [
629
+ 1,
630
+ undefined
631
+ ];
632
+ }
633
+ var match$30 = match$29.tl;
634
+ if (!match$30) {
635
+ return [
636
+ 1,
637
+ undefined
638
+ ];
639
+ }
640
+ if (match$30.hd !== 91) {
641
+ return [
642
+ 1,
643
+ undefined
644
+ ];
645
+ }
646
+ var match$31 = match$30.tl;
647
+ if (match$31 && match$31.hd === 74) {
648
+ return [
649
+ 9,
650
+ /* EraseLine */1
651
+ ];
652
+ } else {
653
+ return [
654
+ 1,
655
+ undefined
656
+ ];
657
+ }
658
+ }
659
+ switch (exit$1) {
660
+ case 2 :
661
+ return [
662
+ length,
663
+ Belt_Option.flatMap(get(colorMode, colorValue + (
664
+ Belt_List.length(xs) === 4 ? 10 : 0
665
+ ) | 0), (function (colorCss) {
666
+ return {
667
+ TAG: /* Style */1,
668
+ _0: colorCss
669
+ };
670
+ }))
671
+ ];
672
+ case 3 :
673
+ return [
674
+ length,
675
+ Belt_Option.flatMap(get(colorMode$1, colorValue$1), (function (colorCss) {
676
+ var fontCss = get$1(style);
677
+ if (fontCss !== undefined) {
678
+ return {
679
+ TAG: /* Style */1,
680
+ _0: Object.assign({}, colorCss, Caml_option.valFromOption(fontCss))
681
+ };
682
+ } else {
683
+ return {
684
+ TAG: /* Style */1,
685
+ _0: colorCss
686
+ };
687
+ }
688
+ }))
689
+ ];
690
+ case 4 :
691
+ return [
692
+ length,
693
+ Belt_Option.flatMap(get(cm1, cv1), (function (colorCss1) {
694
+ return Belt_Option.flatMap(get(cm2, cv2 + (
695
+ Belt_List.length(xs$1) === 9 ? 10 : 0
696
+ ) | 0), (function (colorCss2) {
697
+ var css = Object.assign({}, colorCss1, colorCss2);
698
+ var fontCss = get$1(style$1);
699
+ if (fontCss !== undefined) {
700
+ return {
701
+ TAG: /* Style */1,
702
+ _0: Object.assign({}, css, Caml_option.valFromOption(fontCss))
703
+ };
704
+ } else {
705
+ return {
706
+ TAG: /* Style */1,
707
+ _0: css
708
+ };
709
+ }
710
+ }));
711
+ }))
712
+ ];
713
+
714
+ }
639
715
  }
716
+
640
717
  }
641
718
 
642
719
  var AnsiCode = {
@@ -644,9 +721,11 @@ var AnsiCode = {
644
721
  combine: combine,
645
722
  addWeight: addWeight,
646
723
  addStyle: addStyle,
724
+ addDecoration: addDecoration,
647
725
  int_of_cp: int_of_cp,
648
726
  ColorCss: ColorCss,
649
727
  FontCss: FontCss,
728
+ HttpLink: HttpLink,
650
729
  parse: parse
651
730
  };
652
731
 
@@ -708,6 +787,21 @@ function parse$1(txt, length, pos) {
708
787
 
709
788
  }
710
789
  } else {
790
+ if (!code.TAG) {
791
+ return [
792
+ pos$1,
793
+ {
794
+ hd: prevElem,
795
+ tl: {
796
+ hd: {
797
+ TAG: /* Link */1,
798
+ _0: code._0
799
+ },
800
+ tl: /* [] */0
801
+ }
802
+ }
803
+ ];
804
+ }
711
805
  var match$2 = go(pos$1, pos$1);
712
806
  var styled = match$2[1];
713
807
  if (styled !== undefined) {
@@ -717,7 +811,7 @@ function parse$1(txt, length, pos) {
717
811
  hd: prevElem,
718
812
  tl: {
719
813
  hd: {
720
- TAG: /* DocStyle */1,
814
+ TAG: /* DocStyle */2,
721
815
  _0: code._0,
722
816
  _1: styled
723
817
  },
@@ -770,32 +864,51 @@ function parse$2(txt) {
770
864
  }
771
865
 
772
866
  function render(doc) {
773
- var go = function (_xs, _acc) {
867
+ var go = function (_xs, _idx, _acc) {
774
868
  while(true) {
775
869
  var acc = _acc;
870
+ var idx = _idx;
776
871
  var xs = _xs;
777
872
  if (!xs) {
778
873
  return Belt_List.toArray(Belt_List.reverse(acc));
779
874
  }
780
875
  var txt = xs.hd;
781
876
  if (typeof txt === "number") {
782
- _acc = Belt_List.add(acc, React.createElement("br", undefined));
877
+ _acc = Belt_List.add(acc, React.createElement("br", {
878
+ key: String(idx)
879
+ }));
880
+ _idx = idx + 1 | 0;
783
881
  _xs = xs.tl;
784
882
  continue ;
785
883
  }
786
- if (txt.TAG) {
787
- _acc = Belt_List.add(acc, React.createElement("span", {
788
- style: txt._0
789
- }, go(txt._1, /* [] */0)));
790
- _xs = xs.tl;
791
- continue ;
884
+ switch (txt.TAG | 0) {
885
+ case /* Text */0 :
886
+ _acc = Belt_List.add(acc, txt._0);
887
+ _idx = idx + 1 | 0;
888
+ _xs = xs.tl;
889
+ continue ;
890
+ case /* Link */1 :
891
+ var href = txt._0;
892
+ _acc = Belt_List.add(acc, React.createElement("a", {
893
+ key: String(idx),
894
+ href: href
895
+ }, href));
896
+ _idx = idx + 1 | 0;
897
+ _xs = xs.tl;
898
+ continue ;
899
+ case /* DocStyle */2 :
900
+ _acc = Belt_List.add(acc, React.createElement("span", {
901
+ key: String(idx),
902
+ style: txt._0
903
+ }, go(txt._1, 0, /* [] */0)));
904
+ _idx = idx + 1 | 0;
905
+ _xs = xs.tl;
906
+ continue ;
907
+
792
908
  }
793
- _acc = Belt_List.add(acc, txt._0);
794
- _xs = xs.tl;
795
- continue ;
796
909
  };
797
910
  };
798
- return go(doc, /* [] */0);
911
+ return go(doc, 0, /* [] */0);
799
912
  }
800
913
 
801
914
  function Ansi(Props) {
package/src/Ansi.re CHANGED
@@ -18,6 +18,7 @@
18
18
  type document = list(atom)
19
19
  and atom =
20
20
  | Text(string)
21
+ | Link(string)
21
22
  | LineBreak
22
23
  | DocStyle(ReactDOM.Style.t, document);
23
24
 
@@ -30,6 +31,7 @@ module AnsiCode = {
30
31
  | Clear
31
32
  | EraseLine
32
33
  | CarriageReturn
34
+ | HRef(string)
33
35
  | Style(ReactDOM.Style.t);
34
36
 
35
37
  // Convert a 4 bits color code to its css color: https://en.wikipedia.org/wiki/ANSI_escape_code#3-bit_and_4-bit
@@ -43,6 +45,7 @@ module AnsiCode = {
43
45
  | 05 => "magenta"->Some
44
46
  | 06 => "cyan"->Some
45
47
  | 07 => "white"->Some
48
+ | 09 => "initial"->Some
46
49
  | 10 => "grey"->Some
47
50
  | 11 => "#DA2647"->Some
48
51
  | 12 => "#87FF2A"->Some
@@ -60,6 +63,7 @@ module AnsiCode = {
60
63
  let combine = (css1, css2) => ReactDOM.Style.combine(css1, css2);
61
64
  let addWeight = fontWeight => ReactDOM.Style.make(~fontWeight, ());
62
65
  let addStyle = fontStyle => ReactDOM.Style.make(~fontStyle, ());
66
+ let addDecoration = textDecoration => ReactDOM.Style.make(~textDecoration, ());
63
67
  let int_of_cp = c => c - 48;
64
68
 
65
69
  // Color management
@@ -109,8 +113,13 @@ module AnsiCode = {
109
113
  switch (fontMode) {
110
114
  | 0 => Regular->Some
111
115
  | 1 => "bold"->addWeight->FontStyle->Some
116
+ | 2 => "lighter"->addWeight->FontStyle->Some
112
117
  | 3 => "italic"->addStyle->FontStyle->Some
118
+ | 4 => "underline"->addDecoration->FontStyle->Some
119
+ // TODO: add blink for 5/6
113
120
  | 7 => Regular->Some
121
+ // 8 is for hiding, not widely supported.
122
+ | 9 => "line-through"->addDecoration->FontStyle->Some
114
123
  | _ => None
115
124
  };
116
125
 
@@ -124,9 +133,31 @@ module AnsiCode = {
124
133
  fontMode->int_of_cp->getFontStyle->Option.flatMap(getFontStyleCss);
125
134
  };
126
135
 
136
+ // Link management
137
+ module HttpLink = {
138
+ let linkRe = [%re "/^(http(s)?:\\/\\/[^\s]+)/"];
139
+
140
+ let get = (txt: string): parser(code) =>
141
+ linkRe
142
+ ->Js.Re.exec_(txt)
143
+ ->Option.flatMap(res =>
144
+ (
145
+ switch (res->Js.Re.captures) {
146
+ | [|url, _, _|] => url->Js.Nullable.toOption
147
+ | _ => None
148
+ }
149
+ )
150
+ ->Option.flatMap(url =>
151
+ (url->Js.String.length, url->HRef->Some)->Some
152
+ )
153
+ )
154
+ ->Option.getWithDefault((1, None));
155
+ };
156
+
127
157
  // Parse an ANSI code, returning the length of the sequence
128
158
  let parse = (txt: string, pos: int): parser(code) =>
129
159
  switch (Js.String.codePointAt(pos, txt)) {
160
+ | Some(0x68) => HttpLink.get(txt->Js.String.slice(~from=pos, ~to_=512))
130
161
  | Some(0x0a) => (1, CarriageReturn->Some)
131
162
  | Some(0x0d)
132
163
  | Some(0x1b) =>
@@ -143,12 +174,17 @@ module AnsiCode = {
143
174
  switch (codePoints) {
144
175
  // \n\x0d[1A\x0d[J
145
176
  | [10, 27, 91, 49, 65, 27, 91, 74, ..._] => (9, EraseLine->Some)
146
- // [1K
147
- | [91, 48, 75, ..._] => (4, EraseLine->Some)
177
+ // [_K
178
+ | [91, _, 75, ..._] => (4, EraseLine->Some)
179
+ // [K
180
+ | [91, 75, ..._] => (3, EraseLine->Some)
148
181
  // [00m
149
182
  | [91, 48, 48]
150
183
  // [0m
151
- | [91, 48] => (length, Clear->Some)
184
+ | [91, 48]
185
+ // [m
186
+ | [91] => (length, Clear->Some)
187
+ // [_m
152
188
  | [91, style] => (
153
189
  length,
154
190
  style->FontCss.get->Option.flatMap(style => style->Style->Some),
@@ -219,7 +255,7 @@ module Document = {
219
255
  switch (pos == length, txt->AnsiCode.parse(pos)) {
220
256
  // we reached the end of the txt
221
257
  | (true, _) => (pos, [text(txt, prev, pos)]->Some)
222
- // current codepoint is an ANSI code
258
+ // current codepoint is an ANSI code or a HRef
223
259
  | (_, (length, Some(code))) =>
224
260
  let prevElem = txt->text(prev, pos);
225
261
  let pos = pos + length;
@@ -227,6 +263,7 @@ module Document = {
227
263
  | Clear => (pos, [prevElem]->Some)
228
264
  | EraseLine => pos->go(pos)
229
265
  | CarriageReturn => (pos, [prevElem, LineBreak]->Some)
266
+ | HRef(link) => (pos, [prevElem, link->Link]->Some)
230
267
  | Style(style) =>
231
268
  // recursively parse the stylized block
232
269
  switch (pos->go(pos)) {
@@ -260,15 +297,30 @@ let parse = (txt: string): document => {
260
297
 
261
298
  // Convert a document to a React.element
262
299
  let render = (doc: document): React.element => {
263
- let rec go = (xs: document, acc: list(React.element)): React.element =>
300
+ let rec go =
301
+ (xs: document, idx: int, acc: list(React.element)): React.element =>
264
302
  switch (xs) {
265
303
  | [] => acc->List.reverse->List.toArray->ReasonReact.array
266
- | [LineBreak, ...xs] => xs->go(acc->List.add(<br />))
267
- | [Text(txt), ...xs] => xs->go(acc->List.add(txt->React.string))
304
+ | [LineBreak, ...xs] =>
305
+ xs->go(idx + 1, acc->List.add(<br key={idx->string_of_int} />))
306
+ | [Text(txt), ...xs] =>
307
+ xs->go(idx + 1, acc->List.add(txt->React.string))
308
+ | [Link(href), ...xs] =>
309
+ xs->go(
310
+ idx + 1,
311
+ acc->List.add(
312
+ <a key={idx->string_of_int} href> href->React.string </a>,
313
+ ),
314
+ )
268
315
  | [DocStyle(style, elems), ...xs] =>
269
- xs->go(acc->List.add(<span style> {elems->go([])} </span>))
316
+ xs->go(
317
+ idx + 1,
318
+ acc->List.add(
319
+ <span key={idx->string_of_int} style> {elems->go(0, [])} </span>,
320
+ ),
321
+ )
270
322
  };
271
- doc->go([]);
323
+ doc->go(0, []);
272
324
  };
273
325
 
274
326
  // The react component