whole_func_string: function (data, lookup, options) {
    var property;
    // as long as this contains a template string, keep traversing
    while(property = findProperty(lookup)) {
      // if this doesn't solely contain a template lookup (e.g. '<%= key %>'), then
      // recursively process it as a template to handle interpolated strings (e.g. 'hi <%= key %>).
      if (property.src !== lookup) {
        lookup = _.template(lookup, data, options);
      } else {
        // expand to the literal value of this key
        lookup = expander.process(data, getobject.get(data, property.prop), options);
      }
    }
    // do one final check for templates.
    if (hasTemplate(lookup)) {
      lookup = _.template(lookup, data, options);
    }
    return lookup;
  }
func_code_string: function (data, lookup, options) {
    var property;
    // as long as this contains a template string, keep traversing
    while(property = findProperty(lookup)) {
      // if this doesn't solely contain a template lookup (e.g. '<%= key %>'), then
      // recursively process it as a template to handle interpolated strings (e.g. 'hi <%= key %>).
      if (property.src !== lookup) {
        lookup = _.template(lookup, data, options);
      } else {
        // expand to the literal value of this key
        lookup = expander.process(data, getobject.get(data, property.prop), options);
      }
    }
    // do one final check for templates.
    if (hasTemplate(lookup)) {
      lookup = _.template(lookup, data, options);
    }
    return lookup;
  }
func_documentation_string: recursively expand a string until it doesn't contain any template strings