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 }