🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.text
Article #683

Re: page numbering between chapters in nroff

#683
From: Henry McGilton -- Software Produ...
Date: Wed, 30 Aug 1989 22:08
208 lines
7915 bytes
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     |                        |                           |
+------------------+------------------------+---------------------------+
Technical Details
Message-ID: <124007@sun.Eng.Sun.COM>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watmath!att!dptg!rutgers!apple!sun-barr!newstop!sun!angel!henry
References: <5689@ttidca.TTI.COM>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!watmath!att!dptg!rutgers!apple!sun-barr!newstop!sun!angel!henry
From: henry%angel@Sun.COM (Henry McGilton -- Software Products)
Newsgroups: comp.text
Subject: Re: page numbering between chapters in nroff
Message-ID: <124007@sun.Eng.Sun.COM>
Date: 30 Aug 89 22:08:41 GMT
References: <5689@ttidca.TTI.COM>
Sender: news@sun.Eng.Sun.COM
Lines: 208