xref: /freebsd/contrib/lyaml/README.md (revision 2bc180ef045e5911cce0cea1c2a139cffd2b577a)
1LYAML
2=====
3
4Copyright (C) 2013-2022 Gary V. Vaughan
5
6[![License](https://img.shields.io/:license-mit-blue.svg)](https://mit-license.org)
7[![workflow status](https://github.com/gvvaughan/lyaml/actions/workflows/spec.yml/badge.svg?branch=release-v6.2.8)](https://github.com/gvvaughan/lyaml/actions)
8[![codecov.io](https://codecov.io/github/gvvaughan/lyaml/coverage.svg?branch=release-v6.2.8)](https://codecov.io/github/gvvaughan/lyaml?branch=release-v6.2.8)
9
10[LibYAML] binding for [Lua], with a fast C implementation
11for converting between [%YAML 1.1][yaml11] and [Lua] tables,
12and a low-level [YAML] event parser for implementing more
13intricate [YAML] document loading.
14
15Usage
16-----
17
18### High Level API
19
20These functions quickly convert back and forth between Lua tables
21and [%YAML 1.1][yaml11] format strings.
22
23```lua
24local lyaml   = require "lyaml"
25local t       = lyaml.load (YAML-STRING, [OPTS-TABLE])
26local yamlstr = lyaml.dump (LUA-TABLE, [OPTS-TABLE])
27local null    = lyaml.null ()
28```
29
30#### `lyaml.load`
31
32`lyaml.load` accepts a YAML string for parsing. If the YAML string contains
33multiple documents, only the first document will be returned by default. To
34return multiple documents as a table, set `all = true` in the second
35argument OPTS-TABLE.
36
37```lua
38lyaml.load("foo: bar")
39--> { foo = "bar" }
40
41lyaml.load("foo: bar", { all = true })
42--> { { foo = "bar" } }
43
44multi_doc_yaml = [[
45---
46one
47...
48---
49two
50...
51]]
52
53lyaml.load(multi_doc_yaml)
54--> "one"
55
56lyaml.load(multi_doc_yaml, { all = true })
57--> { "one", "two" }
58```
59
60You can supply an alternative function for converting implicit plain
61scalar values in the `implicit_scalar` field of the OPTS-TABLE argument;
62otherwise a default is composed from the functions in the `lyaml.implicit`
63module.
64
65You can also supply an alternative table for coverting explicitly tagged
66scalar values in the `explicit_scalar` field of the OPTS-TABLE argument;
67otherwise all supported tags are parsed by default using the functions
68from the `lyaml.explicit` module.
69
70#### `lyaml.dump`
71
72`lyaml.dump` accepts a table of values to dump. Each value in the table
73represents a single YAML document. To dump a table of lua values this means
74the table must be wrapped in another table (the outer table represents the
75YAML documents, the inner table is the single document table to dump).
76
77```lua
78lyaml.dump({ { foo = "bar" } })
79--> ---
80--> foo: bar
81--> ...
82
83lyaml.dump({ "one", "two" })
84--> --- one
85--> ...
86--> --- two
87--> ...
88```
89
90If you need to round-trip load a dumped document, and you used a custom
91function for converting implicit scalars, then you should pass that same
92function in the `implicit_scalar` field of the OPTS-TABLE argument to
93`lyaml.dump` so that it can quote strings that might otherwise be
94implicitly converted on reload.
95
96#### Nil Values
97
98[Lua] tables treat `nil` valued keys as if they were not there,
99where [YAML] explicitly supports `null` values (and keys!).  Lyaml
100will retain [YAML] `null` values as `lyaml.null ()` by default,
101though it is straight forward to wrap the low level APIs to use `nil`,
102subject to the usual caveats of how nil values work in [Lua] tables.
103
104
105### Low Level APIs
106
107```lua
108local emitter = require ("yaml").emitter ()
109
110emitter.emit {type = "STREAM_START"}
111for _, event in ipairs (event_list) do
112  emitter.emit (event)
113end
114str = emitter.emit {type = "STREAM_END"}
115```
116
117The `yaml.emitter` function returns an emitter object that has a
118single emit function, which you call with event tables, the last
119`STREAM_END` event returns a string formatted as a [YAML 1.1][yaml11]
120document.
121
122```lua
123local iter = require ("yaml").scanner (YAML-STRING)
124
125for token_table in iter () do
126  -- process token table
127end
128```
129
130Each time the iterator returned by `scanner` is called, it returns
131a table describing the next token of YAML-STRING.  See LibYAML's
132[yaml.h] for details of the contents and semantics of the various
133tokens produced by `yaml_parser_scan`, the underlying call made by
134the iterator.
135
136[LibYAML] implements a fast parser in C using `yaml_parser_scan`, which
137is also bound to lyaml, and easier to use than the token API above:
138
139```lua
140local iter = require ("yaml").parser (YAML-STRING)
141
142for event_table in iter () do
143  -- process event table
144end
145```
146
147Each time the iterator returned by `parser` is called, it returns
148a table describing the next event from the "Parse" process of the
149"Parse, Compose, Construct" processing model described in the
150[YAML 1.1][yaml11] specification using [LibYAML].
151
152Implementing the remaining "Compose" and "Construct" processes in
153[Lua] is left as an exercise for the reader -- though, unlike the
154high-level API, `lyaml.parser` exposes all details of the input
155stream events, such as line and column numbers.
156
157
158Installation
159------------
160
161There's no need to download an [lyaml] release, or clone the git repo,
162unless you want to modify the code.  If you use [LuaRocks], you can
163use it to install the latest release from its repository:
164
165    luarocks --server=http://rocks.moonscript.org install lyaml
166
167Or from the rockspec in a release tarball:
168
169    luarocks make lyaml-?-1.rockspec
170
171To install current git master from [GitHub][lyaml] (for testing):
172
173    luarocks install http://raw.github.com/gvvaughan/lyaml/master/lyaml-git-1.rockspec
174
175To install without [LuaRocks], clone the sources from the
176[repository][lyaml], and then run the following commands:
177
178```sh
179cd lyaml
180build-aux/luke LYAML_DIR=LIBYAML-INSTALL-PREFIX
181sudo build-aux/luke PREFIX=LYAML-INSTALL-PREFIX install
182specl -v1freport spec/*_spec.yaml
183```
184
185The dependencies are listed in the dependencies entry of the file
186[rockspec][L15].
187
188
189Bug reports and code contributions
190----------------------------------
191
192This library is maintained by its users.
193
194Please make bug reports and suggestions as [GitHub Issues][issues].
195Pull requests are especially appreciated.
196
197But first, please check that your issue has not already been reported by
198someone else, and that it is not already fixed by [master][lyaml] in
199preparation for the next release (see  Installation section above for how
200to temporarily install master with [LuaRocks][]).
201
202There is no strict coding style, but please bear in mind the following
203points when proposing changes:
204
2050. Follow existing code. There are a lot of useful patterns and avoided
206   traps there.
207
2081. 3-character indentation using SPACES in Lua sources: It makes rogue
209   TABs easier to see, and lines up nicely with 'if' and 'end' keywords.
210
2112. Simple strings are easiest to type using single-quote delimiters,
212   saving double-quotes for where a string contains apostrophes.
213
2143. Save horizontal space by only using SPACEs where the parser requires
215   them.
216
2174. Use vertical space to separate out compound statements to help the
218   coverage reports discover untested lines.
219
2205. Prefer explicit string function calls over object methods, to mitigate
221   issues with monkey-patching in caller environment.
222
223
224[issues]:   http://github.com/gvvaughas/lyaml/issues
225[libyaml]:  http://pyyaml.org/wiki/LibYAML
226[lua]:      http://www.lua.org
227[luarocks]: http://www.luarocks.org
228[lyaml]:    http://github.com/gvvaughan/lyaml
229[L15]:      http://github.com/gvvaughan/lyaml/blob/master/lyaml-git-1.rockspec#L15
230[yaml.h]:   http://pyyaml.org/browser/libyaml/branches/stable/include/yaml.h
231[yaml]:     http://yaml.org
232[yaml11]:   http://yaml.org/spec/1.1/
233