gtroff has string variables, which are entirely for user
convenience (i.e. there are no built-in strings exept
even this is a read-write string variable).
Although the following requests can be used to create strings, simply using an undefined string will cause it to be defined as empty. See Identifiers.
Define and access a string variable name (one-character name n, two-character name nm). If name already exists,
dsoverwrites the previous definition. Only the syntax form using brackets can take arguments which are handled identically to macro arguments; the single exception is that a closing bracket as an argument must be enclosed in double quotes. See Request and Macro Arguments, and Parameters.
Example:.ds foo a \\$1 test . This is \*[foo nice]. ⇒ This is a nice test.
\*escape interpolates (expands in-place) a previously-defined string variable. To be more precise, the stored string is pushed onto the input stack which is then parsed by
gtroff. Similar to number registers, it is possible to nest strings, i.e., string variables can be called within string variables.
If the string named by the
\*escape does not exist, it is defined as empty, and a warning of type ‘mac’ is emitted (see Debugging, for more details).
Caution: Unlike other requests, the second argument to the
dsrequest takes up the entire line including trailing spaces. This means that comments on a line with such a request can introduce unwanted space into a string..ds UX \s-1UNIX\s0\u\s-3tm\s0\d \" UNIX trademark
Instead the comment should be put on another line or have the comment escape adjacent with the end of the string..ds UX \s-1UNIX\s0\u\s-3tm\s0\d\" UNIX trademark.ds sign " Yours in a white wine sauce,.ds foo lots and lots \ of text are on these \ next several lines
It is not possible to have real newlines in a string. To put a single double quote character into a string, use two consecutive double quote characters.
ds1request turns off compatibility mode while interpreting a string. To be more precise, a compatibility save input token is inserted at the beginning of the string, and a compatibility restore input token at the end..nr xxx 12345 .ds aa The value of xxx is \\n[xxx]. .ds1 bb The value of xxx ix \\n[xxx]. . .cp 1 . \*(aa ⇒ warning: number register `[' not defined ⇒ The value of xxx is 0xxx]. \*(bb ⇒ The value of xxx ix 12345.
Strings, macros, and diversions (and boxes) share the same name space. Internally, even the same mechanism is used to store them. This has some interesting consequences. For example, it is possible to call a macro with string syntax and vice versa..de xxx a funny test. .. This is \*[xxx] ⇒ This is a funny test. .ds yyy a funny test This is .yyy ⇒ This is a funny test.
In particular, interpolating a string does not hide existing macro arguments. Thus in a macro, a more efficient way of doing.xx \\$@
Note that the latter calling syntax doesn't change the value of
\$0, which is then inherited from the calling macro.
Diversions and boxes can be also called with string syntax.
Another consequence is that you can copy one-line diversions or boxes to a string..di xxx a \fItest\fR .br .di .ds yyy This is \*[xxx]\c \*[yyy]. ⇒ This is a test.
As the previous example shows, it is possible to store formatted output in strings. The
\cescape prevents the insertion of an additional blank line in the output.
Copying diversions longer than a single output line produces unexpected results..di xxx a funny .br test .br .di .ds yyy This is \*[xxx]\c \*[yyy]. ⇒ test This is a funny.
Usually, it is not predictable whether a diversion contains one or more output lines, so this mechanism should be avoided. With UNIX
troff, this was the only solution to strip off a final newline from a diversion. Another disadvantage is that the spaces in the copied string are already formatted, making them unstretchable. This can cause ugly results..box xxx a funny .br test .br .box .chop xxx .unformat xxx This is \*[xxx]. ⇒ This is a funny test.
See Gtroff Internals, for more information.
.as sign " with shallots, onions and garlic,
as1request is similar to
as, but compatibility mode is switched off while the appended string is interpreted. To be more precise, a compatibility save input token is inserted at the beginning of the appended string, and a compatibility restore input token at the end.
Rudimentary string manipulation routines are given with the next two requests.
Replace the string named str with the substring defined by the indices n1 and n2. The first character in the string has index 0. If n2 is omitted, it is taken to be equal to the string's length. If the index value n1 or n2 is negative, it is counted from the end of the string, going backwards: The last character has index −1, the character before the last character has index −2, etc..ds xxx abcdefgh .substring xxx 1 -4 \*[xxx] ⇒ bcde
.ds xxx abcd\h'3i'efgh .length yyy \*[xxx] \n[yyy] ⇒ 14
Create an alias named new for the request, string, macro, or diversion object named old. The new name and the old name are exactly equivalent (it is similar to a hard rather than a soft link). If old is undefined,
gtroffgenerates a warning of type ‘mac’ and ignores the request.
To understand how the
alsrequest works it is probably best to think of two different pools: one pool for objects (macros, strings, etc.), and another one for names. As soon as an object is defined,
gtroffadds it to the object pool, adds its name to the name pool, and creates a link between them. When
alscreates an alias, it adds a new name to the name pool which gets linked to the same object as the old name.
Now consider this example..de foo .. . .als bar foo . .de bar . foo .. . .bar ⇒ input stack limit exceeded
The definition of macro
barreplaces the old object this name is linked to. However, the alias to
foois still active! In other words,
foois still linked to the same object as
bar, and the result of calling
baris an infinite, recursive loop which finally leads to an error.
Remove (chop) the last character from the macro, string, or diversion named xx. This is useful for removing the newline from the end of diversions that are to be interpolated as strings. This command can be used repeatedly; see Gtroff Internals, for details on nodes inserted additionally by
See Identifiers, and Comments.