Subversion Repositories munaweb

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/**
2
* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
3
*
4
* Version - 0.99.00.beta
5
* Copyright (c) 2012 Vadim Kiryukhin
6
* vkiryukhin @ gmail.com
7
* http://www.eslinstructor.net/vkbeautify/
8
*
9
* Dual licensed under the MIT and GPL licenses:
10
*   http://www.opensource.org/licenses/mit-license.php
11
*   http://www.gnu.org/licenses/gpl.html
12
*
13
*   Pretty print
14
*
15
*        vkbeautify.xml(text [,indent_pattern]);
16
*        vkbeautify.json(text [,indent_pattern]);
17
*        vkbeautify.css(text [,indent_pattern]);
18
*        vkbeautify.sql(text [,indent_pattern]);
19
*
20
*        @text - String; text to beatufy;
21
*        @indent_pattern - Integer | String;
22
*                Integer:  number of white spaces;
23
*                String:   character string to visualize indentation ( can also be a set of white spaces )
24
*   Minify
25
*
26
*        vkbeautify.xmlmin(text [,preserve_comments]);
27
*        vkbeautify.jsonmin(text);
28
*        vkbeautify.cssmin(text [,preserve_comments]);
29
*        vkbeautify.sqlmin(text);
30
*
31
*        @text - String; text to minify;
32
*        @preserve_comments - Bool; [optional];
33
*                Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
34
*
35
*   Examples:
36
*        vkbeautify.xml(text); // pretty print XML
37
*        vkbeautify.json(text, 4 ); // pretty print JSON
38
*        vkbeautify.css(text, '. . . .'); // pretty print CSS
39
*        vkbeautify.sql(text, '----'); // pretty print SQL
40
*
41
*        vkbeautify.xmlmin(text, true);// minify XML, preserve comments
42
*        vkbeautify.jsonmin(text);// minify JSON
43
*        vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
44
*        vkbeautify.sqlmin(text);// minify SQL
45
*
46
*/
47
 
48
(function() {
49
 
50
function createShiftArr(step) {
51
 
52
	var space = '    ';
53
 
54
	if ( isNaN(parseInt(step)) ) {  // argument is string
55
		space = step;
56
	} else { // argument is integer
57
		switch(step) {
58
			case 1: space = ' '; break;
59
			case 2: space = '  '; break;
60
			case 3: space = '   '; break;
61
			case 4: space = '    '; break;
62
			case 5: space = '     '; break;
63
			case 6: space = '      '; break;
64
			case 7: space = '       '; break;
65
			case 8: space = '        '; break;
66
			case 9: space = '         '; break;
67
			case 10: space = '          '; break;
68
			case 11: space = '           '; break;
69
			case 12: space = '            '; break;
70
		}
71
	}
72
 
73
	var shift = ['\n']; // array of shifts
74
	for(ix=0;ix<100;ix++){
75
		shift.push(shift[ix]+space);
76
	}
77
	return shift;
78
}
79
 
80
function vkbeautify(){
81
	this.step = '    '; // 4 spaces
82
	this.shift = createShiftArr(this.step);
83
};
84
 
85
vkbeautify.prototype.xml = function(text,step) {
86
 
87
	var ar = text.replace(/>\s{0,}</g,"><")
88
				 .replace(/</g,"~::~<")
89
				 .replace(/\s*xmlns\:/g,"~::~xmlns:")
90
				 .replace(/\s*xmlns\=/g,"~::~xmlns=")
91
				 .split('~::~'),
92
		len = ar.length,
93
		inComment = false,
94
		deep = 0,
95
		str = '',
96
		ix = 0,
97
		shift = step ? createShiftArr(step) : this.shift;
98
 
99
		for(ix=0;ix<len;ix++) {
100
			// start comment or <![CDATA[...]]> or <!DOCTYPE //
101
			if(ar[ix].search(/<!/) > -1) {
102
				str += shift[deep]+ar[ix];
103
				inComment = true;
104
				// end comment  or <![CDATA[...]]> //
105
				if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
106
					inComment = false;
107
				}
108
			} else
109
			// end comment  or <![CDATA[...]]> //
110
			if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
111
				str += ar[ix];
112
				inComment = false;
113
			} else
114
			// <elm></elm> //
115
			if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
116
				/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
117
				str += ar[ix];
118
				if(!inComment) deep--;
119
			} else
120
			 // <elm> //
121
			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
122
				str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
123
			} else
