From: jafortun@vela.acs.oakland.edu (James Fortune)
Subject: Latest LaTeX altnline.sty revisions
Organization: Oakland University, Rochester MI.
Date: Sun, 3 Jan 1993 12:38:22 GMT

>From ntomczak@vega.math.ualberta.ca Sat Dec 26 02:20:15 1992
>From: N Tomczak-Jaegermann <ntomczak@vega.math.ualberta.ca>
>Subject: altnlines.sty - 1.1
>To: jafortun@vela.acs.oakland.edu
>Date: Sat, 26 Dec 92 0:19:13 MST

.
.
.

>I played some with 1.0 and added some stuff which you obviously
>wanted to include but you left it alone for a time beeing.  I also
>made some other changes throwing out excessive \global's, modyfying
>the code a little bit and the like.  Unfortunately I do not know
>enough about LaTeX output routine to really know how to code the
>stuff to shut up error messages.  I managed to do that with plain
>but this is obviously not good enough.  I do not know if this will
>be of any help with your other problems.  With not too complicated
>text this stuff seems to work ok.  Equations are not a problem, but
>I did not try what will happen in a presence of float.

>   Merry Xmas and Happy New Year,
>   Michal

Thanks Michal for helping to make it happier.

I was quite impressed with the changes Michal made and the underlying 
understanding of output routines they demonstrate.  BTW, no one else
sent me any comments at all this time.  Here are my remaining comments:

1.  altnline.sty still wipes out hanging indentation.  For long quotations
    the indentation is lost and the right side numbers are moved slightly
    to the left on odd pages until the quotation is ended.  Anyone know
    how I can preserve the indentation when line numbering is occurring?

2.  Since it counts zero length lines I will try something like \parskip
    rather than \\ to separate paragraphs (The editor insisted on a blank
    line between paragraphs to keep in line with other books in the series).

3.  Those using plain TeX can use a similar scheme much more easily.
    I'll try putting \shipout\box255 in the \output definition to see
    if it gets rid of the messages without messing things up.  If I
    find a location that works I'll post it.

4.  Thanks again to all who helped (Cameron Smith, Michal Jaegermann, and
    Rainer Schoepf).  

JAF
---------------------------------------------------------------------------
% altnline.sty    Version - 1.1
%
% Disclaimer - Use at your own risk.
%
% James Fortune                 
% Oakland University            
% jafortun@vela.acs.oakland.edu 
%
% Based upon the TUGboat article ``Output Routines: Examples and Techniques.''
% that appeared in Volume 11 (1990), Nos. 1, 3 and 4.
%
% This version incorporates suggestions made by Michal Jaegermann, namely:
%
% * Include explicit reference to the TUGboat article
% * ``You can use \def in style files without violating LaTeX spirit.
%     If you are writing style it is assumed that you know what you are
%     doing. :-)'' --- I don't know what I'm doing so I left the \newcommand
%   and \renewcommand commands as is.
% * Internal macros from style file should be protected against name conflicts
%   with user stuff by inclusion of '@' character in names. --- This is quite
%   reasonable so command names that the user is not expected to use in a
%   LaTeX file have been changed to include the '@' character.
% * He sent a new appendline command that adds numbers on a left margin
%   only that was also inspired by the Salomon article.  He left it as an
%   exercise for me to modify it for two-sided printing.  I probably shouldn't
%   have picked something from the double dangerous bend signs for my first
%   serious attempt at hacking on a style file :-).
% * A global linesSoFar so that lineCount may be set to linesSoFar to deal
%   with box255 being broken from the bottom up.  countlines (or its
%   equivalent) advances linesSoFar by a count of lines on a current page.
% * Use of a decremented remainder variable to determine when to add a number
%   to a line. --- I'm trying to get all the lines first.
% * He advised not trying to combine the countlines and duplicate operations
%   into a single loop.  ``I am afraid that you really have to first count
%   how many lines you have on a page and later use this value to produce
%   line numbers.''
%
% Changes to version 1.1 - Michal Jaegermann, ntomczak@vega.math.ualberta.ca
%
% * Added logic to print line numbers only every \lineCountInterval
% * Added a way to set up ONE range of numbered lines; use \nlinesBoundary
%   to do that. (It is possible to sprinkle your text with \nlinesBoundary
%   commands and they may even do the right thing if you will put them
%   in right places - but this is a hack.)
% * Miscellaneous cleanup
% * Every implicit or explicit \clearpage will still cause
%   'Output routine didn't use all of \box255' message.  Any volunteers
%   who know enough about LaTeX output routine to repair that?
%
   
% \font\sevenrm=cmr7

% Rainer showed me how to save the previous \output.  Thanks Rainer.
\newtoks\LaTeX@output
\LaTeX@output = \expandafter{\the\output}

\newcommand\zero@ToSp{\parskip=\@ne sp plus\@ne pt
  \renewcommand\vfil{\vskip1sp plus1fil}
  \renewcommand\vfill{\vskip1sp plus1fill}
  \abovedisplayshortskip=\@ne sp plus3pt
  \postdisplaypenalty=\@ne
  \interlinepenalty=\@ne}

\zero@ToSp


