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 }