Current section
Files
Jump to
Current section
Files
src/cf.erl
%%%-------------------------------------------------------------------%%% @author Heinz Nikolaus Gies <heinz@project-fifo.net>%%% @copyright (C) 2015, Project-FiFo UG%%% @doc%%% Printing library for coloured console output, extends the format%%% strings by adding ~! (forground) ~# (background) and ~_ (underline)%%% terminal colours.%%% @end%%% Created : 22 Sep 2015 by Heinz Nikolaus Gies <heinz@licenser.net>%%%--------------------------------------------------------------------module(cf).%% API exports-export([format/1, format/2]).-export([print/1, print/2]).%%====================================================================%% API functions%%====================================================================%% @doc Prints a coloured string.%% Effectively the same as io:format just takes the additional color%% console text colour can be set by ~!**<colour>**. ~#**<colour>**%% will change the background. Both ~# only work with lowercase colours.%% An uppercase letersindicate bold colours.%% A `_` can be added after the ~! to make the text underlined.%%%% The colour can be one of:%%%% ! - resets the output%% ^ - makes text bold%% x,X - black%% r,R - red%% g,G - greeen%% y,Y - yellow%% b,B - blue%% m,M - magenta%% c,C - cyan%% w,W - white%%%% true color is supported by using%% ~!#<rr><gg><bb> as each as hex values so ~!#ff6402%%%% the same can be done for the background by yusign ~##%%%% The function will disable colours on non x term termials%% @endprint(Fmt, Args) -> io:format(cfmt(Fmt), Args).%% @doc Formates a coloured string%% Arguments are the same as for print/2, just returns a string as%% io_lib:format/2 does instead of printing it to stdout.%% @endformat(Fmt, Args) -> io_lib:format(cfmt(Fmt), Args).print(Fmt) -> print(Fmt, []).format(Fmt) -> format(Fmt, []).%%====================================================================%% Internal functions%%====================================================================-define(NX, "\033[0;30m").-define(NR, "\033[0;31m").-define(NG, "\033[0;32m").-define(NY, "\033[0;33m").-define(NB, "\033[0;34m").-define(NM, "\033[0;35m").-define(NC, "\033[0;36m").-define(NW, "\033[0;37m").-define(BX, "\033[1;30m").-define(BR, "\033[1;31m").-define(BG, "\033[1;32m").-define(BY, "\033[1;33m").-define(BB, "\033[1;34m").-define(BM, "\033[1;35m").-define(BC, "\033[1;36m").-define(BW, "\033[1;37m").-define(U, "\033[4m").-define(B, "\033[1m").-define(BGX, "\033[40m").-define(BGR, "\033[41m").-define(BGG, "\033[42m").-define(BGY, "\033[43m").-define(BGB, "\033[44m").-define(BGM, "\033[45m").-define(BGC, "\033[46m").-define(BGW, "\033[47m").-define(R, "\033[0m").-define(CFMT(Char, Colour), cfmt_([$~, $!, Char | S], Enabled) -> [Colour | cfmt_(S, Enabled)]; cfmt_([$~, $!, $_, Char | S], Enabled) -> [Colour, ?U | cfmt_(S, Enabled)]).-define(CFMT_BG(Char, Colour), cfmt_([$~, $#, Char | S], Enabled) -> [Colour | cfmt_(S, Enabled)]).-define(CFMT_U(Char, Colour), cfmt_([$~, $_, Char | S], Enabled) -> [Colour | cfmt_(S, Enabled)]).colour_term() -> case application:get_env(cf, colour_term) of {ok, V} -> V; undefined -> Term = os:getenv("TERM"), V = cf_term:has_color(Term), application:set_env(cf, colour_term, V), V end.cfmt(S) -> cfmt(S, colour_term()).cfmt(S, Enabled) -> lists:flatten(cfmt_(S, Enabled)).cfmt_([$~, $!, $_, _C | S], false) -> cfmt_(S, false);cfmt_([$~, $#, _C | S], false) -> cfmt_(S, false);cfmt_([$~, $!, _C | S], false) -> cfmt_(S, false);cfmt_([$~, $!, $#, _R1, _R2, _G1, _G2, _B1, _B2 | S], false) -> cfmt_(S, false);cfmt_([$~, $#, $#, _R1, _R2, _G1, _G2, _B1, _B2 | S], false) -> cfmt_(S, false);cfmt_([$~, $!, $#, R1, R2, G1, G2, B1, B2 | S], Enabled) -> R = list_to_integer([R1, R2], 16), G = list_to_integer([G1, G2], 16), B = list_to_integer([B1, B2], 16), ["\033[38;2;", integer_to_list(R), $;, integer_to_list(G), $;, integer_to_list(B), $m | cfmt_(S, Enabled)];cfmt_([$~, $#, $#, R1, R2, G1, G2, B1, B2 | S], Enabled) -> R = list_to_integer([R1, R2], 16), G = list_to_integer([G1, G2], 16), B = list_to_integer([B1, B2], 16), ["\033[48;2;", integer_to_list(R), $;, integer_to_list(G), $;, integer_to_list(B), $m | cfmt_(S, Enabled)];cfmt_([$~, $!, $_, $_ | S], Enabled) -> [?U |cfmt_(S, Enabled)];cfmt_([$~,$!, $^ | S], Enabled) -> [?B | cfmt_(S, Enabled)];cfmt_([$~,$!, $_, $^ | S], Enabled) -> [?U, ?B | cfmt_(S, Enabled)];?CFMT($!, ?R);?CFMT($x, ?NX);?CFMT($X, ?BX);?CFMT($r, ?NR);?CFMT($R, ?BR);?CFMT($g, ?NG);?CFMT($G, ?BG);?CFMT($y, ?NY);?CFMT($Y, ?BY);?CFMT($b, ?NB);?CFMT($B, ?BB);?CFMT($m, ?NM);?CFMT($M, ?BM);?CFMT($c, ?NC);?CFMT($C, ?BC);?CFMT($w, ?NW);?CFMT($W, ?BW);?CFMT_BG($x, ?BGX);?CFMT_BG($r, ?BGR);?CFMT_BG($g, ?BGG);?CFMT_BG($y, ?BGY);?CFMT_BG($b, ?BGB);?CFMT_BG($m, ?BGM);?CFMT_BG($c, ?BGC);?CFMT_BG($w, ?BGW);cfmt_([$~,$~ | S], Enabled) -> [$~,$~ | cfmt_(S, Enabled)];cfmt_([C | S], Enabled) -> [C | cfmt_(S, Enabled)];cfmt_([], false) -> "";cfmt_([], _Enabled) -> ?R.