Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/inflex/camelize.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
defmodule Inflex.Camelize do
@moduledoc false

@camelize_regex ~r/(?:^|[-_])|(?=[A-Z][a-z])/

def camelize(word, option \\ :upper) do
case Regex.split(@camelize_regex, to_string(word)) do
case Regex.split(camelize_regex(), to_string(word)) do
words ->
words
|> Enum.filter(&(&1 != ""))
Expand All @@ -25,4 +23,6 @@ defmodule Inflex.Camelize do

def capitalize(word), do: String.capitalize(word)
def lowercase(word), do: String.downcase(word)

defp camelize_regex, do: ~r/(?:^|[-_])|(?=[A-Z][a-z])/
end
242 changes: 93 additions & 149 deletions lib/inflex/pluralize.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,162 +30,17 @@ defmodule Inflex.Pluralize do
"trousers"
]

@irregular [
{~r/(alumn|cact|fung|radi|stimul|syllab)i/i, "\\1us"},
{~r/(alg|antenn|amoeb|larv|vertebr)ae/i, "\\1a"},
{~r/^(gen)era$/i, "\\1us"},
{~r/(pe)ople/i, "\\1rson"},
{~r/^(zombie)s$/i, "\\1"},
{~r/(g)eese/i, "\\1oose"},
{~r/(criteri)a/i, "\\1on"},
{~r/^(m)en$/i, "\\1an"},
{~r/^(echo)es/i, "\\1"},
{~r/^(hero)es/i, "\\1"},
{~r/^(potato)es/i, "\\1"},
{~r/^(tomato)es/i, "\\1"},
{~r/^(t)eeth/i, "\\1ooth"},
{~r/^(l)ice$/i, "\\1ouse"},
{~r/^(addend|bacteri|curricul|dat|memorand|quant)a$/i, "\\1um"},
{~r/^(di)ce/i, "\\1e"},
{~r/^(f)eet/i, "\\1oot"},
{~r/^(phenomen)a/i, "\\1on"}
]

@plural_irregular [
{~r/(alumn|cact|fung|radi|stimul|syllab)us/i, "\\1i"},
{~r/(alg|antenn|amoeb|larv|vertebr)a/i, "\\1ae"},
{~r/^(gen)us$/i, "\\1era"},
{~r/(pe)rson$/i, "\\1ople"},
{~r/^(zombie)s$/i, "\\1"},
{~r/(g)oose$/i, "\\1eese"},
{~r/(criteri)on/i, "\\1a"},
{~r/^(men)$/i, "\\1"},
{~r/^(women)/i, "\\1"},
{~r/^(echo)$/i, "\\1es"},
{~r/^(hero)$/i, "\\1es"},
{~r/^(potato)/i, "\\1es"},
{~r/^(tomato)/i, "\\1es"},
{~r/^(t)ooth$/i, "\\1eeth"},
{~r/^(l)ouse$/i, "\\1ice"},
{~r/^(addend|bacteri|curricul|dat|memorand|quant)um$/i, "\\1a"},
{~r/^(di)e$/i, "\\1ce"},
{~r/^(f)oot$/i, "\\1eet"},
{~r/^(phenomen)on/i, "\\1a"}
]

@singular @irregular ++
[
{~r/(child)ren/i, "\\1"},
{~r/(wo|sea)men$/i, "\\1man"},
{~r/^(m|l)ice$/i, "\\1ouse"},
{~r/(bus|canvas|status|alias)(es)?$/i, "\\1"},
{~r/(ss)$/i, "\\1"},
{~r/(database)s$/i, "\\1"},
{~r/([ti])a$/i, "\\1um"},
{~r/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,
"\\1sis"},
{~r/(analy)(sis|ses)$/i, "\\1sis"},
{~r/(octop|vir)i$/i, "\\1us"},
{~r/(hive)s$/i, "\\1"},
{~r/(tive)s$/i, "\\1"},
{~r/(er)ves$/i, "\\1ve"},
{~r/([lora])ves$/i, "\\1f"},
{~r/([^f])ves$/i, "\\1fe"},
{~r/([^aeiouy]|qu)ies$/i, "\\1y"},
{~r/(m)ovies$/i, "\\1ovie"},
{~r/(x|ch|ss|sh)es$/i, "\\1"},
{~r/(shoe)s$/i, "\\1"},
{~r/(o)es$/i, "\\1"},
{~r/s$/i, ""}
]

