index.js
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;
}
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;
}
recursively expand a string until it doesn't contain any template strings