# substitution

Before a macro body or arguments to /eval are executed, special character sequences are replaced with new text as described below.

## Command separation.
%;

Separates commands within a macro body. See evaluation.

## Pipe.
%|

Separates commands within a macro body, and connects the output of the first to the input of the second. See evaluation.

## Character substitution.
\n
\c

In the first form, the character whose ASCII code is n is substituted. If n starts with "0x", it is interpreted as a hexadecimal number; otherwise, if n starts with "0", it is interpreted as octal; otherwise, it is interpreted as decimal. In the second form, the character c is substituted. This is useful for escaping any special meaning c has; in particular, "\\" is substituted with "\". If the variable %{backslash} is off, the \c form does not have this special interpretation.

## Slash compression.
//...

If %{oldslash} is on, sequences of slashes are replaced with a sequence of one fewer slashes. A single slash, however, is left alone. This feature remains for backward compatibility only; you are encouraged to turn %{oldslash} off to disable this.

## Expression evaluation.
$[expression]

The expression is evaluated and its string value is substituted in its place. See "expressions".

## Command substitution.
$(command)

Command is evaluated as if it were the body of a macro: it goes through substitution, and is executed in a new scope. If command contains any ')' characters, they must be escaped by preceding them with '\' so they are not interpreted as the end of the substitution. The echoed output of command is substituted in place of the $(...) construct (much like `...` in most shells). If command produces more than one line of output, they will be concatenated, with a space between each, to form one line.

Example:

    	/def showver = :is using tf version $(/ver)

could be used to tell other mudders what version of tf you're using.

## Macro substitution.
${name}
$name$

The body of the macro name is substituted. The second form is supported only for backward compatibility, and its use is discouraged. In the first form, the brackets may be omitted if the subsequent text could not be confused as part of the name.

Example: The text "`${foo}`" would be replaced with the body of the macro named "foo".

## Dollar compression.
$$...

Sequences of '$'s are replaced by a sequence of one fewer '$'s. A single '$', however, is left alone, unless it introduces one of the substitutions described above. This is used to put a literal '$' in text that goes through macro substitution.

## Variable and Argument substitution.
%selector
%{selector}
%{selector-default}

The value of a variable or an argument to the macro is substituted, as determined by selector. The brackets are recommended for clarity, but may be omitted if there is no default and the text following it can not be misinterpreted as part of the selector. The selector can be any of:

name
  The value of the variable name is substituted. Names are case sensitive.

0
  selects the name of the executing macro. (Before version 4.0, "0" was equivalent to "*").

#
  selects the count of positional parameters.

*
  selects all positional parameters.

?
  selects the return value of the most recently executed command (builtin or macro).

1, 2, 3, etc.
  selects the corresponding positional parameter. There is no maximum parameter number; any number greater than %{#} will simply produce an empty substitution.

-1, -2, -3, etc.
  selects all positional parameters except the first, all except the first two, all except the first three, etc.

L1, L2, etc.
  selects the last positional parameter, second-to-last, etc. "L" is the same as "L1".

-L1, -L2, etc.
  selects all positional parameters except the last, all except the last two, etc. "-L" is the same as "-L1".

Pn
  selects the text matching the nth parenthesized subexpression from the last regular expression match. See %Pn.

R
  selects a positional parameter at random. (see also: rand())

Variable names are case sensitive; "L", "R", and "P" selectors are not. No substitutions are performed on selector.

If the substitution determined by the selector would be empty, and a default value is given, the default will be substituted instead. Thus "%{1-foofle}" is replaced with the first word if there is one, or "foofle" if not. The default value may contain variable, macro, expression, and command substitutions.

The meaning of "positional parameters" depends on how the macro was called. If called with the traditional "`/name ...`" command syntax, each space-separated word is a positional parameter. If called with the "`name(...)`" function syntax, each function argument is a positional parameter; if more than one is selected, they are concatenated, with a space between each. If called as a trigger, the positional parameters are the words in the text that triggered the macro. In a hook call, the positional parameters are the hook arguments. In an /eval statement, they are inherited from the caller.

Note that in expressions, it is easiest to omit the % and just use the {selector[-default]} part. If the selector is a variable name and no default is desired, the name may be used directly in an expressions without % or {...}.

## Regexp subexpressions.
%{Pn}
%{PL}
%{PR}

This is actually a special case of variable substitution. The %P variables get their values from the last successful regexp match in scope. %P0 expands to the text matched by the entire regexp. %Pn expands to the text matched by the nth parenthesised subexpression of the regexp. %PL and %PR expand to the text to the left and right, respectively, of the text matched by the entire regexp. The "scope" of a regexp match is the lifetime of the macro expansion it triggered, hooked, or in which it occurred (i.e., with regmatch()).

For example, after the text "Jabba the Hutt goes east." matches the regexp

      " goes ([^ ]*)\.$"

then the following expansions will be available until the macro exits: PL = "Jabba the Hutt"; P0 = " goes east."; P1 = "east".

The number n can be any nonnegative number. If there is no subexpression corresponding to n, the substitution will be ignored. When parentheses are nested, n refers to the order of the opening parentheses.

The %Pn subs will always refer to the first regexp match on the line, even if a partial hilite (/def -P) causes the regexp to be applied more than once.

## Percent compression.
%%...

Sequences of '%'s are replaced by a sequence of one fewer '%'s. A single '%', however, is left alone unless it introduces one of the substitutions described above. This is used to put a literal '%' in text that goes through macro substitution.

## Examples

Here are a couple of simple examples.

Definition: `/def advice = whisper %1 = Let the wookie win.`
Command: `/advice R2D2`
Sends: `whisper R2D2 = Let the wookie win.`

Definition: `/set ending=meister`
Definition: `/def greet = :waves to %{1-Jack}%{ending}.`
Command: `/greet`
Sends: `:waves to Jackmeister.`
Command: `/greet Dave`
Sends: `:waves to Davemeister.`

For some more complex examples, look at the files in TFLIBDIR.

See: evaluation, expressions

Back to index
Back to tf home page

Copyright © 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004 Ken Keys