[UP]
The UI language
|
|
|
Bracket expressions $[...] Bracket expressions allow the UI developer to access dialog
variables from page or template definitions (i.e. everywhere the
dollar character is recognized as meta symbol). For example,
$[v] would expand to the current value of the dialog variable
v. Of course, this works only if this variable is a string
variable, as it would be unclear what to do with a non-string value
(e.g. an enumeration). So far, so simple. In recent versions of WDialog, the brackets
cannot only contain variable names but whole expressions that are
computed when the bracket is expanded. For instance, the expression
$[card(v)] expands to the number of words in the string v.
There are a number of functions that can be applied to
variables (see below). The syntax of function calls always includes
parantheses, so x is a variable, and x() is a function
call. Functions may have several arguments, separated by commas, e.g.
f(x1,x2,x3). Of course, the card function is not only reasonable for
strings. We can also define the cardinality of enumerator values, and of
associative lists. Because of this it is allowed to write
$[card(v)] when v is an enumerator or alist.
In general, the intermediate values during evaluation may be of any
type that can be stored in a dialog variable; however the final
value must be a string as the result is inserted into the XML
tree[1]. Typing is dynamic, and although the functions usually
only accept certain types as arguments it is not tried to verify
that by a type checker. It is not only possible to access variables, but also
template parameters. The dollar character must prefix the parameter
name, e.g. $[$p]. Braces are allowed, and even output encodings
can be specified: $[${p}] and $[${p/html}] are legal
expressions. The parameters are evaluated to strings (as if they
would occur in attribute context). A number of UI control elements
are expanded allowing one to mix template-level and dialog-level
evaluation strategies. For example, the template t2 expands
to the size of the expanded template t1:
<ui:template name="t1">
This is a text
</ui:template>
<ui:template name="t2" from-caller="which">
<ui:default param="which"><ui:use template="t1"/></ui:default>
$[card($which)]
</ui:template>
The expanded text is 4, the number of words in t1.
We have mentioned variables, functions, parameters. Is it
possible to include constant values into bracket expressions? Yes,
but the current implementation is quite limited. Numbers can be used
literally, e.g.
$[add(n,2)]. It is also possible to construct strings
of words using the words form, e.g. $[words(a,b,c)]
is the string "a b c". The words must be syntactically names.
It is not (yet) possible to include arbitrary
string constants or any non-string constants. These may be added
later. Another important syntactic note: Bracket expressions must
not contain white space! They are not even recognized by the parser if
they do. There are also some boolean functions. The value 0 is considered
as the false value, and numbers other than 0 are considered as true values. Now the list of functions that are defined by default: id(expr): Just returns expr (identity) length(str): Returns the number of characters of the
string str card(expr): If expr is a string, this
function returns the number of words. If expr is an enumerator
or associative list, this function returns the number of elements. This
definition of cardinality is just the same as that of ui:iterate.
size(expr): Deprecated! If expr is a string, this
function returns the number of characters. If expr is an enumerator
or associative list, this function returns the number of elements. add(num1,...,numN): Adds all the numbers passed
as arguments and returns the sum. sub(num1,...,numN): Subtracts the second and all
following arguments from the first argument, and returns the difference.
mul(num1,...,numN): Multiplies all the numbers
passed as arugments and returns the product. div(num1,...,numN): Divides the first number
through the second number and all following numbers (in turn), and
returns the quotient. modulo(num1,...,numN): Divides the first number
through the second number and takes the modulus, and continues with the following
numbers in turn, and returns the final modulus. assoc(alist,str): Looks up the str argument
in the associative list alist, and returns the value that corresponds
to the str key. Of course, str must be a string. It is an
error if str does not occur in alist. nth(alist,num): Returns the numth value
of the associative list alist, i.e. num is the ordinal
number of the value to return. The first value has the ordinal number
0. It is an error if num is greater or equal than the number of
elements of alist.
contains(container,str): Returns 1 if the first argument contains
the second argument, and 0 otherwise. The second argument must be a string value.
The function is defined as follows:
If the container is a string, it is split up into a list of words,
and it is tested whether str occurs in the list of words.
If the container is a declared enumerator, it is tested whether
the value includes str as item.
If the container is a dynamic enumerator, it is tested whether
the value includes str as internal item.
If the container is an associative list, it is tested whether
the value includes str as index. mentions(container,str): Returns 1 if the first argument contains
the second argument, and 0 otherwise. The second argument must be a string value.
The function is defined as follows:
If the container is a dynamic enumerator, it is tested whether
the value includes str as external item.
If the container is an associative list, it is tested whether
the value includes str as mapped value. translate(dynenum,str): Returns the external value
that corresponds to the internal value str in the dynamic enumerator
dynenum. It is an error if str does not occur as internal
value in dynenum.
translate(enum(name),str): Returns the external value
that corresponds to the internal value str in the declared enumerator
type name (i.e. the name in a ui:enumeration declaration).
It is an error if str does not occur as internal
value in the enumeration. See below for explanations of the enum
form.
rev-translate(dynenum,str): Returns the (first)
internal value
that corresponds to the external value str in the dynamic enumerator
dynenum. It is an error if str does not occur as external
value in dynenum.
rev-translate(enum(name),str): Returns the (first) internal
value
that corresponds to the external value str in the declared enumerator
type enum (i.e. the name in a ui:enumeration declaration).
It is an error if str does not occur as external
value in the enumeration. See below for explanations of the enum
form. eq(str1,str2): Returns 1 if both strings are equal, and 0
otherwise ne(str1,str2): Returns 1 if the strings are not equal, and 0
otherwise match(str1,str2): Returns 1 if the string str1
matches the regular expression str2, and 0 otherwise nomatch(str1,str2): Returns 1 if the string str1
does not match the regular expression str2, and 0 otherwise substring(str,num1): Returns the substring of str
starting at character position num1 until the end of the string.
substring(str,num1,num2): Returns the substring of
str starting at character position num1 with length
num2 (the length can be negative). concat(str1,...,strN): Concatenates the strings
str1 to strN. int-eq(num1,num2): Returns 1 if both numbers are equal, and 0
otherwise int-ne(num1,num2): Returns 1 if the numbers are not equal, and 0
otherwise int-lt(num1,num2): Returns 1 if num1 < num2, and 0
otherwise int-le(num1,num2): Returns 1 if num1 <= num2, and 0
otherwise int-gt(num1,num2): Returns 1 if num1 > num2, and 0
otherwise int-ge(num1,num2): Returns 1 if num1 >= num2, and 0
otherwise int-min(num,...): Returns the minimum of all passed numbers int-max(num,...): Returns the maximum of all passed numbers int-abs(num): Returns the absolute value int-sign(num): Returns the sign of the number card-eq(container,num),
card-ne(container,num),
card-lt(container,num),
card-le(container,num),
card-gt(container,num),
card-ge(container,num): These functions compare the cardinality
of container with the number. The cardinality is defined as for the card
function. height(str): Returns the number of lines the
string str consists of. A line is separated from the next one
by either LF, CR, or CRLF bytes. The number of lines is the number of
these line separators plus 1. width(str): Returns the number of characters the
longest line in string str consists of. The line separators are
not counted for the width. dialog_exists(dlg): Returns 1 if the dialog exists, 0
otherwise and(bool,...): Returns 1 if all arguments are non-zero
integers, and 0 otherwise. This function is evaluated lazily. or(bool,...): Returns 1 if there is a non-zero
integers as argument, and 0 otherwise. This function is evaluated lazily. not(bool): Returns 1 if the argument is 0, and 0 if
the argument is non-zero. true(): Returns 1 false(): Returns 0 if(bool,true_arg,false_arg): If bool is a non-zero
number, the value of true_arg is returned. If 0, the value of
false_arg is returned. This function is evaluated lazily. var(str): Returns the contents of the dialog
variable called str. (This function can be used to access variables
indirectly.)
dialog(): Returns the name of the current
dialog. self(): Returns the current dialog. page(): Returns the name of the current page. language(): Returns the current language,
or the empty string if none is selected. self-base-url(): Return the URL pointing to the current script
(omitting any URL parameters) session-id(): Returns the session ID without checksum create-anchor-event(str): Add the anchor event source called
str, and return the HTML-level identifier. create-xanchor-event(str1,str2): Add the anchor event source called
str1 for index str2, and return the HTML-level identifier.
Furthermore, there are the following special forms, i.e. syntactic
elements evaluated in a special way: type(var): Returns the name of the type of the
variable var. The argument is not expanded before
evaluation of the form, but taken literally, e.g.
type(x) returns the type of the variable x,
and not the type of the variable whose name is stored in
the variable x. The return value is a string: "string" is the type name of string variables "dialog" is the type name of dialog variables "dynamic-enumerator" is the type name of
dynamic enumerator variables The name of the enumeration is the type name of
enumerator variables
The type name is what the ui:variable
element declares with the type argument. It does not matter whether the variable is associative
or not. is-associative(var): Returns whether the type
of the variable var is associative or not.
Like the type form, the argument is taken literally.
The return value is either the string "yes" or
"no".
default(var): Returns the default value used to
initialize the variable var when the dialog object
is created. Like the type form, the argument is taken
literally. The return value is a value of appropriate type.
enum(name): Returns the declaration of the
enumeration enum as a dynamically enumerated
value. The argument is taken literally. words(name,...): Returns the string containing the
names literally (i.e. the concatenated names separated by
spaces). The arguments are taken literally.
Numbers are represented as decimal strings. As strings can contain multi-byte characters, the question arises
whether the string functions take the number of bytes or the number
of characters as "position" or "length". Of course, characters are counted,
so the user does not have to take care of the character encoding.
- [1]
- It may be possible to also allow XML tree types here,
but such types do not occur in the rest of the UI language. This is
an interesting idea for a future extension of the language, though.
|