diff --git a/src/Humanizer/Inflections/Vocabularies.cs b/src/Humanizer/Inflections/Vocabularies.cs
index 1107672ab..2aaaec8e2 100644
--- a/src/Humanizer/Inflections/Vocabularies.cs
+++ b/src/Humanizer/Inflections/Vocabularies.cs
@@ -20,6 +20,94 @@ internal static string ApplyAcronyms(string input) =>
internal static string NormalizeAcronyms(string input) =>
Instance.IsValueCreated ? Instance.Value.NormalizeAcronyms(input) : input;
+ ///
+ /// Element names ending in -ium (and aluminum) are most often uncountable
+ ///
+ internal static readonly string[] UncountableChemicalElementNames =
+ [
+ "actinium",
+ "aluminium",
+ "aluminum",
+ "americium",
+ "barium",
+ "berkelium",
+ "beryllium",
+ "bohrium",
+ "cadmium",
+ "caesium",
+ "californium",
+ "calcium",
+ "cerium",
+ "cesium",
+ "chromium",
+ "copernicium",
+ "curium",
+ "darmstadtium",
+ "dubnium",
+ "dysprosium",
+ "einsteinium",
+ "erbium",
+ "europium",
+ "fermium",
+ "flerovium",
+ "francium",
+ "gadolinium",
+ "gallium",
+ "germanium",
+ "hafnium",
+ "hassium",
+ "helium",
+ "holmium",
+ "indium",
+ "iridium",
+ "lawrencium",
+ "lithium",
+ "livermorium",
+ "lutetium",
+ "magnesium",
+ "meitnerium",
+ "mendelevium",
+ "moscovium",
+ "neodymium",
+ "neptunium",
+ "nihonium",
+ "niobium",
+ "nobelium",
+ "osmium",
+ "palladium",
+ "plutonium",
+ "polonium",
+ "potassium",
+ "praseodymium",
+ "promethium",
+ "protactinium",
+ "radium",
+ "rhenium",
+ "rhodium",
+ "roentgenium",
+ "rubidium",
+ "ruthenium",
+ "rutherfordium",
+ "samarium",
+ "scandium",
+ "seaborgium",
+ "selenium",
+ "sodium",
+ "strontium",
+ "technetium",
+ "tellurium",
+ "terbium",
+ "thallium",
+ "thorium",
+ "thulium",
+ "titanium",
+ "uranium",
+ "vanadium",
+ "ytterbium",
+ "yttrium",
+ "zirconium",
+ ];
+
static Vocabulary BuildDefault()
{
var _default = new Vocabulary();
@@ -27,8 +115,8 @@ static Vocabulary BuildDefault()
_default.AddPlural("$", "s");
_default.AddPlural("s$", "s");
_default.AddPlural("(ax|test)is$", "$1es");
- _default.AddPlural("(octop|vir|alumn|fung|cact|foc|hippopotam|radi|stimul|syllab|nucle)us$", "$1i");
- _default.AddPlural("(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis)$", "$1es");
+ _default.AddPlural("(vir|alumn|fung|cact|foc|radi|stimul|syllab|nucle)us$", "$1i");
+ _default.AddPlural("(alias|bias|iris|status|campus|apparatus|virus|walrus|trellis|octopus|hippopotamus)$", "$1es");
_default.AddPlural("(buffal|tomat|volcan|ech|embarg|her|mosquit|potat|torped|vet)o$", "$1oes");
_default.AddPlural("([dti])um$", "$1a");
_default.AddPlural("sis$", "ses");
@@ -50,6 +138,7 @@ static Vocabulary BuildDefault()
_default.AddSingular("([dti])a$", "$1um");
_default.AddSingular("(analy|ba|diagno|parenthe|progno|synop|the|ellip|empha|neuro|oa|paraly)ses$", "$1sis");
_default.AddSingular("(.+)ves$", "$1ve");
+ _default.AddSingular("(him|her|it|my|one)selves$", "$1self");
_default.AddSingular("(hive)s$", "$1");
_default.AddSingular("(tive)s$", "$1");
_default.AddSingular("(cal|dwar|el|hal|hoo|lea|loa|scar|sel|shel|thie|tur|whar|wol)ves$", "$1f");
@@ -63,9 +152,11 @@ static Vocabulary BuildDefault()
_default.AddSingular("(shoe)s$", "$1");
_default.AddSingular("((?
Assert.Equal(expected, plural.Singularize());
+ [Theory]
+ [InlineData("octopuses", "octopus")]
+ [InlineData("octopi", "octopus")]
+ [InlineData("octopodes", "octopus")]
+ [InlineData("hippopotamuses", "hippopotamus")]
+ [InlineData("hippopotami", "hippopotamus")]
+ [InlineData("premiums", "premium")]
+ [InlineData("premia", "premium")]
+ [InlineData("stadiums", "stadium")]
+ [InlineData("stadia", "stadium")]
+ [InlineData("podiums", "podium")]
+ [InlineData("podia", "podium")]
+ [InlineData("ultimatums", "ultimatum")]
+ [InlineData("ultimata", "ultimatum")]
+ [InlineData("condominiums", "condominium")]
+ [InlineData("condominia", "condominium")]
+ [InlineData("euphoniums", "euphonium")]
+ [InlineData("euphonia", "euphonium")]
+ [InlineData("harmoniums", "harmonium")]
+ [InlineData("harmonia", "harmonium")]
+ [InlineData("criteriums", "criterium")]
+ [InlineData("spandexes", "spandex")]
+ [InlineData("spandices", "spandex")]
+ [InlineData("himselves", "himself")]
+ [InlineData("herselves", "herself")]
+ [InlineData("itselves", "itself")]
+ [InlineData("myselves", "myself")]
+ [InlineData("oneselves", "oneself")]
+ [InlineData("yourselves", "yourself")]
+ [InlineData("aquariums", "aquarium")]
+ [InlineData("auditoriums", "auditorium")]
+ [InlineData("consortiums", "consortium")]
+ [InlineData("symposiums", "symposium")]
+ public void SingularizeRecognizesAlternatePlurals(string plural, string singular)
+ {
+ Assert.Equal(singular, plural.Singularize());
+ Assert.Equal(singular, plural.Singularize(inputIsKnownToBePlural: false));
+ }
+
+ [Fact]
+ public void ChemicalElementNamesEndingInIumAreUncountable()
+ {
+ foreach (var element in Vocabularies.UncountableChemicalElementNames)
+ {
+ Assert.Equal(element, element.Pluralize());
+ Assert.Equal(element, element.Singularize());
+ Assert.Equal(element, element.Pluralize(inputIsKnownToBeSingular: false));
+ Assert.Equal(element, element.Singularize(inputIsKnownToBePlural: false));
+ }
+ }
+
[Theory]
[InlineData("a")]
[InlineData("A")]
@@ -495,7 +546,7 @@ public IEnumerator