[net.text] help with diversions

dberry@ucla-cs.UUCP (02/07/85)

Does anyone have experience using the supplied .PS and .PE macros
that come with ditroff for centering PIC generated pictures.
In particular, I cannot get a PIC picture that is part of a floated keep to
be centered. When I change the .in inside the definition of .PS
there is no change in the indentation of the output.
so we have

....

.dePS
.nr LS \\n(.L
.nr IS \\n(.i
.ls 1
.if t .sp .3
.in (\\n(.lu-\\$2u)/2u
.ne \\$1u
..
.dePE
.ls \\n(LS
.in \\n(IS
.if t .sp .6
..

....

.fs \"start of our macro's floting keep
.PS
boxwid = 1i
boxht = 1i
movewid = 1i
moveht = 1i
circlerad = .5i
box "blah" "blah"
.PE
.ce
Figure 1: Proof Manager
.sp
.fe \" of our floating keep

Now in the actual document the PIC picture does get floated to the next
page at the top. In case it is significant, at the place the text is
printed, there is an indent for a numbered list in effect. The list is
done properly both before and after the picture --so the restoration
of the indent is working properly.

As I said the picture comes out left justified but the caption is centered.
What am I doing wrong????

Daniel M. Berry         UCLA Computer Science Department
dberry@ucla-locus.arpa  ..!{sdcrdcf,ihnp4,cepu,trwspp,ucbvax}!ucla-cs!dberry

padpowell@wateng.UUCP (PAD Powell) (02/12/85)

In article <3807@ucla-cs.ARPA> dberry@ucla-cs.UUCP (Dan Berry) writes:
>Does anyone have experience using the supplied .PS and .PE macros
>that come with ditroff for centering PIC generated pictures.
>In particular, I cannot get a PIC picture that is part of a floated keep to
>be centered. When I change the .in inside the definition of .PS

Ah, yes, the incredible diversion problem.  Actually, what you are
seeing is an interaction of the way diversions are "generated", and
then "inserted".  When you generate a diversion, it takes/uses the
current settings for the indent, fonts, etc., and creates an "image" of
the text that you have in the diversion.  This image is stored in some
magic place, and some of the attributes such as horizontal width,
vertical depth, etc., can be accessed.  By the way, watch out for
multiple page length diversions, they can be really a pain with the -ms
and -me macros packages.

Anyways, to get the diversion inserted, you have to have it
expanded/inserted which is done using the "macro" facility.  However,
the current font/indent and so forth are now applied to the expanded
diversion.  Thus, you will find that you have applied an indent TWICE
to a diversion, or so forth.  Why this?  It is due to the fact that you
can "bury" macros in a diversion, by prefacing them with \&.  This null
character is stripped off, and then the remainder is placed in the
diversion.  If you do \&.tm "Zap!" you will find Zap! magically
appearing when the line in the diversion is placed in the output
stream/page.

Now that you are thoroughly confused, how do you fix this?  The answer is,
to use "no-indent" on floating keeps.  I.E.- put an .in 0 in your floating
keeps.  For example,

.de PS
.in 0	\" in the diversion
\&.in 0	\" in the delayed text
.tm and the rest of your macro here
..

The first .in 0 will slug it out with the diversion.  Good luck.
The "guarded .in 0" will slug it out at the time the diversion is
expanded.  Now for the fun part.  GUARDING DOES NOT ALWAYS WORK.
Some sneaky packages expand diversions into diversions, creating chaos
for the user.

So, just for your entertainment,  I am including a set of macros for the
-me package, that can be added to make **** sure that this occurs
correctly.   I might add that I have been doing hand to hand combat with
the -me macros,  and find that this solution is the best.  If you are
interested in a new debugged, annottated, and redocumented version of
the -me macros, send me mail. 

In addition, note the Table of Contents Macro, which uses a simple
form of this macro, and the Figure Title macro.

Patrick Powell

: Run this shell script with "sh" not "csh"
PATH=:/bin:/usr/bin:/usr/ucb
export PATH
all=FALSE
if [ $1x = -ax ]; then
	all=TRUE
fi
/bin/echo 'Extracting multi.e'
sed 's/^X//' <<'//go.sysin dd *' >multi.e
X.\"From: lwall@sdcrdcf.UUCP
X.\"Newsgroups: net.unix,net.text
X.\"Subject: Passing commands thru multi-level troff diversions
X.\"
X.\"Certain nroff/troff commands must apply either at every diversion level
X.\"or at the outermost level (e.g. commands marked P in the nroff
X.\"document).  \! works okay when you know how deep you are in diversions,
X.\"but when writing macros (such as index and TOC generation) you don't
X.\"always have that information.  Additionally, when deep inside
X.\"diversions (such as inside a tbl text block inside a floating display),
X.\"it gets wearisome to type
X.\"
X.\".cs R 25
X.\"\!.cs R 25
X.\"\!\!.cs R 25
X.\"Constant spaced text.
X.\".cs R
X.\"\!.cs R
X.\"\!\!.cs R
X.\"
X.\"So, for whatever it's worth, here's something I whipped up a while back:
X.\"
X.\"
X.\"     Do a command OUtside of diversions, or for EVery diversion level.
X.\"     (Use OU and EV for macro calls, Ou and Ev for bare nroff commands.)
X.\"
X.\"	Uparrow is used instead of backslash for the escape character
X.\"	so that you needn't count backslashes.  Just use one uparrow where
X.\"	you would want a backslash in the final command.
X.\"
X.\"     Examples:
X.\"
X.\"	".Ev .cs R 25" can be used in a display to set constant spacing
X.\"     mode such that it will again be in effect whenever the display
X.\"     is pulled back in from the diversion.
X.\"
X.\"	If number register P contains the current page number,
X.\"	.Ou .tm Current page number is ^nP
X.\"	will dump the correct page number to fd 2 regardless of how many
X.\"	levels deep in diversion you are, and how many pages your floating
X.\"	display floated across.
X.\"
X.de Ou
X.ie '\\n(.z'' \\{\\
X.di ??
\!\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
X.di
X.ec ^
X.??
X.ec
X.rm ??
'br\\}
X.el \\{\\
\!.ie '\\\\n(.z'' \\\\{\\\\
\!.ec ^
\!\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
\!.ec
\!'br\\\\}
\!.el \\\\{\\\\
\!.Ou "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!'br\\\\}
'br\\}
X..
X.de Ev
X.di ??
\!\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
X.di
X.ec ^
X.??
X.ec
X.rm ??
X.if !'\\n(.z'' \\{\\
\!.ie '\\\\n(.z'' \\\\{\\\\
\!.ec ^
\!\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
\!.ec
\!'br\\\\}
\!.el \\\\{\\\\
\!.Ev "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!'br\\\\}
'br\\}
X..
X.\"
X.\"	Same as above, but quoting is different
X.\"
X.de OU
X.ie '\\n(.z'' \\{\\
X.di ??
\!\\$1 "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
X.di
X.ec ^
X.??
X.ec
X.rm ??
'br\\}
X.el \\{\\
\!.ie '\\\\n(.z'' \\\\{\\\\
\!.ec ^
\!\\$1 "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!.ec
\!'br\\\\}
\!.el \\\\{\\\\
\!.OU "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!'br\\\\}
'br\\}
X..
X.de EV
X.di ??
\!\\$1 "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
X.di
X.ec ^
X.??
X.ec
X.rm ??
X.if !'\\n(.z'' \\{\\
\!.ie '\\\\n(.z'' \\\\{\\\\
\!.ec ^
\!\\$1 "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!.ec
\!'br\\\\}
\!.el \\\\{\\\\
\!.EV "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
\!'br\\\\}
'br\\}
X..
X.\"	Larry Wall
X.\"	{allegra,burdvax,cbosgd,hplabs,ihnp4,sdcsvax}!sdcrdcf!lwall
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
	/bin/chmod 644 multi.e
	/bin/echo -n '	'; /bin/ls -ld multi.e
fi
/bin/echo 'Extracting paper.e'
sed 's/^X//' <<'//go.sysin dd *' >paper.e
X.\"	Package to do
X.\"	1. fancy Table of Content entries
X.\"		uses \n(0x, \n(0y, \n(0z
X.\"		.(x x
X.\"	2. Figures, and produce a figure list
X.\"		uses \n(fg (figure number)
X.\"		.(x f
X.\"	3. Has a fancy underscore fix, can use to get better looking output
X.\"	4. Sets hyphenation to be a little less clever
X.\"	5. Double Spacing is set as default
X.\"	6. Keyword indexing- the .xx macro
X.\"		.xx "keyword"
X.\"		produces an output with .tm, line of form:
X.\"		<garbage> xx keyword :pageno:
X.\"		This can be processed by a filter to produce a sorted index.
X.\"		General method of use:
X.\"		index=/tmp/ind$$
X.\"		cat files | (sh troff >/dev/null 2>${index}
X.\"		<process the index file>
X.\"		cat files  $index |troff
X.\"	7. Bombproof index entry macro .+x, usable inside diversions, etc.
X.\"
X.de $0		\" Table of contents macro.  Called by .sh
X.\"	Actually called by .$p, which is the header printing macro.
X.\"	Generates a table of contents entry of the form
X.\"
X.\"	1. name .... #
X.\"	  1.1 name ..#
X.\"
X.\"	2. name .... #
X.\"	  2.1 name ..#
X.\"      ^ depth (max of 3) * \n(0i
X.\"	\n(0n - space for numbers
X.\"	\n(0i - incremental indent amount
X.\"	\n(0x, \n(0y - temporary
X.nr 0x \\$3
X.if \\$3>3 .nr 0x 3
X.\" fixed 29 Sept 84 p. bain so it works for .uh too
X.if "\\$3"" .nr 0x 1
X.nr 0x ((\\n(0x-1)*\\n(0iu)
X.nr 0y \\n(0xu+\\n(0nu
X.(x
X.if \\$3=1 .sp
X.br
\&\h'|\\n(0xu'\\$2\h'|\\n(0yu'\\$1
X.)x
X.rr 0x
X.rr 0y
X.\"	Reset figure numbers for each section
X.\" revised 25 July 1984 P. Bain. Reset only for .sh 1; good fix, PADPowell
X.if (\\n($0=1) .nr fg 1
X..
X.\"	Initialize figure TOC values
X.nr 0n 1.0i
X.nr 0i .25i
X.de FG	\" Figure Macro. FG "title" "size" "comment"
X.\"	Floats a figure to the top or bottom of page,
X.\"	Reserves space
X.(z
X.rs		\" turn on spacing
X.sp \\$2	\" allocate space
\\$3		\" put in comment
X.sp 1v		\" leave a space between the comment
X.FT \\$1	\" put out the title of the figure
X.)z
X..
X.de FT	\" Generates a figure title of the form Figure <section>.<index>
X.\"		Puts an entry in the figure table.
X.\"		Uses the Bombproof index entry macro
X.ce
Figure \\n($1.\\n(fg \\$1
X.+x f "Figure \\n($1.\\n(fg \\$1"
X.nr fg +1
X..
X.\"	Underscore fixup looks better than standard underscores
X.ds us \h'0.1m'\(ul\h'0.1m'
X.de xx	\" keyword index macro
X.tm xx \\$1 :\\n%:
X..
X.de +x		\" *** single line, bombproof index entry
X.\"	.+x <index> [p1 - p6]
X.\"	This macro is designed to be used inside anything
X.\"	that might be involved with floating keeps, or diversions.
X.\"	If that is the case, badly formatted index entries can
X.\"	result, due to the interaction of the environments,
X.\"	diversion expansions, and "unguarded text".  Anything that
X.\"	is not a request which is processed by a diversion has
X.\"	the current processing of that diversion performed;
X.\"	since indents (.in) are INHERITED, you get progressively
X.\"	indented text.
X.\"
X.\"	For example, if you had a figure, and put it in a floating
X.\"	keep, like so:
X.\"	.(z
X.\"	.sp 2i	\" leave space for figure
X.\"	.ce
X.\"	Figure 1
X.\"	.(x f
X.\"	.sp 1v
X.\"	Figure 1
X.\"	.)x
X.\"	.)z
X.\"	You might find the following index entry formats, depending on
X.\"	how far the float had to go, etc.
X.\"	Figure 1 ...... 1
X.\"	     Figure 1
X.\"	 .............. 1
X.\"		Figure 1
X.\"	 .............. 1
X.\"
X.\"	Solution to this problem is the .+x macro, which is passed the
X.\"	index, and the index entries
X.\"	.+x f ".sp 1v" "Figure 1"
X.\"
X.\"	The way this is done is similar to the .(x macro, and has
X.\"	been unabashedly been stolen.  If you want to use the other
X.\"	.)x P A
X.\"	options, define a similar set of macros, setting P if $2
X.\"	is non-null, and A if $3 is non-null;  this is the +y
X.\"	macro.
X.if \\n@>4 .tm >> +x \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7
X.\" please note these cases MUST be in this order
X.ie !"\\n(.z"" \
\{\
\!.+x "\\$1"  "\\$2"  "\\$3"  "\\$4"  "\\$5"  "\\$6"  "\\$7"
X.\}
X.el \
\{\
X.	(x \\$1
X.	if !""\\$2" \\$2
X.	if !""\\$3" \\$3
X.	if !""\\$4" \\$4
X.	if !""\\$5" \\$5
X.	if !""\\$6" \\$6
X.	if !""\\$7" \\$7
X.\"	NOTE: no tab before )x, .am will fail to close; see .(x macro, and
X.\"	TROFF Reference Manual, .de request
X.)x
X.\}
X..
X.de +y	\" allow the setting of (x P A
X.if \\n@>4 .tm >> +y \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7
X.\" please note these cases MUST be in this order
X.ie !"\\n(.z"" \
\{\
\!.+y "\\$1"  "\\$2"  "\\$3"  "\\$4"  "\\$5"  "\\$6"  "\\$7"
X.\}
X.el \
\{\
X.	(x \\$1
X.	if !""\\$4" \\$4
X.	if !""\\$5" \\$5
X.	if !""\\$6" \\$6
X.	if !""\\$7" \\$7
X.\"	NOTE: no tab before )x, .am will fail to close; see .(x macro, and
X.\"	TROFF Reference Manual, .de request
X.)x \\$2 \\$3
X.\}
X..
X.ls 2	\" double space
X.hy 14	\" suppress hyphenation
X.fo 'DRAFT'%'\*(td'
//go.sysin dd *
made=TRUE
if [ $made = TRUE ]; then
	/bin/chmod 644 paper.e
	/bin/echo -n '	'; /bin/ls -ld paper.e
fi