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.