124
			 // <elm>...</elm> //
125
			if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
126
				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
127
			} else
128
			// </elm> //
129
			if(ar[ix].search(/<\//) > -1) {
130
				str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
131
			} else
132
			// <elm/> //
133
			if(ar[ix].search(/\/>/) > -1 ) {
134
				str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
135
			} else
136
			// <? xml ... ?> //
137
			if(ar[ix].search(/<\?/) > -1) {
138
				str += shift[deep]+ar[ix];
139
			} else
140
			// xmlns //
141
			if( ar[ix].search(/xmlns\:/) > -1  || ar[ix].search(/xmlns\=/) > -1) {
142
				str += shift[deep]+ar[ix];
143
			}
144
 
145
			else {
146
				str += ar[ix];
147
			}
148
		}
149
 
150
	return  (str[0] == '\n') ? str.slice(1) : str;
151
}
152
 
153
vkbeautify.prototype.json = function(text,step) {
154
 
155
	var step = step ? step : this.step;
156
 
157
	if (typeof JSON === 'undefined' ) return text;
158
 
159
	if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
160
	if ( typeof text === "object" ) return JSON.stringify(text, null, step);
161
 
162
	return text; // text is not string nor object
163
}
164
 
165
vkbeautify.prototype.css = function(text, step) {
166
 
167
	var ar = text.replace(/\s{1,}/g,' ')
168
				.replace(/\{/g,"{~::~")
169
				.replace(/\}/g,"~::~}~::~")
170
				.replace(/\;/g,";~::~")
171
				.replace(/\/\*/g,"~::~/*")
172
				.replace(/\*\//g,"*/~::~")
173
				.replace(/~::~\s{0,}~::~/g,"~::~")
174
				.split('~::~'),
175
		len = ar.length,
176
		deep = 0,
177
		str = '',
178
		ix = 0,
179
		shift = step ? createShiftArr(step) : this.shift;
180
 
181
		for(ix=0;ix<len;ix++) {
182
 
183
			if( /\{/.exec(ar[ix]))  {
184
				str += shift[deep++]+ar[ix];
185
			} else
186
			if( /\}/.exec(ar[ix]))  {
187
				str += shift[--deep]+ar[ix];
188
			} else
189
			if( /\*\\/.exec(ar[ix]))  {
190
				str += shift[deep]+ar[ix];
191
			}
192
			else {
193
				str += shift[deep]+ar[ix];
194
			}
195
		}
196
		return str.replace(/^\n{1,}/,'');
197
}
198
 
199
//----------------------------------------------------------------------------
200
 
201
function isSubquery(str, parenthesisLevel) {
202
	return  parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
203
}
204
 
205
function split_sql(str, tab) {
206
 
207
	return str.replace(/\s{1,}/g," ")
208
 
209
				.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
210
				.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
211
				.replace(/ CASE /ig,"~::~"+tab+"CASE ")
212
				.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
213
				.replace(/ END /ig,"~::~"+tab+"END ")
214
				.replace(/ FROM /ig,"~::~FROM ")
215
				.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
216
				.replace(/ HAVING /ig,"~::~HAVING ")
217
				//.replace(/ SET /ig," SET~::~")
218
				.replace(/ IN /ig," IN ")
219
 
220
				.replace(/ JOIN /ig,"~::~JOIN ")
221
				.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
222
				.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
223
				.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
224
				.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
225
 
226
				.replace(/ ON /ig,"~::~"+tab+"ON ")
227
				.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
228
				.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
229
				.replace(/ OVER /ig,"~::~"+tab+"OVER ")
230
 
231
				.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
232
				.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
233
 
234
				.replace(/ THEN /ig," THEN~::~"+tab+"")
235
				.replace(/ UNION /ig,"~::~UNION~::~")
236
				.replace(/ USING /ig,"~::~USING ")
237
				.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
238
				.replace(/ WHERE /ig,"~::~WHERE ")
239
				.replace(/ WITH /ig,"~::~WITH ")
240
 
241
				//.replace(/\,\s{0,}\(/ig,",~::~( ")
242
				//.replace(/\,/ig,",~::~"+tab+tab+"")
243
 
244
				.replace(/ ALL /ig," ALL ")
245
				.replace(/ AS /ig," AS ")
246
				.replace(/ ASC /ig," ASC ")
247
				.replace(/ DESC /ig," DESC ")
248
				.replace(/ DISTINCT /ig," DISTINCT ")
249
				.replace(/ EXISTS /ig," EXISTS ")
250
				.replace(/ NOT /ig," NOT ")
251
				.replace(/ NULL /ig," NULL ")
252
				.replace(/ LIKE /ig," LIKE ")
253
				.replace(/\s{0,}SELECT /ig,"SELECT ")
254
				.replace(/\s{0,}UPDATE /ig,"UPDATE ")
255
				.replace(/ SET /ig," SET ")
256
 
257
				.replace(/~::~{1,}/g,"~::~")
258
				.split('~::~');
259
}
260
 
261
vkbeautify.prototype.sql = function(text,step) {
262
 
263
	var ar_by_quote = text.replace(/\s{1,}/g," ")
264
							.replace(/\'/ig,"~::~\'")
265
							.split('~::~'),
266
		len = ar_by_quote.length,
267
		ar = [],
268
		deep = 0,
269
		tab = this.step,//+this.step,
270
		inComment = true,
271
		inQuote = false,
272
		parenthesisLevel = 0,
273
		str = '',
274
		ix = 0,
275
		shift = step ? createShiftArr(step) : this.shift;;
276
 
277
		for(ix=0;ix<len;ix++) {
278
			if(ix%2) {
279
				ar = ar.concat(ar_by_quote[ix]);
280
			} else {
281
				ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
282
			}
283
		}
284
 
285
		len = ar.length;
286
		for(ix=0;ix<len;ix++) {
287
 
288
			parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
289
 
290
			if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
291
				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
292
			}
293
 
294
			if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix]))  {
295
				ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
296
			}
