Difference between revisions of "LuaAPI/wml"

From The Battle for Wesnoth Wiki
(wml.tovconfig: Document the vconfig object)
(wml.load: Add a bit more information on schemas)
 
(37 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 +
<div class="tright"> __TOC__ </div>
 +
 
The <tt>wml</tt> module contains functions for working with WML tables. This module is available starting in 1.14.0.
 
The <tt>wml</tt> module contains functions for working with WML tables. This module is available starting in 1.14.0.
  
==== wml.child_array ====
+
A WML table is a specially-formatted Lua table representing WML tags and values. For more detail on the format of WML tables, see [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]].
 +
 
 +
== Functions ==
 +
 
 +
=== wml.attribute_count ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.attribute_count'''(''config'') &rarr; ''count''
 +
 
 +
Returns the number of attributes in the specified WML table.
 +
 
 +
=== wml.child_array ===
  
 
* '''wml.child_array'''(''config'', ''child_tag_name'') &rarr; ''array''
 
* '''wml.child_array'''(''config'', ''child_tag_name'') &rarr; ''array''
Line 7: Line 21:
 
Like [[#wml.child_range]], but returns an array instead of an iterator. Useful if you need random access to the children.
 
Like [[#wml.child_range]], but returns an array instead of an iterator. Useful if you need random access to the children.
  
==== wml.child_count ====
+
=== wml.child_count ===
  
 
* '''wml.child_count'''(''config'', ''child_tag_name'') &rarr; ''count''
 
* '''wml.child_count'''(''config'', ''child_tag_name'') &rarr; ''count''
Line 13: Line 27:
 
Returns the number of children in the config with the given tag name.
 
Returns the number of children in the config with the given tag name.
  
==== wml.child_range ====
+
=== wml.child_range ===
  
* '''wml.child_range'''(''config'', ''child_tag_name'') &rarr; ''iterator''
+
* '''wml.child_range'''(''config'', ''child_tag_name'') &rarr; ''iterator'' &rArr; ''wml table''
  
 
Returns an iterator over all the sub-tags of a WML object with the given name.
 
Returns an iterator over all the sub-tags of a WML object with the given name.
  
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
local u = wesnoth.get_units({ id = "Delfador" })[1]
+
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]
 
for att in wml.child_range(u.__cfg, "attack") do
 
for att in wml.child_range(u.__cfg, "attack") do
 
     wesnoth.message(tostring(att.description))
 
     wesnoth.message(tostring(att.description))
Line 26: Line 40:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.get_child ====
+
=== wml.find_child ===
 +
 
 +
{{DevFeature1.15|3}}
  
* '''wml.get_child'''(''config'', ''child_tag_name'' [, ''id'']) &rarr; ''child_table''
+
* '''wml.find_child'''(''config'', [''tag_name''], ''filter'') &rarr; ''child or nil'', ''index''
 +
 
 +
Finds a child of the given config that matches the given filter, and returns the child or nil if not found. The index of the child is also returned. If a tag name is specified, the search is restricted to that tag.
 +
 
 +
=== wml.get_child ===
 +
 
 +
* '''wml.get_child'''(''config'', ''child_tag_name'', [''id'']) &rarr; ''child_table''
  
 
Returns the first sub-tag of a WML object with the given name.
 
Returns the first sub-tag of a WML object with the given name.
  
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
local u = wesnoth.get_units({ id = "Delfador" })[1]
+
local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]
 
local costs = wml.get_child(u.__cfg, "movement_costs")
 
local costs = wml.get_child(u.__cfg, "movement_costs")
 
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))
 
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))
Line 40: Line 62:
 
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.
 
If a third parameter is passed, only children having a ''id'' attribute equal to it are considered.
  
==== wml.get_nth_child ====
+
=== wml.get_nth_child ===
  
 
* '''wml.get_nth_child'''(''config'', ''child_tag_name'', ''n'') &rarr; ''child_table''
 
* '''wml.get_nth_child'''(''config'', ''child_tag_name'', ''n'') &rarr; ''child_table''
Line 46: Line 68:
 
Returns the ''n''th sub-tag of a WML object with the given name.
 
Returns the ''n''th sub-tag of a WML object with the given name.
  
==== wml.remove_child ====
+
=== wml.remove_child ===
  
 
* '''wml.remove_child'''(''config'', ''child_tag_name'')
 
* '''wml.remove_child'''(''config'', ''child_tag_name'')
Line 52: Line 74:
 
Deletes the first child tag with the given name. This does not work on vconfig objects, however.
 
Deletes the first child tag with the given name. This does not work on vconfig objects, however.
  
==== wml.remove_children ====
+
=== wml.remove_children ===
 +
 
 +
{{DevFeature1.17|0}}
  
* '''wml.remove_children'''(''config'', ''child_tag_name'')
+
* '''wml.remove_children'''(''config'', ''child_tag_name'', ...)
  
Deletes all child tags with the given name. This does not work on vconfig objects, however.
+
Deletes all child tags with the given names. This does not work on vconfig objects, however. You can pass as many tag names as you want as separate arguments.
  
==== wml.tag ====
+
=== wml.tag ===
  
 
* '''wml.tag'''.''tag_name''(''contents'') &rarr; ''tag_table''
 
* '''wml.tag'''.''tag_name''(''contents'') &rarr; ''tag_table''
Line 68: Line 92:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.clone ====
+
=== wml.clone ===
  
 
{{DevFeature1.15|0}}
 
{{DevFeature1.15|0}}
Line 76: Line 100:
 
Returns a clone (deep copy) of the passed WML table.
 
Returns a clone (deep copy) of the passed WML table.
  
==== wml.load ====
+
=== wml.equal ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.equal'''(''config'', ''config'') &rarr; ''true or false''
 +
 
 +
