Permalink
Browse files

change indent/outdent application

  • Loading branch information...
1 parent 131fabb commit 7e50d68a444d4051d3e93a529e844f7841910b5d @chjj committed Mar 7, 2012
Showing with 61 additions and 21 deletions.
  1. +61 −21 lib/lexer.js
View
@@ -4,14 +4,8 @@
*/
var lexer = function(str, options) {
- options.pretty = true;
-
- str = str
- .replace(/\r\n|\r/g, '\n')
- .replace(/"/g, '\\"');
-
var i = 0
- , l = str.length
+ , l
, ch
, buff = ''
, key
@@ -22,7 +16,24 @@ var lexer = function(str, options) {
, indent = 0
, indents = []
, newline = true
- , indentSize = 0;
+ , indentSize;
+
+ options.pretty = true;
+ options.indent = 1;
+
+ str = str
+ .replace(/\r\n|\r/g, '\n')
+ .replace(/"/g, '\\"');
+
+ if (options.indent || options.pretty) {
+ indentSize = getIndentSize(str);
+ }
+
+ if (options.indent) {
+ str = applyIndent(str, options.indent * indentSize);
+ }
+
+ l = str.length;
var state = function() {
return stack[stack.length-1];
@@ -31,22 +42,15 @@ var lexer = function(str, options) {
var out = function() {
if (!options.pretty) return buff;
var i = indents.length * indentSize;
- if (i) buff = outdent(buff, i);
- if (options.indent) {
- i = options.indent * indentSize;
- buff = indent(buff, i);
- }
- return buff;
+ if (!i) return buff;
+ return applyOutdent(buff, i);
};
for (; i < l; i++) {
ch = str[i];
offset++;
if (ch > ' ' && newline) {
- if (!indentSize && indent < buff.length) {
- indentSize = buff.length - indent;
- }
// We could use offset - 1 here
// instead of buff.length.
indent = buff.length;
@@ -192,16 +196,52 @@ var lexer = function(str, options) {
return tokens;
};
-var outdent = function(str, n) {
+var applyOutdent = function(str, n) {
if (!n) return str;
- return str.replace(new RegExp('^ {' + n + '}', 'gm'), '');
+ return str.replace(new RegExp('^[ \t]{' + n + '}', 'gm'), '');
};
-var indent = function(str, n) {
+var applyIndent = function(str, n) {
if (!n) return str;
- return str.replace(/^/gm, Array(n).join(' '));
+ var s = '';
+ while (n--) s += ' ';
+ return str.replace(/^/gm, s);
};
+var getIndentSize = function(str) {
+ var start = /^([ \t]+)/.exec(str);
+ if (start) str = applyOutdent(str, start[1].length);
+ var size = /\n([ \t]+)/.exec(str);
+ return size ? size[1].length : 0;
+};
+
+var getIndentSize_ = function(str) {
+ var i = 0
+ , l = str.length
+ , indent = 0
+ , offset = 0
+ , newline = true
+ , ch;
+
+ for (; i < l; i++) {
+ ch = buff[i];
+ if (ch > ' ' && newline) {
+ if (indent < offset) {
+ return buff.length - indent;
+ }
+ newline = false;
+ }
+ if (ch === '\n') {
+ offset = 0;
+ newline = true;
+ }
+ offset++;
+ }
+
+ return 0;
+};
+
+
/**
* Expose
*/

0 comments on commit 7e50d68

Please sign in to comment.