1 /** 2 * Authors: Pedro Tacla Yamada 3 * Date: June 9, 2014 4 * License: Licensed under the MIT license. See LICENSE for more information 5 * Version: 1.0.2 6 */ 7 module colorize.colors; 8 9 import std..string : format; 10 11 private template color_type(int offset) 12 { 13 static enum type : int 14 { 15 init = 39 + offset, 16 17 black = 30 + offset, 18 red = 31 + offset, 19 green = 32 + offset, 20 yellow = 33 + offset, 21 blue = 34 + offset, 22 magenta = 35 + offset, 23 cyan = 36 + offset, 24 white = 37 + offset, 25 26 light_black = 90 + offset, 27 light_red = 91 + offset, 28 light_green = 92 + offset, 29 light_yellow = 93 + offset, 30 light_blue = 94 + offset, 31 light_magenta = 95 + offset, 32 light_cyan = 96 + offset, 33 light_white = 97 + offset 34 } 35 } 36 37 alias color_type!0 .type fg; 38 alias color_type!10 .type bg; 39 40 // Text modes 41 static enum mode : int 42 { 43 init = 0, 44 bold = 1, 45 underline = 4, 46 blink = 5, 47 swap = 7, 48 hide = 8 49 } 50 51 /** 52 * Wraps a string around color escape sequences. 53 * 54 * Params: 55 * str = The string to wrap with colors and modes 56 * c = The foreground color (see the fg enum type) 57 * b = The background color (see the bg enum type) 58 * m = The text mode (see the mode enum type) 59 * Example: 60 * --- 61 * writeln("This is blue".color(fg.blue)); 62 * writeln( 63 * color("This is red over green blinking", fg.blue, bg.green, mode.blink) 64 * ); 65 * --- 66 */ 67 68 string color( 69 const string str, 70 const fg c=fg.init, 71 const bg b=bg.init, 72 const mode m=mode.init 73 ) pure 74 { 75 return format("\033[%d;%d;%dm%s\033[0m", m, c, b, str); 76 } 77 78 unittest 79 { 80 import colorize.cwrite; 81 string ret; 82 83 ret = "This is yellow".color(fg.yellow); 84 cwriteln(ret); 85 assert(ret == "\033[33mThis is yellow\033[0m"); 86 87 ret = "This is light green".color(fg.light_green); 88 cwriteln(ret); 89 assert(ret == "\033[92mThis is light green\033[0m"); 90 91 ret = "This is light blue with red background".color(fg.light_blue, bg.red); 92 cwriteln(ret); 93 assert(ret == "\033[0;94;41mThis is light blue with red background\033[0m"); 94 95 ret = "This is red on blue blinking".color(fg.red, bg.blue, mode.blink); 96 cwriteln(ret); 97 assert(ret == "\033[5;31;44mThis is red on blue blinking\033[0m"); 98 99 ret = color("This is magenta", "magenta"); 100 cwriteln(ret); 101 assert(ret == "\033[35mThis is magenta\033[0m"); 102 } 103 104 string colorHelper(const string str, const string name) pure 105 { 106 int code; 107 108 switch(name) 109 { 110 case "init": code = 39; break; 111 112 case "black" : code = 30; break; 113 case "red" : code = 31; break; 114 case "green" : code = 32; break; 115 case "yellow" : code = 33; break; 116 case "blue" : code = 34; break; 117 case "magenta": code = 35; break; 118 case "cyan" : code = 36; break; 119 case "white" : code = 37; break; 120 121 case "light_black" : code = 90; break; 122 case "light_red" : code = 91; break; 123 case "light_green" : code = 92; break; 124 case "light_yellow" : code = 93; break; 125 case "light_blue" : code = 94; break; 126 case "light_magenta": code = 95; break; 127 case "light_cyan" : code = 96; break; 128 case "light_white" : code = 97; break; 129 130 case "bg_init": code = 49; break; 131 132 case "bg_black" : code = 40; break; 133 case "bg_red" : code = 41; break; 134 case "bg_green" : code = 42; break; 135 case "bg_yellow" : code = 43; break; 136 case "bg_blue" : code = 44; break; 137 case "bg_magenta": code = 45; break; 138 case "bg_cyan" : code = 46; break; 139 case "bg_white" : code = 47; break; 140 141 case "bg_light_black" : code = 100; break; 142 case "bg_light_red" : code = 101; break; 143 case "bg_light_green" : code = 102; break; 144 case "bg_light_yellow" : code = 103; break; 145 case "bg_light_blue" : code = 104; break; 146 case "bg_light_magenta": code = 105; break; 147 case "bg_light_cyan" : code = 106; break; 148 case "bg_light_white" : code = 107; break; 149 150 case "mode_init": code = 0; break; 151 case "mode_bold" : code = 1; break; 152 case "mode_underline": code = 4; break; 153 case "mode_blink" : code = 5; break; 154 case "mode_swap" : code = 7; break; 155 case "mode_hide" : code = 8; break; 156 157 default: 158 throw new Exception( 159 "Unknown fg color, bg color or mode \"" ~ name ~ "\"" 160 ); 161 } 162 163 return format("\033[%dm%s\033[0m", code, str); 164 } 165 166 string colorHelper(T)(const string str, const T t=T.init) pure 167 if(is(T : fg) || is(T : bg) || is(T : mode)) 168 { 169 return format("\033[%dm%s\033[0m", t, str); 170 } 171 172 // Custom colors 173 string customForeground(const string str, float r, float g, float b) 174 { 175 uint red = cast(uint)(r * 5 + 0.5); 176 uint green = cast(uint)(g * 5 + 0.5); 177 uint blue = cast(uint)(b * 5 + 0.5); 178 179 return format("\033[38;5;%dm%s\033[0m", 180 16 + (red * 36 + green * 6 + blue), 181 str); 182 } 183 184 alias colorHelper!bg background; 185 alias colorHelper!fg foreground; 186 alias colorHelper!mode style; 187 188 alias background color; 189 alias foreground color; 190 alias style color; 191 alias colorHelper color; 192 193 unittest 194 { 195 import colorize.cwrite; 196 string ret; 197 198 ret = "This is red on blue blinking" 199 .foreground(fg.red) 200 .background(bg.blue) 201 .style(mode.blink); 202 203 cwriteln(ret); 204 assert(ret == "\033[5m\033[44m\033[31mThis is red on blue blinking\033[0m\033[0m\033[0m"); 205 206 ret = "This is a custom color"; 207 cwriteln(ret.customForeground(1, 0.1, 0.3)); 208 }