@plural @plural_irregular ++
[
{~r/(child)$/i, "\\1ren"},
{~r/(m)an$/i, "\\1en"},
{~r/(m|l)ouse/i, "\\1ice"},
{~r/(database)s$/i, "\\1"},
{~r/(quiz)$/i, "\\1zes"},
{~r/^(ox)$/i, "\\1en"},
{~r/(matr|vert|ind)ix|ex$/i, "\\1ices"},
{~r/(x|ch|ss|sh)$/i, "\\1es"},
{~r/([^aeiouy]|qu)y$/i, "\\1ies"},
{~r/(hive)$/i, "\\1s"},
{~r/(sc[au]rf)$/i, "\\1s"},
{~r/(?:([^f])fe|((hoo)|([lra]))f)$/i, "\\2\\1ves"},
{~r/sis$/i, "ses"},
{~r/([ti])um$/i, "\\1a"},
{~r/(buffal|tomat)o$/i, "\\1oes"},
{~r/(octop|vir)us$/i, "\\1i"},
{~r/(bus|alias|status|canvas)$/i, "\\1es"},
{~r/(ax|test)is$/i, "\\1es"},
{~r/s$/i, "s"},
{~r/data$/i, "data"},
{~r/$/i, "s"}
]

@singular @irregular ++
[
{~r/(child)ren/i, "\\1"},
{~r/(wo|sea)men$/i, "\\1man"},
{~r/^(m|l)ice$/i, "\\1ouse"},
{~r/(bus|canvas|status|alias)(es)?$/i, "\\1"},
{~r/(ss)$/i, "\\1"},
{~r/(database)s$/i, "\\1"},
{~r/([ti])a$/i, "\\1um"},
{~r/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i,
"\\1sis"},
{~r/(analy)(sis|ses)$/i, "\\1sis"},
{~r/(octop|vir)i$/i, "\\1us"},
{~r/(hive)s$/i, "\\1"},
{~r/(tive)s$/i, "\\1"},
{~r/(er)ves$/i, "\\1ve"},
{~r/([lora])ves$/i, "\\1f"},
{~r/([^f])ves$/i, "\\1fe"},
{~r/([^aeiouy]|qu)ies$/i, "\\1y"},
{~r/(m)ovies$/i, "\\1ovie"},
{~r/(x|ch|ss|sh)es$/i, "\\1"},
{~r/(shoe)s$/i, "\\1"},
{~r/(o)es$/i, "\\1"},
{~r/s$/i, ""}
]

@plural @plural_irregular ++
[
{~r/(child)$/i, "\\1ren"},
{~r/(m)an$/i, "\\1en"},
{~r/(m|l)ouse/i, "\\1ice"},
{~r/(database)s$/i, "\\1"},
{~r/(quiz)$/i, "\\1zes"},
{~r/^(ox)$/i, "\\1en"},
{~r/(matr|vert|ind)ix|ex$/i, "\\1ices"},
{~r/(x|ch|ss|sh)$/i, "\\1es"},
{~r/([^aeiouy]|qu)y$/i, "\\1ies"},
{~r/(hive)$/i, "\\1s"},
{~r/(sc[au]rf)$/i, "\\1s"},
{~r/(?:([^f])fe|((hoo)|([lra]))f)$/i, "\\2\\1ves"},
{~r/sis$/i, "ses"},
{~r/([ti])um$/i, "\\1a"},
{~r/(buffal|tomat)o$/i, "\\1oes"},
{~r/(octop|vir)us$/i, "\\1i"},
{~r/(bus|alias|status|canvas)$/i, "\\1es"},
{~r/(ax|test)is$/i, "\\1es"},
{~r/s$/i, "s"},
{~r/data$/i, "data"},
{~r/$/i, "s"}
]

def singularize(word) when is_atom(word) do
find_match(@singular, to_string(word))
find_match(singular_regexes(), to_string(word))
end

def singularize(word), do: find_match(@singular, word)
def singularize(word), do: find_match(singular_regexes(), word)

def pluralize(word) when is_atom(word) do
find_match(@plural, to_string(word))
find_match(plural_regexes(), to_string(word))
end

def pluralize(word), do: find_match(@plural, word)
def pluralize(word), do: find_match(plural_regexes(), word)

def inflect(word, n) when n == 1, do: singularize(word)
def inflect(word, n) when is_number(n), do: pluralize(word)
Expand All @@ -212,4 +67,93 @@ defmodule Inflex.Pluralize do
defp replace(_, word), do: word

defp uncountable?(word), do: Enum.member?(@uncountable, word)

