1 module jssplitter; 2 3 import std.array; 4 import std.algorithm; 5 import std.stdio; 6 import std.string; 7 import std.json; 8 9 enum Type { 10 undefined, 11 strings, 12 call, 13 json, 14 digit, 15 mustache, 16 unknown, 17 } 18 19 Type findType(string[] lines) { 20 Type type = Type.undefined; 21 foreach(l; lines) { 22 bool isCall = l.indexOf("#{") != -1; 23 bool isMustache = l.indexOf("{{") != -1; 24 bool isJson = l.endsWith(": {") || l.endsWith(": ["); 25 bool isDigit = l.indexOf("##") != -1 || l.indexOf(".#") != -1; 26 27 Type t; 28 if(isCall && !isMustache && !isJson && !isDigit) { 29 t = Type.call; 30 } else if(!isCall && isMustache && !isJson && !isDigit) { 31 t = Type.mustache; 32 } else if(!isCall && !isMustache && isJson && !isDigit) { 33 t = Type.json; 34 } else if(!isCall && !isMustache && !isJson && isDigit) { 35 t = Type.digit; 36 } else { 37 t = Type.strings; 38 } 39 40 //writefln("%20s %s", t, l); 41 42 if(type == Type.undefined) { 43 type = t; 44 continue; 45 } else if(t != type && type != Type.json) { 46 type = Type.unknown; 47 break; 48 } 49 } 50 return type; 51 } 52 53 struct TypeLines { 54 Type type; 55 string[] lines; 56 } 57 58 TypeLines jssplit(string input) { 59 string[] lines = split(input, "\n") 60 .map!(a => a.strip("\", \t\n")) 61 .filter!(a => !a.empty && !a.startsWith("//")) 62 .array; 63 64 if(lines.length < 3) { 65 //writeln("\t\tshort"); 66 return TypeLines(Type.undefined, []); 67 } 68 assert(lines.front.startsWith("module[\"exports\"] = ") 69 || lines.front.startsWith("module.exports = ") 70 || lines.front.startsWith("module['exports'] = ") 71 , lines.front ~ "\n" ~ input); 72 lines = lines[1 .. $]; 73 //writeln(lines); 74 assert(lines.back.startsWith("];") 75 || lines.back.startsWith("}") 76 || lines.back.startsWith("]"), 77 lines.back ~ "\n" ~ input); 78 lines = lines[0 .. $ - 1]; 79 80 Type type = findType(lines); 81 if(type == Type.unknown) { 82 //writefln("unknown %(%s\n%)", lines); 83 } 84 85 return TypeLines(type, lines); 86 }