Nested Expressions
Lua can get pretty complicated, especially when you want to create strings using values based on other values. This usually also includes a lot of concatenation.
'On ' .. os.date('%A') .. ' Jane goes to ' .. Locations[os.date('%a')] .. '.' |
Using a little ingenuity this task could get a lot simpler.
'On {LongDay} Jane goes to {{ShortDay}Location}.' |
This is something called Nested Expressions. This could be an insurmountable task, but thankfully it's not. As long as we follow some rules we can use one of Lua's built in functions for this.
The most important rule we need to follow is that our expression must begin and end with different characters. For example, let's use the curly brackets (i.e. '{Expression}'
). If both characters were the same Lua wouldn't be able to tell the difference between the beginning and the end.
Now we need to define a function for our needs. Yes, we really do need a function for this. Since we need to follow the same steps for each nested expression we will need to call the function inside itself.
function nested(line) |
Now we need to start adding the bits that do all the work. What makes this all possible is the balanced expression matching capability of Lua. This would be the %b
pattern matching class. We use it by placing the beginning and ending characters after it. More detail can be found here.
function nested(line) |
Now that we have our expression we need to do something with it. The first thing is to call our function again so we can deal with the nested expressions first. We'll have to strip off the beginning and ending characters or we'll just create an infinite loop.
function nested(line) |
Now we need to start doing something with our expression. This requires some testing. The first thing is to make sure that what we have indeed received is a valid expression and act accordingly. If it's not a valid expression we need to return exactly what we received, including the beginning and ending characters.
You can do whatever you want to your expression, just be sure you return something. It is important to remember to use the newline
variable in whatever you do from this point on. This is the variable that has all of the nested expressions already evaluated.
function nested(line) |
There is one very important thing to note. Our function as written must be a global function. If you want it to be local there is a way to fix this. We must pass the function to itself. It's best not to think about this too hard.
local nested = function(line, self) |
Examples
Here's something extremely simple. We're just going to see what Jane is doing today.
Variables = { |
This one is much more complicated. It's used to replace nested Rainmeter measures and variables.
function Replace(input) |
Here's an example that uses a wrapper function so that we can specify a table of variables when we call the function.
function SomeFunction(InputExpression, FuncTbl) |