Current section
Files
Jump to
Current section
Files
src/string_width@internal@ansi.erl
-module(string_width@internal@ansi).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/string_width/internal/ansi.gleam").
-export([match/1, strip/1]).
-export_type([state/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(false).
-type state() :: text |
{escape, integer()} |
{c_s_i, integer()} |
{o_s_c, integer()} |
{o_s_c_esc, integer()}.
-file("src/string_width/internal/ansi.gleam", 28).
?DOC(false).
-spec match(binary()) -> list({integer(), integer()}).
match(Str) ->
{_, _, Matches@1} = begin
string_width_ffi:fold_bytes(
Str,
{0, text, []},
fun(_use0, Byte) ->
{Pos, State, Matches} = _use0,
case State of
text ->
case Byte of
16#1b ->
{Pos + 1, {escape, Pos}, Matches};
_ ->
{Pos + 1, State, Matches}
end;
{escape, Start} ->
case Byte of
16#5b ->
{Pos + 1, {c_s_i, Start}, Matches};
16#5d ->
{Pos + 1, {o_s_c, Start}, Matches};
_ when (Byte >= 16#30) andalso (Byte =< 16#3f) ->
{Pos + 1,
text,
[{Start, (Pos - Start) + 1} | Matches]};
16#50 ->
{Pos + 1, {o_s_c, Start}, Matches};
16#58 ->
{Pos + 1, {o_s_c, Start}, Matches};
16#5e ->
{Pos + 1, {o_s_c, Start}, Matches};
16#5f ->
{Pos + 1, {o_s_c, Start}, Matches};
_ when (Byte >= 16#40) andalso (Byte =< 16#5f) ->
{Pos + 1,
text,
[{Start, (Pos - Start) + 1} | Matches]};
_ when (Byte >= 16#60) andalso (Byte =< 16#7e) ->
{Pos + 1,
text,
[{Start, (Pos - Start) + 1} | Matches]};
_ ->
{Pos + 1, text, Matches}
end;
{c_s_i, Start@1} ->
case Byte of
_ when (Byte >= 16#20) andalso (Byte =< 16#3f) ->
{Pos + 1, State, Matches};
_ when (Byte >= 16#40) andalso (Byte =< 16#7e) ->
{Pos + 1,
text,
[{Start@1, (Pos - Start@1) + 1} | Matches]};
_ ->
{Pos + 1, text, Matches}
end;
{o_s_c, Start@2} ->
case Byte of
16#07 ->
{Pos + 1,
text,
[{Start@2, (Pos - Start@2) + 1} | Matches]};
16#1b ->
{Pos + 1, {o_s_c_esc, Start@2}, Matches};
_ ->
{Pos + 1, State, Matches}
end;
{o_s_c_esc, Start@3} ->
case Byte of
16#5c ->
{Pos + 1,
text,
[{Start@3, (Pos - Start@3) + 1} | Matches]};
16#07 ->
{Pos + 1,
text,
[{Start@3, (Pos - Start@3) + 1} | Matches]};
_ ->
{Pos + 1, {o_s_c, Start@3}, Matches}
end
end
end
)
end,
lists:reverse(Matches@1).
-file("src/string_width/internal/ansi.gleam", 16).
?DOC(false).
-spec do_strip(binary(), integer(), list({integer(), integer()}), binary()) -> binary().
do_strip(Str, Offset, Matches, Acc) ->
case Matches of
[] ->
<<Acc/binary, Str/binary>>;
[{From, Len} | Matches@1] ->
{Before, At_ansi} = erlang:split_binary(Str, From - Offset),
{_, Str@1} = erlang:split_binary(At_ansi, Len),
do_strip(
Str@1,
From + Len,
Matches@1,
<<Acc/binary, Before/binary>>
)
end.
-file("src/string_width/internal/ansi.gleam", 12).
?DOC(false).
-spec strip(binary()) -> binary().
strip(Str) ->
do_strip(Str, 0, match(Str), <<""/utf8>>).