Packages

Implementation of the Porter2 stemming algorithm for the english language

Current section

Files

Jump to
porter2 lib porter2.ex
Raw

lib/porter2.ex

defmodule Porter2 do
use GenServer
alias Porter2.Word
@moduledoc """
An implementation of the Porter2 word stemming algorithm for the english
language as described on
http://snowballstem.org/algorithms/english/stemmer.html
Please note that special word forms are currently not regarded separately.
"""
@doc """
Stems the given word; works without the GenServer.
"""
@spec stem( binary ) :: binary
def stem( word ) when byte_size( word ) < 3, do: word
def stem( word ) do
Regex.replace( ~r/^'\s*/, String.trim( word ), "", global: false )
|> String.downcase
|> Word.transform_vowel_ys
|> Word.remove_apostrophe_s_suffix
|> Word.replace_suffixes # step 1a, 1b, 1c according to snowball
|> Word.primary_special_suffix_replacement # Step 2 according to snowball
|> Word.secondary_special_suffix_replacement # Step 3 according to snowball
|> Word.primary_suffix_deletion # Step 4 according to snowball
|> Word.secondary_suffix_deletion # step 5 according to snowball
|> String.downcase
end
@doc """
Starts the GenServer
"""
@spec start_link() :: none
def start_link, do: GenServer.start_link( __MODULE__, :ok, [] )
@doc """
Stops the GenServer
"""
@spec stop( pid ) :: :ok
def stop( server ), do: GenServer.stop( server )
@doc """
Calls the given GenServer pid to stem the given word
"""
@spec stem( pid, binary ) :: binary
def stem( server, word ) do
GenServer.call( server, { :stem, word } )
end
### GenServer callbacks
@doc """
GenServer callback for initialization
"""
@spec init( :ok ) :: { :ok, map }
def init( :ok ), do: { :ok, %{} }
@doc """
GenServer callback for stemming a word.
"""
@spec handle_call( { atom, binary }, pid, map ) :: { atom, any, map }
def handle_call( { :stem, word }, _from, state ) when is_binary( word ) do
{ :reply, stem( word ), state }
end
end