Tests whether two WML objects are equal. Equal objects will produce an empty diff, and will be serialized to the same string.
 +
 
 +
=== wml.valid ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.valid'''(''table'') &rarr; ''is_wml''
 +
 
 +
Tests whether the passed table represents a valid WML table. It will also return true if passed a vconfig.
 +
 
 +
=== wml.matches_filter ===
 +
 
 +
* '''wml.matches_filter'''(''WML table'', ''filter'')''' &rarr; ''boolean''
 +
 
 +
Test if a config matches a WML filter (as <tt>[filter_wml]</tt>).
 +
 
 +
=== wml.load ===
  
 
{{DevFeature1.15|0}}
 
{{DevFeature1.15|0}}
  
* '''wml.load'''(''file'' [, ''defines'' [, ''schema'']]) &rarr; ''config''
+
* '''wml.load'''(''file'', [''defines'', [''schema'']]) &rarr; ''config''
 +
 
 +
Loads WML from a file and optionally validates it against a schema. The file and schema (if present) must both be a valid WML path, and the schema must point to a [[SchemaWML]] file. All built-in schema files can be found directly in the "schema" folder – for example, "schema/game_config.cfg" is the schema for an add-on's (and core's) _main.cfg.
  
Loads WML from a file and optionally validates it against a schema. The file and schema (if present) must both be a valid WML path. The second parameter can either be a boolean specifying whether or not to preprocess the file (defaults to true), or an array of macros to be defined in the preprocessor (which of course implies the file will be preprocessed).
+
The second parameter can either be a boolean specifying whether or not to preprocess the file (defaults to true), or an array of macros to be defined in the preprocessor (which of course implies the file will be preprocessed). The second form only allows specifying names to be defined. It does not allow setting a value or anything more complex.
  
==== wml.parse ====
+
=== wml.parse ===
  
 
{{DevFeature1.15|0}}
 
{{DevFeature1.15|0}}
  
* '''wml.parse'''(''string'' [, ''schema'']) &rarr; ''config''
+
* '''wml.parse'''(''string'', [''schema'']) &rarr; ''config''
  
 
Parses a string containing WML code and optionally validates it against the provided schema. Unlike load, this function does ''not'' run the preprocessor, though <tt>#textdomain</tt> directives will still be recognized.
 
Parses a string containing WML code and optionally validates it against the provided schema. Unlike load, this function does ''not'' run the preprocessor, though <tt>#textdomain</tt> directives will still be recognized.
  
