%%% ==================================================================== %%% @LaTeX-style-file{ %%% author = "Michal Jaegermann and James Fortune", %%% version = "1.3", %%% date = "06 Aug 1995", %%% filename = "numline.sty", %%% address = "10923 36Av, Edmonton, %%% Alberta, CANADA T6J 0B7", %%% telephone = "403 438 7012", %%% email = "michal@ellpspace.math.ualberta.ca %%% jafortun@vela.acs.oakland.edu (Internet)", %%% codetable = "ISO/ASCII", %%% keywords = "line numbers", %%% supported = "yes (sort of)", %%% abstract = "LaTeX style file for putting line numbers on %%% margins of at least some documents which will %%% survive such treatment. It works modifying %%% LaTeX output routine, so do not expect that %%% this will work on anything but simple text! %%% If it does then you are very lucky person. %%% On the other hand is equally happy with %%% LaTeX2e as with LaTeX 2.09 %%% %%% In some situations you should be able to %%% adjust it for special needs but do not expect %%% miracles. For plain TeX try EDMAC by Dominik %%% Wujastyk. %%% %%% This style provides: %%% - continuous line numbering for the whole %%% document or, if \lnumpagetrue, restarted %%% on every page %%% - numbers on alternate margins when 'twoside' %%% document option is in force %%% - ajustable interval between line numbers %%% given by a value of \lineCountInterval counter %%% - settable ranges of numbered lines %%% with \nlinesBoundary macro %%% - changing line witdth together with indent.sty %%% See comments and examples below.", %%% } %%% ==================================================================== % % HISTORY: % % Based upon the TUGboat article ``Output Routines: Examples and Techniques.'' % by David Salomon that appeared in Volume 11 (1990), Nos. 1, 3 and 4. % % Started by James Fortune as altnline.sty with some help and advice % from MJ which later hacked it for quite a while. % % Changes for version 1.0 % % * Protect internal macros by including '@' in their names. % * Split countlines and duplicate operations from a single loop % (does not work that way). % % Changes for version 1.1 (mj) % % * 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 % % Changes for 1.2 (mj) % * Prevent 'Output routine didn't use all of \box255' messages % * Add code to handle, in a fashion, indentation generated by indent.sty % * Add switch to restart numbering on every page % * Make switching enumeration margins dependent on 'twoside' option % % Changes for 1.3 (mj) % * None whatsoever to the code % * Confirmed that it works to the same extent as before :-) with LaTeX2e. % * More dire warninigs comments explaining how to make a document % work with numline.sty when it doesn't. % USER INTERFACE: % % In your document you have an access to: % * a conditional \lnumpage which can be set with \lnumpagetrue % or \lnumpagefalse (default); when true line numbers are reset % on every page; % * a counter \lineCountInterval (default 5) to set interval between % line numbers % * a command \nlinesBoundary to set boundaries for line numbering; % example of use: % \nlinesBoundary{12}, or \nlinesBoundary[50]{12} % with \nlinesBoundary[] % Any negative number for an upper limit means number to the very end. % This is a default! % DIRE WARNINGS: % % This IS a hack doing things which is not supposed to do by messing % with LaTeX output routine. It works as expected with versions of % LaTeX I tested it, but your mileage may vary. In particular, if % some your other package does something with \output then you may % have problems forcing such two to cooperate. % % You may still use this on more documents than it looks like at the % first blush. If you will see ``Incomplete breakup'' message consult % DREADED INCOMPLETE BREAKUP section (it follows sample input) for % some day saving hints. % INDENTING: % Any changes in line width caused by indent.sty have the same effect. % So \begin{indentation}{2em}{2em} and \begin{indentation}{4em}{0pt} % are equivalent. Positioning of indented lines can be only performed % by modifications in a definition of \@duplicate. Check examples % below. % % various counters % \newcount\lineCountInterval % used to determine how often lin@Count is printed \lineCountInterval=5 % \newcount\lin@CountInit % used to establish lineCount of first line on page \lin@CountInit=\z@ \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 % \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 % % A command to set boundaries for line numbering. % \def\nlinesBoundary{\@ifnextchar[{\nlin@sBoundary}{\nlin@sBoundary[\m@ne]}} \edef\nlin@sBoundary[#1]#2{% \global\lin@CountFinish=#1\relax \global\lin@CountStart=#2\relax} % % if's % \newif\iflnumpage % if true restart line numbers on every page % \newif\ifa@@lnum % do we really want to print that line number? % % make page easier to break into lines % \def\zero@ToSp{\parskip=\@ne sp plus\@ne pt \def\vfil{\vskip1sp plus1fil} \def\vfill{\vskip1sp plus1fill} \abovedisplayshortskip=\@ne sp plus3pt \postdisplaypenalty=\@ne \interlinepenalty=\@ne} \zero@ToSp % It is possible to change a "look" of numbering by modifications % of this macro; in particular calculations below allow to start % with \lin@CountInit different from 0 \def\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 \def\count@lines{% \global\lin@Count=\lin@sSoFar \loop \Anyleftfalse \ifdim\lastskip=\z@ \ifdim\lastkern=\z@ \ifnum\lastpenalty=\z@ \setbox\z@=\lastbox \ifvoid\z@ \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} \def\@duplicate{% \loop \Anyleftfalse \ifdim\lastskip=\z@ \ifdim\lastkern=\z@ \ifnum\lastpenalty=\z@ \global\setbox\z@=\lastbox \ifvoid\z@ % end of breakup loop \else \Anylefttrue % box present \ifnum\lin@rem=\z@ % if remainder non-zero we do not care \lin@rem=\lineCountInterval \ifnum\lin@Count<\lin@CountStart \a@@lnumfalse \else \ifnum\lin@CountFinish<\z@ % 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 % Position shorter lines to keep indentation. Only a line length % is important % This prints indented lines flush right margin \setbox\z@=\vbox{\hbox to\textwidth{\hfil\box\z@}} % This for centered lines % \setbox\z@=\vbox{\hbox to\textwidth{\hfil\box\z@\hfil\relax}} % For other variants you are on your own!! \ifa@@lnum \append@line \else \global\setbox\@ne=\vbox{\box\z@\unvbox\@ne} \fi \advance\lin@Count\m@ne \advance\lin@rem by\m@ne\fi \else \Anylefttrue % penalty present \pen=\lastpenalty \global\setbox\@ne=\vbox{\penalty\pen\unvbox\@ne}\unpenalty\fi \else \Anylefttrue % kern present \dimen\z@=\lastkern \global\setbox\@ne=\vbox{\kern\dimen\z@\unvbox\@ne}\unkern \fi \else \Anylefttrue % skip present \skip\z@=\lastskip \global\setbox\@ne=\vbox{\vskip\skip\z@\unvbox\@ne}\unskip \fi \ifAnyleft \repeat} \def\append@line{% attach line number \setbox2=\vbox to \z@{\smash{\footnotesize\the\lin@Count}} \wd2=25pt % that much of space for a line number \if@twoside % we are printing twoside \ifodd\count\z@ % on the right margin for odd pages \setbox\z@=\hbox{\box\z@\rlap{\rule{\wd2}{\z@}\box2}} \else % and on the left for even \setbox\z@=\hbox{\llap{\box2}\box\z@} \fi \else % one sided printing \setbox\z@=\hbox{\llap{\box2}\box\z@} % left margin only \fi \global\setbox\@ne=\vbox{\box\z@\unvbox\@ne}}% add this to a reconstructed % page % Rainer showed me how to save the previous \output. Thanks Rainer. (jaf) \newtoks\LaTeX@output \LaTeX@output = \expandafter{\the\output} \newbox\brk \output={\ifnum\outputpenalty <-\@M \output={\LaTeX@output} % Use old output definition if page % is not to be output \else \lin@Count=\lin@sSoFar \setbox\brk=\vbox{\unvcopy\@cclv\count@lines} \global\setbox\@ne=\vbox{} \lin@rem=\total@Rem \iflnumpage \resetlin@sSoFar \else \global\lin@sSoFar=\lin@Count \fi \setbox\brk=\vbox{\unvcopy\@cclv\@duplicate} \ifdim\ht\brk>\z@\message{Incomplete breakup}\fi \ht\@ne=\z@\dp\@ne=\z@ \global\setbox\@cclv=\vbox to\vsize{\unvbox\@ne}% attempt to get glues back \@makecol\@opcol \fi \setbox\brk=\box\@cclv \deadcycles=\z@ } \endinput %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Save up to \end{document} in a separate file and use as a playground %% for testing \ifx\documentclass\undefined \documentstyle[numline% %% This is LaTeX 2.09 %,indent% %% uncomment this line if you have indent.sty ]{article} \else \documentclass{article} %% LaTeX2e header \usepackage{numline% %,indent% %% uncomment this line if you have indent.sty } \fi \newcommand\testtext{% This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. This is the test. } \let\oldSection=\section %\renewcommand{\section}[1]{\vbox{\vspace{3.5ex}\oldSection{#1}}} \def\section#1 \label#2{\vbox{\vspace{3.5ex}\oldSection{#1}\label{#2}}} %\lnumpagetrue % Uncomment this to restart lines numbers at every page %\lineCountInterval=1 % default is 5 \begin{document} % This gives only a length of indented line - not a position. % See comments in numline.sty \section{Section one} \label{sec-start} \testtext % This gives only a length of indented line - not a position. % See comments in numline.sty % Uncomment following four lines if you are using indent.sty %indent%\begin{indentation}{3em}{0cm} %indent% \noindent\testtext %indent% \testtext %indent%\end{indentation} \testtext\testtext\testtext\testtext\testtext\testtext \begin{minipage}{\textwidth} \begin{displaymath} 2 \times 2 = 4 \end{displaymath} \end{minipage} \testtext \par\noindent\parbox{\textwidth}{% \begin{displaymath} 2 \times 2 = 4 \end{displaymath} } \testtext\testtext\testtext\testtext\testtext\testtext\testtext\testtext \section{Another section} \label{sec-too} \testtext\testtext\testtext\testtext\testtext \par\noindent\parbox{\textwidth}{ \begin{displaymath} \left( \begin{array}{c} a \\ b \end{array} \right[ \end{displaymath} } \testtext\testtext\testtext\testtext\testtext\testtext \end{document} DREADED INCOMPLETE BREAKUP AND OTHER PASTIMES The code for line numbering works by splitting an already set page into separate lines and by putting resulting boxes together with their line numbers. One difficulty with that is that is not always clear on a typeset page what constitutes a ``line''. The other, related to some extent, is that TeX does not have tools to accomplish required split in every situation; you will see then ``Incomplete breakup'' message and part of your input will vanish from dvi file. It is usually possible to work around this limitation by hiding troublesome elements in boxes. \minipage and \parbox will serve very well. These two methods do not have the same effect and, depending on circumstances, one or another may be preferable. Test input provides an example for displayed formulas. Sectioning commands will likely cause trouble as well. You may write something like ``\vbox{\vspace{3.5ex}\section{Another section}}'' in place of an original ``\section{Another section}''. These are NOT equivalent, but when you are numbering lines presumably you are not creating a masterpiece of a typography and such replacement should be good enough. In a longer document meant to be typed with and without numbered lines changes like above can be troublesome. Instead you can try re-defini- tions which can be used conditionally. Here is how ``\section'' can be redone: \let\oldSection=\section \renewcommand{\section}[1]{\vbox{\vspace{3.5ex}\oldSection{#1}}} (making this work with optional arguments is left as an exercise :-). This still will not work on section titles with labels. One can use then a redefinition like in the sample text: \let\oldSection=\section \def\section#1 \label#2{\vbox{\vspace{3.5ex}\oldSection{#1}\label{#2}}} Warning: This approach requires rather specific section headers. Every ``\section{...}'' has to be followed by ``\label{...}'' separated by white space and/or one new-line. Go and number your lines.