208 lines
5.9 KiB
Markdown
208 lines
5.9 KiB
Markdown
# formspec_ast
|
|
|
|
A Minetest mod library to make modifying formspecs easier.
|
|
|
|
## API
|
|
|
|
- `formspec_ast.parse(formspec_string)`: Parses `formspec_string` and returns
|
|
an AST.
|
|
- `formspec_ast.unparse(tree)`: Unparses the abstract syntax tree provided
|
|
and returns a formspec string.
|
|
- `formspec_ast.register_element('modname:element', function())`: Registers
|
|
a custom element. See [registering elements] for more information.
|
|
- `formspec_ast.interpret(string_or_tree)`: Returns a formspec string after
|
|
(optionally parsing) and unparsing the formspec provided.
|
|
- `formspec_ast.walk(tree)`: Returns an iterator (use this directly in a for
|
|
loop) that will return all nodes in a tree, including ones inside
|
|
containers.
|
|
- `formspec_ast.find(tree, node_type)`: Similar to `walk(tree)`, however only
|
|
returns `node_type` nodes.
|
|
- `formspec_ast.get_element_by_name(tree, name)`: Returns the first element in
|
|
the tree with the name `name`.
|
|
- `formspec_ast.get_elements_by_name(tree, name)`: Returns a list of all the
|
|
elements with the name `name`.
|
|
- `formspec_ast.apply_offset(tree, x, y)`: Shifts all elements in `tree`.
|
|
Similar to `container`.
|
|
- `formspec_ast.flatten(tree)`: Removes all containers and offsets elements
|
|
that were in containers accordingly. **The use of this function is
|
|
discouraged as `scroll_container[]` elements are not flattened.**
|
|
- `formspec_ast.show_formspec(player_or_name, formname, formspec)`: Similar
|
|
to `minetest.show_formspec`, however also accepts player objects and will
|
|
pass `formspec` through `formspec_ast.interpret` first.
|
|
- `formspec_ast.safe_parse(string_or_tree)`: Similar to `formspec_ast.parse`,
|
|
however will delete any elements that may crash the client (or any I
|
|
haven't added to the safe element list).
|
|
- `formspec_ast.formspec_escape(text)`: The same as `minetest.formspec_escape`,
|
|
should only be used when formspec_ast is being embedded outside of Minetest.
|
|
|
|
## AST
|
|
|
|
The AST is similar (and generated from) [the formspec element list], however
|
|
all attributes are lowercase.
|
|
|
|
[the formspec element list]: https://minetest.gitlab.io/minetest/formspec/#elements
|
|
|
|
### Recent backwards incompatibilities
|
|
|
|
While I try to reduce backwards incompatibilities, sometimes they are necessary
|
|
to either fix bugs in formspec_ast or for implementing new formspec features.
|
|
|
|
#### March 2021
|
|
|
|
- The `index_event` value for `dropdown` is now a boolean instead of a string.
|
|
|
|
#### February 2021
|
|
|
|
- The `close_on_enter` value for `field_close_on_enter` is now a boolean
|
|
instead of a string.
|
|
- The `frame_count`, `frame_duration` and `frame_start` values in
|
|
`animated_image` are now numbers.
|
|
|
|
#### September 2020
|
|
|
|
- The `style[]` element has a `selectors` field instead of `name`. Using
|
|
`name` when unparsing formspecs still works, however parsed formspecs
|
|
always use `selectors`.
|
|
|
|
### Special cases
|
|
|
|
- `formspec_version` (provided it is the first element) is moved to
|
|
`tree.formspec_version` (`1` by default).
|
|
|
|
### `formspec_ast.parse` example
|
|
|
|
*Note that the whitespace in the formspec is optional and exists for
|
|
readability. Non-numeric table items in the `dump()` output are re-ordered for
|
|
readability.*
|
|
|
|
```lua
|
|
> tree = formspec_ast.parse('size[5,2] '
|
|
>> .. 'style[name;bgcolor=blue;textcolor=yellow]'
|
|
>> .. 'container[1,1]'
|
|
>> .. ' label[0,0;Containers are fun]'
|
|
>> .. ' container[-1,-1]'
|
|
>> .. ' button[0.5,0;4,1;name;Label]'
|
|
>> .. ' container_end[]'
|
|
>> .. ' label[0,1;Nested containers work too.]'
|
|
>> .. 'container_end[]'
|
|
>> .. ' image[0,1;1,1;air.png]')
|
|
> print(dump(tree))
|
|
{
|
|
formspec_version = 1,
|
|
{
|
|
type = "size",
|
|
w = 5,
|
|
h = 2,
|
|
},
|
|
{
|
|
type = "style",
|
|
selectors = {"name"},
|
|
props = {
|
|
bgcolor = "blue",
|
|
textcolor = "yellow",
|
|
},
|
|
},
|
|
{
|
|
type = "container",
|
|
x = 1,
|
|
y = 1,
|
|
{
|
|
type = "label",
|
|
x = 0,
|
|
y = 0,
|
|
label = "Containers are fun",
|
|
},
|
|
{
|
|
type = "container",
|
|
x = -1,
|
|
y = -1,
|
|
{
|
|
type = "button",
|
|
x = 0.5,
|
|
y = 0,
|
|
w = 4,
|
|
h = 1,
|
|
name = "name",
|
|
label = "Label",
|
|
},
|
|
},
|
|
{
|
|
type = "label",
|
|
x = 0,
|
|
y = 1,
|
|
label = "Nested containers work too.",
|
|
},
|
|
},
|
|
{
|
|
type = "image",
|
|
x = 0,
|
|
y = 1,
|
|
w = 1,
|
|
h = 1,
|
|
texture_name = "air.png",
|
|
},
|
|
}
|
|
|
|
```
|
|
|
|
### `formspec_ast.flatten` example
|
|
|
|
```lua
|
|
> print(dump(formspec_ast.flatten(tree)))
|
|
{
|
|
formspec_version = 1,
|
|
{
|
|
type = "size",
|
|
w = 5,
|
|
h = 2,
|
|
},
|
|
{
|
|
type = "style",
|
|
selectors = {"name"},
|
|
props = {
|
|
bgcolor = "blue",
|
|
textcolor = "yellow",
|
|
},
|
|
},
|
|
{
|
|
type = "label",
|
|
x = 1,
|
|
y = 1,
|
|
label = "Containers are fun",
|
|
},
|
|
{
|
|
type = "button",
|
|
x = 0.5,
|
|
y = 0,
|
|
w = 4
|
|
h = 1,
|
|
name = "name",
|
|
label = "Label",
|
|
},
|
|
{
|
|
type = "label",
|
|
x = 1,
|
|
y = 2,
|
|
label = "Nested containers work too.",
|
|
},
|
|
{
|
|
type = "image",
|
|
x = 0,
|
|
y = 1,
|
|
w = 1,
|
|
h = 1,
|
|
texture_name = "air.png",
|
|
},
|
|
}
|
|
```
|
|
|
|
### `formspec_ast.unparse` example
|
|
|
|
```lua
|
|
> print(formspec_ast.unparse(tree))
|
|
size[5,2,]style[name;textcolor=yellow;bgcolor=blue]container[1,1]label[0,0;Containers are fun]container[-1,-1]button[0.5,0;4,1;name;Label]container_end[]label[0,1;Nested containers work too.]container_end[]image[0,1;1,1;air.png]
|
|
|
|
> print(formspec_ast.unparse(formspec_ast.flatten(tree)))
|
|
size[5,2,]style[name;textcolor=yellow;bgcolor=blue]label[1,1;Containers are fun]button[0.5,0;4,1;name;Label]label[1,2;Nested containers work too.]image[0,1;1,1;air.png]
|
|
```
|