Skip to content

Instantly share code, notes, and snippets.

@v2e4lisp
Created December 5, 2012 10:32
Show Gist options
  • Save v2e4lisp/4214579 to your computer and use it in GitHub Desktop.
Save v2e4lisp/4214579 to your computer and use it in GitHub Desktop.
javascript minifier written in javascript (todo);
var jsmin = function (js_string) {
js_min = {
holder: '/*wenjun.yan*/', // the minified js
pos: 0, // current position
chr: ' ', // current char
js_string: js_string, // unminified js
specs: ["'", '"', '{', '}', '(', ')',
'[', ']', '+', '-', '*', '/',
':', '?', '!', '|', '&', '\\',';'],
// exit and show error message;
error: function () {
throw "Error! current position: " + this.pos +
" current char: " + this.chr +
" \n the holder value : " + this.holder;
},
// check if current char is ' or "
is_string: function () {
return this.chr === '"' || this.chr === "'";
},
// check if current char is in a specs table
is_special: function () {
return this.specs.indexOf(this.chr) > -1? true: false;
},
// check if current char is a digit
is_word: function () {
var chr = this.chr;
return (chr > '0' && chr < '9') ||
(chr > 'a' && chr < 'z') ||
(chr > 'A' && chr < 'Z') ||
chr === '$' || chr === '_' ||
chr.charCodeAt(0) > 126;
},
// check if current char is blank of any kind
is_blank: function () {
return ' \t\r\n\v'.indexOf(this.chr) > -1? true: false;
},
// check if the current char is the beginning of a comment;
is_comment: function () {
var t = this.peek();
if (this.chr === '/' && (t === '*' || t === '/')) {
this.next();
return true;
}
return false;
},
// save the whole string into holder;
string: function () {
this.save();
var s = '';
var string = '';
if (this.chr === '"') {
s = this.chr;
}
if (this.chr === "'") {
s = this.chr;
}
if (!s) {
console.log("error1");
this.error();
}
while(!(this.chr !== '\\' && this.next().chr === s)) {
this.save();
}
return this.save('"').next();
},
// skip the special chars and following blanks
// undone!!
special: function () {
return this.save().blank();
},
// skip the comment;
comment: function () {
var tmp = this.next().chr;
if (tmp === '/') {
while(this.next().chr !== '\n') {}
return this.next();
} else if (tmp === '*') {
while(this.next().chr) {
if (this.next().chr === '/') {
return this.next();
}
}
console.log("error2");
this.error();
} else {
console.log("error3");
this.error();
}
},
// skip the word (any javascript word) and save it;
word: function () {
var tmp = chr;
while(this.next().chr) {
tmp += this.chr;
}
return this.save(tmp);
},
// skip blank;
blank: function () {
console.log("stepin blank: " + this.chr);
while (this.next().is_blank()) {console.log(this.chr);}
console.log("stepout blank: " + this.chr);
return this;
},
// get next char and update the pos and chr
next: function () {
console.log ("step in next: " + this.chr);
this.pos += 1;
this.chr = this.js_string[this.pos];
console.log ("step out next: " + this.chr);
return this;
},
// get the next char but not update the pos and chr
peek: function () {
return this.js_string[this.pos+1];
},
// save the current char or the word (if there is) to holder
save: function (word) {
if (word) {
this.holder += word;
} else {
this.holder += this.chr;
}
return this;
},
// run
run: function () {
// state stands for the type of the last saved token
// 0: specs
// 1: word, string
var state = 0;
while(this.pos <= this.js_string.length) {
console.log("WHILE current char : " + this.chr,this.peek());
if (this.is_blank()) {
this.blank();
console.log("BLANK current char : " + this.chr);
} else if (this.is_string()) {
console.log("STRING current char : " + this.chr);
if (state !== 0) {
this.save(' ');
state = 1;
}
this.string();
} else if (this.is_special()) {
console.log("SPECIAL current char : " + this.chr);
state = 0;
this.special();
} else if (this.is_comment()) {
console.log("COMMENT current char : " + this.chr);
this.comment();
} else if (this.is_word()) {
console.log("WORD current char : " + this.chr);
if (state !== 0) {
this.save(' ');
state = 1;
}
this.word();
} else {
console.log("ERROR current char : " + this.chr);
console.log("error4");
this.error();
}
}
return this.holder;
}
};
return js_min.run();
};
// comment: skip to the end;
// string: skip to the end of the string and save it;
// special: save it and then skip all following blank;
// word: skip to the end of the word, temp it at the same time. Then save it;
js_str = "var a = 1;"
console.log(jsmin(js_str));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment