[net.text] proposed new troff

budd@arizona.UUCP (07/22/83)

        Thanks for the many cards and letters on my proposed revision
for troff.  I'm about to leave for vacation (Aug 4th, so you still have
time to get in a flame or two), but before I did I thought I would give
an example of what I am contemplating.  Following this note I have
attached (in shar format) three files.  The first two are an example
of input/output of a document illustrating some of my ideas of what
troff macros should really look like.  Scribe users will note the
obvious influence of that system, which is in my opinion a fairly good
model, as far as it goes (it doesn't have quite the versatility of
troff, for example - no mathematics).

        The third file is the set of macros that were used to generate
the second file from the first.  Note that these macros will NOT work
in normal troff, they are for the initial version of my new system.
I am mostly interested in getting feedback on whether you think the new
macros are easier to read/write/understand than those generated for troff.
Before you have a chance to understanding them, however, some explanation
must be given:

1.      The 82 troff commands listed in the manual have been reduced to
about 50 or so.  This was largely done by removing commands that only
set a register value (ps, ll, ls, etc) and replacing them with a .nr
on the appropriate register.

2.      There are several new commands associated with environments.
Environments can be named, and you can have any number of them.  The
command "cv name" pushes a new environment on the environment stack,
which is either uninitialized (no arg given) or initialized the same
as the named environment (note this is a copy, the named environment is
not changed).  "ev name" is the same as cv, only any attributes not
explicitly set are inherited from the previous environment.  "pv name"
pops the environment stack, and if an arg is given saves it under the
given name.  "rv name" clobbers the current environment on the stack,
making it match the named environment.

3.      Environments have 10 registers associated with them, named
r0 to r9.  These can be referenced, whether or not you are in the
associated environment, by <env name-register name>.

4.      Macros can be invoked in line during copy mode processing, using
the format \*{name args}.  There is a return statement for macros (.rt)
and a while loop (.wy).  The next major change will be to allow macros
to have local variables.  (Also on the todo stack- registers and strings
are to be unified into one datatype - variable.  This means number registers
and strings will share a namespace, and will be evaluated the same way).

5.      Tasks which i knew how to do, didn't need to do to get to the
next problem, and which seem uninteresting i have left undone.  Thus,
for example, the symbol table still only allows two character names,
although THIS WILL BE CHANGED as soon as i get around to it to allow
arbitrary length names.  Naming will be by \#a, \#(aa or \#{aaaaaa}.
When this finally gets done several names in the macro package will
be made somewhat more meaningful.  So don't flame about the silly two
character names - it's not an important issue.
Also i have not installed the both margin justification algorithm,
since this can just be copied from K&P, I had intended to do this but
ran out of time, so the example is a bit silly in that regard.


        Thoughtful remarks and suggestions are solicited and welcomed.

--tim budd      {teklabs, ucbvax, kpno} | arizona | budd





echo x - example
cat >example <<'!Funky!Stuff!'
.so macros
.PP
The next three paragraphs (actually the same paragraph repeated three
times over) illustrate the effect of adjustments.  The first is created
using left adjustment, which is the default for the paragraph
environment (this can be overridden, if desired).  The second is
justified on both margins, and is obtained by giving the "PP ad b" command.
The third is right justified, which is somewhat odd but is nevertheless
legal.  The final is truly odd, being a paragraph which is both filled
and centered.
.PP ad b
The next three paragraphs (actually the same paragraph repeated three
times over) illustrate the effect of adjustments.  The first is created
using left adjustment, which is the default for the paragraph
environment (this can be overridden, if desired).  The second is
justified on both margins, and is obtained by giving the "PP ad b" command.
The third is right justified, which is somewhat odd but is nevertheless
legal.  The final is truly odd, being a paragraph which is both filled
and centered.
.PP ad r
The next three paragraphs (actually the same paragraph repeated three
times over) illustrate the effect of adjustments.  The first is created
using left adjustment, which is the default for the paragraph
environment (this can be overridden, if desired).  The second is
justified on both margins, and is obtained by giving the "PP ad b" command.
The third is right justified, which is somewhat odd but is nevertheless
legal.  The final is truly odd, being a paragraph which is both filled
and centered.
.PP ad c
The next three paragraphs (actually the same paragraph repeated three
times over) illustrate the effect of adjustments.  The first is created
using left adjustment, which is the default for the paragraph
environment (this can be overridden, if desired).  The second is
justified on both margins, and is obtained by giving the "PP ad b" command.
The third is right justified, which is somewhat odd but is nevertheless
legal.  The final is truly odd, being a paragraph which is both filled
and centered.
.PP in +10m sp 3v
Other attributes can be similarly altered.  For example this
paragraph has been indented 10m.  As you can see, it is further to the
right than the others.
Also, the amount of space between it and the last paragraph has been
increased by modifying the sp attribute.
.PP ll -10m ti 2m
The line length can be changed by given the command "PP ll -10m", for
example, which will produce lines shorter on the right.
Also the amount of space the paragraph is initially indented has
been reduced by using the "ti 2m" attribute specification.
.MA PE ti 7m
.PP
You can make a permanent change to an environment attribute using the
MA command.  For example, we have just changed the default paragraph
environment so that paragraphs are now indented by 7m.  The command
to do this was "MA PE ti 7m".
.PP in +10m ll -10m
Both the right and left margins can be indented by using the command
form "PP in +10m ll -10m".  This is the same as QS and QE in the ms
macro package.
.LP fi n
An Unfilled paragraph is like a display.
Here there are lines
of different lengths, nevertheless
it is not filled.
.LP fi n ad r
It can, however, be given an adjustment.
Here an unfilled paragraph is
right adjusted.

