LuaFy – a free Lua scripting plug-in for FileMaker Pro®

Lua Libraries Provided by LuaFy

Lua LibraryDescription
ascii85 LuaFy Plus Encode and decode to Ascii85/Base85.
base64 LuaFy Plus Encode and decode to Base64.
bit Do bitwise operations on numbers.
coroutine Create and manage coroutines for cooperative multitasking.
debug Debug and profile Lua code.
io I/O library to read and write to files.
lfs LuaFileSystem library to access and manipulate directories and files.
LPEG Pattern matching library for lua based on Parsing Expression Grammars (PEGs).
luafy Interact with FileMaker Pro® via Lua functions and other utilities.
LuaSocket LuaFy Plus Low-level and high-level TCP/IP networking with modules for HTTP and FTP
math Do many mathematical functions.
os Interact with the operating system.
pack LuaFy Plus Pack and unpack data into or from a binary string.
package Provides functions for working with Lua modules/libraries.
string Provides functions for manipulating strings.
table Provides functions for manipulating Lua tables.
 
Download and Feature List
Purchase a License to LuaFy Plus
Functions Provided by LuaFy
Lua Libraries Provided by LuaFy
Lua Integration with FileMaker
Usage Examples
What is Lua?
Origin Story
Version History & Old Versions

This list is what is provided in the current release. More Lua libraries are in the development pipeline for LuaFy Plus.


ascii85 LuaFy Plus

Encode and decode to Ascii85/Base85.

asci85.encode( string )
Encode the (possibly binary) string to the Ascii85 encoding standard using the ascii85 Lua library. The encoded value is returned by this function.
asci85.decode( string )
Decode the ascii85-encoded string back to the original string.

base64 LuaFy Plus

Encode and decode to Base64.

base64.encode( string )
Encode the (possibly binary) string to the Base64 encoding standard using the base64 Lua library. The encoded value is returned by this function.
base64.decode( string )
Decode the base64-encoded string back to the original string.

bit

BitOp library to do bitwise operations on numbers.

bit.tobit()
bit.tohex()
bit.bnot()
bit.band()
bit.bor()
bit.bxor()
bit.lshift()
bit.rshift()
bit.rol()
bit.ror()
bit.bswap()

These functions are all provided by the BitOp library. The module is pre-loaded in LuaFy. The functions in this module are all described on the BitOp API functions page.

Note that these bit operations only work on 32 bit numbers. If you try to pass a number with more than 32 bits, only the lower 32 bits are passed into the function.

coroutine

Create and manage coroutines for cooperative multitasking.

coroutine.yield( ... )

Suspends execution of the current Lua code and returns control to the calling routine. Any arguments you provide are available to the calling routine's resume() function. If you use coroutine.yield() inside a function invoked by LuaFy_CallFunction(), the Lua script will pause, and the first argument you provide to coroutine.yield() will be the value returned by LuaFy_CallFunction().

Resume execution of your Lua code at the point it yielded by using LuaFy_ResumeFunction(). The arguments you provide to LuaFy_ResumeFunction() will be the values returned by coroutine.yield() in your Lua code when it resumes.

coroutine.create()
coroutine.resume()
coroutine.running()
coroutine.status()
coroutine.wrap()

These functions are part of the standard Lua coroutine library. Detailed info can be found in the Lua 5.1 Reference Manual.

debug

This Lua library provides functions useful for debugging and profiling Lua code.

debug.debug()
debug.getfenv()
debug.gethook()
debug.getinfo()
debug.getlocal()
debug.getmetatable()
debug.getregistry()
debug.getupvalue()
debug.setfenv()
debug.sethook()
debug.setlocal()
debug.setmetatable()
debug.setupvalue()
debug.traceback()

These functions are part of the standard Lua debug library. Detailed info can be found in the Lua 5.1 Reference Manual.

io

This standard Lua input/output library provides functions primarly for reading and writing to files.

io.close()
io.flush()
io.input()
io.lines()
io.open()
io.output()
io.popen()
io.read()
io.tmpfile()
io.type()
io.write()
file:seek
file:setbuf

These functions are part of the standard Lua io library. Detailed info can be found in the Lua 5.1 Reference Manual.

lfs

The LuaFileSystem library provides functions to access and manipulate directories and files. This third-party libary compliments the functionality in the standard io and os libaries.

lfs.attributes()
lfs.chdir()
lfs.lock_dir()
lfs.currentdir()
lfs.dir()
lfs.lock()
lfs.mkdir()
lfs.rmdir()
lfs.setmode()
lfs.symlinkattributes()
lfs.touch()
lfs.unlock

Detailed info can be found in the LuaFileSystem Reference Manual. Note that the syntax of some of these functions is non-obvious. Studying the documentation and examples carefully is recommended.

