docs: function(tag, parent, interpolated){
      this.indents++;
      var name = tag.name
        , pp = this.pp
        , self = this;
      var ast = [];
  
      function bufferName() {
        if (interpolated) {
          if (tag.astExpr) return self.bufferAST(tag.astExpr);
          return self.bufferExpression(tag.expr);
        }
        else return self.buffer(name);
      }
  
      if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = true;
  
      if (!this.hasCompiledTag) {
        if (!this.hasCompiledDoctype && 'html' == name) {
          push.apply(ast, this.visitDoctype());
        }
        this.hasCompiledTag = true;
      }
      // pretty print
      if (pp && !tag.isInline)
        push.apply(ast, this.prettyIndent(0, true));
      if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) {
        push.apply(ast, this.buffer('<'));
        push.apply(ast, bufferName());
        push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
        if (this.terse && !tag.selfClosing) {
          push.apply(ast, this.buffer('>'));
        } else {
          push.apply(ast, this.buffer('/>'));
        }
        // if it is non-empty throw an error
        if (tag.code ||
            tag.block &&
            !(tag.block.type === 'Block' && tag.block.nodes.length === 0) &&
            tag.block.nodes.some(function (tag) {
              return tag.type !== 'Text' || !/^\s*$/.test(tag.val)
            })) {
          this.error(name + ' is a self closing element: <'+name+'/> but contains nested content.', 'SELF_CLOSING_CONTENT', tag);
        }
      } else {
        // Optimize attributes buffering
        push.apply(ast, this.buffer('<'));
        push.apply(ast, bufferName());
        push.apply(ast, this.visitAttributes(tag.attrs, this.attributeBlocks(tag.attributeBlocks)));
        push.apply(ast, this.buffer('>'));
        if (tag.code) push.apply(ast, this.visitCode(tag.code));
        push.apply(ast, this.visit(tag.block, tag));
  
        // pretty print
        if (pp && !tag.isInline && WHITE_SPACE_SENSITIVE_TAGS[tag.name] !== true && !tagCanInline(tag))
          push.apply(ast, this.prettyIndent(0, true));
  
        push.apply(ast, this.buffer('</'));
        push.apply(ast, bufferName());
        push.apply(ast, this.buffer('>'));
      }
  
      if (WHITE_SPACE_SENSITIVE_TAGS[tag.name] === true) this.escapePrettyMode = false;
  
      this.indents--;
      return ast;
    }