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
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
|
\part Front and\\ Back Matter\label{FBM}\endpart
\chapter Front Matter\\(Table of Contents, List of Figures, Tables, etc.)
\label{FRONTMATTER}\endchapter
\runningchapter{Front Matter}
Now that we've covered all the formatting of the paper proper, we only have
to worry about the formatting of the *.toc* and *.tic* files for the front
matter, and the *.ndx* file for the index.
As we've seen in section~\Sref{STYF}, the
*\predocstyle* and *\postdocstyle* commands simply *\input* files with
the extension *.stf* and *.stb*, respectively. In the default style,
we say
**
\predocstyle{lamstex}
**
to *\input lamstex.stf*, and
**
\postdostyle{lamstex}
**
to *\input lamstex.stb*. In this chapter we consider the file *lamstex.stf*,
while the next chapter considers *lamstex.stb*.
As in section~\Sref{GENDEFS}, we will be using double horizontal lines
for code from these subsidiary files.
\section{{\tt lamstex.stf} preliminaries} The file
*lamstex.stf*, although it is only a
particular example of a front matter style file, nevertheless illustrates all
the main points we have to consider.
As usual, we begin with
\CC**
\catcode`\@=11
**
Since we are going to be introducing some *\newdimen*'s, we first
\CC**
\let\alloc@=\alloc@@
**
(compare page~\ref{NEWALLOC}).
\medskip
In the default style, we will be setting entries like
\bigskip
\line{\qquad\bf
Chapter 1. Introduction\leaders\hbox to10pt{\rm\hfil.\hfil}\hfil
\kern10pt\hbox{\rm3}\qquad}
\bigskip
\noindent
using dot leaders. This, of course, is merely a style decision, and some
modern style designers eschew dot leaders, on the grounds that blank space
will work just as well. I suspect, however, that many such supposedly
aesthetic decisions were really influenced by the difficulty of handling dot
leaders correctly. In any case, the default style uses dot leaders, giving us
the opportunity to address the question of long entries, where we will need
to use something like
\bigskip
\line{\qquad\bf Chapter 1. This chapter has such a long title that it will
be \hfil}
\line{\qquad\bf\setbox0\hbox{Chapter 1.}\hskip10pt\hskip\wd0
necessary to split it into two parts\leaders\hbox
to10pt{\rm\hfil.\hfil}\hfil\kern10pt \rm3\qquad}
\bigskip
For the moment, we simply define our leaders,
\CC**
\def\dotleaders{\leaders\hbox to10pt{\rm\hfil.\hfil}\hfil}
**
We also want to define the formatting for page numbers.
The *.toc* and *.tic* files contain lines like
**
\Page {3}{\arabic }{}{}
**
to handle the page number, the numbering style, and possible pre- and
post-page material. The routine *\Page@#1#2#3#4* tells how these will
be combined when typeset:
\CC**
\def\Page@#1#2#3#4{\kern10pt\hbox{\rm#3#2{#1}#4}}
**
Thus, for example,
**
\Page {3}{\roman }{A-}{}
**
will be printed as `A-iii', with at least 10~points of space between the
leaders and the number.
\section{Setting an entry\label{SETENTRY}}
We begin with a test
**
\widerthanhsize@#1#2#3#4
**
to determine
whether
the material for an entry is longer than *\hsize*.
In the example given above, *#1* will be the `\hbox{\bf Chapter 1. }' part of
the heading,
*#2* will be the title `{\bf This chapter \dots into two parts}', *#3* will
be the *\dotleaders*, and *#4* will be the suitable `*\Page@...*'.
Displayed formulas and other
such nonsense aren't allowed in heading levels, but captions, at any rate,
could have more than one paragraph of text; moreover, in the *.toc* file
we might well want
to use *\newline* to force a short line when our entry is so long
that only one or
two of the dot leaders appear.
So we will use a test similar to
the *\widerthanisland@* test of section~\Sref{FMTC}:
\CC**
\long\def\widerthanhsize@#1#2#3#4{%
\test@true
\setbox0=\vbox{\hsize=\maxdimen
\rm\noindent@#1#2#3#4\par\setbox0=\lastbox}%
\ifdim\wd0=0pt
\setbox0=\hbox{\rm#1#2#3#4}%
\ifdim\wd0 > \hsize\else\test@false\fi
\fi}
**
We use *\noindent@* instead of the more complicated *\noindent@@* here
because we will be setting *\everypar{}* while the table of contents is
being made. (Actually, even the *\noindent@* is unnecessary, since we will
also be setting *\parindent=0pt*.)
Instead of *\rm*, other style files
might need to insert something like *\tenpoint* (just
in case the user has, for example, added
*\eightpoint* material at the beginning of the *.toc* file).
Then we define the routine *\setentry@#1#2#3#4*,
which sets the entry with parts *#1*, \dots, *#4* properly; when the
entry will have to be set on more than one line, we call the routine
*\longentry@*:
\CC**
\long\def\setentry@#1#2#3#4{%
\widerthanhsize@{#1}{#2}{#3}{#4}%
\iftest@
\longentry@{#1}{#2}{#3}{#4}%
\else
\hbox to\hsize{\rm\strut#1#2#3#4\strut}%
\fi}
**
Notice that we added the *\strut*'s after the *\rm*; other styles
might have to specify something like *\tenpoint* instead of the *\rm*.
Because our lines have *\strut*'s, which already make the baselines *12pt*
apart,
it is essential that we have
**
\lineskiplimit=0pt "8USELIMITPROB"8
**
while we are setting the table of contents,
so that additional *\lineskip* glue isn't inserted between lines
(compare page~\ref{LIMITPROB}). However, instead of making this assignment
now, we will make it later, within the definition of *\maketoc*.
For entries that are longer than one line,
the default style uses hanging indentation, so that
lines after the first are indented by 10~points more than
the width of argument *#1*. We will declare a \<dimen\> register
*\thehang@*
for the necessary amount of hanging indentation, which will be determined by
**
\setbox0=\hbox{#1}
\thehang@=\wd0 \advance\thehang@ by 10pt
**
All lines before the last will be made shorter
than *\hsize*, so that they don't overlap the width of the page number.
The default style leaves an extra 20~points leeway, which we arrange with
**
\setbox0=\hbox{#4}
\advance\hsize by -\wd0 \advance\hsize by -20pt
\hangafter 1 \hangindent=\thehang@
**
Now the idea is to set a *\vbox* that looks like
\medskip
\line{\qquad\bf Chapter 1. This chapter has such a long title that it will
be necessary\hfil}
\line{\qquad\bf\setbox0\hbox{Chapter 1.}\hskip10pt\hskip\wd0
to split it into two parts\hfil}
\medskip
\noindent
and then use *\lastbox* to extract the last line, to which we will finally
add the dot leaders and the page number:
**
\long\def\longentry@#1#2#3#4{%
\setbox0=\hbox{#1} \thehang@=\wd0 \advance\thehang@ by 10pt
\setbox0=\hbox{#4}
\setbox0=\vbox{\advance\hsize by -\wd0
\advance\hsize by -20pt
\hangafter 1 \hangindent=\thehang@
\rm\noindent@\strut\hbox{#1}#2\vphantom{#3#4}\strut}
. . .
**
We put *#1* inside an *\hbox* so that any glue within it will have only
its natural width, without any
stretch or shrink; this is necessary in order to insure that our hanging
indentation will truly be the width of *#1* plus 10~points.
The *\vphantom{#3#4}* is added so that the height and depth of the
last line of *\box0* won't
change when we add the dot leaders (*#3*) and the page number (*#4*).
As mentioned before, other styles might have to specify something like
*\tenpoint* rather than *\rm*; the *\strut* should come after that,
{\it and also after the\/} *\noindent@* (so that it doesn't start
a paragraph prematurely).
As with footnotes (section~\Sref{VF}), we will actually want to replace
the first *\strut* with
**
\vbox to\ht\strutbox{}
**
and the last *\strut* with
**
\lower\dp\strutbox\vbox to\dp\strutbox{}
**
The latter combination will appear
more than once, so we adopt an abbreviation:
\CC**
\def\endstrut@{\lower\dp\strutbox\vbox to\dp\strutbox{}}
**
Although we will have *\lineskiplimit=0pt* when *\longentry@* is
being used,
within our *\vbox* we want to declare
**
\normalbaselines
**
so that the standard value of *\lineskiplimit* is used there. (In the default
style *\normallineskiplimit* happens to be ~*0pt*, so that this is actually
superfluous, but in other styles that is not necessarily the case.)
Now we start to make a new box, in which we *\unvbox0*:
**
\setbox0=\vbox{\unvbox0
\setbox0=\lastbox
. . .
**
This makes the inner *\box0* the last line of the
paragraph, a ``short'' line that ends with *\parfillskip* glue,
and then yet another glue, namely *\rightskip*. So we need
**
\unhbox0 \unskip\unskip
**
to get rid of this extra glue, before we
add *#3* and *#4*.
In addition,
the hanging indentation does not insert glue or a kern at the beginning of
this box---instead, it merely shifts it to the right in the vertical list.
So we use
**
\setbox0=\vbox{\unvbox0
\setbox0=\lastbox
\hbox to\hsize{\kern\thehang@
\unhbox0 \unskip\unskip#3#4\endstrut@}
}
**
to create the desired final line.
And then we
simply *\unvbox0*:
\CC**
\newdimen\thehang@
"slip
\long\def\longentry@#1#2#3#4{\setbox0=\hbox{#1}%
\thehang@=\wd0 \advance\thehang@ by 10pt
"2
\setbox0=\hbox{#4}%
"2
\setbox0=\vbox{\advance\hsize by -\wd0
\advance\hsize by -20pt
\normalbaselines
\hangafter1 \hangindent=\thehang@
"2
\vskip-\parskip
\rm\noindent@\vbox to\ht\strutbox{}%
\hbox{#1}#2\vphantom{#3#4}\endstrut@}%
"2
\setbox0=\vbox{\unvbox0
\setbox0=\lastbox
\hbox to\hsize{\kern\thehang@
\unhbox0 \unskip\unskip #3#4\endstrut@}%
}%
\unvbox0 }
**
Note that in the last *\setbox0=\vbox* there is no extra glue between the
*\unvbox0* and the *\hbox to\hsize* (compare the footnote on page~\ref{NEXG});
that is why it is important to have the *\vphantom{#3#4}*, to insure
that the *\hbox to\hsize* has the same height as the *\lastbox* that it is
replacing.
\section{Further preliminaries for the table of contents}
The *\maketoc* command is going to *\input* the appropriate *.toc* file,
which will have entries like
\setbox0\hbox{and}
\setbox1\hbox{\<word\>}
\setbox2\hbox{\<formatted heading number\>}
**
\HL {1}{"copy1}{"box2} "8HLILLUS"8
. . .
\Page ...
**
and/or entries like
\setbox0\hbox{and}
\setbox1\hbox{\<word\>}
\setbox2\hbox{\<formatted heading number\>}
**
\chapter {"copy1}{"box2}
. . .
\Page ...
**
(in which case an extra line like
**
\NameHL 1\chapter
**
should appear at the beginning), and similarly for *\hl*.
We will therefore be redefining *\HL* and *\hl* so that such lines
print proper lines for the table of contents.
But
a few preliminaries are needed to deal with the
possibility that something like *""B""*, or even
*""\style B""* occurs instead of a \<formatted heading number\>.
First, we want a flag
\CC**
\newif\ifemptynumber@
**
which will be set true precisely in the case where we have *""""* (in the
paper proper, this happens when *\thelabel@@* is *\empty*). When it comes
time to properly print the argument `*...*'
of *\HL* that represents the heading
number, we will use
**
\Style@...\Style@
**
so that *\Style@* can use a *\futurelet* to see if `*...*' begins with
a *""* (we use *\Style@* because *\style@* is already used, as part of the
definition of *\style*).
We begin with
\CC**
\def\Style@{\emptynumber@false\futurelet\next\Style@@}
\def\Style@@{\ifx\next""\expandafter\Style@@@
\else\expandafter\Style@@@@\fi}
**
For *\Style@@@*, when no *""* occurs, we might expect to use
**
\def\Style@@@#1\Style@{#1}
**
Instead, however, we will use
\CC**
\def\Style@@@@#1\Style@{\style{#1}}
**
so that each heading level can temporarily define `*\style*' to produce
whatever sort of formatting for the number that we want.
On the other hand, *\Style@@@* is defined by
\CC**
\def\Style@@@""#1""\Style@{%
\def\next@{#1}\ifx\next@\emtpy
\emptynumber@true\else#1\fi}
**
Thus, in the special case that our original argument is *""""*,
we simply set *\emptynumber@true*; otherwise we
print the argument *#1*. Notice that if this argument happens
to be something like *""\style B""*, the `*B*' will be formatted according
to the manner in which this heading level has temporarily defined
*\style* to operate.
For setting *\hl1* entries,
we will also declare a new dimension *\digits*,
\CC**
\newdimen\digits "8DIGITS"8
\setbox0\hbox{0.00}
\digits=\wd0
**
so that *\digits* is the width of a double-digit number like `1.12' (the
user could reset *\digits* if necessary to accommodate even more digits).
We also want to define
\CC**
\def\maketoc@W{CONTENTS}
**
so that *\newword\maketoc* can be used to choose a different word.
\section{Starting the \CS{maketoc} command}
The *\maketoc* command first uses *\checkmainfile@* (page~\ref{CHECKMF})
to issue an error message if no *\mainfile* command has appeared in the front
matter file, since it will have to *\input \mainfile@.toc*, where
*\mainfile@* has been defined by *\mainfile*.
Then it
starts a new page,
in case something like a Preface precedes it (the default front
matter style file *lamstex.stf*
doesn't have special constructions for Prefaces, etc., but
the *book* style, for example, does).
\footnote{We don't simply put *\checkmainfile@* at the beginning of
our file, since a user might omit the *\mainfile* line when
simply checking that something like a Preface looks right.}
Then we produce a centered bold heading `{\bf CONTENTS}', followed by
some space.
Now we want to
*\input* the appropriate *.toc* file, which
is when everything interesting will happen. Certain subsidiary definitions
will be needed, so
we will start with
*\begingroup* and add an *\endgroup* after the *\input*, to keep these all
local.
Any
*\label* or *\pagelabel* in a heading level or a
caption will have been written
to the *.toc* or *.tic* file (there's no practical
way to eliminate them), but they play no further role, and
we simply want to ignore them. The same is true of any *\Reset* or
*\Offset*. So after the *\begingroup* we want to add
**
\noset@ \unlabel@
**
(section~\Sref{relax} and ~\Sref{relax2}).
Any *\nopunct* or *\nospace* or *\overlong* in the main file
will also show up in the *.tic* file. Some styles might want to make
use of these (presumably having them set certain flags), but in the default
front matter style *lamstex.stf*, we simply want to
**
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
**
We also add
**
\everypar={}\parindent=0pt
**
for good measure.
Furthermore, as mentioned previously (page~\ref{USELIMITPROB}), it is
essential that we
set
*\lineskiplimit=0pt*.
So our definition of *\maketoc* will start
**
\def\maketoc{\checkmainfile@
\par\vfill\break
\noset@ \unlabel@
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
\everypar={}\parindent=0pt
\lineskiplimit=0pt
**
\section{Redefining \CS{HL} and \CS{hl}}
Next we have to redefine *\HL* and *\hl* so that *\HL* and *\hl* entries
will be properly set for the table of contents.
To redefine *\HL*, recall (page~\ref{HLILLUS})
that it will occur in a combination like
\setbox0\hbox{\<heading level\>}
\setbox1\hbox{\<formatted heading number\>}
\setbox3\hbox{\<heading word\>}
\setbox2\hbox{\<The heading\>}
**
\HL {"box0}{"box3}{"box1}
"box2
\Page{...}{...}{...}{...}
**
so that we need a definition like
**
\def\HL#1#2#3#4\Page#5#6#7#8{ . . . "87ARGS"8
**
(except that *#1* will be *##1*, etc., since this entire definition will be
made within the definition of *\maketoc*).
The definition should always begin
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}
. . .
**
so that subsequent constructions can know which heading level is being
considered. For the default front matter style we will be using
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}
\ifnum\HLlevel@ = 1
. . .
. . .
\else
\Err@{\string\HL#1 not defined in this style}%
\fi}
**
so that an error message will be given if *\HL {*\<number\>*}* occurs
for any \<number\>${}\ne{}$*1*. (Theoretically this shouldn't happen, since
the *.toc* file is generated by the main file, which only recognizes
*\HL1*; but we might as well add this precaution in case the *.toc* file
has been edited.)
When *\HLlevel@* is~*1*, we want to use *\setentry@* with
the appropriate data,
\setbox1\hbox{\<arg$_{\text1}$\>}
\setbox2\hbox{\<arg$_{\text2}$\>}
\setbox3\hbox{\<arg$_{\text3}$\>}
\setbox4\hbox{\<arg$_{\text4}$\>}
**
\setentry@{"box1}{"box2}{"box3}{"box4}
**
In terms of the original arguments *#1*, *#2*, *#3*, \dots, *#8*
of *\HL* (see~ \recentpageref{7ARGS}{above}{the previous page}{}),
\<arg$_{\text2}$\> will be
**
\bf\ignorespaces#4\unskip
**
\<arg$_{\text3}$\> will be *\dotleaders*, and
\<arg$_{\text4}$\> will be
**
\Page@{#5}{#6}{#7}{#8}
**
As for
\<arg$_{\text1}$\>, it will essentially be
\setbox0\hbox{\<word\>}
**
\bf #2 #3
**
More precisely, it will be
**
\bf \def\next@{#2}\ifx\next@\empty\else#2\space\fi
\let\style=\HL@@S \Style@#3\Style@
\ifemptynumber@\else\space\fi
**
So the \<word\> *#2* is followed by a space, if it is non-empty. Moreover,
when *\Style@...\Style@* uses *\style* to
produce the formatting of the number, this *\style*
will be *\HL@@S* (i.e.,
`*\HL@S1*', since *\Hllevel@* was defined to be~*1*). And we also
add a space after this number,
except in the case of an empty number. Naturally, other
style files might do things differently. Note, moreover, that although
`*\HL@S1*' has been defined in *lamstex.tex*, if *\newstyle\HL1* appears
in the main file, it will also have to be added to the *.toc* file to
produce the same effect. (In practice, of course, only style file designers
will use *\newstyle\HL*, except perhaps for transient effects.)
A multi-level *\HL1* heading will have *\\* in it. Although that should
probably be edited out, we can at least give *\\* a provisional definition as
\linebreak
`*\unskip\space\ignorespaces*'.
The only other thing to worry about is the spacing around the heading:
**
\def\HL#1#2#3#4\Page#5#6#7#8{\def\HLlevel@{#1}%
\ifnum\HLlevel@ = 1
"2
\bigbreak
"2
\begingroup
\def\\{\unskip\space\ignorespaces}%
"2
\setentry@
{\bf\def\next@{##2}\ifx\next@\empty\else##2\space\fi
\let\style=\HL@@S \Style@#3\Style@
\ifemptynumber@\else\space\fi}%
{\bf\ignorespaces#4\unskip}%
\dotleaders
{\Page@{#5}{#6}{#7}{#8}}
"2
\endgroup
\nobreak\smallskip
"2
\else
\Err@{\string\HL#1 not defined in this style}%
\fi}
**
\newdimen\digits
\setbox0\hbox{0.00}
\digits=\wd0
The default style for *\hl1* headers is
\medskip
\line{\quad\qquad\hbox to\wd0{1.12}\enspace A short section
\leaders\hbox to10pt{\rm\hfil.\hfil}\hfil\kern10pt79\qquad}
\medskip
\noindent
where we indent a *\quad* from the left margin, and
leave room for a double-digit number like `*1.12*', followed by
an *\enspace*, before the section title.
We have already introduced *\digits* (page~\ref{DIGITS}),
and the definition of *\hl* introduces nothing especially new:
**
\def\hl#1#2#3#4\Page#5#6#7#8{\def\hllevel@{#1}%
\ifnum\hllevel@ = 1
"2
\setentry@
{\rm\quad \let\style=\hl@@S
\hbox to\digits{\Style@#3\Style@\hfil}\enspace}%
{\rm\ignorespaces#4\unskip}%
\dotleaders
{\Page@{#5}{#6}{#7}{#8}}%
"2
\else
\Err@{\string\hl#1 not defined in this style}%
\fi}
**
In the default style, not only is `*\hl@W1*' empty, but *\hl1* doesn't
print this \<word\>, even if it has been changed by *\newword*; so
we also don't bother about printing it in the table of contents.
\section{\CS{NameHL} and \CS{Namehl}}
Finally, *\maketoc* has to deal with alternate names like *\chapter* and
*\section*. If the main file has
**
\NameHL 1 \chapter
\Namehl 1 \section
**
then these lines should also appear in the *.toc* file (before the use
of *\chapter* or *\section*, respectively).
First of all, we have to redefine *\NameHL* so that, for example,
\setbox0\hbox{\<word\>}
**
\chapter {"box0}{2}
. . .
\Page...
**
will typeset the same thing as
\setbox0\hbox{\<word\>}
**
\HL {1}{"box0}{2}
. . .
\Page...
**
In other words, we want to
**
"hskip-20pt\def\chapter#1#2#3\Page{\HL{1}{#1}{#2}#3\Page}
**
(we don't need braces around the second *#3*, since it is delimited by
*\Page*). So in general we want *\NameHL#1#2* to mean
**
\def#2##1##2##3\Page{\HL{#1}{##1}{##2}##3\Page}
**
and, similarly, we want
*\Namehl#1#2* to mean
**
\def#2##1##2##3\Page{\hl{#1}{##1}{##2}##3\Page}}
**
\section{\CS{maketoc}}Putting all this together, our definition of
*\maketoc* is:
\CC**
\def\maketoc{\checkmainfile@ "8STFMAKETOC"8
\par\vfill\break
"2
\begingroup
\noset@ \unlabel@
"2
\let\nopunct=\relax \let\nospace= \relax
"2
\let\overlong=\relax
"2
\everypar{}\parindent=0pt
\lineskiplimit=0pt
"2
\def\HL##1##2##3##4\Page##5##6##7##8{%
\def\HLlevel@{##1}%
"2
\ifnum\HLlevel@=1
\bigbreak
"2
\begingroup
\def\\{\unskip\space\ignorespaces}%
"2
\setentry@{\bf\def\next@{##2}\ifx\next@\empty
\else##2\space\fi
\let\style=\HL@@S \Style@##3\Style@
\ifemptynumber@\else\space\fi}%
{\bf\ignorespaces##4\unskip}\dotleaders
{\Page@{##5}{##6}{##7}{##8}}%
"2
\endgroup
"2
\nobreak\smallskip
"2
\else
\Err@{\string\HL##1 not defined in this style}%
\fi}%
"2
\def\hl##1##2##3##4\Page##5##6##7##8{%
\def\hllevel@{##1}%
"2
\ifnum\hllevel@=1
"2
\setentry@{\rm\quad\let\style=\hl@@S
\hbox to\digits{\Style@##3\Style@\hfil}\enspace}%
{\rm\ignorespaces##4\unskip}\dotleaders
{\Page@{##5}{##6}{##7}{##8}}%
"2
\else
\Err@{\string\hl##1 not defined in this style}%
\fi}%
"2
\def\NameHL##1##2{\def##2####1####2####3\Page
{\HL{##1}{####1}{####2}####3\Page}}%
"2
\def\Namehl##1##2{\def##2####1####2####3\Page
{\hl{##1}{####1}{####2}####3\Page}}%
"2
\centerline{\bf\maketoc@W}%
\vskip30pt plus10pt minus10pt
\input\mainfile@.toc
\endgroup}
**
\nopunct\section{Lists of Figures, Tables, etc.}
The commands
**
\makelistFigures
\makelistTables
**
are defined directly in terms of the more general *\makelist* command,
\CC**
\def\makelistFigures{\makelist\c{F}List of
Figures\endmakelist}
\def\makelistTables{\makelist\c{T}List of
Tables\endmakelist}
**
The syntax has been changed from that of the \lamstex~Manual, page~92,
to conform with the general \amstex\ and \lamstex\ syntax for constructions
that allow *\\* to be used to indicate line breaks.
*\makelist\c#1#2\endmakelist*,
like *\maketoc*, first uses the test\linebreak *\checkmainfile@*, and then
ends the previous page. After this we want to add
**
\noset@ \unlabel@
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
\everypar={}\parindent=0pt
\lineskiplimit=0pt
**
just as in *\maketoc*.
Then
*\makelist* will
**
\def\listclass@{#1}
**
so that, when we *\input* the *.tic* file we will know which of the
*\island*'s to process.
Next *\makelist* must redefine *\island*.
In the case of *\HL#1...*,
once we had defined *\HLlevel@* as *#1*,
the style control sequence *\HL@@S* was defined, so that we could
*\let\style=\HL@@S* in our definition of *\HL*. A construction
introduced with *\NameHL1* is basically just a synonym for *\HL1*,
so we did not need to consider *\HL@@@S*, defined in terms of *\HLtype@*.
But the situation is different for *\island*'s, where we have only
*\island@@@S*, defined in terms of *\islandtype@*, which is *\island* for
an explicitly typed *\island*, but *\Figure* for a *\Figure*, etc.
To deal with this situation,
\setbox0\hbox{\<Figure number\>}
\setbox1\hbox{\<caption\>}
**
\Figure {"box0}
"copy1
\Page ...
**
in the *.tic* file will translate
to
\setbox0\hbox{\<Figure number\>}
\setbox1\hbox{\<caption\>}
\Litbox2=**
\island \at@\Figure \c{F}{Figure}{"copy0}
"copy1
\Page ...
**
$$\vcenter{\box2}\tag"\style{\bf A}"$$
---here *\at@* is simply an arbitrarily chosen \lamstex\ control sequence
that the user can't insert---%
while an explicitly typed *\island*, like
\setbox0\hbox{\<map number\>}
**
\island \c{M}{Map}{"box0}
**
will be regarded as
\setbox0\hbox{\<map number\>}
**
\island \at@\island \c{M}{Map}{"box0}
**
so that eventually everything reduces to a common case.
We begin by redefining *\island* in terms of a *\futurelet*, to see whether
*\at@* follows:
**
\def\island{\futurelet\next\island@}
\def\island@{\ifx\next\at@\expandafter\island@@\else
\expandafter\island@@@\fi}
**
*\island@@*, where *\at@* follows, has 9 arguments:
**
\long\def\island@@\at@#1\c#2#3#4#5\Page#6#7#8#9
**
For example, in ({\bf A}), *#1* is `*\Figure*', *#2* is `*F*', *#3* is
`*Figure*', *#4* is the \<Figure number\>, and *#5* is the \<caption\>.
The definition of *\island@@*
is similar to
the definition of *\HL* except that:
\list\item we use argument *#1* to define
*\islandtype@*, rather than *\HLlevel@*;
\item we print *#3* rather than the \<word\> before the \<Figure number\>;
\item
we process only those *\island*'s whose class *#2* is the *\listclass@* for
the list we are printing.\endlist
**
\long\def\island@@\at@#1\c#2#3#4#5\Page#6#7#8#9{%
\def\islandtype@{#1}%
"2
\def\next@{#2}%
"2
\ifx\next@\listclass@
"2
\setentry@
{\rm#3" \let\style=\island@@@S \Style@#4\Style@
\ifemptynumber@\else\space\fi}%
{\rm\ignorespaces#5\unskip}%
\dotleaders
{\Page@{#6}{#7}{#8}{#9}}%
\fi}
**
The definition of *\island@@@*, when no *\at@* follows, is reduced to
the case where *\at@\island* follows:
**
\long\def\island@@@\c#1#2#3#4\Page#5#6#7#8{%
\island@@\at@\island
\c{#1}{#2}{#3}#4\Page{#5}{#6}{#7}{#8}}
**
\bigskip
When something like
**
\newisland\map\c{M}{Map}
**
appears, an occurrence of
\setbox0\hbox{\<map number\>}
\setbox1\hbox{\<caption\>}
**
\map {"box0}
"box1
\Page ...
**
should translate to
\setbox0\hbox{\<map number\>}
\setbox1\hbox{\<caption\>}
**
\island \at@\map \c{M}{Map}{"box0}
"box1
\Page ...
**
In other words, we should
**
\long\def\map#1#2\Page#3#4#5#6{\island \at@\map
\c{M}{Map}{#1}#2\Page{#3}{#4}{#5}{#6}}
**
So in general, we want to
**
\def\newisland#1\c#2#3{%
\long\def#1##1##2\Page##3##4##5##6{%
\island\at@#1\c{#2}{#3}{##1}##2%
\Page{##3}{##4}{##5}{##6}}}
**
Since *\Figure* and *\Table* are *\island* classes that are assumed to
be present in all styles, we should also add
**
\newisland\Figure\c{F}{Figure}
\newisland\Table\c{T}{Table}
**
Putting this all together, we have
\CC**
\def\makelist\c#1#2\endmakelist{\checkmainfile@
\par\vfill\break
"2
\begingroup
"2
\noset@ \unlabel@
"2
\let\nopunct=\relax \let\nospace=\relax
\let\overlong=\relax
"2
\everypar{}\parindent=0pt
\lineskiplimit=0pt
"2
\def\listclass@{#1}%
\def\island{\futurelet\next@\island@}%
"2
\def\island@{\ifx\next\at@\expandafter\island@@\else
\expandafter\island@@@\fi}%
"2
\long\def\island@@\at@##1\c##2##3##4##5\Page##6##7##8##9{%
\def\islandtype@{##1}%
\def\next@{##2}%
"2
\ifx\next@\listclass@
"2
\setentry@{\rm##3
\let\style=\island@@@S \Style@##4\Style@
\ifemptynumber@\else\space\fi}%
{\rm\ignorespaces##5\unskip}\dotleaders
{\Page@{##6}{##7}{##8}{##9}}%
"2
\fi}%
"2
\long\def\island@@@\c##1##2##3##4\Page##5##6##7##8{%
\island@@\at@\island\c{##1}{##2}{##3}##4\Page
{##5}{##6}{##7}{##8}}%
"2
\def\newisland##1\c##2##3{\long\def##1####1####2\Page
####3####4####5####6{%
\island\at@##1\c{##2}{##3}{####1}####2\Page
{####3}{####4}{####5}{####6}}}%
"2
\newisland\Figure\c{F}{Figure}%
\newisland\Table\c{T}{Table}%
"2
\vbox{\Let@\tabskip\centering@\halign to\hsize
{\bf\hfil\ignorespaces##\unskip\hfil\cr#2\crcr}}%
\vskip30pt plus10pt minus10pt
\input\mainfile@.tic
\endgroup}
**
\section{Fini}Then, as in section~\Sref{DONE},
we finish with
\CC**
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
\ch@ck#1#4#2\allocationnumber=\count1#1
\global#3#5=\allocationnumber
\wlog{\string#5=\string#2\the\allocationnumber}}
\catcode`\@=\active
**
\chapter Back matter\\The index\endchapter
\runningchapter{Back matter; the index}
Although the ``back matter'' may include the bibliography, and other matter,
the default style file *lamstex.stb* is used only for the index. As explained
in Chapter~13 of the \lamstex~Manual, the *\makeindex* command is going to
read in an *.xdx* ``expanded index file'', which is produced by the *index*
program from the *.ndx* file that \lamstex\ writes. The *index* program is
discussed in the next chapter. In this chapter, we are only concerned with
typesetting the *.xdx* file. In the default style, we will be using a
two-column format, with balanced columns at the end.
Page 114 of The \lamstex~Manual
gives
a sample piece from an
*.xdx* file that illustrates almost all the features that we have to
consider;
the only additional feature is *\PageSpan*, mentioned on page~117.
\section{Preliminaries\label{BMPRE}}As with *lamstex.stf*, we begin with
\CC**
\catcode`\@=11
\let\alloc@=\alloc@@
**
Since *"1* has a special role of indicating options in
index entries, if an index entry actually had a \ast\ in it that symbol
will appear as *\asterisk*. So we will need to state
\dotC**
\let\asterisk="1
**
so that *\asterisk* will print out a \ast\,. We've printed dotted lines
around this definition, since it will
actually
only be made within the definition
of *\makeindex*---for any
material inserted before or after *\makeindex*, the control sequence
*\asterisk* will simply be
undefined.
As with the bibliography (section~\Sref{SBMACS}),
we will be redefining *\lkerns@* and
*\nkerns@*
for properly placing punctuation before line-breaking penalties,
\dotC**
\def\lkerns@{\null\kern-1sp\kern1sp}
\def\nkerns@{\null\kern-2sp\kern2sp}
**
(we don't really need the *\null*'s that occurred previously, since we're not
setting *\vbox*'s, but for simplicity we might as well stick to the old
definitions).
Once again, we use dotted lines,
since the redefinitions will only be made later,
by *\makeindex*, so that line
breaking commands won't change their meaning until we are actually setting
the index.
On the other hand, we can give
a definition of *\adjustpunct@*
(section~\Sref{BIBMACS}) right now; it differs from the previous definition
only in the omission of
*\closequotes@*:
\CC**
\def\adjustpunct@#1{\count@\lastkern
\ifnum\count@=0 #1\else
\ifnum\count@>2 #1\else
\ifnum\count@<-2 #1\else
\unkern\unkern\setbox0=\lastbox
\skip@=\lastskip \unskip
\count@@=\lastpenalty \unpenalty
\ifnum\count@ = 2 \unskip \setbox0=\lastbox\fi
\ifdim\skip@ = 0pt \else \hskip\skip@ \fi
#1%
\ifnum\count@=2 \null\hfill\fi
\penalty\count@@
\fi\fi\fi}
**
(Since *\adjustpunct@* is stated within *lamstex.tex* itself,
we could simply state
*\let\closequotes@=\relax*, but restating the definition is preferable
in case *\purge{bib}* has been used.)
In all the commands appearing in the *.xdx* file,
\setbox0\hbox{etc.,}
**
\Entry 10{acetyl-CoA}{}{}{}{}
\Page {34}
"box0
**
we are going to want to ignore the space after the last *}*.
In addition, since blank lines might be introduced during editing,
or by ``error messages'',
we will want to skip over any such blank lines---we can't afford to
introduce a *\par* until we know that there are no more page numbers left to
be printed.
\footnote{In version~*1* of \lamstex@,
the *index* program was careful not to introduce
any blank lines, inserting a~ *%* before an otherwise blank line if
necessary, and users were warned not to introduce blank lines. However,
it seems preferable to have the macros
skip the blank lines, since they can make the
*.xdx* file look so much nicer.}
So we will use *\FNSS@* to get the first non-space token, and then
use a
*\futurelet\next* to see if the next token is
*\par*, which should also be discarded:
\CC**
\def\ignorepars@{\FNSS@\ignorepars@@}
\def\ignorepars@@{\ifx\next\par
\def\next@\par{\futurelet\next\ignorepars@@}\else
\let\next@=\relax\fi\next@}
**
One of the main tasks of the *lamstex.stb* macros is to provide suitable
*\mark*'s so that appropriate ``continuation'' lines may be written at the
top of a page
when a page
break has occurred within an index entry, or subentry, etc. And because of
this,
column-breaking penalties will require more care.
The
*\columnbreak* command was not mentioned in the Manual, but
was added for the
*paper* style, and mentioned in the Installation~Manual. In version~*2*
we are also supplying *\nocolumnbreak* and *\newcolumn* (for a short
column), although *\columnbreak* is really the only important one.
Although these commands
essentially insert penalties in vertical mode, we have to make sure
that the penalties occur at the proper time with respect to the
*\mark*'s that are emitted by the *\LETTER* and *\Entry* construction.
The column-breaking macros work quite differently from the line-breaking
macros because a penalty cannot be removed once it has been placed on the
main vertical list:
they
will not insert any penalties directly, but
will simply set the value of a counter, for later use. We declare the counter
now,
\CC**
\newcount\ctype@
**
but the definitions
\dotC**
\def\nocolumnbreak{\ctype@=1 }
\def\columnbreak{\ctype@=2 }
\def\newcolumn{\ctype@=3 }
**
will only be given within the definition of *\makeindex*.
We also need to
declare a new counter to store the value of *\ctype@*, for use by the
*\output* routine, after other constructions have returned *\ctype@* to~*0*:
\CC**
\newcount\Ctype@
**
It also turns out that column breaks have to be treated quite differently
depending on whether they are inserted in the left column or the right
column, and we will need a flag
\CC**
\newif\ifleftcolbreak@
**
Now we define a routine *\cbreak@#1#2* that uses the value of *\ctype@*,
before resetting it to ~*0*.
The definition begins
**
\def\cbreak@#1#2{\ifcase\ctype@#1\or\nobreak#2\else
. . .
**
Thus, if *\ctype@* is *0* (the usual situation, when no column-breaking
command has recently been given), we simply insert *#1*, which will normally
be penalty and glue. If *\ctype@* is~*1* (because a *\nocolumnbreak*
command has recently been given), we instead insert *\nobreak* and then
*#2* (which would normally be *#1*
without the penalty). If *\ctype@* is *2* or *3* (because a *\columnbreak*
or *\newcolumn* command has recently been given), we simply insert a
*\break*. Then we reset *\ctype@* to~*0*. Before doing that last step,
however, we store *\ctype@* in *\Ctype@*. Moreover, we set
*\ifleftcolbreak@* to be false if $\hbox{*\pagetotal*}>\hbox{*\pageheight*}$
(i.e., we already have enough on the page for the first column), but
true otherwise:
\CC**
\def\cbreak@#1#2{%
\ifcase\ctype@#1\or
"2
\nobreak#2\else
"2
\global\leftcolbreak@true
\ifdim\pagetotal > \pageheight@
\global\leftcolbreak@false
\fi
"2
\global\Ctype@=\ctype@
\break
\fi
\ctype@=0 }
**
The value of *\Ctype@* will be used by the *\output* routine, which will
then globally reset *\Ctype@* to ~*0*.
We have another flag
\CC**
\newif\ifshortlastcolumn@
**
for a final index feature not mentioned in the \lamstex~Manual,
\dotC**
\def\shortlastcolumn{\shortlastcolumn@true}
**
if we want the right
column on the last page of the index
to end short, instead of being spread out to match
the height of the left column.
\section{\CS{LETTER} and \CS{Entry}}
The first *\Entry* after a *\LETTER* will be treated somewhat specially, so
we will need a flag
\CC**
\newif\ifletter@
**
to tell when a *\LETTER* line has just been set.
*\LETTER* will
end the previous paragraph (in which the various page numbers for a previous
entry are being set) and
emit a *\mark{}* to clear the marks.
Then we want
**
\penalty-200
\bigskip
**
to encourage a page break (which really means a column break, since we will
be setting in double columns).
More precisely, we will use
**
\cbreak@{\penalty-200 \bigskip}\bigskip
**
Thus, when a *\nocolumnbreak* command has just appeared, we insert only the
*\bigskip*, and when a *\columnbreak* or *\newcolumnbreak* command
has just appeared, we just insert a *\break*.
Then we set *\ifletter@* to be true,
center the letter in bold face in its column, and finally
add a\linebreak *\nobreak\medskip*:
\dotC**
\def\LETTER#1{\par
\mark{}%
\cbreak@{\penalty-200 \bigskip}\bigskip
\letter@true
\centerline{\bf#1}%
\nobreak\medskip}
**
As usual, the dotted lines indicate that
this is a definition that will actually be included within the
definition of *\makeindex*.
To deal with the necessary *\mark*'s to be provided by
*\Entry*, it will be convenient to have five token lists:
\CC**
\newtoks\marktoks@i
\newtoks\marktoks@ii
\newtoks\marktoks@iii
\newtoks\marktoks@iv
\newtoks\marktoks@v
**
Moreover, we will use a flag
\CC**
\newif\ifentry@
**
which *\Entry* will set true, and each *\Page* will set false.
\def\di{{\it d}$_{\text1}$}
\def\dii{{\it d}$_{\text2}$}
Some aspects of our *\Entry* macro are particular to the default style,
namely the particular manner in which entries and subentries are typeset.
But the really
interesting aspect of *\Entry* is the way that
it uses the first
two arguments (\di, \dii, in the notation of
page~115 of the \lamstex~Manual), to determine which *\mark*'s should be
emitted; these *\mark*'s can be used by any style to define ``continuation
lines'' of any desired sort. To deal with all possibilities, we will need a
new counter
\CC**
\newcount\dii@
**
which will hold the value of \dii\ for the {\it previous\/}
*\Entry*.
The definition begins
**
\def\Entry#1#2#3#4#5#6#7{\par\entry@true
\marktoks@i={#3}\marktoks@ii={#4}\marktoks@iii={#5}%
\marktoks@iv={#6}\marktoks@v={#7}%
\ifcase#1%
\or
. . .
**
Thus, since the
case $\hbox{*#1*}=\hbox{\di}=\hbox{0}$
is not supposed to occur, we consider first
the case $\hbox{*#1*}=\hbox{\di}=\hbox{1}$,
which means that we have a first order entry, i.e.,
*#4*, \dots, *#7* are empty;
in this case $\hbox{*#2*}=\hbox{\dii}$
should be 0, since this new first order
entry can't have any number of groups agreeing with the previous entry.
We begin with
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent@
\mark{10{\the\marktoks@i}}%
\hangafter 1 \hangindent=.5em{#3}%
**
Thus:
\list\item
We issue a *\mark{}* to clear the marks, unless the *\Entry* comes
right after a *\LETTER*, which has already done this.
\item If a *\nocolumnbreak* appeared right before the *\Entry* we
add a *\nobreak*; and if a *\columnbreak* or *\newcolumn* appeared,
we add a *\break*, and also set *\ifleftcolbreak@* to the appropriate value
and store *\ctype@* in *\Ctype@* before restoring *\ctype@* to~ *0*.
\item
Then we start an unindented paragraph, which begins
with a *\mark*,
**
\mark{10{\the\marktoks@i}}%
**
containing *#1#2*, and then a single group containing
*#3* (without any expansion).
The
**
\hangafter1 \hangindent=.5em{#3}%
**
means
that after the entry *#3* is printed we are set up for printing the
various page numbers, with hanging indentation if there are so many that they
won't fit on a line. We enclose *#3* in a group, in case it involves a font
change command, and are careful not to allow a space after *{#3}*, since
punctuation still has to be added.
\endlist
When the paragraph with this entry is completed,
the *\mark{10{...}}*\linebreak will migrate out so that it occurs right after
the first line (before any\linebreak *\baselineskip* glue); consequently,
there will be no legal breakpoint between the *\mark* and this first line,
containing the typeset *{#3}*.
If a page break occurs after this entry, but
before another entry, which contributes a new *\mark*,
then after the
page has been *\output* the value of
*\botmark*
will be
**
10{#3}
**
When a style file has to add continuation lines at the beginning of the next
page, the *10* will tell it that the style broke at a main entry, which will
be contained in the next group.
(Actually, we will be using *\splitbotmark* rather than
*\botmark* when we do two-column setting.)
In summary, our definition begins:
**
\def\Entry#1#2#3#4#5#6#7{\par\entry@true
\marktoks@i={#3}\marktoks@ii={#4}\marktoks@iii={#5}%
\marktoks@iv={#6}\marktoks@v={#7}%
\ifcase#1%
\or
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent@
\mark{10\the\marktoks@i}%
\hangafter1 \hangindent=.5em{#3}%
\or
**
Now let's consider the next case, $\hbox{\di}=\hbox{*#1*}=\hbox{2}$,
so that we have a first order
subentry. In this case $\hbox{\dii}=\hbox{*#2*}$
may be either ~0 or~1. When $\hbox{*#2*}=\hbox{0}$, we
have a subentry that does {\it not\/} have the same main entry as the
previous line, like the situation
**
\Entry 10{abracadabra}{}{}{}{}
\Page {5}
\Entry 20{acetyl-CoA}{action of}{}{}{}
\page {32}
**
As mentioned on page~116 of the \lamstex~Manual, in some styles this might
be printed as
{\bigskip\eightpoint\leftskip=30pt \noindent
abracadabra, 5\newline
acetyl-CoA, action of, 32
\bigskip}
\noindent
In the default style, we will still print
{\bigskip\eightpoint\leftskip=30pt \noindent
abracadabra, 5\newline
acetyl-CoA\newline
\null\hskip5pt action of, 32
\bigskip}
\noindent
but we still have to treat the *\mark*'s differently for the
cases $\hbox{\dii}=\hbox{*#2*}=\hbox{0}$ and $\hbox{\dii}=\hbox{*#2*}=
\hbox{1}$.
For the case $\hbox{*#2*}=\hbox{0}$ we want
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent
\mark{20{\the\marktoks@i}{\the\marktoks@ii}}%
\hangafter1 \hangindent=.5em{#3}\par\nobreak
\noindent\hangafter1 \hangindent=1.5em\quad{#4}%
**
Thus:
\list\item
We clear the previous mark (the one for *abracadabra*).
\item We emit the mark
\setbox0\hbox
{$\bigl[$*20{acetyl-CoA}{action of}*, in the above example$\bigr]$}
**
20{#3}{#4} "box0
**
and then set up the proper format for printing things.
If the page breaks in the middle of this entry, then *\botmark* will have
the value
**
20{#3}{#4}
**
and the *\output* routine will be clued in as to
what sort of continuation lines to
add.
\endlist
The other case, when $\hbox{*#2*}=\hbox{1}$,
corresponds to the more common situation
where we have something like
**
\Entry 10{acetyl-CoA}{}{}{}{}
\Page {32}
\Entry 21{acetyl-Coa}{action of}{}{}{}
\Page {45}
**
Here we will use
**
\mark{10{\the\marktoks@i}}%
\cbreak@\relax\relax
\noindent@
\mark{21{\the\marktoks@i}{\the\marktoks@ii}}%
\hangafter 1 \hangindent=1.5em\quad{#4}
**
Even when the *\cbreak@* contributes nothing (the usual situation), there
is a legal break point between the first *\mark* and the *\noindent@*'ed
paragraph that follows, because of the *\parskip* glue (possibly *0pt*)
before this paragraph.
If the page breaks at this point, then *\botmark* will be this first
**
\mark{10{acetyl-CoA}}
**
which is precisely right: we have broken in the middle of a first level
entry. If the page breaks after the sub-entry begins, but before a new
*\Entry*, which contributes a new *\mark*, then *\botmark* will be
**
21{acetyl-CoA}{action of}
**
again giving the *\output* routine all the information it needs to decide
what sort of continuation lines to insert.
\small
Although we are using *\cbreak@\relax\relax* in all clauses of our
*\Entry* definition, other styles might give more detailed choices. For
example, it might be considered
better to break right before an entry than right before
a subentry. We might use something like
**
\cbreak@{\ifletter@\else\penalty-20 \fi}\relax
**
for the case $\hbox{*#1*}=1$, thereby slightly encouraging a column break
before main entries, except those immediately following a *\LETTER*.
\endsmall
The case $\hbox{\di}=\hbox{*#1*}=\hbox{3}$
begins similarly: When $\hbox{*#2*}=\hbox{0}$ we use
**
\ifletter@\else\mark{}\fi
\cbreak@\relax\relax
\noindent
\mark{30{\the\marktoks@i}{\the\marktoks@ii}{\the\marktoks@iii}}%
\hangafter1 \hangindent=.5em{#3}\par\nobreak
\noindent@\hangafter1 \hangindent=1.5em\quad{#4}\par\nobreak
\noindent@\hangafter1 \hangindent=2.5em\qquad{#5}%
**
and when $\hbox{*#2*}=\hbox{1}$ we use
**
\mark{10{\the\marktoks@i}}%
\cbreak@\relax\relax
\noindent@
\mark{31{\the\marktoks@i}{\the\marktoks@ii}{\the\marktok@iii}}%
\hangafter1 \hangindent=1.5em\quad{#4}\par\nobreak
\noindent@\hangafter1 \hangindent=2.5em\qquad{#5}%
**
But the case $\hbox{*#2*}=\hbox{2}$
is a little different, because the previous entry
might have been an *\Entry 20* or an *\Entry 21*, and to provide the style
with all possible information, we want to supply the correct result. So we
use
**
\mark{2"9\number\dii@"9{\the\marktoks@i}{\the\marktoks@ii}}%
\cbreak@\relax\relax
\noindent@
\mark{32{\the\marktoks@i}{\the\marktoks@ii}{\the\marktoks@iii}}%
\hangafter1 \hangindent=2.5em\qquad{#5}%
**
where *\dii@* will have the proper value, because, at the very end of
this long *\ifcase* (with sub *\ifcase*'s)
we finish off the whole definition of *\Entry* with
**
\dii@=#2\relax
\letter@false\ignorepars@}
**
We won't bother writing out the whole definition, since these parts explain
everything interesting that is going on (moreover, the whole definition
appears only within the definition of *\makeindex*).
\nopunct\section{\CS{Page}, etc.\label{IPAGE}}
Using *\adjustpunct@* (section~\Sref{BMPRE}), we will define
*\Page* for the index setting by
\dotC**
\def\Page#1{\ifentry@\adjustpunct@,\enspace\else
\adjustpunct@, \fi\entry@false{#1}\ignorepars@}
**
In other words, the first *\Page* after an *\Entry*, when *\ifentry@* is
still true,
will add a comma after
the entry, and then an *\enspace*, while successive *\Page*'s, for which
*\ifentry@* will be false,
will simply
add a comma after that page number and then an ordinary space
(with suitable juggling of line-breaking penalties).
We put *#1* in a group in case it involves a font change.
The *\Pagespan*, *\Topage* combination requires a bit more
manipulation, because
the *index* program may have produced something like
**
\Pagespan {123}
\Topage {123}
**
which should be printed simply as `123', rather than as `123@--123'.
We begin with
\dotC**
\def\Pagespan#1{\ifentry@\adjustpunct@,\enspace\else
\adjustpunct@, \fi
\entry@false\def\frompage@{#1}{#1}\ignorepars@}
**
Thus, we supply punctuation just as with *\Page*, and before printing
*#1* we also
store
*#1* in *\frompage@*, for use with *\Topage*, defined by
\dotC**
\def\Topage#1{\def\next@{#1}\ifx\next@\frompage@
\else\hbox{--}{#1}\fi\ignorepars@}
**
The *\hbox{--}* gives an en-dash at which a line break can't occur
(it is what the
\lamstex\ construction *@--* produces).
The variant *\PageSpan#1#2*, which has a control sequence as
its first argument, puts in punctuation in the same manner as
*\Pagespan*, and also
stores the page argument, *#2*, in *\frompage@*, as well as the
control sequence, *#1*, in *\pagecs@*. Then it begins a group in which
the definition of *\Topage* will be changed, so that the *\Topage* following
*\PageSpan* can act differently than when it follows *\Pagespan*:
\dotC**
\def\PageSpan#1#2{\ifentry@\adjustpunct@,\enspace
\else\adjustpunct@, \fi\entry@false
\def\pagecs@{#1}\def\frompage@{#2}%
\bgroup\let\Topage=\Topage@\ignorepars@}
**
Then *\Topage@* will apply *\pagecs@* to the pages spanned (or to
a single page if the two numbers are the same), and supply the *\egroup* to
match the *\bgroup*:
\CC**
\def\Topage@#1#2{\def\next@{#2}\ifx\next@\frompage@
\pagecs@{\frompage@}\else
\pagecs@{\frompage@\hbox{--}#2}\fi
\egroup\ignorepars@}
**
We use *\pagecs@{...}*
in case *\pagecs@* is a control sequence with
an argument; the *\bgroup* and *\egroup* provide the necessary extra level of
grouping in case *\pagecs@* is a font change instruction. We might as
well give the definition of *\Topage@* now, rather than within the
definition of *\makeindex*, since *\Topage@* can't be typed by the user
anyway.
\nopunct\section{\CS{Xref}, etc.}
The description of the *"1x* option
on page~108 of the \lamstex~Manual, and the output it supposedly produces in
the *.xdx* file, as described on page~115 of the Manual, is incorrect.
\footnote{As mentioned on pages~8--9 of the \lamstex\
Installation Manual.}
There are actually {\it two\/} options, *"1x* and *"1X*. The *"1x* option
is to be used
when only a cross-reference is desired, and not a reference to the page on
which the entry is marked, while the *"1X* option indicates a reference to
the page on which the entry is marked, together with a cross reference.
If an entry is always marked with the *"1x* option, then the pages on which
it is marked are completely irrelevant, and it will give rise to an
*\Entryxref* line in the *.xdx* file (possibly followed by various
*\Morexref* lines). Otherwise, it will give rise to something like
\Litbox0=**
\Entry ...
\Xref ...
\Morexref ...
. . .
\Page ...
\Page ...
\Xref ...
\Morexref ...
. . .
**
$$\vcenter{\box0}\tag"\style{\bf A}"$$
with *\Xref...* material occurring both before and after the *\Page*'s because
some styles might want to print the `{\it see also\/}' before the page
numbers instead of after them.
In any case, as the Manual shows on page~115, each *\Xref*, *\Morexref*,
and *\Entryxref* will contain *\See*, which can be defined as needed.
In the default style we will be ignoring the *\Xref* and *\Morexref*'s in
({\bf A}) that come before the first *\Page*;
this means that we want
*\Xref* and *\Morexref* to operate only when *\ifentry@* is false.
*\Xref*, which will occur after some *\Page*, will add a semi-colon after
the page, and then print `{\it see also\/} ' before its argument.
As with the bibliography macros, we use *\semicolon@* instead of~ *;* for
the benefit of French styles (section~\Sref{SEMICOL}), and we add *\/* before
it,
\dotC**
\def\Xref#1{\ifentry@\else
\def\See##1{\/\adjustpunct@\semicolon@\space
{\it see~also\/}~##1}{#1}\fi\ignorepars@}
**
while *\Morexref* will simply add a comma after the previous
cross-reference page, and then a space:
\dotC**
\def\Morexref#1{\ifentry@\else
\def\See##1{\adjustpunct@, ##1}{#1}\fi\ignorepars@}
**
An *\Entryxref* is basically just an *\Entry*, after which we
add the final argument rather than succeeding *\Page*'s.
\dotC**
\def\Entryxref#1#2#3#4#5#6#7#8{%
\Entry{#1}{#2}{#3}{#4}{#5}{#6}{#7}%
\def\See##1{\adjustpunct@, {\it see\/}~##1}%
{#8}\ignorepars@}
**
(The *\adjustpunct@* is added in case the user adds a line-breaking
command, like
**
\Entryxref 10{adrenalin}{}{}{}{}{\linebreak\See {epinephrine}}
**
by hand.)
\small
Suppose that we want to print the `{\it see also }'
before the page numbers instead of after them, which means that
we need to
use the *\Xref*'s and *\Morexref*'s that
appear before the first *\Page*,
ignoring *\Xref*'s and *\Morexref*'s
following a *\Page*.
For this we would introduce a new flag
**
\newif\ifxref@
**
which *\Xref* would set true and *\Entry* would set false, and then
we could use definitions like
**
\def\Xref#1{\ifentry@
\def\See##1{ {\it see also\/} ##1}{#1}\fi\ignorepars@}
\def\Morexref#1{\ifentry@
\def\See##1{\adjustpunct@, ##1}{#1}\fi\ignorepars@}
\def\Page#1{\ifxref@\newline\else
\ifentry@\adjustpunct@,\enspace\else
\adjustpucnt@, \fi\fi\entry@false{#1}\ignorepars@}
**
Then entries without cross-references would appear as before, while
entries with cross-references would appear as
{\bigskip\eightpoint\leftskip30pt
acetyl-CoA {\it see also\/} derivative, pyruvate
\hskip5pt 30, 56, 78
\bigskip}
\noindent Instead of the *\newline* we might prefer `*. *' or
perhaps *\Xref* would add `*({\it see also\/} *' while
*\Page* would add `*) *' instead of *\newline*.
\andsmall
Similarly,
any punctuation after the last page number would have to be added by
the next *\Entry* (the definition
of *\makeindex* would also have to take care of the last *\Entry* specially).
But
no one ever adds this punctuation, so why worry about it.
\endsmall
\section{Preliminaries for double columns}
We first declare
a \<dimen\> register to store *\vsize*,
\CC**
\newdimen\pageheight@
\pageheight@=\vsize
**
since *\vsize* will be changed when
we are storing material for double columns,
and a dimension *\doublepageheight@*, which is a little more than twice
*\pageheight@*,
\CC**
\newdimen\doublepageheight@
\doublepageheight@=2\pageheight@
\advance\doublepageheight@ by 1 pc
**
We also declare a \<dimen\> register
to store the original *\hsize*,
\CC**
\newdimen\pagewidth@
\pagewidth@=\hsize
**
The *\makeindex* routine will be setting columns 3~inches wide, so we will be
changing *\hsize*. Consequently, we must redefine *\makeheadline* and
*\makefootline* from *plain* \tex@, so that *\line* ($=${}*\hbox to\hsize*)
is replaced by *\hbox to\pagewidth@*:
\CC**
\def\makeheadline{\vbox to 0pt{\vskip-22.5pt
\hbox to\pagewidth@{\vbox to 8.5pt{}\the\headline}\vss}%
\nointerlineskip}%
\def\makefootline{\baselineskip=24pt
\hbox to\pagewidth@{\the\footline}}%
**
(The definition of *\makeheadline* isn't really needed for the default style,
since we are going to keep *\headline={}*, but we might as well take care of
the general mechanism.)
As in Appendix E of {\it The \tex book}, page~417,
we will be setting ``pages''
of
length *\doublepageheight@*, so that we can
automatically balance the columns on the last page.
We need another flag
\CC**
\newif\iffirstindexpage@
**
since the first page of the index is special, having a header `{\bf INDEX}'
that extends across both columns.
\section{\CS{makeindex}}
The *\makeindex* routine begins
\setbox0\hbox{\<all previous definitions enclosed in dotted lines}
\setbox1\hbox{\qquad(including the definition of *\Entry*)\>}
**
\def\makeindex{\checkmainfile@\par\vfill\break
\begingroup
"box0
"box1
\hsize=3in
**
Of course all *#*'s in any of those \<previous definitions\> are changed to
*##*'s.
Next we set
**
\global\vsize=\doublepageheight@
**
so that we will have
accumulated slightly more than we need to fill both columns of the page
before the *\output* routine is called (we use *\global* here because
it will be required later, when we set *\vsize* within the *\ouput* routine).
And
we set
**
\maxdepth=\maxdimen
**
so that the depth of
*\box255* will always be the actual depth of its last line; this is
needed at one point later (compare {\it The \tex book}, page~262@--263).
Then we set
**
\global\firstindexpage@true
\global\advance\vsize by -60pt
**
The
60~points is need to leave room for a 30~point heading above both columns.
Next,
we
set
**
\everypar={}\parindent=0pt
**
just as a precaution, and then
**
\rightskip=0pt plus3em \spaceskip=.3333em \xspaceskip=.5em
**
for ragged
right setting (we allow even more ``raggedness'' than the definition of
*\raggedright* in *plain* \tex)@.
And then we want to change the *\output* routine to one called
**
\doublecolumns@
**
before reading in the appropriate *.xdx* file; after this file has been
read we will issue an empty *\mark{}*,
change the *\ouput* routine to one called
*\balancecolumns@*, for the final page of the index, and then supply
the *\endgroup* that matches the *\begingroup* at the beginning of the
definition. For anything that follows the *\makeindex*, we will once
again have *\output="allowbreak{\plainoutput}*. However, *\vsize* has
been globally changed, so we must reset it to *\pageheight@*.
\setbox0\hbox{\<definitions from before\>}
\CC**
\def\makeindex{\checkmainfile@
\par\vfill\break
\begingroup
"box0
\hsize=3in
"2
\global\vsize=\doublepageheight@
"2
\maxdepth=\maxdimen
"2
\global\firstindexpage@true
"2
\global\advance\vsize by -60pt
"2
\everypar={}\parindent=0pt
"2
\rightskip=0pt plus3em \spaceskip=.3333em \xspaceskip=.5em
"2
\output={\doublecolumns@}%
\input\mainfile@.xdx
\mark{}%
\output={\balancecolumns@}%
\vfil\break
\endgroup
\global\vsize=\pageheight@}
**
\section{\CS{combinecols\@}}
Both *\doublecolumns@* and *\balancecolumns@* will store the two columns
in *\box0* and *\box2* and then
use the routine
*\combinecolumns@*, which prints these boxes
side by side, together with the proper headline and footline.
**
\def\makeindex@W{Index}
"slip
\def\combinecolumns@{%
"2
\setbox\outbox@=\vbox{\makeheadline
"2
\vbox to\pageheight@{\boxmaxdepth=\maxdepth
"2
\iffirstindexpage@
"2
\vbox to30pt{\vskip10pt
\hbox to\pagewidth@{\hfil\bf
\uppercase\expandafter{\makeindex@W}\hfil}\vfil}
"2
\nointerlineskip
\fi
"2
\wd0=\hsize \wd2=\hsize
\setbox0=\hbox to\pagewidth@{\box0 \kern.5in\box2}
\dimen@=\dp0 \box0 \kern-\dimen@\vfill}
\makefootline}
{\noexpands@ \let\style=\relax
\shipout@\box\outbox@
}
. . .
**
This is like the *\shipout@* occurring in our definition of
*\plainoutput* (page~\ref{DEFPLOUT}),
except that the *\pagebody* must be replaced by
a *\vbox to*\linebreak*\pageheight@*,
containing the two boxes with a separation
of *.5in*. There are also two minor adjustments to be made:
\list
\item
We must explicitly declare the widths of *\box0* and *\box2*
to be *\hsize* (*\hsize* is simply the width of paragraphs within
these boxes; an inserted *\box* in vertical mode could be any width---compare
the footnote on page~\ref{MAXD}).
\item
Our *\vbox to\pageheight@* ends with the
**
\hbox to\pagewidth@{\box0 \kern.5in\box2}
**
followed by
*\vfill* (preceded by a *\kern*).
That is because on the last page, where we balance
columns, this *\hbox* will generally be smaller than *\pageheight@*.
Most of the time, of course, the *\vfill* will be irrelevant, except that
we have to be sure to insert the *\kern* before the *\vfill*, so that
the depth of the *\hbox* will not cause an *Overfull* box (compare
page~\ref{KMPR}).\pagelabel{USEKMPR}
\endlist
In addition, on the first page of the
index, our two columns, *\box0* and *\box2*
will have been made 30~points smaller
than *\pageheight@*, in order to accommodate the
**
\vbox to30pt{\vskip10pt
\hbox to\pagewidth@{\hfil\bf
\uppercase\expandafter{\makeindex@W}\hfil}\vfil}%
\nointerlineskip
**
that we insert. We use *\makeindex@W*, so that *\newword* can be used
to determine the heading that will be printed.
Notice that we have the *\noexpands@...\shipout@* in a
group, so that the *\noexpands@* won't interfere with
font change instructions in
``continuation'' lines contributed later
(see page~\ref{CONLINES}) by the *\output* routine. (Compare
page~\ref{SHIPOUTGROUP}.)
After all this, we simply declare *\iffirstindexpage@* to be false,
set *\vsize* to *\doublepageheight@*, its proper value for all index pages
after the first, and *\advancepageno*:
\CC**
\def\makeindex@W{Index}
"slip
\def\combinecolumns@{%
"2
\setbox\outbox@=\vbox{\makeheadline
"2
\vbox to\pageheight@{\boxmaxdepth=\maxdepth
"2
\iffirstindexpage@
"2
\vbox to30pt{\vskip10pt
\hbox to\pagewidth@{\hfil\bf
\uppercase\expandafter{\makeindex@W}\hfil}%
\vfil}%
"2
\nointerlineskip
"2
\fi
"2
\wd0=\hsize \wd2=\hsize
\setbox0=\hbox to\pagewidth@{\box0 \kern.5in\box2}%
"2
\dimen@=\dp0 \box0 \kern-\dimen@\vfill}%
\makefootline}%
{\noexpands@ \let\style=\relax
\shipout@\box\outbox@
}%
\global\vsize=\doublepageheight@
\global\firstindexpage@false
\advancepageno}
**
\section{\CS{doublecolumns\@}}
For the
*\doublecolumns@* routine, used for all but the last page, we will need
a new \<dimen\> register
\CC**
\newdimen\prevcoldepth@
**
The routine
begins
with
**
\dimen@=\pageheight@
\iffirstindexpage@ \advance\dimen@ by -30pt \fi
**
so that *\dimen@* is the height of the columns we want for the page.
Now we have to consider the possibility that a *\columnbreak* or a\linebreak
*\newcolumn*
command caused the *\output* routine to be invoked. More precisely, we
want to insert the code
**
\ifleftcolbreak@
\global\leftcolbreak@false
. . .
\else
_ _ _
\fi
**
The flag *\ifleftcolbreak@* is set true (by *\cbreak@*) when
a *\columnbreak* or *\newcolumn* command has been issued
when we are setting the left column,
\footnote{I.e., when *\pagetotal* is
$\le\hbox{*\pageheight@*}$.}
and it is used only in the current
test; since we immediately reset it to be false, this means that
*\ifleftcolbreak@* is true precisely when we have forced a break in the left
column. We will simply let `\hbox{*. . .*}' for this case be
**
\vbox to\dimen@{\dimen@=\dp255 \unvbox255
\ifnum\Ctype@=3 \kern-\dimen@\vfill\fi}
\allowbreak
**
In other words, when our *\output* routine has been forced while we
still have only enough material for the first column, we do not do any
*\shipout*, but simply put material back on the main vertical list.
What we put back is a *\vbox to\dimen@* (remember that *\dimen@* is
the desired height of columns for this page), containing all the material
in *\box255*, either stretched out, when we had a *\columnbreak* (so that
*\Ctype@* is~*2*), or filled with empty space at the bottom, when we had
a *\newcolumn* (so that *\Ctype@* is~*3*). As before (page~\ref{USEKMPR}),
we need to add a
*\kern* before the *\vfill*.
The next time the *\output*
routine is called, *\doublecolumns@* will use the rest of the routine, still
to be defined, which splits the full *\box255* into two boxes of height
*\dimen@*; the first part will then have to be this *\vbox to\dimen@* that
we have just added to the main vertical list.
\footnote{The only problem here is that the *\output* routine could
conceivably be *\balancecolumns* the next time it is called---see
the discussion on page~\ref{CBBAL}~ff.}
Having gotten that consideration out of the way, let's consider the
other situation, where we haven't forced a break in a left-hand column.
Now we want to *\vsplit* *\box255* into two boxes of height *\dimen@*.
During the process we will set *\splittopskip=\topskip* and
*\splitmaxdepth=\maxdepth* (this assignment will be local, since the
*\output* routine, *\doublecolumns*, is implicitly enclosed in a group).
Splitting off the first column requires no special work,
**
\splittopskip=\topskip \splitmaxdepth=\maxdepth
\setbox0=\vsplit255 to\dimen@
**
But for the second column, we can't simply
**
\setbox2=\vsplit255 to\dimen@
**
This works when *\Ctype@* is~*0* or ~*1* (no column-breaking commands,
except perhaps a *\nocolumnbreak*,
were given). But when *\Ctype@* is~
*2* or~ *3*
(a *\columnbreak* or *\newcolumn*
command was given) the *\vsplit*'ing is irrelevant---we
should simply let *\box2* be *\box255*.
And when *\Ctype@* is~*3*
(the *\newcolumn* case), we need to add *\vfill* at the
bottom of the box.
For a later step, we also want to store the depth of the last line
of the second column in *\prevcoldepth@*.
Since the cases when *\Ctype@* is *0* and *1* are treated the same,
we consolidate the cases by first stating
**
\ifnum\Ctype@=0 \global\Ctype@=1 \fi
**
Then we can use
**
\ifcase\Ctype@ \or % case 1 (originally 0 or 1)
\setbox2=\vsplit255 to\dimen@
\global\prevcoldepth@=\dp2
\or % cases 2 and 3
\global\prevcoldepth@=\dp255 % store the depth first
\setbox2=\vbox to\dimen@{\unvbox255
\ifnum\Ctype@=3 \vfill\kern-\prevcoldepth@\vfill\fi}
\fi
**
Once we've determined the columns, *\box0* and *\box2*, in this way,
we use
**
\combinecolumns@
**
to *\shipout* the desired page.
Now we have reached the point where we want the *\output* routine to
add ``continuation'' lines\pagelabel{CONLINES}
(these lines, inserted by the *\output* routine,
will go before anything remaining in *\box255*, since we will add these
lines before we *\unvbox255*; and both go before anything else that happens
to remain on the main vertical list when the page break was chosen).
The default routine adds continuation lines at the beginning of the left
column on
a new page
to reflect the *\mark*'s at the end of the right column on the previous page.
This means that we will want to use *\splitbotmark* when *\box2* was
obtained as a *\vsplit255 to\dimen@*, but *\botmark* otherwise.
The specific continuation lines to be constructed from these marks will
be contributed by a routine, to be defined shortly,
\setbox0\hbox{\<the *\mark*'s\>}
**
\continue@ "box0 \continue@
**
It will be convenient to consider *\continue@* to be followed by at least
~7 (possibly empty) arguments,
and we will use
**
\ifcase\Ctype@ \or % case 1, where \vsplit was used
\expandafter\continue@\splitbotmark{}\relax\relax\relax
\relax\relax\relax\continue@
\else % cases 2 and 3
\epxandafter\continue@\botmark{}\relax\relax\relax
\relax\relax\relax\continue@
\fi
**
As we will see in a minute, *\continue@* will also attend to an important
detail about spacing.
After these continuation lines, we simply use
**
\ifvoid255 \else \unvbox255 \penalty\outputpenalty\fi
**
to finish the *\else* clause of our definition. And, finally, after the
entire *\if...\else...\fi* has been done, we reset *\Ctype@* to be~*0*:
\CC**
\def\doublecolumns@{%
\dimen@=\pageheight@
\iffirstindexpage@ \advance\dimen@ by -30pt \fi
"2
\ifleftcolbreak@
\global\leftcolbreak@false
\vbox to\dimen@{\dimen@=\dp255
\unvbox255 \ifnum\Ctype@=3 \kern-\dimen@\vfill\fi}%
\allowbreak
"2
\else
\splittopskip=\topskip \splitmaxdepth=\maxdepth
\setbox0=\vsplit255 to\dimen@
"2
\ifnum\Ctype@=0 \global\Ctype@=1 \fi
"2
\ifcase\Ctype@ \or
\setbox2=\vsplit255 to\dimen@
\global\prevcoldepth@=\dp2
"2
\else
\global\prevcoldepth@=\dp255
\setbox2=\vbox to\dimen@{\unvbox255
\ifnum\Ctype@=3 \kern-\prevcoldepth@\vfill\fi}%
\fi
"2
\combinecolumns@
"2
\ifcase\Ctype@ \or \expandafter
\continue@\splitbotmark{}\relax\relax\relax
\relax\relax\relax\continue@
\else
\expandafter\continue@\botmark{}\relax\relax\relax
\relax\relax\relax\continue@
\fi
"2
\ifvoid255 \else \unvbox255 \penalty\outputpenalty \fi
\fi
\global\Ctype@=0 }
**
\medskip
The *\continue@* routine is followed by at least~7 (possibly empty) arguments,
**
\def\continue@#1#2#3#4#5#6#7#8\continue@
**
Since *\continue@* is used in a combination
\setbox0\hbox{\<value of *\splitbotmark* or *\botmark*\>}
**
\continue@"box0{}\relax\relax\relax
\relax\relax\relax\continue@
**
the test
**
\def\next@{#1}\ifx\next@\empty
**
isolates the case where the *\mark* is empty (in all other cases the
mark will begin with a digit).
When this is not the case,
we want
**
\noindent@#3 ({\it continued\/})\par
**
as the first continuation line. The default style also introduces
slightly differently formatted continuation lines for any sub-entries, where
the number of levels of sub-entries is known from the value of *#1*,
**
\ifnum#1>1 \noindent@\enspace(#4 {\it continued\/})\par\fi
. . .
\ifnum#1>4 \noindent@\enspace(#7 {\it continued\/})\par\fi
**
After these continuation lines are added, we have to attend to the detail
mentioned on page~263 of {\it The \tex book}, except that
now we have to consider two different cases:
{\bf (1)} Suppose first that all of *\box255* has been used up, and that the
first box waiting to be placed
on the new current page
has height {\it h}.
This box
will be preceded by interline glue {\it g}, since the page break
that created it broke right before the glue. If
that box
were the first thing to be placed on the new page,
the glue {\it g\/} would be irrelevant,
since \tex\ discards glue when the current page does not contain any
boxes ({\it The \tex book}, page~112); instead of this glue, \tex\ would
simply insert the glue determined by *\topskip*.
But this glue will {\it not\/}
be discarded if
continuation lines have already been added.
We have stored the depth of the line
preceding this first box in\linebreak
*\prevcoldepth@*; thus, the glue {\it
g\/}
satisfies
\Math\hbox{*\prevcoldepth@*}+\hbox{\it g}+\hbox{\it h}
=\hbox{*\baselineskip*}\endMath
But now we need new glue {\it g}$'$ such that
\Math
\hbox{*\prevdepth*}+\hbox{\it g}'+\hbox{\it h}=\hbox{*\baselineskip*}\endMath
So we need to add $\hbox{*\prevcoldepth@*}-
\hbox{*\prevdepth*}$ glue; thus, when continuation lines are added,
we need to
**
\global\advance\prevcoldepth@ by -\prevdepth \kern\prevcoldepth@
**
(We can change *\prevcoldepth@* like this, instead of using the more
complicated code
**
"hskip-20pt\dimen@=\prevcoldepth@ \advance\dimen@ by -\prevdepth \kern\dimen@
**
because *\prevcoldepth@* won't be used any more.)
{\bf(2)} When *\box255* has not been used up, however, the situation is quite
different, since this *\box255* is what remains from a *\vsplit*,
so that the glue {\it g\/} is simply enough to make
\Math
\hbox{\it g}+\hbox{\it h}=\hbox{*\topskip*}
\endMath
We want glue {\it g}$'$ such that
\Math
\hbox{\it g}'+\hbox{\it h}+\hbox{*\prevdepth*}=\hbox{*\baselineskip*}
\endMath
so we need to add
\Math\hbox{*\baselineskip*}-\hbox{*\prevdepth*}-\hbox{*\topskip*}
\endMath
extra glue.
Actually, in both cases {\bf(1)} and {\bf(2)}, *\baselineskip* should really
be\linebreak
$\hbox{*\baselineskip*}+\hbox{*\parskip*}$, though this
doesn't make any difference in the final result for {\bf(1)}.
The whole definition is thus
\CC**
\def\continue@#1#2#3#4#5#6#7#8\continue@{%
\def\next@{#1}\ifx\next@\empty
"2
\else
\noindent@#3 ({\it continued\/})\par
"2
\ifnum#1>1 \noindent@\enspace(#4 {\it continued\/})\par\fi
"2
\ifnum#1>2 \noindent@\enspace(#5 {\it continued\/})\par\fi
"2
\ifnum#1>3 \noindent@\enspace(#6 {\it continued\/})\par\fi
"2
\ifnum#1>4 \noindent@\enspace(#7 {\it continued\/})\par\fi
\ifvoid 255
\global\advance\prevcoldepth@ by -\prevdepth \kern\prevcoldepth@
\else
\skip@=\baselineskip \advance\skip@ by \parskip
\advance\skip@ by -\prevdepth
\advance\skip@ by -\topskip
\vskip\skip@
\fi
\fi}
**
\small If we had also
wanted continuation lines at the top of right hand columns,
*\doublecolumns@* would have to be more complicated:
\setbox0\hbox{\<the *\else* part of old *\doublecolumns@* routine\>}
\setbox1\hbox{\<set *\dimen@* as before\>}
\setbox2\hbox{\<corresponding part of old *\doublecolumns@* routine\>}
\setbox3\hbox{\<add continuation lines,}
\setbox4\hbox{\ \ \ adjusting space using *\leftcoldepth@*\>}
\setbox5\hbox{\ \ \ adjusting space using *\prevcoldepth@*\>}
**
\newif\ifleftcol@
\newdimen\leftcoldepth@
"slip
\def\doublecolumns@{"box1
\ifleftcol@
\global\leftcolfalse@
\ifleftcolbreak@
\global\leftcoldepth@=\dp255
"box2
"copy3
"box4
"2
\else
{\splittopskip=\topskip \splitmaxdepth=\maxdepth
\global\setbox1=\vsplit255 to\dimen@
\global\prevcoldepth@=\dp1 }
\box1 \allowbreak
"copy3
"box5
\fi
"2
\else
\global\leftcol@true
"box0
\fi
\global\Ctype@=0 }
**
Thus, *\doublecolumns@* would
end up
being
called twice for each page, even if there was no column break in the left
column.
\endsmall
\section{\CS{balancecolumns\@}}
The *\balancecolumns@* routine basically
follows that of page~417 of {\it The \tex
book}, except that we have to be a little more careful about the final
glue (the routine in {\it The \tex\ book\/} was used for setting
{\it The \tex book}, where the balanced columns are then followed by
more material), and we also have to allow for a short last column.
We begin with
**
\setbox0=\vbox{\unvbox255 \unskip}
\dimen@=\ht0
**
using *\unskip* to completely eliminate *\vfill* that may have been
added by the *\bye* (this *\vfill* might not be there if the page break
actually occurs before the final line); this prevents the depth of *\box255*
from being counted in the height of *\box0*.
Now we basically want to divide *\dimen@* by 2, and split *\box0* into
two pieces of that height. But we make a slight adjustment:
When we split *\box0* into two pieces, the top line of the second piece,
which currently has *\baselineskip* glue before it, should only get
*\topskip* glue. So we use
**
\advance\dimen@ by \topskip
\advance\dimen@ by -\baselineskip
\divide\dimen@ by 2
**
---now *\dimen@* is the ideal height for the two pieces into which we
hope to split *\box0*.
Then we set
**
\splittopskip=\topskip
**
and use a *\loop* for splitting. This *\loop* will operate inside a group
with *\vbadness=10000*, so that *Underfull \vbox*'es won't be reported
unless the columns are actually bad after the balancing act:
**
{\vbadness=10000
\loop
\global\setbox3=\copy 0
\global\setbox1=\vsplit3 to\dimen@
\ifdim\ht3 > \dimen@ \global\advance\dimen@ by 1pt
\repeat}
**
Briefly, we try splitting to the ideal *\dimen@*, but if we can't get
two columns of the same height we want the left column to be the bigger;
so, if the right column turns out to be bigger, we keep increasing *\dimen@*
by 1~point until we get a split where the left column is at least as big as
the right column.
We always *\split* a copy of *\box0* rather than *\box0* itself, so that
*\box0* is always available for the next iteration of the *\loop*.
We used *\global\advance* here because we need to know the final value of
*\dimen@*. But to keep assignments of *\dimen@* local, we will modify this
code to
**
\global\dimen@i=\dimen@
{\vbadness=10000
\loop
\global\setbox3=\copy 0
\global\setbox1=\vsplit3 to\dimen@i
\ifdim\ht3 > \dimen@ \global\advance\dimen@i by 1pt
\repeat}
**
so that *\dimen@i* is the final dimension we are interested in.
Now we have to set each of
*\box0* and *\box2*, which will be used by\linebreak *\combinecolumns@*,
to a *\vbox to\dimen@i* (at this point we may get an *Underfull \vbox*
message):
**
\setbox0=\vbox to\dimen@i{\unvbox1}
\setbox2=\vbox to\dimen@i{\dimen@=\dp3 \unvbox3
\ifshortlastcolumn@ \kern-\dimen@ \vfill\fi}
**
The second column, *\box2* is supplied with *\vfill* when we want
it to be short; as usual (compare page~\ref{KMPR} and~\ref{USEKMPR}),
a
*\kern* is required before the *\vfill* to prevent the depth of
the box from being counted as part of the height, possibly producing
a spurious *Overfull* box.
The complete code is:
\CC**
\def\balancecolumns@{%
\setbox0=\vbox{\unvbox255 \unskip}%
"2
\dimen@=\ht0 \advance\dimen@ by \topskip
\advance\dimen@ by -\baselineskip
\divide\dimen@ by 2
"2
\splittopskip=\topskip
\global\dimen@i=\dimen@
"2
{\vbadness=10000
\loop
"2
\global\setbox3=\copy 0
\global\setbox1=\vsplit 3 to\dimen@i
\ifdim\ht3 > \dimen@i \global\advance\dimen@i by 1pt
\repeat}%
"2
\setbox0=\vbox to\dimen@i{\unvbox1}%
\setbox2=\vbox to\dimen@i{\dimen@=\dp3 \unvbox3
\ifshortlastcolumn@ \kern-\dimen@ \vfill\fi}%
\combinecolumns@}
**
That completes all the routines from *lamstex.stb*, so we end, as in
*lamstex.tex* itself, with
\CC**
\def\alloc@#1#2#3#4#5{\global\advance\count1#1by\@ne
\ch@ck#1#4#2\allocationnumber\count1#1
\global#3#5\allocationnumber
\wlog{\string#5\string#2\the\allocationnumber}}
\catcode`\@=\active
**
\small
Balancing an index can be problematical because of final letters with only a
few entries. \pagelabel{CBBAL}
For example, an index might end
\bigskip
\setbox0\vbox{\hsize10pc
\centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace 13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox1=\vbox to\ht0{\hsize10pc \advance\baselineskip 0pt plus2pt
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
}
\line{\hfil\box1 \kern1pc\box0 \hfil}
\bigskip
\noindent with the first column *Underfull*.
This is the best *\vsplit*, for
if the left column were any
bigger it would have
to include the {\bf Z} and the space after it, and at
least one more line (not to mention all the extra space that would normally
go {\it before\/} the {\bf Z}).
If we added a *\newcolumn* right before the *zebra* *\Entry*
in the *.xdx* file (and also specified *\shortlastcolumn*),
the output would look acceptable,
\bigskip
\setbox2\vtop{\hsize10pc
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox3=\vtop{\hsize=10pc
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
\vskip12pt
\centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
}
\line{\hfil\box3 \kern1pc\box2 \hfil}
\bigskip
\noindent
although we would get *Overfull \vbox* messages
(the *\newcolumn* causes the *\output* routine to be invoked
while we still have *\output={\doublecolumns}*, so the left column
will be made into a *\vbox to\pageheight@*).
If we added the *\newcolumn* before the
*\LETTER Z*
(and also had specified\linebreak *\shortlastcolumn*), we would get
\bigskip
\setbox0\vtop{\hsize10pc
\centerline{\bf Z}
\vskip6pt
\leftline{zap,\enspace13--18}
\leftline{$z$-axis,\enspace 12, 256, 300}
\leftline{zebra,\enspace 121}
\leftline{zed,\enspace 103, 105}
\leftline{Zen,\enspace iii, vi, 122}
\leftline{zenith,\enspace 97,103}
\leftline{zero,\enspace 11, 14, 56, 79}
\leftline{zero-sum,\enspace 118}
\leftline{zeta ($\zeta$),\enspace 133}
\leftline{zilch, {\it see\/} zero}
\leftline{zone,\enspace 204, 208}
\leftline{Zorn's lemma\enspace 112, 145}
}
\setbox1=\vtop{\hsize=10pc
\leftline{yak ({\it continued\/})}
\leftline{\quad habitat of,\enspace 124}
\leftline{yam,\enspace 124}
\leftline{yang,\enspace 187}
\leftline{$y$-axis,\enspace 89, 345}
\leftline{yclept,\enspace 102}
\leftline{yellow,\enspace 103}
\leftline{yellow fever,\enspace108}
\leftline{Yellow Pages,\enspace223}
\leftline{yeti,\enspace301}
\leftline{yin,\enspace186}
\leftline{yodel,\enspace224}
}
\line{\hfil\box1 \kern1pc\box0 \hfil}
\bigskip
\noindent (again with *Overfull \vbox* messages).
Of course, the most reasonable thing would probably be to add a
*\columnbreak* a little before the *yak* entry, so that the left column
on the final page would be a little longer.
\endsmall
\chapter The {\tt index} program\label{IPROG}\endchapter
The *index* program takes the raw data in an *.ndx* file and creates
an *.xdx* file. Specifically, it is invoked as
\setbox0\hbox{\<filename\>}
**
index "box0
**
to operate on \<filename\>*.ndx*, producing \<filename\>*.xdx*.
Among its many tasks, the *index* file essentially sorts entries
alphabetically. As indicated below, the *"1a{*\<string\>*}*
option is used to indicate
that for purposes of alphabetizing, the entry should be treated as if it were
\<string\>.
The *index* program
was originally written in Microsoft~C, for MS-DOS machines. Porting to other
machines will presumably be done by modifying this code. However, this
chapter presents the complete specifications for the *index* program, in case
any one wants to write it from scratch.
It should be pointed out that currently
the alphabetizing part of the program is essentially set up for
English spelling, with the presumption that ``foreign''
words (e.g., those with accented letters)
will be given an *"1a{*\<string\>*}* option. There should obviously
be versions (or perhaps switches)
for other languages that will provide
transparent alphabetizing for words in those languages, so that the *"1a*
option will only be needed for words that are ``foreign'' to those languages.
It might also
be mentioned that the current version of the program specifically
assumes that the final line ends with a \<carriage-return\>, which should be
true of the *.ndx* files that \tex\ writes. Some systems might want to
modify this assumption.
\def\controlseq{\hbox{\rm\<control sequence\>}}
\section{The {\tt.ndx} file}
The *.ndx* file may contain certain lines
**
\define"controlseq . . .
**
that come from *\idefine*'s in the main file, as well as certain lines
**
\abbrev"1"controlseq{...}
**
that come from *\iabbrev*'s in the main file. Moreover, as explained on
page~113 of the \lamstex~Manual, a sequence of commands of the form
\setbox0\hbox{\<pre page material\>}
\setbox1\hbox{\<post page material\>}
\setbox2\hbox{\<order\>}
**
"hskip-40pt\pageorder"controlseq{"box0}{"box1}{"box2}
**
may have been inserted
at the very beginning of the
*.ndx* file (after the *.ndx* file was automatically made by \tex);
here each \controlseq\ is some
numbering style command, and the \<order\>'s are
*1*, *2*, *3*, \dots, in that sequence.
Aside from this, the *.ndx* file
should consist of pairs of lines
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\controlseq*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
"""box0"box1""
{"box2}{"controlseq}{"box4}{"box5}
**
where \<number\> is a decimal number, \controlseq\ is some numbering
style
control sequence
(followed by a space, because \tex\ will always add the
space when it writes to the *.ndx* file),
and \<prefix\> and \<postfix\> are arbitrary, possibly
empty, strings. The \controlseq\ is normally `*\arabic" *'.
Actually, the *index* program as currently written does not assume
that *""* is the delimiter
appearing at the beginning and end of the \<entry\> lines. It is
perfectly legitimate (compare section~\Sref{OTHERD})
to have something like
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\controlseq*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
<"box0"box1>
{"box2}{"controlseq}{"box4}{"box5}
**
Any left delimiter other than *{* or *\* may be used;
the *index* program takes the \<entry\>\<option\>
combination to be everything between the first
symbol and the last non-space symbol on the line.
Each \<entry\> has one of the forms
\setbox1\hbox{\<entry\>$_{\text1}$}
\setbox2\hbox{\<entry\>$_{\text2}$}
\setbox3\hbox{\<entry\>$_{\text3}$}
\setbox4\hbox{\<entry\>$_{\text4}$}
\setbox5\hbox{\<entry\>$_{\text5}$}
**
"copy1
"copy1, "copy2
"copy1, "copy2, "copy3
"copy1, "copy2, "copy3, "copy4
"copy1, "copy2, "copy3, "copy4, "copy5
**
The \<options\> are a possibly empty sequence of
the following types of entries, where \<n\>
stands for *2*, *3*, *4* or *5*. Actually, *1* is also allowed, but simply
treated as if the *1* weren't there.
There are optional spaces between such
entries, including an optional space at the beginning and end of the
\<options\>:
\Math
\vcenter{\halign{#\hfil&\qquad#\hfil\cr
*"1a{*\<string\>*}*&(alphabetize as)\cr
*"1*\<*n*\>*a{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
*"1-{*\<string\>*}*&(print before entry)\cr
*"1*\<*n*\>*-{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
*"1+{*\<string\>*}*&(print after entry)\cr
*"1*\<*n*\>*+{*\<string\>*}*&(same for subentry at level \<*n*\>)\cr
*"1e*\<control sequence\>&(apply control sequence to entry)\cr
*"1*\<*n*\>*e*\<control sequence\>&(same for subentry at level \<*n*\>)\cr
*"1p*\<control sequence\>&(apply control sequence to page number)\cr
*"1f*&(begin page span)\cr
*"1F*&(begin page span, variant form)\cr
*"1t*&(end page span)\cr
*"1x{*\<string\>*}*&(cross reference as)\cr
*"1X{*\<string\>*}*&(list and cross reference as)\cr}}
\endMath
In each
**
\abbrev"1"controlseq{...}
**
line, the `*...*' string should also be a sequence of these possible options,
and error messages should be given if it is not, or if *\abbrev* is otherwise
used incorrectly.
The *"1x* and *"1X* options are meant to be mutually exclusive, so an error
message should be given if both occur in the same \<options\> list.
\section{The {\tt index} program}
Here now are the steps taken by the *index* program.
\medskip
\noindent({\bf I}) {\bf Preprocessing:}
\smallskip
(1) The *index* program first uses any *\pageorder* lines at the beginning,
\setbox1\hbox{$_{\text1}$}
\setbox2\hbox{$_{\text2}$}
\setbox3\hbox{pre\copy1}
\setbox4\hbox{post\copy1}
\setbox5\hbox{pre\copy2}
\setbox6\hbox{post\copy2}
**
\pageorder"controlseq"copy1{"copy3}{"copy4}1
\pageorder"controlseq"copy2{"copy5}{"copy6}2
. . .
**
to
set up an ordering for arrays of the form
\setbox2\hbox{\<number\>}
\setbox3\hbox{\<controlseq\>}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
**
{"box2} {"controlseq} {"box4} {"box5}
**
Namely, all arrays
\setbox1\hbox{$_{\text1}$}
\setbox2\hbox{$_{\text2}$}
\setbox3\hbox{pre\copy1}
\setbox4\hbox{post\copy1}
\setbox5\hbox{pre\copy2}
\setbox6\hbox{post\copy2}
\setbox7\hbox{\<number\>}
**
{"copy7}{"controlseq"copy1}{"copy3}{"copy4}
**
come first, with the ordering then determined by the \<number\>'s,
all arrays
**
{"copy7} {"controlseq"copy2} {"copy5} {"copy6}
**
come next, \dots. All other arrays come after these, and are simply ordered
first by the order of the \<number\>, and then purely alphabetically by
the remaining fields.
Error messages presumably
ought to be given if any *\pageorder* line has the wrong
form, if the \<order\>'s don't occur in the proper order, or if two different
\<order\>'s are assigned to identical material.
(2) Next we consider all lines
**
\abbrev"1"controlseq{...}
**
(which may appear anywhere in the *.ndx* file).
In each case, any
occurrence of *"1"controlseq* in any entry line is replaced by
`*...*'; then the *\abbrev* lines are eliminated.
(3) All *\define* lines anywhere in the *.ndx* file are stored
in a safe place, before being removed; they will be written at the beginning
of the *.xdx* file.
\medskip
\noindent({\bf II}) {\bf Sorting:}
\medskip
\def\1{$_{\text1}$}\def\5{$_{\text2}$}
\def\3{$_{\text3}$}\def\4{$_{\text4}$}\def\5{$_{\text5}$}
\def\n{$_{\text\it n}$}
\def\entrybar{$\overline{\hbox{\rm entry}}$}
(1) For each
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
**
"""box0"box1""
**
line,
if *"1a{*\<string\>*}* appears, replace \<entry\1\> by \<string\>,
and define \<\entrybar\1\> to be the old \<entry\1\>.
Otherwise define
\<\entrybar\1\> to be empty.
Similarly, if
*"1*\<*n*\>*a{*\<string\>*}* appears, replace \<entry\n\> by \<string\>,
and define \<\entrybar\n\> to be the old
\<entry\n\>. Otherwise define \<\entrybar\n\>
to be empty.
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<options\>}
\setbox2\hbox{\<number\>}
\setbox3\hbox{*\nstyle*}
\setbox4\hbox{\<prefix\>}
\setbox5\hbox{\<postfix\>}
\smallskip
(2) Each pair of lines
**
"""box0"box1""
{"box2}{"controlseq}{"box4}{"box5}
**
now gives rise to a collection $\Cal F$ of fields:
*E1* is \<entry\1\> followed by one space.
*E1+* is empty unless *"1-{*\<string\>*}* appears, in which case it is
\<string\> followed by one space (note that
\<string\> may already have one space at
the end).
*E1-* is empty unless *"1+{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.
*E2* is \<entry\5\> followed by one space (hence just a space if
\<entry\5\> is empty).
*E2-* is empty unless *"12-{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.
*E2+* is empty unless *"12+{*\<string\>*}* appears, in which case it is
\<string\> followed by one space.
*E3*, *E3+*, *E3-*, \dots, *E5*, *E5+*, *E5-* are similar.
*P#* is \<number\>.
*Pn* is \controlseq\ (usually `*\arabic" *').
*P-* is the \<prefix\>.
*P+* is the \<postfix\>.
\def\EE{$\overline{\hbox{\tt E}}$}
*"EE1*, \dots, *"EE5* are \<\entrybar\1\>, \dots, \<\entrybar\5\>.
*E1c* is empty unless *"1e*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.
*E2c* is empty unless *"12e*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.
*E3c*, *E4c*, *E5c* are similar, using *"13e*, *"14e* and *"15e*.
*Pc* is empty unless *"1p*\<control sequence\> appears, in which case it
is \<control sequence\>, followed by one space.
*PT* (page type) is *f* if *"1f* appeared, *F* if *"1F* appeared, *t*
if *"1t* appeared, and *s* (for single page) otherwise.
*x* is empty unless *"1x{*\<string\>*}* appears, in which case it is
\<string\>, followed by one space.
*X* is empty unless *"1X{*\<string\>*}* appears, in which case it is
\<string\>, followed by one space.
\medskip
(3)
We first sort these collections $\Cal F$
alphabetically on *E1*, then among those with
identical *E1* on *E1-*, then on *E1+*, then on *E2*, \dots, *E5+*.
If we ignore the *-* and *+* fields for the moment,
this just alphabetizes the entries and subentries.
The spaces that were added after each
\<entry\n\> are meant to ensure that these entries are really sorted
alphabetically; for example, it produces the order
**
Time
Time table
Time tables
Times
Times tables
**
which will eventually appear in the index as
\bigskip\begingroup\parindent0pt\parskip0pt
\hskip30pt Time\par\nobreak
\hskip30pt \hskip10pt table\par\nobreak
\hskip30pt \hskip10pt tables\par\nobreak
\hskip30pt Times\par\nobreak
\hskip30pt \hskip10pt tables\par\nobreak
\endgroup\bigskip
The other fields, *E1-*, *E1+*, \dots, allow entries with
additional elements to appear in the proper order. For example, for the entry
**
""Time "1-{``} "1+{''}""
**
*E1* is *Time* and *E1-* is *``*. This
will come after the entry line
**
""Time""
**
where *E1* is also *Time* but *E1-* is empty,
so that we will obtain the order
\bigskip\begingroup\parindent0pt\parskip0pt
\hskip30pt Time\par\nobreak
\hskip30pt ``Time''\par
\endgroup\bigskip
\noindent in the index.
After using these fields for sorting, we next use the fields
**
P# Pn P- P+
**
where
the sorting order for these arrays
is just that described in step (1) of ({\bf I}).
There may be certain collections $\Cal F$ that are distinct, but agree for
all the fields so far. They can be left in any order, say the order in which
they appear in the *.ndx* file, or further sorted purely alphabetically
according to the remaining fields *"EE1*, \dots, *"EE5*, *E1c*, \dots,
*E5c* and *Pc*.
The *PT*, *x* and *X*
fields are important for further processing, but need not be
considered in the sorting.
After the sorting is completed, the additional spaces added to various fields
are no longer needed, and they are deleted in the next step.
\medskip
\noindent ({\bf III}) {\bf Writing the *.xdx* file:}
\medskip
(1) First, as indicated in step (3) of part ({\bf I}), all *\define* lines
originally in the *.ndx* file are written to the *.xdx* file.
(2) The remaining material in the *.xdx* file will be in sections, each
preceded by a blank line, then a line
**
\LETTER ...
**
and then another blank line.
The line
**
\LETTER A
**
will normally be the first of these, and will precede all entries that begin
with *a* or *A*;
**
\LETTER B
**
will precede all entries that begin with *b* or *B*; etc. No such line
appears for a letter if there are no entries beginning with this
letter. Things like \hbox{*\LETTER !*} can appear if entries begin with
~ *!* (though normally one would expect the *"1a* option to be used for such
entries).
(2) In most cases,
each collection $\Cal F$ gives rise to a pair of lines in the *.xdx*
file:
\def\di{{\it d}$_{\text1}$}
\def\dii{{\it d}$_{\text2}$}
**
\Entry "di"dii{...}{...}{...}{...}{...}
\Page {...}
**
except that if several collections have the exact same *\Entry* line, then
the corresponding *\Page* lines are listed under it in order, with
modifications to be mentioned in a minute, involving
the *PT*, *x* and *X* fields.
For the first *{...}* in the *\Entry* line, `*...*' is
\def\F#1.{\hbox{\rm\<field #1\>}}
**
{E1-}{E1c{E1}}{E1+}
**
except that *E1* is replaced by *"EE1*
if this is non-empty.
Note that there are braces around *E1* (or *"EE1*)
so that it will be the
argument of the control sequence *E1c*. However, these braces are
omitted if *E1c* is empty. Moreover,
all other unnecessary
braces are omitted: the first set of braces is omitted if *E1-* is
empty, the third set is omitted if *E1+* is empty, and the middle set is
also omitted if both are empty.
(Remember that this entire sequence, with
extraneous braces removed, is enclosed in the first set of braces in the
*\Entry* line.)
The second *{...}* in the *\Entry* line is similar, using fields
*E2-*, *E2c*, *E2* and *E2+*. And similarly for the other groups.
\di\ is the number of *{...}* that are non-empty, i.e., not of the form
*{}*.
\dii\ is the number of *{...}* {\it that agree with the most recent *\Entry*
line}.
\medskip
Normally,
the *\Page* lines have the form
\def\FF{$\overline{\hbox{\rm\<field 17\>}}$}
**
\Page {Pc{{P-}{Pn{P#}}{P+}}}
**
But *Pn* is omitted when it is `*\arabic" *' (the usual case).
Moreover, superfluous braces are removed, as before, when
fields are empty.
Duplicate *\Page* lines for the same entry are eliminated. But if
duplicates actually come from lines for which *Pc* is different, then
each *\Page* line after the first is printed as
{\advance\litindent-60pt
**
%% ////////////////////////////////////////////////////////////////////////
%
% \Page {Pc}{...}}
% Duplicate page number formatted differently
%
%% \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
**
where *Pc* is the control sequence for that line. For readability,
there should be
a blank line before and after this ``error message''
(the current version of the *index*
program actually prints things slightly differently).}
When *PT* is *f*, however, *\Page* is replaced by *\Pagespan*. And
if *PT* is *F*, then *\Page* is replaced by *\PageSpan*; moreover, the
line is then written in the form
**
\PageSpan {Pc}{{P-}{Pn{P#}}{P+}}
**
with the *Pc* as a separate argument.
Extraneous braces are removed, as usual.
When *PT* is *t*, *\Page* is replaced by *\Topage*. However, if it was
preceded by a line for which *PT* is *F*, then once again we write
**
\Topage {Pc}{{P-}{Pn{P#}}{P+}}
**
with the *Pc* as a separate argument.
When a *\Page* line for which *PT* is *s* is encountered between lines
for which *PT* is *f* or *F* and the corresponding line for which *PT* is
*t*, it is ignored, {\it unless it has\/} a different *Pc*. In this case
the new *\Page* line is printed as the error message
{\advance\litindent-60pt
\setbox0\hbox{new}
\setbox1\hbox{old}
**
%% ////////////////////////////////////////////////////////////////////////
%
% \Page {"copy0 Pc{...}}
% Page {"copy0 Pc{...}} within span starting at "copy1 Pc{...}
%
%% \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
**
Other such error} messages that should be issued
are indicated on pages 118@--119 of the \lamstex~ Manual.
\bigskip
This description is complete only
for entries that do not have an *"1x* or *"1X* option. For entries that do
have these options, the processing is somewhat different.
Recall that
*"1x* indicates a cross-reference without a reference to the page on
which the entry is marked, while *"1X* indicates a cross-reference together
with a reference to the page.
The situation where at least one occurrence of \<entry\> has an *"1x* or
*"1X* option can happen in different ways:
\medskip
\noindent Case 1: Every occurrence of the \<entry\> involves *"1x* (and thus
not
*"1X*):
\setbox0\hbox{\<entry\>}
\setbox1\hbox{\<string\1\>}
\setbox2\hbox{\<string\5\>}
\setbox3\hbox{\<string\3\>}
**
"copy0 ... "1x{"copy1}
"copy0 ... "1x{"copy2}
"copy0 ... "1x{"copy3}
**
In this case the *.xdx* file
should contain
**
\Entryxref "di"dii{...}{...}{...}{...}{...}{\See {"copy1}}
\Morexref {\See {"copy2}}
. . .
**
\medskip
\noindent Case 2: The opposite case, in which at least one of the following
occurs:
(1) \<entry\> occurs at least once with the *"1X* option, so that the
corresponding page number should appear. Other occurrences of \<entry\>
may or may not have
*"1x* options.
(2) \<entry\> occurs at least once with {\it neither\/} *"1x* nor *"1X*, and
thus there is at least one page number that should appear because no
cross-referencing is involved at all. Other occurrences of \<entry\> may have
either *"1x* or *"1X* options.
\smallskip
In these cases,
let \<string\1\>, \<string\5\>, \dots, be all the \<string\>'s, in
alphabetical order, that
occur in either *"1x* or *"1X* options, and
let
**
\Page {...}
\Page {...}
. . .
\Page {...}
**
be the lines that would be written considering all instances that do not
involve the *"1x* option (but possibly the *"1X* option). These lines
may actually involve *\Pagespan*, *\PageSpan* and *\Topage*.
Then the *.xdx* file should contain
\setbox1\hbox{\<string\1\>}
\setbox2\hbox{\<string\5\>}
**
\Entry "di"dii{...}{...}{...}{...}{...}
\Xref {\See {"copy1}}
\Morexref {\See {"copy2}}
. . .
\Page {...}
\Page {...}
. . .
\Page {...}
\Xref {\See {"copy1}}
\Morexref {\See {"copy2}}
. . .
**
|