Skip to content

Commit

Permalink
parse (gui): add \e[38 and \e[48 ANSI code color converter (only in r…
Browse files Browse the repository at this point in the history
…gb way)
  • Loading branch information
Toni500github committed Sep 30, 2024
1 parent 50e0989 commit d9ee1fb
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 161 deletions.
125 changes: 11 additions & 114 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ Here's an example using my config

![image](screenshot.png)

The config:

```toml
[config]

Expand Down Expand Up @@ -134,115 +132,6 @@ layout = [
"$<builtin.colors_light>" # light colors palette
]

# display ascii-art or image/gif (GUI only) near layout
# put "os" for displaying the OS ascii-art
# or the "/path/to/file" for displaying custom files
# or "off" for disabling ascii-art or image displaying
source-path = "os"

# Path to where we'll take all the distros/OSs ascii arts
# note: it MUST contain an "ascii" subdirectory
data-dir = "/usr/share/customfetch"

# The type of ASCII art to apply ("small", "old").
# Basically will add "_<type>" to the logo filename.
# It will return the regular linux ascii art if it doesn't exist.
# Leave empty it for regular.
ascii-logo-type = ""

# A char (or string) to use in $<builtin.title_sep>
title-sep = "-"

# A separator (or string) that when ecountered, will automatically
# reset color, aka. automatically add ${0} (only in layout)
# Make it empty for disabling
sep-reset = ":"

# Should we reset color after or before the separator?
# true = after ("test ->${0} ")
# false = before ("test ${0}-> ")
sep-reset-after = false

# Offset between the ascii art and the layout
offset = 5

# Padding between the start and the ascii art
logo-padding-left = 0

# Padding of the ascii art from the top
logo-padding-top = 0

# Padding of the layout from the top
layout-padding-top = 0

# Colors can be with: hexcodes (#55ff88) and for bold put '!' (!#55ff88)
# OR ANSI escape code colors like "\e[1;34m"
# remember to add ${0} where you want to reset color
black = "\e[1;30m"
red = "\e[1;31m"
green = "\e[1;32m"
yellow = "\e[1;33m"
blue = "\e[1;34m"
magenta = "\e[1;35m"
cyan = "\e[1;36m"
white = "\e[1;37m"

# $<os.uptime> config
[os.uptime]
# how to display the name of the uptime
# e.g: hours = "hrs" -> "Uptime: 3hrs"
days = " days"
hours = " hours"
mins = " mins"
secs = " seconds"

# $<os.pkgs> config
[os.pkgs]
# Ordered list of which packages installed count should be displayed in $<os.pkgs>
# remember to not enter the same name twice, else the world will finish
# Choices: pacman, flatpak, dpkg, apk
#
# Pro-tip: if your package manager isnt listed here, yet,
# use the bash command tag in the layout
# e.g "Packages: $(pacman -Q | wc -l) (pacman)"
pkg-managers = ["pacman", "dpkg", "flatpak"]

# Distros and package manager specific
# package manager paths for getting the packages count from path.
# They are arrayies so you can add multiple paths.
#
# If you don't know what these ares, leave them by default settings
pacman-dirs = ["/var/lib/pacman/local/"]
dpkg-files = ["/var/lib/dpkg/status"]
flatpak-dirs = ["/var/lib/flatpak/app/", "~/.local/share/flatpak/app/"]
apk-files = ["/var/lib/apk/db/installed"]

# GUI options
# note: customfetch needs to be compiled with GUI_MODE=1 (check with "cufetch --version")
[gui]
enable = false

# Font to be used
# syntax must be [FAMILY-LIST] [STYLE-OPTIONS] [SIZE]
# e.g "Liberation Mono Normal 12"
# check https://lazka.github.io/pgi-docs/Pango-1.0/classes/FontDescription.html#Pango.FontDescription for more infos
font = "Liberation Mono Normal 12"

# These are the colors palette you can use in the GUI mode.
# They can overwritte with ANSI escape code colors
# but they don't work with those, only hexcodes
black = "!#000005"
red = "!#ff2000"
green = "!#00ff00"
blue = "!#00aaff"
cyan = "!#00ffff"
yellow = "!#ffff00"
magenta = "!#f881ff"
white = "!#ffffff"

# Path to image as a background.
# put "disable" for disabling and use the theme color as background.
bg-image = "/tmp/idk.png"

```

Expand Down Expand Up @@ -276,13 +165,21 @@ They can be used in the ascii art text file and layout, but how to use them?
The colors can be: <ins>black</ins>, <ins>red</ins>, <ins>green</ins>, <ins>blue</ins>, <ins>cyan</ins>, <ins>yellow</ins>, <ins>magenta</ins>, <ins>white</ins> and they can be configured in the config file.\
You can put a custom hex color e.g: `${#ff6622}`.\
It's possible to enable multiple options, put these symbols before `#`:\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**Terminal and GUI**\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`b` - for making the color in the background\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`u` - for underline the text\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`u` - to underline the text\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`!` - for making the text bold\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`i` - for making the text italic\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**GUI Only**\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`o` - for overline\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`a(value)` - for fg alpha (either a plain integer between 1 and 65536 or a percentage value like `50%`)\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`L(value)` - to underline the text with a style (`none`, `single`, `double`, `low`, `error`)\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`U(value)` - for choosing the underline color (hexcode without #)\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`B(value)` - for bg color text (hexcode without #)\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;**Terminal Only**\
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`l` - for blinking text\
\
Alternatively, ANSI escape codes can be used, e.g `\\e[1;31m` and `\\e[38;5;160m`\
(NOTE: 256 colors ANSI escape codes, those that have `\e[38` or `\e[48`, can't be used in GUI mode).\
Alternatively, ANSI escape codes can be used, e.g `\\e[1;31m` and `\\e[38;5;160m`.\
For auto coloring, depending on the ascii logo colors, use `${auto}`.\
They can be used for different colors too. So for getting the 2nd color of the ascii logo,\
use `${auto2}`, for the 4th one use `${auto4}` and so on.
Expand Down
2 changes: 1 addition & 1 deletion cufetch.1
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ layout = [
* \fBl\fR for blinking text
.fi
.PP
Alternatively, ANSI escape codes can be used, e.g "\\e[1;31m" and "\\e[38;5;160m", but \fBnote\fR that 256-color ANSI escape codes (those that starts with \\[38 or \\[48) cannot be used in GUI mode.
Alternatively, ANSI escape codes can be used, e.g "\\e[1;31m" and "\\e[38;5;160m".
.PP
You can also use them inside the tag, like \fB${!#343345}\fR or \fB${\\e[1;31m}\fR.
.PP
Expand Down
15 changes: 7 additions & 8 deletions include/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,16 +124,15 @@ inline constexpr std::string_view AUTOCONFIG = R"#([config]
# They can have hexcodes colors (e.g "#5522dd").
# You can apply special effects to colors by using the following symbols before the '#' in hex codes:
# Terminal and GUI GUI Only
# * b for background color. * o for overline
# * u to underline the text * a(value) for fg alpha (either a plain integer between 1 and 65536 or a percentage value like `50%`)
# * ! for bold text * L(value) to underline the text with a style (`none`, `single`, `double`, `low`, `error`)
# * i for italic text * U(value) for choosing the underline color (hexcode without #)
# * B(value) for bg color text (hexcode without #)
# * b - for background color. * o - for overline
# * u - to underline the text * a(value) - for fg alpha (either a plain integer between 1 and 65536 or a percentage value like `50%`)
# * ! - for bold text * L(value) - to underline the text with a style (`none`, `single`, `double`, `low`, `error`)
# * i - for italic text * U(value) - for choosing the underline color (hexcode without #)
# * B(value) - for bg color text (hexcode without #)
# Terminal Only
# * l for blinking text
# * l - for blinking text
#
# Alternatively, ANSI escape codes can be used, e.g ${\e[1;32m} or ${\e[0;34m}.
# NOTE: 256-color ANSI escape codes (those that starts with \\[38 or \\[48) cannot be used in GUI mode.
#
# To reset colors, use ${0} for a normal reset or ${1} for a bold reset.
#
Expand Down Expand Up @@ -239,7 +238,7 @@ magenta = "\e[1;35m"
cyan = "\e[1;36m"
white = "\e[1;37m"
# Alias colors.
# Alias colors. Basically more color variables, but config depending.
# They can be used as like as the color tag.
# This is as like as using the --color argument
# Syntax must be "name=value", e.g "purple=magenta" or "orange=!#F08000"
Expand Down
2 changes: 1 addition & 1 deletion include/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ bool is_file_image(const unsigned char* bytes);
void ctrl_d_handler(const std::istream& cin);
std::string expandVar(std::string ret);
bool taur_exec(const std::vector<std::string_view> cmd_str, const bool noerror_print = true);
std::string which(const std::string& command);
std::string which(const std::string_view command);
bool read_binary_file(std::ifstream& f, std::string& ret);
void replace_str(std::string& str, const std::string_view from, const std::string_view to);
bool read_exec(std::vector<const char*> cmd, std::string& output, bool useStdErr = false, bool noerror_print = true);
Expand Down
75 changes: 48 additions & 27 deletions src/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,27 @@ static std::array<std::string, 3> get_ansi_color(const std::string_view str, con
// clang-format on
}

static std::string convert_ansi_escape_rgb(const std::string_view noesc_str)
{
if (std::count(noesc_str.begin(), noesc_str.end(), ';') < 4)
die("ANSI escape code color '\\e[{}' should have an rgb type value\n"
"e.g \\e[38;2;r;g;b", noesc_str);

const std::vector<std::string>& rgb_str = split(noesc_str.substr(5), ';');

const uint r = std::stoul(rgb_str.at(0));
const uint g = std::stoul(rgb_str.at(1));
const uint b = std::stoul(rgb_str.at(2));

const uint result = (r<<16) | (g<<8)| (b);
std::stringstream ss;
ss << std::hex << result;
return ss.str();
}

static std::string get_and_color_percentage(const float& n1, const float& n2, systemInfo_t& systemInfo,
const Config& config, const colors_t& colors, const bool parsingLayout,
bool invert = false)
const bool invert = false)
{
const float result = static_cast<float>(n1 / n2 * static_cast<float>(100));

Expand Down Expand Up @@ -114,14 +132,6 @@ static std::string get_and_color_percentage(const float& n1, const float& n2, sy
return parse(fmt::format("{}{:.2f}%${{0}}", color, result), systemInfo, _, config, colors, parsingLayout);
}

static const std::string& check_gui_ansi_clr(const std::string& str)
{
if (hasStart(str, "\033") || hasStart(str, "\\e"))
die("GUI colors can't be in ANSI escape sequence");

return str;
}

std::string getInfoFromName(const systemInfo_t& systemInfo, const std::string_view moduleName,
const std::string_view moduleMemberName)
{
Expand All @@ -148,7 +158,7 @@ std::string getInfoFromName(const systemInfo_t& systemInfo, const std::string_vi
std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::string& pureOutput, const Config& config,
const colors_t& colors, const bool parsingLayout)
{
std::string output = input.data();
std::string output{input.data()};
pureOutput = output;

size_t dollarSignIndex = 0;
Expand Down Expand Up @@ -374,7 +384,7 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s
}
break;

case '}': // please pay very attention when reading this unreadable and godawful code
case '}': // please pay very attention when reading this really long code

// if at end there a '$', it will make the end output "$</span>" and so it will confuse
// addValueFromModule() and so let's make it "$ </span>". this is geniunenly stupid
Expand Down Expand Up @@ -438,14 +448,14 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s
{
switch (fnv1a16::hash(command))
{
case "black"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_black); break;
case "red"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_red); break;
case "blue"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_blue); break;
case "green"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_green); break;
case "cyan"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_cyan); break;
case "yellow"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_yellow); break;
case "magenta"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_magenta); break;
case "white"_fnv1a16: str_clr = check_gui_ansi_clr(colors.gui_white); break;
case "black"_fnv1a16: str_clr = colors.gui_black; break;
case "red"_fnv1a16: str_clr = colors.gui_red; break;
case "blue"_fnv1a16: str_clr = colors.gui_blue; break;
case "green"_fnv1a16: str_clr = colors.gui_green; break;
case "cyan"_fnv1a16: str_clr = colors.gui_cyan; break;
case "yellow"_fnv1a16: str_clr = colors.gui_yellow; break;
case "magenta"_fnv1a16: str_clr = colors.gui_magenta; break;
case "white"_fnv1a16: str_clr = colors.gui_white; break;
default: str_clr = command; break;
}

