@@ -20,6 +20,7 @@ interface TextWithAttr {
2020 fg : AU_Color ;
2121 bg : AU_Color ;
2222 bold : boolean ;
23+ faint : boolean ;
2324 italic : boolean ;
2425 underline : boolean ;
2526 text : string ;
@@ -48,7 +49,7 @@ interface TextPacket {
4849//
4950
5051export default class AnsiUp {
51- VERSION = '5 .0.1 ' ;
52+ VERSION = '6 .0.2 ' ;
5253
5354 //
5455 // *** SEE README ON GITHUB FOR PUBLIC API ***
@@ -62,6 +63,7 @@ export default class AnsiUp {
6263 private fg : AU_Color ;
6364 private bg : AU_Color ;
6465 private bold : boolean ;
66+ private faint : boolean ;
6567 private italic : boolean ;
6668 private underline : boolean ;
6769 private _use_classes : boolean ;
@@ -71,14 +73,22 @@ export default class AnsiUp {
7173 private _osc_st : RegExp ;
7274 private _osc_regex : RegExp ;
7375
74- private _url_whitelist : any = { } ;
76+ private _url_allowlist : Record < string , boolean | number > = { } ;
77+ private _escape_html : boolean ;
7578
7679 private _buffer : string ;
7780
81+ private _boldStyle : string ;
82+ private _faintStyle : string ;
83+ private _italicStyle : string ;
84+ private _underlineStyle : string ;
85+
7886 constructor ( ) {
7987 // All construction occurs here
8088 this . setup_palettes ( ) ;
8189 this . resetStyles ( ) ;
90+
91+ this . _use_classes = false ;
8292 }
8393
8494 set use_classes ( arg : boolean ) {
@@ -89,14 +99,33 @@ export default class AnsiUp {
8999 return this . _use_classes ;
90100 }
91101
92- set url_whitelist ( arg : { } ) {
93- this . _url_whitelist = arg ;
102+ set url_allowlist ( arg : Record < string , boolean | number > ) {
103+ this . _url_allowlist = arg ;
94104 }
95105
96- get url_whitelist ( ) : { } {
97- return this . _url_whitelist ;
106+ get url_allowlist ( ) : Record < string , boolean | number > {
107+ return this . _url_allowlist ;
98108 }
99109
110+ set escape_html ( arg : boolean )
111+ {
112+ this . _escape_html = arg ;
113+ }
114+
115+ get escape_html ( ) : boolean
116+ {
117+ return this . _escape_html ;
118+ }
119+
120+ set boldStyle ( arg : string ) { this . _boldStyle = arg ; }
121+ get boldStyle ( ) : string { return this . _boldStyle ; }
122+ set faintStyle ( arg : string ) { this . _faintStyle = arg ; }
123+ get faintStyle ( ) : string { return this . _faintStyle ; }
124+ set italicStyle ( arg : string ) { this . _italicStyle = arg ; }
125+ get italicStyle ( ) : string { return this . _italicStyle ; }
126+ set underlineStyle ( arg : string ) { this . _underlineStyle = arg ; }
127+ get underlineStyle ( ) : string { return this . _underlineStyle ; }
128+
100129 private setup_palettes ( ) : void {
101130 this . ansi_colors = [
102131 // Normal colors
@@ -154,6 +183,10 @@ export default class AnsiUp {
154183 }
155184
156185 private escape_txt_for_html ( txt : string ) : string {
186+ if ( ! this . _escape_html ) {
187+ return txt ;
188+ }
189+
157190 return txt . replace ( / [ & < > " ' ] / gm, str => {
158191 if ( str === '&' ) {
159192 return '&' ;
@@ -209,7 +242,9 @@ export default class AnsiUp {
209242
210243 // NOW WE HANDLE ESCAPES
211244 if ( pos == 0 ) {
212- if ( len == 1 ) {
245+ // All of the sequences typically need at least 3 characters
246+ // So, wait until we have at least that many
247+ if ( len < 3 ) {
213248 // Lone ESC in Buffer, We don't know yet
214249 pkt . kind = PacketKind . Incomplete ;
215250 return pkt ;
@@ -218,9 +253,8 @@ export default class AnsiUp {
218253 const next_char = this . _buffer . charAt ( 1 ) ;
219254
220255 // We treat this as a single ESC
221- // Which effecitvely shows
222- if ( next_char != '[' && next_char != ']' ) {
223- // DeMorgan
256+ // No transformation
257+ if ( next_char != '[' && next_char != ']' && ( next_char != '(' ) ) {
224258 pkt . kind = PacketKind . ESC ;
225259 pkt . text = this . _buffer . slice ( 0 , 1 ) ;
226260 this . _buffer = this . _buffer . slice ( 1 ) ;
@@ -311,10 +345,8 @@ export default class AnsiUp {
311345 var rpos = match [ 0 ] . length ;
312346 this . _buffer = this . _buffer . slice ( rpos ) ;
313347 return pkt ;
314- }
315-
316- // OSC CHECK
317- if ( next_char == ']' ) {
348+ } else if ( next_char == ']' ) {
349+ // OSC CHECK
318350 if ( len < 4 ) {
319351 pkt . kind = PacketKind . Incomplete ;
320352 return pkt ;
@@ -470,6 +502,15 @@ export default class AnsiUp {
470502 var rpos = match [ 0 ] . length ;
471503 this . _buffer = this . _buffer . slice ( rpos ) ;
472504 return pkt ;
505+ } else if ( next_char == '(' ) {
506+ // Other ESC CHECK
507+ // This specifies the character set, which
508+ // should just be ignored
509+
510+ // We have at least 3, so drop the sequence
511+ pkt . kind = PacketKind . Unknown ;
512+ this . _buffer = this . _buffer . slice ( 3 ) ;
513+ return pkt ;
473514 }
474515 }
475516 }
@@ -504,21 +545,26 @@ export default class AnsiUp {
504545 }
505546
506547 resetStyles ( ) {
507- this . _use_classes = false ;
508-
509548 this . bold = false ;
549+ this . faint = false ;
510550 this . italic = false ;
511551 this . underline = false ;
512552 this . fg = this . bg = null ;
513553
514554 this . _buffer = '' ;
515555
516- this . _url_whitelist = { http : 1 , https : 1 } ;
556+ this . _url_allowlist = { http : 1 , https : 1 } ;
557+
558+ this . boldStyle = 'font-weight:bold' ;
559+ this . faintStyle = 'opacity:0.7' ;
560+ this . italicStyle = 'font-style:italic' ;
561+ this . underlineStyle = 'text-decoration:underline' ;
517562 }
518563
519564 private with_state ( pkt : TextPacket ) : TextWithAttr {
520565 return {
521566 bold : this . bold ,
567+ faint : this . faint ,
522568 italic : this . italic ,
523569 underline : this . underline ,
524570 fg : this . fg ,
@@ -540,18 +586,27 @@ export default class AnsiUp {
540586 const sgr_cmd_str = sgr_cmds . shift ( ) ;
541587 const num = parseInt ( sgr_cmd_str , 10 ) ;
542588
589+ // TODO
590+ // AT SOME POINT, JUST CONVERT TO A LOOKUP TABLE
543591 if ( isNaN ( num ) || num === 0 ) {
544- this . fg = this . bg = null ;
592+ this . fg = null ;
593+ this . bg = null ;
545594 this . bold = false ;
595+ this . faint = false ;
546596 this . italic = false ;
547597 this . underline = false ;
548598 } else if ( num === 1 ) {
549599 this . bold = true ;
600+ } else if ( num === 2 ) {
601+ this . faint = true ;
550602 } else if ( num === 3 ) {
551603 this . italic = true ;
552604 } else if ( num === 4 ) {
553605 this . underline = true ;
606+ } else if ( num === 21 ) {
607+ this . bold = false ;
554608 } else if ( num === 22 ) {
609+ this . faint = false ;
555610 this . bold = false ;
556611 } else if ( num === 23 ) {
557612 this . italic = false ;
@@ -612,13 +667,13 @@ export default class AnsiUp {
612667 }
613668
614669 private transform_to_html ( fragment : TextWithAttr ) : string {
615- const txt = fragment . text ;
670+ let txt = fragment . text ;
616671
617672 if ( txt . length === 0 ) {
618673 return txt ;
619674 }
620675
621- // txt = this.escape_txt_for_html(txt);
676+ txt = this . escape_txt_for_html ( txt ) ;
622677
623678 // If colors not set, default style is used
624679 if ( ! fragment . bold && ! fragment . italic && ! fragment . underline && fragment . fg === null && fragment . bg === null ) {
@@ -631,21 +686,26 @@ export default class AnsiUp {
631686 const fg = fragment . fg ;
632687 const bg = fragment . bg ;
633688
634- // Note on bold: https://stackoverflow.com/questions/6737005/what-are-some-advantages-to-using-span-style-font-weightbold-rather-than-b?rq=1
635- if ( fragment . bold ) {
636- styles . push ( 'font-weight:bold' ) ;
637- }
689+ if ( ! this . _use_classes ) {
690+ // USE INLINE STYLES
638691
639- if ( fragment . italic ) {
640- styles . push ( 'font-style:italic' ) ;
641- }
692+ // Note on bold: https://stackoverflow.com/questions/6737005/what-are-some-advantages-to-using-span-style-font-weightbold-rather-than-b?rq=1
693+ if ( fragment . bold ) {
694+ styles . push ( this . _boldStyle ) ;
695+ }
642696
643- if ( fragment . underline ) {
644- styles . push ( 'text-decoration:underline' ) ;
645- }
697+ if ( fragment . faint ) {
698+ styles . push ( this . _faintStyle ) ;
699+ }
700+
701+ if ( fragment . italic ) {
702+ styles . push ( this . _italicStyle ) ;
703+ }
704+
705+ if ( fragment . underline ) {
706+ styles . push ( this . _underlineStyle ) ;
707+ }
646708
647- if ( ! this . _use_classes ) {
648- // USE INLINE STYLES
649709 if ( fg ) {
650710 styles . push ( `color:rgb(${ fg . rgb . join ( ',' ) } )` ) ;
651711 }
@@ -654,6 +714,24 @@ export default class AnsiUp {
654714 }
655715 } else {
656716 // USE CLASSES
717+
718+ // Note on bold: https://stackoverflow.com/questions/6737005/what-are-some-advantages-to-using-span-style-font-weightbold-rather-than-b?rq=1
719+ if ( fragment . bold ) {
720+ classes . push ( "ansi-bold" ) ;
721+ }
722+
723+ if ( fragment . faint ) {
724+ classes . push ( "ansi-faint" ) ;
725+ }
726+
727+ if ( fragment . italic ) {
728+ classes . push ( "ansi-italic" ) ;
729+ }
730+
731+ if ( fragment . underline ) {
732+ classes . push ( "ansi-underline" ) ;
733+ }
734+
657735 if ( fg ) {
658736 if ( fg . class_name !== 'truecolor' ) {
659737 classes . push ( `${ fg . class_name } -fg` ) ;
@@ -691,7 +769,7 @@ export default class AnsiUp {
691769 return '' ;
692770 }
693771
694- if ( ! this . _url_whitelist [ parts [ 0 ] ] ) {
772+ if ( ! this . _url_allowlist [ parts [ 0 ] ] ) {
695773 return '' ;
696774 }
697775
0 commit comments