summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/localloc/localloc.dtx
blob: ad770b5d85a924d33306e31d66b242c369ae42e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
% \iffalse
%
% Package `localloc' to use with LaTeX 2e/2.09 and plain-TeX
% Copyright (C) 1991,1994,1995 Bernd Raichle.  All rights reserved.
%
%
% Copying of this file is authorized only if either
% (1) you make absolutely no changes to your copy, including name, or
% (2) if you do make changes, you name it something other than
%     localloc.dtx, localloc.doc, localloc.tex, or localloc.sty.
% This restriction helps ensure that all styles developed here
% remain identical.
%
% Error reports in case of UNCHANGED versions please to:
%        Bernd Raichle
%        Stettener Str. 73
%        D-73732 Esslingen
%        Federal Republic of Germany
% Email: raichle@Informatik.Uni-Stuttgart.DE
%
%
% ========== INSTALLATION GUIDE: ==========
%
% The complete distribution consists of a set of files, which are
% packed and documented in _one_ `docstrip archive file' called
% `localloc.dtx' (the file you are currently reading).  This archive
% file can be unpacked to create the necessary files containing the
% macros, documentation, etc.
%
% To unpack the archive file you need:
%
%   * `localloc.dtx' (it is the file you are currently reading)
%
%   * `docstrip.tex' version 2.x or newer
%     (You can find this file in the LaTeX 2e release.)
%
% Then run `localloc.dtx' through plainTeX or LaTeX to unpack the
% archive file:
%
%     tex localloc.dtx
% or
%     latex localloc.dtx
%
% This will create a set of file which contain the macro code or
% code to produce the documentation of the `localloc' package.
%
% --------------- start of docstrip archive file ------------------
% \fi
%
% \CheckSum{369}
%
% \iffalse
%<*install>
\def\batchfile{localloc.dtx}
\input docstrip.tex
\preamble

This is a file of the `localloc' package reimplementing
plain-TeX's and LaTeX's basic allocation macros to allow
local allocation of registers.

-- Copyright (C) 1991-1995 Bernd Raichle.  All rights reserved --

This package 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.


IMPORTANT NOTICE:

Copying of this file is authorized only if either
(1) you make absolutely no changes to your copy, including name, or
(2) if you do make changes, you name it something other than
    localloc.dtx, localloc.doc, localloc.tex, or localloc.sty.