Expand Down Expand Up @@ -506,15 +516,26 @@ std::string parse(const std::string_view input, systemInfo_t& systemInfo, std::s
// "\\e" is for checking in the ascii_art, \033 in the config
else if (hasStart(str_clr, "\\e") || hasStart(str_clr, "\033"))
{
const std::array<std::string, 3>& clrs = get_ansi_color(
(hasStart(str_clr, "\033") ? str_clr.substr(2) : str_clr.substr(3)), colors);
const std::string& noesc_str = hasStart(str_clr, "\033") ? str_clr.substr(2) : str_clr.substr(3);
debug("noesc_str = {}", noesc_str);

const std::string_view color = clrs.at(0);
const std::string_view weight = clrs.at(1);
const std::string_view type = clrs.at(2);
output.replace(dollarSignIndex, output.length() - dollarSignIndex,
fmt::format("<span {}='{}' weight='{}'>{}</span>", type, color, weight,
output.substr(endBracketIndex + 1)));
if (hasStart(noesc_str, "38;2;") || hasStart(noesc_str, "48;2;"))
{
const std::string& hexclr = convert_ansi_escape_rgb(noesc_str);
output.replace(dollarSignIndex, output.length() - dollarSignIndex,
fmt::format("<span {}gcolor='#{}'>{}</span>", hasStart(noesc_str, "38") ? 'f' : 'b', hexclr,
output.substr(endBracketIndex + 1)));
}
else
{
const std::array<std::string, 3>& clrs = get_ansi_color(noesc_str, colors);
const std::string_view color = clrs.at(0);
const std::string_view weight = clrs.at(1);
const std::string_view type = clrs.at(2);
output.replace(dollarSignIndex, output.length() - dollarSignIndex,
fmt::format("<span {}='{}' weight='{}'>{}</span>", type, color, weight,
output.substr(endBracketIndex + 1)));
}
}

else
Expand Down
15 changes: 5 additions & 10 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,13 @@ std::string shorten_vendor_name(std::string vendor)

fmt::rgb hexStringToColor(const std::string_view hexstr)
{
// convert the hexadecimal string to individual components
std::stringstream ss;
ss << std::hex << hexstr.substr(1).data();

uint intValue;
ss >> intValue;
uint value;
ss >> value;

const uint red = (intValue >> 16) & 0xFF;
const uint green = (intValue >> 8) & 0xFF;
const uint blue = intValue & 0xFF;

return fmt::rgb(red, green, blue);
return fmt::rgb(value);
}

bool read_binary_file(std::ifstream& f, std::string& ret)
Expand Down Expand Up @@ -270,7 +265,7 @@ bool read_binary_file(std::ifstream& f, std::string& ret)
return false;
}

std::string which(const std::string& command)
std::string which(const std::string_view command)
{
const std::string_view env = std::getenv("PATH");
struct stat sb;
Expand All @@ -282,7 +277,7 @@ std::string which(const std::string& command)
// -300ns for not creating a string. stonks
fullPath += dir;
fullPath += '/';
fullPath += command;
fullPath += command.data();
if ((stat(fullPath.data(), &sb) == 0) && sb.st_mode & S_IXUSR)
return fullPath.data();

Expand Down

0 comments on commit d9ee1fb

Please sign in to comment.