code: function ontext(template, text, config) {
  	var
  		blockStubPos = -1,
  		cursor = 0,
  		children = null,
  		nodes = []
  	;
  	
  	config = extend({virtual: template.virtual}, config);
  
  	// Ensures that consecutive textOnly components are merged into a single VText node
  	function concatText(text) {
  		if ((nodes.length > 0) && nodes[nodes.length - 1].addText) {
  			nodes[nodes.length - 1].addText(text);
  		} else {
  			nodes.push(new VText(text, config));
  		}
  	}
  
  	// DRY parse
  	function concatInterpolatedContent(content) {
  		Expression.parseInterpolated(content, {
  			ontext: function(text) {
  				concatText(text);
  			},
  			onexpression: function(expr) {
  				if (expr.textOnly || (config.virtual === false)) {
  					concatText(expr);
  				} else {
  					nodes.push(expr);
  				}
  			}
  		});
  	}
  
  	// While we find more interpolated handlebars blocks
  	while ((blockStubPos = text.indexOf(_blockStub, cursor)) > -1) {
  
  		// Get pre-text
  		if (blockStubPos > cursor) {
  			concatInterpolatedContent(text.substr(cursor, blockStubPos - cursor));
  		}
  
  		// Add the block to the list of nodes
  		block = template.blocks.shift();
  		if (config.virtual === false) {
  			block.callback.virtual = false;
  			concatText(block);
  		} else {
  			nodes.push(block);
  		}
  
  		// Advance the cursor
  		cursor = blockStubPos + _blockStub.length;
  	}
  
  	// Get post-text (or the only text)
  	if (cursor < text.length) {
  		concatInterpolatedContent(text.substr(cursor));
  	}
  
  	// textOnly is for things like tagName and attribute values
  	return nodes;
  }
docs: ontext helper for html parsing ensure that blocks are handled