1 module utils;
2 
3 
4 import std.array;
5 import std.string;
6 import std.utf;
7 
8 public import jax.filters;
9 
10 
11 string quoted(string x, char q = '\"') {
12 	return concat(q, x, q);
13 }
14 
15 
16 string unquoted(string x, char q = '\0') {
17 	if (!q) {
18 		if (((x[0] == '\'') || (x[0] == '\"')) && (x[0] == x[$-1]))
19 			return x[1..$-1];
20 	} else {
21 		if ((x[0] == q) && (x[$-1] == q))
22 			return x[1..$-1];
23 	}
24 	return x;
25 }
26 
27 
28 bool balancedQuotes(Range)(Range range) {
29 	char open = '\0';
30 	char last = '\0';
31 	foreach(ch; range) {
32 		if (last != '\\') {
33 			switch(ch) {
34 				case '"':
35 					open = (open == '"') ? '\0' : '"';
36 					break;
37 				case '\'':
38 					open = (open == '\'') ? '\0' : '\'';
39 					break;
40 				case '`':
41 					open = (open == '`') ? '\0' : '`';
42 					break;
43 				default:
44 					break;
45 			}
46 		}
47 		last = ch;
48 	}
49 	return open == '\0';
50 }
51 
52 
53 bool balanced(Range, Char)(Range range, Char open, Char close) {
54 	int opens = 0;
55 	foreach(c; range) {
56 		if (c == open) {
57 			++opens;
58 		}
59 		if (c == close) {
60 			--opens;
61 		}
62 		if (opens < 0)
63 			return false;
64 	}
65 	return opens == 0;
66 }
67 
68 
69 size_t countLines(string x) {
70 	size_t count;
71 	foreach(i; 0..x.length)
72 		count += (x.ptr[i] == '\n');
73 
74 	return count;
75 }
76 
77 
78 string unescapeJS(string x) {
79 	auto app = appender!string;
80 	app.reserve(x.length);
81 
82 	bool seq;
83 	foreach (ch; x.byDchar) {
84 		switch (ch) {
85 			case '\\':
86 				if (seq) {
87 					app.put('\\');
88 					seq = false;
89 				} else {
90 					seq = true;
91 				}
92 				break;
93 			case '\'':
94 				app.put('\'');
95 				seq = false;
96 				break;
97 			case '\"':
98 				app.put('\"');
99 				seq = false;
100 				break;
101 			case 'r':
102 				app.put(seq ? '\r' : 'r');
103 				seq = false;
104 				break;
105 			case 'n':
106 				app.put(seq ? '\n' : 'n');
107 				seq = false;
108 				break;
109 			default:
110 				app.put(ch);
111 				break;
112 		}
113 	}
114 	return app.data;
115 }
116 
117 
118 string stripUTFbyteOrderMarker(string x) {
119     if (x.length >= 3 && (x[0] == 0xef) && (x[1] == 0xbb) && (x[2] == 0xbf))
120         return x[3..$];
121     return x;
122 }