# Generated by Snowball.Generator — do not edit by hand. defmodule Text.Stemmer.Stemmers.Porter do @moduledoc """ Snowball stemmer for porter. Generated from the canonical Snowball algorithm source. """ alias Snowball.Runtime alias Snowball.Grouping # Groupings @g_v Grouping.from_string("aeiouy") @g_v_WXY Grouping.from_string("aeiouywxY") # Among tables @a_0 [ {"ic", -1, 1, nil}, {"ance", -1, 1, nil}, {"ence", -1, 1, nil}, {"able", -1, 1, nil}, {"ible", -1, 1, nil}, {"ate", -1, 1, nil}, {"ive", -1, 1, nil}, {"ize", -1, 1, nil}, {"iti", -1, 1, nil}, {"al", -1, 1, nil}, {"ism", -1, 1, nil}, {"ion", -1, 2, nil}, {"er", -1, 1, nil}, {"ous", -1, 1, nil}, {"ant", -1, 1, nil}, {"ent", -1, 1, nil}, {"ment", 15, 1, nil}, {"ement", 16, 1, nil}, {"ou", -1, 1, nil} ] @a_1 [ {"icate", -1, 2, nil}, {"ative", -1, 3, nil}, {"alize", -1, 1, nil}, {"iciti", -1, 2, nil}, {"ical", -1, 2, nil}, {"ful", -1, 3, nil}, {"ness", -1, 3, nil} ] @a_2 [ {"anci", -1, 3, nil}, {"enci", -1, 2, nil}, {"abli", -1, 4, nil}, {"eli", -1, 6, nil}, {"alli", -1, 9, nil}, {"ousli", -1, 12, nil}, {"entli", -1, 5, nil}, {"aliti", -1, 10, nil}, {"biliti", -1, 14, nil}, {"iviti", -1, 13, nil}, {"tional", -1, 1, nil}, {"ational", 10, 8, nil}, {"alism", -1, 10, nil}, {"ation", -1, 8, nil}, {"ization", 13, 7, nil}, {"izer", -1, 7, nil}, {"ator", -1, 8, nil}, {"iveness", -1, 13, nil}, {"fulness", -1, 11, nil}, {"ousness", -1, 12, nil} ] @a_3 [ {"", -1, 3, nil}, {"bb", 0, 2, nil}, {"dd", 0, 2, nil}, {"ff", 0, 2, nil}, {"gg", 0, 2, nil}, {"bl", 0, 1, nil}, {"mm", 0, 2, nil}, {"nn", 0, 2, nil}, {"pp", 0, 2, nil}, {"rr", 0, 2, nil}, {"at", 0, 1, nil}, {"tt", 0, 2, nil}, {"iz", 0, 1, nil} ] @a_4 [ {"ed", -1, 2, nil}, {"eed", 0, 1, nil}, {"ing", -1, 2, nil} ] @a_5 [ {"s", -1, 3, nil}, {"ies", 0, 2, nil}, {"sses", 0, 1, nil}, {"ss", 0, -1, nil} ] @doc """ Stem a word. ### Arguments * `word` is a UTF-8 binary. ### Returns * The stemmed UTF-8 binary. """ @spec stem(binary()) :: binary() def stem(word) when is_binary(word) do state = Runtime.new(word) |> init_vars() state = run_stem(state) Runtime.assign_to(state) end defp init_vars(state), do: %{state | vars: %{p1: 0, p2: 0, Y_found: false}} defp run_stem(%Runtime{} = state) do {_, state} = r_stem(state) state end # Snowball runtime helpers. defp snowball_do_f(state, fun) do saved_c = state.cursor {_, s} = fun.(state) %{s | cursor: saved_c} end defp snowball_do_b(state, fun) do rel = state.limit - state.cursor {_, s} = fun.(state) %{s | cursor: s.limit - rel} end defp snowball_test_b(state, fun) do rel = state.limit - state.cursor case fun.(state) do {:ok, s} -> {:ok, %{s | cursor: s.limit - rel}} {:fail, s} -> {:fail, %{s | cursor: s.limit - rel}} end end defp snowball_or(state, fun1, fun2) do rel = state.limit - state.cursor case fun1.(state) do {:ok, s} -> {:ok, s} {:fail, s} -> fun2.(%{s | cursor: s.limit - rel}) end end defp lift(state, :fail), do: {:fail, state} defp lift(_state, %Runtime{} = s), do: {:ok, s} defp next_codepoint(%Runtime{cursor: c, limit: lim, current: cur} = state) do case Runtime.codepoint_at(cur, c, lim) do {_cp, size} -> {:ok, %{state | cursor: c + size}} :error -> {:fail, state} end end defp next_codepoint_b(%Runtime{cursor: c, limit_backward: lb, current: cur} = state) do case Runtime.codepoint_before(cur, c, lb) do {_cp, size} -> {:ok, %{state | cursor: c - size}} :error -> {:fail, state} end end defp r_Step_5b(%Runtime{} = state) do case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "l")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "l")) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end r -> r end end r -> r end end end defp r_Step_5a(%Runtime{} = state) do case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "e")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> snowball_or(state, fn state -> r_R2(state) end, fn state -> case (fn state -> r_R1(state) end).(state) do {:ok, state} -> (fn state -> saved_c = state.cursor case (fn state -> r_shortv(state) end).(state) do {:ok, s} -> {:fail, %{s | cursor: saved_c}} {:fail, s} -> {:ok, %{s | cursor: saved_c}} end end).(state) r -> r end end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end r -> r end end end defp r_Step_4(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_0) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case result do 1 -> {:ok, Runtime.slice_del(state)} 2 -> case (fn state -> snowball_or(state, fn state -> lift(state, Runtime.eq_s_b(state, "s")) end, fn state -> lift(state, Runtime.eq_s_b(state, "t")) end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end _ -> {:ok, state} end r -> r end end end).() end defp r_Step_3(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_1) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case (fn state -> r_R1(state) end).(state) do {:ok, state} -> case result do 1 -> {:ok, Runtime.slice_from(state, "al")} 2 -> {:ok, Runtime.slice_from(state, "ic")} 3 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end r -> r end end end).() end defp r_Step_2(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_2) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case (fn state -> r_R1(state) end).(state) do {:ok, state} -> case result do 1 -> {:ok, Runtime.slice_from(state, "tion")} 2 -> {:ok, Runtime.slice_from(state, "ence")} 3 -> {:ok, Runtime.slice_from(state, "ance")} 4 -> {:ok, Runtime.slice_from(state, "able")} 5 -> {:ok, Runtime.slice_from(state, "ent")} 6 -> {:ok, Runtime.slice_from(state, "e")} 7 -> {:ok, Runtime.slice_from(state, "ize")} 8 -> {:ok, Runtime.slice_from(state, "ate")} 9 -> {:ok, Runtime.slice_from(state, "al")} 10 -> {:ok, Runtime.slice_from(state, "al")} 11 -> {:ok, Runtime.slice_from(state, "ful")} 12 -> {:ok, Runtime.slice_from(state, "ous")} 13 -> {:ok, Runtime.slice_from(state, "ive")} 14 -> {:ok, Runtime.slice_from(state, "ble")} _ -> {:ok, state} end r -> r end end end).() end defp r_Step_1c(%Runtime{} = state) do case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> snowball_or(state, fn state -> lift(state, Runtime.eq_s_b(state, "y")) end, fn state -> lift(state, Runtime.eq_s_b(state, "Y")) end) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_out_grouping_b(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint_b(s) end end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "i")} r -> r end end r -> r end end end defp r_Step_1b(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_4) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> r_R1(state) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "ee")} r -> r end 2 -> case (fn state -> snowball_test_b(state, fn state -> case Runtime.go_out_grouping_b(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint_b(s) end end) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> (fn -> rel = state.limit - state.cursor state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_3) do :fail -> {:fail, %{state | cursor: state.limit - rel}} {%Runtime{} = s, result} -> state = %{s | cursor: s.limit - rel} case result do 1 -> (fn -> saved_c = state.cursor {:ok, %{Runtime.insert(state, state.cursor, state.cursor, "e") | cursor: saved_c}} end).() 2 -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> next_codepoint_b(state) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} end r -> r end end 3 -> case (fn state -> if state.cursor == state.vars[:p1], do: {:ok, state}, else: {:fail, state} end).(state) do {:ok, state} -> case (fn state -> snowball_test_b(state, fn state -> r_shortv(state) end) end).(state) do {:ok, state} -> (fn -> saved_c = state.cursor {:ok, %{Runtime.insert(state, state.cursor, state.cursor, "e") | cursor: saved_c}} end).() r -> r end r -> r end _ -> {:ok, state} end end end).() end r -> r end _ -> {:ok, state} end end end).() end defp r_Step_1a(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_5) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> {:ok, Runtime.slice_from(state, "ss")} 2 -> {:ok, Runtime.slice_from(state, "i")} 3 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_R2(%Runtime{} = state) do if state.vars[:p2] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_R1(%Runtime{} = state) do if state.vars[:p1] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_shortv(%Runtime{} = state) do case (fn state -> lift(state, Runtime.out_grouping_b(state, @g_v_WXY)) end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.in_grouping_b(state, @g_v)) end).(state) do {:ok, state} -> lift(state, Runtime.out_grouping_b(state, @g_v)) r -> r end r -> r end end defp r_stem(%Runtime{} = state) do case (fn state -> {:ok, put_in(state.vars[:Y_found], false)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_f(state, fn state -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s(state, "y")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_from(state, "Y")} end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:Y_found], true)} end end r -> r end end end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_f(state, fn state -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> case (fn state -> case (fn state -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> v = state.cursor case (fn state -> case (fn state -> lift(state, Runtime.in_grouping(state, @g_v)) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s(state, "y")) end).(state) do {:ok, state} -> {:ok, %{state | ket: state.cursor}} r -> r end end r -> r end end).(state) do {:ok, s} -> {:ok, %{s | cursor: v}} {:fail, _} -> case next_codepoint(%{state | cursor: v}) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, _} -> {:fail, state} end end end) end).(state) do {:ok, state} -> case (fn state -> {:ok, Runtime.slice_from(state, "Y")} end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:Y_found], true)} end r -> r end end).(state) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, s} -> {:ok, %{s | cursor: state.cursor}} end end) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p1], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p2], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_f(state, fn state -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p1], state.cursor)} end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:p2], state.cursor)} r -> r end r -> r end end r -> r end r -> r end end)} end).(state) do {:ok, state} -> case (fn state -> (fn state -> old_cursor = state.cursor old_lb = state.limit_backward state = %{state | cursor: state.limit, limit_backward: old_cursor} {tag, s} = (fn state -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_1a(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_1b(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_1c(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_2(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_3(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_4(state) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_Step_5a(state) end)} end).(state) do {:ok, state} -> {:ok, snowball_do_b(state, fn state -> r_Step_5b(state) end)} end end end end end end end end).(state) {tag, %{s | cursor: old_cursor, limit_backward: old_lb}} end).(state) end).(state) do {:ok, state} -> {:ok, snowball_do_f(state, fn state -> case (fn state -> if state.vars[:Y_found], do: {:ok, state}, else: {:fail, state} end).(state) do {:ok, state} -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> case (fn state -> case (fn state -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> v = state.cursor case (fn state -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s(state, "Y")) end).(state) do {:ok, state} -> {:ok, %{state | ket: state.cursor}} r -> r end end end).(state) do {:ok, s} -> {:ok, %{s | cursor: v}} {:fail, _} -> case next_codepoint(%{state | cursor: v}) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, _} -> {:fail, state} end end end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "y")} r -> r end end).(state) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, s} -> {:ok, %{s | cursor: state.cursor}} end end) r -> r end end)} end end end end end end end end end