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]).
-export([match/1, strip/1]).
-export_type([state/0]).
-type state() :: text |
{escape, integer()} |
{csi, integer()} |
{osc, integer()} |
{osc_esc, integer()}.
-file("/home/arkan/Projects/private/string-width/src/string_width/internal/ansi.gleam", 29).
-spec match(binary()) -> list({integer(), integer()}).
match(Str) ->
{_, _, Matches@1} = (string_width_ffi:fold_codepoints(
Str,
{0, text, []},
fun(_use0, Cp) ->
{Pos, State, Matches} = _use0,
case State of
text ->
case Cp of
16#1b ->
{Pos + 1, {escape, Pos}, Matches};
16#9b ->
{Pos + 1, {csi, Pos}, Matches};
16#9d ->
{Pos + 1, {osc, Pos}, Matches};
_ ->
{Pos + 1, State, Matches}
end;
{escape, Start} ->
case Cp of
16#5b ->
{Pos + 1, {csi, Start}, Matches};
16#5d ->
{Pos + 1, {osc, Start}, Matches};
_ when (Cp >= 16#61) andalso (Cp =< 16#7a) ->
{Pos + 1,
text,
[{Start, (Pos - Start) + 1} | Matches]};
_ when (Cp >= 16#41) andalso (Cp =< 16#5a) ->
{Pos + 1,
text,
[{Start, (Pos - Start) + 1} | Matches]};
_ ->
{Pos + 1, {osc, Start}, Matches}
end;
{csi, Start@1} ->
case Cp of
_ when (Cp >= 16#20) andalso (Cp =< 16#3f) ->
{Pos + 1, State, Matches};
_ when (Cp >= 16#40) andalso (Cp =< 16#7e) ->
{Pos + 1,
text,
[{Start@1, (Pos - Start@1) + 1} | Matches]};
_ ->
{Pos + 1, text, Matches}
end;
{osc, Start@2} ->
case Cp of
16#07 ->
{Pos + 1,
text,
[{Start@2, (Pos - Start@2) + 1} | Matches]};
16#9c ->
{Pos + 1,
text,
[{Start@2, (Pos - Start@2) + 1} | Matches]};
16#1b ->
{Pos + 1, {osc_esc, Start@2}, Matches};
_ ->
{Pos + 1, State, Matches}
end;
{osc_esc, Start@3} ->
case Cp 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]};
16#9c ->
{Pos + 1,
text,
[{Start@3, (Pos - Start@3) + 1} | Matches]};
_ ->
{Pos + 1, {osc, Start@3}, Matches}
end
end
end
)),
lists:reverse(Matches@1).
-file("/home/arkan/Projects/private/string-width/src/string_width/internal/ansi.gleam", 17).
-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("/home/arkan/Projects/private/string-width/src/string_width/internal/ansi.gleam", 13).
-spec strip(binary()) -> binary().
strip(Str) ->
do_strip(Str, 0, match(Str), <<""/utf8>>).