Saturday, March 22, 2014

Conky calendar with month, year, current day of week title, days of week past title, days yet to come title, current day, days past, days yet to come all individually colorable

Summary: Conky calendar with month, year, days already past week heading, current day of week heading, days yet to come week heading, days past, current day,   and days yet to come with each able to have and individual color.   Also month and year can be positioned to your liking using conky's align, voffset and offset commands.

I accidentally found out that conky reloads it's config file at midnight (perhaps at other times as well) so those of us that were using the execpi to make sure our calendars updated when the day changed can save a few electrons by going to execp as I have done below.

Known issues: This Conky calendar uses the cal command.  On my Debian system (now deceased, trying out Arch now) as well as my Ubuntu 13.10 system the cal command must be issued as cal -h.

So this line:
${execp TODAY=`date +%_d`; cal | tail -n+2 | sed \

Must be changed to:
${execp TODAY=`date +%_d`; cal -h | tail -n+2 | sed \

I believe this is because Debian's cal is actually a link to  BSD's ncal.

On my Arch system I found that using the infinality font packages caused conky to render fonts poorly (excessive vertical spacing and clipping part of characters at the bottom of the conky window)

I noticed that a font has to be defined in the conky config or the numbers of the month do not align correctly.  Be sure to use a monospaced font.

History: My Conky/sed script was inspired by the work of Seth Just.

Simple example of calendar:
Uniquely colorized elements

I think the conky code below is a good starting point to mess around with your preferred color scheme by changing the values of color1-color8.  Once you get that sorted you can stick it in your existing conky or build it out as its own conky as I did in the next example.

alignment top_right
color1 burlywood1 #Month color
color2 burlywood4 #Year  color
color3 darkgoldenrod4 #Weekdays lived color
color4 cornsilk #Current weekday color
color5 darkgoldenrod1 #Weekdays yet to come color
color6 darkorange3 #Days of month lived color
color7 firebrick2 #Current day color
color8 darkorange #Days yet to come color
double_buffer true
use_xft yes
xftfont Droid Sans Mono Slashed:size=12
own_window yes
own_window_argb_visual yes
own_window_hints undecorate,sticky,skip_taskbar,skip_pager,below
own_window_transparent yes

TEXT
##################
##   CALENDAR   ##
##################
${alignc}${color1}${time %B} ${color2}${time %Y}
${execp TODAY=`date +%_d`; cal | tail -n+2 | sed \
-e '1 s:.*:\${color3}&\${color6}:' \
-e '1 s:'"$(date +%a |cut -c 1-2)"':\${color4}&\${color5}:' \
-e '0,/'"$TODAY"'/{s/'"$TODAY"'/\${color7}'"$TODAY"'\${color8}/}'}
# 1st -e = days of week, 2nd = current day of week,
# 3rd = current day of month

My personalized calendar
I saved the code below in ~/.conky/conkyrc_cal and run it with:
conky -c ~/.conky/conkyrc_cal

PS.  The mouse and sticky keys indicators require xkbset to be installed, the clock requires the font LCDMono which is located here.

alignment top_right
color1 ffe3a0 #Month color
color2 ffe3a0 #Year  color
color3 7A3900 #Weekdays lived color
color4 ff8a00 #Current weekday color
color5 ffe3a0 #Weekdays yet to come color
color6 7A3900 #Days of month lived color
color7 ff8a00 #Current day color
color8 ffe3a0 #Days yet to come color
color9 ffe3a0 #Sentence color
# count of week and day count of year within sentence is set to color7
double_buffer true
use_xft yes
xftfont DejaVu Sans Mono:size=23
maximum_width 385 # This will have to be adjusted for font size
gap_x 20 
gap_y 15
own_window yes
own_window_argb_visual yes
own_window_hints undecorate,sticky,skip_taskbar,skip_pager,below
own_window_transparent yes

TEXT
##################
##     TIME     ##
##################
${font LCD2:bold:size=75}${alignr 8}${color7}${time %k}${voffset -20}:${voffset 20}${time %M}${font}
######################
# Capslock + Numlock #
######################
${color1}${voffset -89}${if_match "${exec xset q | grep LED | awk '{ print $10 }' | cut -c8}" == "0"}a ↑${else}${if_match "${exec xset q | grep LED | awk '{ print $10 }' | cut -c8}" == "1"}${color7}${blink A}${color1} ↑${else}${if_match "${exec xset q | grep LED | awk '{ print $10 }' | cut -c8}" == "2"}a ${color7}1${else}${if_match "${exec xset q | grep LED | awk '{ print $10 }' | cut -c8}" == "3"}${color7}${blink A} 1${endif}${endif}${endif}${endif}
########################
# Mouse-Keys indicator #
########################
${font :size=12}${voffset -20}${color3}${if_match "${exec xkbset q | grep "Mouse-Keys =" | awk '{print $3}'}" == "Off"}mouse keys${else}${color1}Mouse Keys${endif}
#########################
# Sticky-Keys indicator #
#########################
${color3}${if_match "${exec xkbset q | grep "Sticky-Keys =" | awk '{print $3}'}" == "Off"}sticky keys${else}${color1}Sticky Keys${endif}
###########################
# Latch to Lock indicator #
###########################
${color3}${if_match "${exec xkbset q | grep "Latch to Lock Mask =" | awk '{print $6}'}" == "Off"}mod keys free${else}${color1}Mod Keys Locked${endif}
${color ffe3a0}${hr 2}
##################
##   CALENDAR   ##
##################
${font}${voffset -8}${color1}${time %B}${voffset -5}${font :size=45}${alignr}${color2}${time %Y}
${voffset -71}${font :size=12}${alignr}${color9}week ${color7}${time %U}${color9} and day ${color7}${time %j}${color9} of:                               ${font}
${voffset -10}${execp TODAY=`date +%_d`; cal | tail -n+2 | sed \
-e '1 s:.*:\${color3}&\${color6}:' \
-e '1 s:'"$(date +%a |cut -c 1-2)"':\${color4}&\${color5}:' \
-e '0,/'"$TODAY"'/{s/'"$TODAY"'/\${color7}'"$TODAY"'\${color8}/}'}
# 1st -e = days of week, 2nd = current day of week,
# 3rd = current day of month

Thursday, January 30, 2014

My Conky Calendar with month, year, days of week, current day of week, and day of month all color configurable

[Edit - Really this is the last one. I'M NOT JOKING]
The previous fix listed below seems to work fine but I did a bit more research and changed things so that it looks cleaner to me and I understand the sed more clearly:

alignment top_right
color1 white #Month color
color2 white #Year  color
color3 white #Weekdays color
color4 FFE3A0 #Current weekday color
color5 white  #Days of month color
color6 ff8a00 #Current day color
double_buffer true
use_xft yes
xftfont DejaVu Sans Mono:size=23
maximum_width 385 # This will have to be adjusted for font size
gap_x 20 
gap_y 15
own_window yes
own_window_argb_visual yes
own_window_hints undecorate,sticky,skip_taskbar,skip_pager,below
own_window_transparent yes


TEXT
##################
##     TIME    ##
##################
${font LCD2:bold:size=75}${alignr 8}${color6}${time %k}${voffset -20}:${voffset 20}${time %M}${font}
${color4}${hr 2}${color1}
##################
##   CALENDAR   ##
##################
${alignc}${color1}${time %B} ${color2}${time %Y}
${execpi 60 TODAY=`date +%_d`; cal -h | tail -n+2 | sed \
-e '1 s:.*:\${color3}&\${color5}:' \
-e '1 s:'"$(date +%a |cut -c 1-2)"':\${color4}&\${color3}:' \
-e '0,/'"$TODAY"'/{s/'"$TODAY"'/\${color6}'"$TODAY"'\${color5}/}'}
# 1st -e = days of week, 2nd = current day of week,
# 3rd = current day of month

 

[Edit - Fix]
Had to redo the whole thing :( Now the critical sed line is the one that Seth Just used (linked to below).  Also at the end of this post I mentioned that month name and year could not be realigned or moved.  Now they can be moved around. Here is the new script:

alignment top_right
color1 white #Month color
color2 white #Year  color
color3 white #Weekdays color
color4 FFE3A0 #Current weekday color
color5 white  #Days of month color
color6 ff8a00 #Current day color
double_buffer true
use_xft yes
xftfont DejaVu Sans Mono:size=23
maximum_width 385 # This will have to be adjusted for font size
gap_x 20
gap_y 15
own_window yes
own_window_argb_visual yes
own_window_hints undecorate,sticky,skip_taskbar,skip_pager,below
own_window_transparent yes
 

TEXT
##################
##     TIME    ##
##################
${font LCD2:bold:size=75}${alignr 8}${color6}${time %k}${voffset -20}:${voffset 20}${time %M}${font}
${color4}${hr 2}${color1}
##################
##   CALENDAR   ##
##################
${alignc}${color1}${time %B} ${color2}${time %Y}
${execpi 60 echo '${color3}Su Mo Tu We Th Fr Sa${color5}' | sed  's:'"$(date +%a |cut -c 1-2)"':\${color4}&\${color3}:'}
${execpi 60 DJS=`date +%_d`; cal -h | tail -n+3 |sed s:"\(^\|[^0-9]\)$DJS"'\b':'\1${color6}'"$DJS"'${color5}':}


Pretty much everything I wrote below regarding the sed statements is no longer valid.  Oddly, I was able to fix my original sed when run in a terminal.  Also I was able to put the new sed in a format I kind of understood when run from a terminal.  But from within conky it just didn't work.

The new script produces:

When/if I ever make cron run this script so I can change those execpi 60 commands into execp commands I'll probably make a new post.  But until then it's lights out.


[Edit] Oops, it's the 1st and a huge error showed up that I don't understand, the error is in this sed expression:
 -e '3,8 s:'"$(date +%_d)"':\${color6}&\${color5}:'

On the 1st my calendar looks like:

The Seth Just script (linked below) solved this problem but I can't seem to "port" the solution to my script.  I'll take another shot at it tomorrow.  I'm pretty tired now.  I do not understand Seth's sed so that'll be job #1.  I don't actually think anybody has read this post but if any have I apologize.

Have no idea why 10 and 17 got tagged but none of the other days that start with 1?!?!

Now back to the original post:

My Conky calendar is not colorful at all and I've made it pretty big, it almost takes up the whole right corner of my second monitor:

My Conky calendar + clock, rather bland colors




In the screen shot above you can see that Th and 30 are shown in different colors.  In fact my script allows for the month, year, weekdays, current day of week (Thursday in this case), and current day of the month (the 30th here) all to have their own colors.

My Conky/sed script was inspired by the work of Seth Just.

My calendar is setup as a stand alone Conky intended to be started like:
conky -c /path/to/conkyrc_cal

Here is the listing of my conkyrc_cal file:

alignment top_right
color1 white #Month color
color2 white #Year  color
color3 white #Weekdays color
color4 FFE3A0 #Current weekday color
color5 white  #Days of month color
color6 ff8a00 #Current day color
double_buffer true
use_xft yes
xftfont DejaVu Sans Mono:size=23
maximum_width 385 # This will have to be adjusted for font size
gap_x 20 
gap_y 15
own_window yes
own_window_argb_visual yes
own_window_hints undecorate,sticky,skip_taskbar,skip_pager,below
own_window_transparent yes


TEXT
##################
##     TIME     ##
##################
${font LCD2:bold:size=75}${alignr 8}${color6}${time %k}${voffset -20}:${voffset 20}${time %M}${font}
${color4}${hr 2}${color1}
##################
##   CALENDAR   ##
##################
${execpi 60 cal -h | sed \
-e '1 s:[A-Z][a-z]*:\${color1}&:' \
-e '1 s:[0-9][0-9][0-9][0-9]:\${color2}&:' \
-e '2 s:.*:\${color3}&\${color5}:' \
-e '2 s:'"$(date +%a |cut -c 1-2)"':\${color4}&\${color3}:' \
-e '3,8 s:'"$(date +%_d)"':\${color6}&\${color5}:'}
# 1st -e = Month, 2nd = year, 3rd = days of week,

# 4th = current day of week, 5th = Current day of month 

A basic explanation of how the calendar is created by conky:

This line begins the calendar script
${execpi 60 cal -h | sed \

excepi 60 runs the script every 60 seconds (I don't like this, eventually I think I'll make a cron job to restart the script a midnight).

cal -h | sed \ runs the terminal program cal without highlighting the current day of the month and then pipes it out to sed (Debian requires cal -h but some systems only require cal, if you've got such a system replace cal -h with cal).  The backslash after sed just tells sed that there are more commands to follow.  All of those lines starting with -e are actually just one line as far as sed is concerned.  I used the \ for readability.

-e '1 s:[A-Z][a-z]*:\${color1}&:' \


If you run cal -h in a terminal you'll see that the first line is composed of the month name followed by the year.  The -e expression above matches the month name.

All of my -e expressions begin with a number as highlighted above.  What that number(s) means is that the following command will only operate on that line of input as produced by cal -h (or range of lines as in the last -e that has 3,8).

Notice the highlighted \ before the blue highlighted ${color1} conky command.  The $ has special significance within sed but placing a \ before the $ escapes the $ so that sed sees it as just a character.  So with \$ sed sees $ as just a character like any other but with just a $ sed sees the $ as a sed command and does something you don't want. You must \$ your conky commands within the sed expression.

The red highlighted & is what sed found in it's search (the search being [A-Z][a-z]*) which in this case is the name of the month.  All your conky command changes in the calendar script will come immediately before and/or after the &.

Ok, lets play around a little. Open this window for a listing of Conky window configuration settings.  These are things that setup the Conky window but they don't put anything inside the window.  All these command are placed above the TEXT command.  Open this window for a listing of Conky display objects.  Conky objects are what actually show up in your Conky window.

You're going to have to install LCDMono font which is located here. I think dafont.com has lots of cool fonts.  Unpack the downloaded file (my system uses xarchiver) then install the fonts, some systems just let you click on the font files but I use a program called fontmatrix. DejaVu fonts were either installed by default or I got them from the debian repos so I don't think you'll have to worry about those.

Go to your home directory and create a Conky directory for your script(s).

cd
mkdir .conky

Now you're going to open up/create your Conky calendar script using your preferred editor (I'm going to use Geany).

geany .conky/conkyrc_cal &

Now copy and past the the conkyrc_cal into your editor and save the file.

Go back to your terminal and run your calendar Conky:

conky -c .conky/conkyrc_cal

The Conky should show up in the upper right corner of your monitor so move any windows that are covering that area (I'm running a dual monitor system under Nvidia's twinview so it shows up on the right top of my right monitor).

It's probably best if only the Conky, your terminal, and your editor are visible on the desktop at this point.

First of lets change the clocks colon back to it's normal position.

Change this line:

${font LCD2:bold:size=75}${alignr 8}${color6}${time %k}${voffset -20}:${voffset 20}${time %M}${font}

To read:

${font LCD2:bold:size=75}${alignr 8}${color6}${time %k:%M}${font}

And save the file.  Conky will automatically reload the file.  Notice how on the original line the colon was vertically positioned midway between the hours and minutes but the new version puts the colon at the bottom.  That's how LCDMono font defines it but I found it irritating.

Notice on the original line that ${voffset 20} is placed after the : and everything before that command will be raised twenty pixels hence why I put the other ${voffset -20} command before the : .

Or how about replacing the line with this:

 ${font LCD2:bold:size=75}${alignr 8}${color6}${time %k}${voffset -20}:${font LCD2:bold:size=50}${time %M}${voffset 20}${font}

To learn the codes for the $time command just run man strftime.

All you have to do to change the colors of this Conky is to alter the values that define the colors in the configuration part of the script:

color1 white #Month color
color2 white #Year  color
color3 white #Weekdays color
color4 FFE3A0 #Current weekday color
color5 white  #Days of month color
color6 ff8a00 #Current day color


It should just work.

When changing the font size of the calendar you will have to adjust the following line in the configuration area of the script:

maximum_width 385 # This will have to be adjusted for font size

This is a trial and error process.  With the above line commented out the line seperating the clock from the calendar is longer and the calendar aligns to far right:

I've run into a limitation.  The month and year do not respond to ${align[rc]} nor sed expressions that remove white space.  In the terminal I can alter the white space with sed but in Conky it doesn't work.