Macro primitives

Macros can be used to define new tags and to build procedural abstractions in style files.

Older versions of TeXmacs used to make a distinction between macros (all children accessible) and functions (no accessible child). In modern TeXmacs there are only macros: the accessibility of children is determined heuristically and can be controlled with drd-props.

<macro|var-1||var-n|body>
(macro of fixed arity)

This primitive returns a macro (the TeXmacs analogue of a λ-expression) with n arguments, named after the literal strings var-1 until var-n.

New tags are defined by storing macros in the environment. Most of the time, macros are stored without scope with assign, but it is sometimes useful to redefine a tag locally within the scope of a with. For example, itemized and enumerated environment redefine item locally.

Example 1. Definition of the abbr tag

<assign|abbr|<macro|x|<group|x>>>

Storing a macro in the environment defines a tag whose arity is fixed to the number of arguments taken by the macro.

<arg|var|index-1||index-n>
(retrieve macro arguments)

This primitive is used to retrieve the arguments of a macro within its body. For instance, <arg|var> expands the content of the macro argument with name arg (literal string). Of course, this argument must be defined by a macro containing the arg tag.

This tag is similar to value, but differs in important ways:

When more than one arguments are specified, <arg|var|index-1||index-n> expands to a subtree of the argument var. The value of the named argument must be a compound tree (not a string). The operands var until index-n must all evaluate to positive integers and give the path to the subtree of the macro argument.

<xmacro|var|body>
(macro with a variable arity)

This primitive returns a macro (the TeXmacs analogue of a λ-expression) capable of taking any number of arguments. The arguments are stored in the macro variable with name var (a literal string) during the evaluation of the body. The i-th individual argument can then be accessed using <arg|var|i>.

<map-args|foo|root|var>

<map-args|foo|root|var|first>

<map-args|foo|root|var|first|last>
(map a tag on subtrees of an argument)

This primitive evaluates to a tree whose root is labeled by root and whose children are the result of applying the macro foo to the children of the macro argument with name var.

By default, the macro foo is applied to all children. If first has been specified, then we rather start at the i-th child of var, where i is the result of evaluating first. If last has been specified to, then we stop at the j-th child of var (the j-th child not being included), where j is the result of evaluating last. In this last case, the arity of the returned tree is therefore j - i.

Stated otherwise, map-args applies foo to all subtrees of the macro argument var (or a range of subtrees if first and last are specified) and collect the result in a tree with label root. In addition, the second argument to foo gives its position of the first argument in the expansion of var.

The map-args is analogue to the Scheme function map. Since TeXmacs use labeled trees, the label of the mapping list must also be specified.

Example 2. Comma-separated lists.

The comma-separated tag has any arity (though it does not make much sense with arity zero) and typeset its operands interspersed with commas.

<assign|comma-extra|<macro|x|, x>>

< assign | comma-separated | < xmacro | args |

<\concat|

<arg|args|0>

|

<map-args|comma-extra|concat|args|1>

>

> >

<eval-args|var>
(macro with a variable arity)

This primitive evaluates to the tree with the same label as the expansion of the argument var and whose subtrees are the result of the evaluation of the subtrees of the expansion of var.

<compound|foo|arg-1||arg-n>
(expand an unnamed macro)

This primitive is useful to expand macros which are the result of a computation: it applies the macro which is the result of the evaluation of foo to the arguments arg-1 until arg-n. The compound primitive is useful in call-back and lambda programming idioms, where a higher-level macro is given a macro as an operand, which it may later apply under certain conditions or with operands which are not known the client code.

Actually, in the current implementation, foo may either evaluate to a macro or to a literal string which gives the name of a macro. However, we discourage users to rely on the second case.

Example 3. Lambda programming with macros.

In the code below, <filter|pred|t> expects a macro pred and a tuple t on input and returns a tuple containing the elements of t for which pred evaluates to true.

< assign | filter | < macro | pred | t |

<\if|

<equal|<length|t>|0>

|

<tuple>

|

<\merge|

<\if|

<compound|pred|<look-up|t|0>>

|

<tuple|<look-up|t|0>>

|

<tuple>

>

|

<filter|pred|<range|t|1|<length|t>>>

>

>

> >

As an application, we may define a macro <evens|t>, which expects t to be a tuple containing integers, and which returns the tuple of integers in t which are divisible by 2.

<assign|evens|<macro|t|<filter|<macro|x|<equal|<mod|x|2>|0>>|t>>>

<drd-props|var|prop-1|val-1||prop-n|val-n>
(set D.R.D. properties of a tag)

The arity and children accessibility of tags defined by macros are determined heuristically by default. The drd-props primitive overrides this default for the environment variable (usually a macro) with name var. The currently supported property-value pairs are:

(arity, n)
Sets the arity to the given fixed value n (literal integer).
(accessible, all)
Make it impossible to deactivate the tag with normal editor actions. Inaccessible children become effectively uneditable.
(accessible, none)
Make it impossible to position the caret within the tag when it is active, so children can only be edited when the tag is inactive.

<get-label|expression>
(label of an expression)

Returns the label of the tree obtained when evaluating expression.

<get-arity|expression>
(arity of an expression)

Returns the label of the tree obtained when evaluating expression.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".