javascript - Get ANSI color for character at index -


i have developed couleurs npm package can set append rgb method string.prototype:

> console.log("hello world!".rgb(255, 0, 0)) // "hello world!" in red hello world! undefined > "hello world!".rgb(255, 0, 0) '\u001b[38;5;196mhello world!\u001b[0m' 

this works fine. what's proper way ansi color/style of character @ index i?

probably can hacked regular expressions, i'm not sure if that's (however, if correct implementation available i'm not against it)... i'd prefer native way color/style accessing character interpreted tty.

> function getstyle (input, i) { /* style @ index `i` */ return style; }  > getstyle("hello world!".rgb(255, 0, 0), 0); // style of first char {    start: "\u001b[38;5;196m",    end: "\u001b[0m",    char: "h" } > getstyle("hello " + "world!".rgb(255, 0, 0), 0); // style of first char {    start: "",    end: "",    char: "h" } 

things complicated when have multiple combined styles:

> console.log("green , italic".rgb(0, 255, 0).italic()) green , italic undefined > getstyle("green , italic".rgb(0, 255, 0).italic(), 0); {    start: "\u001b[3m\u001b[38;5;46m",    end: "\u001b[0m\u001b[23m",    char: "g" } > getstyle(("bold & red".bold() + " 1 red").rgb(255, 0, 0), 0); {    start: "\u001b[38;5;196m\u001b[1m",    end: "\u001b[22m\u001b[0m",    char: "b" } > getstyle(("bold & red".bold() + " 1 red").rgb(255, 0, 0), 11); {    start: "\u001b[38;5;196m",    end: "\u001b[0m",    char: "u" } > ("bold & red".bold() + " 1 red").rgb(255, 0, 0) '\u001b[38;5;196m\u001b[1mbold & red\u001b[22m 1 red\u001b[0m' 

like said, i'm looking native way (maybe using child process).

so, how complete ansi style character @ index i?

there couple of ways 'add' formatting text, , 1 of them. problem mixing text , styling same object -- text string. it's similar rtf

here \b bold\b0 , {\i italic} text\par 

but different from, say, native format of word .doc files, works text runs:

(text) here bold , italic text\r (chp)  13 none        4  sprmcfbold        5  none        6  sprmcfitalic        6  none 

-- number @ left count of characters formatting.

the latter format looking for, since want index characters in plain text. subtracting formatting lengths show 1 interested in. depending on how many times expect ask formatting, can one-time runs only, or cache formatted text somewhere.

a one-time run needs inspect each element of encoded string, incrementing "text" index when not inside color string, , updating 'last seen' color string if is. added compatible getcharat function debugging purposes.

var str = '\u001b[38;5;196m\u001b[1mbo\x1b[22mld & red\u001b[22m 1 red\u001b[0m';  const map = {     bold: ["\x1b[1m", "\x1b[22m" ]   , italic: ["\x1b[3m", "\x1b[23m" ]   , underline: ["\x1b[4m", "\x1b[24m" ]   , inverse: ["\x1b[7m", "\x1b[27m" ]   , strikethrough: ["\x1b[9m", "\x1b[29m" ] };  string.prototype.getcolorat = function(index) {     var strindex=0, color=[], cmatch, i,j;      while (strindex < this.length)     {         cmatch = this.substr(strindex).match(/^(\u001b\[[^m]*m)/);         if (cmatch)         {             // global reset?             if (cmatch[0] == '\x1b[0m')             {                 color = [];             } else             {                 // off code?                 (i=0; i<map.length; i++)                 {                     if (map[i][1] == cmatch[0])                     {                         // remove on code?                         (j=color.length-1; j>=0; j--)                         {                             if (color[j] == map[i][0])                                 color.splice (j,1);                         }                         break;                     }                 }                 if (j==map.length)                     color.push (cmatch[0]);             }             strindex += cmatch[0].length;         } else         {             /* regular character! */             if (!index)                 break;             strindex++;             index--;         }     }     return color.join(''); }  string.prototype.getcharat = function(index) {     var strindex=0, cmatch;      while (strindex < this.length)     {         cmatch = this.substr(strindex).match(/^(\u001b\[[^m]*m)/);         if (cmatch)         {             strindex += cmatch[0].length;         } else         {             /* regular character! */             if (!index)                 return this.substr(strindex,1);             strindex++;             index--;         }     }     return ''; }  console.log (str);  color = str.getcolorat (1); text = str.getcharat (1); console.log ('color '+color+color.length+', char '+text); 

the returned color still in original escaped encoding. can make return constant of kind adding these original map array.


Comments

Popular posts from this blog

javascript - Any ideas when Firefox is likely to implement lengthAdjust and textLength? -

matlab - "Contour not rendered for non-finite ZData" -

delphi - Indy UDP Read Contents of Adata -