diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex209/contrib/chbars |
Initial commit
Diffstat (limited to 'macros/latex209/contrib/chbars')
20 files changed, 7723 insertions, 0 deletions
diff --git a/macros/latex209/contrib/chbars/COPYING b/macros/latex209/contrib/chbars/COPYING new file mode 100644 index 0000000000..9a17037581 --- /dev/null +++ b/macros/latex209/contrib/chbars/COPYING @@ -0,0 +1,249 @@ + + GNU GENERAL PUBLIC LICENSE + Version 1, February 1989 + + Copyright (C) 1989 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The license agreements of most software companies try to keep users +at the mercy of those companies. By contrast, our General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. The +General Public License applies to the Free Software Foundation's +software and to any other program whose authors commit to using it. +You can use it for your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Specifically, the General Public License is designed to make +sure that you have the freedom to give away or sell copies of free +software, that you receive source code or can get it if you want it, +that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of a such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must tell them their rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any program or other work which +contains a notice placed by the copyright holder saying it may be +distributed under the terms of this General Public License. The +"Program", below, refers to any such program or work, and a "work based +on the Program" means either the Program or any work containing the +Program or a portion of it, either verbatim or with modifications. Each +licensee is addressed as "you". + + 1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this +General Public License and to the absence of any warranty; and give any +other recipients of the Program a copy of this General Public License +along with the Program. You may charge a fee for the physical act of +transferring a copy. + + 2. You may modify your copy or copies of the Program or any portion of +it, and copy and distribute such modifications under the terms of Paragraph +1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating that + you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that + in whole or in part contains the Program or any part thereof, either + with or without modifications, to be licensed at no charge to all + third parties under the terms of this General Public License (except + that you may choose to grant warranty protection to some or all + third parties, at your option). + + c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive use + in the simplest and most usual way, to print or display an + announcement including an appropriate copyright notice and a notice + that there is no warranty (or else, saying that you provide a + warranty) and that users may redistribute the program under these + conditions, and telling the user how to view a copy of this General + Public License. + + d) You may charge a fee for the physical act of transferring a + copy, and you may at your option offer warranty protection in + exchange for a fee. + +Mere aggregation of another independent work with the Program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other work under the scope of these terms. + + 3. You may copy and distribute the Program (or a portion or derivative of +it, under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal charge + for the cost of distribution) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +Source code for a work means the preferred form of the work for making +modifications to it. For an executable file, complete source code means +all the source code for all modules it contains; but, as a special +exception, it need not include source code for modules which are standard +libraries that accompany the operating system on which the executable +file runs, or for standard header files or definitions files that +accompany that operating system. + + 4. You may not copy, modify, sublicense, distribute or transfer the +Program except as expressly provided under this General Public License. +Any attempt otherwise to copy, modify, sublicense, distribute or transfer +the Program is void, and will automatically terminate your rights to use +the Program under this License. However, parties who have received +copies, or rights to use copies, from you under this General Public +License will not have their licenses terminated so long as such parties +remain in full compliance. + + 5. By copying, distributing or modifying the Program (or any work based +on the Program) you indicate your acceptance of this license to do so, +and all its terms and conditions. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these +terms and conditions. You may not impose any further restrictions on the +recipients' exercise of the rights granted herein. + + 7. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of the license which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +the license, you may choose any version ever published by the Free Software +Foundation. + + 8. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to humanity, the best way to achieve this is to make it +free software which everyone can redistribute and change under these +terms. + + To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19xx name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the +appropriate parts of the General Public License. Of course, the +commands you use may be called something other than `show w' and `show +c'; they could even be mouse-clicks or menu items--whatever suits your +program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + program `Gnomovision' (a program to direct compilers to make passes + at assemblers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/macros/latex209/contrib/chbars/README b/macros/latex209/contrib/chbars/README new file mode 100644 index 0000000000..9e7ef57867 --- /dev/null +++ b/macros/latex209/contrib/chbars/README @@ -0,0 +1,127 @@ +% README for changebar macros 28 Jul 92 +%------------------------------------------------------------ + + +GENERAL NOTES by Joachim Schrod. (Minor revisions by R. Bernstein) + +These are my (Joachim Schrod's) macros for producing change bars with +TeX or LaTeX. Please note that (1) these macros will not produce an +optimal page breaking (i.e. vertical glue will disappear in many +places) and (2) that there is still a problem with these macros: it is +described in the last section of the chapter `Handling the Page +Contents.' By the way, this problem is within the current LaTeX, too. + +The macros were written for TeX 2. In the meantime TeX 3 became +available; new features (i.e., \holdinginsert) would now allow a +better implementation. + +The macros are written for the usage with Plain TeX. R. Bernstein did +the the LaTeX adaption because I neither use LaTeX in my own documents +nor do I need change bars... For me, it was just a nice play to show +what can be done with the \output routine of TeX. Therefore I will not +put further work in these macros. But I will happily redistribute +enhancements and will make them available on the usual TeX servers. + +So: If you enhance the macros, make further adaptations of them for +LaTeX, or if you incorporate the new features of TeX 3, send them to +me so that others can share your work. + + +NOTES ON THE DISTRIBUTED FILES + +The macro file chbars.doc can be LaTeXed (the result is not as +readable as it should be---but this is due to the inflexibility of the +\@startsection macro of LaTeX). The needed style files are included. + +Furthermore four test files for the usage of change bars in vertical +and horizontal mode are included, too. The files test1.tex, test2.tex +and test3.tex should be run through Plain TeX; test4.ltx should be run +through LaTeX. Files test3.tex and test4.tex try out features that +have been added to these macros since they were originally written. In +particular, setting the change bar width, placement on the right or +left margin, redefining the \output routine, and a LaTeX test. + +These macros are documented with my MAKEPROG processor. Perhaps I +should mention why I don't use the doc-option of Frank Mittelbach: +MAKEPROG has been written by me before I have heard of the existence +of doc. But even then I would have written it: doc is a special +documentation tool for TeX macros which heavily depends on LaTeX and +the LaTeX coding conventions. It is not very easy to use it for the +documentation of other stuff than LaTeX macros. In contrary, MAKEPROG +is a {\it general documentation facility\/} which I use for all things +where WEB is not available. (In fact, it was created to document lex +and yacc programs...) Especially the changefile possibility I need +very hardly. MAKEPROG has the disadvantage that a special care of the +TeX environment (e.g. the indexing of macro names) can not be +implemented. I'm still working on MAKEPROG, the next version 2.0 will +have a code rearrangement ability like TANGLE. + +MAKEPROG may be fetched from LISTSERV@DHDURZ1 (for the Bitnet folks) +and per ftp from Washington (where it is in the UNIX distribution). I +would prefer if you get it from there so that I don't have to mail out +so much stuff. If you have no access contact me. If you are working +on an IBM(-compatible) PC you should nevertheless contact me: I have +changefiles for Turbo Pascal available. + +I'm not really satisfied that I have not found the time to update the +documentation of MAKEPROG to mention that progltx, the +progdoc-equivalent LaTeX style option, exists. To get a +documentation you must run LaTeX over progltx.doc and print the +result. Because I print the whole stuff usually on A4 paper I have +included a style option for A4 page layout, too. The macro file +a4-9.sty assumes that the driver leaves a margin of 1 in. Please +note, that this is not just ``one other'' A4 page layout -- it was +designed by a typographer and I have only done the LaTeX +realization---have a look at a4-9.doc! + +Perhaps it is of interest for you how the verbatim typesetting in +progltx is done---the scheme is robuster than the one LaTeX uses, it +works with tabs (are you working on a VAX or a PC?), but it's slower, +too. In the last sections of the files you can have a look at the +`great' internal design of the current LaTeX, too. + + + +Well, I hope that you will enjoy the macros + + Greetings + Joachim Schrod + + +current address: + Technical University of Darmstadt + Department of Computer Science + Joachim Schrod + Alexanderstr. 10 + + D-6100 Darmstadt + FR Germany + + Email: xitijsch@ddathd21.bitnet + + +============================================================================== + +The following files are in the distribution: + +COPYING copy conditions, i.e. the GNU General Public License +README this file you are reading + +chbars.doc The documented macro source (with MAKEPROG!) +progltx.sty Style files needed to print it. +a4-9.sty + +chbars.sty the macro version of chbars.doc +chbars.tex the macro version of chbars.doc (identical to chbars.tex) +chbars-orig.tex Joachim Schrod's original macro version of chbars.doc +test1.tex Test files for chbars.tex +test2.tex +test3.tex Test file for some of the newer features added +test4.ltx LaTeX test file for chbars.sty (a.k.a chbars.tex) + +a4-9.doc a non-arbitrary A4 page layout style option +a4-marg.chf changefile for a4-9.doc, adaption to 1in driver margin + +makeprog.perl Perl version of MAKEPROG +makeprog.lex Lex version of MAKEPROG +-- diff --git a/macros/latex209/contrib/chbars/a4-9.doc b/macros/latex209/contrib/chbars/a4-9.doc new file mode 100644 index 0000000000..d15ce6113d --- /dev/null +++ b/macros/latex209/contrib/chbars/a4-9.doc @@ -0,0 +1,304 @@ +% This is A4-9.DOC as of 10 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for a non-arbitrary A4 page layout +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +\documentstyle[progltx,a4-9]{article} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% local macros +% + +\let\mc=\ninrm % for names like GNU + +\def\WEB{{\tt WEB\/}} +\def\DVI{{\tt DVI\/}} +\def\GNU{{\mc GNU}} + +\chardef\bs=`\\ + +\def\fract#1/#2.{% % fraction a/b within text + \leavevmode % borrowed from D. Knuth's manmac + \kern .1em + \raise .5ex \hbox{\the\scriptfont0 #1}% + \kern -.1em/\kern -.15em + \lower .25ex \hbox{\the\scriptfont0 #2}% + } + +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\begin{document} + + +\title{ + A non-arbitrary A4 page layout\\ + The {\tt a4-9\/} style option + } +\author{\sc Joachim Schrod} + +\maketitle + + + +\sect This macro file is the |a4-9| document style option for \LaTeX{} +that produces a {\it well designed\/} A4 page layout. This style +option works with all standard \LaTeX{} styles and should work with +all other well written ones, too. It should not be used with an +underlined headings page style (see below for an explanation). + +But what does this mean: ``a {\it well designed\/} page layout''? +Mostly it means that the design is not chosen by accident but +within a {\it non-arbitrary process}. To my knowledge this theme +has first been covered by Jan Tschichold in his famous article of +1962: ``Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und +des Satzspiegels'' (look for references at the end). This style +option implements his design (I'm no designer\,\dots) + +If you are interested in typography and you do not know anything of +Jan Tschichold, you should---he and Stanley Morrison were probably the +two most important typographers in this century. He received as one +of very few Europeans the gold medal of the American Institute of +Graphic Arts, was a honorary member of the Double Crown Club, London, +and of the Soci\'et\'e typographique de France. Furthermore he was +appointed as Honorary Royal Designer for Industry by the Royal Society +of Arts, London. In 1965 he got the Gutenberg-Preis of the city +Leipzig (which celebrated its 800th~birthday in this year), the most +important typographic award in Europe. + + +\sect This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~1, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +%You should have received a copy of the \GNU{} General Public License +%along with this program; if not, write to the Free Software Foundation, +If you have not received a copy of the \GNU{} General Public License +along with this program, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\sect This style option implements the partition by nine of the A4 +page as explained by Tschichold. The proportion for a two-sided +layout is shown in Figure~\ref{fig:layout} (the picture is not true to +scale due to the limited features of the \LaTeX{}-{\tt +picture\/}-environment). +% +\begin{figure} +\unitlength=.3mm +\begin{center} +\begin{picture}(420,315) % 420,297 + +% double page (dashed lines) +\multiput(0,0)(210,0){2}{\dashbox{5}(210,315){}} % 210,297 + +% help lines for construction (thin lines) +\put( 0, 0){\line( 4, 3){420}} +\put( 0, 0){\line( 2, 3){210}} +\put( 0,315){\line( 4,-3){420}} +\put(210,315){\line( 2,-3){210}} + +\put(280,315){\line( 0,-1){105}} +\put(140,210){\line( 4, 3){140}} + +% resulting pages (thick lines) +\thicklines +\multiput(46.66666,70)(186.66666,0){2}{\framebox(140,210){}} % 140,198 + +\end{picture} +\end{center} +\caption{Partition by nine of the A4 page according to Tschichold} +\label{fig:layout} +\end{figure} +% +The important fact is that the proportions of the type area and the +margins repeat the proportion of the whole page. The above +construction yields margins with a ratio of $ \sqrt{2} : 1 : 2 : +2\sqrt{2} $, where 1 is the ninth of the page width, i.e.\ $\rm +23\fract 1/3. \,mm$. But we do not use this exact value because +the margin will be shortened by bookbinding or filing. We assume a +total need of 8\,mm for such purposes which results in 4\,mm for +each page. This 4\,mm will first be subtracted from the total +margin width of 70\,mm and the remaining 66\,mm will be divided +into one third for the inner margin and two third for the outer +margin. The resulting approximate values are therefore: +% +\begin{center} +\begin{tabular}{lr} +\multicolumn1{c}{\sc Dimension}& \multicolumn1{c}{\sc Value}\\[2pt] +page width& 210\,mm\\ +width of type area& 140\,mm\\ +inner margin& 26\,mm\\ +outer margin& 44\,mm\\[1pt] +page height& 297\,mm\\ +height of type area& 198\,mm\\ +top margin& 33\,mm\\ +bottom margin& 66\,mm\\ +\end{tabular} +\end{center} +% +The value for the inner margin consists of 4\,mm for binding and +filing purposes and 22\,mm ``real'' margin. Of course, all values +are measured from the paper edge. + +If the page layout is not for two-sided printing, it can be still +assumed that a margin of c\`a.~4\,mm will be needed for filing. +This remaining margin space of 66\,mm is distributed evenly on the +left and on the right side. Precisely spoken, we use 37\,mm for +the left margin ($\rm = 33\,mm + 4\,mm$) and 33\,mm for the right +margin. The resulting margins have a ratio of $1 : 1 : 1 : +2\sqrt{2}$. + + +\sect The height of the type area needs a special remark: Usually this +height does neither include the headline nor the footline. But if the +headline is underlined the headline should be taken into +account---that's the reason why this style option cannot be used with +underlined headings. + +The values in the above table are only approximations to the one +we will use in reality. An approximation because the height of the +type area must be a multiple of a line height, i.e.\ it must equal +$ (n-1)|\baselineskip| + |\topskip| $ where $n$ is the number of lines +on one page. If we have to choose we will prefer the longer type area. + + +\sect We assume a starting position of $\rm (2\,cm, 2\,cm)$, i.e., the +\DVI{} driver shall leave a top and a left margin of 2\,cm by his own. This is +different from the usual 1\,in margin---but the usual margin was made +for legal paper ($\rm 8\,in \times 11.5\,in$). I hope that this +driver margin value---which was presented by Klaus Guntermann and +me at the Euro\TeX88 conference in Exeter---will be accepted +by the \DVI{} driver standards commitee of TUG. + +|\hoffset| and |\voffset| are set to 0\,mm, so that we can proceed on +the assumption of the above margin. If you use a driver which leaves a +margin of 1\,in you should use the changefile |a4-marg.chf|. + +\beginprog +\hoffset=0mm +\voffset=0mm +\endprog + + +\sect To get the precise value of |\textheight| we first calculate the +number of lines which may be on the page in full. Then we add another +line and recalculate the value of |\textheight|. + +\beginprog +\normalsize % this sets \baselineskip + +\dimen@=198mm +\count@=\dimen@ % value in sp +\advance \count@ by -\topskip % \topskip and \baselineskip will be +\divide \count@ by \baselineskip % coerced to integer, value is in sp + +\textheight=\count@\baselineskip % \count@ equals the number of lines - 1 +\advance \textheight by \topskip +\endprog + + +\sect Because we have altered the original value of |\textheight| +(198\,mm) we must alter the value of the top margin, too. It will be +just a third of the remaining place on the page. Please note that the +place for the top margin consists of the four values driver +margin, |\topmargin|, |\headheight|, and |\headsep|. + +\beginprog +\topmargin=297mm + \advance \topmargin by -\textheight % place for top and bottom margin + \divide \topmargin by 3 % place for top margin + \advance \topmargin by -20mm % driver margin + \advance \topmargin by -\headheight + \advance \topmargin by -\headsep + +\textwidth=140.1mm +\if@twoside + \oddsidemargin=6mm % 26mm - 20mm (driver margin) + \evensidemargin=24mm % 44mm - 20mm (driver margin) + \marginparwidth=33mm % half of total vertical margin +\else + \oddsidemargin=17mm % 37mm - 20mm (driver margin) + \marginparwidth=22mm % third of total vertical margin + \evensidemargin=\maxdimen % usage should result in an error message +\fi +\endprog + + +\sect We finish the macro file so that garbage (e.g.\ of exchanges +between systems) can come afterwards. + +\beginprog +\endinput +\endprog + + +%%% +\newpage +%%% + +\sect It remains to give a few pointers to the article where the +design which was implemented here has been described: +% +\begin{itemize} + +\item {\sc Jan Tschichold}: +Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und des Satzspiegels. +In {\it Typographische Monatsbl\"atter}. +February 1964. + +\item {\sc Jan Tschichold}: +Non-arbitrary proportions of page and type area. +In {\it Print in Britain}. +London: September 1963. + +\item {\sc Jan Tschichold}: +Proportions rationelles du format du livre et de la page imprim\'ee. +In {\it Revue suisse d'imprimerie}, 4. +St-Gall 1964. + +\end{itemize} +% +The original paper is a private edition which can not be bought, it +was published in 1962. It appeared in seven different publications +in german language, three times in french, two times in dutch. +Besides being translated to english, it was translated to danish, +norwegian, finn, italian, and hungarian. + + + +\end{document} diff --git a/macros/latex209/contrib/chbars/a4-9.sty b/macros/latex209/contrib/chbars/a4-9.sty new file mode 100644 index 0000000000..e41c3fc6fc --- /dev/null +++ b/macros/latex209/contrib/chbars/a4-9.sty @@ -0,0 +1,324 @@ +% This is A4-9.DOC as of 10 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for a non-arbitrary A4 page layout +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\ninrm % for names like GNU + +%%% \def\WEB{{\tt WEB\/}} +%%% \def\DVI{{\tt DVI\/}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% \def\fract#1/#2.{% % fraction a/b within text +%%% \leavevmode % borrowed from D. Knuth's manmac +%%% \kern .1em +%%% \raise .5ex \hbox{\the\scriptfont0 #1}% +%%% \kern -.1em/\kern -.15em +%%% \lower .25ex \hbox{\the\scriptfont0 #2}% +%%% } + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%% \begin{document} + + +%%% \title{ +%%% A non-arbitrary A4 page layout\\ +%%% The {\tt a4-9\/} style option +%%% } +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + + +%%% \sect This macro file is the |a4-9| document style option for \LaTeX{} +%%% that produces a {\it well designed\/} A4 page layout. This style +%%% option works with all standard \LaTeX{} styles and should work with +%%% all other well written ones, too. It should not be used with an +%%% underlined headings page style (see below for an explanation). + +%%% But what does this mean: ``a {\it well designed\/} page layout''? +%%% Mostly it means that the design is not chosen by accident but +%%% within a {\it non-arbitrary process}. To my knowledge this theme +%%% has first been covered by Jan Tschichold in his famous article of +%%% 1962: ``Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und +%%% des Satzspiegels'' (look for references at the end). This style +%%% option implements his design (I'm no designer\,\dots) + +%%% If you are interested in typography and you do not know anything of +%%% Jan Tschichold, you should---he and Stanley Morrison were probably the +%%% two most important typographers in this century. He received as one +%%% of very few Europeans the gold medal of the American Institute of +%%% Graphic Arts, was a honorary member of the Double Crown Club, London, +%%% and of the Soci\'et\'e typographique de France. Furthermore he was +%%% appointed as Honorary Royal Designer for Industry by the Royal Society +%%% of Arts, London. In 1965 he got the Gutenberg-Preis of the city +%%% Leipzig (which celebrated its 800th~birthday in this year), the most +%%% important typographic award in Europe. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% %You should have received a copy of the \GNU{} General Public License +%%% %along with this program; if not, write to the Free Software Foundation, +%%% If you have not received a copy of the \GNU{} General Public License +%%% along with this program, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect This style option implements the partition by nine of the A4 +%%% page as explained by Tschichold. The proportion for a two-sided +%%% layout is shown in Figure~\ref{fig:layout} (the picture is not true to +%%% scale due to the limited features of the \LaTeX{}-{\tt +%%% picture\/}-environment). +%%% % +%%% \begin{figure} +%%% \unitlength=.3mm +%%% \begin{center} +%%% \begin{picture}(420,315) % 420,297 + +%%% % double page (dashed lines) +%%% \multiput(0,0)(210,0){2}{\dashbox{5}(210,315){}} % 210,297 + +%%% % help lines for construction (thin lines) +%%% \put( 0, 0){\line( 4, 3){420}} +%%% \put( 0, 0){\line( 2, 3){210}} +%%% \put( 0,315){\line( 4,-3){420}} +%%% \put(210,315){\line( 2,-3){210}} + +%%% \put(280,315){\line( 0,-1){105}} +%%% \put(140,210){\line( 4, 3){140}} + +%%% % resulting pages (thick lines) +%%% \thicklines +%%% \multiput(46.66666,70)(186.66666,0){2}{\framebox(140,210){}} % 140,198 + +%%% \end{picture} +%%% \end{center} +%%% \caption{Partition by nine of the A4 page according to Tschichold} +%%% \label{fig:layout} +%%% \end{figure} +%%% % +%%% The important fact is that the proportions of the type area and the +%%% margins repeat the proportion of the whole page. The above +%%% construction yields margins with a ratio of $ \sqrt{2} : 1 : 2 : +%%% 2\sqrt{2} $, where 1 is the ninth of the page width, i.e.\ $\rm +%%% 23\fract 1/3. \,mm$. But we do not use this exact value because +%%% the margin will be shortened by bookbinding or filing. We assume a +%%% total need of 8\,mm for such purposes which results in 4\,mm for +%%% each page. This 4\,mm will first be subtracted from the total +%%% margin width of 70\,mm and the remaining 66\,mm will be divided +%%% into one third for the inner margin and two third for the outer +%%% margin. The resulting approximate values are therefore: +%%% % +%%% \begin{center} +%%% \begin{tabular}{lr} +%%% \multicolumn1{c}{\sc Dimension}& \multicolumn1{c}{\sc Value}\\[2pt] +%%% page width& 210\,mm\\ +%%% width of type area& 140\,mm\\ +%%% inner margin& 26\,mm\\ +%%% outer margin& 44\,mm\\[1pt] +%%% page height& 297\,mm\\ +%%% height of type area& 198\,mm\\ +%%% top margin& 33\,mm\\ +%%% bottom margin& 66\,mm\\ +%%% \end{tabular} +%%% \end{center} +%%% % +%%% The value for the inner margin consists of 4\,mm for binding and +%%% filing purposes and 22\,mm ``real'' margin. Of course, all values +%%% are measured from the paper edge. + +%%% If the page layout is not for two-sided printing, it can be still +%%% assumed that a margin of c\`a.~4\,mm will be needed for filing. +%%% This remaining margin space of 66\,mm is distributed evenly on the +%%% left and on the right side. Precisely spoken, we use 37\,mm for +%%% the left margin ($\rm = 33\,mm + 4\,mm$) and 33\,mm for the right +%%% margin. The resulting margins have a ratio of $1 : 1 : 1 : +%%% 2\sqrt{2}$. + + +%%% \sect The height of the type area needs a special remark: Usually this +%%% height does neither include the headline nor the footline. But if the +%%% headline is underlined the headline should be taken into +%%% account---that's the reason why this style option cannot be used with +%%% underlined headings. + +%%% The values in the above table are only approximations to the one +%%% we will use in reality. An approximation because the height of the +%%% type area must be a multiple of a line height, i.e.\ it must equal +%%% $ (n-1)|\baselineskip| + |\topskip| $ where $n$ is the number of lines +%%% on one page. If we have to choose we will prefer the longer type area. + + +%%% \sect We assume a starting position of $\rm (2\,cm, 2\,cm)$, i.e., the +%%% \DVI{} driver shall leave a top and a left margin of 2\,cm by his own. This is +%%% different from the usual 1\,in margin---but the usual margin was made +%%% for legal paper ($\rm 8\,in \times 11.5\,in$). I hope that this +%%% driver margin value---which was presented by Klaus Guntermann and +%%% me at the Euro\TeX88 conference in Exeter---will be accepted +%%% by the \DVI{} driver standards commitee of TUG. + +%%% |\hoffset| and |\voffset| are set to 0\,mm, so that we can proceed on +%%% the assumption of the above margin. If you use a driver which leaves a +%%% margin of 1\,in you should use the changefile |a4-marg.chf|. + +%%% \beginprog +\hoffset=2cm \advance\hoffset by -1in +\voffset=2cm \advance\voffset by -1in +%%% \endprog + + +%%% \sect To get the precise value of |\textheight| we first calculate the +%%% number of lines which may be on the page in full. Then we add another +%%% line and recalculate the value of |\textheight|. + +%%% \beginprog +\normalsize % this sets \baselineskip + +\dimen@=198mm +\count@=\dimen@ % value in sp +\advance \count@ by -\topskip % \topskip and \baselineskip will be +\divide \count@ by \baselineskip % coerced to integer, value is in sp + +\textheight=\count@\baselineskip % \count@ equals the number of lines - 1 +\advance \textheight by \topskip +%%% \endprog + + +%%% \sect Because we have altered the original value of |\textheight| +%%% (198\,mm) we must alter the value of the top margin, too. It will be +%%% just a third of the remaining place on the page. Please note that the +%%% place for the top margin consists of the four values driver +%%% margin, |\topmargin|, |\headheight|, and |\headsep|. + +%%% \beginprog +\topmargin=297mm + \advance \topmargin by -\textheight % place for top and bottom margin + \divide \topmargin by 3 % place for top margin + \advance \topmargin by -20mm % driver margin + \advance \topmargin by -\headheight + \advance \topmargin by -\headsep + +\textwidth=140.1mm +\if@twoside + \oddsidemargin=6mm % 26mm - 20mm (driver margin) + \evensidemargin=24mm % 44mm - 20mm (driver margin) + \marginparwidth=33mm % half of total vertical margin +\else + \oddsidemargin=17mm % 37mm - 20mm (driver margin) + \marginparwidth=22mm % third of total vertical margin + \evensidemargin=\maxdimen % usage should result in an error message +\fi +%%% \endprog + + +%%% \sect We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\endinput +%%% \endprog + + +%%% %%% +%%% \newpage +%%% %%% + +%%% \sect It remains to give a few pointers to the article where the +%%% design which was implemented here has been described: +%%% % +%%% \begin{itemize} + +%%% \item {\sc Jan Tschichold}: +%%% Willk\"urfreie Ma\ss{}verh\"altnisse der Buchseite und des Satzspiegels. +%%% In {\it Typographische Monatsbl\"atter}. +%%% February 1964. + +%%% \item {\sc Jan Tschichold}: +%%% Non-arbitrary proportions of page and type area. +%%% In {\it Print in Britain}. +%%% London: September 1963. + +%%% \item {\sc Jan Tschichold}: +%%% Proportions rationelles du format du livre et de la page imprim\'ee. +%%% In {\it Revue suisse d'imprimerie}, 4. +%%% St-Gall 1964. + +%%% \end{itemize} +%%% % +%%% The original paper is a private edition which can not be bought, it +%%% was published in 1962. It appeared in seven different publications +%%% in german language, three times in french, two times in dutch. +%%% Besides being translated to english, it was translated to danish, +%%% norwegian, finn, italian, and hungarian. + + + +%%% \end{document} diff --git a/macros/latex209/contrib/chbars/a4-marg.chf b/macros/latex209/contrib/chbars/a4-marg.chf new file mode 100644 index 0000000000..c5aba1d7a4 --- /dev/null +++ b/macros/latex209/contrib/chbars/a4-marg.chf @@ -0,0 +1,34 @@ +% This is A4-MARG.CHF as of 08 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. + +% +% changefile for A4-9.DOC or A4-12.DOC +% for DVI drivers with 1in margin +% + +% +% DATE PERSON REMARK +% 89-10-05 -js first version +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + +@x +\hoffset=0mm +\voffset=0mm +@y +\hoffset=2cm \advance\hoffset by -1in +\voffset=2cm \advance\voffset by -1in +@z diff --git a/macros/latex209/contrib/chbars/chbars-orig.tex b/macros/latex209/contrib/chbars/chbars-orig.tex new file mode 100644 index 0000000000..83801dd7a3 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars-orig.tex @@ -0,0 +1,758 @@ +% This is CHBARS.DOC as of 09 Oct 89 +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in Plain TeX +% MAKEPROG is needed +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\PS{{\sc PostScript}} +%%% \def\DVI{{\tt DVI}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + +%%% \begin{document} + + +%%% \title{Changebars without {\tt \bs{}special}'s} +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + + +%%% \begin{abstract} +%%% It is common practice to use vertical bars in the margins of a +%%% document to mark pieces of text which have changed since the last +%%% version(s) of this document. Such vertical bars are usually +%%% called {\em changebars}. It has often been said that it is +%%% impossible to produce changebars with \TeX{} without the usage of +%%% |\special| commands (driver directives), which extend the +%%% primitives of \TeX{}. This paper presents a \TeX{} macro file +%%% which implements changebars without such a usage. The macro file +%%% is written for the usage with Plain~\TeX{} but the implementation +%%% strategy can be used with \LaTeX{}, too. +%%% \end{abstract} + + + +%%% \chap Introduction. + +%%% Changebars are used to mark modified parts in existing documents. For +%%% the usage in \TeX{} documents, there exist only solutions that use +%%% driver/printer features by the way of inserting |\special| commands in +%%% the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +%%% that are no longer as freely interchangeable as the \DVI{} concept would +%%% allow---device dependency is problematic especially for this application +%%% that is useful for multi-authoring or standards development. + +%%% This macro package offers a pure \TeX{} solution. Nevertheless, it has +%%% its restrictions, too. The page break will no longer be optimal, +%%% because no strechability or shrinkability on a page on top of the last +%%% mark of a change is supported. But this seems to be acceptable, +%%% especially as the change bar feature often will be used for proof +%%% reading and not in the final document. This restriction is the reason +%%% why no change marks can be used on titlepages or for similar +%%% constructions. Changes in floating insertions (footnotes, figures) are +%%% not discovered. + +%%% The demonstrated solution is written in Plain \TeX{}, because it was +%%% easier and could be presented better at the Euro\TeX89 conference in +%%% Karlsruhe. An adaption to \LaTeX{} is possible, but would require +%%% modifications to the \LaTeX{} kernel, i.e.\ the output routine and the +%%% layout parameters of the standard styles. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% %You should have received a copy of the \GNU{} General Public License +%%% %along with this program; if not, write to the Free Software Foundation, +%%% If you have not received a copy of the \GNU{} General Public License +%%% along with this program, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect A changed area is described by two marks, |\beginchange| and +%%% |\endchange|. The method for writing a change bar consists of three +%%% parts: First, it will be indicated to the output routine that a change +%%% has occured. Next, the position of the changed area will be found out +%%% and fixed. A list of all changed areas is built, that can at last be +%%% marked by the output routine using vertical rules at the right margin. + +%%% But before we start we declare some shorthands for category codes. By +%%% declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +%%% letters we can use them in our macros. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +%%% With the at sign we can use the ``private'' Plain macros and with the +%%% underscore we can make our own macros more readable. But as we have to +%%% restore these category codes at the end of this macro file we store +%%% their former values in the control sequences |\atcode| and |\uscode|. +%%% This method is better than to use a group because not all macros have to +%%% be defined global this way. + +%%% \beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter +%%% \endprog + + + + +%%% \chap Triggering the Output Routine. + +%%% \begin{sloppypar} +%%% First, the output routine must know that changes occured. This is done +%%% by the macros |\beginchange| and |\endchange| that append a reserved +%%% penalty value |\break_penalty| to the current list that is below +%%% $-10\,000$. The penalty will be in the range $|\change_penalty_group| +%%% \cdot 100 - 99 \ldots |\change_penalty_group| \cdot 100$. +%%% For the output it must be differentiated if the mark indicates +%%% begin or end of the changed area. This is done with the values +%%% |\change_penalty_begin| and |\change_penalty_end| that are used as the +%%% second-to-last digit of the change penalty. +%%% \end{sloppypar} + +%%% It must also be differentiated between the beginning of a mark being in +%%% horizontal or vertical mode. In horizontal mode, the change bar must +%%% not begin at the baseline of the actual text position, but on top of the +%%% actual line. This is marked in the last digit, an odd digit will be +%%% used in horizontal mode. + +%%% Note that the values mentioned above are used as digits here that can be +%%% concatenated. If they are not followed by an other digit they should be +%%% terminated by |\space| to stop the look-ahead for digits. + +%%% These interactions with the output routine adds a lot of dead cycles; we +%%% must therefore increase |\maxdeadcycles| to prevent \TeX{} from grumbling. + +%%% \beginprog +\def\change_penalty_group{-101} +\def\change_penalty_begin{0} +\def\change_penalty_end{1} + +\maxdeadcycles=100 +%%% \endprog + + +%%% \sect The marks set the change penalty value (including the indication +%%% of begin or end of mark). The rest (|\trigger_output|) is the same action +%%% for both. An end change mark in horizontal mode can be preceeded by +%%% glue that could cause a line break, thus including the following line to +%%% the change area as well. To avoid this unwanted behaviour, the space is +%%% saved in |\save_space|, discarded in front of the mark and restored +%%% afterwards. + +%%% \beginprog +\newcount\break_penalty +\newskip\save_space + +\def\beginchange{% + \break_penalty=\change_penalty_group\change_penalty_begin0 + \trigger_output + } +\def\endchange{% + \ifhmode \save_space=\lastskip \unskip \fi + \break_penalty=\change_penalty_group\change_penalty_end0 + \trigger_output + \ifhmode \hskip\save_space \fi + } +%%% \endprog + + +%%% \sect In |\trigger_output| the real output trigger is done. We must consider +%%% that an |\output|-invocation by our |\break_penalty| can be discarded at +%%% the beginning of a page. So we trigger the output routine twice, first +%%% with a special penalty value that is 2~less than the correct value +%%% (including the code for horizontal or vertical mode). After the first +%%% page break it is asserted that the current list is empty. The output +%%% routine has to save the former page contents if necessary. + +%%% Now we set the penalty to the correct value. The second page break does +%%% the real work, restores the page contents and handles the split +%%% insertions (footnotes, figures,~\dots) + +%%% In horizontal mode |\spacefactor| must not be destroyed. + +%%% \beginprog +\newcount\save_space_factor + +\def\trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else + \ifvmode \let\do_in_vmode=\relax + \advance \break_penalty by -2 + \else \save_space_factor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\break_penalty + \null + \advance \break_penalty by 2 \penalty\break_penalty + }% + \ifhmode \spacefactor\save_space_factor \fi + \fi + } +%%% \endprog + + +%%% \sect The usage of the output routine as an information passing system +%%% has always it's difficulties. One of the real hard parts is the +%%% handling of the page marks, special token lists that are handled by +%%% \TeX{}. These token lists provide informations about text on a page, +%%% they are usually used to create head lines etc. The user may access +%%% these token lists with three control sequences: |\botmark| is the +%%% last page mark given, |\topmark| is the |\botmark| of the previous +%%% page, and |\firstmark| is the first page mark on the actual page or +%%% |\topmark| if none was given. Here ``page'' is used in the \TeX{} +%%% sense, i.e.\ as the material which has been collected between two +%%% |\output| invocations. Of course, the page marks must not be +%%% destroyed---and that means they must be reinserted after each +%%% special use of the output routine. + +%%% But we have luck: A ``special use'' consists of two |\output| +%%% invocations, so we can insert |\topmark| again as a page mark after +%%% the first invocation where it will be the only page mark on that +%%% \TeX{} page. The second invocation will automatically transform this +%%% page mark into the ``last page mark on the previous page,'' i.e.\ in +%%% |\topmark|---that's what we need! Furthermore |\firstmark| and +%%% |\botmark| are saved in control sequences during the first invocation, +%%% they will be inserted again, too. + +%%% There's one situation where this approach doesn't work: In front of +%%% the first page mark |\topmark|, |\firstmark|, and |\botmark| expand +%%% to an empty token list. If we save them then and insert their old +%%% values we have inserted empty page marks. If other page marks follow +%%% on the same ``real'' page |\firstmark| will be empty instead of +%%% expanding to the token list of the first page mark. To prevent this +%%% we must not save and restore page marks before the first |\mark| has +%%% been added to the main vertical list. + +%%% Well, that can be controlled with a switch---but this switch must be +%%% set very carefully. If it is set immediately by the first |\mark| +%%% this may be in horizontal mode and special output invocations can +%%% occur above this page mark (i.e., there may be a |\beginchange| in the +%%% same paragraph in front of the |\mark|). Therefore the setting of the +%%% switch must be delayed until the vertical position of the |\mark| +%%% (precisely: the position of the |\mark| in the current list) is +%%% reached. In horizontal mode this can be done with a |\vadjust| and +%%% the output routine! Voil\`a, this is another command group for the +%%% output routine with only one command. + +%%% \beginprog +\newif\if@save_mark@ \@save_mark@false + +\def\mark_penalty_group{-102} +%%% \endprog + + +%%% \sect We will redefine |\mark| so that the first page mark either sets +%%% the switch to true (in vertical mode all possible special page breaks +%%% are already handled) or forces the |\output| routine to do this at an +%%% appropriate place. In the last case we can use |\trigger_output| +%%% again. Afterwards we restore the original meaning of |\mark| again to +%%% reduce the processing overhead (and the dead cycles). + +%%% This change of |\mark| has the consequence that the first |\mark| in a +%%% document cannot be used anymore in horizontal mode inside a vertical +%%% box that shall be split afterwards. But this is only sensible if this +%%% mark shall be used as |\splitfirstmark| because it will almost never +%%% migrate to the outer list---really a rare case! + +%%% \beginprog +\let\@@mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\@save_mark@true \fi % split marks! + \else \break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \trigger_output + \fi + \global\let\mark=\@@mark + \@@mark + } +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% If the output routine is triggered with the mark penalty value +%%% it will call |\start_saving_page_marks|. +%%% \end{sloppypar} + +%%% \beginprog +\def\start_saving_page_marks{% % this may be executed twice + \unvbox255 + \global\@save_mark@true + } +%%% \endprog + + +%%% \sect To finish the treatment of page marks we can formulate the two +%%% macros which are used at the first resp.\ second invocation of a +%%% ``special output,'' the principles have already been explained. + +%%% \beginprog +\def\backup_page_marks{% + \if@save_mark@ + \mark{\topmark}% + \xdef\save_firstmark{\firstmark}% + \xdef\save_botmark{\botmark}% + \fi + } + +\def\restore_page_marks{% + \if@save_mark@ + \mark{\save_firstmark}\mark{\save_botmark}% + \fi + } +%%% \endprog + + + + + +%%% \chap Positioning the Change Marks. + +%%% Now we must handle the positions of the bars. |\change_pos| will hold +%%% the position of the actual mark, i.e.\ the distance between top of page +%%% and actual mark. |\top_change_pos| will hold the beginning of a changed +%%% area; a value of |\maxdimen| indicates that no change is in effect. If +%%% a changed area is completed, it is appended to the list |\bar_list| as +%%% an element |\bar(\top_change_pos,\change_pos)|. This list contains all +%%% changed areas within the current page so that bars can be written later +%%% on. A single bar will be produced by |\write_bar|. + +%%% \noindent The definition of |\bar| to |\relax| allows the concatenation +%%% of new elements to |\bar_list| with |\xdef|. + +%%% \beginprog +\newdimen\change_pos +\newdimen\top_change_pos \top_change_pos=\maxdimen + +\let\bar_list=\empty + +\let\bar=\relax +\def\write_bar(#1,#2){% + \setbox0=\hbox{\vrule height -#1 depth #2}% + \dp0=0pt \ht0=0pt + \box0 + } +%%% \endprog + + +%%% \sect If the output routine was activated by a |\outputpenalty| value +%%% within the range of our reserved penalties, the change handling will +%%% occur, otherwise standard plain output can be done. + +%%% \beginprog +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\change_penalty_group\space \change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \start_saving_page_marks + \else \plainoutput + \fi + \fi + } +%%% \endprog + + +%%% \sect As explained before, the change handling must differentiate +%%% between the kind of the change command (beginning is indicated by +%%% $|\change_cmd|=0$, end by~1) and between the mode (horizontal indicated +%%% by an odd |\change_mode| value, vertical by an even). A change mode +%%% higher than one indicates that we are doing the first page break that +%%% has to backup the page as far as it exists already and results in an +%%% empty current list of page elements. + +%%% \beginprog +\newcount\change_cmd +\newcount\change_mode + +\def\change_handling{% + \change_cmd=-\outputpenalty % ==> absolute value + \advance \change_cmd by \change_penalty_group00 % subtraction + \change_mode=\change_cmd + \divide \change_cmd by 10 % second-to-last digit + \advance \change_mode by -\number\change_cmd0 % last digit + \ifnum \change_mode>1 \backup_page + \else + \ifcase \change_cmd \begin_change + \or \end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +%%% \endprog + + +%%% \sect Processing a mark during the second trigger of the output routine +%%% means restoring the page and storing the positions. At the beginning, +%%% the begin of the change is saved, at the end, we know the bar already +%%% and put it into the bar list. Then the positioning values are +%%% reinitialized. + +%%% As within every output invocation, the box 255 must be unboxed. As we +%%% are here in the second invocation of the output routine the |\box255| +%%% consists only of the empty |\vbox| we have inserted in +%%% |\trigger_output|. We can therefore throw it away. + +%%% \beginprog +\def\begin_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \global\top_change_pos=\change_pos \global\change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\end_change{% + \restore_page + \setbox0=\box255 + \ifdim \top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=\maxdimen \global\change_pos=0pt + \fi + } +%%% \endprog + + + + +%%% \chap Handling the Page Contents. + +%%% We handle the part of the page that was collected up to now by putting +%%% it into a box. This fixes the position of the change mark so that +%%% |\change_pos| can be set and stored later on in |\top_change_pos| or as +%%% the lower end of a bar in |\bar_list|. + +%%% To save the page contents in the first output invocation, we have to +%%% save the page in |\save_page|. Before that, we store the size of the +%%% box (which equals |\pagegoal|!)\ in |\page_goal|. If the unboxing +%%% caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +%%% we eject the page up to the change mark. Now we have to compute the +%%% current position of our mark in |\change_pos|. It is fixed by the size +%%% of the |\save_page|, but in case of a begin mark in horizontal mode we +%%% must decrease it from the baseline position to the top of the last line. +%%% Finally, we must save the values for the allowed insertions and change +%%% them to the maximal value so that a rest that is split from an insertion +%%% will be appended to the insertion box at the second invocation in every +%%% case. + +%%% The |\vsize| is initialized to |\maxdimen|. This allows to control +%%% whether this first output invocation ocurred or if it was discarded. +%%% For the same reason |\change_pos| is initialized to~0pt. + +%%% \beginprog +\newbox\save_page + +\newdimen\page_goal +\newdimen\save_vsize \save_vsize=\maxdimen +\newdimen\save_dimen_topins +\newdimen\save_dimen_footins + +\def\backup_page{% + \global\page_goal=\ht255 + \global\setbox\save_page=\vbox{\unvbox255}% + \ifdim \ht\save_page>\page_goal \eject_page_so_far \fi + \change_pos=\ht\save_page \global\advance \change_pos by \dp\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode \higher_change_pos \fi + \fi + \global\save_vsize=\vsize \global\vsize=\maxdimen + \global\save_dimen_topins=\dimen\topins \global\dimen\topins=\maxdimen + \global\save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \backup_page_marks + } + +\change_pos=0pt +%%% \endprog + + +%%% \sect To eject a page as far as it is we restore it from the +%%% |\save_page| back to box~255. In horizontal mode and at a begin mark +%%% the last line contains the mark and must not be output. So we remove it +%%% and the preceding glue from the stored rest, just leaving a single hbox +%%% to be on top of the actual page (in |\save_page|) now. Then normal +%%% output can be done with box~255. + +%%% \beginprog +\def\eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox255=\vbox to \page_goal{% + \unvbox\save_page + \ifnum \change_cmd=\change_penalty_begin\space + \ifodd \change_mode + \global\setbox\save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \plainoutput + } +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% In horizontal mode and at a begin mark, we need the position of +%%% the mark (|\change_pos|) on the upper boundary of the last line in +%%% |\save_page|. If there is just one line left from a recent eject, the +%%% height is given by the topskip decreased by the height of this hbox. If +%%% the height of the box is larger than |\topskip| the skip will not be +%%% inserted and the change position results to~0pt. Otherwise, +%%% |\save_page| is a vbox whose last hbox we delete temporarily using +%%% box~0. Height and depth of the rest are the actual position on the page. +%%% \end{sloppypar} + +%%% The double of the page we have constructed this way will immediately be +%%% fed back to the garbage collector because it could have become +%%% reasonably large. + +%%% \beginprog +\def\higher_change_pos{% + \ifhbox \save_page % rest of page from \eject_page_so_far + \change_pos=\topskip \global\advance \change_pos by -\ht\save_page + \ifdim \change_pos<0pt \global\change_pos=0pt \fi + \else + \setbox0=\vbox{% + \unvcopy\save_page + \setbox0=\lastbox % delete last line + }% + \change_pos=\ht0 \global\advance \change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +%%% \endprog + + +%%% \sect To restore a page during the second output invocation, we first +%%% restore the saved values, but only if they were really changed (this can +%%% be discovered by the value of |\save_vsize|). Now the |\save_page| is +%%% appended to the current list as a box, which stops later usage of its +%%% stretch- and shrinkability! Then the collected insertions can be +%%% inserted again. The page marks have to be inserted, too. + +%%% \beginprog +\def\restore_page{% + \ifdim \save_vsize=\maxdimen + \else \global\vsize=\save_vsize + \global\dimen\topins=\save_dimen_topins + \global\dimen\footins=\save_dimen_footins + \global\save_vsize=\maxdimen + \restore_page_marks + \fi + \box\save_page % discards stretch- and shrinkability! + \ifvoid \topins + \else \insert\topins{\floatingpenalty=0 \unvbox\topins}% + \fi + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +%%% \endprog + + +%%% \sect {\em Please note, that there is still a problem with this concept +%%% of handling the output trigger:} + +%%% \bigskip + +%%% If the first output trigger is discarded because a page break has occured +%%% just in front, footnote parts may be juggled around. I.e., if a +%%% footnote is split in three parts, the first part was just been shipped +%%% out, the second part is inserted back into the recent contributions by +%%% the output routine but {\em behind\/} the third part which is saved in +%%% the ``special place'' (according to the \TeX{}book, p.~125). A solution to +%%% this problem might be to insert a |\do_change| again within the second +%%% output trigger and finishing the treatmend afterwards. Afterwards a +%%% full triggering process (two output invocations) is executed again and +%%% alle insertion parts will be accessible in the insertion box. + +%%% By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +%%% \LaTeX{} this can happen every time because at the first output invocation +%%% the |\dimen|-values of the footnote insertion is not increased. I leave +%%% the problem open to the reader\,\dots + + + + + +%%% \chap Writing the Stuff. + +%%% The positions of the bars which mark the changed areas are relative to +%%% the top of the text, i.e.\ the height of the top insertion is not +%%% included. Therefore it is best to write them just after the top +%%% insertions before the page text---but to do this we have to change the +%%% Plain macro |\pagecontents|. + +%%% Below is the new definition, I have just rearranged it a little bit so +%%% that it is more legible. The line I have inserted is marked with +%%% `|%%%%|'. |\insert_current_bar| inserts a last element in |\bar_list| +%%% if a changed area is not yet finished, afterwards all bars can be +%%% written. + +%%% \beginprog +\def\pagecontents{% + \ifvoid \topins \else \unvbox\topins \fi + \insert_current_bar \write_all_bars %%%% + \dimen@=\dp\@cclv \unvbox\@cclv % open up \box255 + \ifvoid \footins + \else % footnote info is present + \vskip\skip\footins + \footnoterule + \unvbox\footins + \fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi + } +%%% \endprog + + +%%% \sect If $|\top_change_pos|=|\maxdimen|$ no change is active. Otherwise +%%% the current change reaches from the begin mark (|\top_change_pos|) to +%%% the end of the page, i.e.\ we insert a virtual end mark. Because the +%%% change continues on the next page we insert a virtual begin mark on the +%%% top of the page, too. + +%%% \beginprog +\def\insert_current_bar{% + \ifdim \top_change_pos=\maxdimen + \else + \change_pos=\ht255 \advance\change_pos by \dp255 + \xdef\bar_list{\bar_list \bar(\the\top_change_pos,\the\change_pos)}% + \global\top_change_pos=0pt + \fi + } +%%% \endprog + + +%%% \sect Now we can write all bars---if they exist anyway. It's rather +%%% easy, we just have to define |\bar| to |\write_bar| and execute +%%% |\bar_list|. The resulting output must not use vertical place. We must +%%% not forget to delete the list, or we will get the same bars on the next +%%% page again. + +%%% \noindent |\BarDistance| is the amount of place between the text margin +%%% and the change bars. + +%%% \beginprog +\newbox\@bars +\newdimen\BarDistance \BarDistance=2cc + +\def\write_all_bars{% + \ifx \bar_list\empty + \else % changes exist + \setbox\@bars=\hbox to \hsize{% + \hskip\hsize \hskip\BarDistance + \vbox to 0pt{\offinterlineskip + \let\bar=\write_bar \bar_list + }% + \hss + }% + \ht\@bars=0pt \dp\@bars=0pt \box\@bars + \global\let\bar_list=\empty + \fi + } +%%% \endprog + + +%%% \sect We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + +%%% \end{document} diff --git a/macros/latex209/contrib/chbars/chbars.aux b/macros/latex209/contrib/chbars/chbars.aux new file mode 100644 index 0000000000..ae1303f2e0 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars.aux @@ -0,0 +1,26 @@ +\relax +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1.}Introduction.}{1}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2.}GNU General Public License.}{3}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {3.}User Interface.}{4}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {4.}Utility Routines.}{5}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {5.}\hbox {}}{5}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {6.}Triggering the Output Routine.}{7}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {7.}\hbox {}}{7}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {8.}\hbox {}}{7}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {9.}\hbox {}}{8}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {10.}\hbox {}}{9}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {11.}\hbox {}}{9}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {12.}\hbox {}}{10}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {13.}Positioning the Change Marks.}{11}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {14.}\hbox {}}{11}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {15.}\hbox {}}{12}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {16.}\hbox {}}{12}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {17.}Handling the Page Contents.}{14}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {18.}\hbox {}}{14}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {19.}\hbox {}}{15}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {20.}\hbox {}}{16}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {21.}\hbox {}}{16}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {22.}Writing the Stuff.}{17}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {23.}\hbox {}}{17}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {24.}\hbox {}}{17}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {25.}\hbox {}}{18}} diff --git a/macros/latex209/contrib/chbars/chbars.doc b/macros/latex209/contrib/chbars/chbars.doc new file mode 100644 index 0000000000..42fe8c5378 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars.doc @@ -0,0 +1,998 @@ +% This is CHBARS.STY as of Aug '92 +% -*-LaTeX-*- +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in LaTeX. +% MAKEPROG will ``weave'' this file into documentation that can be LaTeX'ed. +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 92-08-15 -rlb Use change bars in this document to mark major changes; +% so now you can see for yourself what they are. +% 92-07-28 -rlb Run through a spelling checker before distributing. +% 92-01-15 -rlb 1) Keep \maxdeadcycles the same; just +% don't count calls to output for change processing. +% 2) Allow setting the change bar width. +% 3) Some typos and rewording of some of the comments. +% 4) Allow setting change bar width. Interface copied +% from changebars.sty +% 5) Allow changebars to be on the left as well as +% the right. +% 6) localize some variables global definitions now +% start with cb_. +% 7) Chain onto existing \output routine rather than assume +% \plainoutput. +% And miscellaneous minor hacks. +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +% +% +% These TeX macros were documented with the documentation system +% MAKEPROG and automatically converted to the current form. +% If you have MAKEPROG available you may transform it back to +% the original input: Remove every occurence of three percents +% and one optional blank from the beginning of a line and remove +% every line which starts with four percents. The following lex +% program will do this: +% +% %% +% +% ^%%%\ ? ; +% ^%%%%.*\n ; +% +% MAKEPROG may be obtained over the net from the Bitnet-Listserver +% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +% or via ftp from june.cs.washington.edu. +% +% +\documentstyle[progltx,chbars,a4-9]{article} + + +% +% local macros +% + +\let\mc=\small % for names like GNU + +\def\PS{{\sc PostScript}} +\def\DVI{{\tt DVI}} +\def\GNU{{\mc GNU}} + +\chardef\bs=`\\ + +% + + + +\begin{document} +\tableofcontents + +\title{Changebars without {\tt \bs{}special}'s} +\author{\sc Joachim Schrod} + +\newcommand{\changedate}{Aug 15, 1992} +\date{Revised last on \changedate\footnote{by {\tt rocky@watson.ibm.com}}\\ + Formatted on \today} +\maketitle + + + +\begin{abstract} +It is common practice to use vertical bars in the margins of a +document to mark pieces of text which have changed since the last +version(s) of this document. Such vertical bars are usually +called {\em changebars}. It has often been said that it is +impossible to produce changebars with \TeX{} without the usage of +|\special| commands (driver directives), which extend the +primitives of \TeX{}. This paper presents a \TeX{} macro file +which implements changebars without such a usage. The macro file +is written for the usage with {\sc Plain}~\TeX{} but the implementation +strategy can be used with \LaTeX{}, too with minor changes. + +\end{abstract} + + + +\chap Introduction. + +Changebars are used to mark modified parts in existing documents. For +the usage in \TeX{} documents, there exist only solutions that use +driver/printer features by the way of inserting |\special| commands in +the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +that are no longer as freely interchangeable as the \DVI{} concept would +allow---device dependency is problematic especially for this application +that is useful for multi-authoring or standards development. + +This macro package offers a pure \TeX{} solution. Nevertheless, it has +its restrictions, too. The page break will no longer be optimal, +because there is no strechability or shrinkability of a page +on top of the last +region of change marked. But this seems to be acceptable, +especially as the change bar feature often will be used for proof +reading and not in the final document. This restriction is the reason +why no change marks can be used on title pages or on similar +constructions. Changes in floating insertions (footnotes, figures) are +not handled. Multi-column formats such as a two-column layout +will not work. There is currently no support for nested changes. + +The method for writing a change bar consists of three +parts: First, the output routine is signalled when the beginning +or end of a change bar setting command is encountered. +Next, the position of the changed area is found out +and fixed; the end-of-change command adds the last change bar +position, length and width to a list of all such positions, +lengths and widths of change bars that is accumulated for the current +page. Finally, when +the output routine is triggered (either asynchronously in trying +to ship out the page or synchronously when discovering that the +end of a change bar lies off the page), this list of change +bars information is used create vertical rules which are added to the page. +If the change bar is not complete, a ``virtual'' end change is +inserted, and a ``virtual'' begin change is inserted at the +beginning of the next page. + +\beginchange +The demonstrated solution was originally written in {\sc Plain} +\TeX{}, because it was +easier and could be presented better at the Euro\TeX89 conference in +Karlsruhe. An adaptation to \LaTeX{} has been done too which +requires minor modifications to the \LaTeX's output routine. +\endchange + +Some history. The routines were initially written by Joachim +Schrod. Around Jan.\ 1992, R.\ Bernstein added some of the features +coded in |changebars.sty| to combine the best features +of the two (and added a couple of his own). For example, the +ability to specify change bar widths, put the change bars either on the +right or left margin, specifiy the distance from the margin to the +change bar, and chain to on top of a pre-existing modified +output routine. +\beginchange +Initially, both the {\TeX} and the {\LaTeX} +versions were put into one file. However, due problems in +dealing with conditional definition of code, in particular +problems with an extra or omitted |\fi| in defining or not +|\ifr@ggedbottom|, the code was split into two. +\endchange + +The |changebars.sty| package +was written by Michael Fine and revised by Johannes Braams +and Neil Winton. One or two ideas from Thomas J.~Reid have been +used. + +\chap GNU General Public License. + +This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~2, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +You should have received a copy of the \GNU{} General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\chap User Interface. + +\begin{newsloppy} +A changed area is described by two marks, |\beginchange| and +|\endchange|. The |\beginchange| can take an optional argument, +the bar thickness, enclosed in brackets. That is, either of the +something like |\beginchange[0.4pt]|, or |\beginchange| is valid. +In the latter case where no thickness dimension is specified, the value +of |\changebarwidth| is used. Therefore, by setting this you can +change the bar thickness used when none is given. Changing the bar +thickness might be useful in identifying different classes of changes. + +Another pair of global values that can be set are the +logical variables +{\tt \bs chbar\-Right\-true} and {\tt \bs chbar\-Right\-false}. +These specify whether +changebars should be on the right or left. Say, if one wanted to +have the changebars always appear on the outside margin, one could +change these accordingly on each page. +\end{newsloppy} + +Finally |\BarDistance| is the amount of place between the text margin +and the change bars. This value should normally be positive. For +change bars on the right this value is added to |\hsize|, while +for change bars on the left this value is {\em subtracted\/} from +|\hoffset|. + +\beginprog +\newdimen\changebarwidth \changebarwidth=1pt\relax +\newif\ifchbarRight \chbarRightfalse +\newdimen\BarDistance \BarDistance=2cc + +\endprog + +\chap Utility Routines and Programming Conventions. + +Before we get into the nitty gritty details, we give some common +macros. + +First, we declare some shorthands for category codes. By +declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +letters we can use them in our macros. (I agree with D.~Knuth that +|\identifier_several_words_long| is more readable than +|\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +\beginchange +By defining the at sign to be in the letter class, +we can access {\sc Plain} \TeX's ``private''macros. By defining the +underscore to be in the letter class, we make our own private macros more +readable. But since have to +restore these category codes at the end of this macro file, we store +\endchange +their former values in the control sequences |\atcode| and |\uscode|. +This method is better than to use a group because not all macros have to +be defined global this way. + +All {\em global\/} definitions of the package are prefixed by +|cb_|. In this way, they can be easily determined. If other +packages do likewise, it is less likely that definition +names will clash between packages. (Unless the other package uses the +|cb_| prefix too, in which case there is a good chance that many +variable names will clash.) + +The {\TeX}book recommends the 255 registers be used for scratch +space, so routines use this value when a spare register is +needed. (See for example |\cb_write_bar|.) + + +\beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter + +\endprog + +\sect Now we are ready to code the top-level routine for indicating the +beginning of a change. But first we display the banner and +version number associated with this package. If this package has +been loaded already we terminate. + +Although one can specify a bar +thickness on the |\beginchange| macro, it is at the |\endchange| +where this thickness is recorded and put on a current list of +change bar entries for the current page. It seems more natural to +specify the thickness at the beginning of the change rather than +the end. Therefore at the +|\beginchange| we merely save the value given or save the value of +|\changebarwidth| if no thickness was given. +|\cb_changebarwidth| is this saved value. Auxiliary routine +|\cb_xstart| is used to parse off the optional enclosing +brackets. (This weird name was taken from one used in |changebars.sty|.) + +default value, that is the value when a width is not specified +is |\changebarwidth|. + +\beginprog + +\@ifundefined{cb_xstart}{}{\endinput} +\typeout{Style option `change bars' -- version 1.1a} + +\newdimen\cb_changebarwidth + +\def\beginchange{\@ifnextchar [ + {\cb_xstart} + {\beginchange_\changebarwidth}} +\def\cb_xstart[#1]{\beginchange_{#1}} + +\endprog + +\chap Triggering the Output Routine. + +\beginchange +When a change bar is started or completed, we signal the output +routine in the ``usual'' way described below. Why bother the +output routine? The output routine is supposed to be thought of +as an asynchronous process which has access to the page via the +contents of box register 255. In theory, if we did not perform +actions in the output routine, it might get triggered inadvertantly, +and the output routine might modify this box register on us in the +midst of our work. The information that needs to be recorded +is the position of the beginning and end of the lines containing a +marked change region. + +\begin{newsloppy} +The macros |\beginchange| and |\endchange| signal the output +routine. Rather than merely calling the output routine directly, +these routines signal the output routine by setting a low page penalty, i.e., +one which tells {\TeX} that this is a really good place to break +the page. Of course, we will modify the output routine so that it +doesn't really split the page when it has been called in this fashion. +Again, the reason we signal the output routine in what seems at +first a pretty odd way, is that this is the way it is supposed to +be done. If a low penalty were not set, some +other action (if we weren't careful) might cause a penalty to be +set and thus call the output routine (recursively). + +So that we can distinguish our calls from others, |\beginchange| +and |\endchange| reserve a range of +penalty values; he actual value is stored in |\cb_break_penalty|. +This range of values is below +$-10\,000$, the nominal value for indicating that a page should +occur now. The penalty will be in the range $|\cb_penalty_group| +\cdot 100 - 99 \ldots |\cb_penalty_group| \cdot 100$. +The output routine then decides whether it has been called +to start or end a change bar or neither. This is done with the values +|\cb_penalty_begin| and |\cb_penalty_end| that are used as the +second-to-last digit of the change penalty. +\end{newsloppy} + +The output routine also needs to determine whether +the beginning of change bar starts in horizontal or vertical mode +so it can figure out the exact placement for the beginning of the +bar line. In horizontal mode, the change bar does +not begin at the baseline of the actual text position, but on top of the +actual line. This is marked in the last digit, an odd digit will be +used in horizontal mode. + +Note that the values mentioned above are used as digits here that can be +concatenated. If they are not followed by an other digit they should be +terminated by |\space| to stop {\TeX}'s look-ahead scanning for +digits when reading a number. +\endchange + +\beginprog +\def\cb_penalty_group{-101} \def\cb_penalty_begin{0} +\def\cb_penalty_end{1} + +\endprog + + +\sect The calls to start or end a change bar, set an encoded page-break +penalty which includes an +indication of begin or end of a change bar. The variable +|\cb_break_penalty| is used to create such as special value. +The rest (|\cb_trigger_output|) is the same action +for both. The region just before the end of the changed region can be +in horizontal mode and preceded by +glue that could cause a line break, thus including the following line to +the change area as well. To avoid this unwanted behavior, the space is +saved in |\save_lastskip|, discarded in front of the mark and restored +afterwards. + +\beginprog +\newcount\cb_break_penalty + +\def\beginchange_#1{% + \cb_changebarwidth=#1 + \cb_break_penalty=\cb_penalty_group\cb_penalty_begin0 + \cb_trigger_output + } +\def\endchange{{% + \skipdef\save_lastskip=255% + \ifhmode \save_lastskip=\lastskip \unskip \fi% + \cb_break_penalty=\cb_penalty_group\cb_penalty_end0% + \cb_trigger_output% + \ifhmode \hskip\save_lastskip \fi% + }}%\endchange +\endprog + + +\sect The next routine, |\cb_trigger_output|, +triggers calls to the output routine by setting the page-break +penalty, |\penalty|. {\TeX} may discard an |\output| invocation at +the beginning of a page. So we trigger the output routine twice, first +with a special penalty value that is 2~less than the correct value +(including the code for horizontal or vertical mode). After the first +page break, it is asserted that the current list is empty. The output +routine has to save the former page contents if necessary. + +Next we set the penalty to the correct value. The second page break does +the real work, restores the page contents and handles the split +insertions (footnotes, figures,~\dots). + +In horizontal mode |\spacefactor| must not be destroyed, so it is +saved and restored via local count register |\save_spacefactor|. + +\beginprog + +\def\cb_trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else{% + \countdef\save_spacefactor=255% + \ifvmode + \let\do_in_vmode=\relax + \advance \cb_break_penalty by -2 + \else + \save_spacefactor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \cb_break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\cb_break_penalty% first call to \output + \null + \advance \cb_break_penalty by 2 + \penalty\cb_break_penalty% second call to \output + }% + \ifhmode \spacefactor=\save_spacefactor \fi + }% + \fi + }% cb_trigger_output +\endprog + + +\sect Using the output routine for passing +information has it's difficulties. One of the hard parts is +\beginchange +handling page marks. These are token lists which are set by the +|\mark| command. They record information that can later +be accessed by the output routine. The canonical example of such +a use of the |\mark| command is in creating +\endchange +dictionary-style entry headings. + +The output routine can access one of three +token lists through three control sequences: |\botmark| is the +last page mark given, |\topmark| is the |\botmark| of the previous +page, and |\firstmark| is the first page mark on the actual page or +|\topmark| if none was given. Here ``page'' is used in the \TeX{} +sense, i.e.\ as the material which has been collected between two +|\output| invocations. Of course, the page marks must not be +destroyed---and that means they must be reinserted after each +special use of the output routine. + +But we are lucky: A ``special use'' consists of two |\output| +invocations, so we can insert |\topmark| again as a page mark after +the first invocation where it will be the only page mark on that +\TeX{} page. The second invocation will automatically transform this +page mark into the ``last page mark on the previous page,'' i.e.\ in +|\topmark|---that's what we need! Furthermore |\firstmark| and +|\botmark| are saved in control sequences during the first invocation, +they will be inserted again, too. + +There's one situation where this approach doesn't work: in front of +the first page mark. Here, |\topmark|, |\firstmark|, and |\botmark| expand +to an empty token list. If we save them then and insert their old +values we have inserted empty page marks. If other page marks follow +on the same ``real'' page, |\firstmark| will be empty instead of +expanding to the token list of the first page mark. To prevent this +we must not save and restore page marks before the first |\mark| has +been added to the main vertical list. + +Well, that can be controlled with a switch---but this switch must be +set very carefully. If it is set immediately by the first |\mark| +this may be in horizontal mode and special output invocations can +occur above this page mark (i.e., there may be a |\beginchange| in the +same paragraph in front of the |\mark|). Therefore the setting of the +switch must be delayed until the vertical position of the |\mark| +(precisely: the position of the |\mark| in the current list) is +reached. In horizontal mode this can be done with a |\vadjust| and +the output routine! Voil\`a, this is another command group for the +output routine with only one command. + +\beginprog +\newif\if_cb_save_mark@ \_cb_save_mark@false + +\def\mark_penalty_group{-102} +\endprog + + +\sect We will redefine |\mark| so that the first page mark either sets +the switch to true (in vertical mode all possible special page breaks +are already handled) or forces the |\output| routine to do this at an +appropriate place. In the last case we can use |\cb_trigger_output| +again. Afterwards we restore the original meaning of |\mark| again to +reduce the processing overhead (and the dead cycles). + +This change of |\mark| has the consequence that the first |\mark| in a +document cannot be used anymore in horizontal mode inside a vertical +box that shall be split afterwards. But this is only sensible if this +mark shall be used as |\splitfirstmark| because it will almost never +migrate to the outer list---really a rare case! + +\beginprog +\let\cb_mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\_cb_save_mark@true \fi % split marks! + \else + \cb_break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \cb_trigger_output + \fi + \global\let\mark=\cb_mark + \cb_mark + } +\endprog + + +\sect +\begin{newsloppy} +If the output routine is triggered with the mark penalty value, +it will call {\tt \bs cb\_save\discretionary{\_}{}{}page\_marks}. +\end{newsloppy} + +\beginprog +\def\cb_save_page_marks{% % this may be executed twice + \unvbox\@cclv + \global\_cb_save_mark@true + } +\endprog + + +\sect To finish the treatment of page marks we can formulate the two +macros which are used at the first resp.\ second invocation of a +``special output,'' the principles have already been explained. + +\beginprog +\def\cb_backup_page_marks{% + \if_cb_save_mark@ + \mark{\topmark}% + \xdef\cb_save_firstmark{\firstmark}% + \xdef\cb_save_botmark{\botmark}% + \fi + } + +\def\cb_restore_page_marks{% + \if_cb_save_mark@ + \mark{\cb_save_firstmark}\mark{\cb_save_botmark}% + \fi + } +\endprog + + + + + +\chap Positioning the Change Bars. + +\begin{newsloppy} +Now we handle the positions of the bars. +The dimension |\cb_bot_change_pos| will hold +the position of the end of the change bar, i.e.\ the distance between +top of page the end of the changed area. The dimension +|\cb_top_change_pos| will hold the beginning of a changed +area; a value of |\maxdimen| indicates that no change is in effect. If +a changed area is completed, it is appended to the list |\cb_bar_list| as +an element {\tt \bs cb\_bar(\bs cb\_top\_change\_pos, +\bs cb\_bot\_change\_pos, \bs changebar\-width)}. This list contains all +changed areas within the current page so that bars can be written later +on. A single bar will be produced by |\cb_write_bar|. + +\noindent The definition of |\cb_bar| to |\relax| allows the concatenation +of new elements to |\cb_bar_list| with |\xdef|. + +Local dimension register |\halfwidth| is used to center the change bar. +\end{newsloppy} + +\beginprog +\newdimen\cb_bot_change_pos +\newdimen\cb_top_change_pos \cb_top_change_pos=\maxdimen + +\let\cb_bar_list=\empty + +\let\cb_bar=\relax +\def\cb_write_bar(#1,#2,#3){{% + \dimendef\halfwidth=255% + \setbox0=\hbox{\vrule width #3 height -#1 depth #2}% + \dp0=0pt \ht0=0pt \wd0=0pt% + \halfwidth=#3 \divide\dimen255 by 2% + \hskip -\halfwidth% + \box0% + \hskip \halfwidth% + }} +\endprog + + +\sect If the output routine was activated by a |\outputpenalty| value +within the range of our reserved penalties, the change handling will +occur, otherwise standard plain output can be done. There may be +a lot of interaction between the routines which set change bars and +the output routine. These interactions should not be recorded in +|\deadcycles| or else \TeX{} will soon grumble. One might consider +doing the same for the|\mark_penalty_group|. But since this +group is called once it shouldn't matter all that much. + +One might also consider adding a counter like |\deadcycles| just +to count the change bar interactions as is done for the calls to +|\output|, and have {\TeX} grumble if there are ``too many'' of +them. For now we don't do this---all of this code is correct +anyway! + +First we save away the old output routine in case the user had redefined +this beforehand. + +\beginprog +\newtoks\cb_oldoutput +\edef\cb_oldoutput{\the\output} + +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\cb_penalty_group\space + {\countdef\new_deadcycles=255% don't count as a dead cycle + \new_deadcycles=\deadcycles + \advance \new_deadcycles by -1 + \deadcycles=\new_deadcycles} + \cb_change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \cb_save_page_marks + \else \cb_oldoutput + \fi + \fi + } +\endprog + + +\sect As explained before, the change handling must differentiate +between the kind of the change command (beginning is indicated by +$|\cb_change_cmd|=0$, end by~1) and between the mode (horizontal indicated +by an odd |\cb_change_mode| value, vertical by an even). A change mode +higher than one indicates that we are doing the first page break that +has to backup the page as far as it exists already and results in an +empty current list of page elements. + +\beginprog +\newcount\cb_change_cmd +\newcount\cb_change_mode + +\def\cb_change_handling{% + \cb_change_cmd=-\outputpenalty % ==> absolute value + \advance \cb_change_cmd by \cb_penalty_group00 % subtraction + \cb_change_mode=\cb_change_cmd + \divide \cb_change_cmd by 10 % second-to-last digit + \advance \cb_change_mode by -\number\cb_change_cmd0 % last digit + \ifnum \cb_change_mode>1 \cb_backup_page + \else + \ifcase \cb_change_cmd \cb_begin_change + \or \cb_end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +\endprog + + +\sect Processing a mark during the second trigger of the output routine +means restoring the page and storing the positions. At the beginning, +the begin of the change is saved, at the end, we know the bar already +and put it into the bar list. Then the positioning values are +reinitialized. + +As within every output invocation, the box 255 must be unboxed. As we +are here in the second invocation of the output routine the |\box255| +consists only of the empty |\vbox| we have inserted in +|\cb_trigger_output|. We can therefore throw it away. + +\beginprog +\def\cb_begin_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \global\cb_top_change_pos=\cb_bot_change_pos + \global\cb_bot_change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\cb_end_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos,\the\cb_bot_change_pos, + \the\cb_changebarwidth)} + \global\cb_top_change_pos=\maxdimen + \global\cb_bot_change_pos=0pt + \fi + } +\endprog + + +\chap Handling the Page Contents. + +We handle the part of the page that was collected up to now by putting +it into a box. This fixes the position of the change mark so that +|\cb_bot_change_pos| can be set and stored in |\cb_top_change_pos| +later on or as the lower end of a bar in |\cb_bar_list|. + +In the first output invocation, we save the contents of the +page in |\cb_save_page|. Before that, we store the size of the +box (which equals |\pagegoal|!)\ in |\cb_page_goal|. If the unboxing +caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +we eject the page up to the change mark. Now we have to compute the +current position of our mark in |\cb_bot_change_pos|. It is fixed by the size +of the |\cb_save_page|, but if the change begins in horizontal mode we +must decrease it from the baseline position to the top of the last line. +Finally, we must save the values for the allowed insertions and change +them to the maximal value so that a rest that is split from an insertion +will be appended to the insertion box at the second invocation in every +case. + +The |\vsize| is initialized to |\maxdimen|. This allows to control +whether this first output invocation ocurred or if it was discarded. +For the same reason |\cb_bot_change_pos| is initialized to~0pt. + +\beginprog +\newbox\cb_save_page + +\newdimen\cb_page_goal +\newdimen\cb_save_vsize \cb_save_vsize=\maxdimen +\newdimen\cb_save_dimen_topins +\newdimen\cb_save_dimen_footins + +\def\cb_backup_page{% + \global\cb_page_goal=\ht\@cclv + \global\setbox\cb_save_page=\vbox{\unvbox\@cclv}% + \ifdim \ht\cb_save_page>\cb_page_goal + \cb_eject_page_so_far \fi + \cb_bot_change_pos=\ht\cb_save_page + \global\advance \cb_bot_change_pos by \dp\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode \higher_change_pos \fi + \fi + \global\cb_save_vsize=\vsize \global\vsize=\maxdimen + \global\cb_save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \cb_backup_page_marks + } + +\cb_bot_change_pos=0pt +\endprog + + +\sect To eject a page as far as it is we restore it from the +|\cb_save_page| back to box~255. In horizontal mode and at a begin mark +the last line contains the mark and must not be output. So we remove it +and the preceding glue from the stored rest, just leaving a single hbox +to be on top of the actual page (in |\cb_save_page|) now. Then normal +output can be done with box~255. + +\beginprog +\def\cb_eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox\@cclv=\vbox to \cb_page_goal{% + \unvbox\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode + \global\setbox\cb_save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \cb_oldoutput + } +\endprog + + +\sect +\begin{newsloppy} +In horizontal mode and at a begin mark, we need the position of +the mark ({\tt \bs cb\_bot\discretionary{\_}{}{}change\_pos}) on the upper boundary of +the last line in +|\cb_save_page|. If there is just one line left from a recent eject, the +height is given by |\topskip| decreased by the height of this hbox. If +the height of the box is larger than |\topskip| the skip will not be +inserted and the change position results to~0pt. Otherwise, +|\cb_save_page| is a vbox whose last hbox we delete temporarily using +box~0. Height and depth of the rest are the actual position on the page. +\end{newsloppy} + +The double of the page we have constructed this way will immediately be +fed back to the garbage collector because it could have become +reasonably large. + +\beginprog +\def\higher_change_pos{% + \ifhbox \cb_save_page % rest of page from \cb_eject_page_so_far + \cb_bot_change_pos=\topskip + \global\advance \cb_bot_change_pos by -\ht\cb_save_page + \ifdim \cb_bot_change_pos<0pt + \global\cb_bot_change_pos=0pt + \fi + \else + \setbox0=\vbox{% + \unvcopy\cb_save_page + \setbox0=\lastbox % delete last line + }% + \cb_bot_change_pos=\ht0 + \global\advance \cb_bot_change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +\endprog + + +\sect To restore a page during the second output invocation, we first +restore the saved values, but only if they were really changed (this can +be discovered by the value of |\cb_save_vsize|). Now the |\cb_save_page| is +appended to the current list as a box, which stops later usage of its +stretch- and shrinkability! Then the collected insertions can be +inserted again. The page marks have to be inserted, too. + +\beginprog +\def\cb_restore_page{% + \ifdim \cb_save_vsize=\maxdimen + \else \global\vsize=\cb_save_vsize + \global\dimen\footins=\cb_save_dimen_footins + \global\cb_save_vsize=\maxdimen + \cb_restore_page_marks + \fi + \box\cb_save_page % discards stretch- and shrinkability! + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +\endprog + + +\sect {\em Please note, that there is still a problem with this concept +of handling the output trigger:} + +\bigskip + +If the first output trigger is discarded because a page break has occurred +just in front, footnote parts may be juggled around. I.e., if a +footnote is split in three parts, the first part was just been shipped +out, the second part is inserted back into the recent contributions by +the output routine but {\em behind\/} the third part which is saved in +the ``special place'' (according to the \TeX{}book, p.~125). A solution to +this problem might be to insert a |\do_change| again within the second +output trigger and finishing the treatment afterwards. Afterwards a +full triggering process (two output invocations) is executed again and +all insertion parts will be accessible in the insertion box. + +By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +\LaTeX{} this can happen every time because at the first output invocation +the |\dimen|-values of the footnote insertion is not increased. I leave +the problem open to the reader\,\dots + + + + + +\chap Writing the Stuff. + +The positions of the bars which mark the changed areas are relative to +the top of the text, i.e.\ the height of the top insertion is not +included. Therefore it is best to write them just after the top +insertions before the page text---but to do this we have to change the +\beginchange +either the {\sc Plain} {\TeX} macro |\pagecontents| or the {\LaTeX} +macro |\@makecol|. +\endchange + +Below is the new definition, I have just rearranged it a little bit so +that it is more legible. The new lines have been marked with +`|%%%%|'. |\cb_insert_current_bar| inserts a last element in |\cb_bar_list| +if a changed area is not yet finished, afterwards all bars can be +written. + +\beginprog +\def\@makecol{% + \ifvoid\footins + \setbox\@outputbox + \vbox{ + %\typeout{write all bars -- no footins} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv% + } + \else + \setbox\@outputbox + \vbox{\boxmaxdepth \maxdepth + %\typeout{write all bars} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv\vskip\skip\footins\footnoterule\unvbox\footins% + } + \fi% + \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats + \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth + \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox + \vskip-\dimen128\@textbottom}% + \global\maxdepth\@maxdepth} +\endprog + +\sect If $|\cb_top_change_pos|=|\maxdimen|$ no change is active. Otherwise +the current change reaches from the begin mark (|\cb_top_change_pos|) to +the end of the page, i.e.\ we insert a virtual end mark. Because the +change continues on the next page we insert a virtual begin mark on the +top of the page, too. + +\beginprog +\def\cb_insert_current_bar{% + \ifdim \cb_top_change_pos=\maxdimen + \else% + \cb_bot_change_pos=\ht\@cclv + \advance\cb_bot_change_pos by \dp\@cclv + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos, + \the\cb_bot_change_pos, + \the\changebarwidth)}% + \global\cb_top_change_pos=0pt + \fi% + } +\endprog + + +\sect Now we can write all bars---if they exist anyway. It's rather +easy, we just have to define |\cb_bar| to |\cb_write_bar| and execute +|\cb_bar_list|. The resulting output must not use vertical place. We must +not forget to delete the list, or we will get the same bars on the next +page again. + +\beginprog +\newbox\cb_bars +\newdimen\cb_offset + +\def\cb_write_all_bars{% + \ifx \cb_bar_list\empty + \else % changes exist + \ifchbarRight + \cb_offset = \hsize + \advance \cb_offset by \BarDistance + \else + \cb_offset = \hoffset + \advance \cb_offset by -\BarDistance + \fi + \setbox\cb_bars=\hbox to \cb_offset{% + \hskip\cb_offset + \vbox to 0pt{\offinterlineskip + \let\cb_bar=\cb_write_bar \cb_bar_list + }% + \hss + }% + \ht\cb_bars=0pt \dp\cb_bars=0pt \box\cb_bars + \global\let\cb_bar_list=\empty + \fi + } +\endprog + + +\beginchange\chap Cleaning Up.\endchange + +We finish the macro file so that garbage (e.g.\ of exchanges +between systems) can come afterwards. + +\beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +\endprog + + + +\end{document} + diff --git a/macros/latex209/contrib/chbars/chbars.ltx b/macros/latex209/contrib/chbars/chbars.ltx new file mode 100644 index 0000000000..42fe8c5378 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars.ltx @@ -0,0 +1,998 @@ +% This is CHBARS.STY as of Aug '92 +% -*-LaTeX-*- +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in LaTeX. +% MAKEPROG will ``weave'' this file into documentation that can be LaTeX'ed. +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 92-08-15 -rlb Use change bars in this document to mark major changes; +% so now you can see for yourself what they are. +% 92-07-28 -rlb Run through a spelling checker before distributing. +% 92-01-15 -rlb 1) Keep \maxdeadcycles the same; just +% don't count calls to output for change processing. +% 2) Allow setting the change bar width. +% 3) Some typos and rewording of some of the comments. +% 4) Allow setting change bar width. Interface copied +% from changebars.sty +% 5) Allow changebars to be on the left as well as +% the right. +% 6) localize some variables global definitions now +% start with cb_. +% 7) Chain onto existing \output routine rather than assume +% \plainoutput. +% And miscellaneous minor hacks. +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +% +% +% These TeX macros were documented with the documentation system +% MAKEPROG and automatically converted to the current form. +% If you have MAKEPROG available you may transform it back to +% the original input: Remove every occurence of three percents +% and one optional blank from the beginning of a line and remove +% every line which starts with four percents. The following lex +% program will do this: +% +% %% +% +% ^%%%\ ? ; +% ^%%%%.*\n ; +% +% MAKEPROG may be obtained over the net from the Bitnet-Listserver +% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +% or via ftp from june.cs.washington.edu. +% +% +\documentstyle[progltx,chbars,a4-9]{article} + + +% +% local macros +% + +\let\mc=\small % for names like GNU + +\def\PS{{\sc PostScript}} +\def\DVI{{\tt DVI}} +\def\GNU{{\mc GNU}} + +\chardef\bs=`\\ + +% + + + +\begin{document} +\tableofcontents + +\title{Changebars without {\tt \bs{}special}'s} +\author{\sc Joachim Schrod} + +\newcommand{\changedate}{Aug 15, 1992} +\date{Revised last on \changedate\footnote{by {\tt rocky@watson.ibm.com}}\\ + Formatted on \today} +\maketitle + + + +\begin{abstract} +It is common practice to use vertical bars in the margins of a +document to mark pieces of text which have changed since the last +version(s) of this document. Such vertical bars are usually +called {\em changebars}. It has often been said that it is +impossible to produce changebars with \TeX{} without the usage of +|\special| commands (driver directives), which extend the +primitives of \TeX{}. This paper presents a \TeX{} macro file +which implements changebars without such a usage. The macro file +is written for the usage with {\sc Plain}~\TeX{} but the implementation +strategy can be used with \LaTeX{}, too with minor changes. + +\end{abstract} + + + +\chap Introduction. + +Changebars are used to mark modified parts in existing documents. For +the usage in \TeX{} documents, there exist only solutions that use +driver/printer features by the way of inserting |\special| commands in +the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +that are no longer as freely interchangeable as the \DVI{} concept would +allow---device dependency is problematic especially for this application +that is useful for multi-authoring or standards development. + +This macro package offers a pure \TeX{} solution. Nevertheless, it has +its restrictions, too. The page break will no longer be optimal, +because there is no strechability or shrinkability of a page +on top of the last +region of change marked. But this seems to be acceptable, +especially as the change bar feature often will be used for proof +reading and not in the final document. This restriction is the reason +why no change marks can be used on title pages or on similar +constructions. Changes in floating insertions (footnotes, figures) are +not handled. Multi-column formats such as a two-column layout +will not work. There is currently no support for nested changes. + +The method for writing a change bar consists of three +parts: First, the output routine is signalled when the beginning +or end of a change bar setting command is encountered. +Next, the position of the changed area is found out +and fixed; the end-of-change command adds the last change bar +position, length and width to a list of all such positions, +lengths and widths of change bars that is accumulated for the current +page. Finally, when +the output routine is triggered (either asynchronously in trying +to ship out the page or synchronously when discovering that the +end of a change bar lies off the page), this list of change +bars information is used create vertical rules which are added to the page. +If the change bar is not complete, a ``virtual'' end change is +inserted, and a ``virtual'' begin change is inserted at the +beginning of the next page. + +\beginchange +The demonstrated solution was originally written in {\sc Plain} +\TeX{}, because it was +easier and could be presented better at the Euro\TeX89 conference in +Karlsruhe. An adaptation to \LaTeX{} has been done too which +requires minor modifications to the \LaTeX's output routine. +\endchange + +Some history. The routines were initially written by Joachim +Schrod. Around Jan.\ 1992, R.\ Bernstein added some of the features +coded in |changebars.sty| to combine the best features +of the two (and added a couple of his own). For example, the +ability to specify change bar widths, put the change bars either on the +right or left margin, specifiy the distance from the margin to the +change bar, and chain to on top of a pre-existing modified +output routine. +\beginchange +Initially, both the {\TeX} and the {\LaTeX} +versions were put into one file. However, due problems in +dealing with conditional definition of code, in particular +problems with an extra or omitted |\fi| in defining or not +|\ifr@ggedbottom|, the code was split into two. +\endchange + +The |changebars.sty| package +was written by Michael Fine and revised by Johannes Braams +and Neil Winton. One or two ideas from Thomas J.~Reid have been +used. + +\chap GNU General Public License. + +This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~2, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +You should have received a copy of the \GNU{} General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\chap User Interface. + +\begin{newsloppy} +A changed area is described by two marks, |\beginchange| and +|\endchange|. The |\beginchange| can take an optional argument, +the bar thickness, enclosed in brackets. That is, either of the +something like |\beginchange[0.4pt]|, or |\beginchange| is valid. +In the latter case where no thickness dimension is specified, the value +of |\changebarwidth| is used. Therefore, by setting this you can +change the bar thickness used when none is given. Changing the bar +thickness might be useful in identifying different classes of changes. + +Another pair of global values that can be set are the +logical variables +{\tt \bs chbar\-Right\-true} and {\tt \bs chbar\-Right\-false}. +These specify whether +changebars should be on the right or left. Say, if one wanted to +have the changebars always appear on the outside margin, one could +change these accordingly on each page. +\end{newsloppy} + +Finally |\BarDistance| is the amount of place between the text margin +and the change bars. This value should normally be positive. For +change bars on the right this value is added to |\hsize|, while +for change bars on the left this value is {\em subtracted\/} from +|\hoffset|. + +\beginprog +\newdimen\changebarwidth \changebarwidth=1pt\relax +\newif\ifchbarRight \chbarRightfalse +\newdimen\BarDistance \BarDistance=2cc + +\endprog + +\chap Utility Routines and Programming Conventions. + +Before we get into the nitty gritty details, we give some common +macros. + +First, we declare some shorthands for category codes. By +declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +letters we can use them in our macros. (I agree with D.~Knuth that +|\identifier_several_words_long| is more readable than +|\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +\beginchange +By defining the at sign to be in the letter class, +we can access {\sc Plain} \TeX's ``private''macros. By defining the +underscore to be in the letter class, we make our own private macros more +readable. But since have to +restore these category codes at the end of this macro file, we store +\endchange +their former values in the control sequences |\atcode| and |\uscode|. +This method is better than to use a group because not all macros have to +be defined global this way. + +All {\em global\/} definitions of the package are prefixed by +|cb_|. In this way, they can be easily determined. If other +packages do likewise, it is less likely that definition +names will clash between packages. (Unless the other package uses the +|cb_| prefix too, in which case there is a good chance that many +variable names will clash.) + +The {\TeX}book recommends the 255 registers be used for scratch +space, so routines use this value when a spare register is +needed. (See for example |\cb_write_bar|.) + + +\beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter + +\endprog + +\sect Now we are ready to code the top-level routine for indicating the +beginning of a change. But first we display the banner and +version number associated with this package. If this package has +been loaded already we terminate. + +Although one can specify a bar +thickness on the |\beginchange| macro, it is at the |\endchange| +where this thickness is recorded and put on a current list of +change bar entries for the current page. It seems more natural to +specify the thickness at the beginning of the change rather than +the end. Therefore at the +|\beginchange| we merely save the value given or save the value of +|\changebarwidth| if no thickness was given. +|\cb_changebarwidth| is this saved value. Auxiliary routine +|\cb_xstart| is used to parse off the optional enclosing +brackets. (This weird name was taken from one used in |changebars.sty|.) + +default value, that is the value when a width is not specified +is |\changebarwidth|. + +\beginprog + +\@ifundefined{cb_xstart}{}{\endinput} +\typeout{Style option `change bars' -- version 1.1a} + +\newdimen\cb_changebarwidth + +\def\beginchange{\@ifnextchar [ + {\cb_xstart} + {\beginchange_\changebarwidth}} +\def\cb_xstart[#1]{\beginchange_{#1}} + +\endprog + +\chap Triggering the Output Routine. + +\beginchange +When a change bar is started or completed, we signal the output +routine in the ``usual'' way described below. Why bother the +output routine? The output routine is supposed to be thought of +as an asynchronous process which has access to the page via the +contents of box register 255. In theory, if we did not perform +actions in the output routine, it might get triggered inadvertantly, +and the output routine might modify this box register on us in the +midst of our work. The information that needs to be recorded +is the position of the beginning and end of the lines containing a +marked change region. + +\begin{newsloppy} +The macros |\beginchange| and |\endchange| signal the output +routine. Rather than merely calling the output routine directly, +these routines signal the output routine by setting a low page penalty, i.e., +one which tells {\TeX} that this is a really good place to break +the page. Of course, we will modify the output routine so that it +doesn't really split the page when it has been called in this fashion. +Again, the reason we signal the output routine in what seems at +first a pretty odd way, is that this is the way it is supposed to +be done. If a low penalty were not set, some +other action (if we weren't careful) might cause a penalty to be +set and thus call the output routine (recursively). + +So that we can distinguish our calls from others, |\beginchange| +and |\endchange| reserve a range of +penalty values; he actual value is stored in |\cb_break_penalty|. +This range of values is below +$-10\,000$, the nominal value for indicating that a page should +occur now. The penalty will be in the range $|\cb_penalty_group| +\cdot 100 - 99 \ldots |\cb_penalty_group| \cdot 100$. +The output routine then decides whether it has been called +to start or end a change bar or neither. This is done with the values +|\cb_penalty_begin| and |\cb_penalty_end| that are used as the +second-to-last digit of the change penalty. +\end{newsloppy} + +The output routine also needs to determine whether +the beginning of change bar starts in horizontal or vertical mode +so it can figure out the exact placement for the beginning of the +bar line. In horizontal mode, the change bar does +not begin at the baseline of the actual text position, but on top of the +actual line. This is marked in the last digit, an odd digit will be +used in horizontal mode. + +Note that the values mentioned above are used as digits here that can be +concatenated. If they are not followed by an other digit they should be +terminated by |\space| to stop {\TeX}'s look-ahead scanning for +digits when reading a number. +\endchange + +\beginprog +\def\cb_penalty_group{-101} \def\cb_penalty_begin{0} +\def\cb_penalty_end{1} + +\endprog + + +\sect The calls to start or end a change bar, set an encoded page-break +penalty which includes an +indication of begin or end of a change bar. The variable +|\cb_break_penalty| is used to create such as special value. +The rest (|\cb_trigger_output|) is the same action +for both. The region just before the end of the changed region can be +in horizontal mode and preceded by +glue that could cause a line break, thus including the following line to +the change area as well. To avoid this unwanted behavior, the space is +saved in |\save_lastskip|, discarded in front of the mark and restored +afterwards. + +\beginprog +\newcount\cb_break_penalty + +\def\beginchange_#1{% + \cb_changebarwidth=#1 + \cb_break_penalty=\cb_penalty_group\cb_penalty_begin0 + \cb_trigger_output + } +\def\endchange{{% + \skipdef\save_lastskip=255% + \ifhmode \save_lastskip=\lastskip \unskip \fi% + \cb_break_penalty=\cb_penalty_group\cb_penalty_end0% + \cb_trigger_output% + \ifhmode \hskip\save_lastskip \fi% + }}%\endchange +\endprog + + +\sect The next routine, |\cb_trigger_output|, +triggers calls to the output routine by setting the page-break +penalty, |\penalty|. {\TeX} may discard an |\output| invocation at +the beginning of a page. So we trigger the output routine twice, first +with a special penalty value that is 2~less than the correct value +(including the code for horizontal or vertical mode). After the first +page break, it is asserted that the current list is empty. The output +routine has to save the former page contents if necessary. + +Next we set the penalty to the correct value. The second page break does +the real work, restores the page contents and handles the split +insertions (footnotes, figures,~\dots). + +In horizontal mode |\spacefactor| must not be destroyed, so it is +saved and restored via local count register |\save_spacefactor|. + +\beginprog + +\def\cb_trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else{% + \countdef\save_spacefactor=255% + \ifvmode + \let\do_in_vmode=\relax + \advance \cb_break_penalty by -2 + \else + \save_spacefactor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \cb_break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\cb_break_penalty% first call to \output + \null + \advance \cb_break_penalty by 2 + \penalty\cb_break_penalty% second call to \output + }% + \ifhmode \spacefactor=\save_spacefactor \fi + }% + \fi + }% cb_trigger_output +\endprog + + +\sect Using the output routine for passing +information has it's difficulties. One of the hard parts is +\beginchange +handling page marks. These are token lists which are set by the +|\mark| command. They record information that can later +be accessed by the output routine. The canonical example of such +a use of the |\mark| command is in creating +\endchange +dictionary-style entry headings. + +The output routine can access one of three +token lists through three control sequences: |\botmark| is the +last page mark given, |\topmark| is the |\botmark| of the previous +page, and |\firstmark| is the first page mark on the actual page or +|\topmark| if none was given. Here ``page'' is used in the \TeX{} +sense, i.e.\ as the material which has been collected between two +|\output| invocations. Of course, the page marks must not be +destroyed---and that means they must be reinserted after each +special use of the output routine. + +But we are lucky: A ``special use'' consists of two |\output| +invocations, so we can insert |\topmark| again as a page mark after +the first invocation where it will be the only page mark on that +\TeX{} page. The second invocation will automatically transform this +page mark into the ``last page mark on the previous page,'' i.e.\ in +|\topmark|---that's what we need! Furthermore |\firstmark| and +|\botmark| are saved in control sequences during the first invocation, +they will be inserted again, too. + +There's one situation where this approach doesn't work: in front of +the first page mark. Here, |\topmark|, |\firstmark|, and |\botmark| expand +to an empty token list. If we save them then and insert their old +values we have inserted empty page marks. If other page marks follow +on the same ``real'' page, |\firstmark| will be empty instead of +expanding to the token list of the first page mark. To prevent this +we must not save and restore page marks before the first |\mark| has +been added to the main vertical list. + +Well, that can be controlled with a switch---but this switch must be +set very carefully. If it is set immediately by the first |\mark| +this may be in horizontal mode and special output invocations can +occur above this page mark (i.e., there may be a |\beginchange| in the +same paragraph in front of the |\mark|). Therefore the setting of the +switch must be delayed until the vertical position of the |\mark| +(precisely: the position of the |\mark| in the current list) is +reached. In horizontal mode this can be done with a |\vadjust| and +the output routine! Voil\`a, this is another command group for the +output routine with only one command. + +\beginprog +\newif\if_cb_save_mark@ \_cb_save_mark@false + +\def\mark_penalty_group{-102} +\endprog + + +\sect We will redefine |\mark| so that the first page mark either sets +the switch to true (in vertical mode all possible special page breaks +are already handled) or forces the |\output| routine to do this at an +appropriate place. In the last case we can use |\cb_trigger_output| +again. Afterwards we restore the original meaning of |\mark| again to +reduce the processing overhead (and the dead cycles). + +This change of |\mark| has the consequence that the first |\mark| in a +document cannot be used anymore in horizontal mode inside a vertical +box that shall be split afterwards. But this is only sensible if this +mark shall be used as |\splitfirstmark| because it will almost never +migrate to the outer list---really a rare case! + +\beginprog +\let\cb_mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\_cb_save_mark@true \fi % split marks! + \else + \cb_break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \cb_trigger_output + \fi + \global\let\mark=\cb_mark + \cb_mark + } +\endprog + + +\sect +\begin{newsloppy} +If the output routine is triggered with the mark penalty value, +it will call {\tt \bs cb\_save\discretionary{\_}{}{}page\_marks}. +\end{newsloppy} + +\beginprog +\def\cb_save_page_marks{% % this may be executed twice + \unvbox\@cclv + \global\_cb_save_mark@true + } +\endprog + + +\sect To finish the treatment of page marks we can formulate the two +macros which are used at the first resp.\ second invocation of a +``special output,'' the principles have already been explained. + +\beginprog +\def\cb_backup_page_marks{% + \if_cb_save_mark@ + \mark{\topmark}% + \xdef\cb_save_firstmark{\firstmark}% + \xdef\cb_save_botmark{\botmark}% + \fi + } + +\def\cb_restore_page_marks{% + \if_cb_save_mark@ + \mark{\cb_save_firstmark}\mark{\cb_save_botmark}% + \fi + } +\endprog + + + + + +\chap Positioning the Change Bars. + +\begin{newsloppy} +Now we handle the positions of the bars. +The dimension |\cb_bot_change_pos| will hold +the position of the end of the change bar, i.e.\ the distance between +top of page the end of the changed area. The dimension +|\cb_top_change_pos| will hold the beginning of a changed +area; a value of |\maxdimen| indicates that no change is in effect. If +a changed area is completed, it is appended to the list |\cb_bar_list| as +an element {\tt \bs cb\_bar(\bs cb\_top\_change\_pos, +\bs cb\_bot\_change\_pos, \bs changebar\-width)}. This list contains all +changed areas within the current page so that bars can be written later +on. A single bar will be produced by |\cb_write_bar|. + +\noindent The definition of |\cb_bar| to |\relax| allows the concatenation +of new elements to |\cb_bar_list| with |\xdef|. + +Local dimension register |\halfwidth| is used to center the change bar. +\end{newsloppy} + +\beginprog +\newdimen\cb_bot_change_pos +\newdimen\cb_top_change_pos \cb_top_change_pos=\maxdimen + +\let\cb_bar_list=\empty + +\let\cb_bar=\relax +\def\cb_write_bar(#1,#2,#3){{% + \dimendef\halfwidth=255% + \setbox0=\hbox{\vrule width #3 height -#1 depth #2}% + \dp0=0pt \ht0=0pt \wd0=0pt% + \halfwidth=#3 \divide\dimen255 by 2% + \hskip -\halfwidth% + \box0% + \hskip \halfwidth% + }} +\endprog + + +\sect If the output routine was activated by a |\outputpenalty| value +within the range of our reserved penalties, the change handling will +occur, otherwise standard plain output can be done. There may be +a lot of interaction between the routines which set change bars and +the output routine. These interactions should not be recorded in +|\deadcycles| or else \TeX{} will soon grumble. One might consider +doing the same for the|\mark_penalty_group|. But since this +group is called once it shouldn't matter all that much. + +One might also consider adding a counter like |\deadcycles| just +to count the change bar interactions as is done for the calls to +|\output|, and have {\TeX} grumble if there are ``too many'' of +them. For now we don't do this---all of this code is correct +anyway! + +First we save away the old output routine in case the user had redefined +this beforehand. + +\beginprog +\newtoks\cb_oldoutput +\edef\cb_oldoutput{\the\output} + +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\cb_penalty_group\space + {\countdef\new_deadcycles=255% don't count as a dead cycle + \new_deadcycles=\deadcycles + \advance \new_deadcycles by -1 + \deadcycles=\new_deadcycles} + \cb_change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \cb_save_page_marks + \else \cb_oldoutput + \fi + \fi + } +\endprog + + +\sect As explained before, the change handling must differentiate +between the kind of the change command (beginning is indicated by +$|\cb_change_cmd|=0$, end by~1) and between the mode (horizontal indicated +by an odd |\cb_change_mode| value, vertical by an even). A change mode +higher than one indicates that we are doing the first page break that +has to backup the page as far as it exists already and results in an +empty current list of page elements. + +\beginprog +\newcount\cb_change_cmd +\newcount\cb_change_mode + +\def\cb_change_handling{% + \cb_change_cmd=-\outputpenalty % ==> absolute value + \advance \cb_change_cmd by \cb_penalty_group00 % subtraction + \cb_change_mode=\cb_change_cmd + \divide \cb_change_cmd by 10 % second-to-last digit + \advance \cb_change_mode by -\number\cb_change_cmd0 % last digit + \ifnum \cb_change_mode>1 \cb_backup_page + \else + \ifcase \cb_change_cmd \cb_begin_change + \or \cb_end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +\endprog + + +\sect Processing a mark during the second trigger of the output routine +means restoring the page and storing the positions. At the beginning, +the begin of the change is saved, at the end, we know the bar already +and put it into the bar list. Then the positioning values are +reinitialized. + +As within every output invocation, the box 255 must be unboxed. As we +are here in the second invocation of the output routine the |\box255| +consists only of the empty |\vbox| we have inserted in +|\cb_trigger_output|. We can therefore throw it away. + +\beginprog +\def\cb_begin_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \global\cb_top_change_pos=\cb_bot_change_pos + \global\cb_bot_change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\cb_end_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos,\the\cb_bot_change_pos, + \the\cb_changebarwidth)} + \global\cb_top_change_pos=\maxdimen + \global\cb_bot_change_pos=0pt + \fi + } +\endprog + + +\chap Handling the Page Contents. + +We handle the part of the page that was collected up to now by putting +it into a box. This fixes the position of the change mark so that +|\cb_bot_change_pos| can be set and stored in |\cb_top_change_pos| +later on or as the lower end of a bar in |\cb_bar_list|. + +In the first output invocation, we save the contents of the +page in |\cb_save_page|. Before that, we store the size of the +box (which equals |\pagegoal|!)\ in |\cb_page_goal|. If the unboxing +caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +we eject the page up to the change mark. Now we have to compute the +current position of our mark in |\cb_bot_change_pos|. It is fixed by the size +of the |\cb_save_page|, but if the change begins in horizontal mode we +must decrease it from the baseline position to the top of the last line. +Finally, we must save the values for the allowed insertions and change +them to the maximal value so that a rest that is split from an insertion +will be appended to the insertion box at the second invocation in every +case. + +The |\vsize| is initialized to |\maxdimen|. This allows to control +whether this first output invocation ocurred or if it was discarded. +For the same reason |\cb_bot_change_pos| is initialized to~0pt. + +\beginprog +\newbox\cb_save_page + +\newdimen\cb_page_goal +\newdimen\cb_save_vsize \cb_save_vsize=\maxdimen +\newdimen\cb_save_dimen_topins +\newdimen\cb_save_dimen_footins + +\def\cb_backup_page{% + \global\cb_page_goal=\ht\@cclv + \global\setbox\cb_save_page=\vbox{\unvbox\@cclv}% + \ifdim \ht\cb_save_page>\cb_page_goal + \cb_eject_page_so_far \fi + \cb_bot_change_pos=\ht\cb_save_page + \global\advance \cb_bot_change_pos by \dp\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode \higher_change_pos \fi + \fi + \global\cb_save_vsize=\vsize \global\vsize=\maxdimen + \global\cb_save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \cb_backup_page_marks + } + +\cb_bot_change_pos=0pt +\endprog + + +\sect To eject a page as far as it is we restore it from the +|\cb_save_page| back to box~255. In horizontal mode and at a begin mark +the last line contains the mark and must not be output. So we remove it +and the preceding glue from the stored rest, just leaving a single hbox +to be on top of the actual page (in |\cb_save_page|) now. Then normal +output can be done with box~255. + +\beginprog +\def\cb_eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox\@cclv=\vbox to \cb_page_goal{% + \unvbox\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode + \global\setbox\cb_save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \cb_oldoutput + } +\endprog + + +\sect +\begin{newsloppy} +In horizontal mode and at a begin mark, we need the position of +the mark ({\tt \bs cb\_bot\discretionary{\_}{}{}change\_pos}) on the upper boundary of +the last line in +|\cb_save_page|. If there is just one line left from a recent eject, the +height is given by |\topskip| decreased by the height of this hbox. If +the height of the box is larger than |\topskip| the skip will not be +inserted and the change position results to~0pt. Otherwise, +|\cb_save_page| is a vbox whose last hbox we delete temporarily using +box~0. Height and depth of the rest are the actual position on the page. +\end{newsloppy} + +The double of the page we have constructed this way will immediately be +fed back to the garbage collector because it could have become +reasonably large. + +\beginprog +\def\higher_change_pos{% + \ifhbox \cb_save_page % rest of page from \cb_eject_page_so_far + \cb_bot_change_pos=\topskip + \global\advance \cb_bot_change_pos by -\ht\cb_save_page + \ifdim \cb_bot_change_pos<0pt + \global\cb_bot_change_pos=0pt + \fi + \else + \setbox0=\vbox{% + \unvcopy\cb_save_page + \setbox0=\lastbox % delete last line + }% + \cb_bot_change_pos=\ht0 + \global\advance \cb_bot_change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +\endprog + + +\sect To restore a page during the second output invocation, we first +restore the saved values, but only if they were really changed (this can +be discovered by the value of |\cb_save_vsize|). Now the |\cb_save_page| is +appended to the current list as a box, which stops later usage of its +stretch- and shrinkability! Then the collected insertions can be +inserted again. The page marks have to be inserted, too. + +\beginprog +\def\cb_restore_page{% + \ifdim \cb_save_vsize=\maxdimen + \else \global\vsize=\cb_save_vsize + \global\dimen\footins=\cb_save_dimen_footins + \global\cb_save_vsize=\maxdimen + \cb_restore_page_marks + \fi + \box\cb_save_page % discards stretch- and shrinkability! + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +\endprog + + +\sect {\em Please note, that there is still a problem with this concept +of handling the output trigger:} + +\bigskip + +If the first output trigger is discarded because a page break has occurred +just in front, footnote parts may be juggled around. I.e., if a +footnote is split in three parts, the first part was just been shipped +out, the second part is inserted back into the recent contributions by +the output routine but {\em behind\/} the third part which is saved in +the ``special place'' (according to the \TeX{}book, p.~125). A solution to +this problem might be to insert a |\do_change| again within the second +output trigger and finishing the treatment afterwards. Afterwards a +full triggering process (two output invocations) is executed again and +all insertion parts will be accessible in the insertion box. + +By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +\LaTeX{} this can happen every time because at the first output invocation +the |\dimen|-values of the footnote insertion is not increased. I leave +the problem open to the reader\,\dots + + + + + +\chap Writing the Stuff. + +The positions of the bars which mark the changed areas are relative to +the top of the text, i.e.\ the height of the top insertion is not +included. Therefore it is best to write them just after the top +insertions before the page text---but to do this we have to change the +\beginchange +either the {\sc Plain} {\TeX} macro |\pagecontents| or the {\LaTeX} +macro |\@makecol|. +\endchange + +Below is the new definition, I have just rearranged it a little bit so +that it is more legible. The new lines have been marked with +`|%%%%|'. |\cb_insert_current_bar| inserts a last element in |\cb_bar_list| +if a changed area is not yet finished, afterwards all bars can be +written. + +\beginprog +\def\@makecol{% + \ifvoid\footins + \setbox\@outputbox + \vbox{ + %\typeout{write all bars -- no footins} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv% + } + \else + \setbox\@outputbox + \vbox{\boxmaxdepth \maxdepth + %\typeout{write all bars} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv\vskip\skip\footins\footnoterule\unvbox\footins% + } + \fi% + \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats + \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth + \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox + \vskip-\dimen128\@textbottom}% + \global\maxdepth\@maxdepth} +\endprog + +\sect If $|\cb_top_change_pos|=|\maxdimen|$ no change is active. Otherwise +the current change reaches from the begin mark (|\cb_top_change_pos|) to +the end of the page, i.e.\ we insert a virtual end mark. Because the +change continues on the next page we insert a virtual begin mark on the +top of the page, too. + +\beginprog +\def\cb_insert_current_bar{% + \ifdim \cb_top_change_pos=\maxdimen + \else% + \cb_bot_change_pos=\ht\@cclv + \advance\cb_bot_change_pos by \dp\@cclv + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos, + \the\cb_bot_change_pos, + \the\changebarwidth)}% + \global\cb_top_change_pos=0pt + \fi% + } +\endprog + + +\sect Now we can write all bars---if they exist anyway. It's rather +easy, we just have to define |\cb_bar| to |\cb_write_bar| and execute +|\cb_bar_list|. The resulting output must not use vertical place. We must +not forget to delete the list, or we will get the same bars on the next +page again. + +\beginprog +\newbox\cb_bars +\newdimen\cb_offset + +\def\cb_write_all_bars{% + \ifx \cb_bar_list\empty + \else % changes exist + \ifchbarRight + \cb_offset = \hsize + \advance \cb_offset by \BarDistance + \else + \cb_offset = \hoffset + \advance \cb_offset by -\BarDistance + \fi + \setbox\cb_bars=\hbox to \cb_offset{% + \hskip\cb_offset + \vbox to 0pt{\offinterlineskip + \let\cb_bar=\cb_write_bar \cb_bar_list + }% + \hss + }% + \ht\cb_bars=0pt \dp\cb_bars=0pt \box\cb_bars + \global\let\cb_bar_list=\empty + \fi + } +\endprog + + +\beginchange\chap Cleaning Up.\endchange + +We finish the macro file so that garbage (e.g.\ of exchanges +between systems) can come afterwards. + +\beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +\endprog + + + +\end{document} + diff --git a/macros/latex209/contrib/chbars/chbars.sty b/macros/latex209/contrib/chbars/chbars.sty new file mode 100644 index 0000000000..245f9e5459 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars.sty @@ -0,0 +1,1000 @@ +% This is CHBARS.STY as of Aug '92 +% -*-LaTeX-*- +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in LaTeX. +% MAKEPROG will ``weave'' this file into documentation that can be LaTeX'ed. +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 92-08-15 -rlb Use change bars in this document to mark major changes; +% so now you can see for yourself what they are. +% 92-07-28 -rlb Run through a spelling checker before distributing. +% 92-01-15 -rlb 1) Keep \maxdeadcycles the same; just +% don't count calls to output for change processing. +% 2) Allow setting the change bar width. +% 3) Some typos and rewording of some of the comments. +% 4) Allow setting change bar width. Interface copied +% from changebars.sty +% 5) Allow changebars to be on the left as well as +% the right. +% 6) localize some variables global definitions now +% start with cb_. +% 7) Chain onto existing \output routine rather than assume +% \plainoutput. +% And miscellaneous minor hacks. +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,chbars,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\PS{{\sc PostScript}} +%%% \def\DVI{{\tt DVI}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +%%% \begin{document} +%%% \tableofcontents + +%%% \title{Changebars without {\tt \bs{}special}'s} +%%% \author{\sc Joachim Schrod} + +%%% \newcommand{\changedate}{Aug 15, 1992} +%%% \date{Revised last on \changedate\footnote{by {\tt rocky@watson.ibm.com}}\\ +%%% Formatted on \today} +%%% \maketitle + + + +%%% \begin{abstract} +%%% It is common practice to use vertical bars in the margins of a +%%% document to mark pieces of text which have changed since the last +%%% version(s) of this document. Such vertical bars are usually +%%% called {\em changebars}. It has often been said that it is +%%% impossible to produce changebars with \TeX{} without the usage of +%%% |\special| commands (driver directives), which extend the +%%% primitives of \TeX{}. This paper presents a \TeX{} macro file +%%% which implements changebars without such a usage. The macro file +%%% is written for the usage with {\sc Plain}~\TeX{} but the implementation +%%% strategy can be used with \LaTeX{}, too with minor changes. + +%%% \end{abstract} + + + +%%% \chap Introduction. + +%%% Changebars are used to mark modified parts in existing documents. For +%%% the usage in \TeX{} documents, there exist only solutions that use +%%% driver/printer features by the way of inserting |\special| commands in +%%% the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +%%% that are no longer as freely interchangeable as the \DVI{} concept would +%%% allow---device dependency is problematic especially for this application +%%% that is useful for multi-authoring or standards development. + +%%% This macro package offers a pure \TeX{} solution. Nevertheless, it has +%%% its restrictions, too. The page break will no longer be optimal, +%%% because there is no strechability or shrinkability of a page +%%% on top of the last +%%% region of change marked. But this seems to be acceptable, +%%% especially as the change bar feature often will be used for proof +%%% reading and not in the final document. This restriction is the reason +%%% why no change marks can be used on title pages or on similar +%%% constructions. Changes in floating insertions (footnotes, figures) are +%%% not handled. Multi-column formats such as a two-column layout +%%% will not work. There is currently no support for nested changes. + +%%% The method for writing a change bar consists of three +%%% parts: First, the output routine is signalled when the beginning +%%% or end of a change bar setting command is encountered. +%%% Next, the position of the changed area is found out +%%% and fixed; the end-of-change command adds the last change bar +%%% position, length and width to a list of all such positions, +%%% lengths and widths of change bars that is accumulated for the current +%%% page. Finally, when +%%% the output routine is triggered (either asynchronously in trying +%%% to ship out the page or synchronously when discovering that the +%%% end of a change bar lies off the page), this list of change +%%% bars information is used create vertical rules which are added to the page. +%%% If the change bar is not complete, a ``virtual'' end change is +%%% inserted, and a ``virtual'' begin change is inserted at the +%%% beginning of the next page. + +%%% \beginchange +%%% The demonstrated solution was originally written in {\sc Plain} +%%% \TeX{}, because it was +%%% easier and could be presented better at the Euro\TeX89 conference in +%%% Karlsruhe. An adaptation to \LaTeX{} has been done too which +%%% requires minor modifications to the \LaTeX's output routine. +%%% \endchange + +%%% Some history. The routines were initially written by Joachim +%%% Schrod. Around Jan.\ 1992, R.\ Bernstein added some of the features +%%% coded in |changebars.sty| to combine the best features +%%% of the two (and added a couple of his own). For example, the +%%% ability to specify change bar widths, put the change bars either on the +%%% right or left margin, specifiy the distance from the margin to the +%%% change bar, and chain to on top of a pre-existing modified +%%% output routine. +%%% \beginchange +%%% Initially, both the {\TeX} and the {\LaTeX} +%%% versions were put into one file. However, due problems in +%%% dealing with conditional definition of code, in particular +%%% problems with an extra or omitted |\fi| in defining or not +%%% |\ifr@ggedbottom|, the code was split into two. +%%% \endchange +%%% +%%% The |changebars.sty| package +%%% was written by Michael Fine and revised by Johannes Braams +%%% and Neil Winton. One or two ideas from Thomas J.~Reid have been +%%% used. + +%%% \chap GNU General Public License. + +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~2, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% You should have received a copy of the \GNU{} General Public License +%%% along with this program; if not, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \chap User Interface. + +%%% \begin{newsloppy} +%%% A changed area is described by two marks, |\beginchange| and +%%% |\endchange|. The |\beginchange| can take an optional argument, +%%% the bar thickness, enclosed in brackets. That is, either of the +%%% something like |\beginchange[0.4pt]|, or |\beginchange| is valid. +%%% In the latter case where no thickness dimension is specified, the value +%%% of |\changebarwidth| is used. Therefore, by setting this you can +%%% change the bar thickness used when none is given. Changing the bar +%%% thickness might be useful in identifying different classes of changes. + +%%% Another pair of global values that can be set are the +%%% logical variables +%%% {\tt \bs chbar\-Right\-true} and {\tt \bs chbar\-Right\-false}. +%%% These specify whether +%%% changebars should be on the right or left. Say, if one wanted to +%%% have the changebars always appear on the outside margin, one could +%%% change these accordingly on each page. +%%% \end{newsloppy} + +%%% Finally |\BarDistance| is the amount of place between the text margin +%%% and the change bars. This value should normally be positive. For +%%% change bars on the right this value is added to |\hsize|, while +%%% for change bars on the left this value is {\em subtracted\/} from +%%% |\hoffset|. + +%%% \beginprog +\newdimen\changebarwidth \changebarwidth=1pt\relax +\newif\ifchbarRight \chbarRightfalse +\newdimen\BarDistance \BarDistance=2cc + +%%% \endprog + +%%% \chap Utility Routines and Programming Conventions. + +%%% Before we get into the nitty gritty details, we give some common +%%% macros. +%%% +%%% First, we declare some shorthands for category codes. By +%%% declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +%%% letters we can use them in our macros. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +%%% \beginchange +%%% By defining the at sign to be in the letter class, +%%% we can access {\sc Plain} \TeX's ``private''macros. By defining the +%%% underscore to be in the letter class, we make our own private macros more +%%% readable. But since have to +%%% restore these category codes at the end of this macro file, we store +%%% \endchange +%%% their former values in the control sequences |\atcode| and |\uscode|. +%%% This method is better than to use a group because not all macros have to +%%% be defined global this way. +%%% +%%% All {\em global\/} definitions of the package are prefixed by +%%% |cb_|. In this way, they can be easily determined. If other +%%% packages do likewise, it is less likely that definition +%%% names will clash between packages. (Unless the other package uses the +%%% |cb_| prefix too, in which case there is a good chance that many +%%% variable names will clash.) +%%% +%%% The {\TeX}book recommends the 255 registers be used for scratch +%%% space, so routines use this value when a spare register is +%%% needed. (See for example |\cb_write_bar|.) +%%% + +%%% \beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter + +%%% \endprog + +%%% \sect Now we are ready to code the top-level routine for indicating the +%%% beginning of a change. But first we display the banner and +%%% version number associated with this package. If this package has +%%% been loaded already we terminate. +%%% +%%% Although one can specify a bar +%%% thickness on the |\beginchange| macro, it is at the |\endchange| +%%% where this thickness is recorded and put on a current list of +%%% change bar entries for the current page. It seems more natural to +%%% specify the thickness at the beginning of the change rather than +%%% the end. Therefore at the +%%% |\beginchange| we merely save the value given or save the value of +%%% |\changebarwidth| if no thickness was given. +%%% |\cb_changebarwidth| is this saved value. Auxiliary routine +%%% |\cb_xstart| is used to parse off the optional enclosing +%%% brackets. (This weird name was taken from one used in |changebars.sty|.) + +%%% default value, that is the value when a width is not specified +%%% is |\changebarwidth|. + +%%% \beginprog + +\@ifundefined{cb_xstart}{}{\endinput} +\typeout{Style option `change bars' -- version 1.1a} + +\newdimen\cb_changebarwidth + +\def\beginchange{\@ifnextchar [ + {\cb_xstart} + {\beginchange_\changebarwidth}} +\def\cb_xstart[#1]{\beginchange_{#1}} + +%%% \endprog + +%%% \chap Triggering the Output Routine. + +%%% \beginchange +%%% When a change bar is started or completed, we signal the output +%%% routine in the ``usual'' way described below. Why bother the +%%% output routine? The output routine is supposed to be thought of +%%% as an asynchronous process which has access to the page via the +%%% contents of box register 255. In theory, if we did not perform +%%% actions in the output routine, it might get triggered inadvertantly, +%%% and the output routine might modify this box register on us in the +%%% midst of our work. The information that needs to be recorded +%%% is the position of the beginning and end of the lines containing a +%%% marked change region. + +%%% \begin{newsloppy} +%%% The macros |\beginchange| and |\endchange| signal the output +%%% routine. Rather than merely calling the output routine directly, +%%% these routines signal the output routine by setting a low page penalty, i.e., +%%% one which tells {\TeX} that this is a really good place to break +%%% the page. Of course, we will modify the output routine so that it +%%% doesn't really split the page when it has been called in this fashion. +%%% Again, the reason we signal the output routine in what seems at +%%% first a pretty odd way, is that this is the way it is supposed to +%%% be done. If a low penalty were not set, some +%%% other action (if we weren't careful) might cause a penalty to be +%%% set and thus call the output routine (recursively). + +%%% So that we can distinguish our calls from others, |\beginchange| +%%% and |\endchange| reserve a range of +%%% penalty values; he actual value is stored in |\cb_break_penalty|. +%%% This range of values is below +%%% $-10\,000$, the nominal value for indicating that a page should +%%% occur now. The penalty will be in the range $|\cb_penalty_group| +%%% \cdot 100 - 99 \ldots |\cb_penalty_group| \cdot 100$. +%%% The output routine then decides whether it has been called +%%% to start or end a change bar or neither. This is done with the values +%%% |\cb_penalty_begin| and |\cb_penalty_end| that are used as the +%%% second-to-last digit of the change penalty. +%%% \end{newsloppy} + +%%% The output routine also needs to determine whether +%%% the beginning of change bar starts in horizontal or vertical mode +%%% so it can figure out the exact placement for the beginning of the +%%% bar line. In horizontal mode, the change bar does +%%% not begin at the baseline of the actual text position, but on top of the +%%% actual line. This is marked in the last digit, an odd digit will be +%%% used in horizontal mode. + +%%% Note that the values mentioned above are used as digits here that can be +%%% concatenated. If they are not followed by an other digit they should be +%%% terminated by |\space| to stop {\TeX}'s look-ahead scanning for +%%% digits when reading a number. +%%% \endchange + +%%% \beginprog +\def\cb_penalty_group{-101} \def\cb_penalty_begin{0} +\def\cb_penalty_end{1} + +%%% \endprog + + +%%% \sect The calls to start or end a change bar, set an encoded page-break +%%% penalty which includes an +%%% indication of begin or end of a change bar. The variable +%%% |\cb_break_penalty| is used to create such as special value. +%%% The rest (|\cb_trigger_output|) is the same action +%%% for both. The region just before the end of the changed region can be +%%% in horizontal mode and preceded by +%%% glue that could cause a line break, thus including the following line to +%%% the change area as well. To avoid this unwanted behavior, the space is +%%% saved in |\save_lastskip|, discarded in front of the mark and restored +%%% afterwards. + +%%% \beginprog +\newcount\cb_break_penalty + +\def\beginchange_#1{% + \cb_changebarwidth=#1 + \cb_break_penalty=\cb_penalty_group\cb_penalty_begin0 + \cb_trigger_output + } +\def\endchange{{% + \skipdef\save_lastskip=255% + \ifhmode \save_lastskip=\lastskip \unskip \fi% + \cb_break_penalty=\cb_penalty_group\cb_penalty_end0% + \cb_trigger_output% + \ifhmode \hskip\save_lastskip \fi% + }}%\endchange +%%% \endprog + + +%%% \sect The next routine, |\cb_trigger_output|, +%%% triggers calls to the output routine by setting the page-break +%%% penalty, |\penalty|. {\TeX} may discard an |\output| invocation at +%%% the beginning of a page. So we trigger the output routine twice, first +%%% with a special penalty value that is 2~less than the correct value +%%% (including the code for horizontal or vertical mode). After the first +%%% page break, it is asserted that the current list is empty. The output +%%% routine has to save the former page contents if necessary. + +%%% Next we set the penalty to the correct value. The second page break does +%%% the real work, restores the page contents and handles the split +%%% insertions (footnotes, figures,~\dots). + +%%% In horizontal mode |\spacefactor| must not be destroyed, so it is +%%% saved and restored via local count register |\save_spacefactor|. + +%%% \beginprog + +\def\cb_trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else{% + \countdef\save_spacefactor=255% + \ifvmode + \let\do_in_vmode=\relax + \advance \cb_break_penalty by -2 + \else + \save_spacefactor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \cb_break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\cb_break_penalty% first call to \output + \null + \advance \cb_break_penalty by 2 + \penalty\cb_break_penalty% second call to \output + }% + \ifhmode \spacefactor=\save_spacefactor \fi + }% + \fi + }% cb_trigger_output +%%% \endprog + + +%%% \sect Using the output routine for passing +%%% information has it's difficulties. One of the hard parts is +%%% \beginchange +%%% handling page marks. These are token lists which are set by the +%%% |\mark| command. They record information that can later +%%% be accessed by the output routine. The canonical example of such +%%% a use of the |\mark| command is in creating +%%% \endchange +%%% dictionary-style entry headings. +%%% +%%% The output routine can access one of three +%%% token lists through three control sequences: |\botmark| is the +%%% last page mark given, |\topmark| is the |\botmark| of the previous +%%% page, and |\firstmark| is the first page mark on the actual page or +%%% |\topmark| if none was given. Here ``page'' is used in the \TeX{} +%%% sense, i.e.\ as the material which has been collected between two +%%% |\output| invocations. Of course, the page marks must not be +%%% destroyed---and that means they must be reinserted after each +%%% special use of the output routine. + +%%% But we are lucky: A ``special use'' consists of two |\output| +%%% invocations, so we can insert |\topmark| again as a page mark after +%%% the first invocation where it will be the only page mark on that +%%% \TeX{} page. The second invocation will automatically transform this +%%% page mark into the ``last page mark on the previous page,'' i.e.\ in +%%% |\topmark|---that's what we need! Furthermore |\firstmark| and +%%% |\botmark| are saved in control sequences during the first invocation, +%%% they will be inserted again, too. + +%%% There's one situation where this approach doesn't work: in front of +%%% the first page mark. Here, |\topmark|, |\firstmark|, and |\botmark| expand +%%% to an empty token list. If we save them then and insert their old +%%% values we have inserted empty page marks. If other page marks follow +%%% on the same ``real'' page, |\firstmark| will be empty instead of +%%% expanding to the token list of the first page mark. To prevent this +%%% we must not save and restore page marks before the first |\mark| has +%%% been added to the main vertical list. + +%%% Well, that can be controlled with a switch---but this switch must be +%%% set very carefully. If it is set immediately by the first |\mark| +%%% this may be in horizontal mode and special output invocations can +%%% occur above this page mark (i.e., there may be a |\beginchange| in the +%%% same paragraph in front of the |\mark|). Therefore the setting of the +%%% switch must be delayed until the vertical position of the |\mark| +%%% (precisely: the position of the |\mark| in the current list) is +%%% reached. In horizontal mode this can be done with a |\vadjust| and +%%% the output routine! Voil\`a, this is another command group for the +%%% output routine with only one command. + +%%% \beginprog +\newif\if_cb_save_mark@ \_cb_save_mark@false + +\def\mark_penalty_group{-102} +%%% \endprog + + +%%% \sect We will redefine |\mark| so that the first page mark either sets +%%% the switch to true (in vertical mode all possible special page breaks +%%% are already handled) or forces the |\output| routine to do this at an +%%% appropriate place. In the last case we can use |\cb_trigger_output| +%%% again. Afterwards we restore the original meaning of |\mark| again to +%%% reduce the processing overhead (and the dead cycles). + +%%% This change of |\mark| has the consequence that the first |\mark| in a +%%% document cannot be used anymore in horizontal mode inside a vertical +%%% box that shall be split afterwards. But this is only sensible if this +%%% mark shall be used as |\splitfirstmark| because it will almost never +%%% migrate to the outer list---really a rare case! + +%%% \beginprog +\let\cb_mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\_cb_save_mark@true \fi % split marks! + \else + \cb_break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \cb_trigger_output + \fi + \global\let\mark=\cb_mark + \cb_mark + } +%%% \endprog + + +%%% \sect +%%% \begin{newsloppy} +%%% If the output routine is triggered with the mark penalty value, +%%% it will call {\tt \bs cb\_save\discretionary{\_}{}{}page\_marks}. +%%% \end{newsloppy} + +%%% \beginprog +\def\cb_save_page_marks{% % this may be executed twice + \unvbox\@cclv + \global\_cb_save_mark@true + } +%%% \endprog + + +%%% \sect To finish the treatment of page marks we can formulate the two +%%% macros which are used at the first resp.\ second invocation of a +%%% ``special output,'' the principles have already been explained. + +%%% \beginprog +\def\cb_backup_page_marks{% + \if_cb_save_mark@ + \mark{\topmark}% + \xdef\cb_save_firstmark{\firstmark}% + \xdef\cb_save_botmark{\botmark}% + \fi + } + +\def\cb_restore_page_marks{% + \if_cb_save_mark@ + \mark{\cb_save_firstmark}\mark{\cb_save_botmark}% + \fi + } +%%% \endprog + + + + + +%%% \chap Positioning the Change Bars. + +%%% \begin{newsloppy} +%%% Now we handle the positions of the bars. +%%% The dimension |\cb_bot_change_pos| will hold +%%% the position of the end of the change bar, i.e.\ the distance between +%%% top of page the end of the changed area. The dimension +%%% |\cb_top_change_pos| will hold the beginning of a changed +%%% area; a value of |\maxdimen| indicates that no change is in effect. If +%%% a changed area is completed, it is appended to the list |\cb_bar_list| as +%%% an element {\tt \bs cb\_bar(\bs cb\_top\_change\_pos, +%%% \bs cb\_bot\_change\_pos, \bs changebar\-width)}. This list contains all +%%% changed areas within the current page so that bars can be written later +%%% on. A single bar will be produced by |\cb_write_bar|. + +%%% \noindent The definition of |\cb_bar| to |\relax| allows the concatenation +%%% of new elements to |\cb_bar_list| with |\xdef|. + +%%% Local dimension register |\halfwidth| is used to center the change bar. +%%% \end{newsloppy} + +%%% \beginprog +\newdimen\cb_bot_change_pos +\newdimen\cb_top_change_pos \cb_top_change_pos=\maxdimen + +\let\cb_bar_list=\empty + +\let\cb_bar=\relax +\def\cb_write_bar(#1,#2,#3){{% + \dimendef\halfwidth=255% + \setbox0=\hbox{\vrule width #3 height -#1 depth #2}% + \dp0=0pt \ht0=0pt \wd0=0pt% + \halfwidth=#3 \divide\dimen255 by 2% + \hskip -\halfwidth% + \box0% + \hskip \halfwidth% + }} +%%% \endprog + + +%%% \sect If the output routine was activated by a |\outputpenalty| value +%%% within the range of our reserved penalties, the change handling will +%%% occur, otherwise standard plain output can be done. There may be +%%% a lot of interaction between the routines which set change bars and +%%% the output routine. These interactions should not be recorded in +%%% |\deadcycles| or else \TeX{} will soon grumble. One might consider +%%% doing the same for the|\mark_penalty_group|. But since this +%%% group is called once it shouldn't matter all that much. + +%%% One might also consider adding a counter like |\deadcycles| just +%%% to count the change bar interactions as is done for the calls to +%%% |\output|, and have {\TeX} grumble if there are ``too many'' of +%%% them. For now we don't do this---all of this code is correct +%%% anyway! + +%%% First we save away the old output routine in case the user had redefined +%%% this beforehand. + +%%% \beginprog +\newtoks\cb_oldoutput +\edef\cb_oldoutput{\the\output} + +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\cb_penalty_group\space + {\countdef\new_deadcycles=255% don't count as a dead cycle + \new_deadcycles=\deadcycles + \advance \new_deadcycles by -1 + \deadcycles=\new_deadcycles} + \cb_change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \cb_save_page_marks + \else \cb_oldoutput + \fi + \fi + } +%%% \endprog + + +%%% \sect As explained before, the change handling must differentiate +%%% between the kind of the change command (beginning is indicated by +%%% $|\cb_change_cmd|=0$, end by~1) and between the mode (horizontal indicated +%%% by an odd |\cb_change_mode| value, vertical by an even). A change mode +%%% higher than one indicates that we are doing the first page break that +%%% has to backup the page as far as it exists already and results in an +%%% empty current list of page elements. + +%%% \beginprog +\newcount\cb_change_cmd +\newcount\cb_change_mode + +\def\cb_change_handling{% + \cb_change_cmd=-\outputpenalty % ==> absolute value + \advance \cb_change_cmd by \cb_penalty_group00 % subtraction + \cb_change_mode=\cb_change_cmd + \divide \cb_change_cmd by 10 % second-to-last digit + \advance \cb_change_mode by -\number\cb_change_cmd0 % last digit + \ifnum \cb_change_mode>1 \cb_backup_page + \else + \ifcase \cb_change_cmd \cb_begin_change + \or \cb_end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +%%% \endprog + + +%%% \sect Processing a mark during the second trigger of the output routine +%%% means restoring the page and storing the positions. At the beginning, +%%% the begin of the change is saved, at the end, we know the bar already +%%% and put it into the bar list. Then the positioning values are +%%% reinitialized. + +%%% As within every output invocation, the box 255 must be unboxed. As we +%%% are here in the second invocation of the output routine the |\box255| +%%% consists only of the empty |\vbox| we have inserted in +%%% |\cb_trigger_output|. We can therefore throw it away. + +%%% \beginprog +\def\cb_begin_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \global\cb_top_change_pos=\cb_bot_change_pos + \global\cb_bot_change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\cb_end_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos,\the\cb_bot_change_pos, + \the\cb_changebarwidth)} + \global\cb_top_change_pos=\maxdimen + \global\cb_bot_change_pos=0pt + \fi + } +%%% \endprog + + +%%% \chap Handling the Page Contents. + +%%% We handle the part of the page that was collected up to now by putting +%%% it into a box. This fixes the position of the change mark so that +%%% |\cb_bot_change_pos| can be set and stored in |\cb_top_change_pos| +%%% later on or as the lower end of a bar in |\cb_bar_list|. + +%%% In the first output invocation, we save the contents of the +%%% page in |\cb_save_page|. Before that, we store the size of the +%%% box (which equals |\pagegoal|!)\ in |\cb_page_goal|. If the unboxing +%%% caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +%%% we eject the page up to the change mark. Now we have to compute the +%%% current position of our mark in |\cb_bot_change_pos|. It is fixed by the size +%%% of the |\cb_save_page|, but if the change begins in horizontal mode we +%%% must decrease it from the baseline position to the top of the last line. +%%% Finally, we must save the values for the allowed insertions and change +%%% them to the maximal value so that a rest that is split from an insertion +%%% will be appended to the insertion box at the second invocation in every +%%% case. + +%%% The |\vsize| is initialized to |\maxdimen|. This allows to control +%%% whether this first output invocation ocurred or if it was discarded. +%%% For the same reason |\cb_bot_change_pos| is initialized to~0pt. + +%%% \beginprog +\newbox\cb_save_page + +\newdimen\cb_page_goal +\newdimen\cb_save_vsize \cb_save_vsize=\maxdimen +\newdimen\cb_save_dimen_topins +\newdimen\cb_save_dimen_footins + +\def\cb_backup_page{% + \global\cb_page_goal=\ht\@cclv + \global\setbox\cb_save_page=\vbox{\unvbox\@cclv}% + \ifdim \ht\cb_save_page>\cb_page_goal + \cb_eject_page_so_far \fi + \cb_bot_change_pos=\ht\cb_save_page + \global\advance \cb_bot_change_pos by \dp\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode \higher_change_pos \fi + \fi + \global\cb_save_vsize=\vsize \global\vsize=\maxdimen + \global\cb_save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \cb_backup_page_marks + } + +\cb_bot_change_pos=0pt +%%% \endprog + + +%%% \sect To eject a page as far as it is we restore it from the +%%% |\cb_save_page| back to box~255. In horizontal mode and at a begin mark +%%% the last line contains the mark and must not be output. So we remove it +%%% and the preceding glue from the stored rest, just leaving a single hbox +%%% to be on top of the actual page (in |\cb_save_page|) now. Then normal +%%% output can be done with box~255. + +%%% \beginprog +\def\cb_eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox\@cclv=\vbox to \cb_page_goal{% + \unvbox\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode + \global\setbox\cb_save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \cb_oldoutput + } +%%% \endprog + + +%%% \sect +%%% \begin{newsloppy} +%%% In horizontal mode and at a begin mark, we need the position of +%%% the mark ({\tt \bs cb\_bot\discretionary{\_}{}{}change\_pos}) on the upper boundary of +%%% the last line in +%%% |\cb_save_page|. If there is just one line left from a recent eject, the +%%% height is given by |\topskip| decreased by the height of this hbox. If +%%% the height of the box is larger than |\topskip| the skip will not be +%%% inserted and the change position results to~0pt. Otherwise, +%%% |\cb_save_page| is a vbox whose last hbox we delete temporarily using +%%% box~0. Height and depth of the rest are the actual position on the page. +%%% \end{newsloppy} + +%%% The double of the page we have constructed this way will immediately be +%%% fed back to the garbage collector because it could have become +%%% reasonably large. + +%%% \beginprog +\def\higher_change_pos{% + \ifhbox \cb_save_page % rest of page from \cb_eject_page_so_far + \cb_bot_change_pos=\topskip + \global\advance \cb_bot_change_pos by -\ht\cb_save_page + \ifdim \cb_bot_change_pos<0pt + \global\cb_bot_change_pos=0pt + \fi + \else + \setbox0=\vbox{% + \unvcopy\cb_save_page + \setbox0=\lastbox % delete last line + }% + \cb_bot_change_pos=\ht0 + \global\advance \cb_bot_change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +%%% \endprog + + +%%% \sect To restore a page during the second output invocation, we first +%%% restore the saved values, but only if they were really changed (this can +%%% be discovered by the value of |\cb_save_vsize|). Now the |\cb_save_page| is +%%% appended to the current list as a box, which stops later usage of its +%%% stretch- and shrinkability! Then the collected insertions can be +%%% inserted again. The page marks have to be inserted, too. + +%%% \beginprog +\def\cb_restore_page{% + \ifdim \cb_save_vsize=\maxdimen + \else \global\vsize=\cb_save_vsize + \global\dimen\footins=\cb_save_dimen_footins + \global\cb_save_vsize=\maxdimen + \cb_restore_page_marks + \fi + \box\cb_save_page % discards stretch- and shrinkability! + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +%%% \endprog + + +%%% \sect {\em Please note, that there is still a problem with this concept +%%% of handling the output trigger:} + +%%% \bigskip + +%%% If the first output trigger is discarded because a page break has occurred +%%% just in front, footnote parts may be juggled around. I.e., if a +%%% footnote is split in three parts, the first part was just been shipped +%%% out, the second part is inserted back into the recent contributions by +%%% the output routine but {\em behind\/} the third part which is saved in +%%% the ``special place'' (according to the \TeX{}book, p.~125). A solution to +%%% this problem might be to insert a |\do_change| again within the second +%%% output trigger and finishing the treatment afterwards. Afterwards a +%%% full triggering process (two output invocations) is executed again and +%%% all insertion parts will be accessible in the insertion box. + +%%% By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +%%% \LaTeX{} this can happen every time because at the first output invocation +%%% the |\dimen|-values of the footnote insertion is not increased. I leave +%%% the problem open to the reader\,\dots + + + + + +%%% \chap Writing the Stuff. + +%%% The positions of the bars which mark the changed areas are relative to +%%% the top of the text, i.e.\ the height of the top insertion is not +%%% included. Therefore it is best to write them just after the top +%%% insertions before the page text---but to do this we have to change the +%%% \beginchange +%%% either the {\sc Plain} {\TeX} macro |\pagecontents| or the {\LaTeX} +%%% macro |\@makecol|. +%%% \endchange + +%%% Below is the new definition, I have just rearranged it a little bit so +%%% that it is more legible. The new lines have been marked with +%%% `|%%%%|'. |\cb_insert_current_bar| inserts a last element in |\cb_bar_list| +%%% if a changed area is not yet finished, afterwards all bars can be +%%% written. + +%%% \beginprog +\def\@makecol{% + \ifvoid\footins + \setbox\@outputbox + \vbox{ + %\typeout{write all bars -- no footins} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv% + } + \else + \setbox\@outputbox + \vbox{\boxmaxdepth \maxdepth + %\typeout{write all bars} + \cb_insert_current_bar \cb_write_all_bars %%%% + \unvbox\@cclv\vskip\skip\footins\footnoterule\unvbox\footins% + } + \fi% + \xdef\@freelist{\@freelist\@midlist}\gdef\@midlist{}\@combinefloats + \setbox\@outputbox\vbox to\@colht{\boxmaxdepth\maxdepth + \@texttop\dimen128=\dp\@outputbox\unvbox\@outputbox + \vskip-\dimen128\@textbottom}% + \global\maxdepth\@maxdepth} +%%% \endprog + +%%% \sect If $|\cb_top_change_pos|=|\maxdimen|$ no change is active. Otherwise +%%% the current change reaches from the begin mark (|\cb_top_change_pos|) to +%%% the end of the page, i.e.\ we insert a virtual end mark. Because the +%%% change continues on the next page we insert a virtual begin mark on the +%%% top of the page, too. + +%%% \beginprog +\def\cb_insert_current_bar{% + \ifdim \cb_top_change_pos=\maxdimen + \else% + \cb_bot_change_pos=\ht\@cclv + \advance\cb_bot_change_pos by \dp\@cclv + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos, + \the\cb_bot_change_pos, + \the\changebarwidth)}% + \global\cb_top_change_pos=0pt + \fi% + } +%%% \endprog + + +%%% \sect Now we can write all bars---if they exist anyway. It's rather +%%% easy, we just have to define |\cb_bar| to |\cb_write_bar| and execute +%%% |\cb_bar_list|. The resulting output must not use vertical place. We must +%%% not forget to delete the list, or we will get the same bars on the next +%%% page again. + +%%% \beginprog +\newbox\cb_bars +\newdimen\cb_offset + +\def\cb_write_all_bars{% + \ifx \cb_bar_list\empty + \else % changes exist + \ifchbarRight + \cb_offset = \hsize + \advance \cb_offset by \BarDistance + \else + \cb_offset = \hoffset + \advance \cb_offset by -\BarDistance + \fi + \setbox\cb_bars=\hbox to \cb_offset{% + \hskip\cb_offset + \vbox to 0pt{\offinterlineskip + \let\cb_bar=\cb_write_bar \cb_bar_list + }% + \hss + }% + \ht\cb_bars=0pt \dp\cb_bars=0pt \box\cb_bars + \global\let\cb_bar_list=\empty + \fi + } +%%% \endprog + + +%%% \beginchange\chap Cleaning Up.\endchange + +%%% We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + +%%% \end{document} + diff --git a/macros/latex209/contrib/chbars/chbars.tex b/macros/latex209/contrib/chbars/chbars.tex new file mode 100644 index 0000000000..07b6d7d056 --- /dev/null +++ b/macros/latex209/contrib/chbars/chbars.tex @@ -0,0 +1,1067 @@ +% This is CHBARS.TEX as of Aug '92 +% -*-TeX-*- +%--------------------------------------------------------- +% (c) 1989 by J.Schrod. copy conditions see below. + +% +% Macro package for creating changebars in LaTeX. +% MAKEPROG will ``weave'' this file into documentation that can be LaTeX'ed. +% +% documented in LaTeX (for Anne and Chris) + +% +% VERSION HISTORY (MSCF -- most significant change first) +% +% DATE PERSON REMARK +% 92-08-15 -rlb Use change bars in this document to mark major changes; +% so now you can see for yourself what they are. +% 92-07-28 -rlb Run through a spelling checker before distributing. +% 92-01-15 -rlb 1) Keep \maxdeadcycles the same; just +% don't count calls to output for change processing. +% 2) Allow setting the change bar width. +% 3) Some typos and rewording of some of the comments. +% 4) Allow setting change bar width. Interface copied +% from changebars.sty +% 5) Allow changebars to be on the left as well as +% the right. +% 6) localize some variables global definitions now +% start with cb_. +% 7) Chain onto existing \output routine rather than assume +% \plainoutput. +% And miscellaneous minor hacks. +% 89-10-09 -js converted to LaTeX (progltx) +% 89-09-25 -js repaired \mark processing in horizontal mode +% 89-08 -js first version (for EuroTeX89 in Karlsruhe) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% should be progtex... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx,chbars,a4-9]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\PS{{\sc PostScript}} +%%% \def\DVI{{\tt DVI}} +%%% \def\GNU{{\mc GNU}} + +%%% \chardef\bs=`\\ + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + +%%% \begin{document} +%%% \tableofcontents + +%%% \title{Changebars without {\tt \bs{}special}'s} +%%% \author{\sc Joachim Schrod} + +%%% \newcommand{\changedate}{Aug 15, 1992} +%%% \date{Revised last on \changedate\footnote{by {\tt rocky@watson.ibm.com}}\\ +%%% Formatted on \today} +%%% \maketitle + + + +%%% \begin{abstract} +%%% It is common practice to use vertical bars in the margins of a +%%% document to mark pieces of text which have changed since the last +%%% version(s) of this document. Such vertical bars are usually +%%% called {\em changebars}. It has often been said that it is +%%% impossible to produce changebars with \TeX{} without the usage of +%%% |\special| commands (driver directives), which extend the +%%% primitives of \TeX{}. This paper presents a \TeX{} macro file +%%% which implements changebars without such a usage. The macro file +%%% is written for the usage with {\sc Plain}~\TeX{} but the implementation +%%% strategy can be used with \LaTeX{}, too with minor changes. + +%%% \end{abstract} + + + +%%% \chap Introduction. + +%%% Changebars are used to mark modified parts in existing documents. For +%%% the usage in \TeX{} documents, there exist only solutions that use +%%% driver/printer features by the way of inserting |\special| commands in +%%% the \TeX{} source, e.g.\ for \PS{} drivers. This results in documents +%%% that are no longer as freely interchangeable as the \DVI{} concept would +%%% allow---device dependency is problematic especially for this application +%%% that is useful for multi-authoring or standards development. + +%%% This macro package offers a pure \TeX{} solution. Nevertheless, it has +%%% its restrictions, too. The page break will no longer be optimal, +%%% because there is no strechability or shrinkability of a page +%%% on top of the last +%%% region of change marked. But this seems to be acceptable, +%%% especially as the change bar feature often will be used for proof +%%% reading and not in the final document. This restriction is the reason +%%% why no change marks can be used on title pages or on similar +%%% constructions. Changes in floating insertions (footnotes, figures) are +%%% not handled. Multi-column formats such as a two-column layout +%%% will not work. There is currently no support for nested changes. + +%%% The method for writing a change bar consists of three +%%% parts: First, the output routine is signalled when the beginning +%%% or end of a change bar setting command is encountered. +%%% Next, the position of the changed area is found out +%%% and fixed; the end-of-change command adds the last change bar +%%% position, length and width to a list of all such positions, +%%% lengths and widths of change bars that is accumulated for the current +%%% page. Finally, when +%%% the output routine is triggered (either asynchronously in trying +%%% to ship out the page or synchronously when discovering that the +%%% end of a change bar lies off the page), this list of change +%%% bars information is used create vertical rules which are added to the page. +%%% If the change bar is not complete, a ``virtual'' end change is +%%% inserted, and a ``virtual'' begin change is inserted at the +%%% beginning of the next page. + +%%% \beginchange +%%% The demonstrated solution was originally written in {\sc Plain} +%%% \TeX{}, because it was +%%% easier and could be presented better at the Euro\TeX89 conference in +%%% Karlsruhe. An adaptation to \LaTeX{} has been done too which +%%% requires minor modifications to the \LaTeX's output routine. +%%% \endchange + +%%% Some history. The routines were initially written by Joachim +%%% Schrod. Around Jan.\ 1992, R.\ Bernstein added some of the features +%%% coded in |changebars.sty| to combine the best features +%%% of the two (and added a couple of his own). For example, the +%%% ability to specify change bar widths, put the change bars either on the +%%% right or left margin, specifiy the distance from the margin to the +%%% change bar, and chain to on top of a pre-existing modified +%%% output routine. +%%% \beginchange +%%% Initially, both the {\TeX} and the {\LaTeX} +%%% versions were put into one file. However, due problems in +%%% dealing with conditional definition of code, in particular +%%% problems with an extra or omitted |\fi| in defining or not +%%% |\ifr@ggedbottom|, the code was split into two. +%%% \endchange +%%% +%%% The |changebars.sty| package +%%% was written by Michael Fine and revised by Johannes Braams +%%% and Neil Winton. One or two ideas from Thomas J.~Reid have been +%%% used. + +%%% \chap GNU General Public License. + +%%% This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~2, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% You should have received a copy of the \GNU{} General Public License +%%% along with this program; if not, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \chap User Interface. + +%%% \begin{newsloppy} +%%% A changed area is described by two marks, |\beginchange| and +%%% |\endchange|. The |\beginchange| can take an optional argument, +%%% the bar thickness, enclosed in brackets. That is, either of the +%%% something like |\beginchange[0.4pt]|, or |\beginchange| is valid. +%%% In the latter case where no thickness dimension is specified, the value +%%% of |\changebarwidth| is used. Therefore, by setting this you can +%%% change the bar thickness used when none is given. Changing the bar +%%% thickness might be useful in identifying different classes of changes. + +%%% Another pair of global values that can be set are the +%%% logical variables +%%% {\tt \bs chbar\-Right\-true} and {\tt \bs chbar\-Right\-false}. +%%% These specify whether +%%% changebars should be on the right or left. Say, if one wanted to +%%% have the changebars always appear on the outside margin, one could +%%% change these accordingly on each page. +%%% \end{newsloppy} + +%%% Finally |\BarDistance| is the amount of place between the text margin +%%% and the change bars. This value should normally be positive. For +%%% change bars on the right this value is added to |\hsize|, while +%%% for change bars on the left this value is {\em subtracted\/} from +%%% |\hoffset|. + +%%% \beginprog +\newdimen\changebarwidth \changebarwidth=1pt\relax +\newif\ifchbarRight \chbarRightfalse +\newdimen\BarDistance \BarDistance=2cc + +%%% \endprog + +%%% \chap Utility Routines and Programming Conventions. + +%%% Before we get into the nitty gritty details, we give some common +%%% macros. +%%% +%%% First, we declare some shorthands for category codes. By +%%% declaring the at sign~(`|@|') as well as the underscore~`(|_|)' as +%%% letters we can use them in our macros. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than |\p@@@s|.) +%%% \beginchange +%%% By defining the at sign to be in the letter class, +%%% we can access {\sc Plain} \TeX's ``private''macros. By defining the +%%% underscore to be in the letter class, we make our own private macros more +%%% readable. But since have to +%%% restore these category codes at the end of this macro file, we store +%%% \endchange +%%% their former values in the control sequences |\atcode| and |\uscode|. +%%% This method is better than to use a group because not all macros have to +%%% be defined global this way. +%%% +%%% All {\em global\/} definitions of the package are prefixed by +%%% |cb_|. In this way, they can be easily determined. If other +%%% packages do likewise, it is less likely that definition +%%% names will clash between packages. (Unless the other package uses the +%%% |cb_| prefix too, in which case there is a good chance that many +%%% variable names will clash.) +%%% +%%% The {\TeX}book recommends the 255 registers be used for scratch +%%% space, so routines use this value when a spare register is +%%% needed. (See for example |\cb_write_bar|.) +%%% + +%%% \beginprog +\chardef\letter=11 + +\chardef\atcode=\catcode`\@ +\chardef\uscode=\catcode`\_ + +\catcode`\@=\letter +\catcode`\_=\letter + +%%% \endprog + +%%% \chap Utility Routines for \TeX vs.\ \LaTeX + +%%% If this program was not run from {\LaTeX}, \@ifundefined +%%% may be, well, undefined. So, we define it. What do you know---the +%%% the code for the macro almost contains a copy if itself? +%%% Also, if this is run from {\sc Plain} {\TeX}, there are a few other macros +%%% we need to copy in. These we borrow (sort of) from {\LaTeX}, +%%% if they were undefined. In particular, they are: +%%% +%%% |\@ifundefined{NAME}{YES}{NO}|: if |\NAME| is undefined then it +%%% executes |YES|, otherwise it executes NO. More precisely, +%%% true if |\NAME| either undefined or = |\relax|. +%%% +%%% |\@ifnextchar X{YES}{NO}|: Expands to |YES| if next character is +%%% an 'X', and to |NO| otherwise. (Uses temps a-c). {\it Note: +%%% gobbles any space following it.} +%%% +%%% \beginprog +%%% +\expandafter\ifx\csname @ifundefined\endcsname\relax% + \long\def\@ifundefined#1#2#3{\expandafter\ifx\csname + #1\endcsname\relax#2\else#3\fi}% + \fi + +\def\typeout#1{{\immediate\write16{#1}}} + +% \@ifnextchar X{YES}{NO} +% BEGIN +% \@tempe := X % uses \let +% \@tempa := YES +% \@tempb := NO +% \futurelet\@tempc +% \@ifnch +% END +% +% \@ifnch == +% BEGIN +% if \@tempc = blank space +% then \@tempd := def(\@xifnch) +% else if \@tempc = \@tempe +% then \@tempd := def(\@tempa) +% else \@tempd := def(\@tempb) +% fi +% fi +% \@tempd +% END +% +% \@xifnch == +% BEGIN +% gobble blanks +% \futurelet\@tempc +% \@ifnch +% END +% +\def\@ifnextchar#1#2#3{\let\@tempe #1\def\@tempa{#2}\def\@tempb{#3}\futurelet + \@tempc\@ifnch}% +\def\@ifnch{\ifx \@tempc \@sptoken \let\@tempd\@xifnch% + \else \ifx \@tempc \@tempe\let\@tempd\@tempa\else\let\@tempd\@tempb\fi + \fi \@tempd} + +% NOTE: the following hacking must precede the definition of \: +% as math medium space. + +\def\:{\let\@sptoken= } \: % this makes \@sptoken a space token + +\def\:{\@xifnch} \expandafter\def\: {\futurelet\@tempc\@ifnch} + +%%% \endprog + +%%% \sect Now we are ready to code the top-level routine for indicating the +%%% beginning of a change. But first we display the banner and +%%% version number associated with this package. If this package has +%%% been loaded already we terminate. +%%% +%%% Although one can specify a bar +%%% thickness on the |\beginchange| macro, it is at the |\endchange| +%%% where this thickness is recorded and put on a current list of +%%% change bar entries for the current page. It seems more natural to +%%% specify the thickness at the beginning of the change rather than +%%% the end. Therefore at the +%%% |\beginchange| we merely save the value given or save the value of +%%% |\changebarwidth| if no thickness was given. +%%% |\cb_changebarwidth| is this saved value. Auxiliary routine +%%% |\cb_xstart| is used to parse off the optional enclosing +%%% brackets. (This weird name was taken from one used in |changebars.sty|.) + +%%% default value, that is the value when a width is not specified +%%% is |\changebarwidth|. + +%%% \beginprog + +\@ifundefined{cb_xstart}{}{\endinput} +\typeout{Style option `change bars' -- version 1.1a} + +\newdimen\cb_changebarwidth + +\def\beginchange{\@ifnextchar [ + {\cb_xstart} + {\beginchange_\changebarwidth}} +\def\cb_xstart[#1]{\beginchange_{#1}} + +%%% \endprog + +%%% \chap Triggering the Output Routine. + +%%% \beginchange +%%% When a change bar is started or completed, we signal the output +%%% routine in the ``usual'' way described below. Why bother the +%%% output routine? The output routine is supposed to be thought of +%%% as an asynchronous process which has access to the page via the +%%% contents of box register 255. In theory, if we did not perform +%%% actions in the output routine, it might get triggered inadvertantly, +%%% and the output routine might modify this box register on us in the +%%% midst of our work. The information that needs to be recorded +%%% is the position of the beginning and end of the lines containing a +%%% marked change region. + +%%% \begin{newsloppy} +%%% The macros |\beginchange| and |\endchange| signal the output +%%% routine. Rather than merely calling the output routine directly, +%%% these routines signal the output routine by setting a low page penalty, i.e., +%%% one which tells {\TeX} that this is a really good place to break +%%% the page. Of course, we will modify the output routine so that it +%%% doesn't really split the page when it has been called in this fashion. +%%% Again, the reason we signal the output routine in what seems at +%%% first a pretty odd way, is that this is the way it is supposed to +%%% be done. If a low penalty were not set, some +%%% other action (if we weren't careful) might cause a penalty to be +%%% set and thus call the output routine (recursively). + +%%% So that we can distinguish our calls from others, |\beginchange| +%%% and |\endchange| reserve a range of +%%% penalty values; he actual value is stored in |\cb_break_penalty|. +%%% This range of values is below +%%% $-10\,000$, the nominal value for indicating that a page should +%%% occur now. The penalty will be in the range $|\cb_penalty_group| +%%% \cdot 100 - 99 \ldots |\cb_penalty_group| \cdot 100$. +%%% The output routine then decides whether it has been called +%%% to start or end a change bar or neither. This is done with the values +%%% |\cb_penalty_begin| and |\cb_penalty_end| that are used as the +%%% second-to-last digit of the change penalty. +%%% \end{newsloppy} + +%%% The output routine also needs to determine whether +%%% the beginning of change bar starts in horizontal or vertical mode +%%% so it can figure out the exact placement for the beginning of the +%%% bar line. In horizontal mode, the change bar does +%%% not begin at the baseline of the actual text position, but on top of the +%%% actual line. This is marked in the last digit, an odd digit will be +%%% used in horizontal mode. + +%%% Note that the values mentioned above are used as digits here that can be +%%% concatenated. If they are not followed by an other digit they should be +%%% terminated by |\space| to stop {\TeX}'s look-ahead scanning for +%%% digits when reading a number. +%%% \endchange + +%%% \beginprog +\def\cb_penalty_group{-101} +\def\cb_penalty_begin{0} +\def\cb_penalty_end{1} + +%%% \endprog + + +%%% \sect The calls to start or end a change bar, set an encoded page-break +%%% penalty which includes an +%%% indication of begin or end of a change bar. The variable +%%% |\cb_break_penalty| is used to create such as special value. +%%% The rest (|\cb_trigger_output|) is the same action +%%% for both. The region just before the end of the changed region can be +%%% in horizontal mode and preceded by +%%% glue that could cause a line break, thus including the following line to +%%% the change area as well. To avoid this unwanted behavior, the space is +%%% saved in |\save_lastskip|, discarded in front of the mark and restored +%%% afterwards. + +%%% \beginprog +\newcount\cb_break_penalty + +\def\beginchange_#1{% + \cb_changebarwidth=#1 + \cb_break_penalty=\cb_penalty_group\cb_penalty_begin0 + \cb_trigger_output + } +\def\endchange{{% + \skipdef\save_lastskip=255% + \ifhmode \save_lastskip=\lastskip \unskip \fi% + \cb_break_penalty=\cb_penalty_group\cb_penalty_end0% + \cb_trigger_output% + \ifhmode \hskip\save_lastskip \fi% + }}%\endchange +%%% \endprog + + +%%% \sect The next routine, |\cb_trigger_output|, +%%% triggers calls to the output routine by setting the page-break +%%% penalty, |\penalty|. {\TeX} may discard an |\output| invocation at +%%% the beginning of a page. So we trigger the output routine twice, first +%%% with a special penalty value that is 2~less than the correct value +%%% (including the code for horizontal or vertical mode). After the first +%%% page break, it is asserted that the current list is empty. The output +%%% routine has to save the former page contents if necessary. + +%%% Next we set the penalty to the correct value. The second page break does +%%% the real work, restores the page contents and handles the split +%%% insertions (footnotes, figures,~\dots). + +%%% In horizontal mode |\spacefactor| must not be destroyed, so it is +%%% saved and restored via local count register |\save_spacefactor|. + +%%% \beginprog + +\def\cb_trigger_output{% + \ifinner \errmessage{Change cannot be marked inside a box}% + \else{% + \countdef\save_spacefactor=255% + \ifvmode + \let\do_in_vmode=\relax + \advance \cb_break_penalty by -2 + \else + \save_spacefactor=\spacefactor + \let\do_in_vmode=\vadjust + \advance \cb_break_penalty by -3 + \fi + \do_in_vmode{% + \penalty\cb_break_penalty% first call to \output + \null + \advance \cb_break_penalty by 2 + \penalty\cb_break_penalty% second call to \output + }% + \ifhmode \spacefactor=\save_spacefactor \fi + }% + \fi + }% cb_trigger_output +%%% \endprog + + +%%% \sect Using the output routine for passing +%%% information has it's difficulties. One of the hard parts is +%%% \beginchange +%%% handling page marks. These are token lists which are set by the +%%% |\mark| command. They record information that can later +%%% be accessed by the output routine. The canonical example of such +%%% a use of the |\mark| command is in creating +%%% \endchange +%%% dictionary-style entry headings. +%%% +%%% The output routine can access one of three +%%% token lists through three control sequences: |\botmark| is the +%%% last page mark given, |\topmark| is the |\botmark| of the previous +%%% page, and |\firstmark| is the first page mark on the actual page or +%%% |\topmark| if none was given. Here ``page'' is used in the \TeX{} +%%% sense, i.e.\ as the material which has been collected between two +%%% |\output| invocations. Of course, the page marks must not be +%%% destroyed---and that means they must be reinserted after each +%%% special use of the output routine. + +%%% But we are lucky: A ``special use'' consists of two |\output| +%%% invocations, so we can insert |\topmark| again as a page mark after +%%% the first invocation where it will be the only page mark on that +%%% \TeX{} page. The second invocation will automatically transform this +%%% page mark into the ``last page mark on the previous page,'' i.e.\ in +%%% |\topmark|---that's what we need! Furthermore |\firstmark| and +%%% |\botmark| are saved in control sequences during the first invocation, +%%% they will be inserted again, too. + +%%% There's one situation where this approach doesn't work: in front of +%%% the first page mark. Here, |\topmark|, |\firstmark|, and |\botmark| expand +%%% to an empty token list. If we save them then and insert their old +%%% values we have inserted empty page marks. If other page marks follow +%%% on the same ``real'' page, |\firstmark| will be empty instead of +%%% expanding to the token list of the first page mark. To prevent this +%%% we must not save and restore page marks before the first |\mark| has +%%% been added to the main vertical list. + +%%% Well, that can be controlled with a switch---but this switch must be +%%% set very carefully. If it is set immediately by the first |\mark| +%%% this may be in horizontal mode and special output invocations can +%%% occur above this page mark (i.e., there may be a |\beginchange| in the +%%% same paragraph in front of the |\mark|). Therefore the setting of the +%%% switch must be delayed until the vertical position of the |\mark| +%%% (precisely: the position of the |\mark| in the current list) is +%%% reached. In horizontal mode this can be done with a |\vadjust| and +%%% the output routine! Voil\`a, this is another command group for the +%%% output routine with only one command. + +%%% \beginprog +\newif\if_cb_save_mark@ \_cb_save_mark@false + +\def\mark_penalty_group{-102} +%%% \endprog + + +%%% \sect We will redefine |\mark| so that the first page mark either sets +%%% the switch to true (in vertical mode all possible special page breaks +%%% are already handled) or forces the |\output| routine to do this at an +%%% appropriate place. In the last case we can use |\cb_trigger_output| +%%% again. Afterwards we restore the original meaning of |\mark| again to +%%% reduce the processing overhead (and the dead cycles). + +%%% This change of |\mark| has the consequence that the first |\mark| in a +%%% document cannot be used anymore in horizontal mode inside a vertical +%%% box that shall be split afterwards. But this is only sensible if this +%%% mark shall be used as |\splitfirstmark| because it will almost never +%%% migrate to the outer list---really a rare case! + +%%% \beginprog +\let\cb_mark=\mark +\def\mark{% + \ifvmode + \ifinner \else \global\_cb_save_mark@true \fi % split marks! + \else + \cb_break_penalty=\mark_penalty_group00 % this will corrupt \vsplit + \cb_trigger_output + \fi + \global\let\mark=\cb_mark + \cb_mark + } +%%% \endprog + + +%%% \sect +%%% \begin{newsloppy} +%%% If the output routine is triggered with the mark penalty value, +%%% it will call {\tt \bs cb\_save\discretionary{\_}{}{}page\_marks}. +%%% \end{newsloppy} + +%%% \beginprog +\def\cb_save_page_marks{% % this may be executed twice + \unvbox\@cclv + \global\_cb_save_mark@true + } +%%% \endprog + + +%%% \sect To finish the treatment of page marks we can formulate the two +%%% macros which are used at the first resp.\ second invocation of a +%%% ``special output,'' the principles have already been explained. + +%%% \beginprog +\def\cb_backup_page_marks{% + \if_cb_save_mark@ + \mark{\topmark}% + \xdef\cb_save_firstmark{\firstmark}% + \xdef\cb_save_botmark{\botmark}% + \fi + } + +\def\cb_restore_page_marks{% + \if_cb_save_mark@ + \mark{\cb_save_firstmark}\mark{\cb_save_botmark}% + \fi + } +%%% \endprog + + + + + +%%% \chap Positioning the Change Bars. + +%%% \begin{newsloppy} +%%% Now we handle the positions of the bars. +%%% The dimension |\cb_bot_change_pos| will hold +%%% the position of the end of the change bar, i.e.\ the distance between +%%% top of page the end of the changed area. The dimension +%%% |\cb_top_change_pos| will hold the beginning of a changed +%%% area; a value of |\maxdimen| indicates that no change is in effect. If +%%% a changed area is completed, it is appended to the list |\cb_bar_list| as +%%% an element {\tt \bs cb\_bar(\bs cb\_top\_change\_pos, +%%% \bs cb\_bot\_change\_pos, \bs changebar\-width)}. This list contains all +%%% changed areas within the current page so that bars can be written later +%%% on. A single bar will be produced by |\cb_write_bar|. + +%%% \noindent The definition of |\cb_bar| to |\relax| allows the concatenation +%%% of new elements to |\cb_bar_list| with |\xdef|. + +%%% Local dimension register |\halfwidth| is used to center the change bar. +%%% \end{newsloppy} + +%%% \beginprog +\newdimen\cb_bot_change_pos +\newdimen\cb_top_change_pos \cb_top_change_pos=\maxdimen + +\let\cb_bar_list=\empty + +\let\cb_bar=\relax +\def\cb_write_bar(#1,#2,#3){{% + \dimendef\halfwidth=255% + \setbox0=\hbox{\vrule width #3 height -#1 depth #2}% + \dp0=0pt \ht0=0pt \wd0=0pt% + \halfwidth=#3 \divide\dimen255 by 2% + \hskip -\halfwidth% + \box0% + \hskip \halfwidth% + }} +%%% \endprog + + +%%% \sect If the output routine was activated by a |\outputpenalty| value +%%% within the range of our reserved penalties, the change handling will +%%% occur, otherwise standard plain output can be done. There may be +%%% a lot of interaction between the routines which set change bars and +%%% the output routine. These interactions should not be recorded in +%%% |\deadcycles| or else \TeX{} will soon grumble. One might consider +%%% doing the same for the|\mark_penalty_group|. But since this +%%% group is called once it shouldn't matter all that much. + +%%% One might also consider adding a counter like |\deadcycles| just +%%% to count the change bar interactions as is done for the calls to +%%% |\output|, and have {\TeX} grumble if there are ``too many'' of +%%% them. For now we don't do this---all of this code is correct +%%% anyway! + +%%% First we save away the old output routine in case the user had redefined +%%% this beforehand. + +%%% \beginprog +\newtoks\cb_oldoutput +\edef\cb_oldoutput{\the\output} + +\newcount\penalty_group + +\output={% + \boxmaxdepth=\maxdepth + \penalty_group=\outputpenalty \divide \penalty_group by 100 + \ifnum \penalty_group=\cb_penalty_group\space + {\countdef\new_deadcycles=255% don't count as a dead cycle + \new_deadcycles=\deadcycles + \advance \new_deadcycles by -1 + \deadcycles=\new_deadcycles} + \cb_change_handling + \else + \ifnum \penalty_group=\mark_penalty_group\space + \cb_save_page_marks + \else \cb_oldoutput + \fi + \fi + } +%%% \endprog + + +%%% \sect As explained before, the change handling must differentiate +%%% between the kind of the change command (beginning is indicated by +%%% $|\cb_change_cmd|=0$, end by~1) and between the mode (horizontal indicated +%%% by an odd |\cb_change_mode| value, vertical by an even). A change mode +%%% higher than one indicates that we are doing the first page break that +%%% has to backup the page as far as it exists already and results in an +%%% empty current list of page elements. + +%%% \beginprog +\newcount\cb_change_cmd +\newcount\cb_change_mode + +\def\cb_change_handling{% + \cb_change_cmd=-\outputpenalty % ==> absolute value + \advance \cb_change_cmd by \cb_penalty_group00 % subtraction + \cb_change_mode=\cb_change_cmd + \divide \cb_change_cmd by 10 % second-to-last digit + \advance \cb_change_mode by -\number\cb_change_cmd0 % last digit + \ifnum \cb_change_mode>1 \cb_backup_page + \else + \ifcase \cb_change_cmd \cb_begin_change + \or \cb_end_change + \else \errmessage{Invalid changepenalty}% + \fi + \fi + } +%%% \endprog + + +%%% \sect Processing a mark during the second trigger of the output routine +%%% means restoring the page and storing the positions. At the beginning, +%%% the begin of the change is saved, at the end, we know the bar already +%%% and put it into the bar list. Then the positioning values are +%%% reinitialized. + +%%% As within every output invocation, the box 255 must be unboxed. As we +%%% are here in the second invocation of the output routine the |\box255| +%%% consists only of the empty |\vbox| we have inserted in +%%% |\cb_trigger_output|. We can therefore throw it away. + +%%% \beginprog +\def\cb_begin_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \global\cb_top_change_pos=\cb_bot_change_pos + \global\cb_bot_change_pos=0pt + \else \errmessage{Nested change bars are not supported}% + \fi + } + +\def\cb_end_change{% + \cb_restore_page + \setbox0=\box\@cclv + \ifdim \cb_top_change_pos=\maxdimen + \errmessage{No change is in effect}% + \else + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos,\the\cb_bot_change_pos, + \the\cb_changebarwidth)} + \global\cb_top_change_pos=\maxdimen + \global\cb_bot_change_pos=0pt + \fi + } +%%% \endprog + + +%%% \chap Handling the Page Contents. + +%%% We handle the part of the page that was collected up to now by putting +%%% it into a box. This fixes the position of the change mark so that +%%% |\cb_bot_change_pos| can be set and stored in |\cb_top_change_pos| +%%% later on or as the lower end of a bar in |\cb_bar_list|. + +%%% In the first output invocation, we save the contents of the +%%% page in |\cb_save_page|. Before that, we store the size of the +%%% box (which equals |\pagegoal|!)\ in |\cb_page_goal|. If the unboxing +%%% caused an increase of height (i.e.\ if $|\pagetotal|>|\pagegoal|$), +%%% we eject the page up to the change mark. Now we have to compute the +%%% current position of our mark in |\cb_bot_change_pos|. It is fixed by the size +%%% of the |\cb_save_page|, but if the change begins in horizontal mode we +%%% must decrease it from the baseline position to the top of the last line. +%%% Finally, we must save the values for the allowed insertions and change +%%% them to the maximal value so that a rest that is split from an insertion +%%% will be appended to the insertion box at the second invocation in every +%%% case. + +%%% The |\vsize| is initialized to |\maxdimen|. This allows to control +%%% whether this first output invocation ocurred or if it was discarded. +%%% For the same reason |\cb_bot_change_pos| is initialized to~0pt. + +%%% \beginprog +\newbox\cb_save_page + +\newdimen\cb_page_goal +\newdimen\cb_save_vsize \cb_save_vsize=\maxdimen +\newdimen\cb_save_dimen_topins +\newdimen\cb_save_dimen_footins + +\def\cb_backup_page{% + \global\cb_page_goal=\ht\@cclv + \global\setbox\cb_save_page=\vbox{\unvbox\@cclv}% + \ifdim \ht\cb_save_page>\cb_page_goal + \cb_eject_page_so_far \fi + \cb_bot_change_pos=\ht\cb_save_page + \global\advance \cb_bot_change_pos by \dp\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode \higher_change_pos \fi + \fi + \global\cb_save_vsize=\vsize \global\vsize=\maxdimen + \global\cb_save_dimen_topins=\dimen\topins + \global\dimen\topins=\maxdimen + \global\cb_save_dimen_footins=\dimen\footins + \global\dimen\footins=\maxdimen + \cb_backup_page_marks + } + +\cb_bot_change_pos=0pt +%%% \endprog + + +%%% \sect To eject a page as far as it is we restore it from the +%%% |\cb_save_page| back to box~255. In horizontal mode and at a begin mark +%%% the last line contains the mark and must not be output. So we remove it +%%% and the preceding glue from the stored rest, just leaving a single hbox +%%% to be on top of the actual page (in |\cb_save_page|) now. Then normal +%%% output can be done with box~255. + +%%% \beginprog +\def\cb_eject_page_so_far{% + \begingroup + \vbadness=20000 % don't complain about underfull vboxes + \global\setbox\@cclv=\vbox to \cb_page_goal{% + \unvbox\cb_save_page + \ifnum \cb_change_cmd=\cb_penalty_begin\space + \ifodd \cb_change_mode + \global\setbox\cb_save_page=\lastbox + \unskip + \fi + \fi + }% + \endgroup + \cb_oldoutput + } +%%% \endprog + + +%%% \sect +%%% \begin{newsloppy} +%%% In horizontal mode and at a begin mark, we need the position of +%%% the mark ({\tt \bs cb\_bot\discretionary{\_}{}{}change\_pos}) on the upper boundary of +%%% the last line in +%%% |\cb_save_page|. If there is just one line left from a recent eject, the +%%% height is given by |\topskip| decreased by the height of this hbox. If +%%% the height of the box is larger than |\topskip| the skip will not be +%%% inserted and the change position results to~0pt. Otherwise, +%%% |\cb_save_page| is a vbox whose last hbox we delete temporarily using +%%% box~0. Height and depth of the rest are the actual position on the page. +%%% \end{newsloppy} + +%%% The double of the page we have constructed this way will immediately be +%%% fed back to the garbage collector because it could have become +%%% reasonably large. + +%%% \beginprog +\def\higher_change_pos{% + \ifhbox \cb_save_page % rest of page from \cb_eject_page_so_far + \cb_bot_change_pos=\topskip + \global\advance \cb_bot_change_pos by -\ht\cb_save_page + \ifdim \cb_bot_change_pos<0pt + \global\cb_bot_change_pos=0pt + \fi + \else + \setbox0=\vbox{% + \unvcopy\cb_save_page + \setbox0=\lastbox % delete last line + }% + \cb_bot_change_pos=\ht0 + \global\advance \cb_bot_change_pos by \dp0 + \setbox0=\box\voidb@x + \fi + } +%%% \endprog + + +%%% \sect To restore a page during the second output invocation, we first +%%% restore the saved values, but only if they were really changed (this can +%%% be discovered by the value of |\cb_save_vsize|). Now the |\cb_save_page| is +%%% appended to the current list as a box, which stops later usage of its +%%% stretch- and shrinkability! Then the collected insertions can be +%%% inserted again. The page marks have to be inserted, too. + +%%% \beginprog +\def\cb_restore_page{% + \ifdim \cb_save_vsize=\maxdimen + \else \global\vsize=\cb_save_vsize + \global\dimen\topins=\cb_save_dimen_topins + \global\dimen\footins=\cb_save_dimen_footins + \global\cb_save_vsize=\maxdimen + \cb_restore_page_marks + \fi + \box\cb_save_page % discards stretch- and shrinkability! + \ifvoid \topins + \else \insert\topins{\floatingpenalty=0 \unvbox\topins}% + \fi + \ifvoid \footins + \else \insert\footins{\floatingpenalty=20000 \unvbox\footins}% + \fi + } +%%% \endprog + + +%%% \sect {\em Please note, that there is still a problem with this concept +%%% of handling the output trigger:} + +%%% \bigskip + +%%% If the first output trigger is discarded because a page break has occurred +%%% just in front, footnote parts may be juggled around. I.e., if a +%%% footnote is split in three parts, the first part was just been shipped +%%% out, the second part is inserted back into the recent contributions by +%%% the output routine but {\em behind\/} the third part which is saved in +%%% the ``special place'' (according to the \TeX{}book, p.~125). A solution to +%%% this problem might be to insert a |\do_change| again within the second +%%% output trigger and finishing the treatment afterwards. Afterwards a +%%% full triggering process (two output invocations) is executed again and +%%% all insertion parts will be accessible in the insertion box. + +%%% By the way, the almost same problem appears in \LaTeX{}, too. Almost: in +%%% \LaTeX{} this can happen every time because at the first output invocation +%%% the |\dimen|-values of the footnote insertion is not increased. I leave +%%% the problem open to the reader\,\dots + + + + + +%%% \chap Writing the Stuff. + +%%% The positions of the bars which mark the changed areas are relative to +%%% the top of the text, i.e.\ the height of the top insertion is not +%%% included. Therefore it is best to write them just after the top +%%% insertions before the page text---but to do this we have to change the +%%% \beginchange +%%% either the {\sc Plain} {\TeX} macro |\pagecontents| or the {\LaTeX} +%%% macro |\@makecol|. +%%% \endchange + +%%% Below is the new definition, I have just rearranged it a little bit so +%%% that it is more legible. The new lines have been marked with +%%% `|%%%%|'. |\cb_insert_current_bar| inserts a last element in |\cb_bar_list| +%%% if a changed area is not yet finished, afterwards all bars can be +%%% written. + +%%% \beginprog +\def\pagecontents{% + \ifvoid \topins \else \unvbox\topins \fi + \cb_insert_current_bar \cb_write_all_bars %%%% + \dimen@=\dp\@cclv \unvbox\@cclv % open up \box255 + \ifvoid \footins + \else % footnote info is present + \vskip\skip\footins + \footnoterule + \unvbox\footins + \fi + \ifr@ggedbottom \kern-\dimen@ \vfil \fi + } +%%% \endprog + +%%% \sect If $|\cb_top_change_pos|=|\maxdimen|$ no change is active. Otherwise +%%% the current change reaches from the begin mark (|\cb_top_change_pos|) to +%%% the end of the page, i.e.\ we insert a virtual end mark. Because the +%%% change continues on the next page we insert a virtual begin mark on the +%%% top of the page, too. + +%%% \beginprog +\def\cb_insert_current_bar{% + \ifdim \cb_top_change_pos=\maxdimen + \else% + \cb_bot_change_pos=\ht\@cclv + \advance\cb_bot_change_pos by \dp\@cclv + \xdef\cb_bar_list{\cb_bar_list + \cb_bar(\the\cb_top_change_pos, + \the\cb_bot_change_pos, + \the\changebarwidth)}% + \global\cb_top_change_pos=0pt + \fi% + } +%%% \endprog + + +%%% \sect Now we can write all bars---if they exist anyway. It's rather +%%% easy, we just have to define |\cb_bar| to |\cb_write_bar| and execute +%%% |\cb_bar_list|. The resulting output must not use vertical place. We must +%%% not forget to delete the list, or we will get the same bars on the next +%%% page again. + +%%% \beginprog +\newbox\cb_bars +\newdimen\cb_offset + +\def\cb_write_all_bars{% + \ifx \cb_bar_list\empty + \else % changes exist + \ifchbarRight + \cb_offset = \hsize + \advance \cb_offset by \BarDistance + \else + \cb_offset = \hoffset + \advance \cb_offset by -\BarDistance + \fi + \setbox\cb_bars=\hbox to \cb_offset{% + \hskip\cb_offset + \vbox to 0pt{\offinterlineskip + \let\cb_bar=\cb_write_bar \cb_bar_list + }% + \hss + }% + \ht\cb_bars=0pt \dp\cb_bars=0pt \box\cb_bars + \global\let\cb_bar_list=\empty + \fi + } +%%% \endprog + + +%%% \beginchange\chap Cleaning Up.\endchange + +%%% We finish the macro file so that garbage (e.g.\ of exchanges +%%% between systems) can come afterwards. + +%%% \beginprog +\catcode`\@=\atcode +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + +%%% \end{document} + diff --git a/macros/latex209/contrib/chbars/makeprog.lex b/macros/latex209/contrib/chbars/makeprog.lex new file mode 100644 index 0000000000..e1c9a11d87 --- /dev/null +++ b/macros/latex209/contrib/chbars/makeprog.lex @@ -0,0 +1,4 @@ +%% + +^%%%\ ? ; +^%%%%.*\n ; diff --git a/macros/latex209/contrib/chbars/makeprog.perl b/macros/latex209/contrib/chbars/makeprog.perl new file mode 100644 index 0000000000..6c1c889828 --- /dev/null +++ b/macros/latex209/contrib/chbars/makeprog.perl @@ -0,0 +1,3 @@ +#!/usr/bin/perl -np +s/^%%%\ ?//g; +s/^%%%%.*\n//g;
\ No newline at end of file diff --git a/macros/latex209/contrib/chbars/progltx.ltx b/macros/latex209/contrib/chbars/progltx.ltx new file mode 100644 index 0000000000..389a3eae60 --- /dev/null +++ b/macros/latex209/contrib/chbars/progltx.ltx @@ -0,0 +1,754 @@ +% This is PROGLTX.DOC as of 25 May 90 +%--------------------------------------------------------- +% (c) 1989,1990 by J.Schrod. copy conditions see below + +% +% Macro package for the documentation of programs +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 92-01-15 rlb add newsloppy environment (based on comment by +% Frank Mittlebach. Don't force a \newpage in +% Chapters, Just put a bigger space there. +% 89-11-18 js repaired the handling of `|' (verbatim and \index). +% 89-10-05 js first version (for TeX89) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% documented with itself... +\documentstyle[progltx]{article} + + +% +% +% local macros +% + +\let\mc=\small % for names like GNU + +\def\WEB{{\tt WEB\/}} +\def\GNU{{\mc GNU}} + +% +% + + +\begin{document} + + +\title{ + Documenting programs in a \WEB{} style\\ + The {\tt progltx\/} style option + } +\author{\sc Joachim Schrod} + +\maketitle + + +\chap Introduction. + +\WEB{} systems allow the documentation of programs by supporting the +separation in program fragments which can be collected and rearranged +afterwards. This allows {\it top-down\/} programming as well as the +{\it bottom-up\/} design of programs. Each program fragment can be +documented, usually with \TeX{}\@. A disadvantadge is that \WEB{} +actually exists only for a few programming languages (Pascal, C, +Modula-2). Besides, building up \WEB{} systems for ``exotic'' +programming languages like \TeX{} is very difficult. + +This macro package was built to allow good documentation for programs +in languages for which \WEB{} doesn't exist. It separates a program +text in sections that can be documented. All sections, collected +sequentially, will result in the complete program. In every section +begin and end of the program part are marked with |\beginprog| and +|\endprog|, this program part will be formatted as it is input +(``verbatim''). + +Originally these macros were written for the usage with Plain \TeX{} +resp.\ on top of the \WEB{} macro package |webmac.tex|. But often the +requirement has been told to me that a \LaTeX{} version would be +useful, too---well, here it is. But even with \LaTeX{} I have decided +that still |\beginprog| and |\endprog| must be used for the markup of +the program parts, not |\begin{prog}| or |\end{prog}| which would be +more ``\LaTeX{}-like.'' The reason behind this is that I didn't want +to maintain two versions of the {\mc MAKEPROG\/} processor---but {\mc +MAKEPROG\/} wants to see the non-\LaTeX{}-like macros. But everybody +is encouraged to change it by themselves (it is {\it very\/} easy). + +The user of these macros may use the usual sectioning macros of +\LaTeX{} for structuring his documentation. Additionally we provide a +|progdoc|-compatible (i.e.\ \WEB{}-like) markup with the two macros +|\chap| and |\sect|. + +In the documentation part of a section text pieces, e.g.\ names of +variables, can be inserted verbatim to demonstrate the connection to +the program text. These parts are included in vertical bars +(`{\tt\vbar}') This makes this style option extremely useful if your +identifiers (or your file names) include characters which would be +special characters for \TeX{} otherwise. (One example of these +program languages is \TeX{} itself, but just enclose the macro names +in vertical bars and {\tt \vbar|\relax|\vbar}.) + +The macros |\makevertother| and |\makevertactive| are available to +activate and deactivate the special behaviour of the vertical bar but +these macros should be needed seldom because the usual cases as the +usage within |verbatim| and |tabular| environments or |\index| macros +etc.\ are handled. + +If a vertical bar must be used in the original fashion you can use two +command sequences: |\origvert| holds the meaning of the vertical bar +at the time this macro file was read in and |\vbar| is the character +with the {\mc ASCII\/} code of the vertical bar (i.e.~|"EC|) in the +current font. + +The new notion of |\verb| must not be used within parameters of +macros, e.g.\ in the argument of |\section| etc.---it will result in +an error message by \TeX{}\@. Furthermore within the preamble of a +|tabular|, an |array| environment, or the |\multicolumn| command the +vertical bar has the same meaning as before. (That means within +|@{|\ldots|}| it is an ordinary character and otherwise it specifies a +vertical rule between the columns. + +This macro package does not offer the automatic creation of an index +because it is not known which syntactical tokens the language has that +should be mentioned in an index. But of course all \LaTeX{} stuff like +|\index|, |\tableofcontents|, etc.\ may be used. + + +\sect This program is free software; you can redistribute it and/or +modify it under the terms of the \GNU{} General Public License as +published by the Free Software Foundation; either version~1, or (at your +option) any later version. + +This program is distributed in the hope that it will be useful, but +{\bf without any warranty\/}; without even the implied warranty of +{\bf merchantability\/} or {\bf fitness for a particular purpose}. See +the \GNU{} General Public License for more details. + +You should have received a copy of the \GNU{} General Public License +along with this program; if not, write to the Free Software Foundation, +Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +\sect We have to realize three parts: (1)~the formatting of rather +small verbatim texts in a line, (2)~the formatting of larger parts of +program and (3)~the document structuring elements for the separation +of the sections. + +\begin{sloppypar} +Before we start we declare some shorthands for category codes. By +declaring the underscore~`(|_|)' as a letter we can use it in our +macros names. (I agree with D.~Knuth that +|\identifier_several_words_long| is more readable than +|\IdentifierSeveralWordsLong| and in every case better than +|\p@@@s|.) But as we have to restore the category codes at the end +of this macro file we store its former value in the control +sequence |\uscode|. This method is better than the usage of a +group because not all macros have to be defined global this way. +\end{sloppypar} + +\beginprog +\chardef\escape=0 +\chardef\open=1 +\chardef\close=2 +\chardef\letter=11 +\chardef\other=12 +%\chardef\active=13 % is defined in Plain already + +\chardef\uscode=\catcode`\_ + +\catcode`\_=\letter +\endprog + + + + +\chap Local Verbatim Formatting. + +The main point of every verbatim formatting is the switching of the +character codes of all characters that have a special \TeX{} meaning. +This can be done with the control sequence |\dospecials| that applies +the control sequence |\do| to all special characters. Additionally, +every line is regarded as a paragraph without indentation. Between +two paragraphs, i.e.\ between two lines, no extra space is set. +Finally all blanks and tabular characters shall be obeyed and the +inter word space after sentence terminators shall not be enlarged. +The activation of the tabular characters with |\obeytabs| is +equivalent to |\obeyspaces| in {\tt plain.tex}. + +\begin{sl} +As a matter of fact, I would like to use the character set with the +extended {\mc ASCII} (like in\/ \WEB{}) for setting the verbatim texts +in monospace. But then I must code many\/ |\@getfont|'s\,\dots +\end{sl} + +\beginprog +%\font\tentex=cmtex10 % typewriter extended ASCII 10pt +%\let\ttex=\tentex % only with base size 10pt +\def\ttex{\tt} % as a substitute + +\def\setup_verbatim{% + \def\do##1{\catcode`##1\other}\dospecials + \parskip\z@skip \parindent\z@ + \catcode`\`\active \@noligs + \obeylines \@vobeyspaces \obeytabs \frenchspacing + \ttex + } + +\let\tab=\space +\begingroup + \catcode`\^^I=\active% % Attention: no tabs! + \gdef\obeytabs{\catcode`\^^I=\active\def^^I{\tab}} + \global\let^^I=\tab% % if an active tab appears in a \write +\endgroup +\endprog + + +\sect After having saved the old meaning of `{\tt\vbar}' in +|\origvert| and after declaring |\vbar| as a synonym for the character +that has the code of a vertical bar in the actual font, the vertical +bar can be made active. Then we call |\setup_verbatim|. But the +newline characters shall not be processed, they shall be regarded like +blank space. This can be reached by defining |\par| as |\space|. + +The next vertical bar in the input closes the group which becomes an +(unbreakable) |\hbox| then. The old meanings of the special +characters and of the vertical bar are restored and \TeX{} is in +normal (horizontal) mode again. + +\beginprog +\let\origvert=| +\chardef\vbar=`\| + +\def\makebaractive{\catcode`\|\active} +\def\makebarother{\catcode`\|\other} +\makebaractive + +\def|{% + \leavevmode + \hbox\bgroup + \let\par\space \setup_verbatim + \let|\egroup + } +\endprog + + +\sect A problem with this definition of the vertical bar is that +the bar is not a normal character any more but there exists situations +where the \LaTeX{} macros assumes this: +% +\begin{itemize} + +\item In a |verbatim| environment a vertical bar must be typeset if it +occurs in the input. + +\item In a |tabular| or an |array| environment a vertical bar is used +to denote rules between columns in the table. These environments must +be started with a parameter which is a ``preamble,'' the same preamble +construction is used to specify the format of multi-column entries. + +\item In an output of an index entry the vertical bar must not result +in an error message. Usually index entries are typeset in a seperate +\TeX{} run where |idverb| is not used as a style option and the +vertical bar is therefore useful. This is no problem in section +headings or captions etc. Because they take their argument as a +parameter in every case the vertical bar can never be used there. But +|\origvert| resp.\ |\vbar| may be used there. + +\end{itemize} +% +In the next sections we handle each of these problems. + + +\sect Before we start a |verbatim| environment we just redefine the +vertical bar as an ordinary character. Because this is within the +environment grouping the end of the environment will reestablish the +special meaning. + +\beginprog +\let\@@verbatim=\@verbatim +\def\@verbatim{% + \makebarother + \@@verbatim + } +\endprog + + +\sect Special care is needed in the |tabular| and the |array| +environment. Both environments are begun by one macro (|\@tabarray|), +we redefine it so that the bar can be used in the preamble +specification. The same problem occurs in |\multicolumn|, it is +solved the same way. After the preamble construction (with +|\@mkpream|) the special meaning of the bar can be switched on +again---this allows the usage of the new meaning in the body of a +table. + +Of course this mean that the ``verbatim identifier'' facility can +not be used within a preamble of a table. Furthermore it can not +be used within the |\multicolumn| statement, neither in the +preamble part (the second parameter) nor within the text part (the +third parameter). + +\beginprog +\let\@@tabarray=\@tabarray +\def\@tabarray{% + \makebarother + \@@tabarray + } + +\def\multicolumn#1{% + \multispan{#1}% + \begingroup + \makebarother + \restof_multicolumn + } +\def\restof_multicolumn#1#2{% + \@mkpream{#1}% + \def\@sharp{#2}% + \let\protect\relax + \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox + \@arstrut \@preamble + \endgroup + \ignorespaces + } + +\let\@@mkpream=\@mkpream +\def\@mkpream#1{% + \@@mkpream{#1}% + \makebaractive + } +\endprog + + +\sect Before an index entry is scanned almost all special characters +are transformed into ordinary characters. The only exceptions are the +opening and the closing brace because they are needed to delimit the +argument. This transformation is done with |\@sanitize|, this macro +must be called within a group. We just append the transformation of +the vertical bar. + +\beginprog +\begingroup + \def\@makeother{\noexpand\@makeother\noexpand} + \xdef\@sanitize{\@sanitize\@makeother\|} +\endgroup +\endprog + + + + +\chap Fragments in Verbatim. + +We need macros to format the program fragments without any +linebreaking. Such a text area shall start with the macro +|\beginprog| and end with |\endprog|, i.e.\ as a kind of a +|prog|-environment. The macro |\endprog| must stand at the very +beginning of a line and must be followed by white space (blank, tab or +newline character). After |\beginprog| as well as after +|\endprog| the rest of the line is ignored. + +Two demands must be regarded: There should be no length restrictions +for the processed text, and the tabular characters should be expanded +so that this macro works on PC's and on VAXes etc., too. + + +\sect The implementation method is quite simple: We read the next +line, test, wether the end is reached (by comparing with the end line) +and otherwise set the line actually read. Every character is +inspected and tabular characters are expanded. + +The verbatim text is started with |\begin_verbatim| which will be +either called by |\beginprog| or by |\beginverbatim|. These macros +will also define the contents of the end line. + +Whether a line is set or whether the end of the processed area is +reached is indicated by the switch |\if@print|. At the beginning of +the |\begin_verbatim| macro most settings are done with +|\setup_verbatim| (the vertical bar must be handled separately) +and the rest of the line is ignored. As everything is done within +a group, the end of the verbatim text can be processed by simply +closing this group. + +For the user it looks as if |\endprog| or |\endverbatim| +terminates the processing, but it just serves for the +identification of the end, the true processing is done with the +internal macro |\end_verbatim|. + +\beginprog +\newif\if@print + +\def\begin_verbatim{% + \endgraf + \bigbreak + \begingroup + \setup_verbatim \makebarother + \@printtrue + \ignore_rest_line + } +\let\end_verbatim=\endgroup % internal command ! +\endprog + + +\sect {\sloppy + The first line is ignored, all the other lines are identified with +|\set_next_line| and processed with |\do_set|. This separation in +identification and processing allows that the line end character is +active in the definition only for a short time. + \par} + +When a line is to be formatted, we first check with |\check_print| +wether it contains the end line, otherwise it is printed with +|\print_char|. The printing must be done for every character +individually because we want to check for tabular characters; the +exact algorithm is described below. Here we just have to note that +|\print_char| is used with two parameters of which the second one is +finished with the token |\end_line|. The first parameter is the first +character of the line, the second parameter is the rest of the line. +If the line is empty, the argument of |\do_set| is empty, too; so the +activation of |\print_char| must be finished with two |\end_line|. +Then the first |\end_line| is the first argument for |\print_char| and +the second argument is empty. But if the line did contain something, +the second |\end_line| is evaluated, for this case it is defined as +|\relax|. + +At last we call |\set_next_line| again to format the next line. If +the end is reached, i.e.\ if the sample line was found, +|\set_next_line| will be redefined as |\relax|. This can be done +because the original meaning is restored while closing the group +with |\end_verbatim|. + +\beginprog +\begingroup + \obeylines% % ^^M is active! ==> every line must end with % + \gdef\ignore_rest_line#1^^M{\set_next_line}% + \gdef\set_next_line#1^^M{\do_set{#1}}% +\endgroup + +\def\do_set#1{% + \endgraf + \check_print{#1}% + \if@print \indent \print_char#1\end_line\end_line + \else \let\set_next_line\end_verbatim + \fi + \set_next_line + } +\let\end_line=\relax +\endprog + + +\sect {\sloppy + Before we look at the problem of formatting a line, we declare +|\check_print| that checks the end of the verbatim mode. We have to +do two things: we must split everything in front of the first blank +or tabular character and compare for identity with |\endprog|. The +splitting is easy because the line which is our first argument +contains blanks and tabulators as active characters. First we call +|\cut_at_tab| that demands a tabular character as separator for its +two pramenters so that everything in the line in front of the first +tabulator is part of the first parameter. If there is no tabular +character in the line, we append one so that the second parameter is +empty. The same trick is used to separate the part in front of the +first blank character from the resulting first part. + \par} + +The check is done with |\do_check|. We use a separate macro here so +that we can indent it (in the following definition blanks are active!) + +\beginprog +\begingroup +\obeyspaces\obeytabs +\gdef\check_print#1{\cut_at_tab#1^^I\end_line} +\gdef\cut_at_tab#1^^I#2\end_line{\check_first_part#1 \end_line}% blank ! +\gdef\check_first_part#1 #2\end_line{\do_check{#1}} +\endgroup +\endprog + + +\sect +\begin{sloppypar} +|\do_check| compares the line with a sample line that is +available in |\end_verbatim_line|. This macro will be defined later. +\end{sloppypar} + +\beginprog +\def\do_check#1{% + \def\@line{#1}% + \ifx \@line\end_verbatim_line \@printfalse + \fi + } +\endprog + + +\sect Now we can set a line: we start with the first character, +followed by the rest of the line. Each character is counted in +|\char_count|. At the beginning of a line |\char_count| is~0, this +is reset at the end of the line. + +\beginprog +\newcount\char_count \char_count\z@ + +\def\print_char#1#2\end_line{% + \print_first_char{#1}% + \print_rest_of_line{#2}% + } +\endprog + + +\sect For each character that is set |\char_count| is incremented. +If a character is a tabulator, we set with |\print_tab| the fitting +amount of blank characters, otherwise the character itself. We must +compare the character that is stored in |\@char| with a macro of which +the ``first-level'' expansion is an active tabulator. For this case +we declare |\@tab|. + +\beginprog +{\obeytabs\gdef\@tab{^^I}} + +\def\print_first_char#1{% + \def\@char{#1}% + \advance \char_count\@ne + \ifx \@char\@tab \print_tab + \else \@char + \fi + } +\endprog + + +\sect If we want to fill the line with blank spaces up to the next +column with a number that can be divided by~8, we must be able to +compute the column number modulo~8, but \TeX{} has no modulo operator. +So we define the macro |\mod_viii| that computes its argument modulo~8 +and returns the result in the counter |\count_mod_viii|. For the +computation we need the temporary counter |\count@|. + +\beginprog +\newcount\count_mod_viii +\def\mod_viii#1{% + \count@ #1\relax \count_mod_viii\count@ + \divide \count@ 8\relax + \multiply \count@ 8\relax + \advance \count_mod_viii -\count@ + } +\endprog + + +\sect Now we can declare |\print_tab|. We must remember that +|\char_count| was incremented already, if we set only one blank +character the counter keeps untouched. + +\beginprog +\def\print_tab{% + \loop \space \mod_viii\char_count + \ifnum \count_mod_viii>\z@ + \advance \char_count\@ne + \repeat + } +\endprog + + +\sect If the rest of the line is empty, we are ready. |\char_count| +is reset to~0 for the next line. + +Inside the |\else| part of |\ifx| |\print_char| should not be used +directly because this costs too much storage of \TeX{}\@. Instead we +set a control sequence |\next| that is processed afterwards, depending +on the result of the comparison. (This tail recursion will be +discovered by \TeX{} and handled appropriately.) If there is still +something to set, we use |\print_char| again, otherwise a +syntactically similar macro that expands to |\relax|. + +\beginprog +\def\print_rest_of_line#1{% + \def\@line{#1}% + \ifx \@line\empty \char_count\z@ + \def\next##1\end_line{\relax}% + \else \let\next\print_char + \fi + \next#1\end_line + } +\endprog + + +\sect {\sloppy +Now we are ready to define the two ``user accessible'' macros +|\beginprog| and |\beginverbatim|. They must define the prototyp end +line |\end_verbatim_line| which will be compared against every line +in the verbatim text. During the definition of +|\end_verbatim_line| it must be cared for that the escape character~`|\|' +is a printable character: A comparison with |\ifx| demands identical +category codes. As a temporary escape character we use the slash. +\par} + +\beginprog +{\catcode`\/=\escape % / is temporary escape char + \catcode`\\=\other + /gdef/beginprog{% + /gdef/end_verbatim_line{\endprog}% + /begin_verbatim + } + /gdef/beginverbatim{% + /gdef/end_verbatim_line{\endverbatim}% + /begin_verbatim + } +} % here \endgroup can't be used +\endprog + + + + +\chap Document Structuring. + +In addition to the normal \LaTeX{} structuring markups we will +provide a markup for a layout of the document that is like in +\WEB{}. This can be done easily. All sections are numbered, the +number of the next section is stored in the counter |section|. We +distinguish between main sections which start a group of sections +and between normal sections within a group. + +The main sections are started with the macro |\chap|. It has one +parameter, the title of the section group. This parameter must be +terminated by a dot. We start a new page, typeset the title in +bold face and separate it from the section text with a |\medskip|. +This text, the documentation part of the section, is formatted +without paragraph indentation. + +If the \WEB{}-like macros are used every section number should be +output with a following dot. We want to establish this when we use the +|\chap| or the |\sect| macro the first time. Furthermore the new page +at the begin of a main section should not be started at the first +|\chap| because a title may precede it (and the title should not +be on a seperate page unless explicitely requested). Instead a +skip of (approximately) 2~pica should be set. To achieve +both goals a macro |\chap_intro| is defined that defines |\thesection| +appropriately, skips the 2~pica, and redefines itself to +|\newpage|---we then just have to call |\chap_intro| at the beginning +of |\chap|. The same applies to |\sect_intro|. + +\beginprog +\newskip\pre_sect_skip \pre_sect_skip=2pc plus 1pc minus 6pt + +\def\chap_intro{% + \gdef\thesection{\arabic{section}.}% + \gdef\chap_intro{\bigbreak}% + \addvspace{\pre_sect_skip}% + } + +\def\sect_intro{% + \gdef\thesection{\arabic{section}.}% + \global\let\sect_intro\relax + } +\endprog + + +\sect Now we will have a look at the {\it wonderful\/} internal +interface of \LaTeX{}\@. With ``wonderful'' I mean that I'm always +full of wonder why it was designed in this way. E.g., if anybody +can explain to me why the coding of the non-indentation of the first +line in the following paragraph was combined with the coding of +the skip which will come in front of the section---I will be thankful +for the rest of my life. Such different things should be kept +different, i.e., the suppression of the indentation should not be +hidden in the sign of a skip! The same comment applies to the combined +coding of the skip below the section heading resp.\ to the right +of a run-in heading. + +\begin{quote} \it +I want the following layout: no indentation in the following +paragraph\/ {\rm but no} space in front of the section heading. +How do I code a value of\/ $\sl -0 pt$? +\end{quote} +% +Well, a work-around is to use a value of $\rm -1\,sp$ because the +reader will not see this distance---but in my opinions this is no +good programming style. In this special case I have luck, too: +the skip is not set anyway, either it is discarded by the preceding +|\newpage| or it is not added by |\addvspace| because of the preceding +|\pre_sect_skip|. + +\beginprog +\def\chap#1.{% + \chap_intro + \@startsection{section}{1}% + {\z@}% + {\m@ne sp}% + {\medskipamount}% + {\normalsize\bf}% + {#1.}% + } +\endprog + + +\sect Normal sections are started with |\sect|. This macro has no +parameter. Between two paragraphs we skip |\pre_sect_skip|. +Between the section number and the text one quad of space is set. +We have to take care for empty documentation parts where the +program part (i.e.\ |\beginprog|) will follow immediately. Then +the program part should begin on a new line and not behind the +section number. So we provide |\null| as an empty documentation +part in every case. + +Now again the design of |\@startsection| comes in hand: \LaTeX{} +always leaves a quad after the section number (by the way, +this is not mentioned in the documentation---you have to look +in the macros to figure this out). Because our section header +consists only of the number we have to code a value of $\rm +-0\,pt$\,\dots + +\begin{quote} +Again: {\it non-orthogonal design is bad design}. +\end{quote} + +\beginprog +\def\sect{% + \sect_intro + \@startsection{section}{1}% + {\z@}% + {\pre_sect_skip}% + {\m@ne sp}% + {\normalsize\bf}% + {\null}% + } +\endprog + +\sect Finally, the |newsloppy| environment. As pointed out by +Frank Mittelbach, {\LaTeX}'s |\sloppy| environment is just a +little too sloppy. The tolerence value with which it allows {\TeX} to +break at is considered infinite. Using a value just short of this +improves output considerably. + +\beginprog + \newcount\pl_tolerance \pl_tolerance = 9999 + \newenvironment{newsloppy}% + {\begingroup\tolerance\pl_tolerance}% + {\endgroup} +\endprog + +\sect We are finished and just have to restore the category code. + +\beginprog +\catcode`\_=\uscode + +\endinput +\endprog + + + + + +\end{document} diff --git a/macros/latex209/contrib/chbars/progltx.sty b/macros/latex209/contrib/chbars/progltx.sty new file mode 100644 index 0000000000..96f1129a32 --- /dev/null +++ b/macros/latex209/contrib/chbars/progltx.sty @@ -0,0 +1,774 @@ +% This is PROGLTX.DOC as of 25 May 90 +%--------------------------------------------------------- +% (c) 1989,1990 by J.Schrod. copy conditions see below + +% +% Macro package for the documentation of programs +% LaTeX style option +% MAKEPROG is needed +% + +% +% DATE PERSON REMARK +% 92-01-15 rlb add newsloppy environment (based on comment by +% Frank Mittlebach. Don't force a \newpage in +% Chapters, Just put a bigger space there. +% 89-11-18 js repaired the handling of `|' (verbatim and \index). +% 89-10-05 js first version (for TeX89) +% + +% author's current address: +% +% Detig$\,\cdot\,$Schrod \TeX{}sys +% Joachim Schrod +% Kranichweg 1 +% +% D-6074 R\"odermark-Urberach +% FR Germany +% +% Tel. (+6074) 1617 +% Bitnet: XITIJSCH@DDATHD21 + + + +% documented with itself... +%%%% +%%%% +%%%% These TeX macros were documented with the documentation system +%%%% MAKEPROG and automatically converted to the current form. +%%%% If you have MAKEPROG available you may transform it back to +%%%% the original input: Remove every occurence of three percents +%%%% and one optional blank from the beginning of a line and remove +%%%% every line which starts with four percents. The following lex +%%%% program will do this: +%%%% +%%%% %% +%%%% +%%%% ^%%%\ ? ; +%%%% ^%%%%.*\n ; +%%%% +%%%% MAKEPROG may be obtained over the net from the Bitnet-Listserver +%%%% LISTSERV@DHDURZ1 (filelist WEBWARE), from tuglib@science.utah.edu, +%%%% or via ftp from june.cs.washington.edu. +%%%% +%%%% +%%% \documentstyle[progltx]{article} + + +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% % +%%% % local macros +%%% % + +%%% \let\mc=\small % for names like GNU + +%%% \def\WEB{{\tt WEB\/}} +%%% \def\GNU{{\mc GNU}} + +%%% % +%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%% \begin{document} + + +%%% \title{ +%%% Documenting programs in a \WEB{} style\\ +%%% The {\tt progltx\/} style option +%%% } +%%% \author{\sc Joachim Schrod} + +%%% \maketitle + + +%%% \chap Introduction. + +%%% \WEB{} systems allow the documentation of programs by supporting the +%%% separation in program fragments which can be collected and rearranged +%%% afterwards. This allows {\it top-down\/} programming as well as the +%%% {\it bottom-up\/} design of programs. Each program fragment can be +%%% documented, usually with \TeX{}\@. A disadvantadge is that \WEB{} +%%% actually exists only for a few programming languages (Pascal, C, +%%% Modula-2). Besides, building up \WEB{} systems for ``exotic'' +%%% programming languages like \TeX{} is very difficult. + +%%% This macro package was built to allow good documentation for programs +%%% in languages for which \WEB{} doesn't exist. It separates a program +%%% text in sections that can be documented. All sections, collected +%%% sequentially, will result in the complete program. In every section +%%% begin and end of the program part are marked with |\beginprog| and +%%% |\endprog|, this program part will be formatted as it is input +%%% (``verbatim''). + +%%% Originally these macros were written for the usage with Plain \TeX{} +%%% resp.\ on top of the \WEB{} macro package |webmac.tex|. But often the +%%% requirement has been told to me that a \LaTeX{} version would be +%%% useful, too---well, here it is. But even with \LaTeX{} I have decided +%%% that still |\beginprog| and |\endprog| must be used for the markup of +%%% the program parts, not |\begin{prog}| or |\end{prog}| which would be +%%% more ``\LaTeX{}-like.'' The reason behind this is that I didn't want +%%% to maintain two versions of the {\mc MAKEPROG\/} processor---but {\mc +%%% MAKEPROG\/} wants to see the non-\LaTeX{}-like macros. But everybody +%%% is encouraged to change it by themselves (it is {\it very\/} easy). + +%%% The user of these macros may use the usual sectioning macros of +%%% \LaTeX{} for structuring his documentation. Additionally we provide a +%%% |progdoc|-compatible (i.e.\ \WEB{}-like) markup with the two macros +%%% |\chap| and |\sect|. + +%%% In the documentation part of a section text pieces, e.g.\ names of +%%% variables, can be inserted verbatim to demonstrate the connection to +%%% the program text. These parts are included in vertical bars +%%% (`{\tt\vbar}') This makes this style option extremely useful if your +%%% identifiers (or your file names) include characters which would be +%%% special characters for \TeX{} otherwise. (One example of these +%%% program languages is \TeX{} itself, but just enclose the macro names +%%% in vertical bars and {\tt \vbar|\relax|\vbar}.) + +%%% The macros |\makevertother| and |\makevertactive| are available to +%%% activate and deactivate the special behaviour of the vertical bar but +%%% these macros should be needed seldom because the usual cases as the +%%% usage within |verbatim| and |tabular| environments or |\index| macros +%%% etc.\ are handled. + +%%% If a vertical bar must be used in the original fashion you can use two +%%% command sequences: |\origvert| holds the meaning of the vertical bar +%%% at the time this macro file was read in and |\vbar| is the character +%%% with the {\mc ASCII\/} code of the vertical bar (i.e.~|"EC|) in the +%%% current font. + +%%% The new notion of |\verb| must not be used within parameters of +%%% macros, e.g.\ in the argument of |\section| etc.---it will result in +%%% an error message by \TeX{}\@. Furthermore within the preamble of a +%%% |tabular|, an |array| environment, or the |\multicolumn| command the +%%% vertical bar has the same meaning as before. (That means within +%%% |@{|\ldots|}| it is an ordinary character and otherwise it specifies a +%%% vertical rule between the columns. + +%%% This macro package does not offer the automatic creation of an index +%%% because it is not known which syntactical tokens the language has that +%%% should be mentioned in an index. But of course all \LaTeX{} stuff like +%%% |\index|, |\tableofcontents|, etc.\ may be used. + + +%%% \sect This program is free software; you can redistribute it and/or +%%% modify it under the terms of the \GNU{} General Public License as +%%% published by the Free Software Foundation; either version~1, or (at your +%%% option) any later version. + +%%% This program is distributed in the hope that it will be useful, but +%%% {\bf without any warranty\/}; without even the implied warranty of +%%% {\bf merchantability\/} or {\bf fitness for a particular purpose}. See +%%% the \GNU{} General Public License for more details. + +%%% You should have received a copy of the \GNU{} General Public License +%%% along with this program; if not, write to the Free Software Foundation, +%%% Inc., 675~Mass Ave, Cambridge, MA~02139, USA. + + +%%% \sect We have to realize three parts: (1)~the formatting of rather +%%% small verbatim texts in a line, (2)~the formatting of larger parts of +%%% program and (3)~the document structuring elements for the separation +%%% of the sections. + +%%% \begin{sloppypar} +%%% Before we start we declare some shorthands for category codes. By +%%% declaring the underscore~`(|_|)' as a letter we can use it in our +%%% macros names. (I agree with D.~Knuth that +%%% |\identifier_several_words_long| is more readable than +%%% |\IdentifierSeveralWordsLong| and in every case better than +%%% |\p@@@s|.) But as we have to restore the category codes at the end +%%% of this macro file we store its former value in the control +%%% sequence |\uscode|. This method is better than the usage of a +%%% group because not all macros have to be defined global this way. +%%% \end{sloppypar} + +%%% \beginprog +\chardef\escape=0 +\chardef\open=1 +\chardef\close=2 +\chardef\letter=11 +\chardef\other=12 +%\chardef\active=13 % is defined in Plain already + +\chardef\uscode=\catcode`\_ + +\catcode`\_=\letter +%%% \endprog + + + + +%%% \chap Local Verbatim Formatting. + +%%% The main point of every verbatim formatting is the switching of the +%%% character codes of all characters that have a special \TeX{} meaning. +%%% This can be done with the control sequence |\dospecials| that applies +%%% the control sequence |\do| to all special characters. Additionally, +%%% every line is regarded as a paragraph without indentation. Between +%%% two paragraphs, i.e.\ between two lines, no extra space is set. +%%% Finally all blanks and tabular characters shall be obeyed and the +%%% inter word space after sentence terminators shall not be enlarged. +%%% The activation of the tabular characters with |\obeytabs| is +%%% equivalent to |\obeyspaces| in {\tt plain.tex}. + +%%% \begin{sl} +%%% As a matter of fact, I would like to use the character set with the +%%% extended {\mc ASCII} (like in\/ \WEB{}) for setting the verbatim texts +%%% in monospace. But then I must code many\/ |\@getfont|'s\,\dots +%%% \end{sl} + +%%% \beginprog +%\font\tentex=cmtex10 % typewriter extended ASCII 10pt +%\let\ttex=\tentex % only with base size 10pt +\def\ttex{\tt} % as a substitute + +\def\setup_verbatim{% + \def\do##1{\catcode`##1\other}\dospecials + \parskip\z@skip \parindent\z@ + \catcode`\`\active \@noligs + \obeylines \@vobeyspaces \obeytabs \frenchspacing + \ttex + } + +\let\tab=\space +\begingroup + \catcode`\^^I=\active% % Attention: no tabs! + \gdef\obeytabs{\catcode`\^^I=\active\def^^I{\tab}} + \global\let^^I=\tab% % if an active tab appears in a \write +\endgroup +%%% \endprog + + +%%% \sect After having saved the old meaning of `{\tt\vbar}' in +%%% |\origvert| and after declaring |\vbar| as a synonym for the character +%%% that has the code of a vertical bar in the actual font, the vertical +%%% bar can be made active. Then we call |\setup_verbatim|. But the +%%% newline characters shall not be processed, they shall be regarded like +%%% blank space. This can be reached by defining |\par| as |\space|. + +%%% The next vertical bar in the input closes the group which becomes an +%%% (unbreakable) |\hbox| then. The old meanings of the special +%%% characters and of the vertical bar are restored and \TeX{} is in +%%% normal (horizontal) mode again. + +%%% \beginprog +\let\origvert=| +\chardef\vbar=`\| + +\def\makebaractive{\catcode`\|\active} +\def\makebarother{\catcode`\|\other} +\makebaractive + +\def|{% + \leavevmode + \hbox\bgroup + \let\par\space \setup_verbatim + \let|\egroup + } +%%% \endprog + + +%%% \sect A problem with this definition of the vertical bar is that +%%% the bar is not a normal character any more but there exists situations +%%% where the \LaTeX{} macros assumes this: +%%% % +%%% \begin{itemize} + +%%% \item In a |verbatim| environment a vertical bar must be typeset if it +%%% occurs in the input. + +%%% \item In a |tabular| or an |array| environment a vertical bar is used +%%% to denote rules between columns in the table. These environments must +%%% be started with a parameter which is a ``preamble,'' the same preamble +%%% construction is used to specify the format of multi-column entries. + +%%% \item In an output of an index entry the vertical bar must not result +%%% in an error message. Usually index entries are typeset in a seperate +%%% \TeX{} run where |idverb| is not used as a style option and the +%%% vertical bar is therefore useful. This is no problem in section +%%% headings or captions etc. Because they take their argument as a +%%% parameter in every case the vertical bar can never be used there. But +%%% |\origvert| resp.\ |\vbar| may be used there. + +%%% \end{itemize} +%%% % +%%% In the next sections we handle each of these problems. + + +%%% \sect Before we start a |verbatim| environment we just redefine the +%%% vertical bar as an ordinary character. Because this is within the +%%% environment grouping the end of the environment will reestablish the +%%% special meaning. + +%%% \beginprog +\let\@@verbatim=\@verbatim +\def\@verbatim{% + \makebarother + \@@verbatim + } +%%% \endprog + + +%%% \sect Special care is needed in the |tabular| and the |array| +%%% environment. Both environments are begun by one macro (|\@tabarray|), +%%% we redefine it so that the bar can be used in the preamble +%%% specification. The same problem occurs in |\multicolumn|, it is +%%% solved the same way. After the preamble construction (with +%%% |\@mkpream|) the special meaning of the bar can be switched on +%%% again---this allows the usage of the new meaning in the body of a +%%% table. + +%%% Of course this mean that the ``verbatim identifier'' facility can +%%% not be used within a preamble of a table. Furthermore it can not +%%% be used within the |\multicolumn| statement, neither in the +%%% preamble part (the second parameter) nor within the text part (the +%%% third parameter). + +%%% \beginprog +\let\@@tabarray=\@tabarray +\def\@tabarray{% + \makebarother + \@@tabarray + } + +\def\multicolumn#1{% + \multispan{#1}% + \begingroup + \makebarother + \restof_multicolumn + } +\def\restof_multicolumn#1#2{% + \@mkpream{#1}% + \def\@sharp{#2}% + \let\protect\relax + \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox + \@arstrut \@preamble + \endgroup + \ignorespaces + } + +\let\@@mkpream=\@mkpream +\def\@mkpream#1{% + \@@mkpream{#1}% + \makebaractive + } +%%% \endprog + + +%%% \sect Before an index entry is scanned almost all special characters +%%% are transformed into ordinary characters. The only exceptions are the +%%% opening and the closing brace because they are needed to delimit the +%%% argument. This transformation is done with |\@sanitize|, this macro +%%% must be called within a group. We just append the transformation of +%%% the vertical bar. + +%%% \beginprog +\begingroup + \def\@makeother{\noexpand\@makeother\noexpand} + \xdef\@sanitize{\@sanitize\@makeother\|} +\endgroup +%%% \endprog + + + + +%%% \chap Fragments in Verbatim. + +%%% We need macros to format the program fragments without any +%%% linebreaking. Such a text area shall start with the macro +%%% |\beginprog| and end with |\endprog|, i.e.\ as a kind of a +%%% |prog|-environment. The macro |\endprog| must stand at the very +%%% beginning of a line and must be followed by white space (blank, tab or +%%% newline character). After |\beginprog| as well as after +%%% |\endprog| the rest of the line is ignored. + +%%% Two demands must be regarded: There should be no length restrictions +%%% for the processed text, and the tabular characters should be expanded +%%% so that this macro works on PC's and on VAXes etc., too. + + +%%% \sect The implementation method is quite simple: We read the next +%%% line, test, wether the end is reached (by comparing with the end line) +%%% and otherwise set the line actually read. Every character is +%%% inspected and tabular characters are expanded. + +%%% The verbatim text is started with |\begin_verbatim| which will be +%%% either called by |\beginprog| or by |\beginverbatim|. These macros +%%% will also define the contents of the end line. + +%%% Whether a line is set or whether the end of the processed area is +%%% reached is indicated by the switch |\if@print|. At the beginning of +%%% the |\begin_verbatim| macro most settings are done with +%%% |\setup_verbatim| (the vertical bar must be handled separately) +%%% and the rest of the line is ignored. As everything is done within +%%% a group, the end of the verbatim text can be processed by simply +%%% closing this group. + +%%% For the user it looks as if |\endprog| or |\endverbatim| +%%% terminates the processing, but it just serves for the +%%% identification of the end, the true processing is done with the +%%% internal macro |\end_verbatim|. + +%%% \beginprog +\newif\if@print + +\def\begin_verbatim{% + \endgraf + \bigbreak + \begingroup + \setup_verbatim \makebarother + \@printtrue + \ignore_rest_line + } +\let\end_verbatim=\endgroup % internal command ! +%%% \endprog + + +%%% \sect {\sloppy +%%% The first line is ignored, all the other lines are identified with +%%% |\set_next_line| and processed with |\do_set|. This separation in +%%% identification and processing allows that the line end character is +%%% active in the definition only for a short time. +%%% \par} + +%%% When a line is to be formatted, we first check with |\check_print| +%%% wether it contains the end line, otherwise it is printed with +%%% |\print_char|. The printing must be done for every character +%%% individually because we want to check for tabular characters; the +%%% exact algorithm is described below. Here we just have to note that +%%% |\print_char| is used with two parameters of which the second one is +%%% finished with the token |\end_line|. The first parameter is the first +%%% character of the line, the second parameter is the rest of the line. +%%% If the line is empty, the argument of |\do_set| is empty, too; so the +%%% activation of |\print_char| must be finished with two |\end_line|. +%%% Then the first |\end_line| is the first argument for |\print_char| and +%%% the second argument is empty. But if the line did contain something, +%%% the second |\end_line| is evaluated, for this case it is defined as +%%% |\relax|. + +%%% At last we call |\set_next_line| again to format the next line. If +%%% the end is reached, i.e.\ if the sample line was found, +%%% |\set_next_line| will be redefined as |\relax|. This can be done +%%% because the original meaning is restored while closing the group +%%% with |\end_verbatim|. + +%%% \beginprog +\begingroup + \obeylines% % ^^M is active! ==> every line must end with % + \gdef\ignore_rest_line#1^^M{\set_next_line}% + \gdef\set_next_line#1^^M{\do_set{#1}}% +\endgroup + +\def\do_set#1{% + \endgraf + \check_print{#1}% + \if@print \indent \print_char#1\end_line\end_line + \else \let\set_next_line\end_verbatim + \fi + \set_next_line + } +\let\end_line=\relax +%%% \endprog + + +%%% \sect {\sloppy +%%% Before we look at the problem of formatting a line, we declare +%%% |\check_print| that checks the end of the verbatim mode. We have to +%%% do two things: we must split everything in front of the first blank +%%% or tabular character and compare for identity with |\endprog|. The +%%% splitting is easy because the line which is our first argument +%%% contains blanks and tabulators as active characters. First we call +%%% |\cut_at_tab| that demands a tabular character as separator for its +%%% two pramenters so that everything in the line in front of the first +%%% tabulator is part of the first parameter. If there is no tabular +%%% character in the line, we append one so that the second parameter is +%%% empty. The same trick is used to separate the part in front of the +%%% first blank character from the resulting first part. +%%% \par} + +%%% The check is done with |\do_check|. We use a separate macro here so +%%% that we can indent it (in the following definition blanks are active!) + +%%% \beginprog +\begingroup +\obeyspaces\obeytabs +\gdef\check_print#1{\cut_at_tab#1^^I\end_line} +\gdef\cut_at_tab#1^^I#2\end_line{\check_first_part#1 \end_line}% blank ! +\gdef\check_first_part#1 #2\end_line{\do_check{#1}} +\endgroup +%%% \endprog + + +%%% \sect +%%% \begin{sloppypar} +%%% |\do_check| compares the line with a sample line that is +%%% available in |\end_verbatim_line|. This macro will be defined later. +%%% \end{sloppypar} + +%%% \beginprog +\def\do_check#1{% + \def\@line{#1}% + \ifx \@line\end_verbatim_line \@printfalse + \fi + } +%%% \endprog + + +%%% \sect Now we can set a line: we start with the first character, +%%% followed by the rest of the line. Each character is counted in +%%% |\char_count|. At the beginning of a line |\char_count| is~0, this +%%% is reset at the end of the line. + +%%% \beginprog +\newcount\char_count \char_count\z@ + +\def\print_char#1#2\end_line{% + \print_first_char{#1}% + \print_rest_of_line{#2}% + } +%%% \endprog + + +%%% \sect For each character that is set |\char_count| is incremented. +%%% If a character is a tabulator, we set with |\print_tab| the fitting +%%% amount of blank characters, otherwise the character itself. We must +%%% compare the character that is stored in |\@char| with a macro of which +%%% the ``first-level'' expansion is an active tabulator. For this case +%%% we declare |\@tab|. + +%%% \beginprog +{\obeytabs\gdef\@tab{^^I}} + +\def\print_first_char#1{% + \def\@char{#1}% + \advance \char_count\@ne + \ifx \@char\@tab \print_tab + \else \@char + \fi + } +%%% \endprog + + +%%% \sect If we want to fill the line with blank spaces up to the next +%%% column with a number that can be divided by~8, we must be able to +%%% compute the column number modulo~8, but \TeX{} has no modulo operator. +%%% So we define the macro |\mod_viii| that computes its argument modulo~8 +%%% and returns the result in the counter |\count_mod_viii|. For the +%%% computation we need the temporary counter |\count@|. + +%%% \beginprog +\newcount\count_mod_viii +\def\mod_viii#1{% + \count@ #1\relax \count_mod_viii\count@ + \divide \count@ 8\relax + \multiply \count@ 8\relax + \advance \count_mod_viii -\count@ + } +%%% \endprog + + +%%% \sect Now we can declare |\print_tab|. We must remember that +%%% |\char_count| was incremented already, if we set only one blank +%%% character the counter keeps untouched. + +%%% \beginprog +\def\print_tab{% + \loop \space \mod_viii\char_count + \ifnum \count_mod_viii>\z@ + \advance \char_count\@ne + \repeat + } +%%% \endprog + + +%%% \sect If the rest of the line is empty, we are ready. |\char_count| +%%% is reset to~0 for the next line. + +%%% Inside the |\else| part of |\ifx| |\print_char| should not be used +%%% directly because this costs too much storage of \TeX{}\@. Instead we +%%% set a control sequence |\next| that is processed afterwards, depending +%%% on the result of the comparison. (This tail recursion will be +%%% discovered by \TeX{} and handled appropriately.) If there is still +%%% something to set, we use |\print_char| again, otherwise a +%%% syntactically similar macro that expands to |\relax|. + +%%% \beginprog +\def\print_rest_of_line#1{% + \def\@line{#1}% + \ifx \@line\empty \char_count\z@ + \def\next##1\end_line{\relax}% + \else \let\next\print_char + \fi + \next#1\end_line + } +%%% \endprog + + +%%% \sect {\sloppy +%%% Now we are ready to define the two ``user accessible'' macros +%%% |\beginprog| and |\beginverbatim|. They must define the prototyp end +%%% line |\end_verbatim_line| which will be compared against every line +%%% in the verbatim text. During the definition of +%%% |\end_verbatim_line| it must be cared for that the escape character~`|\|' +%%% is a printable character: A comparison with |\ifx| demands identical +%%% category codes. As a temporary escape character we use the slash. +%%% \par} + +%%% \beginprog +{\catcode`\/=\escape % / is temporary escape char + \catcode`\\=\other + /gdef/beginprog{% + /gdef/end_verbatim_line{\endprog}% + /begin_verbatim + } + /gdef/beginverbatim{% + /gdef/end_verbatim_line{\endverbatim}% + /begin_verbatim + } +} % here \endgroup can't be used +%%% \endprog + + + + +%%% \chap Document Structuring. + +%%% In addition to the normal \LaTeX{} structuring markups we will +%%% provide a markup for a layout of the document that is like in +%%% \WEB{}. This can be done easily. All sections are numbered, the +%%% number of the next section is stored in the counter |section|. We +%%% distinguish between main sections which start a group of sections +%%% and between normal sections within a group. + +%%% The main sections are started with the macro |\chap|. It has one +%%% parameter, the title of the section group. This parameter must be +%%% terminated by a dot. We start a new page, typeset the title in +%%% bold face and separate it from the section text with a |\medskip|. +%%% This text, the documentation part of the section, is formatted +%%% without paragraph indentation. + +%%% If the \WEB{}-like macros are used every section number should be +%%% output with a following dot. We want to establish this when we use the +%%% |\chap| or the |\sect| macro the first time. Furthermore the new page +%%% at the begin of a main section should not be started at the first +%%% |\chap| because a title may precede it (and the title should not +%%% be on a seperate page unless explicitely requested). Instead a +%%% skip of (approximately) 2~pica should be set. To achieve +%%% both goals a macro |\chap_intro| is defined that defines |\thesection| +%%% appropriately, skips the 2~pica, and redefines itself to +%%% |\newpage|---we then just have to call |\chap_intro| at the beginning +%%% of |\chap|. The same applies to |\sect_intro|. + +%%% \beginprog +\newskip\pre_sect_skip \pre_sect_skip=2pc plus 1pc minus 6pt + +\def\chap_intro{% + \gdef\thesection{\arabic{section}.}% + \gdef\chap_intro{\bigbreak}% + \addvspace{\pre_sect_skip}% + } + +\def\sect_intro{% + \gdef\thesection{\arabic{section}.}% + \global\let\sect_intro\relax + } +%%% \endprog + + +%%% \sect Now we will have a look at the {\it wonderful\/} internal +%%% interface of \LaTeX{}\@. With ``wonderful'' I mean that I'm always +%%% full of wonder why it was designed in this way. E.g., if anybody +%%% can explain to me why the coding of the non-indentation of the first +%%% line in the following paragraph was combined with the coding of +%%% the skip which will come in front of the section---I will be thankful +%%% for the rest of my life. Such different things should be kept +%%% different, i.e., the suppression of the indentation should not be +%%% hidden in the sign of a skip! The same comment applies to the combined +%%% coding of the skip below the section heading resp.\ to the right +%%% of a run-in heading. + +%%% \begin{quote} \it +%%% I want the following layout: no indentation in the following +%%% paragraph\/ {\rm but no} space in front of the section heading. +%%% How do I code a value of\/ $\sl -0 pt$? +%%% \end{quote} +%%% % +%%% Well, a work-around is to use a value of $\rm -1\,sp$ because the +%%% reader will not see this distance---but in my opinions this is no +%%% good programming style. In this special case I have luck, too: +%%% the skip is not set anyway, either it is discarded by the preceding +%%% |\newpage| or it is not added by |\addvspace| because of the preceding +%%% |\pre_sect_skip|. + +%%% \beginprog +\def\chap#1.{% + \chap_intro + \@startsection{section}{1}% + {\z@}% + {\m@ne sp}% + {\medskipamount}% + {\normalsize\bf}% + {#1.}% + } +%%% \endprog + + +%%% \sect Normal sections are started with |\sect|. This macro has no +%%% parameter. Between two paragraphs we skip |\pre_sect_skip|. +%%% Between the section number and the text one quad of space is set. +%%% We have to take care for empty documentation parts where the +%%% program part (i.e.\ |\beginprog|) will follow immediately. Then +%%% the program part should begin on a new line and not behind the +%%% section number. So we provide |\null| as an empty documentation +%%% part in every case. + +%%% Now again the design of |\@startsection| comes in hand: \LaTeX{} +%%% always leaves a quad after the section number (by the way, +%%% this is not mentioned in the documentation---you have to look +%%% in the macros to figure this out). Because our section header +%%% consists only of the number we have to code a value of $\rm +%%% -0\,pt$\,\dots + +%%% \begin{quote} +%%% Again: {\it non-orthogonal design is bad design}. +%%% \end{quote} + +%%% \beginprog +\def\sect{% + \sect_intro + \@startsection{section}{1}% + {\z@}% + {\pre_sect_skip}% + {\m@ne sp}% + {\normalsize\bf}% + {\null}% + } +%%% \endprog + +%%% \sect Finally, the |newsloppy| environment. As pointed out by +%%% Frank Mittelbach, {\LaTeX}'s |\sloppy| environment is just a +%%% little too sloppy. The tolerence value with which it allows {\TeX} to +%%% break at is considered infinite. Using a value just short of this +%%% improves output considerably. + +%%% \beginprog + \newcount\pl_tolerance \pl_tolerance = 9999 + \newenvironment{newsloppy}% + {\begingroup\tolerance\pl_tolerance}% + {\endgroup} +%%% \endprog + +%%% \sect We are finished and just have to restore the category code. + +%%% \beginprog +\catcode`\_=\uscode + +\endinput +%%% \endprog + + + + + +%%% \end{document} diff --git a/macros/latex209/contrib/chbars/test1.tex b/macros/latex209/contrib/chbars/test1.tex new file mode 100644 index 0000000000..92d2839ef8 --- /dev/null +++ b/macros/latex209/contrib/chbars/test1.tex @@ -0,0 +1,60 @@ +\input chbars + +\catcode`\@=\letter +\catcode`\_=\letter +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +Zeile 1 +\beginchange +Zeile 2 +\mark{Mark 1}% +\write 16{Ausgabe 1}% +Zeile 3 +\endchange +Zeile 4% +\mark{Mark 2}% +\mark{Mark 3} +\beginchange +Zeile 5 +\write 16{Ausgabe 2}% +Zeile 6 +\endchange +Zeile 7 +\beginchange +Zeile 8 +\write 16{Ausgabe 3}% +Zeile 9 +\endchange +Zeile 10 +\beginchange +Zeile 11 +\write 16{Ausgabe 4}% +Zeile 12 +\endchange +Zeile 13 +\beginchange +Zeile 14 +\write 16{Ausgabe 5}% +Zeile 15 +\endchange +Zeile 16 +\beginchange +Zeile 17 +\write 16{Ausgabe 6}% +Zeile 18 +\endchange +Zeile 19 + + +\bye diff --git a/macros/latex209/contrib/chbars/test2.tex b/macros/latex209/contrib/chbars/test2.tex new file mode 100644 index 0000000000..5dbdd4a17a --- /dev/null +++ b/macros/latex209/contrib/chbars/test2.tex @@ -0,0 +1,70 @@ +\input chbars + +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +Zeile 1 + +\beginchange + +Zeile 2 + +\mark{Mark 1}% +\write 16{Ausgabe 1}% + +Zeile 3 + +\endchange + +Zeile 4 + +\mark{Mark 2}% + +\mark{Mark 3}% + +\beginchange + +Zeile 5 + +\write 16{Ausgabe 2}% + +Zeile 6 + +\endchange + +Zeile 7 + + +\beginchange + +Zeile 8 + +\write 16{Ausgabe 3}% + +Zeile 9 + +\endchange + +Zeile 10 + +\beginchange + +Zeile 11 + +\write 16{Ausgabe 4}% + +Zeile 12 + +\endchange + +\bye diff --git a/macros/latex209/contrib/chbars/test3.tex b/macros/latex209/contrib/chbars/test3.tex new file mode 100644 index 0000000000..1f08fa6b98 --- /dev/null +++ b/macros/latex209/contrib/chbars/test3.tex @@ -0,0 +1,84 @@ +\message{--Starting test 3--} +%%% Test redefinition of \output +\output={\message{==output here==}\plainoutput} +\input chbars +\chardef\uscode=\catcode`\_ +\catcode`\@=\letter +\catcode`\_=\letter +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +\changebarwidth=1.1pt % Set the default size to 1.1pt +\chbarRighttrue % do the margins on the right +Zeile 1 + +\beginchange[2pt] % Test giving an option +Zeile 2 +\mark{Mark 1}% +\write 16{Ausgabe 1}% +Zeile 3 +\endchange + +Zeile 4% +\mark{Mark 2}% +\mark{Mark 3} + +\beginchange[0.4pt] % Now try another size +Zeile 5 +\write 16{Ausgabe 2}% +Zeile 6 +\endchange + +Zeile 7 +\beginchange +Zeile 8 +\write 16{Ausgabe 3}% +Zeile 9 +\endchange +Zeile 10 +\beginchange +Zeile 11 +\write 16{Ausgabe 4}% +Zeile 12 +\endchange +Zeile 13 +\beginchange +Zeile 14 +\write 16{Ausgabe 5}% +Zeile 15 +\endchange +Zeile 16 +\beginchange +Zeile 17 +\write 16{Ausgabe 6}% +Zeile 18 +\endchange +Zeile 19 +\beginchange +Zeile 20 +\write 16{Ausgabe 6}% Test of change bars spanning newpage +\np +Zeile 21 +\endchange + +\changebarwidth=3pt +\beginchange +Zeile 22 +\endchange + +Next to last paragraph. +\np % No pagemarks across here + +One more line on the next page. + +\bye diff --git a/macros/latex209/contrib/chbars/test4.aux b/macros/latex209/contrib/chbars/test4.aux new file mode 100644 index 0000000000..84c3d38c0d --- /dev/null +++ b/macros/latex209/contrib/chbars/test4.aux @@ -0,0 +1,3 @@ +\relax +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {1}test}{1}} +\@writefile{toc}{\string\contentsline\space {section}{\string\numberline\space {2}test2}{2}} diff --git a/macros/latex209/contrib/chbars/test4.ltx b/macros/latex209/contrib/chbars/test4.ltx new file mode 100644 index 0000000000..73a3ef0de9 --- /dev/null +++ b/macros/latex209/contrib/chbars/test4.ltx @@ -0,0 +1,86 @@ +\documentstyle[chbars]{article} +\begin{document} +\catcode`\@=\letter +\catcode`\_=\letter +\hsize=2in \vsize=3in +\tolerance=10000 \hbadness=10000 +\def\nl{\unskip \hfill \break} +\def\np{% + \ifhmode \vadjust \fi + {% + \vfill \eject + }% + } + +\tracingall \tracingonline=0 +\tracingparagraphs=0 + +\section{test} + +\changebarwidth=1.1pt % Set the default size to 1.1pt +Zeile 1 + +\beginchange[2pt] % Test giving an option +Zeile 2 +\mark{Mark 1}% +\write 16{Ausgabe 1}% +Zeile 3 +\endchange + +Zeile 4% +\mark{Mark 2}% +\mark{Mark 3} + +\beginchange[0.4pt] % Now try another size +Zeile 5 +\write 16{Ausgabe 2}% +Zeile 6 +\endchange + +Zeile 7 +\beginchange +Zeile 8 +\write 16{Ausgabe 3}% +Zeile 9 +\endchange +Zeile 10 +\beginchange +Zeile 11 +\write 16{Ausgabe 4}% +Zeile 12 +\endchange +Zeile 13 +\beginchange +Zeile 14 +\write 16{Ausgabe 5}% +Zeile 15 +\endchange +Zeile 16 +\beginchange +Zeile 17 +\write 16{Ausgabe 6}% +Zeile 18 +\endchange +Zeile 19 +\beginchange +Zeile 20 +\write 16{Ausgabe 6}% Test of newpage +\np +Zeile 21 +\endchange + +\chbarRighttrue % do the margins on the right +\changebarwidth=3pt +\beginchange +Zeile 22 +\endchange + +One last paragraph before the new section. + +\beginchange\section{test2}\endchange + +Last section and quit + +\end{document} + + |