Difference between revisions of "SchemaWML"
(→Defining a tag: Clarify what can go in a conditional tag section) |
(→Defining a type: Document allow_translatable) |
||
(9 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | SchemaWML is a way of describing the form of a WML document using WML. A WML schema consists of a root '''[wml_schema]''' tag containing a single '''[tag]''' tag and possibly some '''[type]''' tags. | + | [[Category:Validation]] |
+ | {{WML Tags}} | ||
+ | SchemaWML is a way of describing the form of a WML document using WML. A WML schema consists of a root '''[wml_schema]''' tag containing a single '''[tag]''' tag and possibly some '''[type]''' tags. The [[ValidationFAQ]] describes how to run the corresponding tool. | ||
== Defining a type == | == Defining a type == | ||
Line 7: | Line 9: | ||
* '''name''': The name of the type, to be referenced from elsewhere in the schema. | * '''name''': The name of the type, to be referenced from elsewhere in the schema. | ||
* '''value''': A regular expression that matches the type. Note that anchors (<tt>^</tt> and <tt>$</tt>) are not automatically added, so the expression will match if it can match any substring of the key's value. {{DevFeature1.15|0}} Regular expressions are now anchored. To obtain the previous behaviour, add <tt>.*</tt> at the beginning and end of the expression. | * '''value''': A regular expression that matches the type. Note that anchors (<tt>^</tt> and <tt>$</tt>) are not automatically added, so the expression will match if it can match any substring of the key's value. {{DevFeature1.15|0}} Regular expressions are now anchored. To obtain the previous behaviour, add <tt>.*</tt> at the beginning and end of the expression. | ||
+ | * '''allow_translatable''': {{DevFeature1.15|15}} Most types (other than '''t_string''') are required to be non-translatable. By setting '''allow_translatable''' to true, the type is permitted (but not required) to be translatable. This key can only be used together with '''value'''. | ||
* '''link''': {{DevFeature1.15|0}} Use instead of '''value''' to define an alias for another type. The value of '''link''' must name another defined type. | * '''link''': {{DevFeature1.15|0}} Use instead of '''value''' to define an alias for another type. The value of '''link''' must name another defined type. | ||
* '''[union]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a type as a union of one or more other types. It contains one or more '''[type]''' subtags, without the '''name''' key. The union type matches any value that matches one of the subtypes. | * '''[union]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a type as a union of one or more other types. It contains one or more '''[type]''' subtags, without the '''name''' key. The union type matches any value that matches one of the subtypes. | ||
− | * '''[intersection]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a type as an intersection of one or more other types. It contains one or more '''[type]''' subtags, without the '''name''' key. The | + | * '''[intersection]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a type as an intersection of one or more other types. It contains one or more '''[type]''' subtags, without the '''name''' key. The intersection type matches only values that match ''all'' of the subtypes. |
* '''[list]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a list type. Supports the following additional keys and tags: | * '''[list]''': {{DevFeature1.15|0}} Use instead of '''value''' to define a list type. Supports the following additional keys and tags: | ||
** '''min''': The minimum number of list elements | ** '''min''': The minimum number of list elements | ||
** '''max''': The maximum number of list elements | ** '''max''': The maximum number of list elements | ||
** '''split''': A regular expression used to split the key value up into list elements; defaults to <tt>\s*,\s*</tt>. | ** '''split''': A regular expression used to split the key value up into list elements; defaults to <tt>\s*,\s*</tt>. | ||
− | ** '''[element]''': One or more of these tags is required; they are equivalent to the '''[type]''' subtags in '''[union]''' and '''[intersection]''', and specify possible types for the list elements. Each list element must match at | + | ** '''[element]''': One or more of these tags is required; they are equivalent to the '''[type]''' subtags in '''[union]''' and '''[intersection]''', and specify possible types for the list elements. Each list element must match at least one of these subtypes for the whole list to match. |
+ | |||
+ | ===Finding the definition of a type=== | ||
+ | |||
+ | SchemaWML is run through the usual WML preprocessor, and some of the frequently-used types' definitions are created with macros, therefore a search for a type's name won't find its definition. | ||
+ | |||
+ | Several types with names beginning '''s_''' created with the '''SUBST_TYPE''' macro, which accepts any value that includes a WML variable substitution. For example '''x,y=$Chantal.x,$Chantal.y''' validates by assuming that the WML variables contain valid values. Similarly, types with names beginning '''f_''' are usually created with the '''FORMULA_TYPE''' macro, which accepts any value enclose in parentheses (assumed to be [[Wesnoth Formula Language]]) in addition to the base type. | ||
+ | |||
+ | Types with names ending '''_list''' might use one of the '''LIST_TYPE''' macros. | ||
+ | |||
+ | For example, to find the definition of '''s_range_list''': | ||
+ | * s_range_list is defined by '''{SUBST_TYPE range_list}''' | ||
+ | * range_list is defined by '''{LIST_TYPE_COMPLEX range ( ...''' | ||
+ | * to find the definition, try '''git grep 'LIST_TYPE.*range' data/schema''' | ||
+ | |||
+ | {{DevFeature1.15|14}} Additionally, t_string is a built-in type, so there is no WML definition. It can match either an empty string or a string with a translation mark. | ||
== Defining a tag == | == Defining a tag == | ||
Line 27: | Line 45: | ||
* '''min''': The minimum number of times this tag may occur. {{DevFeature1.15|0}} Defaults to 0. | * '''min''': The minimum number of times this tag may occur. {{DevFeature1.15|0}} Defaults to 0. | ||
* '''max''': The maximum number of times this tag may occur. Specify -1 if it may occur an unlimited number of times. {{DevFeature1.15|0}} Defaults to 1. Also, you can now use '''infinite''' instead of -1. | * '''max''': The maximum number of times this tag may occur. Specify -1 if it may occur an unlimited number of times. {{DevFeature1.15|0}} Defaults to 1. Also, you can now use '''infinite''' instead of -1. | ||
− | * '''super''': The path to a defined tag that is used as a starting point for this tag. That is, anything defined in the supertag is also allowed in this tag. Note that '''min''' and ''' | + | * '''min_tags''': {{DevFeature1.15|7}} The minimum number of subtags this tag must have, regardless of the tag name. Defaults to 0. |
+ | * '''max_tags''': {{DevFeature1.15|7}} The maximum number of subtags this tag may have, regardless of the tag name. Can be a number or the special string '''infinite''', which is the default. | ||
+ | * '''super''': The path to a defined tag that is used as a starting point for this tag. That is, anything defined in the supertag is also allowed in this tag. Note that '''min''', '''max''', '''min_tags''', and '''max_tags''' are ''not'' inherited from the parent tag, though '''any_tag''' is. {{DevFeature1.15|0}} This can also be a comma-separated list of paths, supporting multiple inheritance of tag definitions. | ||
* '''any_tag''': {{DevFeature1.15|0}} If set to '''true''', this tag will accept any subtag without error. Known subtags that match a tag definition will be validated as normal; unknown subtags will simply be ignored. | * '''any_tag''': {{DevFeature1.15|0}} If set to '''true''', this tag will accept any subtag without error. Known subtags that match a tag definition will be validated as normal; unknown subtags will simply be ignored. | ||
* '''deprecated''': {{DevFeature1.15|0}} Set to '''true''' to mark the tag as deprecated. A warning will be issued if it is used. | * '''deprecated''': {{DevFeature1.15|0}} Set to '''true''' to mark the tag as deprecated. A warning will be issued if it is used. |
Latest revision as of 06:16, 20 June 2021
SchemaWML is a way of describing the form of a WML document using WML. A WML schema consists of a root [wml_schema] tag containing a single [tag] tag and possibly some [type] tags. The ValidationFAQ describes how to run the corresponding tool.
Defining a type
A type in SchemaWML is defined by the [type] tag. Types are used to validate the values of WML keys. The [type] tag supports the following keys and subtags:
- name: The name of the type, to be referenced from elsewhere in the schema.
- value: A regular expression that matches the type. Note that anchors (^ and $) are not automatically added, so the expression will match if it can match any substring of the key's value. (Version 1.15.0 and later only) Regular expressions are now anchored. To obtain the previous behaviour, add .* at the beginning and end of the expression.
- allow_translatable: (Version 1.15.15 and later only) Most types (other than t_string) are required to be non-translatable. By setting allow_translatable to true, the type is permitted (but not required) to be translatable. This key can only be used together with value.
- link: (Version 1.15.0 and later only) Use instead of value to define an alias for another type. The value of link must name another defined type.
- [union]: (Version 1.15.0 and later only) Use instead of value to define a type as a union of one or more other types. It contains one or more [type] subtags, without the name key. The union type matches any value that matches one of the subtypes.
- [intersection]: (Version 1.15.0 and later only) Use instead of value to define a type as an intersection of one or more other types. It contains one or more [type] subtags, without the name key. The intersection type matches only values that match all of the subtypes.
- [list]: (Version 1.15.0 and later only) Use instead of value to define a list type. Supports the following additional keys and tags:
- min: The minimum number of list elements
- max: The maximum number of list elements
- split: A regular expression used to split the key value up into list elements; defaults to \s*,\s*.
- [element]: One or more of these tags is required; they are equivalent to the [type] subtags in [union] and [intersection], and specify possible types for the list elements. Each list element must match at least one of these subtypes for the whole list to match.
Finding the definition of a type
SchemaWML is run through the usual WML preprocessor, and some of the frequently-used types' definitions are created with macros, therefore a search for a type's name won't find its definition.
Several types with names beginning s_ created with the SUBST_TYPE macro, which accepts any value that includes a WML variable substitution. For example x,y=$Chantal.x,$Chantal.y validates by assuming that the WML variables contain valid values. Similarly, types with names beginning f_ are usually created with the FORMULA_TYPE macro, which accepts any value enclose in parentheses (assumed to be Wesnoth Formula Language) in addition to the base type.
Types with names ending _list might use one of the LIST_TYPE macros.
For example, to find the definition of s_range_list:
- s_range_list is defined by {SUBST_TYPE range_list}
- range_list is defined by {LIST_TYPE_COMPLEX range ( ...
- to find the definition, try git grep 'LIST_TYPE.*range' data/schema
(Version 1.15.14 and later only) Additionally, t_string is a built-in type, so there is no WML definition. It can match either an empty string or a string with a translation mark.
Defining a tag
The [tag] tag defines a single WML tag that is allowed in a particular context. All WML schemas have at least one tag, the "root" tag; this represents the root level of the WML document and is not actually a real tag.
Each tag can be uniquely referenced by a path, which consists of a sequence of tag names (as specified in the name key) separated by slashes. The initial "root" tag is omitted from the path.
Tags support the following keys and subtags:
- name: The name of the tag; should be "root" for the root tag. (Version 1.15.0 and later only) Supports glob syntax, which allows a single [tag] to match multiple actual tags. Also note that the name does not need to be a valid tag name - if it's not a valid tag name, it will never match any tags in the document, but can still be referenced by other tag definitions.
- min: The minimum number of times this tag may occur. (Version 1.15.0 and later only) Defaults to 0.
- max: The maximum number of times this tag may occur. Specify -1 if it may occur an unlimited number of times. (Version 1.15.0 and later only) Defaults to 1. Also, you can now use infinite instead of -1.
- min_tags: (Version 1.15.7 and later only) The minimum number of subtags this tag must have, regardless of the tag name. Defaults to 0.
- max_tags: (Version 1.15.7 and later only) The maximum number of subtags this tag may have, regardless of the tag name. Can be a number or the special string infinite, which is the default.
- super: The path to a defined tag that is used as a starting point for this tag. That is, anything defined in the supertag is also allowed in this tag. Note that min, max, min_tags, and max_tags are not inherited from the parent tag, though any_tag is. (Version 1.15.0 and later only) This can also be a comma-separated list of paths, supporting multiple inheritance of tag definitions.
- any_tag: (Version 1.15.0 and later only) If set to true, this tag will accept any subtag without error. Known subtags that match a tag definition will be validated as normal; unknown subtags will simply be ignored.
- deprecated: (Version 1.15.0 and later only) Set to true to mark the tag as deprecated. A warning will be issued if it is used.
- [tag]: Define a subtag.
- [key]: Define a key. See below.
- [switch]: (Version 1.15.0 and later only) Sometimes the allowed content of a tag may be governed by the value of one particular key in the tag. That's what a [switch] tag is for. It supports the following keys and subtags:
- key: The key whose value is checked to determine which branch to take.
- [case]: Defines a single branch of the switch.
- value: The value or values (a comma-separated list) that cause this branch to match. Note that cases are considered in order of appearance.
- trigger_if_missing: If true, this case also matches if the key is absent. If no case includes this, the [else] tag matches when the key is absent.
- Anything that is allowed in [tag] is allowed in [case], including another [switch]. Note that tags defined inside a [switch] do not have a path and thus cannot be referenced from elsewhere, not even by other tags in the same [switch]. Note that the min and max keys, although accepted, have no effect here. Both super and any_tag keys may be conditionally applied, though.
- [else]: A switch may have one of these, which matches if none of the cases match. Other than the lack of value and trigger_if_missing keys, and the fact that there can be only one, this is equivalent to [case].
- [if]: (Version 1.15.0 and later only) Sometimes the allowed content of a tag may depend on some subset of its content. That's what an [if] tag is for - it runs a [filter_wml] on the tag being validated and uses the outcome to determine what else is allowed in that tag.
- The same syntax as [filter_wml] is supported.
- [then]: Contains tag contents (same as in [else]) that will be used if the filter matches. This can also be omitted if needed.
- [elseif]: Adds another filter to test if the first fails. You can use more than one of these. Each one requires a [then] tag in addition to the filter.
- [else]: Contains tag contents to be used if none of the filters match
If you want to include an existing tag definition verbatim with no changes, including inheriting the min and max attributes, you can use the [link] tag instead of [tag]. It accepts just one key, name, which must be the path to the parent tag.
Defining a key
The [key] tag defines an allowed key that can occur in the current context. It supports the following keys:
- name: The name of the key. (Version 1.15.0 and later only) Supports glob syntax, allowing a single [key] definition to match multiple actual keys.
- type: The type of the key. Must reference a valid type defined elsewhere in the document. (Version 1.15.0 and later only) This can also be a comma-separated list of types, in which case the key value may match any one of the referenced types.
- mandatory: If set to true, this key is required, and an error will be raised if it is missing.
- default: Contains the default value for this key. Note that this must match the key's type. Mutually exclusive with mandatory.
- deprecated: (Version 1.15.0 and later only) Set to true to mark the key as deprecated. A warning will be issued if it is used.