[comp.text] page numbering between chapters in nroff

kevin@ttidca.TTI.COM (Kevin Carothers) (08/29/89)

Hello

I apologize if this is a simple request, but all the nroff/troff
people I know don't seem to have any ideas either, so here goes.

I have a very large document, consisting of multiple chapters, and
I would like to pass the ending page from the previous chapter to 
thefirst page of the next chapter (plus 1, of course).

Does anyone have any nifty algorithms for doing this? So far I haven't
been able to figure out a simple way of doing this. 

The only thing that seems doable so far is to append a ".so" to the end
of each chapter, but this is rather unacceptable, as each chapter can
stand on its own, or in conjunction with all others.

The Nroff/Troff Users guide mentions that number registers (.nr %) can
be read or written, but I have seen no example.  Ideally, I would like to
set an environment variable with the page #, so that from a makefile I can
do something like

      "nroff -ms -n$page chapterx.ms"

Any help would be very welcome.

Thank you all

--
    Kevin Carothers           {philabs,csun,psivax}!ttidca!kevin

psfales@cbnewsc.ATT.COM (Peter Fales) (08/30/89)

In article <5689@ttidca.TTI.COM>, kevin@ttidca.TTI.COM (Kevin Carothers) writes:
> people I know don't seem to have any ideas either, so here goes.
> 
> I have a very large document, consisting of multiple chapters, and
> I would like to pass the ending page from the previous chapter to 
> thefirst page of the next chapter (plus 1, of course).
> 
> The Nroff/Troff Users guide mentions that number registers (.nr %) can
> be read or written, but I have seen no example.  Ideally, I would like to
> set an environment variable with the page #, so that from a makefile I can
> do something like
> 
>       "nroff -ms -n$page chapterx.ms"


I don't have access to the ms macros, but if I understand what you
are asking, I tried the following and it works.

	nroff -mm -rP5 filex

This cause the first page to be printed  with page number 5.  By way
of explanation, "P" is the name of the number register that holds the
page number in the mm macros.   It can be be set this way from the 
command line, or by putting a 

.nr P 5