==== wml.tostring ====
+
=== wml.merge ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.merge'''(''base table'', ''merge data'', [''mode'']) &rarr; ''merged config''
 +
 
 +
Merges two WML tables recursively, using the specified mode. Possible modes are '''merge''', '''replace''', and '''append'''. The modes work the same as in [[InternalActionsWML#.5Bset_variables.5D|[set_variables]]]. The mode only affects how child tags are merged; merging of attributes is always done the same way. The default mode is '''merge'''.
 +
 
 +
=== wml.diff ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.diff'''(''left'', ''right'') &rarr; ''diff config''
 +
 
 +
Compares two WML tables and produces an output table in [[DiffWML]] detailing their differences.
 +
 
 +
=== wml.patch ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.patch'''(''base'', ''diff'') &rarr; ''patched config''
 +
 
 +
Takes a WML table and a diff in [[DiffWML]] format and returns a new WML table modified according to the diff's instructions.
 +
 
 +
=== wml.interpolate ===
 +
 
 +
{{DevFeature1.15|3}}
 +
 
 +
* '''wml.interpolate'''('''template''', '''variables''') &rarr; ''interpolated config''
 +
 
 +
Interpolates variables into a WML table, including '''[insert_tag]'''. This is the same as what a vconfig does implicitly, but can use any valid WML table as a source of variables.
 +
 
 +
<syntaxhighlight lang=lua>
 +
local variables = {
 +
  -- A scalar variable
 +
  number = 100,
 +
  -- An array variable with two entries
 +
  wml.tag.list{value = 42, rank = 3},
 +
  wml.tag.list{value = 21, rank = 1},
 +
}
 +
local subst = {
 +
  key = "$number",
 +
  wml.tag.insert_tag{
 +
    name = "entry",
 +
    variable = "list"
 +
  }
 +
}
 +
local result = wml.interpolate(subst, variables)
 +
print(wml.tostring(result))
 +
</syntaxhighlight>
 +
 
 +
The above code will output the following WML in the Lua console:
 +
 
 +
<syntaxhighlight lang=wml>
 +
key=100
 +
[entry]
 +
  rank=3
 +
  value=42
 +
[/entry]
 +
[entry]
 +
  rank=1
 +
  value=21
 +
[/entry]
 +
</syntaxhighlight>
 +
 
 +
=== wml.tostring ===
  
 
* '''wml.tostring'''(''wml_table'') &rarr; ''string''
 
* '''wml.tostring'''(''wml_table'') &rarr; ''string''
Line 107: Line 220:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.tovconfig ====
+
=== wml.tovconfig ===
  
* '''wml.tovconfig'''(''config'') &rarr; ''vconfig''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.tovconfig'''(''config'') &rarr; ''vconfig''
  
