Next: , Previous: , Up: GNU troff Reference   [Contents][Index]


5.33 I/O

Occasionally a document wants to access the file system or other services provided by the operating environment. GNU troff permits the reading of files and, when unsafe mode is enabled at the command line, the execution of an external commands, with or without inclusion of their output in the document.

Request: .so ["]file
Request: .soquiet ["]file

Replace the so request’s control line with the contents of the file named by the argument, “sourcing” it. file is sought in the directories specified by -I command-line option. If file does not exist, a warning in category ‘file’ is produced and the request has no further effect. See Warnings, for information about the enablement and suppression of warnings.

GNU troff strips a leading neutral double quote from the argument, allowing embedded leading spaces in contents.

so can be useful for large documents; e.g., allowing each chapter of a book to be kept in a separate file. However, files interpolated with so are not preprocessed; to overcome this limitation, see the gsoelim(1) man page.

Caution: Since the formatter replaces the entire control line with the contents of a file, file must end with a newline, or the formatter will continue reading the next input line of the roff file as if were part of the last line of the sourced file. Consider a file xxx containing only the word ‘foo’ without a trailing newline.

$ printf 'foo' > xxx
$ groff <<EOF
The situation is
.so xxx
bar.
EOF
    ⇒ The situation is foobar.

soquiet works the same way, except that GNU troff issues no warning diagnostic if file does not exist.

Request: .pso ["]command

Read the standard output from the specified command when passed to popen(3) and include it in place of the pso request.

It is an error to use this request in safer mode, which is the default. Invoke GNU troff or a front end with the -U option to enable unsafe mode.

The cautionary note regarding a final newline in the stream read by the so request applies to pso as well.

Request: .mso ["]file
Request: .msoquiet ["]file

Identical to the so and soquiet requests, respectively, except that GNU troff searches for the specified file in the same directories as macro files for the -m command-line option.

Request: .trf file
Request: .cf file

Transparently output the contents of file. Each line is output as if preceded by \!, but is not read in copy mode. If file does not end with a newline, trf appends one. Both requests break the line before reading file, unless invoked with the no-break control character.

When used in a diversion, these requests embed a node (see Gtroff Internals) in it that, when interpolated, causes the contents of file to be copied to the output. In AT&T troff, cf does so even if a diversion is in use; this behavior is so anomalous that it must be considered a bug.

While cf copies the contents of file completely unprocessed, trf disallows characters such as NUL that are not valid gtroff input characters (see Identifiers).

For cf, within a diversion, “completely unprocessed” means that each line of a file to be inserted is handled as if it were preceded by \!\\!.

To define a macro x containing the contents of file f, use

.ev 1
.di x
.trf f
.di
.ev

The calls to ev prevent the partially collected output line from becoming part of the diversion (see Diversions).

Request: .nx [file]

Stop processing the input file. If file is specified, read it; otherwise, read the next pending input file, if any.

Request: .rd [prompt [arg1 arg2 …]]

Read from standard input, and include what is read as though it were part of the input file. Text is read until a blank line is encountered.

If standard input is a TTY input device (keyboard), write prompt to standard error, followed by a colon (or send BEL for a beep if no argument is given).

Arguments after prompt are available for the input. For example, the line

.rd data foo bar

with the input ‘This is \$2. prints

This is bar.

Using the nx and rd requests, it is easy to set up form letters. The form letter template is constructed like this, putting the following lines into a file called repeat.let:

.ce
\*(td
.sp 2
.nf
.rd
.sp
.rd
.fi
Body of letter.
.bp
.nx repeat.let

When this is run, a file containing the following lines should be redirected in. Requests included in this file are executed as though they were part of the form letter. The last block of input is the ex request, which tells GNU troff to stop processing. If this were not there, troff would not know when to stop.

Trent A. Fisher
708 NW 19th Av., #202
Portland, OR  97209

Dear Trent,

Len Adollar
4315 Sierra Vista
San Diego, CA  92103

Dear Mr. Adollar,

.ex
Request: .pi ["]contents

Use GNU troff’s device-independent output as the input to the commands specified in pipe and emit their output to the standard output stream instead of GNU troff’s usual output. Since that output is in a page description language,135 using this request without specifying the -Z option to groff is likely to provoke fatal errors from an output driver.

The formatter reads the remainder of the input line into contents and passes it to popen(3). Output produced by the command(s) is not captured by GNU troff.

GNU troff strips a leading neutral double quote from the argument, allowing embedded leading spaces in contents.

Multiple pi requests construct a multi-stage pipeline in the same order as the formatter encounters the requests.

pi must be invoked before GNU troff writes any nodes to its output.136 The formatter reports an error and ignores the request if pi is invoked “too late”. Roughly, this means you should set up your pi pipeline early in a document, before anything but register, string, and macro definitions (and/or sourcing of files that comprise these exclusively).

Use of this request in safer mode (GNU troff’s default) is erroneous. Invoke GNU troff or a front end with the -U option to enable unsafe mode.

.pi foo
.pi bar

is the same as ‘.pi foo | bar.

Request: .sy ["]contents
Register: \n[systat]

Execute the specified shell command(s). The formatter reads the remainder of the input line into contents and passes it to system(3). Output produced by the command(s) is not captured by GNU troff.

GNU troff strips a leading neutral double quote from the argument, allowing embedded leading spaces in contents.

It is an error to use this request in safer mode; this is the default. Give GNU troff or a front end program the -U option to enable unsafe mode.

The writable register systat contains the return value of the system(3) function executed by the most recent sy request.

The following code fragment introduces the current time into a document.

.sy perl -e 'printf ".nr H %d\\n.nr M %d\\n.nr S %d\\n",\
             (localtime(time))[2,1,0]' > /tmp/x\n[$$]
.so /tmp/x\n[$$]
.sy rm /tmp/x\n[$$]
\nH:\nM:\nS

This works by having the Perl script (run by sy) write nr requests that set the registers H, M, and S to a temporary file. The roff document then reads the temporary file using the so request.

The registers seconds, minutes, and hours, initialized at startup of GNU troff, should satisfy most requirements. Use the af request to format their values for output.

.af hours 00
.af minutes 00
.af seconds 00
\n[hours]:\n[minutes]:\n[seconds]
    ⇒ 02:17:54
Request: .open stream file
Request: .opena stream file

Open the specified file for writing and associates the specified stream with it.

The opena request is like open, but if the file exists, append to it instead of truncating it.

It is an error to use these requests in safer mode; this is the default. Give GNU troff or a front end program the -U option to enable unsafe mode.

The pstream request dumps the list of open streams to the standard error stream; Debugging.

Request: .write stream ["]contents
Request: .writec stream ["]contents

Write contents to stream, which must previously have been the subject of an open (or opena) request. GNU troff flushes the stream after writing to it.

A leading neutral double quote in the second argument is stripped from it, allowing embedded leading spaces in contents, which is read to the end of the input line in copy mode.

The writec request is like write, but only write appends a newline to contents.

Request: .writem stream name

Write the contents of the macro or string name to stream, which must previously have been the subject of an open (or opena) request. The contents of name are read in copy mode. That is, already formatted elements (nodes) are ignored. Consequently, diversions must be unformatted with the asciify request before calling writem. Usually, this means a loss of information.

Request: .close stream

Close the specified stream; the stream is no longer an acceptable argument to the write request.

Here a simple macro to write an index entry.

.open idx test.idx
.
.de IX
.  write idx \\n[%] \\$*
..
.
.IX test entry
.
.close idx
Escape sequence: \Ve
Escape sequence: \V(ev
Escape sequence: \V[env]

Interpolate the contents of the specified environment variable env (one-character name e, two-character name ev) as returned by the function getenv(3). \V is interpreted even in copy mode (see Copy Mode).


Next: , Previous: , Up: GNU troff Reference   [Contents][Index]