Skip to content

Using Lua scripts (Part 13): Useful functions and code

lasers edited this page Jan 5, 2019 · 3 revisions

xiii: Useful functions and code

in general i like to work out my own functions and write them myself, but sometimes its just easier to use existing functions that other people have made

here are some examples of function that i use regularly in scripts.

Split string function

function string:split(delimiter)
local result = { }
local from = 1
local delim_from, delim_to = string.find( self, delimiter, from )
while delim_from do
table.insert( result, string.sub( self, from , delim_from-1 ) )
from = delim_to + 1
delim_from, delim_to = string.find( self, delimiter, from )
end
table.insert( result, string.sub( self, from ) )
return result
end--of function

this function takes a string, and splits it up at a given delimiter then puts all the pieces into a table

you put this function into your lua script (either above the main function, or below (which will work due to the way conky and lua work together))

in the main function you use it like this

text_string="this is some text i want to split up into individual words"
split_table=string.split(text_string," ")

so text_string contains the stuff we want to split up split_table is the name of the table that we will be putting the pieces into string.split() is how we call the function

this looks a little bit different from how we have called function in the past, but the function itself is set up a little differently too but it works!

then inside the () we send the function the information it needs

first the string we want to split up (text_string, " ") then the delimiter which we want the function to split the string up at in this case i have set a single space (text_string, " ")

you can use anything you like to split the string up

so what you get is a tabel called split_table which looks like this

split_table={
"this",
"is",
"some",
"text",
"i",
"want",
"to",
"split",
"up",
"into",
"individual",
"words",
}

so we can access each entry in the table individually, for example

print (split_table[1]) --> "this"
print (split_table[6]) --> "want"

this has a great number of applications

Color conversion function

lua uses RGBA values to set colors like so cairo_set_source_rgba (cr,1,1,1,1)

each number in the () brackets is between 0 and 1 so in this case 1,1,1,1 will give me fully opaque white

BUT if you are more familiar with setting colors with hexidecimal values then you need to convert the hexidecimal values to RGBA values

you can do it using this function:

function color_convert(c,a)
return ( (c/0x10000) % 0x100)/255,( (c/0x100) % 0x100)/255,(c % 0x100)/255,a
end--local function

there are several variations of this function floating around as with all functions, put it in the script, outside of the main function either above or below just remember that it is only due to the way that conky and lua work together that you can have function below the main function if you ever write a standalone lua script (i do this as an alternative to bash scripts) then you HAVE to define your functions BEFORE they are used, ie ABOVE

there are a few different ways you can use this:

hex_color=0xffffff
alpha=1
red,green,blue,alpha=color_convert(hex_color,alpha)
cairo_set_source_rgba (cr,red,green,blue,alpha)

sometimes breaking code up into steps like above can be helpful

NOTE red,green,blue,alpha=color_convert(hex_color,alpha) lua has the ability to return multiple values from the same function in this case the colorconvert funtion is returning 4 values, so we need to set 4 strings to accept those values

when we do this we get the string set in the same order that they are returned: for example: you have in your function:

function number()
return 1,2,3,4
end

and you call it like this:

one,two,three,four=numbers()
print (one) --> 1
print (three) -->3

two,three,one,four=numbers()
print (one) --> 3
print (three) -->2

HOWEVER you could do the same thing in less lines like this cairo_set_source_rgba (cr,color_convert(0xffffff,1)) in this case the returned vales are being fed directly to the color setting function

Image display function

function image(im)--#################################################################
x=nil
x=(im.x or 0)
y=nil
y=(im.y or 0)
w=nil
w=(im.w or 0)
h=nil
h=(im.h or 0)
file=nil
file=tostring(im.file)
if file==nil then print("set image file") end
---------------------------------------------
local show = imlib_load_image(file)
if show == nil then return end
imlib_context_set_image(show)
if tonumber(w)==0 then
width=imlib_image_get_width()
else
width=tonumber(w)
end
if tonumber(h)==0 then
height=imlib_image_get_height()
else
height=tonumber(h)
end
imlib_context_set_image(show)
local scaled=imlib_create_cropped_scaled_image(0, 0, imlib_image_get_width(), imlib_image_get_height(), width, height)
imlib_free_image()
imlib_context_set_image(scaled)
imlib_render_image_on_drawable(x, y)
imlib_free_image()
show=nil
end--function image ##################################################################

