yaml
LibYAML binding for Lua

Compiling

This module is distributed as a set of C source files. A makefile is provided which should be used to compile the module. The initialization function is luaopen_yaml and it is a Lua open-library compatible function.

Installation

This module conforms to the Lua 5.1 package model and should be installed in your package.path. Installation using LuaRocks is coming soon.

load

The load function parses a Lua string and returns a Lua representation of each YAML document it contained. If an error is encountered load will throw a hopefully descriptive error.

result = yaml.load("lua: rocks\npeppers: [ habanero, chipotle, jalapeno ]\n")

print(result.lua) -> rocks
print(result.peppers[1]) -> habanero

anchors & aliases

YAML anchors and alias nodes are fully supported. YAML nodes that reference other nodes are loaded with these references intact within Lua.

yamlstr = [[
cars:
- &car1
  make: Audi
  model: S4
- &car2
  make: VW
  model: GTI
favorite: *car1
]]

result = yaml.load(yamlstr)

print(result.favorite.model) -> S4
assert(result.favorite == result.cars[1]) -> true

When loading a string containing an unknown number of YAML documents it may be useful to take advantage of Lua's ellipsis construct to handle an the arbitrary number of results.

metatables

By default, load sets metatables on all loaded YAML collections to allow for differentiation between sequences and maps. These metatables are also used by dump to emit nodes in the same collection style as they were loaded. Building on the example from above:

print(getmetatable(result.cars)._yaml) -> sequence
print(getmetatable(result.favorite)._yaml) -> map

This behavior may be disabled using the configure function.

dump

dump emits a YAML document describing the provided Lua table.

print(yaml.dump({ VW = "GTI", Audi = "S4" }))
---
VW: GTI
Audi: S4

sequences vs. maps

YAML supports two different collection types, sequences (arrays) and maps (hashes). Since Lua does not have a native array type, dump cannot always infer the correct collection type.

dump defaults to using the equivalent of table.getn() to determine if a Lua table should be emitted as an array. In cases where a table contains both string and number keys, table.getn() will succeed and cause the output to only contain the numeric keys.

data = { "one", "two", nil, "three", dog = "cat" }
print(yaml.dump(data))
---
- one
- two
- three

If dump encounters a table with a metatable containing the key _yaml it uses the value to select the YAML collection type. The recognized values of the _yaml key are sequence or map.

data = { "one", "two", "three", dog = "cat" }
setmetatable(data, { _yaml = "map" })
print(yaml.dump(data))
---
1: one
2: two
3: three
dog: cat

anchors & aliases

Tables containing multiple references to other tables will have these nodes aliased where appropriate. Numeric anchor names are automatically chosen; it is not possible to specify a desired anchor name.

colors = {
   reds = {
      normal = { hex = "FF0000", rgb = { 255, 0, 0 } },
      dark = { hex = "8B0000", rgb = { 139, 0, 0 } },
   }
}
colors.all = { colors.reds.normal, colors.reds.dark }

print(yaml.dump(colors))
---
all:
- &0
  hex: FF0000
  rgb:
  - 255
  - 0
  - 0
- &1
  hex: 8B0000
  rgb:
  - 139
  - 0
  - 0
reds:
  normal: *0
  dark: *1

Multiply referenced scalars are not dumped as anchors and aliases in order to make the output YAML as human readable as possible. This will likely be something that is made configurable in the future.

multiple arguments

You may provide multiple objects and dump will serialize them in sequence and return the resulting multi-document YAML stream.

print(yaml.dump({ VW = "GTI", Audi = "S4" }, { "one", "two", "three" }))
---
VW: GTI
Audi: S4
---
- one
- two
- three

configure

Information on the configure function is coming soon...