LPEG

LPEG is a Lua pattern matching library for lua based on Parsing Expression Grammars (PEGs). Detailed info can be found at the home page for LPEG.

LuaFy library

LuaFy comes with a special "luafy" library to make it easier to do useful things with FileMaker. Some of the features of this library are exclusive to LuaFy Plus.

luafy.damlevlim(string1, string2, limit) LuaFy Plus

This Lua function calculates the Damerau-Levenshtein distance or "Edit Distance" between two strings. This counts the number of simple edits needed to go from the first string to the second. The function stops counting after it reaches "limit" edits. Keep the value of limit small to make the function run faster. Internally the value of limit is capped at 255 so any value of limit higher than 255 will be silently treated as if you used 255.

Internally this uses simple C-strings (one byte per character) to store and compare the characters in text1 and text2. LuaFy sends UTF-8 strings to this function. If your input strings contain content not representable in ASCII and thus use more than one byte per character, luafy.damlevlim() will give a higher than normal answer for the count of edits to transform one string to the other.

A more significant problem with handling non-ASCII input is that the same codepoint coded in more than one way in UTF-8. luafy.damlevlim() does not normalize the string and thus will treat the differently the two UTF-8 entries (UTF-8 code for an accented letter e) and (UTF-8 code for the action to combine the accent symbol with the letter e symbol).

Since LuaFy uses a FileMaker API function to do the conversion of FileMaker-provided text to UTF-8, it is possible that normalization is done by FileMaker and this codepoint encoding issue will never come up. Without specific tests on each applicable version of FileMaker to discover the internal behavior it is recommended that you don not trust this function fully with non-ASCII input.

luafy.Evaluate(expression)

This provides the FileMaker Evaluate() function within Lua. The Lua string expression is run through FileMaker's calculation engine. It returns a text string as the result calculated by FileMaker.

luafy.ExecuteSQL(expression)

This provides an SQL interface to FileMaker where expression is a Lua string containing the SQL statement you want evaluated. luafy.ExecuteSQL() returns Lua two-dimensional Lua table containing the rows and columns of the query results. The rows are array entries in the table. Each column is automatically keyed with "f1", "f2", "f3", and so on for the total number of columns.

This uses the older ExecuteSQL() API function not the newer ExecuteFileSQL() introduced with FileMaker 11.

Example: SQLResult = luafy.ExecuteSQL("SELECT FirstName, LastName from Contacts")
Result: SQLResult[4].f2 is assigned the value of the 4th LastName.

While the SQL statement can be anything that FileMaker's internal SQL engine will accept, it is recommended that you only use SELECT statements.

luafy.fnv32a(string) LuaFy Plus

This Lua function calculates a 32-bit hash value of the input string. The result is an integer. The algorithm is FNV-1a.

Like luafy.damlevlim() this uses C-strings internally. This function also does not normalize the UTF-8 strings and thus will be subject to the problem of treating not recognizing the same codepoint if it is encoded differently. Thus hashes of the same text are not guaranteed to be generate the same 32-bit value if they contain non-ASCII characters.

luafy.get(path_keyword)

where path_keyword is one of the following: "DesktopPath", "DocumentsPath", "FileMakerPath", or "TemporaryPath". This generates the same result as the corresponding FileMaker Get() calculations using the same keywords except that the result is adjusted to be a path immediately usable by Lua file or directory functions.

LuaFy adds an additional keyword, "DirOfFilePath" which is based on FileMaker's Get(FilePath). When Get(FilePath) starts with "file:", luafy.get("DirOfFilePath") returns the directory of the current locally hosted FileMaker file in a format immediately usable by Lua. If the current FileMaker file is hosted remotely or if there is no active FileMaker file (e.g. running the Data Viewer in FileMaker Pro Advanced with no open file), luafy.get("DirOfFilePath") returns nil.

Example: theFile = luafy.get('DocumentsPath') .. 'myFileName.txt'
Result: (Mac) theFile is "/Volumes/Macintosh HD/Users/jexample/Documents/myFileName.txt"
Result: (Win) theFile is "C:/Documents and Settings/Joe Example/My Documents/myFileName.txt"

luafy.md5(string) LuaFy Plus

This Lua function calculates the standard MD5 function of the input string. The result is a 32-character string representing the MD5 hash in hexadecimal.

luafy.platform

This Lua variable is predefined by LuaFy to be "Win" or "Mac" depending on which version of the plug-in is installed. This can be useful if you are adapting your Lua script to be cross-platform and want to gracefully handle platform-specific situations.

luafy.timestamp

