[net.text] Bug in MS macros ?

joel@dicomed.UUCP (Joel D. Neisen) (06/01/84)

One of the fellows here came across a very unusaul happenstance
today.  The first few lines of a document are

.po 8
.sp 5
.ul 1
Title text
.sp 3
Subtitle text
.po +8
.EQ I
x sub 1 ~~ x sub 2
.EN


When using (n)eqn with n/vtroff and the ms macros the
"subtitle text" would not appear on the output.
After a little experimenting I discovered that
one line of output text (NOT source line) was being thrown
away.

Has anyone run across/fixed this bug ?? If so I would
appreciate to hear your fix.  By the way we have 4.2BSD.

Thanks much,

-- 
	Joel Neisen
	(612) 887-7183
	DICOMED Corp.
	1120 East 80 ST. Suite 101
	Minneapolis MN 55420

	{mgnetp,uwvax,ihnp4}!dicomed!joel

rusty@sdccsu3.UUCP (06/04/84)

one thing that i discovered a long time ago is that it usually
helps with things like this to almost ALWAYS helps to put
	.RT
at the very beginning of your file. RT stands for "reset" and
gets -ms ready to work.

gbergman@ucbtopaz.CC.Berkeley.ARPA (06/05/84)

The bug described was that with eqn|troff -ms, a file beginning
as follows did not print the ``Subtitle text'':

	.po 8
	.sp 5
	.ul 1
	Title text
	.sp 3
	Subtitle text
	.po +8
	.EQ I
	x sub 1 ~~ x sub 2
	.EN

     One can't actually call it a bug, because the -ms macros
aren't being used as they are supposed to be.  The last item of
section 1.3 of ``Document formatting on UNIX.  Using the -ms
Macros'' says

	Finally, there is an important rule about the
	order in which things should appear...: the file should not
	begin immediately with a line of text.  Instead, one of the
	following -ms macros must precede the first line of text:
		.TL	.SH	.NH	.PP	.LP

Why is it set up this way?  I don't know.  The -ms macro package is
such a monster that no one seems to entirely understand how it works.
(I don't use it myself.)
     But anyway, if you're curious, I've tracked down the way that
the failure to ``initialize'' causes a line of text to be lost:
     The above five  macros are set up so that the first time they are
called, they invoke an initializing macro, .BG (`begin'').  (Several,
but not all of them do this by invoking the macro .RT recommended for
initialization in <1895@sdccsu3.UUCP>.  .RT itself invokes .BG, and it
looks to me as though .BG should be as good as .RT for initialization.
Anway, .BG definitely prevents this ``lost line'' problem.)
     The key line in the definition of .BG, in turn, is
	.nr YE 1
which apparently exists just to tell .EQ ``The initialization has been
done.''  (So if you put this line anywhere before the .EQ, your
lost line will likewise be restored.  Just to confuse things, there
seems to be a different number register, \n(1T, that exists to tell
all other macros that the initialization has been done.)
    Now how does the value of \n(YE come into the behavior of .EQ?
The definition of the .EQ macro contains the line
	.if \\n(YE>0 .nf
just before the point where the material defining the formula
(put in by the eqn program) is processed.  Eqn builds
up the formula as a string, \*(10, and then outputs the string, but
the -ms macros package wants to do some hocus-pocus before it uses
this output, so it hides it in a diversion, which it throws away
(remembering its measurements), and then calls the string again when it
is ready for it.  Now the above line says that if initialization
has occurred the diversion is to be processed in nofill mode.  Why
only if initialization has occurred?  I don't know!  But I can describe
the effect if nofill mode is not invoked.  The filling process adds
the eqn material to the end of the preceding partial line.  When the
resulting line is ended (by a .br inside the .EN macro), it is output
within the diversion.  But, as I have said, -ms throws away the
diversion.  Result: the preceding text is thrown away, though the
formula, being the defined value of the string \*(10, is later output
correctly.
     Knowing this much, one can see a million ways to prevent this
particular ``happenstance'', e.g. preceding the .EQ by .br, or by .nf,
or by .sp 0, ....  But like the writer of reply <1895@sdccsu3.UUCP>,
I suggest that if you want to use the -ms macro package, you use one
of the 5 listed macros, or .BG or .RT, to initialize any manuscript.
     Incidentally, if you look through /usr/lib/tmac/tmac.s, my
statement that the definition of .EQ involves \n(YE may appear to be
incorrect.  In fact, in 4.2bsd, the definition of .EQ sources another
file via the line
	.so \*(//s.eqn
where \*(// expands to /usr/lib/ms/.  If you look at the definition of
.EQ in /usr/lib/ms/s.eqn, it contains the line I quoted.  Similar
comments apply to the definition of .TL (the first of the 5
``initializing macros'' listed.)

     For those who, like me, like to write their own troff
macros, and for those who wish to understand existing macro packages,
let me restate the key fact about diversions relevant to the above:
The diversion process apparently occurs after the line-fill process,
so the contents of a diversion will be those lines \fIcompleted\fP
between the call .di xx and the closing call .di.  Since one generally
wants the diversion to contain the lines \fIinput\fP between those two
calls, one should precede each of them by .br, or an environment-change
in cases where you want the preceding text to be continuous with the
text following the diversion.

     Does anyone know of any documentation of {dit,t,n}roff in which
one can find such facts clearly stated, instead of learning them by
endless trial and error???  I find the NROFF/TROFF USERS MANUAL
invaluable, but far from equal to the task!

			George Bergman
			...!ucbvax!ucbcartan!gbergman