[comp.text] Marking Output Line Position

morrell@hpsal2.HP.COM (Michael Morrell) (04/13/89)

Does anyone know how I can get troff to save the current horizontal position
on the output line?  My documentation says that the ".k" register hold the
current input line, which is close to what I need, but it won't compensate for
the filling that takes place when the line is output.  In fact, I don't
understand what use it is to have the horizontal position on the input line.

On a side note, the book "Unix Text Processing" by Dale Dougherty and Tim
O'Reilly mentions an escape sequence "\jx" which is supposed to mark the
horizontal place in the output line in register x (as opposed to "\kx" which
marks the horizontal place in the input line in register x).  My troff (from
Elan) doesn't understand "\j".  Does anyone know of a troff which does
understand this escape sequence?  Considering the large number of errors in
this book, I wouldn't be surprised if no troff has "\j" (I haven't seen this
many errors in a technical book in a long time!).

Thanks in advance,

  Michael Morrell

jaap+@andrew.cmu.edu (Jaap Akkerhuis) (04/14/89)

> *Excerpts from ext.nn.comp.text: 12-Apr-89 Marking Output Line Positio..*
> *Michael Morrell@hpsal2.H (995)*
>  "\jx" which is supposed to mark the
> horizontal place in the output line in register x (as opposed to "\kx" which
> marks the horizontal place in the input line in register x).  My troff (from
> Elan) doesn't understand "\j".  Does anyone know of a troff which does
> understand this escape sequence?  Considering the large number of errors in
> this book, I wouldn't be surprised if no troff has "\j"
This request was available in the old (V7) troff and not documented. It was also
buggy. It contains bogus information on the moment you are executing a .ti.

Because of these two reasons it was left out from the modern version of troff
(ditroff) on which Elan's version is based.

A more clumsy approach is to cause a break and look at the register (.n) which
gives the length of the text portion on previous ouput line, but that is not
really equivalent to the \j request..

I always liked \j, but never came around reimplementing it. There is also a
problem with this request which makes it hard. Suppose you have a \jx in a line
and are actually interpolating its value in the same output line with \nx. Due
to the fact that \nx now could have a different value, you need to realign the
line again, which will make \j need to recalculate the position. Of course \nx
now might not have the same width anymore so...

A cop-out would be that the value of x would only valid after the filled ouput
line containing \jx got printed. This is the way you want to use it most of the
time anyway (you want to set a tab on that position or something along that
line) and would make it slightly easier to implement.

        jaap

dns@sq.com (David Slocombe) (04/17/89)

morrell@hpsal2.HP.COM (Michael Morrell) writes:

> Does anyone know how I can get troff to save the current horizontal position
> on the output line?  My documentation says that the ".k" register hold the
> current input line, which is close to what I need, but it won't compensate for
> the filling that takes place when the line is output.  In fact, I don't
> understand what use it is to have the horizontal position on the input line.
> 
> On a side note, the book "Unix Text Processing" by Dale Dougherty and Tim
> O'Reilly mentions an escape sequence "\jx" which is supposed to mark the
> horizontal place in the output line in register x (as opposed to "\kx" which
> marks the horizontal place in the input line in register x)....

The "\jx" escape sequence was an undocumented feature of V7 [nt]roff.
It was removed by the time of the first ditroff tape and has never
appeared in any Documenter's Workbench tape, presumably because it
wasn't useful.

This is a very confusing topic, so it is perhaps useful to lay out all the
details in one place:

In Nofill Mode (.nf), troff's "input line" is the same as its "output line".

But by default, troff is in Fill Mode (.fi) with Adjusting (.ad).  In Fill
Mode, of course, the "input line" and the "output line" get out-of-sync
because troff is filling up output lines with as much as it can fit in,
without regard to what input line it is coming from.  Adjusting means that
after filling is done, the inter-word spaces are expanded to make the right
margin straight (justified) instead of ragged.

Now, the "\kx" escape sequence fetches into number-register "x" the horizontal
distance from the beginning of the INPUT LINE on which it appears.

In Nofill Mode, this distance is going to be the same for the OUTPUT LINE.
In this mode, the width of the inter-word space is a fixed value (subject
to modification by the ".ss" request).  Therefore, one can do useful
things with the "\kx" escape sequence, such as

	I say, \kxhello world!\l'|\nxu\(ul'

to underline something, for example.

This WILL NOT WORK if troff is in Fill Mode with Adjustment because
the actual width of the space between "hello" and "world" is not
determined until the WHOLE output line has been created, which is
after the "\kx" and the "\nx" have been processed.

Moreover, in Fill Mode no matter whether with Adjustment or not,
constructions like the above will fail some portion of the time
because you have no guarantee that "hello" and "world" will appear
on the same output line.

(Constructions like the above ARE always useful if no interword space
is involved and there is no possibility of hyphenation.)

Now the "\jx" escape sequence of old troff had exactly the same
problem in Fill Mode with Adjustment:  it fetched into number
register "x" the current position on the OUTPUT LINE, but this
was done when the line was still being constructed -- either because it
was easier to do, or so that subsequent parts of the line could use
that value, or both.  So the REAL position on the output line (i.e.
after "adjustment") was not available.

In Nofill Mode, or Fill Mode without Adjustment, the \j sequence had
almost no use beyond what the \k escape sequence could provide.  And in
addition it had the syntactic quirk of accepting only a 1-character
number register name -- "\k(xx" refers to register "xx", but "\j(xx"
referred to register "(" and the "xx" was taken as text.  I don't know,
but I suspect \j was removed by someone frustrated by all the people
trying to use it to do the un-doable.

To add to the confusion, the ".k" read-only register does give the
horizontal position on the OUTPUT LINE (hence is NOT related to the
similarly-named "\kx" escape sequence), BUT IS UPDATED ONLY AT EACH INTER-
WORD SPACE!  (At least the \j escape sequence gave you the value in the
middle of the word if you wanted it -- but in most practical cases the
\k escape sequence gives the same value because input and output lines
are the same!)

(Note, Michael: ".k" --> OUTPUT LINE, not as you stated in your posting.)

The ".k" register IS useful in Nofill Mode:  books of modern poetry,
for example, where some lines start underneath a specific word in
the line above, could not be typeset without it.  (And, yes, we
have at least one customer who does lots of those!)

Mark Brader (msb@sq.com) helped me to get all this right -- even
after all these years I continue to forget the ins and outs.
(I guess that is a pun.)

----------------------------------------------------------------
David Slocombe				(416) 963-8337
Vice-President, Research & Development  (800) 387-2777 (from U.S. only)
SoftQuad Inc.				uucp: {uunet!attcan!utzoo, utai}!sq!dns
720 Spadina Ave.			Internet: dns@sq.com
Toronto, Ontario, Canada M5S 2T9