docs: function (tree, data) {
        var res = ''
        var s
        var node
        var tmp
        var plugin
  
        for (var i = 0; i < tree.length; ++i) {
          node = tree[i]
          s = ''
  
          if (node.type === 'text') {
            s = node.data
          } else if (node.type === 'var') {
            s = this.getVarValue(node, data)
          } else if (node.type === 'boolean') {
            s = !!node.data
          } else if (node.type === 'build-in') {
            tmp = this.buildInFunctions[node.name].process.call(this, node, data)
            if (typeof tmp.tpl !== 'undefined') {
              // If tmp is object, which means it has modified, data also
              // so copy it back to data.
              s = tmp.tpl
              data = tmp.data
            } else {
              // If tmp is string means it has not modified data.
              s = tmp
            }
          } else if (node.type === 'plugin') {
            if (this.runTimePlugins[node.name]) {
              // Thats call for {function}.
              tmp = this.buildInFunctions['function'].process.call(this, node, data)
              if (typeof tmp.tpl !== 'undefined') {
                // If tmp is object, which means it has modified, data also
                // so copy it back to data.
                s = tmp.tpl
                data = tmp.data
              } else {
                // If tmp is string means it has not modified data.
                s = tmp
              }
            } else {
              plugin = this.plugins[node.name]
              if (plugin.type === 'block') {
                var repeat = {value: true}
                while (repeat.value) {
                  repeat.value = false
                  tmp = this.process(node.subTree, data)
                  if (typeof tmp.tpl !== 'undefined') {
                    data = tmp.data
                    tmp = tmp.tpl
                  }
                  s += plugin.process.call(
                    this,
                    this.getActualParamValues(node.params, data),
                    tmp,
                    data,
                    repeat
                  )
                }
              } else if (plugin.type === 'function') {
                s = plugin.process.call(this, this.getActualParamValues(node.params, data), data)
              }
            }
          }
          if (typeof s === 'boolean' && tree.length !== 1) {
            s = s ? '1' : ''
          }
          if (s === null || s === undefined) {
            s = ''
          }
          if (tree.length === 1) {
            return {tpl: s, data: data}
          }
          res += ((s !== null) ? s : '')
  
          if (data.smarty.continue || data.smarty.break) {
            return {tpl: res, data: data}
          }
        }
        return {tpl: res, data: data}
      }