defp singular_regexes do
[
{~r/(alumn|cact|fung|radi|stimul|syllab)i/i, "\\1us"},
{~r/(alg|antenn|amoeb|larv|vertebr)ae/i, "\\1a"},
{~r/^(gen)era$/i, "\\1us"},
{~r/(pe)ople/i, "\\1rson"},
{~r/^(zombie)s$/i, "\\1"},
{~r/(g)eese/i, "\\1oose"},
{~r/(criteri)a/i, "\\1on"},
{~r/^(m)en$/i, "\\1an"},
{~r/^(echo)es/i, "\\1"},
{~r/^(hero)es/i, "\\1"},
{~r/^(potato)es/i, "\\1"},
{~r/^(tomato)es/i, "\\1"},
{~r/^(t)eeth/i, "\\1ooth"},
{~r/^(l)ice$/i, "\\1ouse"},
{~r/^(addend|bacteri|curricul|dat|memorand|quant)a$/i, "\\1um"},
{~r/^(di)ce/i, "\\1e"},
{~r/^(f)eet/i, "\\1oot"},
{~r/^(phenomen)a/i, "\\1on"},
{~r/(child)ren/i, "\\1"},
{~r/(wo|sea)men$/i, "\\1man"},
{~r/^(m|l)ice$/i, "\\1ouse"},
{~r/(bus|canvas|status|alias)(es)?$/i, "\\1"},
{~r/(ss)$/i, "\\1"},
{~r/(database)s$/i, "\\1"},
{~r/([ti])a$/i, "\\1um"},
{~r/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, "\\1sis"},
{~r/(analy)(sis|ses)$/i, "\\1sis"},
{~r/(octop|vir)i$/i, "\\1us"},
{~r/(hive)s$/i, "\\1"},
{~r/(tive)s$/i, "\\1"},
{~r/(er)ves$/i, "\\1ve"},
{~r/([lora])ves$/i, "\\1f"},
{~r/([^f])ves$/i, "\\1fe"},
{~r/([^aeiouy]|qu)ies$/i, "\\1y"},
{~r/(m)ovies$/i, "\\1ovie"},
{~r/(x|ch|ss|sh)es$/i, "\\1"},
{~r/(shoe)s$/i, "\\1"},
{~r/(o)es$/i, "\\1"},
{~r/s$/i, ""}
]
end

defp plural_regexes do
[
{~r/(alumn|cact|fung|radi|stimul|syllab)us/i, "\\1i"},
{~r/(alg|antenn|amoeb|larv|vertebr)a/i, "\\1ae"},
{~r/^(gen)us$/i, "\\1era"},
{~r/(pe)rson$/i, "\\1ople"},
{~r/^(zombie)s$/i, "\\1"},
{~r/(g)oose$/i, "\\1eese"},
{~r/(criteri)on/i, "\\1a"},
{~r/^(men)$/i, "\\1"},
{~r/^(women)/i, "\\1"},
{~r/^(echo)$/i, "\\1es"},
{~r/^(hero)$/i, "\\1es"},
{~r/^(potato)/i, "\\1es"},
{~r/^(tomato)/i, "\\1es"},
{~r/^(t)ooth$/i, "\\1eeth"},
{~r/^(l)ouse$/i, "\\1ice"},
{~r/^(addend|bacteri|curricul|dat|memorand|quant)um$/i, "\\1a"},
{~r/^(di)e$/i, "\\1ce"},
{~r/^(f)oot$/i, "\\1eet"},
{~r/^(phenomen)on/i, "\\1a"},
{~r/(child)$/i, "\\1ren"},
{~r/(m)an$/i, "\\1en"},
{~r/(m|l)ouse/i, "\\1ice"},
{~r/(database)s$/i, "\\1"},
{~r/(quiz)$/i, "\\1zes"},
{~r/^(ox)$/i, "\\1en"},
{~r/(matr|vert|ind)ix|ex$/i, "\\1ices"},
{~r/(x|ch|ss|sh)$/i, "\\1es"},
{~r/([^aeiouy]|qu)y$/i, "\\1ies"},
{~r/(hive)$/i, "\\1s"},
{~r/(sc[au]rf)$/i, "\\1s"},
{~r/(?:([^f])fe|((hoo)|([lra]))f)$/i, "\\2\\1ves"},
{~r/sis$/i, "ses"},
{~r/([ti])um$/i, "\\1a"},
{~r/(buffal|tomat)o$/i, "\\1oes"},
{~r/(octop|vir)us$/i, "\\1i"},
{~r/(bus|alias|status|canvas)$/i, "\\1es"},
{~r/(ax|test)is$/i, "\\1es"},
{~r/s$/i, "s"},
{~r/data$/i, "data"},
{~r/$/i, "s"}
]
end
end