For error reports see original source file `localloc.dtx'.

\endpreamble
%\generateFile{localloc.ins}{t}{\from{localloc.dtx}{install}}
\generateFile{localloc.sty}{t}{\from{localloc.dtx}{package}}
\generateFile{localloc.drv}{t}{\from{localloc.dtx}{driver}}
\generateFile{localtst.tex}{t}{\from{localloc.dtx}{test}}

\Msg{***********************************************************}
\Msg{*}
\Msg{* To finish the installation you have to move the following}
\Msg{* file into a directory searched by TeX:}
\Msg{*}
\Msg{* \space\space localloc.sty}
\Msg{*}
\Msg{* To produce the documentation of this archive file run the}
\Msg{* file `localloc.drv' through LaTeX 2e:}
\Msg{*}
\Msg{* \space\space latex localloc.drv}
\Msg{*}
\Msg{* Happy TeXing}
\Msg{***********************************************************}
\relax\endinput
%</install>
% \fi
%
% \changes{v1.1b}{95/09/24}{Released after a long sleep in my
%                archives; prefixed some tokens with \cs{lcllc@}.}
% \changes{v1.1a}{94/10/16}{English documentation; added support for
%                \LaTeXe; added self unpacking archive code.}
% \changes{v1.0b}{91/09/06}{Error in \cs{newinsert}: consecutive calls
%                return the same insertion register number.}
% \changes{v1.0a}{91/09/04}{All macros in {plain.tex} replaced.}
%
% \DoNotIndex{\fileversion,\filedate,\docdate,\filename}
% \DoNotIndex{\begingroup,\endgroup,\def,\relax}
% \DoNotIndex{\ifnum,\ifcase,\else,\fi}
% \DoNotIndex{\expandafter,\the}
% \DoNotIndex{\@ne,\m@ne,\next}
%
%
% \newcommand{\PiCTeX}{\protect\pPiCTeX}
% \newcommand{\pPiCTeX}{\relax
%     P\kern-.12em\lower.5ex\hbox{I}\kern-.075emC\kern-.11em\TeX}
%
%
% \title{An Enhanced Implementation of the Allocation Macros in \LaTeXe,
%    \LaTeX~2.09, and plain-\TeX}
% \date{\filedate~(\fileversion)}
% \author{Bernd Raichle\\
%         Stettener Str.~73\\
%         D-73732 Esslingen, FRG\\
%         Email: {\tt raichle@Informatik.Uni-Stuttgart.DE}}
%
% \maketitle
%
% \begin{abstract}
%   This style option reimplements the allocation command macros
%   provided by plain-\TeX\ and adds macros to allow allocation 
%   of local registers inside groups.
% \end{abstract} 
% 
%^^A \tableofcontents
%
% \section{Introduction}
%
% \subsection{Restrictions of {\tt plain.tex}'s Register Allocation Macros}
%
%  In {\tt plain.tex}, Donald E.\ Knuth writes about the macros for
%  register allocation~\cite[lines 149ff]{plain.tex-3.14159}: 
%  \begin{quote}
%    When a register is used only temporarily, it need not be
%    allocated;  grouping can be used, making the value previously in
%    the register return after the close of the group.  The main use
%    of these macros is for registers that are defined by one macro
%    and used by others, possibly at different nesting levels.  All
%    such registers should be defined through these macros; otherwise
%    conflicts may occur, especially when two or more more macro
%    packages are being used at once.
%  \end{quote}
%  Additional remarks can be read in the TeXbook~\cite[p.~346]{DEK91}:
%  \begin{quote}
%    {\it Allocation of registers.\/} The second major part of the
%    {\tt plain.tex} file provides a foundation on which systems of
%    independently developed macros can coexist peacefully without
%    interfering in their usage of registers. The idea is that macro
%    writers should abide by the macro conventions following ground
%    rules: [\ldots]
%    (4)~Furthermore, it's possible to use any register in a group, if
%    you ensure that \TeX's grouping mechanism will restore the
%    register when you're done with the group, and if you are certain
%    that other macros will not make global assignments to that
%    register when you need it. \
%    (5)~But when a register is used by several macros, or over long
%    spans of time, it should be allocated by \verb+\newcount+,
%    \verb+\newdimen+, \verb+\newbox+, etc. \ (6)~Similar remarks apply
%    [\ldots]
%    to insertions (which require \verb+\box+, \verb+\count+,
%    \verb+\dimen+, and \verb+\skip+ registers all having the same
%    number).
%  \end{quote}
%
%  This means, that within plain-\TeX\ and all formats based on
%  plain-\TeX\ a user can not allocate a register for temporary use
%  using the given mechanisms.  Nonetheless there is often the need
%  for a allocated register which is only used within a rather small
%  piece of document text and should be set free for reuse in the rest
%  of the formatting run:
%
%  If a macro~\verb+\macroa+ needs a register which should never be
%  destroyed by another macro~\verb+\macrob+ which is called by
%  \verb+\macroa+, you either have to know about the realisation of
%  \verb+\macrob+ or you have to allocate a new register.
%
%  The name of this newly allocated register is only known to the
%  macro package in which macro~\verb+\macroa+ resides.  If you have
%  a lot of macros which needs registers by their own it is possible
%  that all of the 256~registers of one type will be allocated.  In
%  most cases it would be possible to share some of these registers by
%  more than one macro because the register is only needed within (an
%  environment delimited by) a group.  To share registers---if they are
%  used only locally---it will be necessary to provide a mechanism to
%  allocate registers locally.  Unfortunately {\tt plain.tex} and all
%  derived formats, like \LaTeX, misses this mechanism leading to the
%  problem that some macro packages cannot be combined.
%
%  In the following example it is necessary to call two macros
%  |\macroa| and |macrob| in the same group (e.g.\ because |\macroa|
%  performs special actions at the begin and |\macrob| at the end of
%  an environment).  Further you do not have any knowledge about the
%  use of scratch register in |\macroa|, |\macrob| or the text in the
%  argument specified by the user.  Therefore it is impossible to use
%  a scratch register to save the current value of |\hsize|; we have
%  to allocate a new register to save it.
%\begin{verbatim}
%    \newdimen\savedhsize
%\end{verbatim}
%\begin{verbatim}
%    \def\callAandB#1{\begingroup
%        \savedhsize=\hsize
%        \hsize=0.8\hsize    \macroa
%        #1\relax
%        \hsize=\savedhsize  \macrob
%      \endgroup}
%\end{verbatim}
%  If there will be a mechanism, e.g. by a macro |\lnewdimen|, to
%  allocate a local register it is possible to use this local register
%  inside the group without worrying about possible dependencies
%  between the macros and the user specified text.  Additionally after
%  leaving the group, the dimen register will be free to be used by
%  other macros.
%\begin{verbatim}
%    \def\callAandB#1{\begingroup
%        \lnewdimen\savedhsize  \savedhsize=\hsize
%        \hsize=0.8\hsize    \macroa
%        #1\relax
%        \hsize=\savedhsize  \macrob
%      \endgroup}
%\end{verbatim}
%
%
% \subsection{Local Register Allocation Macros}
%
% \DescribeMacro{\newcount}
% \DescribeMacro{\newdimen}
% \DescribeMacro{\newskip}
% \DescribeMacro{\newbox}
% {\let\newinsert=\relax \DescribeMacro{\newinsert}}^^A
%  When using this reimplementation of the allocation macros, the {\tt
%  plain.tex} macros |\newcount|, |\newdimen|, |\newskip|, and
%  |\newbox| will have a changed behaviour in two aspects:
%  \begin{itemize}
%  \item Do not assume that registers which are allocated consecutively
%     have consecutive register numbers.  In general you should not
%     make any assumption about the order of register numbers.
%  \item It is possible that a register was locally allocated and used
%     in the past.  After leaving the group the register is set to free
%     and the old value---normally zero---is restored.  Nonetheless
%     you should not assume that a newly allocated register is
%     initialised with the value zero.
%  \end{itemize}
%
% {\let\newmuskip=\relax \DescribeMacro{\newmuskip}}
% {\let\newtoks=\relax \DescribeMacro{\newtoks}}^^A
%  The behaviour of the macros |\newmuskip| and |\newtoks| are not
%  changed because they are not used for insertions.  Nonetheless this
%  can be changed in a future version.
%  
% \DescribeMacro{\lnewcount}
% \DescribeMacro{\lnewdimen}
% \DescribeMacro{\lnewskip}
% \DescribeMacro{\lnewmuskip}
% \DescribeMacro{\lnewbox}
% \DescribeMacro{\lnewtoks}
%  |\lnewcount|, |\lnewdimen|, |\lnewskip|, |\lnewmuskip|, |\lnewbox|,
%  and |\lnewtoks| are the set of new macros to allocate registers
%  within the scope of the current group.  At the end of the current
%  group the allocated register is freed.
%
%  As with their global counterparts you should not assume that the
%  registers are allocated in a consecutive order---neither increasing
%  nor decreasing---or that the allocated register is initialised with
%  zero.
%
%
% \subsection{Usage Examples}
%
% \subsubsection{\LaTeX's Picture Environment}
%
%  \LaTeX's picture environment uses the box register |\@picbox| and
%  the dimen register |\@picht| to save the contents of a picture and
%  the user specified height of this picture at the beginning of the
%  environment.  These two registers are set at the beginning and used
%  at the end of the |picture| environment.  Because the two registers
%  are used nowhere else, it is possible to share them by only
%  allocating them within the environment.
%
%  This is the simplified code for the |\begin{picture}| and
%  |\end{picture}| commands; the macros |\begin| and |\end| start and
%  end a new group:
%\begin{verbatim}
%\newbox\@picbox
%\newdimen\@picht
%\end{verbatim}
%\begin{verbatim}
%\def\picture(#1,#2){%
%  \@picht = #2\unitlength  % save picture height
%  \setbox\@picbox = \hbox to #1\unitlength\bgroup
%    \ignorespaces}
%\end{verbatim}
%\begin{verbatim}
%\def\endpicture{%
%    \hss
%  \egroup                  % close picture box
%  \ht\@picbox = \@picht    % set box height to save picture height
%  \dp\@picbox = 0pt        % set box depth to 0pt
%  \mbox{\box\@picbox}}     % output this box
%\end{verbatim}
%
%  Using the new local allocation macros the code changes is simple:
%  Move the |\newbox| and |\newdimen| command within the |\picture|
%  macro definition and rename them to |\lnewbox| and |\lnewdimen|:
%\begin{verbatim}
% %\newbox\@picbox
% %\newdimen\@picht
%\end{verbatim}
%\begin{verbatim}
%\def\picture(#1,#2){%
%  \lnewbox\@picbox
%  \lnewdimen\@picht
%  \@picht = #2\unitlength  % save picture height
%  \setbox\@picbox = \hbox to #1\unitlength\bgroup
%    \ignorespaces}
%\end{verbatim}
%
%  Additionally we can use a property of the usage pattern of these
%  two registers:
%  Within a nested use of the |picture| environment---you can use
%  subpictures within a picture---these registers are allocated for
%  each nesting level.  This is not really necessary because the box
%  and the dimen register is always used in a group and is never
%  changed globally.
%  It is possible to add tests to avoid a (local) reallocation of
%  these registers:
%\begin{verbatim}
%\let\@picbox=\relax    % mark register as not yet allocated
%\let\@picht =\relax    % mark register as not yet allocated
%\end{verbatim}
%\begin{verbatim}
%\def\picture(#1,#2){%
%  \ifx\@picbox\relax \lnewbox\@picbox  \fi
%  \ifx\@picht\relax  \lnewdimen\@picht \fi
%  \@picht = #2\unitlength  % save picture height
%  \setbox\@picbox = \hbox to #1\unitlength\bgroup
%    \ignorespaces}
%\end{verbatim}
%
%
% \subsubsection{\LaTeX's {\tt\protect\bslash multiput} Macro}
%
%  Another example of registers which are used only in one rarely
%  used macro, are the count register |\@multicnt| and the two dimen
%  registers |\@xdim| and |\@ydim| for the |\multiput| command.  To
%  change it according to the scheme above you have to insert an
%  additional grouping.
%
%  In \LaTeXe\ these three rarely used registers and some more are
%  shared with the |\bezier| command, whose definition has to be
%  changed accordingly.  This shows the need---and advantage---of a
%  better allocation scheme.
%
% \subsubsection{\PiCTeX}
%
%  The macro package \PiCTeX\ uses a lot of dimen registers.  A subset
%  of these registers are only used within a picture or within a set
%  of drawing and parameter setting commands.
%
%  As an example the dimen registers |\totalarclength| is only used in
%  a very restrictic set of commands, i.e., it can be allocated within
%  the scope of the higher level commands or within \PiCTeX's
%  |\beginpicture| \ldots\ |\endpicture| environment.
%
%
% \StopEventually{^^A
%   \begin{thebibliography}{0}
%   \bibitem{DEK91} Donald E.\ Knuth,
%     {\it The \TeX{}book},
%     Addison-Wesley Publ., Reading, Mass., Juni 1991.
%   \bibitem{plain.tex-3.14159} File {\tt plain.tex},
%     version 3.14159,
%     March 1995.
%   \end{thebibliography}
% }
%
%
%
% \section{Implementation}
%
%
% \subsection{Prolog, \LaTeXe\ Package Declarations, etc.}
%
%    The very first thing we do is to ensure that this file is not
%    read in twice.  To this end we check whether the macro
%    |\lnewcount| is defined. If so, we just stop reading this file.
%    \begin{macrocode}
%<+package>\expandafter\ifx\csname lnewcount\endcsname\relax
%<+package>\else \expandafter\endinput \fi
%    \end{macrocode}
%
%    For the sake of \LaTeXe\ users declarations for this package are
%    included.  The additional group hack is needed to prevent the
%    definition of |\ProvidesPackage| as |\relax| if it is undefined.
%    \begin{macrocode}
%<+package|test>\begingroup\expandafter\expandafter\expandafter\endgroup
%<+package|test>\expandafter\ifx\csname ProvidesPackage\endcsname\relax
%<+package|test>\else
  \NeedsTeXFormat{LaTeX2e}
%<+package>  \ProvidesPackage{localloc}%
%<+test>  \ProvidesFile{localtst.tex}%
%<*!package&!test>
  \ProvidesFile{localloc.dtx}%
%</!package&!test>
    [1995/09/24 v1.1b %
     Additional LaTeX Kernel Macros (local allocation)]
%<+package|test>\fi
%    \end{macrocode}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
%    To allow the use of this file within a plain-\TeX\ job, we have
%    to change the category code of the `at' character~{\tt @}.
%    \begin{macrocode}
\expandafter\chardef\csname lcllc@at\endcsname=\catcode`\@
\catcode`\@=11 % \makeatletter
%    \end{macrocode}
%
%
% \subsection{Accessing the {\tt muskip} registers}
%
%    Beside the well-known \TeX\ registers, like |\count| or |\box|,
%    there is another set of registers which are used only in few
%    macros.  The |\muskip| registers are normally used in math mode
%    only and the coercion of the value in a |\muskip| register to an
%    integer (|\count|), dimension (|\dimen|), or glue (|\glue|)
%    produces an error.
%
%    The unit of a |\muskip| value is~$1$\,mu---there are $18$\,mu in
%    $1$\,em of the current font in {\em math family~2}.  If you
%    assign a value to a |\muskip| register, this value is represented
%    in the unit~mu, not in~pt.  The dimension of the |\muskip| value
%    is computed, if this value is used by |\mskip| or |\mkern|.
%
%    To use a |\muskip| register as a replacement for a |\count|
%    register, it is necessary to do assignments, additions, and other
%    operations in units of~mu.  If you want to coerce an
%    integer to a |\muskip| register, you have to get the value with
%    |\the| and add the keyword~|mu| while scanning the number. To get
%    the integer value of a |\muskip| register, you can use the
%    following macro~|\lcllc@cnvmutocnt|.
%
% \begin{macro}{\lcllc@cnvmutocnt}
%    The macro |\lcllc@cnvmutocnt| ist called with a |\muskip| register
%    or a value in~|mu| units as its argument.  It will expand to the
%    integer value.  To get the value of a register, we first expand
%    the value of this register to a list of tokens with \TeX's |\the|
%    primitive.
%    Example: if the register has the value~$3.4$\,mu, the expansion of
%    |\the| produces the tokens $\mbox{\tt 3}_{12} \mbox{\tt .}_{12}
%    \mbox{\tt 4}_{12} \mbox{\tt m}_{12} \mbox{\tt u}_{12}$.
%    \begin{macrocode}
\def\lcllc@cnvmutocnt#1{\expandafter\lcllc@delmukey\the#1}
%    \end{macrocode}
%
%    After we have expanded the value of the register, it is necessary
%    to strip of the unit keyword~|mu| and the fraction of the value.
%    To do this, we have to use tokens with {\em category code}~12 to
%    match the expansion string produced by~|\the|.
%    \begin{macrocode}
\begingroup \catcode`\M=12 \catcode`\U=12 \catcode`\.=12
  \lowercase{\endgroup
\def\lcllc@delmukey#1.#2MU{#1}}
%    \end{macrocode}
% \end{macro}
%
%
%  \subsection{Allocation registers}
%
%  \subsubsection{Registers defined in {\tt plain.tex}}
%
%    Plain-\TeX's allocation macros use a fixed set of |count|
%    registers containing a set of numbers with the highest allocated
%    register number.  To make the following macro code more readable,
%    alias names for these |count| registers are defined.
%    \begin{macrocode}
\countdef\count@ptr    = 10
\countdef\dimen@ptr    = 11
\countdef\skip@ptr     = 12
\countdef\muskip@ptr   = 13
\countdef\box@ptr      = 14
\countdef\toks@ptr     = 15
\countdef\read@ptr     = 16
\countdef\write@ptr    = 17
\countdef\mathfam@ptr  = 18
%    \end{macrocode}
%    {\tt plain.tex} for \TeX~3 introduces a new allocation command
%    needing an additional allocation count register.  To simplify the
%    code of this package with older versions of {\tt plain.tex}, a
%    dummy count register is allocated and used.
%    \begin{macrocode}
\begingroup\expandafter\expandafter\expandafter\endgroup
\expandafter\ifx\csname newlanguage\endcsname\relax
  \csname newcount\endcsname\language@ptr
\else
  \countdef\language@ptr = 19
\fi
%    \end{macrocode}
%
%    The allocation command for insertion uses another register, which
%    is already aliased as |\insc@unt|.
%\begin{verbatim}
%\countdef\insc@unt = 20 % = 19 in older versions of `plain.tex'
%\end{verbatim}
%
%
%  \subsubsection{Additional Registers}
%
%    For the new local allocation macros additional registers are
%    needed containing the boundaries for all types of locally
%    allocated registers.  Whereas all globally allocated registers
%    are located in the lower region of the register numbers (with the
%    exception of the set of registers needed for an insertion),
%    locally allocated registers are taken from the higher region of
%    the register numbers---from top towards the bottom.
%
%    To avoid using six additional count registers we use |\muskip|
%    registers to save the current lower boundary of the allocatable
%    register region.  These boundaries are initialised either
%    with~$256$ or the actual boundary of the insertion allocation
%    register.
%    \begin{macrocode}
\newmuskip\count@limit  \count@limit  = \the\insc@unt mu
\newmuskip\dimen@limit  \dimen@limit  = \the\insc@unt mu
\newmuskip\skip@limit   \skip@limit   = \the\insc@unt mu
\newmuskip\box@limit    \box@limit    = \the\insc@unt mu
\newmuskip\muskip@limit \muskip@limit = 256mu
\newmuskip\toks@limit   \toks@limit   = 256mu
%    \end{macrocode}
%
%    To simplify the code of the following allocation macros and to
%    save macro space, two additional |\muskip| registers are
%    allocated and initialised with the constants $16$ and~$256$.
%    \begin{macrocode}
\newmuskip\cclvi@mu     \cclvi@mu     = 256mu
\newmuskip\xvi@mu       \xvi@mu       = 16mu
%    \end{macrocode}
%
%
%  \subsection{Allocation Macros for the ``End User''}
%
%  \subsubsection{Global Allocation Macros}
%
% \begin{macro}{\newcount} \begin{macro}{\newdimen}
% \begin{macro}{\newskip}  \begin{macro}{\newmuskip}
% \begin{macro}{\newbox}   \begin{macro}{\newtoks}
% \begin{macro}{\newread}  \begin{macro}{\newwrite}
% \begin{macro}{\newfam}   \begin{macro}{\newlanguage}
%    We have to replace the original macros in {\tt plain.tex} by new
%    ones to allow locally allocated registers.  Otherwise it will be
%    possible that the two regions, the lower one with globally
%    allocated registers and the higher one with locally allocated
%    registers, will overlap resulting in a double use of the same
%    register.
%
%    With the new macros it will be unnecessary to un-outer the {\tt
%    plain.tex} macros, because the local allocation macros have to be
%    non outer.  Nonetheless we want to use this package in
%    conjunction with \LaTeX\ and therefore we have to define some of
%    them as non outer.
%
%    The top level macros use the low level macro |\alloc@| which has
%    the following parameters:
%    The boundaries of the lower and the higher region, the type of
%    the allocated register, a flag if we have to check on overlapping
%    with insertion registers, the \TeX\ primitive to be used to
%    define this register, and the user given control sequence.
%    \begin{macrocode} 
%\outer
\def\newcount  {\alloc@\count@ptr  \count@limit \count  1\countdef }
%\outer
\def\newdimen  {\alloc@\dimen@ptr  \dimen@limit \dimen  1\dimendef }
%\outer
\def\newskip   {\alloc@\skip@ptr   \skip@limit  \skip   1\skipdef  }
% \outer
\def\newmuskip {\alloc@\muskip@ptr \muskip@limit\muskip 0\muskipdef}
%\outer
\def\newbox    {\alloc@\box@ptr    \box@limit   \box    1\chardef  }
% \outer
\def\newtoks   {\alloc@\toks@ptr   \toks@limit  \toks   0\toksdef  }
% \outer
\def\newread   {\alloc@\read@ptr   \xvi@mu      \read   0\chardef  }
%\outer
\def\newwrite  {\alloc@\write@ptr  \xvi@mu      \write  0\chardef  }
%\outer
\def\newfam    {\alloc@\mathfam@ptr\xvi@mu      \fam    0\chardef  }
% \outer
\def\newlanguage{\alloc@\lang@ptr  \cclvi@mu   \language0\chardef  }
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
%    |\newinsert| needs additional code because this macro has to
%    allocate a set of |\box|, |\count|, |\dimen|, and |\skip|
%    registers with the restriction that all registers have to have
%    the same number. |\newinsert| is redefined at the end of this
%    file.
%
%
%  \subsubsection{Local Allocation Macros}
%
%
% \begin{macro}{\lnewcount} \begin{macro}{\lnewdimen}
% \begin{macro}{\lnewskip}  \begin{macro}{\lnewmuskip}
% \begin{macro}{\lnewbox}   \begin{macro}{\lnewtoks}
%    There is an equivalent set of macros to allocate registers
%    locally.  Instead of using the low level macro |\alloc@| it uses
%    the macro |\lalloc@| with the same set of parameters.
%    \begin{macrocode}
\def\lnewcount {\lalloc@\count@ptr \count@limit \count  1\countdef }
\def\lnewdimen {\lalloc@\dimen@ptr \dimen@limit \dimen  1\dimendef }
\def\lnewskip  {\lalloc@\skip@ptr  \skip@limit  \skip   1\skipdef  }
\def\lnewmuskip{\lalloc@\muskip@ptr\muskip@limit\muskip 0\muskipdef}
\def\lnewbox   {\lalloc@\box@ptr   \box@limit   \box    1\chardef  }
\def\lnewtoks  {\lalloc@\toks@ptr  \toks@limit  \toks   0\toksdef  }
%    \end{macrocode}
% \end{macro}\end{macro}\end{macro}\end{macro}\end{macro}\end{macro}
%
%    Local allocation macros for |\read|, |\write| streams, math
%    |\fam|, |language| numbers, or insertions are possible but not
%    very useful because of the global nature of these resources.
%
%
%  \subsection{Low Level Allocation Macros}
%
%    The allocation scheme used by the macros in {\tt plain.tex} is
%    simple:
%    \begin{itemize}
%    \item all allocations are global,
%    \item register, math family, language, input/output stream
%      numbers are allocated using the lowest possible number, i.e.,
%      it is done from lower number to higher numbers,
%    \item the set of insertion registers (|box|, |count|, |skip|, and
%      |dimen|), which have to have the same register number, are
%      allocated beginning from~$255$ to lower numbers.
%    \end{itemize}
%
%    Contrary to this simple scheme this package uses numbers for
%    locally allocated registers from top to bottom interfering with
%    the original insertion register allocation scheme {\it and\/} the
%    simple test for a register number overflow.
%
% \begin{macro}{\lcllc@insnums}
%    Insertion registers are now allocated in a non-monotonous order
%    using the lowest possible number (because the allocation of the
%    needed set of registers is done in a global way).  To allow the
%    checking of overlapping of globally or locally allocated
%    registers with the registers used for insertions, the insertion
%    register numbers are saved as a list in |\lcllc@insnums|.
%    Each entry in this list is saved as \mbox{\tt\string\do$\langle
%    n\rangle$.}; the list is initialised as empty.
%    \begin{macrocode} 
\def\lcllc@insnums{}
%    \end{macrocode} 
% \end{macro}
%
% \begin{macro}{\lcllc@checkins}
%    Whenever a new |box|, |count|, |skip|, or |dimen| register is
%    allocated it has to be checked first, if the next possible
%    free register is already allocated for an insertion.
%
%    To detect a collision between a possibly free register number and
%    the set of insertion registers, the macro |\lcllc@checkins| is
%    called with the register number to be tested in
%    |\allocationnumber|.  The argument of this macro has to be either
%    $1$ or~$-1$ and is used to get the next register number to be
%    tested against the insertion number list if an additional
%    iteration is needed.  The result is a register number in
%    |\allocationnumber| which is not used for an insertion.  (Note:
%    Nonetheless it can be an out-of-region register number of an
%    already used register!)
%    \begin{macrocode} 
\def\lcllc@checkins#1{%
  \begingroup
%    \end{macrocode} 
%    After opening a new group, the macro |\do| is defined to read the
%    next insertion number delimited by a simple dot.  It then tests
%    this number against the current |\allocationnumber| and if the
%    register numbers are equal, |\allocationnumber| is advanced by the
%    given argument (which is $1$ or~$-1$).
%
%    To avoid a global change of |\allocationnumber|, a group hack
%    with expansion is used:  If the list |\lcllc@insnums| is expanded
%    with this definition of |\do|, the result is empty if the
%    register number is not used for an insertion.  Otherwise it
%    expands to the |\advance| command followed by an additional
%    |lcllc@checkins| (which has to be protected by |\noexpand|) to
%    start another iteration with the changed |\allocationnumber|.
%    \begin{macrocode} 
    \def\do##1.{%
      \ifnum##1=\allocationnumber
        \advance\allocationnumber#1\relax
        \noexpand\lcllc@checkins{#1}%
      \fi}%
%    \end{macrocode}
%    The following expanded definition text of |\x| contains code to
%    close the group and the expansion of |\lcllc@insnums|, which is
%    either empty or contains the change of |\allocationnumber| and an
%    iterative call of |\lcllc@checkins|.  After the definition is
%    completed, the code is executed which closes the group.
%    \begin{macrocode}
    \edef\x{\endgroup \lcllc@insnums}%
  \x}
%    \end{macrocode} 
% \end{macro}
%
%
% \begin{macro}{\alloc@}
%    |\alloc@| is the low level macro for global allocation, which is
%    called with six arguments.  The macro itself only uses the first
%    four argument: The two boundaries, the item type to be allocated,
%    and a flag if this item is propably used for an insertion.  The
%    remaining two arguments, the \TeX\ primitive and the control
%    sequence to assign the allocated number is used by
%    |\lcllc@def|.
%    \begin{macrocode}
\def\alloc@#1#2#3#4{%
%    \end{macrocode}
%    In the first step we assign the boundary of the lower region for
%    this item type to |\allocationnumber| and increment it by one.
%    \begin{macrocode}
  \allocationnumber#1%
  \advance\allocationnumber\@ne
%    \end{macrocode}
%    If this item type is used by insertion, we have to check for
%    collision with the |\lcllc@checkins| macro.  After the execution of
%    this macro, |\allocationnumber| contains the next free number to
%    be used for allocation.  This number is assigned globally to the
%    register containing the boundary.
%    \begin{macrocode}
  \ifnum#4=\@ne \lcllc@checkins\@ne \fi
  \global#1\allocationnumber
%    \end{macrocode}
%    We now have found an unused register.  Nonetheless it is possible
%    that the register number is either not in the range of existing
%    register number or it is used for a locally allocated register.
%    |\ch@ck| is used to test these things.
%    \begin{macrocode}
  \ch@ck#1#2#3%
%    \end{macrocode}
%    At the end the \meta{control sequence} is defined using the
%    found |\allocationnumber|.
%    \begin{macrocode}
  \lcllc@def\global{}#3}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\lalloc@}
%    |\lalloc@| is the low level macro for local allocation.  The
%    definition of this macro a copy of |\alloc@| with some small
%    changes.
%    \begin{macrocode}
\def\lalloc@#1#2#3#4{%
%    \end{macrocode}
%    In the first step we assign the boundary of the {\it higher\/}
%    region and {\it decrement\/} it by one.   Because the higher
%    boundary is saved in a |\muskip| register, we have to use
%    |\lcllc@cnvmutocnt| to get the boundary value.
%    \begin{macrocode}
  \allocationnumber\lcllc@cnvmutocnt#2%
  \advance\allocationnumber\m@ne
%    \end{macrocode}
%    The check for insertion number collisions is called with~$-1$ to
%    decrement the register number to get the next free register
%    number.  The |\allocationnumber| is then assigned {\it locally\/}
%    to the |\muskip| register containing the boundary.
%    \begin{macrocode}
  \ifnum#4=\@ne \lcllc@checkins\m@ne \fi
  #2\the\allocationnumber mu %
%    \end{macrocode}
%    The check for an already used globally allocated register or a
%    range underflow is needed, too.
%    \begin{macrocode}
  \ch@ck#1#2#3%
%    \end{macrocode}
%    At the end the \meta{control sequence} is defined using the
%    found |\allocationnumber|.
%    \begin{macrocode}
  \lcllc@def\relax{(local)}#3}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\ch@ck}
%    The test macro |\ch@ck| for a collision of the globally and
%    locally allocated registers from {\tt plain.tex} has to be
%    changed because the higher boundary is given as a |\muskip| value
%    instead of a normal integer.
%    \begin{macrocode}
\def\ch@ck#1#2#3{%
  \ifnum#1<\lcllc@cnvmutocnt#2\relax \else
    \errmessage{No room for a new #3}%
    % \allocationnumber\m@ne
  \fi}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\lcllc@def}
%    |\lcllc@def| is used to assign the found |\allocationnumber|
%    to the \meta{control sequence} using the \TeX\ primitive.
%    Additionally an entry is written to the {\tt log} file.
%    \begin{macrocode}
\def\lcllc@def#1#2#3#4#5{%
  #1#4#5=\allocationnumber
  \wlog{\string#5#2=\string#3\the\allocationnumber}}
%    \end{macrocode}
%  \end{macro}
%
%
%  \subsubsection{Low Level Insertion Allocation Macros}
%
%    Insertions need a set of registers with the same register number.
%    To find a new register number when allocating an insertion, we
%    have to get the maximum of all boundaries used for an insertion.
%
%  \begin{macro}{\lcllc@getmax}
%    |\lcllc@getmax| is used to assign |\allocationnumber| to the
%    maximum of |\allocationnumber| and its argument.
%    \begin{macrocode}
\def\lcllc@getmax#1{%
  \ifnum#1<\allocationnumber \else
    \allocationnumber#1\advance\allocationnumber\@ne
  \fi}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\newinsert}
%    |\newinsert| globally allocates a set of registers used for an
%    insertion.
%    \begin{macrocode}
\outer\def\newinsert{%
%    \end{macrocode}
%    First we have to find the maximum of all globally allocated
%    register number used for an insertion.   We start
%    by setting |\allocationnumber| to~$-1$\,\ldots
%    \begin{macrocode}
  \allocationnumber\m@ne
%    \end{macrocode}
%    \ldots\,and get the maxmimum of the boundaries for |count|,
%    |dimen|, |skip|, and |box| registers.
%    \begin{macrocode}
  \lcllc@getmax\count@ptr \lcllc@getmax\dimen@ptr
  \lcllc@getmax\skip@ptr  \lcllc@getmax\box@ptr
%    \end{macrocode}
%    Then we have to check if this |\allocationnumber| is already used
%    for another insertion.
% \changes{v1.0b}{91/09/06}{\cs{lcllc@checkins} inserted}
%    \begin{macrocode}
  \lcllc@checkins\@ne
%    \end{macrocode}
%    At last we have to check if this |\allocationnumber| is used for
%    one of the locally allocated registers.
%    \begin{macrocode}
  \ch@ck\allocationnumber\count@limit\count
  \ch@ck\allocationnumber\dimen@limit\dimen
  \ch@ck\allocationnumber\skip@limit\skip
  \ch@ck\allocationnumber\box@limit\box
%    \end{macrocode}
%    The found register number for insertions is then (globally)
%    inserted into the list of insertion numbers.
%    \begin{macrocode}
  \begingroup
    \let\do\relax
    \xdef\lcllc@insnums{\do\the\allocationnumber.\lcllc@insnums}%
  \endgroup
%    \end{macrocode}
%    At the end the \meta{control sequence} is defined using the
%    found |\allocationnumber|.
%    \begin{macrocode}
  \lcllc@def\global{}\insert\chardef}
%    \end{macrocode}
%  \end{macro}
%
%    The register |\insc@unt| which is used to contain the boundary
%    number for insertion registers in the original {\tt plain.tex}
%    macro is not used anymore.
%
%
%    Finally, the category code of the `at' character~{\tt @} is reset
%    to its original value.
%    \begin{macrocode}
\catcode`\@=\lcllc@at
%    \end{macrocode}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
%
% \iffalse
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\documentclass[a4paper]{ltxdoc}
\GetFileInfo{localloc.dtx}
\begin{document}
 \DocInput{\filename}
\end{document}
%</driver>
% \fi
%
% \iffalse
%
% \section{Test File}
%
%  A first version of a test file which can be used for plain-TeX,
%  \LaTeX~2.09, and \LaTeXe.  The result shows the allocated register
%  numbers.  You should notice that the insertions and global box
%  registers are not contiguously allocated but interfere.  Further
%  from one to the next line there is a new global register number
%  greater than the former one.  Whereas the local register numbers
%  are set to zero when leaving a group and they are recycled in the
%  next lines.
%
%    \begin{macrocode}
%<*test>
% This test file can be used with plain-TeX & LaTeX 2.09/2e.
%
\edef\FORMAT{%
  \expandafter\ifx\csname documentstyle\endcsname\relax 0%
  \else\expandafter\ifx\csname documentclass\endcsname\relax
  1\else 2\fi\fi}
\immediate\write16{=====>>> You are using %
  \ifcase\FORMAT plainTeX\or LaTeX 2.09\or LaTeX 2e\else ??\fi}
\ifcase\FORMAT
  \input localloc.sty\relax \or
  \documentstyle[localloc]{article}\begin{document}\or
  \documentclass{article}\usepackage{localloc}\begin{document}\fi
\tracingstats=1
% some macros
\def\Message#1{\immediate\write16{#1}}
\def\RegVal#1{\the\csname test#1\endcsname}
\def\ShowSet#1{\if l#1local\else global\fi:
   \RegVal{i#1} \RegVal{ii#1}/\RegVal{iii#1}
   \RegVal{iv#1}}
\def\ShowAll#1{\Message{#1 -- \ShowSet{g} -- \ShowSet{l}}}
\def\ShowIns{\Message{Insertions:
   \the\testinsi, \the\testinsii, \the\testinsiii}}
% initialise
\chardef\testig=0    \chardef\testil=0
\chardef\testiig=0   \chardef\testiil=0
\chardef\testiiig=0  \chardef\testiiil=0
\chardef\testivg=0   \chardef\testivl=0
\chardef\testinsii=0 \chardef\testinsiii=0
% allocate an insertion/set of registers
\newinsert\testinsi
% make sure that a collision boxes/insertions occurs
{\count0=\testinsi \advance\count0 -2
 \loop\csname newbox\endcsname\testig
 \ifnum\testig<\count0\repeat}
%
\newbox\testig \lnewbox\testil
\ShowAll{Level 0}
\begingroup
 \lnewbox\testiil \newbox\testiig
 \ShowAll{Level 1}
 \begingroup
  \newbox\testivg \lnewbox\testivl
  \ShowAll{Level 2}\ShowIns
 \endgroup
 \lnewbox\testiiil \newbox\testiiig
 \ShowAll{Level 1b}
 \csname newinsert\endcsname\testinsii
 \ShowIns
 \begingroup
  \newbox\testivg \lnewbox\testivl
  \ShowAll{Level 2}
 \endgroup
 \ShowAll{Level 1b}
\endgroup
\newinsert\testinsiii
\ShowAll{Level 0}\ShowIns
\begingroup
 \lnewbox\testiil \newbox\testiig
 \lnewbox\testiiil \newbox\testiiig
 \ShowAll{Level 1}
 \begingroup
  \newbox\testivg \lnewbox\testivl
  \newbox\testvg \lnewbox\testvl
  \ShowAll{Level 2}\ShowIns
 \endgroup
 \ShowAll{Level 1}
\endgroup
\ShowAll{Level 0}
\end{document}
%</test>
%    \end{macrocode}
%
% \fi
%
% \Finale
%
%% \CharacterTable 
%%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z 
%%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z 
%%   Digits        \0\1\2\3\4\5\6\7\8\9 
%%   Exclamation   \!     Double quote  \"     Hash (number) \# 
%%   Dollar        \$     Percent       \%     Ampersand     \& 
%%   Acute accent  \'     Left paren    \(     Right paren   \) 
%%   Asterisk      \*     Plus          \+     Comma         \, 
%%   Minus         \-     Point         \.     Solidus       \/ 
%%   Colon         \:     Semicolon     \;     Less than     \< 
%%   Equals        \=     Greater than  \>     Question mark \?  
%%   Commercial at \@     Left bracket  \[     Backslash     \\ 
%%   Right bracket \]     Circumflex    \^     Underscore    \_ 
%%   Grave accent  \`     Left brace    \{     Vertical bar  \| 
%%   Right brace   \}     Tilde         \~} 
%% 
%
\endinput