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 string removeLicense(string code) { 54 if(code.startsWith("/*")) { 55 code = code[code.indexOf("*/", 2) + 2 .. $].stripLeft(); 56 } 57 return code; 58 } 59 60 struct TypeLines { 61 Type type; 62 string[] lines; 63 } 64 65 TypeLines jssplit(string input) { 66 string[] lines = split(input.removeLicense(), "\n") 67 .map!(a => a.strip("\", \t\n\r")) 68 .filter!(a => !a.empty && !a.startsWith("//")) 69 .array; 70 71 if(lines.length < 3) { 72 //writeln("\t\tshort"); 73 return TypeLines(Type.undefined, []); 74 } 75 assert(lines.front.startsWith("module[\"exports\"] = ") 76 || lines.front.startsWith("module.exports = ") 77 || lines.front.startsWith("module['exports'] = ") 78 , lines.front ~ "\n" ~ input); 79 lines = lines[1 .. $] 80 .map!(a => { 81 if(!a.empty && a[$ - 1] == '\'') { 82 a = a[0 .. $ - 1]; 83 } 84 if(!a.empty && a[0] == '\'') { 85 a = a[1 .. $]; 86 } 87 return a; 88 }()) 89 .array; 90 //writeln(lines); 91 assert(lines.back.startsWith("];") 92 || lines.back.startsWith("}") 93 || lines.back.startsWith("]"), 94 lines.back ~ "\n" ~ input); 95 lines = lines[0 .. $ - 1]; 96 97 Type type = findType(lines); 98 if(type == Type.unknown) { 99 //writefln("unknown %(%s\n%)", lines); 100 } 101 102 return TypeLines(type, lines); 103 }