This is a new Lua "userdata" data type to let you pass FileMaker Timestamp values (and Date and Time values) into and out of Lua. Any FileMaker Timestamp, Date, or Time value passed into Lua is automatically converted into a luafy.timestamp. If you "return" a luafy.timestamp value to FileMaker, it will be sent back as a FileMaker Timestamp value.

This new datatype comes with some built-in functions.

luafy.timestamp.new([seconds])

Creates a new luafy.timestamp value. If you provide a value for seconds, the timestamp will be assigned to be that number of seconds since the "epoch". This follows the same epoch convention as os.time(). The most common use is to create a value using os.time() and assign that to luafy.timestamp.

luafy.timestamp.value()

Gets the luafy.timestamp value in seconds since the epoch. For a luafy.timestamp value named lfs, you can invoke this as lfs:value().

luafy.timestamp.set(Timestamp, seconds)

Assigns the timestamp value to the number of seconds since the epoch. For a luafy.timestamp variable named lfs, you can invoke this as lfs:set(seconds).

luafy.tolist(table, separator)

This is designed to be the inverse function of luafy.totable(). This function returns a multi-line block of text with each table entry on a separate line (using \r as the line ending since it is preferred by FileMaker). If you provide a separator the key will precede the table's value with the separator in between.

Example: theTable[1]="apple"; theTable[2]="peach"; theTable[3]="orange"
theString = luafy.tolist(theTable)
Result: theString is "apple¶peach¶orange"

Example: theTable["Tom"]="apple"; theTable["Sara"]="peach"; theTable["Jane"]="orange"
theString = luafy.tolist(theTable, "|")
Result: theString is "Tom|apple¶Sara|peach¶Jane|orange"

luafy.totable(text, separator)

This Lua function converts multiple lines of text into separate entries in a Lua table and returns the table it constructs.

If you provide a value for the separator argument, each line is split at first instance of the separator. The left side is used as the associative key for the table entry. The separator can be a multi-character sequence.

Example: theTable = luafy.totable("apple¶peach¶orange")
Result: theTable[1] is "apple", theTable[2] is "peach", theTable[3] = "orange"

Example: theTable = luafy.totable("Tom|apple¶Sara|peach¶Jane|orange", "|")
Result: theTable["Tom"] is "apple", theTable["Sara"] is "peach", theTable["Jane"] = "orange"

luafy.ScriptTime( keyword )

This function returns a value related to the internal timer that LuaFy uses to track how long a script has run since FileMaker gave control to it. If keyword is missing or if keyword is "elapsed", luafy.ScriptTime() will return how many seconds the script has been running. If keyword is "remaining" it will return the number of seconds remaining before the script will halt due to reaching the timeout value set by LuaFy_Timeout(). If keyword is "timeout" luafy.ScriptTime() will return the number of seconds to which the timeout is currently set.

In LuaFy Plus luafy.ScriptTime() can be very useful if you are trying to determine where and when to use coroutine.yield() in your scripts. You can adapt your code to yield more freqently on slower machines. You can ensure that coroutine.yield() happens well before a timeout would occur.

luafy.shellexec(cmd)

Run a command in the Mac OS X or DOS shell. The results of the shell command are returned by this function.

Note that this function is different from os.execute() which returns only the status code. luafy.shellexec() uses io.popen() and io.read() so if you have disabled those functions, luafy.shellexec() will be disabled too.

If cmd is not recognized by the shell, this function will not generate an error. The only way to tell if this function fails is to examine its results (empty for shell error). If your cmd generates no result as standard behavior, you can use io.execute() instead and check the status code it returns to determine success.

Example: theResult = luafy.shellexec('ls') -- Mac OS X
Example: theResult = luafy.shellexec('dir') -- Windows

Be careful with this command. It is possible to issue a shell command that takes an arbitrarily long time to execute or that never returns. LuaFy cannot enforce its timeout on a shell command. You can lock up FileMaker with this command.

luafy.version

This Lua value returns the version info of the luafy library.

LuaSocket

socket
socket.ftp
socket.http
socket.smtp
socket.tp
socket.url

The LuaSocket library provides the tables of functions listed above. Each table has many functions which are fully described in the LuaSocket documentation.

All LuaSocket modules are already "include"-ed for you in LuaFy Plus.

os

This standard Lua library provides functions that interact with the operating system.

os.clock()
os.date()
os.difftime()
os.execute()
os.getenv()
os.remove()
os.rename()
os.setlocale()
os.time()
os.tmpname()

These functions are part of the standard Lua os library. Detailed info can be found in the Lua 5.1 Reference Manual.

Note that standard io library function os.exit() is specifically disabled because it would cause FileMaker Pro to terminate abnormally.

math

This library provides a useful collection of math functions some of which are not present in. FileMaker"Pro lacks many of these.

