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