private static string ProcessMacroInternal(this string value, GetMacroValueDelegate getMacroValue, object eachItem = null) {
bool keepGoing;
do {
keepGoing = false;
foreach (var macro in Macros) {
var matches = macro.Matches(value);
foreach (var m in matches) {
var match = m as Match;
var innerMacro = match.Groups[2].Value;
var outerMacro = match.Groups[1].Value;
string replacement = null;
// get the first responder.
foreach (GetMacroValueDelegate del in getMacroValue.GetInvocationList()) {
replacement = del(innerMacro);
if (replacement != null) {
break;
}
}
if (eachItem != null) {
// try resolving it as an ${each.property} style.
// the element at the front is the 'this' value
// just trim off whatever is at the front up to and including the first dot.
try {
if (innerMacro.Contains(".")) {
innerMacro = innerMacro.Substring(innerMacro.IndexOf('.') + 1).Trim();
var r = eachItem.SimpleEval(innerMacro).ToString();
value = value.Replace(outerMacro, r);
keepGoing = true;
}
} catch {
// meh. screw em'
}
}
if (replacement != null) {
value = value.Replace(outerMacro, replacement);
keepGoing = true;
break;
}
}
}
} while (keepGoing);
return value;
}