private static string TemplateRedirectsHashSet(string articleText, Dictionary<Regex, string> TemplateRedirects)
{
// performance: first check there's a match between templates used in article and listed template redirects
// using intersection of HashSet lists of the two
HashSet<string> TemplatesFound = new HashSet<string>(GetAllTemplates(articleText));
TemplatesFound.IntersectWith(WikiRegexes.AllTemplateRedirectsHS);
// run replacements only if matches found
if (TemplatesFound.Any())
{
// performance: secondly filter the TemplateRedirects dictionary down to those rules matching templates used in article
string all = String.Join(" ", TemplatesFound.Select(s => "{{" + s + "}}").ToArray());
TemplateRedirects = TemplateRedirects.Where(s => s.Key.IsMatch(all))
.ToDictionary(x => x.Key, y => y.Value);
// performance: thirdly then run replacement for only those matching templates, and only against the matching rules, handle nested templates
Regex MatchedTemplates = Tools.NestedTemplateRegex(TemplatesFound.ToList());
articleText = MatchedTemplates.Replace(articleText, m2 =>
{
string res = m2.Value;
string valBefore = "";
// inner loop to handle nested templates
while(res != valBefore)
{
valBefore = res;
foreach (KeyValuePair<Regex, string> kvp in TemplateRedirects)
{
res = kvp.Key.Replace(res, m => TemplateRedirectsME(m, kvp.Value));
// if template name changed and not nested template, done, so break out
if (!res.Equals(m2.Value) && !m2.Groups[3].Value.Contains("{{"))
break;
}
}
return res;
});
}
return articleText;
}