1 module net.masterthought.rainbow.r; 2 3 import std.array; 4 import std.conv; 5 import std.stdio; 6 import std.string; 7 import std.range; 8 import std.algorithm; 9 10 R rainbow(string s){ 11 return R.bow(s); 12 } 13 14 enum Effect{ 15 bold = "1", 16 dim = "2", 17 underlined = "4", 18 blink = "5", 19 inverted = "7", 20 hidden = "8" 21 } 22 23 private static genColorEnums(string colorType){ 24 string[] colorList; 25 colorList ~= "enum " ~ colorType ~ "{"; 26 if(colorType == "FgColor"){ 27 colorList ~= "original = \"39\", 28 black = \"30\", 29 red = \"31\", 30 green = \"32\", 31 yellow = \"33\", 32 blue = \"34\", 33 magenta = \"35\", 34 cyan = \"36\", 35 lightGray = \"37\", 36 darkGray = \"90\", 37 lightRed = \"91\", 38 lightGreen = \"92\", 39 lightYellow = \"93\", 40 lightBlue = \"94\", 41 lightMagenta = \"95\", 42 lightCyan = \"96\", 43 white = \"97\","; 44 foreach(color ; iota(0,257)){ 45 colorList ~= "c" ~ to!string(color) ~ " = " ~ "\"38;5;" ~ to!string(color) ~ "\","; 46 } 47 } else { 48 colorList ~= "original = \"49\", 49 black = \"40\", 50 red = \"41\", 51 green = \"42\", 52 yellow = \"43\", 53 blue = \"44\", 54 magenta = \"45\", 55 cyan = \"46\", 56 lightGray = \"47\", 57 darkGray = \"100\", 58 lightRed = \"101\", 59 lightGreen = \"102\", 60 lightYellow = \"103\", 61 lightBlue = \"104\", 62 lightMagenta = \"105\", 63 lightCyan = \"106\", 64 white = \"107\","; 65 foreach(color ; iota(0,257)){ 66 colorList ~= "c" ~ to!string(color) ~ " = " ~ "\"48;5;" ~ to!string(color) ~ "\","; 67 } 68 } 69 colorList ~= "}"; 70 return colorList.join(""); 71 } 72 73 mixin(genColorEnums("FgColor")); 74 mixin(genColorEnums("BgColor")); 75 76 class R{ 77 78 private string content; 79 private string[] codes = ["\033["]; 80 81 this(string content){ 82 this.content = content; 83 } 84 85 // makes .red and .onRed etc... 86 private static genColors(string colorType){ 87 string[] colorList; 88 foreach(color ; [__traits(allMembers, FgColor)]){ 89 string methName = colorType == "FgColor" ? color : "on" ~ to!string(color[0]).capitalize() ~ to!string(color[1..$]); 90 colorList ~= "@property public R " ~ methName ~ "(){ codes ~= " ~ colorType ~ "." ~ color ~ " ; codes ~= \";\" ; return this;}"; 91 } 92 return colorList.join(""); 93 } 94 95 // makes .blink effects etc 96 private static genEffects(){ 97 string[] effectList; 98 foreach(effect ; [__traits(allMembers, Effect)]){ 99 effectList ~= "@property public R " ~ effect ~ "(){ codes ~= Effect." ~ effect ~ " ; codes ~= \";\" ; return this;}"; 100 } 101 return effectList.join(""); 102 } 103 104 mixin(genColors("FgColor")); 105 mixin(genColors("BgColor")); 106 mixin(genEffects()); 107 108 public static R bow(string content){ 109 return new R(content); 110 } 111 112 public R fg(FgColor color){ 113 codes ~= color; 114 codes ~= ";"; 115 return this; 116 } 117 118 public R bg(BgColor color){ 119 codes ~= color; 120 codes ~= ";"; 121 return this; 122 } 123 124 public R ef(Effect effect){ 125 codes ~= effect; 126 codes ~= ";"; 127 return this; 128 } 129 130 override public string toString(){ 131 if(codes[$-1] == ";"){ 132 codes.popBack; 133 } 134 codes ~= "m" ~ content ~ "\033[0m"; 135 //writeln(codes); 136 return codes.join(""); 137 } 138 139 string opBinary(string op)(R rhs) 140 { 141 static if (op == "~"){ 142 return this.toString() ~ rhs.toString(); 143 } 144 else static assert(0, "Operator "~op~" not implemented"); 145 } 146 147 string opBinaryRight(string op)(string lhs) 148 { 149 static if (op == "~"){ 150 return lhs ~ this.toString(); 151 } 152 else static assert(0, "Operator "~op~" not implemented"); 153 } 154 155 public void logo(){ 156 writeln(""); 157 writeln(R.bow("╦═╗").red.onBlack, R.bow("╔═╗").c208.onBlack, R.bow("╦").c221.onBlack, R.bow("╔╗╔").green.onBlack, R.bow("╔╗").cyan.onBlack, R.bow(" ╔═╗").c57.onBlack, R.bow("╦ ╦").c99.onBlack); 158 writeln(R.bow("╠╦╝").red.onBlack,R.bow("╠═╣").c208.onBlack, R.bow("║").c221.onBlack, R.bow("║║║").green.onBlack, R.bow("╠╩╗").cyan.onBlack, R.bow("║ ║").c57.onBlack, R.bow("║║║").c99.onBlack); 159 writeln(R.bow("╩╚═").red.onBlack,R.bow("╩ ╩").c208.onBlack, R.bow("╩").c221.onBlack, R.bow("╝╚╝").green.onBlack, R.bow("╚═╝").cyan.onBlack, R.bow("╚═╝").c57.onBlack,R.bow("╚╩╝").c99.onBlack); 160 writeln(""); 161 } 162 163 } 164