1 /**
2  * Hackish library to colorize standard output.
3  * Example:
4  * ---
5  * import termcolor;
6  * import std.stdio : write, writeln;
7  * import std.traits : EnumMembers;
8  * writeln("Written in ", C.green.fg, "green color and ", C.blackDark.bg, "dark background", resetColor, "!");
9  *
10  * // show all color combinations
11  * foreach(f; EnumMembers!C) {
12  *     foreach(b; EnumMembers!C) {
13  *         write(f.fg, b.bg, "foo", resetColor(), " ");
14  *     }
15  *     writeln();
16  * }
17  * ---
18  */
19 module termcolor;
20 
21 version(Posix):
22 
23 /**
24  * All colors
25  *
26  * Example:
27  * --------------------
28  * // Available colors:
29  * black       // darker grey
30  * blackDark   // black
31  * blue
32  * blueDark
33  * cyan
34  * cyanDark
35  * green
36  * greenDark
37  * magenta
38  * magentaDark
39  * red
40  * redDark
41  * white       // white
42  * whiteDark   // lighter grey
43  * yellow
44  * yellowDark
45  * --------------------
46  */
47 enum C
48 {
49     black = 0,
50     red = 1,
51     green = 2,
52     yellow = 3,
53     blue = 4,
54     magenta = 5,
55     cyan = 6,
56     white = 7,
57 
58     blackDark = 8,
59     redDark = 9,
60     greenDark = 10,
61     yellowDark = 11,
62     blueDark = 12,
63     magentaDark = 13,
64     cyanDark = 14,
65     whiteDark = 15,
66 
67     reset = 16,
68 }
69 unittest
70 {
71     // ensure there are 8 colors from Color.white(Dark) to Color.black(Dark)
72     assert(C.white - C.black == 7);
73     assert(C.whiteDark - C.blackDark == 7);
74 }
75 
76 string fg(C color)
77 {
78     return color.ANSINumber.ANSIString;
79 }
80 
81 string bg(C color)
82 {
83     return (color.ANSINumber + 10).ANSIString;
84 }
85 
86 string resetColor()
87 {
88     return 0.ANSIString;
89 }
90 
91 private
92 {
93     import std.conv : text;
94 
95     version (OSX)
96     {
97         enum LightColorIndexStart = 90;
98         enum DarkColorIndexStart = 30;
99     }
100     else
101     {
102         enum LightColorIndexStart = 30;
103         enum DarkColorIndexStart = 90;
104     }
105 
106     /// ANSI color code from enum Color
107     int ANSINumber(in C color) pure
108     {
109         if (color == C.reset) {
110             return 39;
111         }
112 
113         return (color < 8 ? LightColorIndexStart : DarkColorIndexStart) + (color % 8);
114     }
115 
116     string ANSIString(int number)
117     {
118         return text("\033[", number, "m");
119     }
120 }