groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Groff] Re: begin page blues


From: Miklos Somogyi
Subject: Re: [Groff] Re: begin page blues
Date: Tue, 14 Mar 2006 16:15:55 +1100


On 14/03/2006, at 3:46 AM, Werner LEMBERG wrote:

.ev 1                   \" 1a) why is this necessary?
.di x                   \" 1b)
. trf psline.ps \" 1c) dumps psline.ps with \\$1 replaced onto macro x?
.di                     \" 1d)
.ev                     \" 1e)

Why are 1a) and 1e) necessary?

Switching to another environment protects the current partial output
line.  Consider this:

  foo
  .di x
  I'm in a diversion.
  .br
  .di
  bar
  .di x

You mean `.x' I presume.
     => bar foo I'm in a diversion.

And now this:

  foo
  .ev 1
  .di x
  I'm in a diversion.
  .br
  .di
  .ev
  bar
  .di x

     => foo bar I'm in a diversion.


Werner, this should be part of the `.di' documentation. With an explanation of what `.br' is
doing here (or possibly before `I' m in a diversion').
`.di' documentation does not even mention how to `download' the macro's content. Yes, there are useful things in `.box' but one might not notice that it should be read
in conjunction with `.di'.


.de line                \" 4a)
.  de line-aux END      \" 5a)
     ps: def \\*x       \" 5b) appends `x' to prologue
.  END
.
.  nop \Y[line-aux]             \" 4b) ??
.  nop \X'ps: exec psline'      \" 4c) ??
..

What exactly happens at 4b) and 4c) ?

The `line' macro defines another macro, `line-aux'.  During execution
of `line', normal register, macro, and string expansion takes place.
This means that `line-aux' no longer contains expandable material
(except if you you protect it with an additional level of backslashes,
something like `\\\\*x').  The \Y escape takes the contents of
`line-aux' and inserts it into the output data stream as a special
node which is eventually emitted as `x X ...' in the intermediate
output.  \X does the same; it embeds its argument into a special node
in the same way as \Y (but no newlines are allowed in the argument).

The `x X' commands in the intermediate output must start with `ps:
xxx'; otherwise grops don't recognize them.

.\"--- external file psline.ps
.\"
.\" /psline {
.\"   \$1 0 rlineto
.\"   stroke
.\" } bind def
.\"
.\"--- questions
.\"
.\"   - Where (and in which pass) does the $1 replacement occur?

An external file read in with .trf is copied verbatim -- backslashes
are not interpreted as escape characters.  The .di request doesn't
interpret anything by itself; it just diverts the data stream to a
diversion.  This means that \$1 is expanded one level higher, during
the call of the `line' macro.


Oh jeez, there's a lot to learn!


.\" - Why can't `..' and `.  END' have side comments like anything
      else?

This is possible.  How do you come to a different conclusion?


Yeah, you are right. It's not `\" comment' that causes problems, but the TABS before it ...

  .de foo
  bar
  ..       \" a comment
  .
  foo
  .foo
  foo

      => foo bar foo

.\"        Why can't they handle trailing tabs?

This is a known limitation.  To cite section 7.3 of the original AT&T
troff reference:

  The argument separator is the space character (not tab) [...]

Any line starting with a dot is treated as either a request or as a
macro.  You can even do something perverse like this:

  .de .
  bar
  ..
  .
  foo
  ..
  foo

      => foo bar foo

With other words, `..' is basically handled as an (undefined) macro
which finishes the `.de' request.

If you input `..<tab>', groff doesn't interpret this as `..' because a
tab doesn't separate a macro name from its arguments.

In general, groff doesn't handling trailing whitespace.  This is the
very reason why you always should say

  .ds foo blablabla\"

to avoid an accidentally inserted whitespace at the end of the string
definition.


I'll remember that!


    Werner


Thank you for these (lots of) clarifications. I seem to fall into every pothole between
SGI troff and groff.

Miklos





reply via email to

[Prev in Thread] Current Thread [Next in Thread]