Manual
For the impatient
local CodeGen = require 'CodeGen' tmpl = CodeGen { -- instanciation tarball = "${name}-${version}.tar.gz", name = 'lua', } tmpl.version = 5.1 output = tmpl 'tarball' -- interpolation print(output) --> lua-5.1.tar.gz
The instanciation
The instanciation of a template is done by the call of CodeGen
with optional parameters. This first parameter is a table. This table uses
only string as key and could contains 3 kinds of value :
- chunk of template which is a string and could contains primitives i.e.
${...}
- data which gives access to the data model
- formatter which is a function which accepts a string as parameter and returns it after a transformation. The typical usage is for escape sequence.
The other parameters allow inheritance (ie. access to field) from other templates or simple tables.
A common pattern is to put this step in an external file.
-- file: tarball.tmpl return CodeGen { tarball = "${name}-${version}.tar.gz", }
tmpl = dofile 'tarball.tmpl'
Setting data and other alteration
After the instanciation and before the interpolation, all member of the template are accessible and modifiable like in a table.
Typically, data from the model are added after the instanciation.
The interpolation
The interpolation is done by calling the template with one string parameter which is the keyname of the entry point template.
The interpolation returns a string as result and an optional string which contains some error messages.
The 4 primitives in template
The data
could be in the form of foo.bar.baz
.
1. Attribute reference
The syntax is ${data[; separator='sep'][; format=name]}
.
An undefined data
produces an empty string.
The option format
allows to specify a formatter function,
which is a value of the template referred by the key name
.
The default behavior is given by the standard Lua function tostring
.
When data
is a table, the option separator
is used as parameter of table.concat(data, sep)
.
This parameter could be simple quoted or double quoted,
and it handles escape sequence like Lua.
The characters {
and }
are forbidden,
there must be represented by a decimal escape sequence \ddd
.
local CodeGen = require 'CodeGen' tmpl = CodeGen { call = "${name}(${parameters; separator=', '});", } tmpl.name = 'print' tmpl.parameters = { 1, 2, 3 } output = tmpl 'call' print(output) --> print(1, 2, 3);
2. Template include
The syntax is ${name()}
where name
is the keyname of a chunk template.
If name
is not the keyname of a valid chunk,
there are no substitution and an error is reported.
3. Conditional include
The if
syntax is ${data?name1()}
and the if/else
syntax is ${data?name1()!name2()}
where name1
and name2
are the keyname of a chunk template
and data
is evaluated as a boolean.
4. Template application
The syntax is ${data/name()[; separator='sep']}
where data
must be a table.
The template name
is called for each item of the array data
,
and the result is concatened with an optional separator
.
The template has a direct access in the item,
and inherits access from the caller.
If the item is not a table, it is accessible via the key it
.
Examples
A generic template for rockspec.
-- file: rockspec.tmpl return CodeGen { rockspec = [[ package = '${name}' version = '${version}-${revision}' ${_source()} ${_description()} ${_dependencies()} ]], _source = [[ source = { url = ${_url()}, md5 = '${md5}', dir = '${name}-${version}', }, ]], _description = [[ description = { ${desc.summary?_summary()} ${desc.homepage?_homepage()} ${desc.maintainer?_maintainer()} ${desc.license?_license()} }, ]], _summary = 'summary = "${desc.summary}",', _homepage = 'homepage = "${desc.homepage}",', _maintainer = 'maintainer = "${desc.maintainer}",', _license = 'license = "${desc.license}",', _dependencies = [[ dependencies = { ${dependencies/_depend()} } ]], _depend = [[ '${name} >= ${version}', ]], }
A specialization for all my projects.
-- file: my_rockspec.tmpl local parent = dofile 'rockspec.tmpl' return CodeGen({ lower = string.lower, _tarball = "${name; format=lower}-${version}.tar.gz", _url = "'http://cloud.github.com/downloads/fperrad/${name}/${_tarball()}'", _homepage = 'homepage = "http://fperrad.github.com/${name}",', desc = { homepage = true, maintainer = "Francois Perrad", license = "MIT/X11", }, }, parent)
And finally, an use for this project.
CodeGen = require 'CodeGen' local rs = dofile 'my_rockspec.tmpl' rs.name = 'lua-CodeGen' rs.version = '0.1.0' rs.revision = 1 rs.md5 = 'XxX' rs.desc.summary = "a template engine" rs.dependencies = { { name = 'lua', version = 5.1 }, { name = 'lua-testmore', version = '0.2.1' }, } print(rs 'rockspec')
The output is :
package = 'lua-CodeGen' version = '0.1.0-1' source = { url = 'http://cloud.github.com/downloads/fperrad/lua-CodeGen/lua-codegen-0.1.0.tar.gz', md5 = 'XxX', dir = 'lua-CodeGen-0.1.0', }, description = { summary = "a template engine", homepage = "http://fperrad.github.com/lua-CodeGen", maintainer = "Francois Perrad", license = "MIT/X11", }, dependencies = { 'lua >= 5.1', 'lua-testmore >= 0.2.1', }