diff --git a/lib/tput.js b/lib/tput.js index d3fe228..707e059 100644 --- a/lib/tput.js +++ b/lib/tput.js @@ -330,19 +330,7 @@ Tput.prototype._compile = function(val) { function clear() { if (buff) { - code += 'out.push(' - + JSON.stringify(buff).replace(/\\u001b/g, '\\x1b') - + '),'; - // code += 'out.push("'; - // code += buff - // .replace(/"/g, '\\"') - // .replace(/\x1b/g, '\\x1b') - // .replace(/\r/g, '\\r') - // .replace(/\n/g, '\\n') - // .replace(/\x07/g, '\\x07') - // .replace(/\x08/g, '\\x08') - // .replace(/\t/g, '\\t'); - // code += '"),'; + echo(JSON.stringify(buff).replace(/\\u001b/g, '\\x1b')); buff = ''; } } @@ -356,128 +344,142 @@ Tput.prototype._compile = function(val) { return cap; } - function stmt() { - if (code[code.length-1] === ',') code = code.slice(0, -1); + function stmt(c) { + if (code[code.length-1] === ',') { + code = code.slice(0, -1); + } + code += c; + // code += ';' + c; + } + + function expr(c) { + code += c + ','; + // code += '(' + c + '),'; + } + + function echo(c) { + expr('out.push(' + c + ')'); + } + + function print(c) { + echo('"' + c + '"'); } while (val) { // '\e' -> ^[ if (read(/^\\e/i)) { - code += 'out.push("'; - code += '\\x1b'; - code += '"),'; + print('\\x1b'); continue; } // '^A' -> ^A // case-insensitive? if (read(/^\^(.)/i)) { - code += 'out.push("'; switch (ch.toUpperCase()) { case '@': - code += '\\x00'; + ch = '\\x00'; break; case 'A': - code += '\\x01'; + ch = '\\x01'; break; case 'B': - code += '\\x02'; + ch = '\\x02'; break; case 'C': - code += '\\x03'; + ch = '\\x03'; break; case 'D': - code += '\\x04'; + ch = '\\x04'; break; case 'E': - code += '\\x05'; + ch = '\\x05'; break; case 'F': - code += '\\x06'; + ch = '\\x06'; break; case 'G': - code += '\\x07'; + ch = '\\x07'; break; case 'H': - code += '\\x08'; + ch = '\\x08'; break; case 'I': - code += '\\x09'; // \t + ch = '\\x09'; // \t break; case 'J': - code += '\\x0a'; // \n + ch = '\\x0a'; // \n break; case 'K': - code += '\\x0b'; + ch = '\\x0b'; break; case 'L': - code += '\\x0c'; + ch = '\\x0c'; break; case 'M': - code += '\\x0d'; + ch = '\\x0d'; break; case 'N': - code += '\\x0e'; + ch = '\\x0e'; break; case 'O': - code += '\\x0f'; + ch = '\\x0f'; break; case 'P': - code += '\\x10'; + ch = '\\x10'; break; case 'Q': - code += '\\x11'; + ch = '\\x11'; break; case 'R': - code += '\\x12'; + ch = '\\x12'; break; case 'S': - code += '\\x13'; + ch = '\\x13'; break; case 'T': - code += '\\x14'; + ch = '\\x14'; break; case 'U': - code += '\\x15'; + ch = '\\x15'; break; case 'V': - code += '\\x16'; + ch = '\\x16'; break; case 'W': - code += '\\x17'; + ch = '\\x17'; break; case 'X': - code += '\\x18'; + ch = '\\x18'; break; case 'Y': - code += '\\x19'; + ch = '\\x19'; break; case 'Z': - code += '\\x1a'; + ch = '\\x1a'; break; case '\\': - code += '\\x1c'; + ch = '\\x1c'; break; case '^': - code += '\\x1e'; + ch = '\\x1e'; break; case '_': - code += '\\x1f'; + ch = '\\x1f'; break; case '[': - code += '\\x1b'; + ch = '\\x1b'; break; case ']': - code += '\\x1d'; + ch = '\\x1d'; break; case '?': - code += '\\x7f'; + ch = '\\x7f'; break; default: - code += '\\' + ch; + ch = '\\' + ch; break; } - code += '"),'; + print(ch); continue; } @@ -485,75 +487,71 @@ Tput.prototype._compile = function(val) { // '\r' -> \r // '\0' -> \200 (special case) if (read(/^\\([nlrtbfs\^\\,:0])/)) { - code += 'out.push("'; switch (ch) { case 'n': - code += '\\n'; + ch = '\\n'; break; case 'l': - code += ''; + ch = ''; break; case 'r': - code += '\\r'; + ch = '\\r'; break; case 't': - code += '\\t'; + ch = '\\t'; break; case 'b': - code += '\\x08'; + ch = '\\x08'; break; case 'f': - code += '\\x0c'; + ch = '\\x0c'; break; case 's': - code += ' '; + ch = ' '; break; case '\\': - code += '\\\\'; + ch = '\\\\'; break; case ',': - code += ','; + ch = ','; break; case ';': - code += ';'; + ch = ';'; break; case '0': - //code += '\\0'; - code += '\\200'; + //ch = '\\0'; + ch = '\\200'; break; //case 'v': - // code += '\\x0b'; + // ch = '\\x0b'; // break; //case 'a': - // code += '\\x07': + // ch = '\\x07': // break; + default: + ch = ''; + break; } - code += '"),'; + print(ch); continue; } // 3 octal digits -> character if (read(/^\\(\d\d\d)/)) { - code += 'out.push("'; - code += '\\' + ch; - //code += String.fromCharCode(parseInt(ch, 8)); - code += '"),'; + print('\\' + ch); continue; } // $<5> -> padding // e.g. flash_screen: '\u001b[?5h$<100/>\u001b[?5l', if (read(/^\$<(\d+)>(\*|\/)/)) { - code += 'out.push("'; - code += '"),'; + print(''); continue; } // %% outputs `%' if (read(/^%%/)) { - code += 'out.push("'; - code += '%'; - code += '"),'; + print('%'); continue; } @@ -562,61 +560,54 @@ Tput.prototype._compile = function(val) { // next character to be a `-' flag, avoiding interpreting "%-" as an // operator. if (read(/^%(:-|[+# ])(?:(\d+)(\.\d+)?)?([doxXs])?/)) { - code += 'out.push("'; - code += '"),'; + print(''); continue; } // %c print pop() like %c in printf if (read(/^%c/)) { - code += 'out.push('; - code += 'stack.pop()'; // TODO: FORMAT - code += '),'; + echo('stack.pop()'); continue; } // %d print pop() like %d in printf // NOT SURE ABOUT %d being print! if (read(/^%d/)) { - code += 'out.push('; - code += 'stack.pop()'; // TODO: FORMAT - code += '),'; + echo('stack.pop()'); continue; } // %s print pop() like %s in printf if (read(/^%s/)) { - code += 'out.push('; - code += 'stack.pop()'; // TODO: FORMAT - code += '),'; + echo('stack.pop()'); continue; } // %p[1-9] // push i'th parameter if (read(/^%p([1-9])/)) { - code += '(stack.push(v = params[' + (i - 1) + ']), v),'; + expr('(stack.push(v = params[' + (i - 1) + ']), v)'); continue; } // %P[a-z] // set dynamic variable [a-z] to pop() if (read(/^%P([a-z])/)) { - code += 'dyn.' + v + ' = stack.pop(),'; + expr('dyn.' + v + ' = stack.pop()'); continue; } // %g[a-z] // get dynamic variable [a-z] and push it if (read(/^%g([a-z])/)) { - code += '(stack.push(dyn.' + v + '), dyn.' + v + '),'; + expr('(stack.push(dyn.' + v + '), dyn.' + v + ')'); continue; } // %P[A-Z] // set static variable [a-z] to pop() if (read(/^%P([A-Z])/)) { - code += 'stat.' + v + ' = stack.pop(),'; + expr('stat.' + v + ' = stack.pop()'); continue; } @@ -630,26 +621,26 @@ Tput.prototype._compile = function(val) { // impact portability to other implementations. if (read(/^%g([A-Z])/)) { - code += '(stack.push(v = stat.' + v + '), v),'; + expr('(stack.push(v = stat.' + v + '), v)'); continue; } // %'c' char constant c if (read(/^%'(\w)'/)) { - code += '(stack.push(v = "' + ch + '", v),'; + expr('(stack.push(v = "' + ch + '", v)'); continue; } // %{nn} // integer constant nn if (read(/^%\{(\d+)\}/)) { - code += '(stack.push(v = ' + ch + '), v),'; + expr('(stack.push(v = ' + ch + '), v)'); continue; } // %l push strlen(pop) if (read(/^%l/)) { - code += '(stack.push(v = stack.pop().length), v),'; + expr('(stack.push(v = stack.pop().length), v)'); continue; } @@ -662,28 +653,27 @@ Tput.prototype._compile = function(val) { if (read(/^%([+\-*\/m&|\^=><])/)) { if (op === '=') op = '==='; else if (op === 'm') op = '%'; - code += '(stack.push(v = (stack.pop() ' + op + ' stack.pop())), v),'; + expr('(stack.push(v = (stack.pop() ' + op + ' stack.pop())), v)'); continue; } // %A, %O // logical AND and OR operations (for conditionals) if (read(/^%([AO])/)) { - stmt(); - code += op === ' A ' ? ' && ' : ' || '; + stmt(op === ' A ' ? ' && ' : ' || '); continue; } // %! %~ // unary operations (logical and bit complement): push(op pop()) if (read(/^%([!~])/)) { - code += '(stack.push(v = ' + op + 'stack.pop()), v),'; + expr('(stack.push(v = ' + op + 'stack.pop()), v)'); continue; } // %i add 1 to first two parameters (for ANSI terminals) if (read(/^%i/)) { - code += '(params[0]++, params[1]++),'; + expr('(params[0]++, params[1]++)'); continue; } @@ -703,34 +693,30 @@ Tput.prototype._compile = function(val) { // written on one line. The -f option splits the string into lines with // the parts indented. if (read(/^%\?/)) { - stmt(); - code += ';if ('; + stmt(';if ('); continue; } if (read(/^%t/)) { - stmt(); - code += ') {'; + stmt(') {'); continue; } if (read(/^%e/)) { - stmt(); var end = val.indexOf('%;'); var els = val.indexOf('%e'); var then = val.indexOf('%t'); // does else if's like this: %?[expr]%t...%e[expr]%t...%; if (then < end && then < els) { - code += '} else if ('; + stmt('} else if ('); } else { - code += '} else {'; + stmt('} else {'); } continue; } if (read(/^%;/)) { - stmt(); - code += '}'; + stmt('}'); continue; } @@ -768,8 +754,7 @@ Tput.prototype._compile = function(val) { clear(); - stmt(); - code += ';return out.join("");'; + stmt(';return out.join("");'); // Optimize // ... out.push("foo");return out.join("");