A blank line normally starts a new paragraph, as was done here.
This can be changed by giving the pg command.  The pg command
followed by a macro name establishes that macro as the macro
to execute on blank lines.  The pg command followed by no
argument turn this feature off.

There is a new form for command invocation.  Besides the normal initial
dot convention, a construct of the form \\*{name args} will evaluate
the macro "name" in COPY MODE (ie, before the line is decoded).  Macros
can act as functions using the .rt command to return a value.  There
are a few built in commands for such actions as subscripting and
character translation.  There is also a new while loop (wy - perhaps
it should be wyle loop).  For a grand example of all of this see the
roman number conversion routine in the macro package.  For an example
of its use, if you type \\*{RO 1983} you get \*{RO 1983}.  There is
also an upper case version \*{Ro 1983}.
!Funky!Stuff!
echo x - exam.out
cat >exam.out <<'!Funky!Stuff!'



0
                                top of page
                                                                0


     The next three paragraphs (actually the same paragraph
repeated three times over) illustrate the effect of adjustments.
The first is created using left adjustment, which is the default
for the paragraph environment (this can be overridden, if
desired).  The second is justified on both margins, and is
obtained by giving the "PP ad b" command.  The third is right
justified, which is somewhat odd but is nevertheless legal.  The
final is truly odd, being a paragraph which is both filled and
centered.

     The next three paragraphs (actually the same paragraph
repeated three times over) illustrate the effect of adjustments.
The first is created using left adjustment, which is the default
for the paragraph environment (this can be overridden, if
desired).  The second is justified on both margins, and is
obtained by giving the "PP ad b" command.  The third is right
justified, which is somewhat odd but is nevertheless legal.  The
final is truly odd, being a paragraph which is both filled and
centered.

           The next three paragraphs (actually the same paragraph
 repeated three times over) illustrate the effect of adjustments.
 The first is created using left adjustment, which is the default
        for the paragraph environment (this can be overridden, if
       desired).  The second is justified on both margins, and is
    obtained by giving the "PP ad b" command.  The third is right
 justified, which is somewhat odd but is nevertheless legal.  The
   final is truly odd, being a paragraph which is both filled and
                                                        centered.

     The next three paragraphs (actually the same paragraph
repeated three times over) illustrate the effect of adjustments.
The first is created using left adjustment, which is the default
    for the paragraph environment (this can be overridden, if
   desired).  The second is justified on both margins, and is
  obtained by giving the "PP ad b" command.  The third is right
justified, which is somewhat odd but is nevertheless legal.  The
 final is truly odd, being a paragraph which is both filled and
                            centered.



               Other attributes can be similarly altered.  For
          example this paragraph has been indented 10m.  As you
          can see, it is further to the right than the others.
          Also, the amount of space between it and the last
          paragraph has been increased by modifying the sp
          attribute.

  The line length can be changed by given the command
"PP ll -10m", for example, which will produce lines
shorter on the right.  Also the amount of space the
paragraph is initially indented has been reduced by
using the "ti 2m" attribute specification.

ixcmzvldw
                              bottom of page
                                                                0







1
                                top of page
                                                                i


       You can make a permanent change to an environment
attribute MA command.  For example, we have just changed the
default paragraph environment so that paragraphs are now
indented by 7m.  The command to do this was "MA PE ti 7m".

                 Both the right and left margins can
          be indented by using the command form "PP in
          +10m ll -10m".  This is the same as QS and
          QE in the ms macro package.

An Unfilled paragraph is like a display.
Here there are lines
of different lengths, nevertheless
it is not filled.

                         It can, however, be given an adjustment.
                                    Here an unfilled paragraph is
                                                  right adjusted.

       A blank line normally starts a new paragraph, as was done
here.  This can be changed by giving the pg command.  The pg
command followed by a macro name establishes that macro as the
macro to execute on blank lines.  The pg command followed by no
argument turn this feature off.

       There is a new form for command invocation.  Besides the
