Basic information

This page explains the basic concepts of the Marta API. Some of the ideas may seem trivial to you, especially if you have experience with different programming languages. However, reading the page will surely help you to dive into Marta plugin development.

Lua distribution

Marta bundles Lua 5.3.5 from lua.org with a few customizations:

  • NSLog is used instead of cout/cerr for print and error functions. This allows to see the output in the Console application.
  • Custom search paths are set so the plugin will not accidentally touch system-global Lua libraries. You are free to redefine paths to whatever you want.
    • For single-file plugins package.path and package.cpath are empty.
    • For complex plugins package.path is DIR/?.lua;DIR/?/init.lua, package.cpath is DIR/?.so, where DIR is a plugin directory path.

Include search path: /Applications/Marta.app/Contents/Headers.
Library search path: /Applications/Marta.app/Contents/Frameworks.
Run Clang with the -llua option to compile against Lua library.

Declaration kinds

Marta API introduces several kinds of declarations. If you know some OOP language such as Java or Kotlin, this will be familiar to you.

  • Modules contain all API declarations, including classes and top-level functions and values. In Lua, Marta API modules are visible as global variables. Currently, there are two modules: marta and martax.
  • Classes hold state and provide ways to access and/or modify it. Classes can contain other classes, methods, and properties.
  • Properties are like variables. They contain some value and allow to get and, sometimes, modify it. Immutable properties are called values.
  • Functions are just functions, as in Lua. Functions enclosed in a class are called methods.

All methods are called with a colon syntax: obj:method(). In Marta API there are no static methods.

Instantiable classes

If a class is declared as “instantiable”, you can create an instance of it in Lua and pass it to the API method.

The most obvious example is the action declaration. Normally, you define an action using the action() function that accepts a single argument of a ActionDeclaration type. Because the ActionDeclaration class is instantiable, we can create a table and pass it:

action({
    id = "id",
    name = "Name",
    apply = function(context) end
})

Lua allows to omit parentheses if the only argument type is a string literal, or a table constructor:

action {
    id = "id",
    name = "Name",
    apply = function(context) end
}

Type kinds

Marta API is strong-typed. If you pass a number value for a string-typed parameter, an error will occur. In some places, however, Marta API accepts values of several types.

Here are the type kinds used in the API reference:

  • Simple type: a class name with optional type arguments. Examples: Int, Array<String>. A simple type does not accept nil values.
  • Nullable type: any type with a question mark at the end. Examples: Int?, Array<String>? (nullable array of not-null items), Array<String?> (not-null array of nullable items).
  • Union type: a cortege or possible types, e.g. [String | Int] (accepts a string or an integer), [String | Array<String>] (accepts a string or a string array). Union type can be empty ([]) – in some languages it is called a ‘void’ or a ‘unit’ type.
  • Function type: accepts functions with the specified argument and return value types. E.g., (String, Int) -> String denotes a function that gets a string and an integer, and returns an another string.
  • Vararg type: synthetic type allowed only in function parameter type position. Accepts zero or more values of the same type. E.g., String?... accepts an arbitrary number of String? values.

You do not need to use type annotations in Lua code, just pass values of correct types to API functions.

Built-in types

There are several built-in types:

  • Any – any type. In some programming languages it is called a variant type. Any, however, can not hold a nil value (Any? can).
  • Int – a 64-bit integer type (0, 5, -1000).
  • Float – a 64-bit float type (0.2, 0.333).
  • Number – essentially, [Int | Float].
  • String – a string type. As Lua does not care about the contents of strings, in some places the String type is used as a chunk of bytes.
  • Boolean – boolean type (true, false).
  • Array<T> – array type, holding elements of T type. Array<String> holds only strings, Array<Any> can hold any values.
  • Dictionary<Key, Value> – unsorted dictionary/map type. Dictionary<String, Int> holds integer values accessible by string keys.

Errors

Some methods can throw error objects. Use the pcall() function to catch them.