297
 
298
			if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix]))  {
299
				deep++;
300
				str += shift[deep]+ar[ix];
301
			} else
302
			if( /\'/.exec(ar[ix]) )  {
303
				if(parenthesisLevel<1 && deep) {
304
					deep--;
305
				}
306
				str += ar[ix];
307
			}
308
			else  {
309
				str += shift[deep]+ar[ix];
310
				if(parenthesisLevel<1 && deep) {
311
					deep--;
312
				}
313
			}
314
			var junk = 0;
315
		}
316
 
317
		str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
318
		return str;
319
}
320
 
321
 
322
vkbeautify.prototype.xmlmin = function(text, preserveComments) {
323
 
324
	var str = preserveComments ? text
325
							   : text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
326
									 .replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
327
	return  str.replace(/>\s{0,}</g,"><");
328
}
329
 
330
vkbeautify.prototype.jsonmin = function(text) {
331
 
332
	if (typeof JSON === 'undefined' ) return text;
333
 
334
	return JSON.stringify(JSON.parse(text), null, 0);
335
 
336
}
337
 
338
vkbeautify.prototype.cssmin = function(text, preserveComments) {
339
 
340
	var str = preserveComments ? text
341
							   : text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
342
 
343
	return str.replace(/\s{1,}/g,' ')
344
			  .replace(/\{\s{1,}/g,"{")
345
			  .replace(/\}\s{1,}/g,"}")
346
			  .replace(/\;\s{1,}/g,";")
347
			  .replace(/\/\*\s{1,}/g,"/*")
348
			  .replace(/\*\/\s{1,}/g,"*/");
349
}
350
 
351
vkbeautify.prototype.sqlmin = function(text) {
352
	return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
353
}
354
 
355
window.vkbeautify = new vkbeautify();
356
 
357
})();
358