-
- Notifications
You must be signed in to change notification settings - Fork 646
Using Lua scripts (Part 13): 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.
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 endThis 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 functions in the past: 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, the place at which we want to split the string. 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 table 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.
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 endThere 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 on 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 endAnd 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) -->2HOWEVER, you could do the same thing in fewer 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.
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 endYou 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 streamlined 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 order either, ie image ({x = 100, y = 100, h = 50, w = 50, file = "/home/username/cute_puppy.png"}) does the same thing 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 and 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) --> 100Also note 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.xwill returnniland if this is the case then x is set to 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.
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 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) endCalled 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. However, I am using it as a local function, a function that 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.
OK, thats it for this section.
- Home
- Installation
- Configurations
- Window Configuration
- Configs
- FAQ
- Lua
- Variables
- Compatibility
- Using Lua scripts
- How to Load and Use Lua Scripts
- Essentials of Drawing
- Drawing Lines
- Drawing Rectangles, Circles and Arcs
- Making A Bar Meter and A Circle Meter
- Borders and If Statements
- Alarm Colors and Complex If Statements
- Functions
- Function Parameters
- Table Parameters
- For Loops and CPU Chart
- Clock and Circular Things
- Useful Functions and Code
- CLI Commands Timers and Line Editing
- Mouse Events
- Rendering an SVG with librsvg and Cairo
- Contributing
- Issue Reporting