From 9eaf45acab5be25cd28a6022ef2b72ab306cde56 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 13 Jun 2013 20:21:41 -0500 Subject: [PATCH] parsable attribute tags. --- example/ping | 5 ++-- lib/program.js | 3 +++ lib/widget.js | 65 ++++++++++++++++++++++++++++++++++++++------------ test/widget.js | 3 ++- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/example/ping b/example/ping index 3e7afeb..d29ae63 100755 --- a/example/ping +++ b/example/ping @@ -85,7 +85,8 @@ var score = new blessed.Box({ }, shrink: true, //align: 'center', - bold: true + bold: true, + tags: true }); score.lwins = 0; @@ -174,7 +175,7 @@ function reset() { lpaddle.rtop = 0; rpaddle.rtop = 0; - score.setContent('Score: ' + score.lwins + ' | ' + score.rwins); + score.setContent('{green-fg}Score:{/} ' + score.lwins + ' | ' + score.rwins); rpaddle.movable = true; diff --git a/lib/program.js b/lib/program.js index 6158126..ca511f1 100644 --- a/lib/program.js +++ b/lib/program.js @@ -1262,11 +1262,14 @@ Program.prototype._attr = function(param, val) { switch (param) { // attributes case 'normal': + case 'default': return '\x1b[m'; case 'bold': return val === false ? '\x1b[22m' : '\x1b[1m'; + case 'ul': + case 'underline': case 'underlined': return val === false ? '\x1b[24m' diff --git a/lib/widget.js b/lib/widget.js index 9c2ff53..f052382 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -433,9 +433,6 @@ Screen.prototype.draw = function(start, end) { out += '48;5;' + bgColor + ';'; } } - //else { - // out += '49;'; - //} if (fgColor !== 0x1ff) { if (fgColor < 16 || (this.tput && this.tput.colors <= 16)) { @@ -450,9 +447,6 @@ Screen.prototype.draw = function(start, end) { out += '38;5;' + fgColor + ';'; } } - //else { - // out += '39;'; - //} if (out[out.length-1] === ';') out = out.slice(0, -1); @@ -602,7 +596,9 @@ function Element(options) { this.screen._listenKeys(this); } - this.content = options.content || ''; + this.parseTags = options.parseTags || options.tags; + // TODO: Maybe simply set _pcontent with _parseTags result. + this.content = this._parseTags(options.content || ''); if (options.label) { this.append(new Box({ @@ -682,7 +678,8 @@ Element.prototype.focus = function() { Element.prototype.setContent = function(content) { var ret = this.render(true); - this.content = content || ''; + // TODO: Maybe simply set _pcontent with _parseTags result. + this.content = this._parseTags(content || ''); this.screen.clearRegion( ret.xi + (this.border ? 1 : 0), ret.xl - (this.border ? 1 : 0), @@ -690,6 +687,25 @@ Element.prototype.setContent = function(content) { ret.yl - (this.border ? 1 : 0)); }; +// Convert `{red-fg}foo{/red-fg}` to `\x1b[31mfoo\x1b[39m`. +Element.prototype._parseTags = function(text) { + if (!this.parseTags) return text; + var program = this.screen.program; + return text.replace(/{(\/?)([\w\-,;!]*)}/g, function(tag, slash, color) { + if (!color) return slash ? '\x1b[m' : tag; + + color = color.replace(/-/g, ' '); + var result = program._attr(color, !slash); + + // Parse error. Just return the original text. + if (!/^\x1b\[[\d;]*m$/.test(result)) { + return tag; + } + + return result; + }); +}; + /** * Positioning */ @@ -1870,27 +1886,42 @@ function attrCode(code, cur) { for (i = 0; i < code.length; i++) { c = +code[i] || 0; switch (c) { - case 0: + case 0: // normal bg = 0x1ff; fg = 0x1ff; flags = 0; break; - case 1: + case 1: // bold flags |= 1; break; - case 4: + case 22: + flags &= ~1; + break; + case 4: // underline flags |= 2; break; - case 5: + case 24: + flags &= ~2; + break; + case 5: // blink flags |= 4; break; - case 7: + case 25: + flags &= ~4; + break; + case 7: // inverse flags |= 8; break; - case 8: + case 27: + flags &= ~8; + break; + case 8: // invisible flags |= 16; break; - default: + case 28: + flags &= ~16; + break; + default: // color if (c === 48 && code[i+1] === '5') { i += 2; bg = +code[i]; @@ -1905,11 +1936,15 @@ function attrCode(code, cur) { } else if (c >= 100 && c <= 107) { bg = c - 100; bg += 8; + } else if (c === 49) { + bg = 0x1ff; } else if (c >= 30 && c <= 37) { fg = c - 30; } else if (c >= 90 && c <= 97) { fg = c - 90; fg += 8; + } else if (c === 39) { + fg = 0x1ff; } break; } diff --git a/test/widget.js b/test/widget.js index 8c43974..266f1b6 100644 --- a/test/widget.js +++ b/test/widget.js @@ -9,7 +9,8 @@ screen.append(new blessed.Text({ top: 0, left: 2, width: '100%', - content: 'Welcome to my program', + content: '{green-fg}Welcome{/green-fg} to my {red-bg,underlined}program{/}', + tags: true, align: 'center' }));