you use it like this: image({x=100,y=100,h=50,w=50,file="/home/username/cute_puppy.png"})

when i was writing this function i wanted the input part to be as streamline as possible and i also wanted the ability to set default values so that you dont have to enter every setting, every time you wanted to display an image

to achieve this, you need to set and send a TABLE and this is what i am doing by using the curly brackets {} inside the curved brackets ()

this also means that you DONT have to enter the values in any particular oder either image({x=100,y=100,h=50,w=50,file="/home/username/cute_puppy.png"})

does the same things as: image({file="/home/username/cute_puppy.png",h=50,x=100,y=100,w=50})

NOTE the function contains these lines

function image(im)
x=nil
x=(im.x or 0)
y=nil
y=(im.y or 0)
w=nil
w=(im.w or 0)
h=nil
h=(im.h or 0)
file=nil
file=tostring(im.file)

so everything you send the function is received by the function and put as separate entries in a table called "im" if we sent the info as described above, if we were then to look in the table "im" we would see this:

im={
x=100,
y=100,
h=50,
w=50,
file="/home/username/cute_puppy.png"
}

so im is a dictionary type table and we can access dictionary type tables in a couple of ways in this case i am accessing the info using this method

table_name.entry_in_table

so to get the vale of x that we set in the main function when we called the function:

x_value=im.x
print (x_value) --> 100

also not that i am doing this:

x=nil
x=(im.x or 0)

setting x=nil is just a kind of maintenance line to catch and remove any other values of x that might be floating around in lua space

THEN (and this is a handy trick i picked up recently)x=(im.x or 0)

which does the following...

  • checks the table "im" for a value for x
  • if the table has an x value set in it then, set a string within the function called "x" that equals the value of x in table "im"
  • if there is NOT an entry for x in table "im", then im.x will return nil and if this is the case then x is set to equal 0

this is where the defaults can be used so when i call the function, say i want my image to be set to coordinates 0,0 (i have the same lines for y as for x in the function) then i wouldn't need to enter a value for x

image({h=50,w=50,file="/home/username/cute_puppy.png"})

i sey the table to the function, the table gets read, there is no values for x or y so the script sets x both to 0

Text output

i also wanted to streamline the output of text onto the conky display

function out(tx)--####################################################################
c=nil
c=(tx.c or 0xffffff)
a=nil
a=(tx.a or 1)
f=nil
f=(tx.f or "mono")
fs=nil
fs=(tx.fs or 12)
x=nil
x=(tx.x or 0)
y=nil
y=(tx.y or 0)
txt=nil
txt=(tx.txt or "set txt")
local function col(c,a)
return ( (c/0x10000) % 0x100)/255,( (c/0x100) % 0x100)/255,(c % 0x100)/255,a
end--local function
cairo_select_font_face (cr, f, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size (cr, fs)
cairo_set_source_rgba (cr,col(c,a))
cairo_move_to (cr,x,y)
cairo_show_text (cr,txt)
cairo_stroke (cr)
end--function out ###################################################################

called like this in the main function: out({x=10,y=10,c=0xffffff,a=1,f="mono",fs=12,txt="hello world"})

it works in a very similar way to the image function you only need to set those values that are different from the defaults

NOTE i am using the color conversion function (i called it "col" for brevity) that i described earlier in the out() function but i am using it as a local function a local function is only available to the function which contains it i put in the color conversion function as a local function in the out() function so that it would always be there and i wouldn't have to remember to put in 2 separate function every time i wanted to use out()

think of it like a dependency out() requires the ability to use the col() function i could put the col function as a separate function in the script and use it that way BUT if i were to forget to put the col function in then i would get errors so its built into the function that needs it!

ok thats it for this section

You can’t perform that action at this time.