Next: Conditionals and Loops, Previous: Colors, Up: GNU troff Reference [Contents][Index]
GNU
troff supports strings primarily for user convenience.
Conventionally,
if one would define a macro only to interpolate a small amount of text,
without invoking requests or calling any other macros,
one defines a string instead.
The language prefedines only one string.
Contains the name of the output device (for example, ‘utf8’ or ‘pdf’).
The
ds
request creates a string with a specified name and contents,
as
appends to a string,
and the
\*
escape sequence dereferences a string,
interpolating its contents.
If the string named by the
\*
escape sequence does not exist,
the formatter defines it as empty
and interpolates nothing.233
"]contents]"]contents]Define a string called
name
with contents
contents.
In
GNU
troff, if
name
already exists as an alias,
the request replaces the contents of the alias’s target;
see
als
and
rm
below.
Omitting
contents
defines
name
as an empty string.
Otherwise,
the formatter reads
contents
in copy mode.
\*
is itself interpreted even in copy mode.234
The
\*
escape sequence interpolates a previously defined string
name
(one-character name n,
two-character name
nm).
Its bracketed interpolation form accepts arguments
that are handled as macro arguments are;
recall Calling Macros.
In contrast to macro calls,
however,
if a closing bracket
‘]’
occurs in a string argument,
that argument must be enclosed in double quotes.
When defining strings,
argument interpolations must be escaped
if they are to reference parameters
from the calling context.235
.ds cite (\\$1, \\$2)
Gray codes are explored in \*[cite Morgan 1998].
⇒ Gray codes are explored in (Morgan, 1998).
Caution: After the formatter has read the space character that ends the first argument, it treats the remainder of the input line as the second argument, including any spaces, up to a newline or comment escape sequence. Ending string definitions (and appendments) with a comment, even an empty one, prevents unwanted space from creeping into them during source document maintenance.
.ds Si silicon \" use chemical symbol
My tricorder indicates a \*[Si]-based life form.
⇒ My tricorder indicates a silicon -based life form.
Instead, place the comment on another line or put the comment escape sequence immediately adjacent to the last character of the string.
.ds Si silicon\" use chemical symbol
My tricorder indicates a \*[Si]-based life form.
⇒ My tricorder indicates a silicon-based life form.
Because the first space after the string name separates the arguments, you can retain it while using a comment to document an empty string.
.ds author Alice Pleasance Liddell\" .ds friends \" empty; append to with .as
The formatter removes a leading neutral double quote
‘"’
from
contents,
permitting initial embedded spaces in it.
It interprets any other
‘"’
literally,
but the wise author uses the special character escape sequence
\[dq]
instead if the string
might be interpolated as part of a macro argument;
recall Calling Macros.
.ds salutation " Yours in a white wine sauce,\" .ds c-var-defn " char mydate[]=\[dq]2020-07-29\[dq];\"
Strings are not limited to a single input line of text.
\RET
works just as it does elsewhere.
The resulting string is stored
without
the newlines.
When filling is disabled,
care is required to avoid oversetting the line
when interpolating strings.
.ds foo This string contains \ text on multiple lines \ of input.
Conversely,
when filling is enabled,
it is not necessary to append
\c
to a string interpolation to prevent a break afterward,
as might be required in a macro argument.
Nor does a string require use of
GNU
troff’s chop
request to excise a trailing newline
as is often done with diversions.236
It is not possible to embed a newline in a string
that the formatter interprets as such when interpolating it.
To achieve that effect,
use
\*
to interpolate a macro instead.237
Because strings are similar to macros,
they too can be defined so as to suppress AT&T
troff compatibility mode when used.238
The ds1
request defines a string such that compatibility mode is off when the
string is later interpolated.
To be more precise,
GNU
troff inserts a
compatibility save
token at the beginning of
contents,
and a
compatibility restore
token at the end.239
.nr xxx 12345
.ds aa The value of xxx is \\n[xxx].
.ds1 bb The value of xxx is \\n[xxx].
.
.cp 1
.
\*(aa
error→ warning: register '[' not defined
⇒ The value of xxx is 0xxx].
\*(bb
⇒ The value of xxx is 12345.
"]contents]"]contents]The
as
request is similar to
ds,
but appends
contents
to the string stored as
name
instead of repopulating it.
If
name
does not already exist,
the formatter creates it.
Omitting
contents
performs no operation,
beyond dereferencing
(and thus possibly creating)
the string.
.as salutation " with shallots, onions and garlic,\"
Caution:
The formatter reads the second argument to the end of the line
in copy mode,
omitting any leading neutral double quote
‘"’
character.
See the discussion of the
ds
request above.
The as1 request works as does as, but like ds1, it
brackets contents with compatibility save and
restore tokens.
Several requests exist to perform rudimentary string operations.
Strings can be queried (length) and modified (chop,
substring, stringup, stringdown), and their names
can be manipulated through renaming, removal, and aliasing (rn,
rm, als).
"]contents]Compute the number of characters in
contents
and store the count in the register
reg.
If
reg
doesn’t exist,
GNU
troff creates it.
GNU
troff removes a leading neutral double quote
‘"’
from
contents,
permitting initial embedded spaces in it,
and reads it to the end of the input line
in copy mode.240
.ds xxx abcd\h'3i'efgh
.length yyy \*[xxx]
\n[yyy]
⇒ 14
Caution:
The formatter reads the second argument to the end of the line
in copy mode,
omitting any leading neutral double quote
‘"’
character.
See the discussion of the
ds
request above.
Caution:
If you interpolate a macro or diversion in
contents,241
the
length
request counts characters
(or nodes)
only up to the first newline,
and leaves the rest on the input stream.
In conventional circumstances,
that means the remainder is interpreted,
and may be formatted.
To discover the length of any
string,
macro,
or diversion,
use the
pm
request.242
Remove the last character from the macro,
string,
or diversion named
object.
This is useful for removing the newline from the end of a diversion
that is to be interpolated as a string.
You can apply
chop
repeatedly to the same
object.243
Replace the string named
str
with its substring bounded by the indices
start
and
end,
inclusively.
The first element of the string has index 0.
Omitting
end
implies the largest valid value
(the string length minus one).
Negative indices count backward from the end of the string:
the last element has index -1,
the element before the last has index -2,
and so on.
If both
start
and
end
lie outside the string,
GNU
troff ignores the request.244
.ds xxx abcdefgh
.substring xxx 1 -4
\*[xxx]
⇒ bcde
.substring xxx 2
\*[xxx]
⇒ de
Compatibility save and restore tokens do
not
count for the purpose of index computation,
even though they appear in string contents reported by the
pm
request and figure in the value computed by the
length
request.
Alter the string named
str
by replacing each of its bytes with its
lowercase
(stringdown)
or uppercase
(stringup)
version
(if one exists).
GNU
troff’s built-in special characters often transform in the expected way
due to the regular naming convention
for accented characters.245
When they do not,
use substrings and/or catenation.
.ds resume R\['e]sum\['e]\"
\*[resume]
.stringdown resume
\*[resume]
.stringup resume
\*[resume]
⇒ Résumé résumé RÉSUMÉ
Rename the request, macro, diversion, or string old to new.
Remove each request, macro, diversion, or string name. GNU
troff treats subsequent invocations as if the name had never
been defined.
This request is incorrectly documented in the AT&T
troff manual as accepting only one argument.
Create alias (additional name) new-name of request, string, macro, or diversion existing-name, causing the names to refer to the same stored object. If existing-name is undefined, the formatter ignores the request.246 If new-name already exists, its contents are lost unless already aliased.
To understand how the als request works, consider two different
storage pools: one for objects (macros, strings, etc.), and another
for names. As soon as an object is defined, GNU troff adds it to
the object pool, adds its name to the name pool, and creates a link
between them. When als creates an alias, it adds a new name to
the name pool that gets linked to the same object as the old name.
Now consider this example.
.de foo
..
.
.als bar foo
.
.de bar
. foo
..
.
.bar
error→ input stack limit exceeded (probable infinite
error→ loop)
In the above,
bar
remains an
alias—another
name for—the object referred to by
foo,
which the second
de
request replaces.
Alternatively,
imagine that the
de
request
dereferences
its argument before replacing it.
Either way,
the result of calling
bar
is a recursive loop
that finally leads to an error.247
To remove an alias,
call
rm
on its name.
The object itself is not destroyed until it has no more names.
When a request, macro, string, or diversion is aliased, redefinitions and appendments “write through” alias names. To replace an alias with a separately defined object, remove its name first.
Next: Conditionals and Loops, Previous: Colors, Up: GNU troff Reference [Contents][Index]