private static string ListToString(ICollection<string> items)
{
if (!items.Any())
return "";
List<string> uniqueItems = new List<string>();
// remove duplicates: duplicate if an existing list item starts the with string
// also duplicate when one category is same as another with a sortkey
// e.g. [[Category:One]] is duplicate of [[Category:One|A]]
// Or sortkeys vary only by first letter case
foreach (string s in items)
{
bool addme = true;
string s2 =s;
bool isACategory = WikiRegexes.Category.IsMatch (s2);
// compare based on first letter upper sortkey for categories
if (s2.Contains("|") && isACategory)
s2 = Regex.Replace(s2, @"(\|\s*)(.+)(\s*\]\]$)", m=> m.Groups[1].Value + Tools.TurnFirstToUpper(m.Groups[2].Value) + m.Groups[3].Value);
foreach (string u in uniqueItems)
{
if (u.StartsWith(s2) || u.StartsWith(s2.TrimEnd(']') + @"|") || u.Equals(s) || u.Equals(s2))
{
addme = false;
break;
}
if (s2.StartsWith(u)) // e.g. [[Category:A]] already added but [[Category:A]] <!-- comment--> next in list
{
uniqueItems.Remove(u);
break;
}
// for Category: e.g. [[Category:A|Foo]] already added but [[Category:A|Foo bar]] next in list
if (isACategory && u.Contains("|") && s2.TrimEnd(']').StartsWith(u.TrimEnd(']')))
{
uniqueItems.Remove(u);
break;
}
if (isACategory && s2.Contains("|") && u.TrimEnd(']').StartsWith(s2.TrimEnd(']')))
{
addme = false;
break;
}
// compare on first letter case insensitive for templates
if (WikiRegexes.NestedTemplates.IsMatch(s2) && WikiRegexes.NestedTemplates.IsMatch(u))
{
string s2upper = s2.Substring(1, 3).ToUpper() + s2.Substring(3);
string uupper = u.Substring(1, 3).ToUpper() + u.Substring(3);
if (s2upper.Equals(uupper))
{
addme = false;
break;
}
}
}
if (addme)
uniqueItems.Add(s);
}
StringBuilder list = new StringBuilder();
foreach (string s in uniqueItems)
{
list.Append(s + "\r\n"); // Don't just use AppendLine as this may just give \n under Mono
}
return list.ToString();
}