Converts a WML table into a proxy object which performs variable substitution on the fly. The proxy object can for most intents and purposes be treated as a read-only table - the length operator works as expected, as do the pairs and ipairs functions. Integer indices will contain ''tag tables'', a two-element table where the first element is the name of the tag and the second element is another vconfig representing the tag's contents. String indices represent keys in the config. There are four special keys (''__literal'', ''__parsed'', ''__shallow_literal'', ''__shallow_parsed'') which correspond to the functions in this module by the same name, but in most cases it is better to use the functions.
+
Converts a WML table into a proxy object which performs variable substitution on the fly. The proxy object can for most intents and purposes be treated as a read-only table - the length operator works as expected, as does the ipairs function. The pairs function also works, but it is a little different than on a plain table - it will return only the attributes of the vconfig and not the tags. See [[LuaWML#Encoding_WML_objects_into_Lua_tables|LuaWML]] for more information about the structure of a vconfig (which is the same as the structure of a WML table). A vconfig has four special keys (''__literal'', ''__parsed'', ''__shallow_literal'', ''__shallow_parsed'') which correspond to the functions in this module by the same name, but in most cases it is better to use the functions.
  
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
Line 124: Line 237:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.literal ====
+
=== wml.literal ===
  
 
* '''wml.literal'''(''config'') &rarr; ''wml_table''
 
* '''wml.literal'''(''config'') &rarr; ''wml_table''
Line 139: Line 252:
 
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.
 
Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.
  
==== wml.parsed ====
+
=== wml.parsed ===
  
 
* '''wml.parsed'''(''config'') &rarr; ''wml_table''
 
* '''wml.parsed'''(''config'') &rarr; ''wml_table''
Line 145: Line 258:
 
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
 
Returns the ''__parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
  
==== wml.shallow_literal ====
+
=== wml.shallow_literal ===
  
 
* '''wml.shallow_literal'''(''config'') &rarr; ''wml_table''
 
* '''wml.shallow_literal'''(''config'') &rarr; ''wml_table''
Line 151: Line 264:
 
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
 
Returns the ''__shallow_literal'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
  
==== wml.shallow_parsed ====
+
=== wml.shallow_parsed ===
  
 
* '''wml.shallow_parsed'''(''config'') &rarr; ''wml_table''
 
* '''wml.shallow_parsed'''(''config'') &rarr; ''wml_table''
Line 157: Line 270:
 
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
 
Returns the ''__shallow_parsed'' field of its argument if it is a userdata, the argument itself otherwise. See also [[#wml.literal]].
  
==== wml.all_variables ====
+
=== wml.all_variables ===
  
* (game only) '''wml.all_variables''' &rarr; ''table''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.all_variables''' &rarr; ''table''
  
 
Returns a copy of all the WML variables currently set in the form of a WML table.
 
Returns a copy of all the WML variables currently set in the form of a WML table.
Line 173: Line 286:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.variables ====
+
=== wml.variables ===
  
* (game only) '''wml.variables'''.''variable'' &harr; ''variable_contents''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''.''variable'' &harr; ''variable_contents''
* (game only) '''wml.variables'''[''variable_path''] &harr; ''variable_contents''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables'''[''variable_path''] &harr; ''variable_contents''
  
 
This table grants read-write access to the WML variables by their fully-qualified name. Looking up a non-existent variable yields nil; otherwise, it returns a scalar for a WML attribute and a table for a WML object. The format of the table is described in [[LuaWML#Encoding WML objects into Lua tables]].
 
This table grants read-write access to the WML variables by their fully-qualified name. Looking up a non-existent variable yields nil; otherwise, it returns a scalar for a WML attribute and a table for a WML object. The format of the table is described in [[LuaWML#Encoding WML objects into Lua tables]].
Line 186: Line 299:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Note that, if the variable name happens to designate a sequence of WML objects, only the first one (index 0) is fetched. If all the WML objects with this name should have been returned, use [[#wml.get_variable_array]] instead. If you need a specific one, include the index in the lookup key.
+
Note that, if the variable name happens to designate a sequence of WML objects, only the first one (index 0) is fetched. If all the WML objects with this name should have been returned, use [[#wml.array_access.get]] instead. If you need a specific one, include the index in the lookup key.
  
 
Assigning to a key in this table converts the Lua object to a WML variable if possible. For a table, a WML object is created; otherwise, an attribute is created. Note that you cannot assign a simple array as it will be mistaken for a WML table and give an error. Assigning nil clears the variable.
 
Assigning to a key in this table converts the Lua object to a WML variable if possible. For a table, a WML object is created; otherwise, an attribute is created. Note that you cannot assign a simple array as it will be mistaken for a WML table and give an error. Assigning nil clears the variable.
Line 194: Line 307:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.variables_proxy ====
+
=== wml.variables_proxy ===
  
* (game only) '''wml.variables_proxy'''.''variable'' &harr; ''proxy''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''.''variable'' &harr; ''proxy''
* (game only) '''wml.variables_proxy'''[''variable_path''] &harr; ''proxy''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.variables_proxy'''[''variable_path''] &harr; ''proxy''
  
 
Similar to <tt>wml.variables</tt>, but if the variable is a container, then the fields of the returned table are then proxies to the WML objects with the same names; reading/writing to them will directly access the WML sub-variables. Note that this is still somewhat experimental and doesn't allow you to fully treat variables as if they were standard Lua tables.
 
Similar to <tt>wml.variables</tt>, but if the variable is a container, then the fields of the returned table are then proxies to the WML objects with the same names; reading/writing to them will directly access the WML sub-variables. Note that this is still somewhat experimental and doesn't allow you to fully treat variables as if they were standard Lua tables.
  
==== wml.array_access.get ====
+
=== wml.array_access.get ===
  
* (game only) '''wml.array_access.get'''(''var_name''[, ''context'']) &rarr; ''array of variable_contents''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get'''(''var_name'', [''context'']) &rarr; ''array of variable_contents''
  
 
Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.
 
Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.
Line 209: Line 322:
 
<syntaxhighlight lang=lua>
 
<syntaxhighlight lang=lua>
 
function get_recall_list(side)
 
function get_recall_list(side)
     wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list })
+
     wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })
 
     local l = wml.array_access.get "LUA_recall_list"
 
     local l = wml.array_access.get "LUA_recall_list"
 
     wml.variables.LUA_recall_list = nil
 
     wml.variables.LUA_recall_list = nil
Line 216: Line 329:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== wml.array_access.get_proxy ====
+
=== wml.array_access.get_proxy ===
  
* (game only) '''wml.array_access.get_proxy'''(''var_name'') &rarr; ''array of proxies''
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.get_proxy'''(''var_name'') &rarr; ''array of proxies''
  
 
Creates proxies for all the WML container variables with given name and returns a table containing them (starting at index 1). This function is similar to [[#wml.array_access.get]], except that the proxies can be used for modifying WML containers. Note that changes to the returned array itself will not be reflected in the variable, however; only changes to the array elements.
 
Creates proxies for all the WML container variables with given name and returns a table containing them (starting at index 1). This function is similar to [[#wml.array_access.get]], except that the proxies can be used for modifying WML containers. Note that changes to the returned array itself will not be reflected in the variable, however; only changes to the array elements.
  
==== wml.array_access.set ====
+
=== wml.array_access.set ===
  
* (game only) '''wml.array_access.set'''(''varname'', ''array'' [, ''context''])
+
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_access.set'''(''varname'', ''array'', [''context''])
  
 
Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.
 
Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.
Line 232: Line 345:
 
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3
 
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
=== wml.array_variables ===
 +
 +
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''.''variable'' &harr; ''array of variable_contents''
 +
* {{LuaGameOnly}}{{LuaMapOnly}} '''wml.array_variables'''[''variable_path''] &harr; ''array of variable_contents''
 +
 +
Like '''wml.variables''', except that it works on arrays as with '''wml.array_access.get''' and '''wml.array_access.set'''. This is a little more convenient when working with global WML variables rather than unit or side variables.
 +
 +
=== wml.eval_conditional ===
 +
 +
* {{LuaGameOnly}} '''wml.eval_conditional'''(''conditional_tags'') &rarr; ''boolean''
 +
 +
Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.
 +
 +
<syntaxhighlight lang=lua>
 +
local result = wml.eval_conditional {
 +
  wml.tag.have_unit { id = "hero" },
 +
  wml.tag.variable { name = "counter", numerical_equals = "$old_counter" }
 +
}
 +
</syntaxhighlight>
 +
 +
Note: Prior to 1.15.13, this was available as '''wesnoth.eval_conditional'''.
 +
 +
=== wml.fire ===
 +
 +
* {{LuaGameOnly}} '''wml.fire'''(''tag'', ''parameters'')
 +
* {{DevFeature1.17|17}} {{LuaGameOnly}} '''wml.fire'''.''tag''(''parameters'')
 +
 +
Fire a WML action tag. Note: WML variables are substituted into the parameters table.
 +
 +
Note: Prior to 1.15.13, this was available as '''wesnoth.fire'''. The second form was available through '''helper.set_wml_action_metatable'''.
 +
 +
=== wml.error ===
 +
 +
* {{LuaGameOnly}} '''wml.error'''(''message'')
 +
 +
Interrupts the current execution and displays a WML error message. This is intended for error messages in the implementaton of custom ActionWML or ConditionalWML tags. For errors in a Lua API, the built-in '''error''' function is a more suitable choice.
 +
 +
<syntaxhighlight lang=lua>
 +
local names = cfg.name or wml.error("[clear_variable] missing required name= attribute.")
 +
</syntaxhighlight>
 +
  
 
[[Category: Lua Reference]]
 
[[Category: Lua Reference]]

Latest revision as of 05:26, 22 August 2024

The wml module contains functions for working with WML tables. This module is available starting in 1.14.0.

A WML table is a specially-formatted Lua table representing WML tags and values. For more detail on the format of WML tables, see LuaWML.

Functions

wml.attribute_count

(Version 1.15.3 and later only)

  • wml.attribute_count(config) → count

Returns the number of attributes in the specified WML table.

wml.child_array

  • wml.child_array(config, child_tag_name) → array

Like #wml.child_range, but returns an array instead of an iterator. Useful if you need random access to the children.

wml.child_count

  • wml.child_count(config, child_tag_name) → count

Returns the number of children in the config with the given tag name.

wml.child_range

  • wml.child_range(config, child_tag_name) → iteratorwml table

Returns an iterator over all the sub-tags of a WML object with the given name.

local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]
for att in wml.child_range(u.__cfg, "attack") do
    wesnoth.message(tostring(att.description))
end

wml.find_child

(Version 1.15.3 and later only)

  • wml.find_child(config, [tag_name], filter) → child or nil, index

Finds a child of the given config that matches the given filter, and returns the child or nil if not found. The index of the child is also returned. If a tag name is specified, the search is restricted to that tag.

wml.get_child

  • wml.get_child(config, child_tag_name, [id]) → child_table

Returns the first sub-tag of a WML object with the given name.

local u = wesnoth.units.find_on_map{ id = "Delfador" }[1]
local costs = wml.get_child(u.__cfg, "movement_costs")
wesnoth.message(string.format("Delfador needs %d points to move through a forest.", costs.forest))

If a third parameter is passed, only children having a id attribute equal to it are considered.

wml.get_nth_child

  • wml.get_nth_child(config, child_tag_name, n) → child_table

Returns the nth sub-tag of a WML object with the given name.

wml.remove_child

  • wml.remove_child(config, child_tag_name)

Deletes the first child tag with the given name. This does not work on vconfig objects, however.

wml.remove_children

(Version 1.17.0 and later only)

  • wml.remove_children(config, child_tag_name, ...)

Deletes all child tags with the given names. This does not work on vconfig objects, however. You can pass as many tag names as you want as separate arguments.

wml.tag

  • wml.tag.tag_name(contents) → tag_table

Returns a table representing a tag within a WML table; can be used to create subtags with less brackets. It's common to use direct-table invocation for this, omitting the function parentheses.

wesnoth.wml_actions.event { name = "new turn", wml.tag.message { speaker = "narrator", message = "?" } }

wml.clone

(Version 1.15.0 and later only)

  • wml.clone(wml_table) → cloned_table

Returns a clone (deep copy) of the passed WML table.

wml.equal

(Version 1.15.3 and later only)

  • wml.equal(config, config) → true or false

Tests whether two WML objects are equal. Equal objects will produce an empty diff, and will be serialized to the same string.

wml.valid

(Version 1.15.3 and later only)

  • wml.valid(table) → is_wml

Tests whether the passed table represents a valid WML table. It will also return true if passed a vconfig.

wml.matches_filter

  • wml.matches_filter(WML table, filter)boolean

Test if a config matches a WML filter (as [filter_wml]).

wml.load

(Version 1.15.0 and later only)

  • wml.load(file, [defines, [schema]]) → config

Loads WML from a file and optionally validates it against a schema. The file and schema (if present) must both be a valid WML path, and the schema must point to a SchemaWML file. All built-in schema files can be found directly in the "schema" folder – for example, "schema/game_config.cfg" is the schema for an add-on's (and core's) _main.cfg.

The second parameter can either be a boolean specifying whether or not to preprocess the file (defaults to true), or an array of macros to be defined in the preprocessor (which of course implies the file will be preprocessed). The second form only allows specifying names to be defined. It does not allow setting a value or anything more complex.

wml.parse

(Version 1.15.0 and later only)

  • wml.parse(string, [schema]) → config

Parses a string containing WML code and optionally validates it against the provided schema. Unlike load, this function does not run the preprocessor, though #textdomain directives will still be recognized.

wml.merge

(Version 1.15.3 and later only)

  • wml.merge(base table, merge data, [mode]) → merged config

Merges two WML tables recursively, using the specified mode. Possible modes are merge, replace, and append. The modes work the same as in [set_variables]. The mode only affects how child tags are merged; merging of attributes is always done the same way. The default mode is merge.

wml.diff

(Version 1.15.3 and later only)

  • wml.diff(left, right) → diff config

Compares two WML tables and produces an output table in DiffWML detailing their differences.

wml.patch

(Version 1.15.3 and later only)

  • wml.patch(base, diff) → patched config

Takes a WML table and a diff in DiffWML format and returns a new WML table modified according to the diff's instructions.

wml.interpolate

(Version 1.15.3 and later only)

  • wml.interpolate(template, variables) → interpolated config

Interpolates variables into a WML table, including [insert_tag]. This is the same as what a vconfig does implicitly, but can use any valid WML table as a source of variables.

local variables = {
  -- A scalar variable
  number = 100,
  -- An array variable with two entries
  wml.tag.list{value = 42, rank = 3},
  wml.tag.list{value = 21, rank = 1},
}
local subst = {
  key = "$number",
  wml.tag.insert_tag{
    name = "entry",
    variable = "list"
  }
}
local result = wml.interpolate(subst, variables)
print(wml.tostring(result))

The above code will output the following WML in the Lua console:

key=100
[entry]
  rank=3
  value=42
[/entry]
[entry]
  rank=1
  value=21
[/entry]

wml.tostring

  • wml.tostring(wml_table) → string

Takes a userdata with metatable wml object or a wml table and dumps its content into a pretty string. (Version 1.15.0 and later only) The string output is syntactically valid WML that if parsed would produce the same config.

wml.variables["number"] = 100
local vconfig = wml.tovconfig({ key = "$number", another_key = true,
    {"a_subtag", { a_key_in_the_subtag = "foo" }}
})
wesnoth.message(wml.tostring(vconfig))
wesnoth.message(wml.tostring(vconfig.__literal))

wml.tovconfig

  • wml.tovconfig(config) → vconfig

Converts a WML table into a proxy object which performs variable substitution on the fly. The proxy object can for most intents and purposes be treated as a read-only table - the length operator works as expected, as does the ipairs function. The pairs function also works, but it is a little different than on a plain table - it will return only the attributes of the vconfig and not the tags. See LuaWML for more information about the structure of a vconfig (which is the same as the structure of a WML table). A vconfig has four special keys (__literal, __parsed, __shallow_literal, __shallow_parsed) which correspond to the functions in this module by the same name, but in most cases it is better to use the functions.

wml.variables["varname"] = "to_be_deleted"

-- correct
wesnoth.wml_actions.clear_variable { name = "to_be_deleted" }
-- error: try to delete a variable literally called "$varname"
wesnoth.wml_actions.clear_variable { name = "$varname" }
-- correct: "$varname" is replaced by "to_be_deleted" at the right time
wesnoth.wml_actions.clear_variable(wml.tovconfig { name = "$varname" })

wml.literal

  • wml.literal(config) → wml_table

Returns the __literal field of its argument if it is a userdata, the argument itself otherwise. If the argument is nil, it returns an empty table. This function is meant to be called when a WML action handler can be called indifferently from WML (hence receiving a userdata) or from Lua (hence possibly receiving a table).

function wml_actions.display_literal_value(cfg)
   cfg = wml.literal(cfg)
   wesnoth.message(tostring(cfg.value)) 
end

Note: when the argument is a plain table, the function returns it as is. In particular, modifying the fields of the returned table causes the original table to be modified too.

wml.parsed

  • wml.parsed(config) → wml_table

Returns the __parsed field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.shallow_literal

  • wml.shallow_literal(config) → wml_table

Returns the __shallow_literal field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.shallow_parsed

  • wml.shallow_parsed(config) → wml_table

Returns the __shallow_parsed field of its argument if it is a userdata, the argument itself otherwise. See also #wml.literal.

wml.all_variables

  • wml.all_variablestable

Returns a copy of all the WML variables currently set in the form of a WML table.

for key, value in pairs(wml.all_variables) do
    if type(value) == "table" then
        print(key, value[1], value[2])
    else
        print(key, value)
    end
end

wml.variables

  • wml.variables.variablevariable_contents
  • wml.variables[variable_path] ↔ variable_contents

This table grants read-write access to the WML variables by their fully-qualified name. Looking up a non-existent variable yields nil; otherwise, it returns a scalar for a WML attribute and a table for a WML object. The format of the table is described in LuaWML#Encoding WML objects into Lua tables.

wesnoth.fire("store_unit", { variable="my_unit", { "filter", { id="hero" } } })
local heros_hp = wml.variables["my_unit[0].hitpoints"]
wesnoth.message(string.format("The 'hero' unit has %d hitpoints.", heros_hp))

Note that, if the variable name happens to designate a sequence of WML objects, only the first one (index 0) is fetched. If all the WML objects with this name should have been returned, use #wml.array_access.get instead. If you need a specific one, include the index in the lookup key.

Assigning to a key in this table converts the Lua object to a WML variable if possible. For a table, a WML object is created; otherwise, an attribute is created. Note that you cannot assign a simple array as it will be mistaken for a WML table and give an error. Assigning nil clears the variable.

wml.variables["my_unit.hitpoints"] = heros_hp + 10

wml.variables_proxy

  • wml.variables_proxy.variableproxy
  • wml.variables_proxy[variable_path] ↔ proxy

Similar to wml.variables, but if the variable is a container, then the fields of the returned table are then proxies to the WML objects with the same names; reading/writing to them will directly access the WML sub-variables. Note that this is still somewhat experimental and doesn't allow you to fully treat variables as if they were standard Lua tables.

wml.array_access.get

  • wml.array_access.get(var_name, [context]) → array of variable_contents

Fetches all the WML container variables with given name and returns a table containing them (starting at index 1). The context specifies where to get variables from. You can pass either a unit or a side as the context in order to get an array from the unit variables or side variables, respectively.

function get_recall_list(side)
    wesnoth.fire("store_unit", { x = "recall", variable = "LUA_recall_list" })
    local l = wml.array_access.get "LUA_recall_list"
    wml.variables.LUA_recall_list = nil
    return l
end

wml.array_access.get_proxy

  • wml.array_access.get_proxy(var_name) → array of proxies

Creates proxies for all the WML container variables with given name and returns a table containing them (starting at index 1). This function is similar to #wml.array_access.get, except that the proxies can be used for modifying WML containers. Note that changes to the returned array itself will not be reflected in the variable, however; only changes to the array elements.

wml.array_access.set

  • wml.array_access.set(varname, array, [context])

Creates WML container variables with given name from given table. The context specifies where to put the variables. You can pass either a unit or a side as the context in order to set an array in the unit variables or side variables, respectively.

wml.array_access.set("target", { {t=t1}, {t=t2}, {t=t3} })
-- target[0].t <- t1; target[1].t <- t2; target[2].t <- t3

wml.array_variables

  • wml.array_variables.variablearray of variable_contents
  • wml.array_variables[variable_path] ↔ array of variable_contents

Like wml.variables, except that it works on arrays as with wml.array_access.get and wml.array_access.set. This is a little more convenient when working with global WML variables rather than unit or side variables.

wml.eval_conditional

  • wml.eval_conditional(conditional_tags) → boolean

Returns true if the conditional described by the WML table passes. Note: WML variables are substituted.

local result = wml.eval_conditional {
  wml.tag.have_unit { id = "hero" },
  wml.tag.variable { name = "counter", numerical_equals = "$old_counter" }
}

Note: Prior to 1.15.13, this was available as wesnoth.eval_conditional.

wml.fire

Fire a WML action tag. Note: WML variables are substituted into the parameters table.

Note: Prior to 1.15.13, this was available as wesnoth.fire. The second form was available through helper.set_wml_action_metatable.

wml.error

  • wml.error(message)

Interrupts the current execution and displays a WML error message. This is intended for error messages in the implementaton of custom ActionWML or ConditionalWML tags. For errors in a Lua API, the built-in error function is a more suitable choice.

local names = cfg.name or wml.error("[clear_variable] missing required name= attribute.")
This page was last edited on 22 August 2024, at 05:26.