\newcount\lin@CountInit  % used to establish lineCount of first line on page
\lin@CountInit=\z@
\newcount\lineCountInterval  % used to determine how often lin@Count is printed
\lineCountInterval=5
%
\newcount\lin@CountStart  % don't print line numbers below this value
\lin@CountStart=\@ne
\newcount\lin@CountFinish  % don't print line numbers higher than this
\lin@CountFinish=\m@ne
%
% A command to set boundaries for line numbering.  Use as:
%   \nlinesBoundary{12}, or \nlinesBoundary[50]{12}
%   \nlinesBoundary[<optional upper limit>]<lower limit>
% Any negative number for an upper limit means number to the very end.
% This is a default!
%
\def\nlinesBoundary{\@ifnextchar[{\nlin@sBoundary}{\nlin@sBoundary[\m@ne]}}
\edef\nlin@sBoundary[#1]#2{%
  \global\lin@CountFinish=#1\relax
  \global\lin@CountStart=#2\relax}

\newif\ifa@@lnum  % do we really want to print that line number?

\newcount\lin@sSoFar
% remainder from division of \lin@sSoFar by \lineCountInterval
\newcount\total@Rem
% current value of remainder used to produce line numbers
\newcount\lin@rem
% these calculations allow to start with \lin@CountInit different from 0
\newcommand\resetlin@sSoFar{%
  \global\lin@sSoFar=\lin@CountInit
  \total@Rem=\lin@CountInit
  \divide\total@Rem by\lineCountInterval
  \multiply\total@Rem by-\lineCountInterval
  \global\advance\total@Rem by\lin@CountInit}

\resetlin@sSoFar

\newcount\lin@Count
\newif\ifAnyleft \newcount\pen
\newcommand\count@lines{%
  \global\lin@Count=\lin@sSoFar
  \loop \Anyleftfalse
    \ifdim\lastskip=\z@ \ifdim\lastkern=\z@ \ifnum\lastpenalty=\z@
      \setbox0=\lastbox
    \ifvoid0
    \else \Anylefttrue \global\advance\lin@Count by\@ne
                       \global\advance\total@Rem by\@ne
                       \ifnum\total@Rem=\lineCountInterval
                          \global\total@Rem=\z@
                       \fi\fi
    \else \Anylefttrue \unpenalty \fi
    \else \Anylefttrue \unkern \fi
    \else \Anylefttrue \unskip \fi
  \ifAnyleft \repeat}

\newcommand\@duplicate{%
  \loop \Anyleftfalse
    \ifdim\lastskip=\z@ \ifdim\lastkern=\z@ \ifnum\lastpenalty=\z@
      \global\setbox0=\lastbox \ifvoid0 % end of breakup loop
    \else \Anylefttrue                  % box present
      \ifnum\lin@rem=0                  % if remainder non-zero we do not care
        \lin@rem=\lineCountInterval
        \ifnum\lin@Count<\lin@CountStart
          \a@@lnumfalse
        \else
          \ifnum\lin@CountFinish<0      % no upper bound
            \a@@lnumtrue                % print it
          \else
            \ifnum\lin@Count>\lin@CountFinish
              \a@@lnumfalse
            \else
              \a@@lnumtrue              % this is the ticket
            \fi
          \fi
        \fi
      \else
         \a@@lnumfalse
      \fi
      \ifa@@lnum
         \append@line
      \else
         \global\setbox1=\vbox{\box0\unvbox1}
      \fi
      \advance\lin@Count\m@ne
      \advance\lin@rem by\m@ne\fi
    \else \Anylefttrue                  % penalty present
      \pen=\lastpenalty
      \global\setbox1=\vbox{\penalty\pen\unvbox1}\unpenalty\fi
    \else \Anylefttrue                  % kern present
      \dimen0=\lastkern
      \global\setbox1=\vbox{\kern\dimen0\unvbox1}\unkern \fi
    \else \Anylefttrue                  % skip present
      \skip0=\lastskip
      \global\setbox1=\vbox{\vskip\skip0\unvbox1}\unskip \fi
    \ifAnyleft \repeat}

\newcommand\append@line{%  attach line number
  \setbox2=\vbox to \z@{\smash{\footnotesize\the\lin@Count}}
  \wd2=25pt                           % that much of space for a line number
  \ifodd\count0                       % on the right margin for odd pages
     \setbox0=\hbox{\box0\rlap{\rule{\wd2}{\z@}\box2}}  
  \else                               % and on the left for even
     \setbox0=\hbox{\llap{\box2}\box0}
  \fi
  \global\setbox1=\vbox{\box0\unvbox1}} % add this to a reconstructed page

\newbox\brk    % Use old output definition if page is not to be output
\output={\ifnum\outputpenalty <-\@M
  \output={\LaTeX@output}
\else
  \lin@Count=\lin@sSoFar
  \setbox\brk=\vbox{\unvcopy\@cclv\count@lines}
           \global\setbox1=\vbox{}
           \lin@rem=\total@Rem
  \global\lin@sSoFar=\lin@Count
  \setbox\brk=\vbox{\unvcopy\@cclv\@duplicate}
  \ifdim\ht\brk>\z@\message{Incomplete breakup}\fi
  \ht1=\z@\dp1=\z@
  \global\setbox\@cclv=\vbox to\vsize{\unvbox1}% attempt to get glues back
  \@makecol\@opcol
\fi}
\endinput

---------------------------------------------------------------------------
-- 
James Fortune                  - Internet: Thousands of people mostly unaware
Oakland University             - of the sight and sound of each other, linked
jafortun@vela.acs.oakland.edu  - together by the bits of our souls that can
Disclaimer: Not O.U. opinions  - fit through computer keyboards.
Newsgroups: comp.text.tex