Scripting
Data
There is a reciprocity between capturing data out of text, by matching
with a pattern, and inserting data into text by formatting with a
format-string. This script adds up numbers in a text.
#!lua
local numpat = "(%d+%.?%d+)"
local strfmt = "Total = %f"
local total = 0
for line in io.lines (arg[1]) do
for num in line:gmatch (numpat) do
total += tonumber (num)
end -- for
end -- for
print (strfmt:format (total))
A great deal of scripting comes down to understanding pattern-matching.
The reciprocal art of formatting is generally rather easier.
If you have a script with masses of invocations of string.format there is a convenient little trick that gets rid of them. Insert the line
(getmetatable "").__call = string.formatat the start and you will be able to apply string variables as functions, omitting string.format . Thus strfmt (total) instead of strfmt:format (total) . This is an example of changing the syntax of Lua by using metamethods.
A particularly convenient use of scripting is to handle information in
TSV files. These consist of lines which are records, the first
naming the fields, with each field a string, fields being separated by TAB characters. This script converts a TSV file to labelled record form.
#!lua
local pat = "(.-)\t"
local dbase, row = { }, { }
local header, item, k, N
for line in io.lines (arg[1]) do
if not nonheader then
for field in (line .. "\t"):gmatch (pat) do
row[1 + #row] = field
end -- for
nonheader, N = true, #row
else
item, k = { }, 1
for field in (line .. "\t"):gmatch (pat) do
if k <= N then
item[ row[k] ]= field
k + = 1
else break end -- if
end -- for
dbase[1 + #dbase] = item
end -- if
end -- for
-- dbase is a list of records, each record is a table labelled
-- by the fields of the header. Fields extending further than
-- the header are omitted.
local fmt " [%q] = %q;"
print "{"
for _, item in dbase do
print " {"
for label, field in pairs (dbase) do
print fmt:format (label, field)
print " };"
print "}"
We have lost control of the order of the labels. Note the formatting
character %q which prints strings doublequoted. Labelled records
are a more convenient format for Lua because they can be read straight
into Lua as lists of tables without further parsing.