Skip to content

Commit

Permalink
Refactor all text entities to be text nodes
Browse files Browse the repository at this point in the history
Previously we had several ways text was stored:

* As a property on a Tag node
* As multiple nodes in a Text node
* As multiple Text nodes in a Block node

We have decided upon simplifying the Text node to just being a piece of text.

Multiple lines of text become multiple Text nodes in a Block.

There is no more text property in the Tag node.

And pretty printing for Text blocks is also supported now.
  • Loading branch information
chowey authored and tj committed Apr 18, 2012
1 parent 14ef550 commit d495a7b
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 40 deletions.
55 changes: 39 additions & 16 deletions lib/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,23 @@ Compiler.prototype = {
}
},

/**
* Buffer an indent based on the current `indent` property and an additional
* `offset`.
*
* @param {Number} offset
* @param {Boolean} newline (defaults to true)
* @api public
*/

prettyIndent: function (offset, newline) {
offset = offset || 0;
(newline === false) ? newline = '' : newline = '\\n';
this.buffer(newline + Array(this.indents + offset).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
},

/**
* Visit `node`.
*
Expand Down Expand Up @@ -155,8 +172,7 @@ Compiler.prototype = {
*/

visitNode: function(node){
var name = node.constructor.name
|| node.constructor.toString().match(/function ([^(\s]+)()/)[1];
var name = node.getType();
return this['visit' + name](node);
},

Expand Down Expand Up @@ -214,8 +230,23 @@ Compiler.prototype = {

visitBlock: function(block){
var len = block.nodes.length;

// Pretty print multi-line text
if (this.pp && len > 1 && !this.escape
&& block.nodes[0].getType() === 'Text'
&& block.nodes[1].getType() === 'Text')
this.prettyIndent(1);

for (var i = 0; i < len; ++i) {
// Pretty print text
if (this.pp && i > 0 && !this.escape && block.nodes[0].getType() === 'Text')
this.prettyIndent(1, false)

this.visit(block.nodes[i]);
// Multiple text nodes are separated by newlines
if (block.nodes[i+1] && block.nodes[i].getType() === 'Text'
&& block.nodes[i+1].getType() === 'Text')
this.buffer('\\n');
}
},

Expand Down Expand Up @@ -283,9 +314,7 @@ Compiler.prototype = {

// pretty print
if (this.pp && inlineTags.indexOf(name) == -1) {
this.buffer('\\n' + Array(this.indents).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
this.prettyIndent();
}

if (~selfClosing.indexOf(name) && !this.xml) {
Expand All @@ -304,15 +333,12 @@ Compiler.prototype = {
this.buffer('<' + name + '>');
}
if (tag.code) this.visitCode(tag.code);
if (tag.text) this.buffer(utils.text(tag.text.nodes[0].trimLeft()));
this.escape = 'pre' == tag.name;
this.visit(tag.block);

// pretty print
if (this.pp && !~inlineTags.indexOf(name) && !tag.textOnly && !tag.isText()) {
this.buffer('\\n' + Array(this.indents).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
if (this.pp && !~inlineTags.indexOf(name) && !tag.isText()) {
this.prettyIndent();
}

this.buffer('</' + name + '>');
Expand Down Expand Up @@ -356,10 +382,9 @@ Compiler.prototype = {
*/

visitText: function(text){
text = utils.text(text.nodes.join('\\n'));
text = utils.text(text.val);
if (this.escape) text = escape(text);
this.buffer(text);
this.buffer('\\n');
},

/**
Expand All @@ -372,9 +397,7 @@ Compiler.prototype = {
visitComment: function(comment){
if (!comment.buffer) return;
if (this.pp) {
this.buffer('\\n' + Array(this.indents + 1).join(' '));
if (this.parentIndents)
this.buf.push("buf.push.apply(buf, __indent);");
this.prettyIndent(1);
}
this.buffer('<!--' + utils.escape(comment.val) + '-->');
},
Expand Down Expand Up @@ -515,4 +538,4 @@ function escape(html){
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
}
4 changes: 2 additions & 2 deletions lib/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ Lexer.prototype = {

blank: function() {
var captures;
if (this.pipeless) return;
if (captures = /^\n *\n/.exec(this.input)) {
this.consume(captures[0].length - 1);
if (this.pipeless) return this.tok('text', '');
return this.next();
}
},
Expand Down Expand Up @@ -250,7 +250,7 @@ Lexer.prototype = {
*/

text: function() {
return this.scan(/^(?:\| ?)?([^\n]+)/, 'text');
return this.scan(/^(?:\| ?| ?)?([^\n]+)/, 'text');
},

/**
Expand Down
7 changes: 6 additions & 1 deletion lib/nodes/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@
* @api public
*/

var Node = module.exports = function Node(){};
var Node = module.exports = function Node(){};

Node.prototype.getType = function () {
return this.constructor.name
|| node.constructor.toString().match(/function ([^(\s]+)()/)[1];
}
4 changes: 3 additions & 1 deletion lib/nodes/tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,7 @@ Tag.prototype.getAttribute = function(name){
*/

Tag.prototype.isText = function(){
return !this.block.nodes.length;
return this.block.nodes.length === 0
|| (this.block.nodes.length === 1
&& this.block.nodes[0].getType() === 'Text');
};
16 changes: 2 additions & 14 deletions lib/nodes/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,12 @@ var Node = require('./node');
*/

var Text = module.exports = function Text(line) {
this.nodes = [];
if ('string' == typeof line) this.push(line);
this.val = '';
if ('string' == typeof line) this.val = line;
};

/**
* Inherit from `Node`.
*/

Text.prototype.__proto__ = Node.prototype;

/**
* Push the given `node.`
*
* @param {Node} node
* @return {Number}
* @api public
*/

Text.prototype.push = function(node){
return this.nodes.push(node);
};
14 changes: 8 additions & 6 deletions lib/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,8 @@ Parser.prototype = {
*/

parseTextBlock: function(){
var text = new nodes.Text;
text.line = this.line();
var block = new nodes.Block;
block.line = this.line();
var spaces = this.expect('indent').val;
if (null == this._spaces) this._spaces = spaces;
var indent = Array(spaces - this._spaces + 1).join(' ');
Expand All @@ -516,17 +516,19 @@ Parser.prototype = {
break;
case 'indent':
this.parseTextBlock().nodes.forEach(function(node){
text.push(node);
block.push(node);
});
break;
default:
text.push(indent + this.advance().val);
var text = new nodes.Text(indent + this.advance().val);
text.line = this.line();
block.push(text);
}
}

if (spaces == this._spaces) this._spaces = null;
this.expect('outdent');
return text;
return block;
},

/**
Expand Down Expand Up @@ -603,7 +605,7 @@ Parser.prototype = {
// (text | code | ':')?
switch (this.peek().type) {
case 'text':
tag.text = this.parseText();
tag.block.push(this.parseText());
break;
case 'code':
tag.code = this.parseCode();
Expand Down

0 comments on commit d495a7b

Please sign in to comment.