math.abs()
math.acos()
math.asin()
math.atan()
math.atan2()
math.ceil()
math.cos()
math.cosh()
math.deg()
math.exp()
math.floor()
math.fmod()
math.frexp()
math.huge
math.ldexp()
math.log()
math.log10()
math.max()
math.min()
math.modf()
math.pi
math.pow()
math.rad()
math.random()
math.randomseed()
math.sin()
math.sinh()
math.sqrt()
math.tan()
math.tanh()

These functions are part of the standard Lua math library. Detailed info can be found in the Lua 5.1 Reference Manual.

pack LuaFy Plus

This library adds two new functions to the string library to pack data into or unpack data from a binary string. These functions are useful if you need to read or write data to/from a specific binary format.

string.pack( format, ... )

Return a string containing all of the functions arguments packed together as a sequence of bytes described by format.

string.unpack( binaryString, format, [initialBytePosition] )

Returns a list of values unpacked from binaryString. format describes how to interpret the values in the binaryString. The optional initialBytePosition designates where in binaryString to begin unpacking. The default value of initialBytePosition is 1, designating the first byte.

format is composed of a combination of the following codes.

CodeMeaning
zzero-terminated string (C-string)
pstring preceeded by a single byte designating its length
Pstring preceeded by two bytes designating its length
astring preceeded by four bytes designating its length
Astring
ffloat
ddouble
nLua number
cchar
bunsigned char
hshort
iint
Iunsigned int
<little endian
>big endian
=native endian

The code for endianness immediately precedes the codes for the number type.

package

This standard Lua library provides functions and predefined tables for working with Lua modules/libraries. Note that two of its functions are global functions: module() and require().

module()
require()
package.cpath
package.loaded
package.loaders
package.loadlib()
package.path
package.preload
package.seeall()

Detailed information on these standard Lua functions and tables can be found in the Lua 5.1 Reference Manual.

string

This standard Lua library provides functions for manipulating Lua strings. Note that the finding and pattern matching is case-sensitive.

string.byte()
string.char()
string.dump()
string.find()
string.format()
string.gmatch()
string.gsub()
string.len()
string.match()
string.rep()
string.reverse()
string.sub()
string.upper()

Detailed information on these standard Lua functions and the syntax for pattern matching can be found in the Lua 5.1 Reference Manual.

string.isvalidutf8(str)

Examines all of str and returns true if the string conforms to the UTF8 encoding specification. It returns false when it doesn't. This does not check to see if all of the characters correspond to legitimate unicode codep points.

string.is7bitascii(str)

Returns true when str consists only of 7-bit ASCII characters and false otherwise. This function is useful to determine if you can use Lua's standard string operations on a UTF8 string since 7-bit ASCII strings have only one byte per character.

string.nextutf8(str, pos)

Examines the string starting at the byte position pos and locates a valid UTF8 character. It returns two values, nextpos and char, where nextpos is the position after the character it found and char is the UTF8 character it found. If pos is higher than the string length, nextpos is nil. If no valid UTF8 character is found at pos it gives an error.

string.utf8len(str)

Returns the length in UTF8 characters of str. The standard string.len() counts the number of bytes in the string. Since a UTF8 character can be from 1 to 4 bytes, string.utf8len() is always less than or equal to string.len(). If str is not a valid UTF8 string, it gives an error.

string.seekutf8(str, pos, shift)

Starting at the byte index position pos in str, return the byte postion shift characters to the left (negative shift) or right (positive shift). If shift is zero, it returns pos.

string.utf8code(UTF8char)

This function returns a numeric value for the UTF8 character presented. The string UTF8char must represent a single character in UTF8. Two or more characters will generate an "invalid" error.

string.utf8char(number)

This function returns a string containing the single UTF8 character corresponding to the number provided. This is the inverse function for string.utf8code().

string.utf8sub(s, i [,j])

This works just like string.sub() except that s must be a valid sequence of UTF8 characters and i and j designate positions of UTF8 characters instead of single-byte characters. Note that using string.sub() on strings of UTF8 characters can generate substrings that are not valid UTF8. string.utf8sub() will always generate valid UTF8 substrings.

string.utf8characters(str)

This provides an iterator for the letters of a UTF8 string. This is useful for processing all of the characters of the UTF8 string in order in a for loop.

for char in string.utf8characters(str) do something end

table

This standard Lua library provides functions for manipulating Lua tables.

table.concat()
table.insert()
table.maxn()
table.remove()
table.sort()

Detailed information on these standard Lua functions can be found in the Lua 5.1 Reference Manual.


LuaFy is a product of Cosmic Consulting
Tom Hays <trhays@luafy.com>