Lua: Small tagging system
Just came across another small trick while updating LibCargoShip-2.0 some time ago.
Small introduction:
Imagine you have a string with tags like “[name] wants to eat [food].”. Of course, you could replace both tags with “%s” and use a format instead, e.g.
cci lang=“lua”:format(“Cargor”, “a cookie”)[/cci]. While this method is recommended for most cases, there is also the possibility that your input string is “[food] is the thing [name] wants to eat.”. You notice: The arguments are swapped, so format wouldn’t work on these dynamic strings where you don’t know which tag comes where.
And now to the code!
local tagString1 = “[name] wants to eat [food]”
local tagString2 = “[food] is the thing [name] wants to eat.”
local function tagger(word)
if word == “name” then
return “Cargor”
else
return “a cookie”
end
local tagged1 = tagString1:gsub(”[(.-)]”, tagger)
— “Cargor wants to eat a cookie.”
local tagged2 = tagString2:gsub(”[(.-)]”, tagger)
— “a cookie is the thing Cargor wants to eat.”
The “gsub”-function (global substitute) finds all occurrences of a word in [] brackets and then calls the function “tagger” with the word as its argument. And this function then returns the replacement. Easy, isn’t it?
Of course, there are a lot ways to extend it:
You maybe want to store your words in a table and then just call different functions depending on them:
local tags = {
[“name”] = function() return UnitName(“player”) end,
[“food”] = function() return GetContainerItemLink(0, 1) end,
}
local function tagger(word) return tags[word] end
Or you refine the search pattern and take two or more arguments:
local function tagger(word, count)
local text = (word == “name” and “Cargor” or “cookies”)
if count then
text = count..” “..text
end
return text
end
local tagString = “[name] wants to eat [food:20]”
local tagged = tagString:gsub(”[(.):?(.)]”, tagger)
— “Cargor wants to eat 20 cookies.”