ANSI escape sequences in JavaScript (color on the command line!)

Recently I’ve been doing a lot of work in Rhino, Mozilla’s JavaScript interpreter written in Java. While it’s a bit slower than some of the other JavaScript interpreters out there it has the advantage of being able to call Java libraries. This is immensely useful since JavaScript is pretty bare-bones in terms of built-in libraries.

Anyway, I had a simple logging system with the usual “error”, “warn”, “info”, etc levels, which was great except the important errors and warnings would get lost in the hundreds of info and debug messages. I didn’t know much about ANSI escape codes except that it allows for neat things like coloring text in your terminal, so I wrote a little code to help with this:

ANSI_ESC            = String.fromCharCode(0x1B);
ANSI_CSI            = ANSI_ESC + ‘[‘;
ANSI_TEXT_PROP      = ‘m’;
ANSI_RESET          = ‘0’;
ANSI_BOLD           = ‘1’;
ANSI_FAINT          = ‘2’; // unsupported?
ANSI_NORMAL         = ’22’;
ANSI_ITALIC         = ‘3’; // unsupported?
ANSI_UNDER          = ‘4’;
ANSI_UNDER_DBL      = ’21’; // unsupported?
ANSI_UNDER_OFF      = ’24’;
ANSI_BLINK          = ‘5’;
ANSI_BLINK_FAST     = ‘6’; // unsupported?
ANSI_BLINK_OFF      = ’25’;
ANSI_REVERSE        = ‘7’;
ANSI_POSITIVE       = ’27’;
ANSI_CONCEAL        = ‘8’;
ANSI_REVEAL         = ’28’;
ANSI_FG             = ‘3’;
ANSI_BG             = ‘4’;
ANSI_FG_INTENSE     = ‘9’;
ANSI_BG_INTENSE     = ’10’;
ANSI_BLACK          = ‘0’;
ANSI_RED            = ‘1’;
ANSI_GREEN          = ‘2’;
ANSI_YELLOW         = ‘3’;
ANSI_BLUE           = ‘4’;
ANSI_MAGENTA        = ‘5’;
ANSI_CYAN           = ‘6’;
ANSI_WHITE          = ‘7’;

ANSIControlCode = function(code, parameters)
{
    if (parameters == undefined)
        parameters = "";
    else if (typeof(parameters) == ‘object’ && (parameters instanceof Array))
        parameters = parameters.join(‘;’);
    return ANSI_CSI + String(parameters) + String(code);
}

// simple text helpers:

ANSITextApplyProperties = function(string, properties)
{
    return ANSIControlCode(ANSI_TEXT_PROP, properties) + String(string) + ANSIControlCode(ANSI_TEXT_PROP);
}

var colorCodeMap = {
    "black"   : ANSI_BLACK,
    "red"     : ANSI_RED,
    "green"   : ANSI_GREEN,
    "yellow"  : ANSI_YELLOW,
    "blue"    : ANSI_BLUE,
    "magenta" : ANSI_MAGENTA,
    "cyan"    : ANSI_CYAN,
    "white"   : ANSI_WHITE
}

ANSITextColorize = function(string, color)
{
    if (colorCodeMap[color] == undefined)
        return string;
    return ANSITextApplyProperties(string, ANSI_FG + colorCodeMap[color]);
}

Download here: ansi_sequences.js

ANSIControlCode(code, parameters) takes in a control code as a string (a single alphabetic character, see above Wikipedia article), and zero or more parameters, either as a single string/number or array of strings/numbers (again, see above Wikipedia article). It returns a string with the control sequence.

There are also two helpers functions for setting text properties:

ANSITextApplyProperties(string, properties) wraps “string” in a pair of control sequences. First the sequence to set text properties (“m” along with the given parameters), second the reset text properties sequence (“m” with no parameters). It returns the wrapped string. This lets you easily apply a number of properties to a string.

ANSITextColorize(string, color) simply sets the foreground color of a string, and returns the wrapped string.

Here are examples of the helper functions:

Note that color control codes must be combined with either ANSI_FG or ANSI_BG.

Also note that this is completely useless in the browser. Only shells can understand these control codes, so use it in Rhino and other command line JavaScript interpreters (while this code is written in JavaScript, the same concepts be applied to any other programming language that can run in a shell: C, Python, Ruby, etc).

  • James

    your image doesnt work; its asking for authentication