10_JSON_to_GROFF.d (1594B)
1 module jsontogroff; 2 import std.stdio; 3 import std.process; 4 import std.json; 5 import std.array; 6 import std.algorithm; 7 import std.regex; 8 import std.format; 9 import std.conv; 10 import std.range; 11 import std.datetime : Clock; 12 13 void main(string[] argv){ 14 auto str=stdin.byChunk(4096).map!(a=>cast(char[])a).joiner(); 15 auto j=parseJSON(str); 16 17 string positions(){ 18 Appender!string app; 19 app~=".na\n"; 20 app~=".TS\n"; 21 "llxni\n".repeat(j["articles"].array.length).copy(app); 22 app~="===\n"; 23 app~="llxbni\n"; 24 app~=".\n"; 25 double total=0; 26 foreach(ulong ix,art; j["articles"]){ 27 double price=art["price"].str.to!double; 28 string name=art["name"].str; 29 ulong amount=art["amount"].integer; 30 auto esc_name=name.replace("\\","\\\\").replace("\n","\n "); 31 app.formattedWrite!"%d\tT{\n%s\nT}\t%.2f\n"(amount,esc_name,price*amount); 32 total+=price * amount; 33 } 34 app~="\n"; 35 app.formattedWrite("\tTOTAL\t%.2f\n", total); 36 app~=".TE\n"; 37 app~=".al\n"; 38 return app.data; 39 } 40 string delegate()[string] tbl=[ 41 "sale_id": (){return j["sale_id"].integer.to!string;}, 42 "positions": &positions, 43 "today": (){return Clock.currTime.toISOExtString();}, 44 ]; 45 auto lookup(Captures!(char[]) cap){ 46 auto b=cap[1]; 47 auto fct=b in tbl; 48 if(!fct){ 49 return "{{"~b~"}}"; 50 } 51 else{ 52 return cast(const(char)[])(*fct)(); 53 } 54 } 55 File tmplate=File(environment.get("GROFF_TEMPLATE"), "r"); 56 scope(exit)tmplate.close(); 57 auto reg=ctRegex!("\\{\\{([^}]+)\\}\\}"); 58 auto sink=stdout.lockingTextWriter; 59 60 foreach(line; tmplate.byLine(KeepTerminator.yes)){ 61 replaceAllInto!(lookup)(sink, line, reg); 62 } 63 64 }