-module(etui@style). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/etui/style.gleam"). -export([none/0, bold/0, dim/0, italic/0, underline/0, blink/0, reverse/0, strikethrough/0, add/2, remove/2, has/2, is_none/1, modifier_equal/2, default_style/0, with_fg/2, with_bg/2, with_modifier/2, bold_style/0, reversed/0, italic_style/0, dim_style/0, underline_style/0, add_modifier/2, remove_modifier/2, color_from_hex/1, patch/2, ansi_fg/1, ansi_bg/1, ansi_modifier/1, ansi_reset/0]). -export_type([color/0, modifier/0, style/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. -type color() :: default | {indexed, integer()} | {rgb, integer(), integer(), integer()}. -opaque modifier() :: {modifier, integer()}. -type style() :: {style, color(), color(), modifier()}. -file("src/etui/style.gleam", 27). ?DOC(" No modifiers active.\n"). -spec none() -> modifier(). none() -> {modifier, 0}. -file("src/etui/style.gleam", 32). ?DOC(" Bold / increased intensity.\n"). -spec bold() -> modifier(). bold() -> {modifier, 1}. -file("src/etui/style.gleam", 37). ?DOC(" Dim / decreased intensity.\n"). -spec dim() -> modifier(). dim() -> {modifier, 2}. -file("src/etui/style.gleam", 42). ?DOC(" Italic text.\n"). -spec italic() -> modifier(). italic() -> {modifier, 4}. -file("src/etui/style.gleam", 47). ?DOC(" Underline.\n"). -spec underline() -> modifier(). underline() -> {modifier, 8}. -file("src/etui/style.gleam", 52). ?DOC(" Blinking text (terminal support varies).\n"). -spec blink() -> modifier(). blink() -> {modifier, 16}. -file("src/etui/style.gleam", 57). ?DOC(" Swap foreground and background colors.\n"). -spec reverse() -> modifier(). reverse() -> {modifier, 32}. -file("src/etui/style.gleam", 62). ?DOC(" Strikethrough.\n"). -spec strikethrough() -> modifier(). strikethrough() -> {modifier, 64}. -file("src/etui/style.gleam", 70). ?DOC(" Combine two modifiers (bitwise OR).\n"). -spec add(modifier(), modifier()) -> modifier(). add(A, B) -> {modifier, erlang:'bor'(erlang:element(2, A), erlang:element(2, B))}. -file("src/etui/style.gleam", 75). ?DOC(" Remove modifier bits from `a` that are set in `b`.\n"). -spec remove(modifier(), modifier()) -> modifier(). remove(A, B) -> {modifier, erlang:'band'(erlang:element(2, A), erlang:'bnot'(erlang:element(2, B)))}. -file("src/etui/style.gleam", 80). ?DOC(" Check if `flag` bits are set in `m`.\n"). -spec has(modifier(), modifier()) -> boolean(). has(M, Flag) -> erlang:'band'(erlang:element(2, M), erlang:element(2, Flag)) /= 0. -file("src/etui/style.gleam", 85). ?DOC(" True when no modifier bits are set.\n"). -spec is_none(modifier()) -> boolean(). is_none(M) -> erlang:element(2, M) =:= 0. -file("src/etui/style.gleam", 90). ?DOC(" Structural equality for modifiers.\n"). -spec modifier_equal(modifier(), modifier()) -> boolean(). modifier_equal(A, B) -> erlang:element(2, A) =:= erlang:element(2, B). -file("src/etui/style.gleam", 103). ?DOC(" Default style: terminal colors, no modifiers.\n"). -spec default_style() -> style(). default_style() -> {style, default, default, none()}. -file("src/etui/style.gleam", 108). ?DOC(" Set foreground color on a style.\n"). -spec with_fg(style(), color()) -> style(). with_fg(S, Fg) -> {style, Fg, erlang:element(3, S), erlang:element(4, S)}. -file("src/etui/style.gleam", 113). ?DOC(" Set background color on a style.\n"). -spec with_bg(style(), color()) -> style(). with_bg(S, Bg) -> {style, erlang:element(2, S), Bg, erlang:element(4, S)}. -file("src/etui/style.gleam", 118). ?DOC(" Set modifier on a style.\n"). -spec with_modifier(style(), modifier()) -> style(). with_modifier(S, M) -> {style, erlang:element(2, S), erlang:element(3, S), M}. -file("src/etui/style.gleam", 123). ?DOC(" Default colors with bold modifier.\n"). -spec bold_style() -> style(). bold_style() -> {style, default, default, bold()}. -file("src/etui/style.gleam", 128). ?DOC(" Default colors with reverse modifier (swap fg/bg).\n"). -spec reversed() -> style(). reversed() -> {style, default, default, reverse()}. -file("src/etui/style.gleam", 133). ?DOC(" Default colors with italic modifier.\n"). -spec italic_style() -> style(). italic_style() -> {style, default, default, italic()}. -file("src/etui/style.gleam", 138). ?DOC(" Default colors with dim modifier.\n"). -spec dim_style() -> style(). dim_style() -> {style, default, default, dim()}. -file("src/etui/style.gleam", 143). ?DOC(" Default colors with underline modifier.\n"). -spec underline_style() -> style(). underline_style() -> {style, default, default, underline()}. -file("src/etui/style.gleam", 148). ?DOC(" Add a modifier to a `Style` (bitwise OR).\n"). -spec add_modifier(style(), modifier()) -> style(). add_modifier(S, M) -> {style, erlang:element(2, S), erlang:element(3, S), add(erlang:element(4, S), M)}. -file("src/etui/style.gleam", 153). ?DOC(" Remove modifier bits from a `Style`.\n"). -spec remove_modifier(style(), modifier()) -> style(). remove_modifier(S, M) -> {style, erlang:element(2, S), erlang:element(3, S), remove(erlang:element(4, S), M)}. -file("src/etui/style.gleam", 192). -spec hex_digit(binary()) -> {ok, integer()} | {error, nil}. hex_digit(C) -> case C of <<"0"/utf8>> -> {ok, 0}; <<"1"/utf8>> -> {ok, 1}; <<"2"/utf8>> -> {ok, 2}; <<"3"/utf8>> -> {ok, 3}; <<"4"/utf8>> -> {ok, 4}; <<"5"/utf8>> -> {ok, 5}; <<"6"/utf8>> -> {ok, 6}; <<"7"/utf8>> -> {ok, 7}; <<"8"/utf8>> -> {ok, 8}; <<"9"/utf8>> -> {ok, 9}; <<"a"/utf8>> -> {ok, 10}; <<"A"/utf8>> -> {ok, 10}; <<"b"/utf8>> -> {ok, 11}; <<"B"/utf8>> -> {ok, 11}; <<"c"/utf8>> -> {ok, 12}; <<"C"/utf8>> -> {ok, 12}; <<"d"/utf8>> -> {ok, 13}; <<"D"/utf8>> -> {ok, 13}; <<"e"/utf8>> -> {ok, 14}; <<"E"/utf8>> -> {ok, 14}; <<"f"/utf8>> -> {ok, 15}; <<"F"/utf8>> -> {ok, 15}; _ -> {error, nil} end. -file("src/etui/style.gleam", 185). -spec hex_pair(binary(), binary()) -> {ok, integer()} | {error, nil}. hex_pair(Hi, Lo) -> case {hex_digit(Hi), hex_digit(Lo)} of {{ok, H}, {ok, L}} -> {ok, (H * 16) + L}; {_, _} -> {error, nil} end. -file("src/etui/style.gleam", 164). ?DOC( " Parse an RGB color from a hex string (`\"#RRGGBB\"` or `\"RRGGBB\"`).\n" " Returns `Error(Nil)` for malformed input.\n" "\n" " ```gleam\n" " style.color_from_hex(\"#1e1e2e\") // Ok(Rgb(30, 30, 46))\n" " style.color_from_hex(\"ff5555\") // Ok(Rgb(255, 85, 85))\n" " ```\n" ). -spec color_from_hex(binary()) -> {ok, color()} | {error, nil}. color_from_hex(Hex) -> S = case gleam_stdlib:string_starts_with(Hex, <<"#"/utf8>>) of true -> gleam@string:drop_start(Hex, 1); false -> Hex end, case string:length(S) =:= 6 of false -> {error, nil}; true -> Chars = gleam@string:to_graphemes(S), case Chars of [R1, R2, G1, G2, B1, B2] -> case {hex_pair(R1, R2), hex_pair(G1, G2), hex_pair(B1, B2)} of {{ok, R}, {ok, G}, {ok, B}} -> {ok, {rgb, R, G, B}}; {_, _, _} -> {error, nil} end; _ -> {error, nil} end end. -file("src/etui/style.gleam", 217). ?DOC( " Apply `over` on top of `base`. Default fg/bg fall back to `base`.\n" " Modifier: if `over` has any bits set, they are OR'd into `base`;\n" " `none()` in `over` means \"no modifier override\" (keep base).\n" ). -spec patch(style(), style()) -> style(). patch(Base, Over) -> Fg = case erlang:element(2, Over) of default -> erlang:element(2, Base); C -> C end, Bg = case erlang:element(3, Over) of default -> erlang:element(3, Base); C@1 -> C@1 end, Modifier = case is_none(erlang:element(4, Over)) of true -> erlang:element(4, Base); false -> add(erlang:element(4, Base), erlang:element(4, Over)) end, {style, Fg, Bg, Modifier}. -file("src/etui/style.gleam", 237). ?DOC(" Foreground color escape sequence.\n"). -spec ansi_fg(color()) -> binary(). ansi_fg(Color) -> case Color of default -> <<""/utf8>>; {indexed, 0} -> <<"\x{001B}[30m"/utf8>>; {indexed, 1} -> <<"\x{001B}[31m"/utf8>>; {indexed, 2} -> <<"\x{001B}[32m"/utf8>>; {indexed, 3} -> <<"\x{001B}[33m"/utf8>>; {indexed, 4} -> <<"\x{001B}[34m"/utf8>>; {indexed, 5} -> <<"\x{001B}[35m"/utf8>>; {indexed, 6} -> <<"\x{001B}[36m"/utf8>>; {indexed, 7} -> <<"\x{001B}[37m"/utf8>>; {indexed, 8} -> <<"\x{001B}[90m"/utf8>>; {indexed, 9} -> <<"\x{001B}[91m"/utf8>>; {indexed, 10} -> <<"\x{001B}[92m"/utf8>>; {indexed, 11} -> <<"\x{001B}[93m"/utf8>>; {indexed, 12} -> <<"\x{001B}[94m"/utf8>>; {indexed, 13} -> <<"\x{001B}[95m"/utf8>>; {indexed, 14} -> <<"\x{001B}[96m"/utf8>>; {indexed, 15} -> <<"\x{001B}[97m"/utf8>>; {indexed, N} -> <<<<"\x{001B}[38;5;"/utf8, (erlang:integer_to_binary(N))/binary>>/binary, "m"/utf8>>; {rgb, R, G, B} -> <<<<<<<<<<<<"\x{001B}[38;2;"/utf8, (erlang:integer_to_binary(R))/binary>>/binary, ";"/utf8>>/binary, (erlang:integer_to_binary(G))/binary>>/binary, ";"/utf8>>/binary, (erlang:integer_to_binary(B))/binary>>/binary, "m"/utf8>> end. -file("src/etui/style.gleam", 269). ?DOC(" Background color escape sequence.\n"). -spec ansi_bg(color()) -> binary(). ansi_bg(Color) -> case Color of default -> <<""/utf8>>; {indexed, 0} -> <<"\x{001B}[40m"/utf8>>; {indexed, 1} -> <<"\x{001B}[41m"/utf8>>; {indexed, 2} -> <<"\x{001B}[42m"/utf8>>; {indexed, 3} -> <<"\x{001B}[43m"/utf8>>; {indexed, 4} -> <<"\x{001B}[44m"/utf8>>; {indexed, 5} -> <<"\x{001B}[45m"/utf8>>; {indexed, 6} -> <<"\x{001B}[46m"/utf8>>; {indexed, 7} -> <<"\x{001B}[47m"/utf8>>; {indexed, 8} -> <<"\x{001B}[100m"/utf8>>; {indexed, 9} -> <<"\x{001B}[101m"/utf8>>; {indexed, 10} -> <<"\x{001B}[102m"/utf8>>; {indexed, 11} -> <<"\x{001B}[103m"/utf8>>; {indexed, 12} -> <<"\x{001B}[104m"/utf8>>; {indexed, 13} -> <<"\x{001B}[105m"/utf8>>; {indexed, 14} -> <<"\x{001B}[106m"/utf8>>; {indexed, 15} -> <<"\x{001B}[107m"/utf8>>; {indexed, N} -> <<<<"\x{001B}[48;5;"/utf8, (erlang:integer_to_binary(N))/binary>>/binary, "m"/utf8>>; {rgb, R, G, B} -> <<<<<<<<<<<<"\x{001B}[48;2;"/utf8, (erlang:integer_to_binary(R))/binary>>/binary, ";"/utf8>>/binary, (erlang:integer_to_binary(G))/binary>>/binary, ";"/utf8>>/binary, (erlang:integer_to_binary(B))/binary>>/binary, "m"/utf8>> end. -file("src/etui/style.gleam", 301). ?DOC(" Text modifier escape sequence. Emits all active modifier bits.\n"). -spec ansi_modifier(modifier()) -> binary(). ansi_modifier(M) -> case is_none(M) of true -> <<""/utf8>>; false -> Parts = [], Parts@1 = case has(M, bold()) of true -> [<<"1"/utf8>> | Parts]; false -> Parts end, Parts@2 = case has(M, dim()) of true -> [<<"2"/utf8>> | Parts@1]; false -> Parts@1 end, Parts@3 = case has(M, italic()) of true -> [<<"3"/utf8>> | Parts@2]; false -> Parts@2 end, Parts@4 = case has(M, underline()) of true -> [<<"4"/utf8>> | Parts@3]; false -> Parts@3 end, Parts@5 = case has(M, blink()) of true -> [<<"5"/utf8>> | Parts@4]; false -> Parts@4 end, Parts@6 = case has(M, reverse()) of true -> [<<"7"/utf8>> | Parts@5]; false -> Parts@5 end, Parts@7 = case has(M, strikethrough()) of true -> [<<"9"/utf8>> | Parts@6]; false -> Parts@6 end, <<<<"\x{001B}["/utf8, (gleam@string:join(Parts@7, <<";"/utf8>>))/binary>>/binary, "m"/utf8>> end. -file("src/etui/style.gleam", 340). ?DOC(" Reset all styles.\n"). -spec ansi_reset() -> binary(). ansi_reset() -> <<"\x{001B}[0m"/utf8>>.