Lua Table Interop Notation

daurnimator edited this page Jan 6, 2013 · 9 revisions

This document describes the strict subset of Lua that works as a great data interchange format. The idea is similar to JSON from JavaScript, but based on Lua syntax and semantics. When saved to disk, the extension is ".ltin" and the mime type is "application/ltin". This is written as LTIN format (pronounced el-tin).


A table starts with { and ends with } It can contain 0 or more key-value or value entries.


{ key = "value", "another value" }

For values without keys, their key is an integer starting at 1 and counting up for each value without a key.

The order of the keys in a table is not defined and must not be depended on by any program consuming LTIN data.


A table key can be a plain unquoted name if it follows the lua name/identifier spec.

Names (also called identifiers) in Lua can be any string of letters, digits, and underscores, not beginning with a digit. This coincides with the definition of names in most languages. (The definition of letter depends on the current locale: any character considered alphabetic by the current locale can be used in an identifier.) Identifiers are used to name variables and table fields.

The following keywords are reserved and cannot be used as names:

  • and
  • break
  • do
  • else
  • elseif
  • end
  • for
  • function
  • goto
  • if
  • in
  • local
  • not
  • or
  • repeat
  • return
  • then
  • until
  • while

If the key is some other value, it must be wrapped in [ and ] and may then contain any valid LTIN value including another table.


Value can be any lua primitive including Table as described above.


A literal nil; symbolises the lack of a value.

Boolean literals:

  • true
  • false


A numerical constant can be written with an optional decimal part and an optional decimal exponent. Lua also accepts integer hexadecimal constants, by prefixing them with '0x'. Examples of valid numerical constants are

 3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56


Literal strings can be delimited by matching single or double quotes, and can contain the following C-like escape sequences: '\a' (bell), '\b' (backspace), '\f' (form feed), '\n' (newline), '\r' (carriage return), '\t' (horizontal tab), '\v' (vertical tab), '\' (backslash), '"' (quotation mark [double quote]), and ''' (apostrophe [single quote]). Moreover, a backslash followed by a real newline results in a newline in the string. A character in a string can also be specified by its numerical value using the escape sequence \ddd, where ddd is a sequence of up to three decimal digits. (Note that if a numerical escape is to be followed by a digit, it must be expressed using exactly three digits.) Strings in Lua can contain any 8-bit value, including embedded zeros, which can be specified as '\0'.

Multi-Line String

Literal strings can also be defined using a long format enclosed by long brackets. We define an opening long bracket of level n as an opening square bracket followed by n equal signs followed by another opening square bracket. So, an opening long bracket of level 0 is written as [[, an opening long bracket of level 1 is written as [=[, and so on. A closing long bracket is defined similarly; for instance, a closing long bracket of level 4 is written as ]====]. A long string starts with an opening long bracket of any level and ends at the first closing long bracket of the same level. Literals in this bracketed form can run for several lines, do not interpret any escape sequences, and ignore long brackets of any other level. They can contain anything except a closing bracket of the proper level.

For convenience, when the opening long bracket is immediately followed by a newline, the newline is not included in the string. As an example, in a system using ASCII (in which 'a' is coded as 97, newline is coded as 10, and '1' is coded as 49), the five literal strings below denote the same string:

 a = 'alo\n123"'
 a = "alo\n123\""
 a = '\97lo\10\04923"'
 a = [=[alo
 a = [==[


LTIN allows lua style single-line or multi-line comments. If a data format allows for arbitrary whitespace it should allow comments as well. Both are useful when humans write and/or consume the format.