mirror of
https://github.com/beautifier/js-beautify.git
synced 2024-11-23 12:49:40 +00:00
Added option to ignore existing whitespace.
For ugly javascript i guess i'm not the only one who needs a possibility to throw away existing whitespace and reformat everything nicely. For some reason I didn't have this feature, and nobody told anything about it. Now there is one, and the world will be slightly better place.
This commit is contained in:
parent
f649089c84
commit
f5ec6a9159
109
HTML-Beautify.js
109
HTML-Beautify.js
@ -7,11 +7,11 @@
|
||||
Written by Nochum Sossonko, (nsossonko@hotmail.com)
|
||||
$Date$
|
||||
$Revision$
|
||||
|
||||
Based on code initially developed by: Einars "elfz" Lielmanis, <elfz@laacz.lv>
|
||||
|
||||
Based on code initially developed by: Einars "elfz" Lielmanis, <elfz@laacz.lv>
|
||||
http://elfz.laacz.lv/beautify/
|
||||
|
||||
|
||||
|
||||
You are free to use this in any way you want, in case you find this useful or working for you.
|
||||
|
||||
Usage:
|
||||
@ -21,11 +21,11 @@
|
||||
|
||||
function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
//Wrapper function to invoke all the necessary constructors and deal with the output.
|
||||
|
||||
|
||||
var Parser, multi_parser;
|
||||
|
||||
|
||||
function Parser() {
|
||||
|
||||
|
||||
this.pos = 0; //Parser position
|
||||
this.token = '';
|
||||
this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT
|
||||
@ -37,7 +37,7 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
this.tag_type = '';
|
||||
this.token_text = this.last_token = this.last_text = this.token_type = '';
|
||||
|
||||
|
||||
|
||||
this.Utils = { //Uilities made available to the various functions
|
||||
whitespace: "\n\r\t ".split(''),
|
||||
single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed'.split(','), //all the single tags for HTML
|
||||
@ -51,9 +51,9 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.get_content = function () { //function to capture regular content between tags
|
||||
|
||||
|
||||
var char = '';
|
||||
var content = [];
|
||||
var space = false; //if a space is needed
|
||||
@ -61,12 +61,12 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length?content.join(''):['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
this.line_char_count++;
|
||||
|
||||
|
||||
|
||||
|
||||
if (this.Utils.in_array(char, this.Utils.whitespace)) {
|
||||
if (content.length) {
|
||||
space = true;
|
||||
@ -92,9 +92,9 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
return content.length?content.join(''):'';
|
||||
}
|
||||
|
||||
|
||||
this.get_script = function () { //get the full content of a script to pass to js_beautify
|
||||
|
||||
|
||||
var char = '';
|
||||
var content = [];
|
||||
var reg_match = new RegExp('\<\/script' + '\>', 'igm');
|
||||
@ -105,16 +105,16 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length?content.join(''):['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
|
||||
|
||||
|
||||
|
||||
content.push(char);
|
||||
}
|
||||
return content.length?content.join(''):''; //we might not have any content at all
|
||||
}
|
||||
|
||||
|
||||
this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object
|
||||
if (this.tags[tag + 'count']) { //check for the existence of this tag type
|
||||
this.tags[tag + 'count']++;
|
||||
@ -127,7 +127,7 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent)
|
||||
this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1')
|
||||
}
|
||||
|
||||
|
||||
this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer
|
||||
if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it
|
||||
var temp_parent = this.tags.parent; //check to see if it's a closable tag.
|
||||
@ -151,7 +151,7 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.get_tag = function () { //function to get a full tag and parse its type
|
||||
var char = '';
|
||||
var content = [];
|
||||
@ -161,28 +161,28 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
if (this.pos >= this.input.length) {
|
||||
return content.length?content.join(''):['', 'TK_EOF'];
|
||||
}
|
||||
|
||||
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++;
|
||||
this.line_char_count++;
|
||||
|
||||
|
||||
if (this.Utils.in_array(char, this.Utils.whitespace)) { //don't want to insert unnecessary space
|
||||
space = true;
|
||||
this.line_char_count--;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (char === "'" || char === '"') {
|
||||
if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially
|
||||
char += this.get_unformatted(char);
|
||||
space = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (char === '=') { //no space before =
|
||||
space = false;
|
||||
}
|
||||
|
||||
|
||||
if (content.length && content[content.length-1] !== '=' && char !== '>'
|
||||
&& space) { //no space after = or before >
|
||||
if (this.line_char_count >= this.max_char) {
|
||||
@ -197,7 +197,7 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
content.push(char); //inserts character at-a-time (or string)
|
||||
} while (char !== '>');
|
||||
|
||||
|
||||
var tag_complete = content.join('');
|
||||
var tag_index;
|
||||
if (tag_complete.indexOf(' ') != -1) { //if there's whitespace, thats where the tag name ends
|
||||
@ -257,9 +257,9 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
return content.join(''); //returns fully formatted tag
|
||||
}
|
||||
|
||||
|
||||
this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety
|
||||
|
||||
|
||||
if (orig_tag && orig_tag.indexOf(delimiter) != -1) {
|
||||
return '';
|
||||
}
|
||||
@ -267,11 +267,11 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
var content = '';
|
||||
var space = true;
|
||||
do {
|
||||
|
||||
|
||||
|
||||
|
||||
char = this.input.charAt(this.pos);
|
||||
this.pos++
|
||||
|
||||
|
||||
if (this.Utils.in_array(char, this.Utils.whitespace)) {
|
||||
if (!space) {
|
||||
this.line_char_count--;
|
||||
@ -290,21 +290,22 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
content += char;
|
||||
this.line_char_count++;
|
||||
space = true;
|
||||
|
||||
|
||||
|
||||
|
||||
} while (content.indexOf(delimiter) == -1);
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
this.get_token = function () { //initial handler for token-retrieval
|
||||
var token;
|
||||
|
||||
|
||||
if (this.last_token === 'TK_TAG_SCRIPT') { //check if we need to format javascript
|
||||
var temp_token = this.get_script();
|
||||
if (typeof temp_token !== 'string') {
|
||||
return temp_token;
|
||||
}
|
||||
token = js_beautify(temp_token, this.indent_size, this.indent_character, this.indent_level); //call the JS Beautifier
|
||||
token = js_beautify(temp_token,
|
||||
{indent_size: this.indent_size, indent_char: this.indent_character, indent_level: this.indent_level}); //call the JS Beautifier
|
||||
return [token, 'TK_CONTENT'];
|
||||
}
|
||||
if (this.current_mode === 'CONTENT') {
|
||||
@ -316,7 +317,7 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
return [token, 'TK_CONTENT'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(this.current_mode === 'TAG') {
|
||||
token = this.get_tag();
|
||||
if (typeof token !== 'string') {
|
||||
@ -328,9 +329,9 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.printer = function (js_source, indent_character, indent_size, max_char) { //handles input/output and some other printing functions
|
||||
|
||||
|
||||
this.input = js_source || ''; //gets the input for the Parser
|
||||
this.output = [];
|
||||
this.indent_character = indent_character || ' ';
|
||||
@ -339,11 +340,11 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
this.indent_level = 0;
|
||||
this.max_char = max_char || 70; //maximum amount of characters per line
|
||||
this.line_char_count = 0; //count to see if max_char was exceeded
|
||||
|
||||
|
||||
for (var i=0; i<this.indent_size; i++) {
|
||||
this.indent_string += this.indent_character;
|
||||
}
|
||||
|
||||
|
||||
this.print_newline = function (ignore, arr) {
|
||||
this.line_char_count = 0;
|
||||
if (!arr || !arr.length) {
|
||||
@ -359,16 +360,16 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
arr.push(this.indent_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
this.print_token = function (text) {
|
||||
this.output.push(text);
|
||||
}
|
||||
|
||||
|
||||
this.indent = function () {
|
||||
this.indent_level++;
|
||||
}
|
||||
|
||||
|
||||
this.unindent = function () {
|
||||
if (this.indent_level > 0) {
|
||||
this.indent_level--;
|
||||
@ -377,25 +378,25 @@ function style_html(html_source, indent_size, indent_character, max_char) {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/*_____________________--------------------_____________________*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
multi_parser = new Parser(); //wrapping functions Parser
|
||||
multi_parser.printer(html_source, indent_character, indent_size); //initialize starting values
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
while (true) {
|
||||
var t = multi_parser.get_token();
|
||||
multi_parser.token_text = t[0];
|
||||
multi_parser.token_type = t[1];
|
||||
|
||||
|
||||
if (multi_parser.token_type === 'TK_EOF') {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
switch (multi_parser.token_type) {
|
||||
case 'TK_TAG_START': case 'TK_TAG_SCRIPT': case 'TK_TAG_STYLE':
|
||||
|
@ -5,6 +5,7 @@ var test_result = '';
|
||||
|
||||
var indent_size = 4;
|
||||
var indent_char = ' ';
|
||||
var preserve_newlines = true;
|
||||
|
||||
function lazy_escape(str)
|
||||
{
|
||||
@ -15,7 +16,7 @@ function bt(input, expected)
|
||||
{
|
||||
expected = expected || input;
|
||||
|
||||
result = js_beautify(input, indent_size, indent_char);
|
||||
result = js_beautify(input, {indent_size:indent_size, indent_char:indent_char, preserve_newlines:preserve_newlines});
|
||||
|
||||
if (result != expected) {
|
||||
test_result +=
|
||||
@ -145,14 +146,21 @@ function test_js_beautify()
|
||||
|
||||
indent_size = 1;
|
||||
indent_char = ' ';
|
||||
bt('{ one_char() }', "{\n one_char()\n}")
|
||||
bt('{ one_char() }', "{\n one_char()\n}");
|
||||
|
||||
indent_size = 4;
|
||||
indent_char = ' ';
|
||||
bt('{ one_char() }', "{\n one_char()\n}")
|
||||
bt('{ one_char() }', "{\n one_char()\n}");
|
||||
|
||||
indent_size = 1;
|
||||
indent_char = "\t";
|
||||
bt('{ one_char() }', "{\n\tone_char()\n}")
|
||||
bt('{ one_char() }', "{\n\tone_char()\n}");
|
||||
|
||||
preserve_newlines = false;
|
||||
bt('var\na=dont_preserve_newlines', 'var a = dont_preserve_newlines');
|
||||
|
||||
preserve_newlines = true;
|
||||
bt('var\na=do_preserve_newlines', 'var\na = do_preserve_newlines');
|
||||
|
||||
return results();
|
||||
}
|
||||
|
55
beautify.js
55
beautify.js
@ -6,7 +6,7 @@
|
||||
$Revision$
|
||||
|
||||
|
||||
Written by Einars "elfz" Lielmanis, <elfz@laacz.lv>
|
||||
Written by Einars Lielmanis, <einars@gmail.com>
|
||||
http://elfz.laacz.lv/beautify/
|
||||
|
||||
Originally converted to javascript by Vital, <vital76@gmail.com>
|
||||
@ -17,16 +17,39 @@
|
||||
|
||||
Usage:
|
||||
js_beautify(js_source_text);
|
||||
js_beautify(js_source_text, options);
|
||||
|
||||
The options are:
|
||||
indent_size (default 4) — indentation size,
|
||||
indent_char (default space) — character to indent with,
|
||||
preserve_newlines (default true) — whether existing line breaks should be preserved,
|
||||
indent_level (default 0) — initial indentation level, you probably won't need this ever,
|
||||
|
||||
e.g
|
||||
|
||||
js_beautify(js_source_text, {indent_size: 1, indent_char: '\t'});
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
function js_beautify(js_source_text, indent_size, indent_character, indent_level)
|
||||
|
||||
function js_beautify(js_source_text, options)
|
||||
{
|
||||
|
||||
var input, output, token_text, last_type, last_text, last_word, current_mode, modes, indent_string;
|
||||
var whitespace, wordchar, punct, parser_pos, line_starters, in_case;
|
||||
var prefix, token_type, do_block_just_closed, var_line, var_line_tainted, if_line_flag;
|
||||
var indent_level;
|
||||
|
||||
|
||||
var options = options || {};
|
||||
var opt_indent_size = options['indent_size'] || 4;
|
||||
var opt_indent_char = options['indent_char'] || ' ';
|
||||
var opt_preserve_newlines =
|
||||
typeof options['preserve_newlines'] === 'undefined' ? true : options['preserve_newlines'];
|
||||
var opt_indent_level = options['indent_level'] || 0; // starting indentation
|
||||
|
||||
|
||||
function trim_output()
|
||||
{
|
||||
@ -138,12 +161,16 @@ function js_beautify(js_source_text, indent_size, indent_character, indent_level
|
||||
}
|
||||
while (in_array(c, whitespace));
|
||||
|
||||
if (n_newlines > 1) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
print_newline(i === 0);
|
||||
var wanted_newline = false;
|
||||
|
||||
if (opt_preserve_newlines) {
|
||||
if (n_newlines > 1) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
print_newline(i === 0);
|
||||
}
|
||||
}
|
||||
wanted_newline = (n_newlines === 1);
|
||||
}
|
||||
var wanted_newline = (n_newlines === 1);
|
||||
|
||||
|
||||
if (in_array(c, wordchar)) {
|
||||
@ -287,14 +314,13 @@ function js_beautify(js_source_text, indent_size, indent_character, indent_level
|
||||
|
||||
//----------------------------------
|
||||
|
||||
indent_character = indent_character || ' ';
|
||||
indent_size = indent_size || 4;
|
||||
|
||||
indent_string = '';
|
||||
while (indent_size--) {
|
||||
indent_string += indent_character;
|
||||
while (opt_indent_size--) {
|
||||
indent_string += opt_indent_char;
|
||||
}
|
||||
|
||||
indent_level = opt_indent_level;
|
||||
|
||||
input = js_source_text;
|
||||
|
||||
last_word = ''; // last 'TK_WORD' passed
|
||||
@ -303,8 +329,8 @@ function js_beautify(js_source_text, indent_size, indent_character, indent_level
|
||||
output = [];
|
||||
|
||||
do_block_just_closed = false;
|
||||
var_line = false;
|
||||
var_line_tainted = false;
|
||||
var_line = false; // currently drawing var .... ;
|
||||
var_line_tainted = false; // false: var a = 5; true: var a = 5, b = 6
|
||||
|
||||
whitespace = "\n\r\t ".split('');
|
||||
wordchar = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$'.split('');
|
||||
@ -318,8 +344,7 @@ function js_beautify(js_source_text, indent_size, indent_character, indent_level
|
||||
current_mode = 'BLOCK';
|
||||
modes = [current_mode];
|
||||
|
||||
indent_level = indent_level || 0;
|
||||
parser_pos = 0; // parser position
|
||||
parser_pos = 0;
|
||||
in_case = false; // flag for parser that case/default has been processed, and next colon needs special attention
|
||||
while (true) {
|
||||
var t = get_next_token(parser_pos);
|
||||
|
20
index.html
20
index.html
@ -18,17 +18,21 @@ window.onload = function() {
|
||||
function do_js_beautify()
|
||||
{
|
||||
document.getElementById('beautify').disabled = true;
|
||||
js_source = document.getElementById('content').value.replace(/^\s+/, '');
|
||||
tabsize = document.getElementById('tabsize').value;
|
||||
tabchar = ' ';
|
||||
if (tabsize == 1) {
|
||||
tabchar = '\t';
|
||||
var js_source = document.getElementById('content').value.replace(/^\s+/, '');
|
||||
var indent_size = document.getElementById('tabsize').value;
|
||||
var indent_char = ' ';
|
||||
var preserve_newlines = document.getElementById('preserve-newlines').checked;
|
||||
|
||||
if (indent_size == 1) {
|
||||
indent_char = '\t';
|
||||
}
|
||||
|
||||
|
||||
if (js_source && js_source[0] === '<') {
|
||||
document.getElementById('content').value = style_html(js_source, tabsize, tabchar, 80);
|
||||
document.getElementById('content').value = style_html(js_source, tabsize, indent_char, 80);
|
||||
} else {
|
||||
document.getElementById('content').value = js_beautify(js_source, tabsize, tabchar);
|
||||
document.getElementById('content').value =
|
||||
js_beautify(js_source, {indent_size: indent_size, indent_char: indent_char, preserve_newlines:preserve_newlines});
|
||||
}
|
||||
|
||||
document.getElementById('beautify').disabled = false;
|
||||
@ -66,6 +70,8 @@ var latest_changes=new Object({'2008-12-04':'Moved to github.com','2008-02-22':'
|
||||
<option value="4" selected="selected">indent with 4 spaces</option>
|
||||
<option value="8">indent with 8 spaces</option>
|
||||
</select>
|
||||
<input type="checkbox" id="preserve-newlines" /><label for="preserve-newlines"> Preserve existing line
|
||||
breaks?</label>
|
||||
<p>You can always see the latest version of the code in github — <a
|
||||
href="http://github.com/einars/js-beautify">http://github.com/einars/js-beautify</a>.</p>
|
||||
<p>If you're writing javascript, <a href="http://jslint.com/">JSLint</a> is a really fine piece of software, too. You should at least understand what and why it says about your code — to be a better person. Even if it hurts your feelings.</p>
|
||||
|
Loading…
Reference in New Issue
Block a user