in the document.  Number registers can also be printed in a document
using the \n construct.  You could say somthing like: "the page number
I am currently on is \nP."  To print a two character number register
like Fg, you would print \n(Fg. 

I hope this is what you are looking for.

-- 
Peter Fales			AT&T, Room 5B-420
				2000 N. Naperville Rd.
UUCP:	...att!peter.fales	Naperville, IL 60566
Domain: peter.fales@att.com	work:	(312) 979-8031

henry%angel@Sun.COM (Henry McGilton -- Software Products) (08/31/89)

In article 5223, Kevin Carothers writes:

    * I have a very large document, consisting of multiple
    * chapters, and I would like to pass the ending page from
    * the previous chapter to the first page of the next
    * chapter (plus 1, of course).

    * Does anyone have any nifty algorithms for doing this?
    * So far I haven't been able to figure out a simple way
    * of doing this.

    * The only thing that seems doable so far is to append a
    * ".so" to the end of each chapter, but this is rather
    * unacceptable, as each chapter can stand on its own, or
    * in conjunction with all others.
What you want is doable without mucking around with .so
lines and such.

    * The Nroff/Troff Users guide mentions that number
    * registers (.nr %) can be read or written, but I have
    * seen no example.
Be aware that even if you set the  %  number register from the command
line, you might not necessarily get the results you want, because
the  -ms  macro package uses an internal number register called
PN  to record its notion of the current page.
    * Ideally, I would like to set an environment variable
    * with the page #, so that from a makefile I can do
    * something like

	* nroff -ms -n$page chapterx.ms

By an  `environment variable' I assume you mean a Shell
environment variable?  If so, be aware that it's only
fairly recently that  make  took notice of Shell
environment variables.  Older versions of  make  couldn't
do this, and if you're stuck with such a version, you'll
have to modify the approach.  I show how below.

There are several approaches.

First off, if you've already gone to the trouble of
creating a Makefile, why format one chapter at a time?  Just
format the whole shebang every time.  Create a Makefile
that has approximately this form:

    CHAPTERS = c1.ms  c2.ms  c3.ms  c4.ms   . . . and so on . . .

    DEVICE = -Tlw

    MACROPACKAGE = -ms

    FORMATTER = /usr/bin/troff $(DEVICE) $(MACROPACKAGE) -t

    book.dit:
	    $(FORMATTER) $(CHAPTERS) > book.dit

This way, the document gets formatted every time, and the start
page of one chapter is one more than the end page of the previous
chapter.

OK -- it's quite possible you're concerned about the amount
of time taken to reformat the whole document every time a
line gets changed.  Especially if your document is large.
But just for comparison, my 600 page UNIX System V book
formats in under two hours on a Sun-2/120 (that includes
cross references, pic, tbl, eqn, troff, tables of contents,
and index).

However, here's one way to do what you want.  Create a Makefile
that looks like this:

    1	DEVICE = -Tlw
    2	MACROPACKAGE = -ms
    3	FORMATTER = /usr/bin/troff $(DEVICE) $(MACROPACKAGE) -t

    5	.SUFFIXES: .ms .dit

    6	.ms.dit:
    7	        $(FORMATTER) -rP$$page  $<  >  $@

Let's pull this apart.  Line 5 describes the suffixes you will
be using.  You will be transforming  ms  files into  dit  files.
I am assuming you're using device independent troff here.  The same
process applies equally well to nroff or old four font C/A/T troff.

Lines 6 and seven describe the actual rule.  To get from a
 .ms file to a  .dit  file, you run the formatter, with the
input file as the  $<  macro, and the output file as the
$@  macro.  Notice the  -rP$$page  portion of the rule.
This is setting number register  P  to the contents of the
page  environment variable.  This assumes you have a
version of  make  that looks at environment variables.

Why the double  $  sign?   make  uses the  $  sign to
mark the onset of a macro reference.  If you simply coded
it as  $page  as in your query,  make  would expand this
reference as  whatever `p' is defined to be, followed by
the letters `age'.  Chances are, this would expand to
	
    troff  -Tlw  -ms  -t  age  c1.ms > c1.dit
    
and  troff  would then complain about not being able to
open file `age'.  The double  $  sign expands to a single
$  sign, and then the Shell fills in the result of  $page
when the Shell eventually gets to running the  troff  command.

How would you use this?  You would do something like:

    setenv  page  5		(if you're using the C Shell)
    make  chapter1.dit

But, rather than messing with environment variables, you could
simply pass the page number into the  make  process as a make
macro.  Modify the  Makefile  to read:

    6	.ms.dit:
    7	        $(FORMATTER) -rP$(PAGE)  $<  >  $@

and then you type

    make  chapter1.dit  PAGE=5

Now, so far, I haven't said how you get the starting page
number into the actual  troff process.  At the start of each
of your chapters, you could write something like this:

    1	.LP
    2	.rs
    3	.if \nP
    4	.bp \nP
    5	.NH 1
    6	Chapter One Heading
    7	.LP
    8	text

Line 1 is the  .LP  (or  .PP, .IP, .QP, or whatever) you need
to get the  -ms  macro package initialised.

Line 2 clears no space mode so the  .bp  will have effect.

Line 3 asks if the  P  number register has been set to something
other than zero from the  troff  command line.  If it has, line
4 does a page eject withe that page number as the start page number.

There are other approaches, but they involve making changes to
the macro package.

Here is another approach.  This one assumes you're using
device independent troff.  Device independent troff places the
page number at the start of each `page' in its output file.
The page number just appears at the start of the line, like

    p123

for page 123.  Note that the page number is the actual 
number printed at the bottom of the page, as a decimal
number.

This means that you can discover the number of the last
printed page by simply doing

    grep ^p  outputfile.dit

The last page number printed will be the last line of output
from grep.  

For example, I have this file called  c1.dit  and I can run
grep  to get the result like this:

    grep ^p  c1.dit
    p1
    p5
    p6

Why is there a p1 in the file?  That's because of the
extra blank page generated by the  .bp  in the example
earlier.  The real start of the chapter is at page 5, and
the chapter is two pages long.

Now I can embellish this process a little by doing:

    grep ^p  c1.dit | sed  -n -e '$s/p//p'
    6

The  sed  command goes to the last line of its input,
subsitutes the letter `p' for nothing, and prints the
result.  So, now you get the number 6.

How would you use this magic?  Suppose you already had
built chapter1.dit, and you now want to start on chapter2.dit.
The starting page number for chapter2.dit can be obtained by:

    make  chapter2.dit  PAGE=`grep ^p  chapter1.dit | sed  -n -e '$s/p//p'`

Finally, suppose all your chapter pages should start on odd
numbered pages.  Pipe the output of  sed  into this silly
little  awk  program:

    awk '{ if ($0 % 2 == 0) print $0 + 1; else print $0 + 2 }'

I package the  grep,  sed, and  awk  stuff into a little Shell
script called getlast or something like that, and use it instead
of the complex command line.
+------------------+------------------------+---------------------------+
| Henry McGilton   | I saw the future,      | arpa: hmcgilton@sun.com   |
| Sun Microsystems | and it didn't work.    | uucp: ...!sun!angel!henry |
| Mt. View, CA     |                        |                           |
+------------------+------------------------+---------------------------+

yost@esquire.UUCP (David A. Yost) (08/31/89)

In article <5689@ttidca.TTI.COM>, kevin@ttidca.TTI.COM (Kevin Carothers) writes:
>
> I have a very large document, consisting of multiple
> chapters, and I would like to pass the ending page from
> the previous chapter to the first page of the next
> chapter (plus 1, of course).

I don't have my solution online, but it's one
of the few things I ever did with troff that
was easier than I thought it would be, in
fact much easier.

* Make a directory called pn for page number files
* Make a file called pn/ch1.end.
* Link it to pn/ch2.begin.
* At the end of chapter one,
  .tm or .sy out the chapter number into pn/ch1.end.
* At the beginning of chapter 2, .so pn/ch2.begin.

Why the tricky linking, you ask.  For full
automation.  You want to simply call
.BEGIN_FILE at the beginning of the file, and
.END_FILE at the end, without hard coding
the file's name in itself (why worry about
editing the file just because you've changed
its name.)  When your makefile runs troff, it
sets a string variable to the filename, so
those macros can do their work with the
appropriate external files.

Now make a master file containing the names
of the source files in the order they appear
in the book, then write a shell script that
ensures that the right pn files exist and
that they are properly linked.

.PUTREF refs
In a similar vein, it is amazingly easy to do
page-numbered cross references in troff (see
p. \
.GETREF refs
).  You pick a name for each reference
target, and you have at least two macros, one
that outputs the current page number to a
file of that name and another that reads the
page number in.

Now the trick is to take the time to learn
TeX and apply all this technology to that
environment so I never have to touch troff
again.

 --dave yost