Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ANSI colors in C and ncurses

I know I can do the attron and attroff with the color I choose to, however, I would like to know if it's possible to do it with the ANSI colour escape codes within ncurses:

#include <stdio.h>
#include <ncurses.h>

int main()
{
   initscr();
   char *s2 = NULL;
   const char *s1 = "World";
   int n = 10; 

   // What would be a good way to colour %d?
   // seems it is not safe to us the ANSI color escape in here...
   s2 = malloc (snprintf (NULL, 0, "Hello %s \033[22;31m%d", s1, n) + 2); 
   sprintf (s2, "Hello %s \033[22;31m%d", s1, n); 
   printw("%s", s2);
   refresh();
   getch();
   endwin();

   return 0;
}

Linking with -lncurses

a regular printf("\033[22;31mHello, World!\n"); in a non-ncurses program works.

like image 878
DaNiro1 Avatar asked Dec 07 '10 05:12

DaNiro1


People also ask

How do you use colors in ncurses?

In curses , you define colors in pairs: a foreground color on a background color. This allows curses to set both color attributes at once, which often is what you want to do. To establish a color pair, use init_pair() to define a foreground and background color, and associate it to an index number.

How does ANSI color work?

In fact, any code we type into this prompt will also be colored red, as will any subsequent output! That is how Ansi colors work: once you print out the special code enabling a color, the color persists forever until someone else prints out the code for a different color, or prints out the Reset code to disable it.

Do ANSI escape sequences work on Windows?

The advantage of using ANSI escape codes is that, today, these are available on most operating systems, including Windows, and you don't need to install third party libraries. These are well suited for simple command line applications. If you need to do complex text graphics check the ncurses library.


2 Answers

I think you're probably straying into dangerous territory there. Curses will almost certainly track character positions based on output characters and, since it provides its own colour handling, it probably won't detect ANSI escape sequences as well.

If you're after a possible way to allow the ANSI escape sequences in your strings, then one way (kludge though it is) would be to intercept the string and modify it. Have a helper function like myPrintW() which takes a string and breaks it down, something like (pseudo-code):

def myPrintW(s as copy):
    while s not empty:
        p = position of first ansi-sequence in s
        if p == NULL exit while
        printw first p characters of s
        remove the first p characters from s

        decode ansi-sequence at start of s
        issue relevant attron/off for that ansi-sequence
        remove ansi-sequence from start of s

    endwhile
    output s though it may be empty
enddef

This would basically break down the string into normal character sequences and ansi-sequences and you'd process each separately.

It would require a lookup table (or smarts if you need to handle ANSI sequences with arbitrary parameters) in order to translate the sequences into the desired attron/off calls.

like image 174
paxdiablo Avatar answered Sep 20 '22 14:09

paxdiablo


Yes. It all depends on what kind of software or firmware is listening to the program's output. For V3.3 MSDOS, no, it won't work unless the device driver ansi.sys is loaded.

Modern terminal windows tend to have ANSI x3.64 semantics, so those escape sequences will often work. But don't expect too much: extra wide and extra high characters are notoriously poorly supported.

like image 34
wallyk Avatar answered Sep 20 '22 14:09

wallyk