1 module feature.feature; 2 import std.stdio; 3 import std.string; 4 import dweb.view_engine; 5 import std.array; 6 import std.conv; 7 import feature.types; 8 public class Feature : ViewEngine{ 9 private Type function(string)[string] _types; 10 private Type function(Type[])[string] functions; 11 12 this(){ 13 this._types = [ 14 "string": &str, 15 "int": &integer 16 ]; 17 this.functions = [ 18 "concat": &concatstr 19 ]; 20 } 21 public override string render(string source){ 22 return srender(source); 23 } 24 private string srender(string source, Type[string] co = null){ 25 Type[string] constants; 26 if(co !is null) 27 constants = co; 28 string res = source.dup; 29 string[] src = source.split("\n"); 30 for(int i = 0; i < src.length; i++){ 31 string str = src[i]; 32 ptrdiff_t index = indexOf(str, "@define"); 33 if(index != -1){ 34 string ns = str.split("@define ")[1]; 35 string val; 36 string name; 37 string type; 38 39 if(ns.split(' ').length > 0) 40 type = ns.split(' ')[0]; 41 else 42 throw new Exception("Type of constant has no wrote!"); 43 if(ns.split(' ').length > 1) 44 name = ns.split(' ')[1]; 45 else 46 throw new Exception("Name of constant has no wrote!"); 47 if(ns.split(' ').length > 2) 48 val = ns.split(' ')[2 .. ns.split(' ').length].join(' '); 49 else 50 throw new Exception("Value of constant named as \"" ~ name ~ "\" has no wrote!"); 51 Type c = this._types[type](val); 52 constants[name] = c; 53 54 src[i] = str.replace(name, "").replace("@define", "").replace(val, "").replace(type, ""); 55 } 56 index = indexOf(str, "@repeat"); 57 if(index != -1){ 58 string ns = str.split("@repeat ")[1]; 59 int num; 60 if(ns.split(' ').length > 0) 61 num = ns.split(' ')[0].to!int(); 62 else 63 throw new Exception("Number of repeats has no wrote!"); 64 string[] torepeat; 65 int r = 1; 66 int start = i; 67 while(r > 0){ 68 i++; 69 if(src[i].indexOf("@end") != -1){ 70 r--; 71 if(r == 0){ 72 src[i] = ""; 73 continue; 74 } 75 } 76 if(src[i].indexOf("@repeat") != -1){ 77 r++; 78 } 79 torepeat ~= [src[i]]; 80 81 } 82 int end = i; 83 src = src[0 .. start] ~ src[end .. src.length]; 84 for(int j = 0; j < num; j++){ 85 constants["iteration"] = new IntType(j); 86 src[start] ~= "\n" ~ srender(torepeat.join("\n"), constants) ~ "\n"; 87 } 88 constants.remove("iteration"); 89 90 } 91 foreach(func; this.functions.byPair){ 92 if(indexOf(str, "@" ~ func.key ~ "(") != -1){ 93 string[] sargs =str.split("@" ~ func.key ~ "(")[1].split(")")[0].split(' '); 94 Type[] args; 95 for(int h = 0; h < sargs.length; h++){ 96 Type arg; 97 98 if(sargs[h][0] == '@'){ 99 arg = constants[sargs[h].replace("@", "")]; 100 } 101 else{ 102 arg = new StringType(sargs[h]); 103 } 104 args ~= [arg]; 105 } 106 str = str.replace("@" ~ func.key, func.value(args).ToString()); 107 str = str[0 .. indexOf(str, "(")] ~ str[indexOf(str, ")") + 1 .. str.length]; 108 src[i] = str; 109 } 110 } 111 foreach(constant; constants.byPair){ 112 if(indexOf(str, "@" ~ constant.key) != -1){ 113 str=str.replace("@" ~ constant.key, constant.value.ToString()); 114 115 src[i] = str; 116 } 117 } 118 119 } 120 return src.join("\n"); 121 } 122 } 123 124 Type str(string val) { 125 StringType s = new StringType(val); 126 127 return s; 128 } 129 Type integer(string val) { 130 IntType s = new IntType(val); 131 132 return s; 133 } 134 Type concatstr(Type[] args){ 135 string str; 136 foreach(arg; args){ 137 str ~= arg.ToString(); 138 } 139 StringType s = new StringType(str); 140 141 return s; 142 }