diff --git a/Knossos.NET/Classes/KnUtils.cs b/Knossos.NET/Classes/KnUtils.cs
index 46152247..ec9d8ada 100644
--- a/Knossos.NET/Classes/KnUtils.cs
+++ b/Knossos.NET/Classes/KnUtils.cs
@@ -5,6 +5,7 @@
using System.Runtime.Intrinsics.X86;
using System.Text;
using System.Text.Json;
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Security.Cryptography;
@@ -951,6 +952,20 @@ public static string EscapeUnderscores(string? text)
return text.Replace("_", "__");
}
+ ///
+ /// Gets rid of 'A', 'An', and 'The' at the beginning of a string, case-insensitively
+ ///
+ /// A string
+ /// The string with any articles removed from the beginning
+ public static string RemoveArticles(string title)
+ {
+ var match = Regex.Match(title, "((A)|(An)|(The))\\s+", RegexOptions.IgnoreCase);
+ if (match.Index == 0 && match.Length > 0)
+ return title.Substring(match.Length);
+ else
+ return title;
+ }
+
///
/// Checks if a file is currently in use
///
diff --git a/Knossos.NET/Models/Mod.cs b/Knossos.NET/Models/Mod.cs
index 9eab44c1..2617d545 100644
--- a/Knossos.NET/Models/Mod.cs
+++ b/Knossos.NET/Models/Mod.cs
@@ -779,19 +779,18 @@ public async Task LoadFulLNebulaData()
///
/// To use with the List .Sort()
- /// Retuns a list that is sort from older to newer
+ /// Orders the two mods from older to newer
///
///
///
public static int CompareVersion(Mod mod1, Mod mod2)
{
- //inverted
return SemanticVersion.Compare(mod1.version, mod2.version);
}
///
/// To use with the List .Sort()
- /// Retuns a list that is sort from newer to older
+ /// Orders the two mods from newer to older
///
///
///
@@ -801,6 +800,17 @@ public static int CompareVersionNewerToOlder(Mod mod1, Mod mod2)
return SemanticVersion.Compare(mod2.version, mod1.version);
}
+ ///
+ /// To use with the List .Sort()
+ /// Orders the two titles using a regular case-insensitive string comparison, but ignoring any leading 'A', 'An', or 'The' articles
+ ///
+ ///
+ ///
+ public static int CompareTitles(string title1, string title2)
+ {
+ return String.Compare(KnUtils.RemoveArticles(title1), KnUtils.RemoveArticles(title2), StringComparison.CurrentCultureIgnoreCase);
+ }
+
///
/// Compares two mods and determines if the metadata is different
/// Full data must be loaded on both mods for this to work properly
diff --git a/Knossos.NET/ViewModels/ModListViewModel.cs b/Knossos.NET/ViewModels/ModListViewModel.cs
index 300a6733..cff2830b 100644
--- a/Knossos.NET/ViewModels/ModListViewModel.cs
+++ b/Knossos.NET/ViewModels/ModListViewModel.cs
@@ -177,7 +177,7 @@ private int CompareMods(Mod modA,Mod modB)
switch (sortType)
{
case MainWindowViewModel.SortType.name:
- return String.Compare(modA.title, modB.title);
+ return Mod.CompareTitles(modA.title, modB.title);
case MainWindowViewModel.SortType.release:
if (modA.firstRelease == modB.firstRelease)
return 0;
diff --git a/Knossos.NET/ViewModels/NebulaModListViewModel.cs b/Knossos.NET/ViewModels/NebulaModListViewModel.cs
index 4f862208..9d854d0f 100644
--- a/Knossos.NET/ViewModels/NebulaModListViewModel.cs
+++ b/Knossos.NET/ViewModels/NebulaModListViewModel.cs
@@ -327,7 +327,7 @@ private int CompareMods(Mod modA,Mod modB)
switch (sortType)
{
case MainWindowViewModel.SortType.name:
- return String.Compare(modA.title, modB.title);
+ return Mod.CompareTitles(modA.title, modB.title);
case MainWindowViewModel.SortType.release:
if (modA.firstRelease == modB.firstRelease)
return 0;
@@ -370,7 +370,7 @@ private int CompareMods(Mod modA,Mod modB)
return 0;
}
}
-
+
///
/// Changes a modcard to "installing" mode
///