normal initial dot convention, a construct of the form \*{name
args} will evaluate the macro "name" in COPY MODE (ie, before
the line is decoded).  Macros can act as functions using the .rt
command to return a value.  There are a few built in commands
for such actions as subscripting and character translation.
There is also a new while loop (wy - perhaps it should be wyle
loop).  For a grand example of all of this see the roman number
conversion routine in the macro package.  For an example of its
use, if you type \*{RO 1983} you get mcmlxxxiii.  There is also
an upper case version MCMLXXXIII.



















I
                              bottom of page
                                                                1




!Funky!Stuff!
echo x - macros
cat >macros <<'!Funky!Stuff!'
.nr sm 1                        \" turn space mode on
.nr pn 0                        \" first page is numbered 0
.nr np 1                        \" next page will be 1
.\"Top of Page Processing
.cv TE                          \" first define top of page environment
.nr ad 'l'
.nr in 1i
.nr ti 0
.nr r1 1c                       \" where top banner is going
.nr r2 1i                       \" top of useful page
.pv TE                          \" pop environment, capture attributes
.\"
.wh 0 TP                        \" at top of page, spring TP macro
.\"
.de TP                  \" TP - top of page macro ------------------
.ev TE                          \" first get into TP environment
.nr sm 1                        \" restore spacing
.sp |\\#(r1u                    \" move to where banner goes
.TL \\#(pn "top of page" \\*{RO \\#(pn}
.sp |\\#(r2u                    \" move to top of user page
.pv                             \" pop back out of top of tape environment
.nr sm 0                        \" turn no spacing mode on
..
.\"Bottom of Page Processing
.cv BE                          \" define bottom of page environment
.nr ad 'l'
.nr in 1i
.nr ti 0
.nr r1 0-1i                     \" where the bottom of page trap goes (floats)
.nr r2 \#(r1+2v                 \" where bottom banner goes
.nr r3 0-1i                     \" whre the bottom goes (perm)
.pv BE                          \" pop off and capture bottom environment
.\"
.wh \#<BE-r3> BP                \" set up bottom of page trap
.wh \#<BE-r3> FX                \" set up footnote soaker (hidden unless needed)
.\"
.de BP                  \" BP - bottom of page trap
.nr <BE-r1> 0+\\#<BE-r3>        \" reset where bottom of page trap is
.rm FY                          \" remove footnote overflow area
.if \\#<FE-r2> \{               \" if there are footnotes
.ev DE                          \" get in an appropriate environment
.FB                             \" and dump them out
.br
.ie \\#(dl \{
.di                             \" footnotes overflowed, end diversion
.nr <BE-r1> -\\#(dnu            \" change footnote position
.rn FY FB                       \" remove footnote body
.\}
.el \{
.rm FB                          \" else remove body
.nr <FE-r2> 0                   \" no footnotes now
.\}
.nr sm 1                        \" insure space mode is on
.sp |\\#<BE-r3>                 \" go to top of normal BP, springing FX
.sp 1u                          \" just a bit more, make sure fx is spung
.pv                             \" restore environment
.\}
.ev BE                          \" get in bottom of page environment
.nr sm 1                        \" insure space mode is on
.sp |\\#(r2u                    \" go to where banner goes
.TL \\*{Ro \\#(pn} "bottom of page"  \\#(pn
.br
.pv                             \" go back to previous environment
.ch BP \\#<BE-r1>               \" reset bottom of page footnote trap
'bp                             \" now break page, without line break
..
.de FX                          \" soak up excess footnotes
.if \\#<FE-r2> \{
.ev                             \" ev allows bar to get in before text
.di FY                          \" start up new diversion
.br
-------
.br
.pv                             \" pop back to old ev to get rest of text
.\}
..
.\"Footnote management
.cv FE                          \" define footnote environment
.nr in 0
.nr ti 0
.nr r1 1v                       \" amount to space on footnotes
.nr r2 0                        \" number of footnotes on current page
.pv FE
.\"
.cv DE                          \" DE - display environment,
.nr fi 'n'                      \" can be used to display diversions
.nr ls 1                        \" since it takes the text
.nr ad 'l'                      \" verbatim, no change
.pv DE
.\"
.de FS                  \" FS - footnote start
.ne 4                           \" need enough space for reference and 1 line
.nr <FE-r2> +1                  \" add 1 to footnote counter
.ev FE                          \" get into the right environment
.AT \\$*                        \" modifying attributes if user wants
.da FB                          \" divert into footnote body
.ie 1=\\#(r2 \{
--------------
.br \}
.el .sp \\#(r1u
..
.de FE                  \" FE - footnote end
.br                             \" break any pending text
.di                             \" end diversion
.pv                             \" restore previous environment
.nr <BE-r1> -\\#(dnu            \" change location of bottom page trap
.ch BP \\#<BE-r1>               \" change bottom of page trap
.if ((\\#(pl+\\#<BE-r1>) < \\#(cx ) .BP         \" too big, spring trap now
..
.\"Three part titles
.de TL
.ev
.nr ls 0
.nr fi 'n'
.nr ad 'l'
\\$1
.br
.nr ad 'c'
\\$2
.br
.nr ad 'r'
\\$3
.br
.pv
'sp 1v
..
.\"Environment Attribute Setting
.de NS  \" see if a spefic attribute was specified
.nr xx 2
.nr xy 1
.wy \\#(xx < \\#(.$ \{
.if '\\$1'\\$\\#(xx' .nr xy 0
.nr xx +1
.\}
.rt \\#(xy
..
.de AT  \" set attributes
.nr xx 1
.wy \\#(xx < \\#(.$ \{
.ds x1 \\$\\#(xx
.nr xx +1
.ds x2 \\$\\#(xx
.nr xx +1
.SA \\*(x1 \\*(x2
.\}
..
.de SA  \" single set attribute processor
.if '\\$1'ls' .nr ls \\$2
.if '\\$1'll' .nr ll \\$2
.if '\\$1'ps' .nr ps \\$2
.if '\\$1'vs' .nr vs \\$2
.if '\\$1'in' .nr in \\$2
.if '\\$1'ti' .nr ti \\$2
.if '\\$1'sp' .nr is \\$2
.if '\\$1'ad' .nr ad '\\$2'
.if '\\$1'fi' .nr fi '\\$2'
..
.de MA                          \" MA - modify environment
.cv \\$1
.AT \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
.pv \\$1
..
.\"Paragraffitti
.ev PE                          \" push a new environment for text
.nr ls 1v
.nr fi 'f'
.nr ad 'l'
.nr ti +5m
.nr is 40u
.pv PE
.\"
.pg PP                          \" a blank line gets a new paragraph
.\"
.de PP                  \" PP - standard paragraph start
.br                             \" break any pending text
.rv PE                          \" reset attributes
.AT \\$*                        \" change any attributes user specified
.sp \\#(isu                     \" issue initial space
.nr ti +\\#(in                  \" take whatever ti was given and add indent
.nr sm 0                        \" turn on no space mode
..
.de LP
.br
.rv PE
.nr ti 0                        \" same as pp with no initial ti
.AT \\$*
.sp \\#(isu
.nr ti +\\#(in                  \" but perhaps the user gave one
.nr sm 0
..
.\"Register Instructions
.de EV                          \" EV - Evaluate an arbitrary expression
.nr xx \\$1
.rt \\#(xx
..
.de r+                          \" r+ register post increment (for in line use)
.nr xx \\#{\\$1}
.ie ''\\$2' .nr \\$1 +1
.el .nr \\$1 +\\$2
.rt \\#(xx
..
.de r-                          \" r- register post decrement (for in line use)
.nr xx \\#{\\$1}
.ie ''\\$2' .nr \\$1 -1
.el .nr \\$1 -\\$2
.rt \\#(xx
..
.de +r                          \" +r register pre increment
.ie ''\\$2' .nr \\$1 +1
.el .nr \\$1 +\\$2
.rt \\#{\\$1}
..
.de -r                          \" -r register pre decrement
.ie ''\\$2' .nr \\$1 -1
.el .nr \\$1 -\\$2
.rt \\#{\\$1}
..
.\"Roman Number Conversion
.de RO                          \" RO - roman number algorithm
.ie 0=\\$1 .ds zz 0
.el .ds zz \\*{R1 \\$1 ixcmz vldw}
.rt \\*(zz
..
.de R1                          \" roman number algorithm - internals
.ds xx
.if \\$1 \{
.ev
.ds xx \\*{R1 \\*{EV \\$1/10} \\*{ss \\$2 1 10} \\*{ss \\$3 1 10}}
.nr r1 \\$1 % 10
.nr r2 \\#(r1 / 5
.nr r3 \\#(r1 % 5
.ie 4=\\#(r3 \{
.as xx \\*{ss \\$2 0 1}
.ie 1=\\#(r2 .as xx \\*{ss \\$2 1 1}
.el .as xx \\*{ss \\$3 0 1}
.\}
.el \{
.if \\#(r2 .as xx \\*{ss \\$3 0 1}
.wy \\*{r- r3}>0 .as xx \\*{ss \\$2 0 1}
.\}
.pv
.\}
.rt \\*(xx
..
.de Ro                          \" Ro - upper case roman number
.rt \\*{tr \\*{RO \\$1} ixcmzvldw0 IXCMZVLDW0}
..
!Funky!Stuff!