Packages

Pure-Gleam implementation of KnuthLiang Hyphenation.

Current section

Files

Jump to
hyphenation src hyphenation@internal@patterns.erl
Raw

src/hyphenation@internal@patterns.erl

-module(hyphenation@internal@patterns).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([get_pattern_score/2, new_patterns/0, insert_reference/2, parse_reference/1, new/1, hyphenate/1, read_patterns/1, from_codegen/1, update_score/3, conseq_sublist/1, process_input/2, process/2]).
-export_type([input/0, reference_/0, pattern/1, patterns/0]).
-opaque input() :: input.
-opaque reference_() :: reference.
-type pattern(FYQ) :: {pattern, list(binary()), list(integer())} |
{gleam_phantom, FYQ}.
-type patterns() :: {patterns, list({list(binary()), list(integer())})}.
-spec get_pattern_score(patterns(), list(binary())) -> {ok, list(integer())} |
{error, nil}.
get_pattern_score(Ps, P) ->
{patterns, Ls} = Ps,
gleam@list:key_find(Ls, P).
-spec new_patterns() -> patterns().
new_patterns() ->
{patterns, [{[], []}]}.
-spec insert_reference(patterns(), pattern(any())) -> patterns().
insert_reference(Ps, P) ->
Ref = {erlang:element(2, P), erlang:element(3, P)},
{patterns, Ls} = Ps,
{patterns, [Ref | Ls]}.
-spec score_reference(binary()) -> list(integer()).
score_reference(S) ->
case gleam@string:pop_grapheme(S) of
{error, nil} ->
[];
{ok, {X, Xs}} ->
case gleam@int:parse(X) of
{error, nil} ->
[0 | score_reference(Xs)];
{ok, N} ->
case gleam@string:pop_grapheme(Xs) of
{error, nil} ->
[N];
{ok, {_, Ys}} ->
[N | score_reference(Ys)]
end
end
end.
-spec parse_reference(binary()) -> pattern(reference_()).
parse_reference(S) ->
Is_not_digit = fun(X) -> _pipe = X,
_pipe@1 = gleam@int:parse(_pipe),
gleam@result:is_error(_pipe@1) end,
New_s = begin
_pipe@2 = S,
_pipe@3 = gleam@string:to_graphemes(_pipe@2),
gleam@list:filter(_pipe@3, Is_not_digit)
end,
{pattern, New_s, score_reference(S)}.
-spec new(binary()) -> pattern(input()).
new(S) ->
New_s = gleam@string:to_graphemes(S),
L = gleam@list:length(New_s),
Empty_score = gleam@list:repeat(0, L + 1),
{pattern, New_s, Empty_score}.
-spec do_hyphenate(list({binary(), integer()}), list(binary())) -> list(binary()).
do_hyphenate(Ls, Acc) ->
Extract_string = fun(List) -> _pipe = List,
_pipe@1 = gleam@list:map(_pipe, fun(T) -> erlang:element(1, T) end),
gleam@string:concat(_pipe@1) end,
{Head, New_ls} = case Ls of
[] ->
{{<<""/utf8>>, 0}, []};
[X | Xs] ->
case gleam@int:is_odd(erlang:element(2, X)) of
true ->
{X, Xs};
false ->
{{<<""/utf8>>, 0}, [X | Xs]}
end
end,
Split = gleam@list:split_while(
New_ls,
fun(T@1) -> gleam@int:is_even(erlang:element(2, T@1)) end
),
case Split of
{[], Rest} ->
case Rest of
[] ->
gleam@list:append(Acc, [erlang:element(1, Head)]);
[X@1 | Xs@1] ->
case gleam@int:is_odd(erlang:element(2, Head)) of
true ->
do_hyphenate(
[X@1 | Xs@1],
gleam@list:append(
Acc,
[erlang:element(1, Head)]
)
);
false ->
do_hyphenate(
Xs@1,
gleam@list:append(
Acc,
[<<(erlang:element(1, Head))/binary,
(erlang:element(1, X@1))/binary>>]
)
)
end
end;
{Syllable, []} ->
gleam@list:append(
Acc,
[<<(erlang:element(1, Head))/binary,
(Extract_string(Syllable))/binary>>]
);
{Syllable@1, Rest@1} ->
do_hyphenate(
Rest@1,
gleam@list:append(
Acc,
[<<(erlang:element(1, Head))/binary,
(Extract_string(Syllable@1))/binary>>]
)
)
end.
-spec hyphenate(list({binary(), integer()})) -> list(binary()).
hyphenate(Ls) ->
do_hyphenate(Ls, []).
-spec read_patterns(binary()) -> {ok, patterns()} |
{error, simplifile:file_error()}.
read_patterns(File) ->
gleam@result:map(
simplifile:read(File),
fun(Patterns_str) -> _pipe = Patterns_str,
_pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>),
_pipe@2 = gleam@list:map(_pipe@1, fun parse_reference/1),
gleam@list:fold(_pipe@2, new_patterns(), fun insert_reference/2) end
).
-spec from_codegen(list(binary())) -> patterns().
from_codegen(Codegen) ->
_pipe = Codegen,
_pipe@1 = gleam@list:map(_pipe, fun parse_reference/1),
gleam@list:fold(_pipe@1, new_patterns(), fun insert_reference/2).
-spec update_score(list(integer()), list(integer()), integer()) -> list(integer()).
update_score(Old, New, Padding) ->
Pad_left_new = gleam@list:append(gleam@list:repeat(0, Padding), New),
Pad_right = gleam@list:repeat(
0,
gleam@list:length(Old) - gleam@list:length(Pad_left_new)
),
Padded_new = gleam@list:append(Pad_left_new, Pad_right),
gleam@list:map2(Old, Padded_new, fun gleam@int:max/2).
-spec do_conseq_sublist(list(FZU)) -> list(list(FZU)).
do_conseq_sublist(L) ->
_pipe = L,
gleam@list:index_map(_pipe, fun(_, I) -> gleam@list:take(L, I + 1) end).
-spec conseq_sublist(list(FZQ)) -> list({integer(), list(FZQ)}).
conseq_sublist(L) ->
_pipe = L,
_pipe@3 = gleam@list:index_map(
_pipe,
fun(_, I) -> _pipe@1 = gleam@list:drop(L, I),
_pipe@2 = do_conseq_sublist(_pipe@1),
gleam@list:map(_pipe@2, fun(Subl) -> {I, Subl} end) end
),
gleam@list:concat(_pipe@3).
-spec process_input(pattern(input()), patterns()) -> list(integer()).
process_input(Inp, Patterns) ->
Subs = begin
_pipe = erlang:element(2, Inp),
conseq_sublist(_pipe)
end,
_pipe@1 = Subs,
gleam@list:fold(
_pipe@1,
erlang:element(3, Inp),
fun(Old_score, Ind_substring) ->
case get_pattern_score(Patterns, erlang:element(2, Ind_substring)) of
{ok, New_score} ->
update_score(
Old_score,
New_score,
erlang:element(1, Ind_substring)
);
{error, nil} ->
Old_score
end
end
).
-spec process(binary(), patterns()) -> list(binary()).
process(S, Ps) ->
Pattern = begin
_pipe = S,
new(_pipe)
end,
Res_score = process_input(Pattern, Ps),
hyphenate(gleam@list:zip(erlang:element(2, Pattern), Res_score)).