How to do math manipulation with variables in conky?

This is part of my conky code.

``````conky.config = {
alignment = 'top_right',
background = true,
color2 = '2ECC71',
cpu_avg_samples = 2,
default_color = 'FFFFFF',
double_buffer = true,
font = 'Bitstream Vera Sans:size=8',
gap_x = 25,
gap_y = 13,
minimum_width = 230,
no_buffers = true,
own_window = true,
own_window_type = 'override',
own_window_transparent = true,
update_interval = 1.0,
use_xft = true,
}

\${voffset 20}\${goto 40}\${color e19e19}\${cpugraph 14, \$minimum_width e19e19 ffffff}
\${goto 40}\${color}CPU\${font Bitstream Vera Sans:bold:size=8}\$alignr\$cpu%

\${voffset 15}\${goto 40}\${color}\${membar 14, \$minimum_width}
\${goto 40}\${color}RAM\${font Bitstream Vera Sans:bold:size=8}\$alignr \$mem / \$memmax   \$memperc%\$font

\${voffset 15}\${goto 40}\${color}\${downspeedgraph eno1 14, 115 55ff55 55ff55} \$alignr\${upspeedgraph eno1 14, 115 554455 ff55ff}
``````

Notice how with the CPU graph you can use the variable `\$minimum_width`. I would like to yield half of this amount to each of the `downspeedgraph` and `upspeedgraph` (along with the necessary offset to do spacing in between).

The division operator `/` has no effect when I tried it. Is there a way to apply mathematical operations to variables in conky to achieve the intended effect?

• I think you may be mistaken about `\$minimum_width`. You cannot use variables like this. Try replacing it with 0 and you should see the same display. The easiest way to configure conky as you wish is to use something like `awk` to do replacements in the config and create the `.conkyrc` before running conky. – meuh May 21 '18 at 12:32
• @meuh Could you please explain with an example? I'm entirely new to conky. – Ébe Isaac May 21 '18 at 12:50

Since conky is usually built to use `lua` there may be a cleaner solution involving that language, but here is a quick pre-processing script written in `perl`. It expects a simple configuration file, and extracts from the `conky.config={...}` part the variables being set. For example, `minimum_width = 230,` will create a perl variable of the same name and set it to that value.

Then it goes through the `conky.text=[[...]]` part and looks for expressions inside `@...@`. This assumes you do not use the `@` character for anything else. It then evaluates the perl expression you have put inside it. Perl also uses `\$` in front of simple variables, so you can use expressions like `@\$minimum_width/5@` and it will be replaced by 230/5 i.e. 46.

``````#!/usr/bin/perl
# https://unix.stackexchange.com/a/445140/119298
# parse conky 1.10 vars in conky.config and eval @expression@ in .text part
use strict;
use Safe;
my \$pack = new Safe();
sub replace{
my (\$a,\$body,\$c) = @_;
#    \$body =~ s/@(.*?)@/eval(\$1)/gse;
\$body =~ s/@(.+?)@/\$pack->reval(\$1)/gse; # evaluate @expression@ using vars
return \$a.\$body.\$c;
}
my \$config = join('',<>);
if(\$config =~ m/conky\.config\s*=\s*\{(.*?)\}/s){
my \$vars = "\$1,";
while(\$vars =~ m/\s*([a-z0-9_]+)\s*=\s*(.+?)\s*,/gs){
\${\$pack->varglob(\$1)} = \$2;
}
}
\$config =~ s/(conky\.text\s*=\s*\[\[)(.*?)(\]\])/replace(\$1,\$2,\$3)/se;
print \$config;
``````

Put this script in a file, say `conkyparse`, and make it executable with `chmod +x conkyparse`. Move your `~/.conkyrc` file to say, `preconky` and edit it as given above, then before running conky, run `conkyparse <preconky >~/.conkyrc` to have the expressions calculated and replaced.

Note, you could also invent and use your own variable names. To avoid a conky error, you need to hide their definition inside a comment (a line starting `--`). Here is an example `preconky` file:

``````conky.config = {
minimum_width = 230,
-- myvar = 22,
}
conky.text = [[
\${goto @3*\$myvar@} \${cpugraph 14,@\$minimum_width/2@ e19e19 ffffff}
]]
``````

and the resulting output file

``````conky.config = {
minimum_width = 230,
-- myvar = 22,
}
conky.text = [[
\${goto 66} \${cpugraph 14,115 e19e19 ffffff}
]]
``````