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
|
% \iffalse meta-comment
%
% Copyright 1993 1994 1995 1996 1997 1998 1999
% The LaTeX3 Project and any individual authors listed elsewhere
% in this file.
%
% This file is part of the Standard LaTeX `Tools Bundle'.
% -------------------------------------------------------
%
% It may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.2
% of this license or (at your option) any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.2 or later is part of all distributions of LaTeX
% version 1999/12/01 or later.
%
% The list of all files belonging to the LaTeX `Tools Bundle' is
% given in the file `manifest.txt'.
%
% \fi
%\iffalse % this is a METACOMMENT !
%
%<*dtx>
\ProvidesFile{f-array.dtx}
%</dtx>
%% Package `array' to use with LaTeX 2e
%% Copyright (C) 1989-1998 Frank Mittelbach, all rights reserved.
%<+package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
%<+package>\ProvidesPackage{array}
% \fi
% \ProvidesFile{f-array.dtx}
[1998/05/13 v2.3m Tabular extension package (FMi)]
%
%
% \CheckSum{1108}
%% \CharacterTable
%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%% Digits \0\1\2\3\4\5\6\7\8\9
%% Exclamation \! Double quote \" Hash (number) \#
%% Dollar \$ Percent \% Ampersand \&
%% Acute accent \' Left paren \( Right paren \)
%% Asterisk \* Plus \+ Comma \,
%% Minus \- Point \. Solidus \/
%% Colon \: Semicolon \; Less than \<
%% Equals \= Greater than \> Question mark \?
%% Commercial at \@ Left bracket \[ Backslash \\
%% Right bracket \] Circumflex \^ Underscore \_
%% Grave accent \` Left brace \{ Vertical bar \|
%% Right brace \} Tilde \~}
%%
%
%
% \changes{v2.3c}{1995/11/02}{(DPC) changement mineur dans la documentation}
%
% \changes{v2.3a}{1994/10/16}{ajout du code pour \cs{firsthline} et
% assimil\'es}
%
% \changes{v2.2c}{1994/03/14}{suppression du test du bug de \cs{@tfor}}
%
% \changes{v1.0b}{1987/06/04}{`@classi (plus rapide),
% `@classvi (nouveau) A dans le pr\'eambule
% signifie \&\& dans `halign.}
%
% \changes{v1.1a}{1987/07/05}{Nouveau concept:
% preamblechar: c,l,r,C,L,R,A,p,t,{\tt !|},@,!!}
% \changes{v1.1b}{1987/09/21}{p reprend son r\^ole original comme dans
% \LaTeX{} et z pour une `parbox centr\'ee.}
%
% \changes{v1.2a}{1987/09/27}{Impl\'ementatrion compl\`etement nouvelle.}
% \changes{v1.2b}{1987/10/06}{{\tt !|} ne g\'en\`ere plus d'espace au
% d\'ebut ou \`a la fin du pr\'eambule. Sinon
% `hline est trop longue.}
%\selectlanguage{english}
% \changes{v1.2b}{1987/10/06}{Enlarged `@arstrutbox by 1pt (Test-Impl)
% with dimen `@strutheight.}
% \changes{v1.2c}{1987/10/22}{Nouvelle dimension `extrarowheight
% (d\'efaut: 0pt).}
% \changes{v1.2c}{1987/10/22}{Augmente `@arstrutbox de `extrarowheight.
% Thus you may avoid large characters to
% overprint a `hline.}
% \changes{v1.2c}{1987/10/22}{Introduced `m@th in `@array to allow
% non-zero values of `mathsurround.}
% \changes{v1.2d}{1987/11/02}{Completed the documentation.}
% \changes{v1.2e}{1987/11/03}{Bug fixed: A at start of preamble resulted
% in an error since `@mkpream generated
% `@arstrut \& ... as a preamble.}
% \changes{v1.2f}{1987/11/09}{`@testpach documented.}
%
% \changes{v1.3a}{1987/11/11}{Again a new implementation, with a new
% concept (cf. the documentation).}
% \changes{v1.3b}{1988/03/17}{`@decl expands now into `@empty, i.e., it
% disappears when the preamble is generated,
% except when the user specifies A\{\} or
% B\{\}.}
%
% \changes{v1.4a}{1988/03/18}{Test implementation of use of token
% registers in order to do without `protect.}
% \changes{v1.4b}{1988/03/19}{Changed erroneous class numbers:
% 5 -!> 6
% 6 -!> 7
% 7 -!> 5
% Corresponding changes in the macros.}
% \changes{v1.4c}{1988/03/19}{Everything except p,z now works with token
% registers.}
%
% \changes{v1.9a}{1988/03/20}{Last (so I hope) major change: 1) Options
% B,A now called !>,<. These options now point
% to the column they modify.}
% \changes{v1.9a}{1988/03/20}{2) `protect is no longer necessary. But
% still the macro `@expast needs top be
% modified. `multicolumn still does not work.}
% \changes{v1.9b}{1988/04/29}{inserted missing `fi in `@testpach.
% Corrected \LaTeX bug in `@tfor.}
% \changes{v1.9c}{1988/05/07}{Re-introduced `@endpbox.
% `multicolumn now works!! Version number still
% 1.9 since the documentation is still not
% finished.}
% \changes{v1.9c}{1988/05/07}{1) `def `the@toks \{`the ...\} remaining
% only in `@mkpream. 2) Removed `@classiii and
% replaced by `save@decl.}
% \changes{v1.9c}{1988/05/07}{3) `insert@column contains only `@tempcnta
% and `count@ counters. 4) `@@startpbox and
% `@@endpbox now totally obsolete.}
% \changes{v1.9d}{1988/05/10}{Replaced `number by `the where the `toks
% registers' contents are used.}
% \changes{v1.9e}{1988/05/11}{Re-introduced `@xargarraycr and
% `@yargarraycr, since `endtemplate seems to
% be `outer.}
% \changes{v1.9f}{1988/05/20}{Small changes finally carried out:
% 1) `par!=`@empty.
% 2) \{..ifnum0!=!`\}... $\to$ `bgroup and
% analoguously `egroup.}
% \changes{v1.9g}{1988/02/24}{Inserted again \{..ifnum0!=!`\}..,
% c.f. Appendix D of the \protect\TeX{}book.}
% \changes{v1.9h}{1988/06/28}{No longer necessary to read in the file
% twice.}
% \changes{v1.9i}{1988/06/28}{Corrected typo in german version.}
% \changes{v1.9j}{1988/11/23}{In a `r' column an extra `kern`z@ is
% needed.}
% \changes{v1.9j}{1988/11/23}{Otherwise the `hfil on the left side
% will be removed by the `unskip in
% `insert@column if the entry is empty.}
% \changes{v1.9k}{1988/06/28}{Corrected typo in german version.}
% \changes{v1.9k}{1989/01/16}{`begin{Macro} changed to `begin{macro} in
% documentation.}
%
% \changes{v2.0a}{1989/05/12}{{\tt\textbackslash @thetoks} changed to
% {\tt\textbackslash the@toks}.}
% \changes{v2.0a}{1989/05/12}{source changed to reflect new doc.sty
% conventions.}
% \changes{v2.0a}{1989/05/12}{t option renamed to p to be compatible to
% the original.}
% \changes{v2.0a}{1989/05/12}{File renamed from arraye.sty to
% array.sty.}
% \changes{v2.0b}{1989/05/17}{Three forgotten end macro added.}
% \changes{v2.0b}{1989/05/17}{All lines shortened to 72 or less.}
% \changes{v2.2a}{1994/02/03}{Upgrade to \LaTeXe}
%\selectlanguage{french}
%
% \DoNotIndex{\@depth,\@ehc,\@fortmp,\@height,\@ifnextchar,\@ifstar}
% \DoNotIndex{\@ifundefined,\@ne,\@nil,\@tempa,\@tempb}
% \DoNotIndex{\@tempcnta,\@tempd,\@tempdima,\@whilenum,\@width,\\}
% \DoNotIndex{\@tforloop}
% \DoNotIndex{\advance}
% \DoNotIndex{\baselineskip,\begingroup,\bgroup}
% \DoNotIndex{\cr,\crcr,\csname}
% \DoNotIndex{\def,\do,\docdate,\dp}
% \DoNotIndex{\edef,\egroup,\else,\endcsname,\endinput,\expandafter}
% \DoNotIndex{\fi,\filedate,\fileversion}
% \DoNotIndex{\gdef}
% \DoNotIndex{\hbox,\hfil,\hsize,\hskip,\ht}
% \DoNotIndex{\if,\ifcase,\ifdim,\ifnum,\ifx,\ignorespaces}
% \DoNotIndex{\kern}
% \DoNotIndex{\leavevmode,\let,\lineskip}
% \DoNotIndex{\m@ne,\multispan}
% \DoNotIndex{\newcount,\newdimen,\noalign}
% \DoNotIndex{\or}
% \DoNotIndex{\relax}
% \DoNotIndex{\setbox,\space,\strutbox}
% \DoNotIndex{\tabskip,\thr@@,\the,\toks,\toks@,\tw@,\typeout}
% \DoNotIndex{\unhcopy,\unskip}
% \DoNotIndex{\vbox,\vcenter,\vline,\vrule,\vtop,\vskip}
% \DoNotIndex{\xdef}
% \DoNotIndex{\z@}
%
% \GetFileInfo{f-array.dtx}
%
% \title{Une nouvelle \'ecriture des environnements
% \textsf{tabular} et \textsf{array} de \LaTeX\thanks{Ce fichier
% a le num\'ero de version \fileversion, r\'evis\'e
% le \filedate.}}
%
% \author{Frank Mittelbach
% \and
% David Carlisle\thanks{David a accept\'e gr\^acieusement l'inclusion
% de code auparavant dans \texttt{newarray.sty} pour l'\'ecriture
% de \texttt{\textbackslash{}newcolumntype}} \and
% \makebox[0.9\linewidth]{Traduction fran\c{c}aise
% par Jean-Pierre Drucbert\thanks{Derni\`ere mise \`a
% jour le 20/01/2000}}}
%
% \date{Imprim\'e le \today}
%
% \maketitle
%
% \MakeShortVerb{\=}
%
% \begin{abstract}
% Ce package est une nouvelle impl\'ementation des environnements
% \texttt{tabular} et \texttt{array} de \LaTeX. Les principaux avantages
% de cette impl\'ementation sont de nouvelles options pour mettre en
% forme les colonnes et que les commandes <<~fragiles~>> de \LaTeX\
% n'ont plus besoin d'\^etre prot\'eg\'ees par =\protect= \`a
% l'int\'erieur de ces environnements.
%
% La majeure partie du code de ce package date de 1988---il en est
% de m\^eme de sa documentation.
% \end{abstract}
%
%
%
% \section{Introduction}
%
% Cette nouvelle impl\'ementation des environnements \texttt{tabular} et
% \texttt{array} fait partie d'un projet plus large, dans lequel nous
% essayons d'am\'eliorer le code de \LaTeX\ et de le rendre encore plus
% facile \`a manipuler.
%
% Le lecteur devrait \^etre familier avec les environnements
% mentionn\'es ci-dessus. De plus amples informations sont disponibles
% dans \cite{bk:lamport} et \cite{bk:GMS94}. Les options
% suppl\'ementaires qui peuvent \^etre utilis\'ees dans le pr\'eambule
% ainsi que celles qui ont un sens l\'eg\`erement diff\'erent sont
% d\'ecrites dans la table~\ref{tab+opt}.
%
% \DescribeMacro\extrarowheight
% Il y a un nouveau param\`etre, la longueur =\extrarowheight=, qui, si
% elle est positive, est ajout\'ee \`a la hauteur normale de chaque
% ligne de la table, alors que la profondeur reste la m\^eme. Ceci est
% important pour les tables comportant des lignes horizontales car
% normalement ces lignes touchent les lettres majuscules.
% Par exemple, nous avons utilis\'e =\setlength{\extrarowheight}{1pt}=
% dans la table~\ref{tab+opt}.
%
% \begin{table}[t]
% \begin{center}
% \setlength{\extrarowheight}{1pt}
% \begin{tabular}{|>{\tt}c|m{9cm}|}
% \hline
% \multicolumn{2}{|c|}{Options inchang\'ees}\\
% \hline
% l & Colonne cadr\'ee \`a gauche. \\
% c & Colonne centr\'ee. \\
% r & Colonne cadr\'ee \`a droite. \\
% p\{width\} & \'Equivalente \`a =\parbox[t]{width}=. \\
% @\{decl.\} & Supprime l'espace entre les colonnes et le
% remplace par \texttt{decl.}. \\
% \hline
% \multicolumn{2}{|c|}{Options nouvelles}\\
% \hline
% m\{width\} & D\'efinit une colonne de largeur \texttt{width}.
% Chaque entr\'ee sera centr\'ee en proportion du
% reste de la ligne. Ceci est assez semblable \`a
% =\parbox{width}=. \\
% \hline
% b\{width\} & \'Equivalente \`a =\parbox[b]{width}=. \\
% \hline
% >\{decl.\} & Peut \^etre utilis\'ee avant une option \texttt{l}, \texttt{r},
% \texttt{c}, \texttt{p}, \texttt{m} ou
% \texttt{b}. Ceci ins\`ere \texttt{decl.}
% directement en t\^ete de l'entr\'ee dans la colonne. \\
% \hline
% <\{decl.\} & Peut \^etre utilis\'ee apr\`es une option \texttt{l}, \texttt{r},
% \texttt{c}, \texttt{p}, \texttt{m} ou
% \texttt{b}. Ceci ins\`ere \texttt{decl.}
% juste apr\`es l'entr\'ee dans la colonne. \\
% \hline
% | & Ins\`ere une ligne verticale. La distance entre
% deux colonnes sera augment\'ee de l'\'epaisseur
% de la ligne, contrairement \`a la d\'efinition
% originale de \LaTeX.\\
% \hline
% !\{decl.\} & Peut \^etre utilis\'ee n'importe o\`u et correspond \`a l'option
% \texttt{|}. La diff\'erence est que
% \texttt{decl.} sera ins\'er\'ee \`a la place
% d'une ligne verticale, donc
% cette option ne supprime pas l'espace
% normalement ins\'er\'e entre
% les colonnes, contrairement \`a =@{...}=.\\
% \hline
% \end{tabular}
% \end{center}
% \caption{Les options du pr\'eambule.} \label{tab+opt}
% \end{table}
%
%
% Nous allons pr\'esenter quelques exemples des nouvelles options du
% pr\'eambule.
% \begin{itemize}
% \item
% Si vous d\'esirez utiliser une fonte sp\'eciale (par exemple
% =\bfseries=) dans une colonne cadr\'ee \`a gauche, ceci peut se
% faire avec =>{\bfseries}l=. Vous n'\^etes plus oblig\'es de
% commencer chaque entr\'ee par =\bfseries=.
% \item
% Dans les colonnes qui ont \'et\'e engendr\'ees par \texttt{p},
% \texttt{m} ou \texttt{b}, la valeur par d\'efaut de =\parindent=
% est 0pt. Ceci peut \^etre modifi\'e par:\\
% =>{\setlength{\parindent}{1cm}}p=.
% \item
% les options \texttt{<} et \texttt{>} avaient \'et\'e
% d\'evelopp\'ees \`a l'origine pour l'application suivante:
% =>{$}c<{$}= engendre une colonne en mode math\'ematique
% dans un environnement \textsf{tabular}. Si vous utilisez ce type
% de pr\'eambule dans un environnement \textsf{array}, vous
% obtenez une colonne en mode~LR car les dollars suppl\'ementaires
% annulent ceux d\'ej\`a pr\'esents.
% \item
% Vous pouvez aussi penser \`a des applications plus complexes. Un
% probl\`eme classique peut facilement \^etre r\'esolu avec la
% s\'equence
% =>{\centerdots}c=\linebreak[0]=<{\endcenterdots}=.
% Pour centrer des nombres sur leurs points d\'ecimaux, il
% suffit\,\footnote{C'est Frank Mittelbach qui le
% dit!}~(juste~?) de d\'efinir les macros suivantes:
% \begin{verbatim}
%{\catcode`\.\active\gdef.{\egroup\setbox2\hbox\bgroup}}
%\def\centerdots{\catcode`\.\active\setbox0\hbox\bgroup}
%\def\endcenterdots{\egroup\ifvoid2 \setbox2\hbox{0}\fi
% \ifdim \wd0>\wd2 \setbox2\hbox to\wd0{\unhbox2\hfill}\else
% \setbox0\hbox to\wd2{\hfill\unhbox0}\fi
% \catcode`\.12 \box0.\box2}
%\end{verbatim}
% Attention: ces macros ne marchent pas si une cellule comporte
% plusieurs points d\'ecimaux ou si le tableau est utilis\'e en argument
% d'une autre commande. Une approche bien meilleure est d'utiliser le
% package \texttt{dcolumn.sty} \'ecrit par David Carlisle.
% \item
% En utilisant =c!{\hspace{1cm}}c= vous \'elargissez d'un
% centim\`etre l'espace entre deux colonnes, tandis que
% =c@{\hspace{1cm}}c= vous donne exactement un centim\`etre
% d'espace entre deux colonnes.
% \end{itemize}
%
% \subsection{D\'efinir de nouveaux types de colonnes}
%
% \DeleteShortVerb{\=}
% \MakeShortVerb{\"}
% \DescribeMacro{\newcolumntype}
% Alors qu'il est pratique de taper
% \begin{quote}
% ">{"\meta{quelques d\'eclarations}"}{c}<{"\meta{quelques
% autres d\'eclarations}"}"
% \end{quote}
% si vous avez une colonne particuli\`ere dans une seule table, cela
% devient peu pratique si vous utilisez souvent des colonnes de cette
% forme. La nouvelle version vous permet de d\'efinir un nouveau
% sp\'ecificateur de colonne, par exemple \texttt{x}, qui remplacera
% plusieurs commandes de sp\'ecificateurs de colonnes\footnote{Cette
% commande \'etait appel\'ee \texttt{\textbackslash{}newcolumn} dans
% \texttt{newarray.sty}. Actuellement, la commande
% \texttt{\textbackslash{}newcolumn} est toujours valide (mais affiche
% un message d'avertissement). Dans les versions ult\'erieures, elle
% dispara\^{\i}tra.}.
% Nous pouvons donc d\'efinir:
% \begin{quote}
% "\newcolumntype{x}{>{"\meta{ d\'eclarations}"}{c}<{"\meta{autres
% d\'eclarations}"}}"\hspace*{-3cm} ^^A no overfull from this line
% \end{quote}
% On peut alors utiliser le sp\'ecificateur de colonne \texttt{x} dans
% les arguments de pr\'eambule de tous les environnements \texttt{array}
% ou \texttt{tabular} dans lesquels vous d\'esirez ce format.
%
% Il est habituel d'avoir besoin de colonnes en mode math\'ematique
% et en mode~LR
% dans le m\^eme tableau. Si nous d\'efinissons:
% \begin{quote}
% "\newcolumntype{C}{>{$}c<{$}}" \\
% "\newcolumntype{L}{>{$}l<{$}}" \\
% "\newcolumntype{R}{>{$}r<{$}}"
% \end{quote}
% alors nous pouvons utiliser \texttt{C} pour avoir un mode~LR centr\'e
% dans un \texttt{array}, ou un mode math\'ematique centr\'e dans
% un \texttt{tabular}.
%
% L'exemple donn\'e plus haut pour les <<~points d\'ecimaux centr\'es~>>
% pourrait \^etre affect\'e \`a un sp\'ecificateur \texttt{d} par la
% commande suivante:
% \begin{quote}
% "\newcolumntype{d}{>{\centerdots}c<{\endcenterdots}}"
% \end{quote}
%
% Cette solution centre toujours le point dans la colonne. Ceci n'est
% pas tr\`es joli si la colonne est form\'ee de grands nombres, mais
% avec peu de d\'ecimales. Une autre solution d'une colonne \texttt{d}
% est:
% \begin{quote}
% "\newcolumntype{d}[1]{>{\rightdots{#1}}r<{\endrightdots}}"
% \end{quote}
% o\`u les macros ad\'equates seraient\footnote{Le package
% \texttt{dcolumn.sty} contient des commandes plus robustes bas\'ees sur
% ces id\'ees.}:
% \begin{verbatim}
% \def\coldot{.}% Ou si vous pr\'ef\'erez, \def\coldot{\cdot}
% {\catcode`\.=\active
% \gdef.{$\egroup\setbox2=\hbox to \dimen0 \bgroup$\coldot}}
% \def\rightdots#1{%
% \setbox0=\hbox{$1$}\dimen0=#1\wd0
% \setbox0=\hbox{$\coldot$}\advance\dimen0 \wd0
% \setbox2=\hbox to \dimen0 {}%
% \setbox0=\hbox\bgroup\mathcode`\.="8000 $}
% \def\endrightdots{$\hfil\egroup\box0\box2}
%\end{verbatim}
% Notez que "\newcolumntype" accepte le m\^eme argument optionnel que
% "\newcommand" pour d\'eclarer le nombre d'arguments pour le
% sp\'ecificateur de colonne. Maintenant vous pouvez
% sp\'ecifier "d{2}" dans votre pr\'eambule pour une colonne de
% nombres ayant au plus deux d\'ecimales.
%
% Une utilisation assez diff\'erente de "\newcolumntype"
% tire parti du fait que le texte de remplacement dans cette commande
% peut si ncessaire faire r\'ef\'erence \`a plus d'une colonne.
% Supposons maintenant que notre document contienne de nombreux
% environnements \texttt{tabular} utilisant le m\^eme pr\'eambule,
% mais que vous vouliez en essayer d'autres. La d\'efinition originale
% dans \LaTeX\ (par Leslie Lamport) vous permettait de faire (bien que
% ce soit sans doute un usage incorrect du syst\`eme):
% \begin{quote}
% "\newcommand{\X}{clr}"\\
% "\begin{tabular}{\X}" \ldots
% \end{quote}
% \texttt{array.sty} fait bien attention de ne pas d\'evelopper le
% pr\'eambule, et donc la solution ci-dessus ne marche pas avec le
% nouveau sch\'ema. Cette fonctionnalit\'e est obtenue avec:
% \begin{quote}
% "\newcolumntype{X}{clr}"\\
% "\begin{tabular}{X}" \ldots
% \end{quote}
%
% Le texte de remplacement dans une commande "\newcolumntype" peut faire
% r\'ef\'erence \`a chacune des primitives de \texttt{array.sty} (voir
% la table~\ref{tab+opt} en page~\pageref{tab+opt}), ainsi qu'aux
% nouvelles lettres d\'efinies dans d'autres commandes "\newcolumntype".
%
% \DescribeMacro{\showcols}Une liste de tous les sp\'ecificateurs
% d\'efinis par "\newcolumntype" est affich\'ee \`a l'\'ecran et dans le
% fichier de logs lorsque la commande "\showcols" est utilis\'ee.
%
%
% \subsection{Variantes sp\'eciales de \texttt{\textbackslash hline}}
%
% La famille des environnements \texttt{tabular} permet un
% positionnement vertical bas\'e sur la ligne de base du texte dans
% lequel l'environnement apparait. Par d\'efaut, l'environnement est
% centr\'e verticalement, mais cela peut \^etre modifi\'e pour l'aligner
% sur la premi\`ere ou la derni\`ere ligne l'environnement en
% sp\'ecifiant la valeur \texttt{t} ou \texttt{b} \`a l'argument
% optionnel de positionnement. Cependant, cela ne marche pas si le
% premier ou le dernier \'el\'ement de l'environnement est une commande
% "\hline" ; dans ce cas, l'environnement est align\'e sur la barre
% horizontale.
%
% \pagebreak[3]
%
% Voici un example:
% \begin{center}
% \begin{minipage}[t]{.4\linewidth}
% Tables
% \begin{tabular}[t]{l}
% sans \\ commande \\ hline
% \end{tabular} et \\ tables
% \begin{tabular}[t]{|l|}
% \hline
% avec \\ commandes \\ hline \\
% \hline
% \end{tabular}
% \end{minipage}
% \begin{minipage}[t]{.5\linewidth}
% \begin{verbatim}
% Tables
% \begin{tabular}[t]{l}
% sans \\ commande \\ hline
% \end{tabular} et \\ tables
% \begin{tabular}[t]{|l|}
% \hline
% avec \\ commandes \\ hline \\
% \hline
% \end{tabular}
% \end{verbatim}
% \end{minipage}
% \end{center}
%
% \DescribeMacro\firsthline
% \DescribeMacro\lasthline
% L'utilisation de "\firsthline" et "\lasthline" va r\'esoudre ce
% probl\`eme, et les tables seront correctement align\'ees tant que
% leur premi\`ere ou derni\`ere ligne ne contient pas d'objets
% excessivement larges.
% \begin{center}
% \begin{minipage}[t]{.4\linewidth}
% Tables
% \begin{tabular}[t]{l}
% sans \\ commande \\ ...line
% \end{tabular} et \\ tables
% \begin{tabular}[t]{|l|}
% \firsthline
% avec \\ commandes \\ ...line \\
% \lasthline
% \end{tabular}
% \end{minipage}
% \begin{minipage}[t]{.5\linewidth}
% \begin{verbatim}
% Tables
% \begin{tabular}[t]{l}
% sans \\ commande \\ ...line
% \end{tabular} et \\ tables
% \begin{tabular}[t]{|l|}
% \firsthline
% avec \\ commandes \\ ...line \\
% \lasrhline
% \end{tabular}
% \end{verbatim}
% \end{minipage}
% \end{center}
%
% \DescribeMacro\extratabsurround
% L'\'ecriture de ces deux commandes contient une longueur
% suppl\'ementaire, appel\'ee "\extratabsurround", pour ajouter une
% espace au d\'ebut ou \`a la fin de ces environnements.
% C'est tr\`es utile quand les tables sont embo\^{\i}t\'ees.
%
% \section{Derniers commentaires}
%
% \subsection{Manipulation des barres de s\'eparation}
%
% Il y a deux approches pour la manipulation des barres horizontales et
% verticales \`a l'int\'erieur des tables:
% \begin{enumerate}
% \item ces barres peuvent \^etre plac\'ees dans l'espace disponible
% sans augmenter la taille de la table, ou
% \item elles peuvent \^etre plac\'ees entre les colonnes et les
% lignes, et par l\`a m\^eme agrandissent la table.
% \end{enumerate}
% \texttt{array.sty} impl\'emente la seconde approche, alors que
% la premi\`ere est utilis\'ee dans le noyau de \LaTeX.
% Les deux ont chacunes leurs avantages, mais il faut faire attention aux
% implications suivantes:
% \begin{itemize}
% \item
% Avec le \LaTeX{} standard, ajouter des barres dans une table ne
% modifiera ni la largeur ni la hauteur de la table (\`a moins
% d'utiliser des doubles barres) ; par exemple changer le
% pr\'eambule de \verb=lll= en \verb=l|l|l= ne modifie pas le
% document autrement qu'en ajoutant les barres. Au contraire, avec
% \texttt{array.sty}, une table qui rentre juste dans la largeur
% \verb=\textwidth= peut produire un d\'ebordement horizontal.
% \item
% Avec le \LaTeX{} standard, modifier l'\'epaisseur des barres peut
% d\'et\'eriorer l'apparence des tables si on ne modifie pas en m\^eme
% temps les param\`etres \verb=\tabcolsep=, etc, l'espace entre la
% barre et la colonne pouvant alors devenir trop petit (ou trop
% grand). En fait, la surimpression de texte est m\^eme possible.
% Au contraire, avec \texttt{array.sty}, la modification de cette
% largeur marche souvent sans probl\`eme parce que les espaces de
% s\'eparation (comme \verb=\tabcolsep=, etc) ne d\'ependent pas de
% l'\'epaisseur des barres.
% \item
% Avec le \LaTeX{} standard, les tableaux encadr\'es pr\'esentent des
% coins bizarres parce que les barres horizontales se terminent au
% milieu des barres verticales. Quand le param\`etre
% \verb=\arrayrulewidth= est grand, l'apparence de la table est tr\`es
% d\'esagr\'eable. Dans ce cas, une simple table comme
%\begin{verbatim}
%\setlength{\arrayrulewidth}{5pt}
%\begin{tabular}{|l|}
% \hline A \\ \hline
%\end{tabular}
%\end{verbatim}
% donnera quelque chose comme
% \begin{center}
%\setlength{\arrayrulewidth}{5pt}
%\begin{tabular}{@{}l@{}}
% \hline \null\hskip-.5\arrayrulewidth\vline
% \hskip\tabcolsep
% A\hskip\tabcolsep
% \vline\hskip-.5\arrayrulewidth\null \\ \hline
%\end{tabular}
% \quad
% au lieu de
% \quad
%\begin{tabular}{|l|}
% \hline A \\ \hline
%\end{tabular}
% \end{center}
% \end{itemize}
%
% \subsection{Comparaisons avec les anciennes versions de \texttt{array.sty}}
%
% Il y a plusieurs diff\'erences dans la fa\c{c}on dont la version 2.1
% traite les donn\'ees incorrectes, m\^eme si le fichier source ne
% semble pas utiliser les fonctionnalit\'es suppl\'ementaires de cette
% nouvelle version.
% \begin{itemize}
% \item Un pr\'eambule de la forme "{wx*{0}{abc}yz}" \'etait trait\'ee
% dans les versions ant\'erieures \`a 2.1 comme "{wx}". La version 2.1
% le traite comme "{wxyz}"
% \item Un param\`etre de positionnement erron\'e comme \texttt{[Q]}
% \'etait consid\'er\'e comme \texttt{[c]} par \texttt{array.sty}, mais
% il est maintenant trait\'e comme \texttt{[t]}.
% \item Un pr\'eambule tel que "{cc*{2}}" avec une erreur dans
% l'argument de l'\'etoile~$*$ engendrera des erreurs diff\'erentes dans
% la nouvelle version. Dans les deux cas, les messages d'erreur ne sont
% pas d'une aide tr\`es utile pour l'utilisateur ordinaire.
% \item Des r\'ep\'etitions de constructions avec \texttt{<} ou \texttt{>}
% engendraient une erreur dans les versions ant\'erieures, mais sont
% maintenant autoris\'ees. Par exemple,
% ">{"\meta{decl1}"}>{"\meta{decl2}"}" est \'equivalent \`a
% ">{"\meta{decl2}\meta{decl1}"}".
% \item La commande "\extracolsep" ne fonctionne pas avec les anciennes
% versions de \texttt{array.sty} (lire les commentaires dans
% \texttt{array.bug}). Avec la version 2.1, "\extracolsep" peut de
% nouveau \^etre utilis\'ee dans des expressions \verb=@{...}= comme avec
% le \LaTeX{} standard; elle peut aussi se trouver dans une commande
% \verb=!{...}=, mais il convient de lire la note ci-dessous.
% \end{itemize}
%
%
% \subsection{Bogues et fonctionnalit\'es}
%
% \begin{itemize}
% \item Les messages d'erreur engendr\'es en d\'ecodant les
% sp\'ecifications des colonnes font r\'ef\'erence \`a l'argument du
% pr\'eambule \textbf{apr\`es} qu'il a \'et\'e r\'e\'ecrit par la
% commande "\newcolumntype", et non pas au pr\'eambule tel qu'il a
% \'et\'e \'ecrit par l'utilisateur. Cela semble in\'evitable pour
% tout syst\`eme utilisant un pr\'e-traitement, et est donc
% consid\'er\'e comme une \textbf{fonctionnalit\'e}.
%
% \item Le traitement de la d\'eclaration de plusieurs \texttt{<} ou
% \texttt{>} peut sembler \'etrange de prime abord. Les anciennes
% versions consid\'eraient ">{"\meta{decl1}"}>{"\meta{decl2}"}"
% comme \'equivalant \`a ">{"\meta{decl1}\meta{decl2}"}".
% Cependant, cela emp\^eche l'utilisateur de remplacer les
% param\`etres d'une commande "\newcolumntype" d\'efinie en utilisant
% ces d\'eclarations. Par exemple, supposons que nous utilisons un
% sp\'ecificateur de colonne \texttt{C} (d\'efini au-dessus) dans un
% environnement \texttt{array}. Le \texttt{C} indique du texte
% centr\'e dans la colonne, alors que ">{\bfseries}C", qui est
% r\'e\'ecrit en ">{\bfseries}>{$}c<{$}" ne peut pas sp\'ecifier une
% colonne de texte en gras, parce que le pr\'eambule ressemblera en
% fait \`a "\hfil$\bfseries$#$ $\hfil" et donc le texte dans la
% colonne n'est pas affect\'e par la commande "\bfseries"\,! La
% version actuelle inverse l'ordre de ces d\'eclarations, et ainsi
% l'exemple pr\'ec\'edent fournit un pr\'eambule de la forme "\hfil$"
% "$\bfseries#$" "$\hfil", les dollars s'annulant mutuellement pour
% donner l'effet escompt\'e.
%
% \item L'utilisation de "\extracolsep" est sujette aux deux
% restrictions suivantes. Il doit y a voir au plus une commande
% "\extracolsep" par sp\'ecificateur "@" ou "!", et cette commande
% doit \^etre entr\'ee telle quelle, elle ne doit pas \^etre le
% r\'esultat du d\'eveloppement d'une commande.
%
% Ainsi, "\newcommand{\ef}{\extracolsep{\fill}}" \ldots "@{\ef}" ne
% marche pas avec ce package. Cependant, il est possible d'utiliser
% \`a la place une construction comme
% "\newcolumntype{e}{@{\extracolsep{\fill}}".
%
% \item Comme indiqu\'e dans le \LaTeX{} book, afin de d\'efinir la
% commande "\multicolumn", chaque colonne \`a l'exception de la
% premi\`ere est compos\'ee du texte compris dans la cellule et de ce
% qui se trouve dans l'espace entre les colonnes situ\'e
% \emph{apr\`es} cette colonne. Cela signifie que dans un tableau avec
% comme pr\'eambule "|l|l|l|l|", une entr\'ee telle que
% "\multicolumn{2}{|c|}" est incorrecte si elle n'intervient pas dans la
% premi\`ere colonne.
%
% Dans le \LaTeX{} standard, cette erreur n'est pas tellement visible
% parce que cette version ajoute des espaces n\'egatifs, si bien que
% chaque "|" n'occupe pas de place horizontalement. Mais dans ce
% package, les lignes verticales conservent leur \'epaisseur, on voit
% alors deux lignes si deux barres ont \'et\'e sp\'ecifi\'ees.
% \end{itemize}
%
%
%
% \changes{v2.2b}{1994/02/04}{Suppression de l'invite en mode interactif}
%
% \StopEventually{
%
%
% \begin{thebibliography}{1}
% \bibitem{bk:GMS94} \textsc{M.~Goossens}, \textsc{F.~Mittelbach}
% et \textsc{A.~Samarin}.
% \newblock The \LaTeX{} Companion.
% \newblock
% Addison-Wesley, Reading, Massachusetts, 1994.
% \bibitem{bk:knuth} \textsc{D. E. Knuth}.
% \newblock The \TeX{}book (Computers \& Typesetting Volume A).
% \newblock
% Addison-Wesley, Reading, Massachusetts, 1986.
% \bibitem{bk:lamport} \textsc{L. Lamport}.
% \newblock
% \LaTeX\ --- A Document Preparation System.
% \newblock
% Addison-Wesley, Reading, Massachusetts, 1986.
% \end{thebibliography}
%
% } ^^A end of \StopEventually
%
%
%\selectlanguage{english}
%
%
% \section{The documentation driver file}
%
% The first bit of code contains the documentation driver file for
% \TeX{}, i.e., the file that will produce the documentation you are
% currently reading. It will be extracted from this file by the
% \texttt{docstrip} program.
% \begin{macrocode}
%<*driver>
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\documentclass{ltxdoc}
\AtBeginDocument{\DeleteShortVerb{\|}} % undo the default is not used
\usepackage{array}
%</driver>
% \end{macrocode}
% \iffalse
%<*driver>
\usepackage[english,frenchb]{babel}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
%</driver>
% \fi
% \begin{macrocode}
%<*driver>
% Allow large table at bottom
\renewcommand{\bottomfraction}{0.7}
\EnableCrossrefs
%\DisableCrossrefs % Say \DisableCrossrefs if index is ready
\RecordChanges % Gather update information
\CodelineIndex % Index code by line number
%\OnlyDescription % comment out for implementation details
%\OldMakeindex % use if your MakeIndex is pre-v2.9
\begin{document}
\DocInput{f-array.dtx}
\end{document}
%</driver>
% \end{macrocode}
%
%
% \section{The construction of the preamble}
%
% \DeleteShortVerb{\"}
% \MakeShortVerb{\=}
%
% It is obvious that those environments will consist mainly of an
% =\halign=, because \TeX\ typesets tables using this primitive.
% That is why we will now take a look at the algorithm which determines
% a preamble for a =\halign= starting with a given user preamble
% using the options mentioned above.
%
%
% The current version is defined at the top of the file looking
% something like this
% \begin{macrocode}
%<*package>
%\NeedsTeXFormat{LaTeX2e}[1994/05/13]
%\ProvidesPackage{array}[\filedate\space version\fileversion]
% \end{macrocode}
%
% The most interesting macros of this implementation are without doubt
% those which are responsible for the construction of the preamble for
% the =\halign=. The underlying algorithm was developed by
% \textsc{Lamport} (resp.\ \textsc{Knuth}, see texhax V87\#??), and it
% has been extended and improved.
%
% The user preamble will be read \textsf{token} by \textsf{token}. A
% \textsf{token} is a single character like \texttt{c} or a block
% enclosed in ={...}=. For example the preamble of
% =\begin{tabular}=\linebreak[0]={lc||c@{\hspace{1cm}}}= consists of
% the \textsf{token} \texttt{l}, \texttt{c}, \texttt{|}, \texttt{|},
% \texttt{@} and =\hspace{1cm}=.
%
% The currently used \textsf{token} and the one, used before, are needed
% to decide on how the construction of the preamble has to be
% continued.
% In the example mentioned above the \texttt{l} causes the preamble
% to begin with =\hskip\tabcolsep=. Furthermore
% =# \hfil= would be appended to define a flush left column.
% The next \textsf{token} is a \texttt{c}. Because it was preceded by an
% \texttt{l} it generates a new column. This is done with
% =\hskip \tabcolsep & \hskip \tabcolsep=. The column which is to
% be centered will be appended with =\hfil # \hfil=.
% The \textsf{token} \texttt{|} would then add a space of
% =\hskip \tabcolsep=
% and a vertical line because the last
% \textsf{tokens} was a \texttt{c}.
% The following \textsf{token} \texttt{|} would only add a space
% =\hskip \doublerulesep= because it was preceded by the
% \textsf{token} \texttt{|}. We will not discuss our example further but
% rather take a look at the general case of constructing preambles.
%
% The example shows that the desired preamble for the
% =\halign= can be constructed as soon as the action of all
% combinations
% of the preamble \textsf{tokens} are specified. There are 18 such
% \textsf{tokens}
% so we have $19 \cdot 18 \string= 342$ combinations if we count the
% beginning of
% the preamble as a special \textsf{token}. Fortunately, there are many
% combinations which generate the same spaces, so we can define
% \textsf{token} classes. We will identify a
% \textsf{token} within a class with a number, so we can insert the
% formatting (for example of a column).
% Table~\ref{tab+Klassen} lists all \textsf{token} classes and
% their corresponding numbers.
% \begin{table}[ht]
% \begin{center}
% \begin{tabular}[t]{>{\ttfamily}ccc}
% \textsf{token} & =\@chclass= & =\@chnum= \\[2mm]
% c & 0 & 0 \\
% l & 0 & 1 \\
% r & 0 & 2 \\
% p-arg & 0 & 3 \\
% t-arg & 0 & 4 \\
% b-arg & 0 & 5 \\
% | & 1 & 0 \\
% !-arg & 1 & 1 \\
% <-arg & 2 & --- \\
% >-arg & 3 & ---
% \end{tabular}
% \kern3mm \vrule \kern3mm%
% \begin{tabular}[t]{>{\ttfamily}ccc}
% \textsf{token} & =\@chclass= & =\@chnum= \\[2mm]
% Start & 4 & --- \\
% @-arg & 5 & --- \\
% ! & 6 & --- \\
% @ & 7 & --- \\
% < & 8 & --- \\
% > & 9 & --- \\
% p & 10 & 3 \\
% t & 10 & 4 \\
% b & 10 & 5
% \end{tabular}
% \end{center}
% \caption{Classes of preamble \textsf{tokens}}
% \label{tab+Klassen}
% \end{table}
%
%
% \begin{macro}{\@chclass}
% \begin{macro}{\@chnum}
% \begin{macro}{\@lastchclass}
% The class and the number of the current \textsf{token} are saved in
% the
% \textsf{count} registers =\@chclass=
% and =\@chnum=, while the class of the previous
% \textsf{token} is stored in the
% \textsf{count} register =\@lastchclass=.
% All of the mentioned registers are already allocated in
% \texttt{latex.tex},
% which is the reason why the following three lines of code are
% commented out.
% Later throughout the text I will not mention it again explicitely
% whenever I use a =%= sign. These parts are already defined in
% \texttt{latex.tex}.
% \begin{macrocode}
% \newcount \@chclass
% \newcount \@chnum
% \newcount \@lastchclass
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\@addtopreamble}
% We will save the already constructed preamble for
% the =\halign=
% in the global macro =\@preamble=. This will then be
% enlarged with
% the command =\@addtopreamble=.
% \begin{macrocode}
\def\@addtopreamble#1{\xdef\@preamble{\@preamble #1}}
% \end{macrocode}
% \end{macro}
%
%
%
%
%
% \subsection{The character class of a \textsf{token}}
%
% \begin{macro}{\@testpach}
% \changes{v2.0a}{1989/05/12}{p option renamed to m (middle).}
% \changes{v2.0a}{1989/05/12}{t option renamed to p to be compatible to
% the original.}
% With the help of =\@lastchclass= we can now define a macro
% which determines the class and the number of a given preamble
% \textsf{token}
% and assigns them to the registers
% =\@chclass= and =\@chnum=.
% \changes{v2.0f}{1992/02/29}{Argument removed since implicitly known}
% \begin{macrocode}
\def\@testpach{\@chclass
% \end{macrocode}
% First we deal with the cases in which the \textsf{token}
% (=#1=) is the argument of \texttt{!}, \texttt{@}, \texttt{<} or
% \texttt{>}. We can see this from the value of =\@lastchclass=:
% \begin{macrocode}
\ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
\ifnum \@lastchclass=7 5 \else
\ifnum \@lastchclass=8 \tw@ \else
\ifnum \@lastchclass=9 \thr@@
% \end{macrocode}
% Otherwise we will assume that the \textsf{token} belongs to the
% class $0$
% and assign the corresponding number to =\@chnum= if our
% assumption is correct.
% \begin{macrocode}
\else \z@
% \end{macrocode}
% If the last \textsf{token} was a \texttt{p}, \texttt{m} or a
% \texttt{b}, =\@chnum= already has the right value. This is the
% reason for the somewhat curious choice of the \textsf{token}
% numbers in class $10$.
% \begin{macrocode}
\ifnum \@lastchclass = 10 \else
% \end{macrocode}
% Otherwise we will check if =\@nextchar= is either a \texttt{c},
% \texttt{l} or an \texttt{r}. Some applications change the
% catcodes of certain characters like ``\texttt{@}'' in
% \texttt{amstex.sty}. As a result the tests below would fail since
% they assume non-active character tokens. Therefore we evaluate
% =\@nextchar= once thereby turning the first token of its
% replacement text into a char. At this point here this should have
% been the only char present in =\@nextchar= which put into via a
% =\def=.
% \changes{v2.0f}{1992/02/29}{Ensure to test a char which is not active}
% \begin{macrocode}
\edef\@nextchar{\expandafter\string\@nextchar}%
\@chnum
\if \@nextchar c\z@ \else
\if \@nextchar l\@ne \else
\if \@nextchar r\tw@ \else
% \end{macrocode}
% If it is a different \textsf{token}, we know that the class was
% not $0$. We assign the value $0$ to =\@chnum= because this value
% is needed for the \texttt{|}--\textsf{token}. Now we must check
% the remaining classes. Note that the value of =\@chnum= is
% insignificant here for most classes.
% \begin{macrocode}
\z@ \@chclass
\if\@nextchar |\@ne \else
\if \@nextchar !6 \else
\if \@nextchar @7 \else
\if \@nextchar <8 \else
\if \@nextchar >9 \else
% \end{macrocode}
% The remaining permitted \textsf{tokens} are \texttt{p},
% \texttt{m} and \texttt{b} (class $10$).
% \begin{macrocode}
10
\@chnum
\if \@nextchar m\thr@@\else
\if \@nextchar p4 \else
\if \@nextchar b5 \else
% \end{macrocode}
% Now the only remaining possibility is a forbidden \textsf{token},
% so we choose class $0$ and number $0$ and give an error message.
% Then we finish the macro by closing all =\if='s.
% \begin{macrocode}
\z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
\fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}
% \end{macrocode}
% \end{macro}
%
%
%
%
%
% \subsection{Multiple columns ($*$--form)}
%
% \begin{macro}{\@xexpast}
% \begin{macro}{\the@toks}
% \begin{macro}{\the@toksz}
% \label{@xexpast} Now we discuss the macro that deletes all forms
% of type =*{=\textit{N\/}=}{=\textit{String\/}=}= from a user
% preamble and replaces them with \textit{N} copies of
% \textit{String}. Nested $*$--expressions are dealt with
% correctly, that means $*$--expressions are not substituted if
% they are in explicit braces, as in =@{*}=.
%
% This macro is called via
% =\@xexpast=\meta{preamble}=*0x\@@=.
% The $*$--expression =*0x= is being used to terminate the
% recursion,
% as we shall see later, and =\@@= serves as an argument
% delimiter. =\@xexpast= has four arguments. The first
% one is the part of the
% user preamble before the first $*$--expression while the second
% and third ones are the arguments of the first $*$--expression
% (that is \textit{N} and \textit{String} in the notation mentioned
% above).
% The fourth argument is the rest of the preamble.
% \begin{macrocode}
\def\@xexpast#1*#2#3#4\@@{%
% \end{macrocode}
% The number of copies of \textit{String} (=#2=) that are to be
% produced will be saved in a \textsf{count} register.
% \begin{macrocode}
\@tempcnta #2
% \end{macrocode}
% We save the part of the preamble which does not
% contain a $*$--form (=#1=)
% in a \PlainTeX\ \textsf{token} register.
% We also save \textit{String} (=#3=) using a \LaTeX\
% \textsf{token} register.
% \begin{macrocode}
\toks@={#1}\@temptokena={#3}%
% \end{macrocode}
% Now we have to use a little trick to produce \textit{N} copies of
% \textit{String}.
% We could try =\def\@tempa{#1}= and then
% \textit{N} times =\edef\@tempa{\@tempa#3}=. This would have the
% undesired effect that all macros within =#1= and =#3=
% would be expanded, although, for example, constructions like
% =@{..}= are not supposed to be changed.
% That is why we =\let= two control sequences to
% be equivalent to =\relax=.
% \begin{macrocode}
\let\the@toksz\relax \let\the@toks\relax
% \end{macrocode}
% Then we ensure that =\@tempa= contains
% ={\the@toksz\the@toks...\the@toks}= (the macro
% =\the@toks= exactly \textit{N\/} times) as substitution text.
% \begin{macrocode}
\def\@tempa{\the@toksz}%
\ifnum\@tempcnta >0 \@whilenum\@tempcnta >0\do
{\edef\@tempa{\@tempa\the@toks}\advance \@tempcnta \m@ne}%
% \end{macrocode}
% If \textit{N\/} was greater than zero we prepare for another call
% of =\@xexpast=. Otherwise we assume we have reached the end of
% the user preamble, because we had appended =*0x\@@= when we first
% called =\@xexpast=. In other words: if the user inserts
% =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it.
% \begin{macrocode}
\let \@tempb \@xexpast \else
\let \@tempb \@xexnoop \fi
% \end{macrocode}
% Now we will make sure that the part of the user preamble, which
% was already dealt with, will be saved again in =\@tempa=.
% \begin{macrocode}
\def\the@toksz{\the\toks@}\def\the@toks{\the\@temptokena}%
\edef\@tempa{\@tempa}%
% \end{macrocode}
% We have now evaluated the first $*$--expression, and the user
% preamble up to this point
% is saved in =\@tempa=. We will put the contents of
% =\@tempa= and the rest of the user preamble together and work
% on the result with =\@tempb=. This macro either corresponds
% to =\@xexpast=, so that the next
% $*$--expression is handled, or to the macro =\@xexnoop=,
% which only ends the recursion by deleting its argument.
% \begin{macrocode}
\expandafter \@tempb \@tempa #4\@@}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@xexnoop}
% So the first big problem is solved. Now it is easy to
% specify =\@xexnoop=.
% Its argument is delimited by =\@@= and it simply expands to
% nothing.
% \begin{macrocode}
% \def\@xexnoop#1\@@{}
% \end{macrocode}
% \end{macro}
%
%
%
%
% \section{The insertion of declarations
% (\texttt{>}, \texttt{<}, \texttt{!}, \texttt{@})}
%
%
% The preamble will be enlarged with the help of =\xdef=, but the
% arguments of \texttt{>}, \texttt{<},~\texttt{!}\ and \texttt{@} are
% not supposed to be expanded during the construction (we want an
% implementation that doesn't need a =\protect=). So we have to find a
% way to inhibit the expansion of those arguments.
%
% We will solve this problem with \textsf{token} registers. We need
% one register for every \texttt{!}\ and \texttt{@}, while we need two
% for every \texttt{c}, \texttt{l}, \texttt{r}, \texttt{m}, \texttt{p}
% or \texttt{b}. This limits the number of columns of a table because
% there are only 256 \textsf{token} registers. But then, who needs
% tables with more than 100 columns?
%
% One could also find a solution which only needs two or three
% \textsf{token} registers by proceeding similarly as in the macro
% =\@xexpast= (see page \pageref{@xexpast}). The advantage of our
% approach is the fact that we avoid some of the problems that arise
% with the other method\footnote{Maybe there are also historical
% reasons.}.
%
% So how do we proceed? Let us assume that we had =!{foo}= in the
% user preamble and say we saved \texttt{foo} in
% \textsf{token} register $5$. Then we call
% =\@addtopreamble{\the@toks5}= where
% =\the@toks= is defined in a way that it does not expand
% (for example it could be equivalent to =\relax=). Every
% following call
% of =\@addtopreamble= leaves =\the@toks5= unchanged in
% =\@preamble=. If the construction of the preamble is completed
% we change the definition of =\the@toks= to
% =\the\toks= and expand =\@preamble= for the last time.
% During this process all parts of the form
% =\the@toks=\meta{Number}
% will be substituted by the contents of the respective \textsf{token}
% registers.
%
% As we can see from this informal discussion the construction of the
% preamble has to take place within a group, so that the
% \textsf{token} registers we use will be freed later on. For that
% reason we keep all assignments to =\@preamble= global; therefore the
% replacement text of this macro will remain the same after we leave
% the group.
%
% \begin{macro}{\count@}
% We further need a \textsf{count} register to remember which
% \textsf{token} register is to be used next. This will be
% initialized with $-1$ if we want to begin with the \textsf{token}
% register $0$. We use the \PlainTeX\ scratch register =\count@=
% because everything takes place locally. All we have to do is
% insert =\the@toks= =\the= =\count@= into the preamble.
% =\the@toks= will remain unchanged and =\the\count@= expands into
% the saved number.
% \end{macro}
%
% \begin{macro}{\prepnext@tok}
% The macro =\prepnext@tok= is in charge of preparing the next
% \textsf{token} register. For that purpose we increase
% =\count@= by $1$:
% \begin{macrocode}
\def\prepnext@tok{\advance \count@ \@ne
% \end{macrocode}
% Then we locally delete any contents the
% \textsf{token} register might have.
% \begin{macrocode}
\toks\count@{}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\save@decl}
% During the construction of the preamble the current
% \textsf{token} is always saved in the macro =\@nextchar= (see the
% definition of =\@mkpream= on page \pageref{@mkpream}). The macro
% =\save@decl= saves it into the next free \textsf{token} register,
% i.e.\ in =\toks\count@=.
% \changes{v2.0c}{1990/08/14}{\cs{relax} removed and added elsewhere.}
% \begin{macrocode}
\def\save@decl{\toks\count@ \expandafter{\@nextchar}}
% \end{macrocode}
% The reason for the use of =\relax= is the following
% hypothetical situation in the preamble:
% \quad =..\the\toks1\the\toks2..= \quad \TeX\ expands
% =\the\toks2= first in order to find out if the digit =1=
% is followed by other digits. E.g.\ a =5= saved in the
% \textsf{token} register $2$ would lead \TeX\ to insert the contents
% of \textsf{token} register $15$ instead of $1$ later on.
%
% The example above referred to an older version of =\save@decl= which
% inserted a =\relex= inside the token register. This is now moved to
% the places where the actual token registers are inserted (look for
% =\the@toks=) because the old version would still make =@=
% expressions to moving arguments since after expanding the second
% register while looking for the end of the number the contents of the
% token register is added so that later on the whole register will be
% expanded. This serious bug was found after nearly two years
% international use of this package by Johannes Braams.
% \end{macro}
%
%
%
% How does the situation look like, if we want to add another column
% to the preamble, i.e.\ if we have found a \texttt{c}, \texttt{l},
% \texttt{r}, \texttt{p}, \texttt{m} or \texttt{b} in the user
% preamble? In this case we have the problem of the \textsf{token}
% register from =>{..}= and =<{..}= having to be inserted at this
% moment because formating instructions like =\hfil= have to be set
% around them. On the other hand it is not known yet, if any =<{..}=
% instruction will appear in the user preamble at all.
%
% We solve this problem by adding two \textsf{token} registers at a
% time. This explains, why we have freed the \textsf{token} registers
% in =\prepnext@tok=.
%
% \begin{macro}{\insert@column}
% \begin{macro}{\@sharp}
% We now define the macro =\insert@column= which will do
% this work for us.
% \begin{macrocode}
\def\insert@column{%
% \end{macrocode}
% Here, we assume that the \textsf{count} register
% =\@tempcnta= has saved the value $=\count@= - 1$.
% \begin{macrocode}
\the@toks \the \@tempcnta
% \end{macrocode}
% Next follows the =#= sign which specifies the place
% where the text of the column shall be inserted. To avoid
% errors during the expansions in
% =\@addtopreamble= we hide this sign in the command
% =\@sharp= which is temporarily occupied with
% =\relax= during the build-up of the preamble.
% To remove unwanted spaces before and after the column text, we set
% an =\ignorespaces= in front and a =\unskip= afterwards.
% \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel}
% \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of
% \cs{d@llarbegin}}
% \begin{macrocode}
\ignorespaces \@sharp \unskip
% \end{macrocode}
% Then the second \textsf{token} register follows whose number should
% be saved in =\count@=.
% We make sure that there will be no further expansion after reading
% the number, by finishing with =\relax=. The case above is not
% critical since it is ended by =\ignorespaces=.
% \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
% \cs{the}\cs{toks0}\cs{the}\cs{toks1}.}
% \begin{macrocode}
\the@toks \the \count@ \relax}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%
% \subsection{The separation of columns}
%
% \begin{macro}{\@addamp}
% In the preamble a =&= has to be inserted between any two columns;
% before the first column there should not be a =&=. As the user
% preamble may start with a \texttt{|} we have to remember somehow
% if we have already inserted a =#= (i.e.\ a column). This is done
% with the boolean variable =\if@firstamp= that we test in
% =\@addamp=, the macro that inserts the =&=.
% \begin{macrocode}
% \newif \@iffirstamp
% \def\@addamp{\if@firstamp \@firstampfalse
% \else \@addtopreamble &\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@acol}
% \begin{macro}{\@acolampacol}
% \begin{macro}{\col@sep}
% We will now define some abbreviations for the extensions,
% appearing most often in the preamble build-up.
% Here =\col@sep= is a \textsf{dimen} register which is set
% equivalent to =\arraycolsep= in an \textsf{array}--environment,
% otherwise it is set equivalent to =\tabcolsep=.
% \begin{macrocode}
\newdimen\col@sep
\def\@acol{\@addtopreamble{\hskip\col@sep}}
% \def\@acolampacol{\@acol\@addamp\@acol}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsection{The macro \texttt{\textbackslash @mkpream}}
%
% \begin{macro}{\@mkpream}
% \begin{macro}{\the@toks}
% \label{@mkpream}
% Now we can define the macro which builds up the preamble for the
% =\halign=.
% First we initialize =\@preamble=, =\@lastchclass=
% and the boolean variable =\if@firstamp=.
% \begin{macrocode}
\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
% \end{macrocode}
% During the build-up of the preamble we cannot directly use the
% =#= sign; this would lead to an error message in the next
% =\@addtopreamble= call.
% Instead, we use the command =\@sharp= at places where later
% a =#= will be.
% This command is at first given the meaning =\relax=;
% therefore it will not be expanded when the preamble
% is extended.
% In the macro =\@array=, shortly before the =\halign=
% is carried out, =\@sharp= is given its final meaning.
%
% In a similar way,
% we deal with the commands =\@startpbox= and
% =\@endpbox=, although the reason is different here: these
% macros expand in many \textsf{tokens} which would delay the
% build-up of the preamble.
% \begin{macrocode}
\let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
% \end{macrocode}
% Now we remove possible $*$-forms in the user preamble with the
% command =\@xexpast=. As we already know, this command saves
% its result in the macro =\@tempa=.
% \begin{macrocode}
\@xexpast #1*0x\@@
% \end{macrocode}
% Afterwards we initialize all registers and macros, that we need
% for the build-up of the preamble.
% Since we want to start with the \textsf{token} register $0$,
% =\count@= has to contain the value $-1$.
% \begin{macrocode}
\count@\m@ne
\let\the@toks\relax
% \end{macrocode}
% Then we call up =\prepnext@tok= in order to prepare the
% \textsf{token} register $0$ for use.
% \begin{macrocode}
\prepnext@tok
% \end{macrocode}
% To evaluate the user preamble (without stars) saved in
% =\@tempa= we use the \LaTeX--macro =\@tfor=.
% The strange appearing construction with =\expandafter= is
% based on the fact that we have to put the replacement text of
% =\@tempa= and not the macro =\@tempa= to this
% \LaTeX--macro.
% \begin{macrocode}
\expandafter \@tfor \expandafter \@nextchar
\expandafter :\expandafter =\@tempa \do
% \end{macrocode}
% The body of this loop (the group after the =\do=)
% is executed for one \textsf{token} at a time, whereas
% the current \textsf{token} is saved in =\@nextchar=.
% At first we evaluate the current \textsf{token} with the already
% defined macro =\@testpach=, i.e.\ we assign to
% =\@chclass= the character class and to =\@chnum=
% the character number of this \textsf{token}.
% \changes{v2.0f}{1992/02/29}{\cs{@testpach} now without arg}
% \begin{macrocode}
{\@testpach
% \end{macrocode}
% Then we branch out depending on the value of =\@chclass= into
% different macros that extend the preamble respectively.
% \begin{macrocode}
\ifcase \@chclass \@classz \or \@classi \or \@classii
\or \save@decl \or \or \@classv \or \@classvi
\or \@classvii \or \@classviii \or \@classix
\or \@classx \fi
% \end{macrocode}
% Two cases deserve our special attention: Since the current
% \textsf{token} cannot have the character class $4$ (start) we
% have skipped this possibility. If the character class is $3$,
% only the content of =\@nextchar= has to be saved into the current
% \textsf{token} register; therefore we call up =\save@decl=
% directly and save a macro name. After the preamble has been
% extended we assign the value of =\@chclass= to the counter
% =\@lastchclass= to assure that this information will be available
% during the next run of the loop.
% \begin{macrocode}
\@lastchclass\@chclass}%
% \end{macrocode}
% After the loop has been finished space must still be added to
% the created preamble, depending on the last \textsf{token}.
% Depending on the value of =\@lastchclass= we perform
% the necessary operations.
% \begin{macrocode}
\ifcase\@lastchclass
% \end{macrocode}
% If the last class equals $0$ we add a
% =\hskip \col@sep=.
% \begin{macrocode}
\@acol \or
% \end{macrocode}
% If it equals $1$ we do not add any additional space so that the
% horizontal lines do not exceed the vertical ones.
% \begin{macrocode}
\or
% \end{macrocode}
% Class $2$ is treated like class $0$ because a =<{...}= can
% only directly follow after class $0$.
% \begin{macrocode}
\@acol \or
% \end{macrocode}
% Most of the other possibilities can only appear if the user
% preamble was defective. Class $3$ is not allowed since after a
% =>{..}= there must always follow a \texttt{c}, \texttt{l},
% \texttt{r}, \texttt{p},\texttt{m} or \texttt{b}. We report an
% error and ignore the declaration given by ={..}=.
% \begin{macrocode}
\@preamerr \thr@@ \or
% \end{macrocode}
% If =\@lastchclass= is $4$ the user preamble has been empty.
% To continue, we insert a =#= in the preamble.
% \begin{macrocode}
\@preamerr \tw@ \@addtopreamble\@sharp \or
% \end{macrocode}
% Class $5$ is allowed again. In this case
% (the user preamble ends with =@{..}=) we need not
% do anything.
% \begin{macrocode}
\or
% \end{macrocode}
% Any other case means that the arguments to =@=, \texttt{!},
% \texttt{<}, \texttt{>}, \texttt{p}, \texttt{m} or \texttt{b} have
% been forgotten. So we report an error and ignore the last
% \textsf{token}.
% \begin{macrocode}
\else \@preamerr \@ne \fi
% \end{macrocode}
% Now that the build-up of the preamble is almost finished we can
% insert the \textsf{token} registers and therefore redefine
% =\the@toks=. The actual insertion, though, is performed
% later.
% \begin{macrocode}
\def\the@toks{\the\toks}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \section{The macros \texttt{\textbackslash @classz}
% to \texttt{\textbackslash @classx}}
%
% The preamble is extended by the macros =\@classz= to
% =\@classx= which are called by =\@mkpream=
% depending on =\@lastchclass=
% (i.e. the character class of the last \textsf{token}).
% \begin{macro}{\@classx}
% First we define =\@classx= because of its important r\^ole.
% When it is called we find that the current
% \textsf{token} is \texttt{p}, \texttt{m} or \texttt{b}.
% That means that a new column has to start.
% \begin{macrocode}
\def\@classx{%
% \end{macrocode}
% Depending on the value of =\@lastchclass= different actions
% must take place:
% \begin{macrocode}
\ifcase \@lastchclass
% \end{macrocode}
% If the last character class was $0$ we separate the columns by
% =\hskip\col@sep= followed by =&= and another
% =\hskip\col@sep=.
% \begin{macrocode}
\@acolampacol \or
% \end{macrocode}
% If the last class was class $1$ --- that means that a vertical
% line was
% drawn, --- before this line a =\hskip\col@sep= was inserted.
% Therefore there has to be only a =&= followed by
% =\hskip\col@sep=. But this =&= may be inserted only
% if this is not the first column. This process is controlled
% by =\if@firstamp= in the macro =\addamp=.
% \begin{macrocode}
\@addamp \@acol \or
% \end{macrocode}
% Class $2$ is treated like class $0$ because =<{...}= can only
% follow after class $0$.
% \begin{macrocode}
\@acolampacol \or
% \end{macrocode}
% Class $3$ requires no actions because all things necessary have
% been done by the preamble \textsf{token} \texttt{>}.
% \begin{macrocode}
\or
% \end{macrocode}
% Class $4$ means that we are at the beginning of the preamble.
% Therefore we start the preamble with =\hskip\col@sep= and
% then call =\@firstampfalse=. This makes sure that a later
% =\@addamp= inserts the character
% =&= into the preamble.
% \begin{macrocode}
\@acol \@firstampfalse \or
% \end{macrocode}
% For class $5$ \textsf{tokens} only the character =&= is inserted
% as a column separator. Therefore we call =\@addamp=.
% \begin{macrocode}
\@addamp
% \end{macrocode}
% Other cases are impossible. For an example
% $=\@lastchclass= \string= 6$---as it might appear in a
% preamble of the form =...!p...=---\texttt{p} would have
% been taken as an argument of \texttt{!}\ by =\@testpach=.
% \begin{macrocode}
\fi}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classz}
% If the character class of the last \textsf{token} is $0$ we have
% \texttt{c}, \texttt{l}, \texttt{r} or an argument of \texttt{m},
% \texttt{b} or\ \texttt{p}. In the first three cases the preamble
% must be extended the same way as if we had class $10$. The
% remaining two cases do not require any action because the space
% needed was generated by the last \textsf{token} (i.e.\
% \texttt{m}, \texttt{b} or \texttt{p}). Since =\@lastchclass= has
% the value $10$ at this point nothing happens when =\@classx= is
% called. So the macro =\@chlassz= may start like this:
% \begin{macrocode}
\def\@classz{\@classx
% \end{macrocode}
% According to the definition of =\insert@column= we must store
% the number of the \textsf{token} register in which a preceding
% =>{..}= might have stored its argument into
% =\@tempcnta=.
% \begin{macrocode}
\@tempcnta \count@
% \end{macrocode}
% To have $=\count@= \string= =\@tmpcnta= + 1$ we prepare
% the next \textsf{token} register.
% \begin{macrocode}
\prepnext@tok
% \end{macrocode}
% Now the preamble must be extended with the column whose format
% can be determinated by =\@chnum=.
% \begin{macrocode}
\@addtopreamble{\ifcase \@chnum
% \end{macrocode}
% If =\@chnum= has the value $0$ a centered column has to be
% generated.
% So we begin with stretchable space.
% \begin{macrocode}
\hfil
% \end{macrocode}
% The command =\d@llarbegin= follows expanding into =\begingroup=
% (in the \textsf{tabular}--environment) or into =$=. Doing this
% (provided an appropriate setting of =\d@llarbegin=) we achieve
% that the contents of the columns of an \textsf{array}--environment
% are set in math mode while those of a \textsf{tabular}--environment
% are set in LR mode.
% \begin{macrocode}
\d@llarbegin
% \end{macrocode}
% Now we insert the contents of the two \textsf{token} registers
% and the symbol
% for the column entry (i.e.\ =#= or
% more precise =\@sharp=) using =\insert@column=.
% \begin{macrocode}
\insert@column
% \end{macrocode}
% We end this case with =\d@llarend= and =\hfil= where =\d@llarend=
% again is either =$= or =\endgroup=.
% \begin{macrocode}
\d@llarend \hfil \or
% \end{macrocode}
% The templates for \texttt{l} and \texttt{r} (i.e.\ =\@chnum= $1$
% or $2$) are generated the same way. Since one =\hfil= is
% missing the text is moved to the relevant side.
% The =\kern\z@= is needed in case of an empty column
% entry. Otherwise
% the =\unskip= in =\insert@column= removes the
% =\hfil=. Changed to =\hskip1sp= so that it interacts better with
% =\@bsphack=.
% \changes{v2.3f}{1996/04/22}
% {(DPC) Extra \cs{kern} keeps tabcolsep in empty l columns
% internal/2122}
% \changes{v2.3i}{1996/06/14}
% {Change both \cs{kern}\cs{z@} to \cs{hskip}1sp for latex/2160}
% \begin{macrocode}
\hskip1sp\d@llarbegin \insert@column \d@llarend \hfil \or
\hfil\hskip1sp\d@llarbegin \insert@column \d@llarend \or
% \end{macrocode}
% The templates for \texttt{p}, \texttt{m} and \texttt{b} mainly
% consist of a \textsf{box}. In case of \texttt{m} it is generated
% by =\vcenter=. This command is allowed only in math
% mode. Therefore we start with a~=$=.
% \begin{macrocode}
$\vcenter
% \end{macrocode}
% The part of the templates which is the same in all three cases
% (\texttt{p}, \texttt{m} and \texttt{b})
% is built by the macros =\@startpbox= and
% =\@endpbox=. =\@startpbox= has an argument:
% the width of the column which is stored in the current
% \textsf{token} (i.e.\ =\@nextchar=).
% Between these two macros we find the well known
% =\insert@column=.
% \begin{macrocode}
\@startpbox{\@nextchar}\insert@column \@endpbox $\or
% \end{macrocode}
% The templates for \texttt{p} and \texttt{b} are generated in the
% same way though we do not need the =$= characters because we use
% =\vtop= or =\vbox=.
% \begin{macrocode}
\vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or
\vbox \@startpbox{\@nextchar}\insert@column \@endpbox
% \end{macrocode}
% Other values for =\@chnum= are impossible. Therefore we
% end the arguments to =\@addtopreamble= and =\ifcase=.
% Before we come to the end of =\@classz= we have to
% prepare the next \textsf{token} register.
% \begin{macrocode}
\fi}\prepnext@tok}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classix}
% In case of class $9$ (\texttt{>}--\textsf{token}) we first check
% if the character class of the last
% \textsf{token} was $3$. In this case we have a
% user preamble of the form =..>{...}>{...}..= which
% is not allowed. We only give an error message and continue.
% So the declarations defined by the first =>{...}=
% are ignored.
% \begin{macrocode}
\def\@classix{\ifnum \@lastchclass = \thr@@
\@preamerr \thr@@ \fi
% \end{macrocode}
% Furthermore, we call up =\@class10= because afterwards always a
% new column is started by \texttt{c}, \texttt{l}, \texttt{r},
% \texttt{p}, \texttt{m} or \texttt{b}.
% \begin{macrocode}
\@classx}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\@classviii}
% If the current \textsf{token} is a \texttt{<} the last character
% class must be $0$. In this case it is not necessary to extend the
% preamble. Otherwise we output an error message, set =\@chclass=
% to $6$ and call =\@classvi=. By doing this we achieve that
% \texttt{<} is treated like \texttt{!}.
% \begin{macrocode}
\def\@classviii{\ifnum \@lastchclass >\z@
\@preamerr 4\@chclass 6 \@classvi \fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arrayrule}
% There is only one incompatibility with the original definition:
% the definition of =\@arrayrule=. In the original a line without
% width\footnote{So the space between \texttt{cc} and \texttt{c|c}
% is equal.} is created by multiple insertions of
% =\hskip .5\arrayrulewidth=.
% We only insert a vertical line into the
% preamble. This is done to prevent problems with \TeX's main
% memory when generating tables with many vertical lines in them
% (especially in the case of \textsf{floats}).
% \begin{macrocode}
\def\@arrayrule{\@addtopreamble \vline}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classvii}
% As a consequence it follows that in case of class $7$
% (=@= \textsf{token}) the preamble need not to be extended.
% In the original definition $=\@lastchclass= \string= 1$
% is treated by inserting =\hskip .5\arrayrulewidth=.
% We only check if the last \textsf{token} was of class $3$ which is
% forbidden.
% \begin{macrocode}
\def\@classvii{\ifnum \@lastchclass = \thr@@
% \end{macrocode}
% If this is true we output an error message and
% ignore the declarations stored
% by the last =>{...}=, because these are overwritten
% by the argument of \texttt{@}.
% \begin{macrocode}
\@preamerr \thr@@ \fi}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@classvi}
% If the current \textsf{token} is a regular \texttt{!}\ and the
% last class was $0$ or $2$ we extend the preamble with
% =\hskip\col@sep=. If the last \textsf{token} was of class $1$
% (for instance \texttt{|}) we extend with =\hskip \doublerulesep=
% because the construction =!{...}= has to be treated like
% \texttt{|}.
% \begin{macrocode}
\def\@classvi{\ifcase \@lastchclass
\@acol \or
\@addtopreamble{\hskip \doublerulesep}\or
\@acol \or
% \end{macrocode}
% Now =\@preamerr...= should follow because a
% user preamble of the form =..>{..}!.= is not allowed.
% To save memory we call =\@classvii= instead which also
% does what we want.
% \begin{macrocode}
\@classvii
% \end{macrocode}
% If =\@lastchclass= is $4$ or $5$ nothing has to be done.
% Class $6$ to $10$ are not possible.
% So we finish the macro.
% \begin{macrocode}
\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classii}
% \begin{macro}{\@classiii}
% In the case of character classes $2$ and $3$ (i.e.\ the argument
% of \texttt{<} or \texttt{>}) we only have to store the current
% \textsf{token} (=\@nextchar=) into the corresponding
% \textsf{token} register since the preparation and
% insertion of these registers
% are done by the macro =\@classz=.
% This is equivalent to calling =\save@decl= in the case of
% class $3$. To save command identifiers we do this call up
% in the macro =\@mkpream=.
%
% Class $2$ exhibits a more complicated situation: the
% \textsf{token} registers have already been inserted by
% =\@classz=. So the value of =\count@= is too high
% by one. Therefore we decrease =\count@= by $1$.
% \begin{macrocode}
\def\@classii{\advance \count@ \m@ne
% \end{macrocode}
% Next we store the current \textsf{token} into the correct
% \textsf{token} register by calling =\save@decl= and then
% increase the value of =\count@= again. At this point we
% can save memory once more (at the cost of time) if we use the
% macro =\prepnext@tok=.
% \begin{macrocode}
\save@decl\prepnext@tok}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\@classv}
% If the current \textsf{token} is of class $5$ then it is an
% argument of a \texttt{@} \textsf{token}. It must be stored into a
% \textsf{token} register.
% \begin{macrocode}
\def\@classv{\save@decl
% \end{macrocode}
% We extend the preamble with a command which inserts this
% \textsf{token} register into the preamble when its construction
% is finished. The user expects that this argument is worked out in
% math mode if it was used in an
% \textsf{array}--environment. Therefore we surround it with
% =\d@llar...='s.
% \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
% `the`toks0`the`toks1.}
% \begin{macrocode}
\@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
% \end{macrocode}
% Finally we must prepare the next \textsf{token} register.
% \begin{macrocode}
\prepnext@tok}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classi}
% In the case of class $0$ we were able to generate the necessary
% space between columns by using the macro =\@classx=.
% Analogously the macro =\@classvi= can be used for class $1$.
% \begin{macrocode}
\def\@classi{\@classvi
% \end{macrocode}
% Depending on =\@chnum= a vertical line
% \begin{macrocode}
\ifcase \@chnum \@arrayrule \or
% \end{macrocode}
% or (in case of =!{...}=) the current \textsf{token} --- stored
% in =\@nextchar= --- has to be inserted into the preamble.
% This corresponds to calling =\@classv=.
% \begin{macrocode}
\@classv \fi}
% \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\@startpbox}
% In =\@classz= the macro =\@startpbox= is used.
% The width of the \textsf{parbox} is passed as an argument.
% =\vcenter=, =\vtop= or =\vbox= are already in the
% preamble. So we start with the braces for the wanted box.
% \begin{macrocode}
\def\@startpbox#1{\bgroup
% \end{macrocode}
% The argument is the width of the box. This information has to be
% assigned to =\hsize=.
% Then we assain default values to several parameters used in a
% \textsf{parbox}.
% \changes{v2.3k}{1998/05/12}{Use \cs{setlength} to set \cs{hsize},
% so that the calc package can be applied here (pr/2793)}
% \begin{macrocode}
\setlength\hsize{#1}\@arrayparboxrestore
% \end{macrocode}
% Our main problem is to obtain the same distance between succeeding
% lines of the \textsf{parbox}.
% We have to remember that the distance between two \textsf{parboxes}
% should be defined by =\@arstrut=. That means that it can be
% greater than the distance in a \textsf{parbox}.
% Therefore it is not enough to set a =\@arstrut= at the
% beginning and at the end of the \textsf{parbox}. This would
% dimension the distance
% between first and second line and the distance between the two
% last lines of the \textsf{parbox} wrongly.
% To prevent this we set an invisible rule of height
% =\@arstrutbox=
% at the beginning of the \textsf{parbox}. This has no effect on the
% depth of the first line. At the end of the \textsf{parbox} we set
% analogously another invisible rule which only affects the depth
% of the last line. It is necessary to wait inserting this strut
% until the paragraph actually starts to allow for things like
% =\parindent= changes via =>{...}=.
% \changes{v2.1c}{1992/12/14}{Use `everypar to insert strut}
% \begin{macrocode}
\everypar{%
\vrule \@height \ht\@arstrutbox \@width \z@
\everypar{}}%
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@endpbox}
% If there are any declarations defined by =>{...}=
% and =<{...}=
% they now follow in the macro =\@classz= --- the contents
% of the column in between.
% So the macro =\@endpbox= must insert the \textsf{specialstrut}
% mentioned earlier and then close the group opened by
% =\@startpbox=.
% \changes{v2.2d}{1994/05/16}{Use \LaTeXe \cs{@finalstrut}}
% \changes{v2.3g}{1996/05/07}{Add \cs{hfil} for tools/2120}
% \begin{macrocode}
\def\@endpbox{\@finalstrut\@arstrutbox \egroup\hfil}
% \end{macrocode}
% \end{macro}
%
%
% \section{Building and calling \texttt{\textbackslash halign}}
%
% \begin{macro}{\@array}
% After we have discussed the macros needed for the evaluation
% of the user preamble we can define the macro =\@array=
% which uses these macros to create a =\halign=.
% It has two arguments. The first one is a position argument
% which can be \texttt{t}, \texttt{b} or \texttt{c}; the
% second one describes the wanted preamble,
% e.g.\ it has the form =|c|c|c|=.
% \begin{macrocode}
\def\@array[#1]#2{%
% \end{macrocode}
% First we define a \textsf{strut} whose size basically corresponds
% to a normal \textsf{strut} multiplied by the factor
% =\arraystretch=.
% This \textsf{strut} is then inserted into every row and enforces
% a minimal distance between two rows.
% Nevertheless, when using horizontal lines, large letters
% (like accented capital letters) still collide with such lines.
% Therefore at first we add to the height of a normal \textsf{strut}
% the value of the parameter =\extrarowheight=.
% \begin{macrocode}
\@tempdima \ht \strutbox
\advance \@tempdima by\extrarowheight
\setbox \@arstrutbox \hbox{\vrule
\@height \arraystretch \@tempdima
\@depth \arraystretch \dp \strutbox
\@width \z@}%
% \end{macrocode}
% Then we open a group, in which the user preamble is evaluated by
% the macro =\@mkpream=. As we know this must happen locally.
% This macro creates a preamble for a =\halign= and saves
% its result globally in the control sequence =\@preamble=.
% \begin{macrocode}
\begingroup
\@mkpream{#2}%
% \end{macrocode}
% We again redefine =\@preamble= so that a call up of =\@preamble=
% now starts the =\halign=. Thus also the arguments of \texttt{>},
% \texttt{<}, \texttt{@} and \texttt{!}, saved in the
% \textsf{token} registers are inserted into the preamble. The
% =\tabskip= at the beginning and end of the preamble is set to
% \textsf{0pt} (in the beginning by the use of =\ialign=). Also the
% command =\@arstrut= is build in, which inserts the
% =\@arstrutbox=, defined above. Of course, the opening brace after
% =\ialign= has to be implicit as it will be closed in =\endarray=
% or another macro.
% \changes{v2.3m}{1998/12/31}{Added \cs{noexpand} in front of \cs{ialign}
% to guard against interesting :-) changes to \cs{halign} done to support
% text glyphs in math}
%
% The =\noexpand= in front of =\ialign= does no harm in standard \LaTeX{}
% and was added since some experimental support for using text glyphs in math
% redefines =\halign= with the result that is becomes expandable with
% disastrous results in cases like this.
% In the kernel definition for this macro the problem does
% not surface because there =\protect= is set (which is not necessary in this
% implementation as there is no arbitrary user input that can get expanded) and
% the experimental code made the redefinition robust. Whether this is the right
% approach is open to question; consider the =\noexpand= a curtesy to allow an
% unsupported redefinition of a \TeX{} primitive for the moment (as people rely
% on that experimental code).
% \begin{macrocode}
\xdef\@preamble{\noexpand \ialign \@halignto
\bgroup \@arstrut \@preamble
\tabskip \z@ \cr}%
% \end{macrocode}
% What we have not explained yet is the macro =\@halignto=
% that was just used. Depending on its replacement text the
% =\halign= becomes a =\halign= \texttt{to} \meta{dimen}.
% Now we close the group again. Thus
% =\@startpbox= and =\@endpbox= as well as all
% \textsf{token} registers get their former meaning back.
% \begin{macrocode}
\endgroup
% \end{macrocode}
% To support the \texttt{delarray.sty} package we include a hook
% into this part of the code which is a no-op in the main package.
% \changes{v2.1a}{1992/07/03}{Hook for delarray added}
% \begin{macrocode}
\@arrayleft
% \end{macrocode}
% Now we decide depending on the position argument in which
% \textsf{box} the =\halign= is to be put. (=\vcenter= may be used
% because we are in math mode.)
% \changes{v2.1a}{1992/07/03}{Wrong spec is now equiv to [t]}
% \begin{macrocode}
\if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
% \end{macrocode}
% Now another implicit opening brace appears; then definitions
% which shall stay local follow. While constructing the
% =\@preamble= in =\@mkpream= the =#= sign must be
% hidden in the macro =\@sharp= which is =\let= to
% =\relax= at that moment (see definition of =\@mkpream=
% on page~\pageref{@mkpream}).
% All these now get their actual meaning.
% \begin{macrocode}
\bgroup
\let \@sharp ##\let \protect \relax
% \end{macrocode}
% With the above defined \textsf{struts} we fix down the distance
% between rows by setting =\lineskip= and =\baselineskip=
% to \textsf{0pt}. Since there have to be set =$='s
% around every column in the \textsf{array}--environment
% the parameter =\mathsurround= should
% also be set to \textsf{0pt}. This prevents additional space between
% the rows. The
% \PlainTeX--macro =\m@th= does this.
% \begin{macrocode}
\lineskip \z@
\baselineskip \z@
\m@th
% \end{macrocode}
% Beside, we have to assign a special meaning (which we still have
% to specify) to the line separator =\\=. We also have to
% redefine the command =\par= in such a way that empty lines in
% =\halign= cannot do any damage. We succeed in doing so
% by choosing something that will disappear when expanding.
% After that we only have to call up =\@preamble= to
% start the wanted =\halign=.
% \changes{1994/12/08}{v2.3b}{add \cs{tabularnewline}}
% \begin{macrocode}
\let\\\@arraycr \let\tabularnewline\\\let\par\@empty \@preamble}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\extrarowheight}
% The \textsf{dimen} parameter used above also needs to be
% allocated. As a default value we use \textsf{0pt}, to ensure
% compatibility with standard \LaTeX.
% \begin{macrocode}
\newdimen \extrarowheight
\extrarowheight=0pt
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arstrut}
% Now the insertion of =\@arstrutbox= through =\@arstut=
% is easy since we know exactly in which mode \TeX\ is while working
% on the =\halign= preamble.
% \begin{macrocode}
\def\@arstrut{\unhcopy\@arstrutbox}
% \end{macrocode}
% \end{macro}
%
%
% \section{The line separator \texttt{\textbackslash\textbackslash}}
%
% \begin{macro}{\@arraycr}
% In the macro =\@array= the line separator =\\= is
% =\let= to the command =\@arraycr=.
% Its definition starts with a special brace which I have directly
% copied from the original definition. It is
% necessary, because the =\futurlet= in =\@ifnextchar=
% might
% expand a following =&= \textsf{token} in a construction like
% =\\ &=. This would otherwise end the alignment template at a
% wrong time. On the other hand we have to be careful to avoid
% producing a real group, i.e.\ ={}=, because the command will also
% be used for the array environment, i.e.\ in math mode. In that
% case an extra ={}= would produce an ord atom which could mess up
% the spacing. For this reason we use a combination that does not
% really produce a group at all but modifies the master counter so
% that a =&= will not be considered belonging to the current
% =\halign= while we are looking for a =*= or =[=.
% For further information see
% \cite[Appendix D]{bk:knuth}.
% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
% \begin{macrocode}
\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi
% \end{macrocode}
% Then we test whether the user is using the star form and ignore
% a possible star (I also disagree with this procedure, because a
% star does not make any sense here).
% \begin{macrocode}
\@ifstar \@xarraycr \@xarraycr}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xarraycr}
% In the command =\@xarraycr= we test if an optional argument
% exists.
% \begin{macrocode}
\def\@xarraycr{\@ifnextchar [%
% \end{macrocode}
% If it does, we branch out into the macro =\@argarraycr= if
% not we close the special brace (mentioned above) and end the row
% of the =\halign= with a =\cr=.
% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
% \begin{macrocode}
\@argarraycr {\ifnum 0=`{}\fi\cr}}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\@argarraycr}
% If additional space is requested by the user this case is treated
% in the macro =\@argarraycr=. First we close the special brace
% and then we test if the additional space is positive.
% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
% \begin{macrocode}
\def\@argarraycr[#1]{\ifnum0=`{}\fi\ifdim #1>\z@
% \end{macrocode}
% If this is the case we create an invisible vertical rule with
% depth =\dp\@arstutbox=${}+{}$\meta{wanted\ space}.
% Thus we achieve that all vertical lines specified
% in the user preamble by a \texttt{|} are now
% generally drawn.
% Then the row ends with a =\cr=.
%
% If the space is negative we end the row at once with a =\cr=
% and move back up with a =\vskip=.
%
% While testing these macros I found out that the
% =\endtemplate=
% created by =\cr= and =&= is something like an
% =\outer= primitive and therefore it should not appear in
% incomplete =\if= statements. Thus the following solution was
% chosen which hides the =\cr= in other macros when \TeX\
% is skipping conditional text.
% \changes{v2.3c}{1995/04/23}{Use \cs{expandafter}'s in conditional}
% \begin{macrocode}
\expandafter\@xargarraycr\else
\expandafter\@yargarraycr\fi{#1}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@xargarraycr}
% \begin{macro}{\@yargarraycr}
% The following macros were already explained above.
% \begin{macrocode}
\def\@xargarraycr#1{\unskip
\@tempdima #1\advance\@tempdima \dp\@arstrutbox
\vrule \@depth\@tempdima \@width\z@ \cr}
\def\@yargarraycr#1{\cr\noalign{\vskip #1}}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%
% \section{Spanning several columns}
%
% \begin{macro}{\multicolumn}
% If several columns should be held together with a special format
% the command =\multicolumn= must be used. It has three
% arguments: the number of columns to be covered; the format for
% the result column and the actual column entry.
% \changes{v2.3j}{1998/01/29}{Command made \cs{long} to match
% kernel change for pr/2180}
% \begin{macrocode}
\long\def\multicolumn#1#2#3{%
% \end{macrocode}
% First we combine the given number of columns into a single one;
% then we start a new block so that the following definition is kept
% local.
% \begin{macrocode}
\multispan{#1}\begingroup
% \end{macrocode}
% Since a =\multicolumn= should only describe the format of a
% result column, we redefine =\@addamp= in such a way that one gets
% an error message if one uses more than one \texttt{c},
% \texttt{l}, \texttt{r}, \texttt{p}, \texttt{m} or \texttt{b} in
% the second argument. One should consider that this definition is
% local to the build-up of the preamble; an \textsf{array}-- or
% \textsf{tabular}--environment in the third argument of the
% =\multicolumn= is therefore worked through correctly as well.
% \begin{macrocode}
\def\@addamp{\if@firstamp \@firstampfalse \else
\@preamerr 5\fi}%
% \end{macrocode}
% Then we evaluate the second argument with the help of
% =\@mkpream=.
% Now we still have to insert the contents of the \textsf{token}
% register into the =\@preamble=, i.e.\ we have to say
% =\xdef\@preamble{\@preamble}=. This is achieved shorter by
% writing:
% \begin{macrocode}
\@mkpream{#2}\@addtopreamble\@empty
% \end{macrocode}
% After the =\@preamble= is created we forget all local
% definitions and occupations of the \textsf{token} registers.
% \begin{macrocode}
\endgroup
% \end{macrocode}
% In the special situation of =\multicolumn= =\@preamble=
% is not needed as preamble for a =\halign= but it is directly
% inserted into our table. Thus instead of =\sharp=
% there has to be the column entry (=#3=) wanted by the user.
% \begin{macrocode}
\def\@sharp{#3}%
% \end{macrocode}
% Now we can pass the =\@preamble= to \TeX\ . For safety
% we start with an =\@arstrut=. This should usually be in the
% template for the first column however we do not know if this
% template was overwritten by our =\multicolumn=.
% We also add a =\null= at the right end to prevent any following
% =\unskip= (for example from =\\[..]=) to remove the =\tabcolsep=.
% \changes{v2.2e}{1994/06/01}{Added \cs{null}}
% \begin{macrocode}
\@arstrut \@preamble
\null
\ignorespaces}
% \end{macrocode}
% \end{macro}
%
%
%
% \section{The Environment Definitions}
%
% After these preparations we are able to define the environments. They
% only differ in the initialisations of =\d@llar...=, =\col@sep=
% and =\@halignto=.
%
% \begin{macro}{\@halignto}
% \begin{macro}{\d@llarbegin}
% \begin{macro}{\d@llarend}
% In order to relieve the \textsf{save stack} we assign the
% replacement texts for =\@halignto= globally. =\d@llar= has to be
% local since otherwise nested \textsf{tabular} and \textsf{array}
% environments (via =\multicolumn=) are impossible.
% \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on toplevel.}
% When the new font selection scheme is in force we have to
% we surround all =\halign= entries
% with braces. See remarks in TUGboat 10\#2. Actually we are going
% to use =\begingroup= and =\endgroup=. However, this is only
% necessary when we are in text mode. In math the surrounding
% dollar signs will already serve as the necessary extra grouping
% level. Therefore we switch the settings of =\d@llarbegin= and
% =\d@llarend= between groups and dollar signs.
% \begin{macrocode}
\let\d@llarbegin\begingroup
\let\d@llarend\endgroup
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\array}
% Our new definition of =\array= then reads:
% \changes{v2.0d}{1990/08/20}{`d@llar local to preamble.}
% \begin{macrocode}
\def\array{\col@sep\arraycolsep
\def\d@llarbegin{$}\let\d@llarend\d@llarbegin\gdef\@halignto{}%
% \end{macrocode}
% Since there might be an optional argument we call another
% macro which is also used by the other environments.
% \begin{macrocode}
\@tabarray}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@tabarray}
% This macro tests for a optional bracket and then calls up
% =\@array= or =\@array[c]= (as default).
% \begin{macrocode}
\def\@tabarray{\@ifnextchar[{\@array}{\@array[c]}}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\tabular}
% \begin{macro}{\tabular*}
% The environments \textsf{tabular} and \textsf{tabular$*$} differ
% only in the initialisation of the command =\@halignto=. Therefore
% we define
% \begin{macrocode}
\def\tabular{\gdef\@halignto{}\@tabular}
% \end{macrocode}
% and analoguesly for the star form. We evalute the argument first
% using =\setlength= so that users of the \texttt{calc} package can
% write code like\\ =\begin{tabular*}{(\columnwidth-1cm)/2}...=
% \changes{v2.3l}{1998/05/13}{Use \cs{setlength} evaluate arg
% so that the calc package can be applied here (pr/2793)}
% \begin{macrocode}
\expandafter\def\csname tabular*\endcsname#1{%
\setlength\dimen@{#1}%
\xdef\@halignto{to\the\dimen@}\@tabular}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@tabular}
% The rest of the job is carried out by the =\@tabular= macro:
% \begin{macrocode}
\def\@tabular{%
% \end{macrocode}
% First of all we have to make sure that we start out in
% \textsf{hmode}. Otherwise we might find our table dangling by
% itself on a line.
% \begin{macrocode}
\leavevmode
% \end{macrocode}
% It should be taken into consideration that the macro =\@array=
% must be called in math mode. Therefore we open a \textsf{box},
% insert a =$= and then assign the correct values to =\col@sep= and
% =\d@llar...=.
% \changes{v2.0d}{1990/08/20}{`d@llar local to preamble.}
% \begin{macrocode}
\hbox \bgroup $\col@sep\tabcolsep \let\d@llarbegin\begingroup
\let\d@llarend\endgroup
% \end{macrocode}
% Now everything \textsf{tabular} specific is done and we are able to
% call the =\@tabarray= macro.
% \begin{macrocode}
\@tabarray}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endarray}
% When the processing of \textsf{array} is finished we have to
% close the =\halign=
% and afterwards the surrounding \textsf{box} selected by
% =\@array=. To save \textsf{token} space we then redefine
% =\@preamble=
% because its replacement text isn't longer needed.
% \begin{macrocode}
\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endtabular}
% \begin{macro}{\endtabular*}
% To end a \textsf{tabular} or \textsf{tabular$*$} environment we
% call up =\endarray=, close the math mode and then the surrounding
% =\hbox=.
% \begin{macrocode}
\def\endtabular{\endarray $\egroup}
\expandafter\let\csname endtabular*\endcsname=\endtabular
% \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \section{Last minute definitions}
%
%
% If this file is used as a package file we should =\let= all macros
% to =\relax= that were used in the original but are no longer
% necessary.
% \begin{macrocode}
\let\@ampacol=\relax \let\@expast=\relax
\let\@arrayclassiv=\relax \let\@arrayclassz=\relax
\let\@tabclassiv=\relax \let\@tabclassz=\relax
\let\@arrayacol=\relax \let\@tabacol=\relax
\let\@tabularcr=\relax \let\@@endpbox=\relax
\let\@argtabularcr=\relax \let\@xtabularcr=\relax
% \end{macrocode}
%
% \begin{macro}{\@preamerr}
% We also have to redefine the error routine =\@preamerr= since
% new kind of errors are possible.
% The code for this macro is not perfect yet;
% it still needs too much memory.
% \begin{macrocode}
\def\@preamerr#1{\def\@tempd{{..} at wrong position: }%
\PackageError{array}{%
\ifcase #1 Illegal pream-token (\@nextchar): `c' used\or %0
Missing arg: token ignored\or %1
Empty preamble: `l' used\or %2
>\@tempd token ignored\or %3
<\@tempd changed to !{..}\or %4
Only one column-spec. allowed.\fi}\@ehc} %5
% \end{macrocode}
% \end{macro}
%
%
%
% \section
% [Defining your own column specifiers]
% {Defining your own column specifiers\footnotemark}
%
% \footnotetext{The code and the documentation in this section was
% written by David. So far only the code from newarray was plugged
% into array so that some parts of the documentation still claim
% that this is newarray and even worse, some parts of the code are
% unnecessarily doubled. This will go away in a future release. For
% the moment we thought it would be more important to bring both
% packages together.}
% \changes{v2.1a}{1992/07/03}{Newcolumn stuff added}
%
% \DeleteShortVerb{\=}
% \MakeShortVerb{\"}
%
% \begin{macro}{\newcolumn}
% In \texttt{newarray.sty} the macro for specifying new columns was
% named "\newcolumn". When the functionality was added to
% \texttt{array.sty} the command was renamed "\newcolumntype".
% Initially both names were supported, but now (In versions of this
% package distributed for \LaTeXe) the old name is not defined.
% \changes{v2.2a}{1994/02/03}{Now made `newcolumn an error}
% \changes{v2.2a}{1994/02/04}{Removed `newcolumn}
% \begin{macrocode}
%<*ncols>
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\newcolumntype}
% \changes{v2.1b}{1992/06/07}{Macro renamed from `newcolumn} As
% described above, the "\newcolumntype" macro gives users the chance
% to define letters, to be used in the same way as the primitive
% column specifiers, `c' `p' etc.
% \begin{macrocode}
\def\newcolumntype#1{%
% \end{macrocode}
% "\NC@char" was added in V2.01 so that active characters, like "@" in
% AMS\LaTeX\ may be used. This trick was stolen from \texttt{array.sty}
% 2.0h. Note that we need to use the possibly active token,
% "#1", in several places, as that is the token that actually
% appears in the preamble argument.
% \begin{macrocode}
\edef\NC@char{\string#1}%
% \end{macrocode}
% First we check whether there is already a definition for this column.
% Unlike "\newcommand" we give a warning rather than an error if it is
% defined. If it is a new column, add "\NC@do" \meta{column} to
% the list "\NC@list".
% \begin{macrocode}
\@ifundefined{NC@find@\NC@char}%
{\@tfor\next:=<>clrmbp@!|\do{\if\noexpand\next\NC@char
\PackageWarning{array}%
{Redefining primitive column \NC@char}\fi}%
\NC@list\expandafter{\the\NC@list\NC@do#1}}%
{\PackageWarning{array}{Column \NC@char\space is already defined}}%
% \end{macrocode}
% Now we define a macro with an argument delimited by the new column
% specifier, this is used to find occurences of this specifier in the
% user preamble.
% \begin{macrocode}
\@namedef{NC@find@\NC@char}##1#1{\NC@{##1}}%
% \end{macrocode}
% If an optional argument was not given, give a default argument of 0.
% \begin{macrocode}
\@ifnextchar[{\newcol@{\NC@char}}{\newcol@{\NC@char}[0]}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\newcol@}
% We can now define the macro which does the rewriting,
% "\@reargdef" takes the same arguments as "\newcommand", but
% does not check that the command is new. For a column, say `D' with
% one argument, define a command "\NC@rewrite@D" with one
% argument, which recursively calls "\NC@find" on the user preamble
% after replacing the first token or group with the replacement text
% specified in the "\newcolumntype" command. "\NC@find" will find the
% next occurrence of `D' as it will be "\let" equal to
% "\NC@find@D" by "\NC@do".
% \begin{macrocode}
\def\newcol@#1[#2]#3{\expandafter\@reargdef
\csname NC@rewrite@#1\endcsname[#2]{\NC@find#3}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@}
% Having found an occurence of the new column, save the preamble
% before the column in "\@temptokena", then check to see if we
% are at the end of the preamble. (A dummy occurrence of the column
% specifier will be placed at the end of the preamble by "\NC@do".
% \begin{macrocode}
\def\NC@#1{%
\@temptokena\expandafter{\the\@temptokena#1}\futurelet\next\NC@ifend}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@ifend}
% We can tell that we are at the end as "\NC@do" will place a "\relax"
% after the dummy column.
% \begin{macrocode}
\def\NC@ifend{%
% \end{macrocode}
% If we are at the end, do nothing. (The whole preamble will now be in
% "\@temptokena".)
% \begin{macrocode}
\ifx\next\relax
% \end{macrocode}
% Otherwise set the flag "\if@tempswa", and rewrite the column.
% "\expandafter" introduced 1n V2.01
% \begin{macrocode}
\else\@tempswatrue\expandafter\NC@rewrite\fi}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@do}
% If the user has specified `C' and `L' as new columns, the list of
% rewrites (in the token register "\NC@list") will look like
% "\NC@do *" "\NC@do C" "\NC@do L".
% So we need to define "\NC@do" as a one argument macro which
% initialises the rewriting of the specified column. Let us assume that
% `C' is the argument.
% \begin{macrocode}
\def\NC@do#1{%
% \end{macrocode}
% First we let "\NC@rewrite" and "\NC@find" be
% "\NC@rewrite@C" and "\NC@find@C" respectively.
% \begin{macrocode}
\expandafter\let\expandafter\NC@rewrite
\csname NC@rewrite@\string#1\endcsname
\expandafter\let\expandafter\NC@find
\csname NC@find@\string#1\endcsname
% \end{macrocode}
% Clear the token register "\@temptokena" after putting the present
% contents of the register in front of the token "\NC@find". At the
% end we place the tokens `"C\relax"' which "\NC@ifend" will use
% to detect the end of the user preamble.
% \begin{macrocode}
\expandafter\@temptokena\expandafter{\expandafter}%
\expandafter\NC@find\the\@temptokena#1\relax}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\showcols}
% This macro is useful for debugging "\newcolumntype" specifications,
% it is the equivalent of the primitive "\show" command for macro
% definitions. All we need to do is locally redefine "\NC@do" to take
% its argument (say `C') and then "\show" the (slightly modified)
% definition of "\NC@rewrite@C". Actually as the the list always
% starts off with "\NC@do *" and we do not want to print the
% definition of the $*$-form, define "\NC@do" to throw away the first
% item in the list, and then redefine itsef to print the rest of the
% definitions.
% \begin{macrocode}
\def\showcols{{\def\NC@do##1{\let\NC@do\NC@show}\the\NC@list}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@show}
% If the column `C' is defined as above, then
% "\show\NC@rewrite@C" would output\\
% "\long macro: ->\NC@find >{$}c<{$}".
% We want to strip the "long macro: ->" and the "\NC@find". So first we
% use "\meaning" and then apply the macro "\NC@strip" to the tokens so
% produced and then "\typeout" the required string.
% \begin{macrocode}
\def\NC@show#1{%
\typeout{Column #1\expandafter\expandafter\expandafter\NC@strip
\expandafter\meaning\csname NC@rewrite@#1\endcsname\@@}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@strip}
% Delimit the arguments to "\NC@strip" with `\texttt{:}', `\texttt{->}',
% a space, and "\@@" to pull out the required parts of the output from
% "\meaning".
% \begin{macrocode}
\def\NC@strip#1:#2->#3 #4\@@{#2 -> #4}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\NC@list}
% Allocate the token register used for the rewrite list.
% \begin{macrocode}
\newtoks\NC@list
% \end{macrocode}
% \end{macro}
%
% \subsection{The $*$--form}
% We view the $*$-form as a slight generalisation of the system
% described in the previous subsection. The idea is to define a $*$
% column by a command of the form:
% \begin{verbatim}
% \newcolumntype{*}[2]{%
% \count@=#1\ifnum\count@>0
% \advance\count@ by -1 #2*{\count@}{#2}\fi}
% \end{verbatim}
% \begin{macro}{\NC@rewrite@*}\label{NC@rewrite@*}
% This does not work however as "\newcolumntype" takes great care not
% to expand anything in the preamble, and so the "\if" is never
% expanded. "\newcolumntype" sets up various other parts of the
% rewrite correctly though so we can define:
% \begin{macrocode}
\newcolumntype{*}[2]{}
% \end{macrocode}
% Now we must correct the definition of "\NC@rewrite@*". The
% following is probably more efficient than a direct translation of
% the idea sketched above, we do not need to put a $*$ in the preamble
% and call the rewrite recursively, we can just put "#1" copies of
% "#2" into "\@temptokena". (Nested $*$ forms will be expanded
% when the whole rewrite list is expanded again, see "\@mkpream")
% \begin{macrocode}
\long\@namedef{NC@rewrite@*}#1#2{%
% \end{macrocode}
% Store the number.
% \begin{macrocode}
\count@#1
% \end{macrocode}
% Put "#1" copies of "#2" in the token register.
% \begin{macrocode}
\loop
\ifnum\count@>\z@
\advance\count@\m@ne
\@temptokena\expandafter{\the\@temptokena#2}%
\repeat
% \end{macrocode}
% "\NC@do" will ensure that "\NC@find" is "\let" equal
% to "\NC@find@*".
% \begin{macrocode}
\NC@find}
% \end{macrocode}
% \end{macro}
%
% \subsection{Modifications to internal macros of \texttt{array.sty}}
%
% \begin{macro}{\@xexpast}
% \begin{macro}{\@xexnoop}
% These macros are used to expand $*$-forms in
% \texttt{array.sty}. "\let" them to "\relax" to save space.
% \begin{macrocode}
\let\@xexpast\relax
\let\@xexnoop\relax
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\save@decl}
% We do not assume that the token register is free, we add the new
% declarations to the front of the register. This is to allow user
% preambles of the form, ">{foo}>{bar}..". Users are not encouraged to
% enter such expressions directly, but they may result from the
% rewriting of "\newcolumntype"'s.
% \begin{macrocode}
\def\save@decl{\toks \count@ = \expandafter\expandafter\expandafter
{\expandafter\@nextchar\the\toks\count@}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\@mkpream}
% The main modification to "\@mkpream" is to replace the call to
% "\@xexpast" (which expanded $*$-forms) by a loop which expands
% all "\newcolumntype" specifiers.
% \begin{macrocode}
\def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
\let\@sharp\relax \let\@startpbox\relax \let\@endpbox\relax
% \end{macrocode}
% Now we remove possible $*$-forms and user-defined column
% specifiers in the user preamble by repeatedly executing the list
% "\NC@list" until the re-writes have no more effect. The
% expanded preamble will then be in the token register
% "\@temptokena". Actually we need to know at this point that
% this is not "\toks0".
% \begin{macrocode}
\@temptokena{#1}\@tempswatrue
\@whilesw\if@tempswa\fi{\@tempswafalse\the\NC@list}%
% \end{macrocode}
% Afterwards we initialize all registers and macros, that we need
% for the build-up of the preamble.
% \begin{macrocode}
\count@\m@ne
\let\the@toks\relax
\prepnext@tok
% \end{macrocode}
% Having expanded all tokens defined using "\newcolumntype" (including
% "*"), we evaluate the remaining tokens, which are saved in
% "\@temptokena". We use the \LaTeX--macro "\@tfor" to inspect each
% token in turn.
% \begin{macrocode}
\expandafter \@tfor \expandafter \@nextchar
\expandafter :\expandafter =\the\@temptokena \do
% \end{macrocode}
% "\@testpatch" does not take an argument since \texttt{array.sty} 2.0h.
% \begin{macrocode}
{\@testpach
\ifcase \@chclass \@classz \or \@classi \or \@classii
\or \save@decl \or \or \@classv \or \@classvi
\or \@classvii \or \@classviii
% \end{macrocode}
% In \texttt{newarray.sty} class 9 is equivalent to class 10.
% \begin{macrocode}
\or \@classx
\or \@classx \fi
\@lastchclass\@chclass}%
\ifcase\@lastchclass
\@acol \or
\or
\@acol \or
\@preamerr \thr@@ \or
\@preamerr \tw@ \@addtopreamble\@sharp \or
\or
\else \@preamerr \@ne \fi
\def\the@toks{\the\toks}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classix}
% \texttt{array.sty} does not allow repeated \texttt{>}
% declarations for the same column. This is allowed in
% \texttt{newarray.sty} as documented in the introduction. Removing
% the test for this case makes class 9 equivalent to class 10, and
% so this macro is redundant. It is "\let" to "\relax" to save
% space.
% \begin{macrocode}
\let\@classix\relax
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classviii}
% In \texttt{newarray.sty} explicitly allow class 2, as repeated
% \texttt{<} expressions are accepted by this package.
% \begin{macrocode}
\def\@classviii{\ifnum \@lastchclass >\z@\ifnum\@lastchclass=\tw@\else
\@preamerr 4\@chclass 6 \@classvi \fi\fi}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@classv}
% Class 5 is \texttt{@}-expressions (and is also called by class 1)
% This macro was incorrect in Version~1. Now we do not expand the
% "@"-expression, but instead explicitly replace an
% "\extracolsep" command by an assignment to "\tabskip" by a
% method similar to the "\newcolumntype" system described above.
% "\d@llarbegin" "\d@llarend" were introduced in V2.01 to match
% \texttt{array.sty} 2.0h.
% \begin{macrocode}
\def\@classv{\save@decl
\expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@
\@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}%
\prepnext@tok}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\NC@ecs}
% Rewrite the first occurrence of "\extracolsep{1in}" to
% "\tabskip1in\relax". As a side effect discard any tokens after a
% second "\extracolsep", there is no point in the user entering two of
% these commands anyway, so this is not really a restriction.
% \begin{macrocode}
\def\NC@ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}%
\ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi}
%</ncols>
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Support for the \texttt{delarray.sty}}
%
% The \texttt{delarray.sty} package extends the array syntax by
% supporting the notation of delimiters. To this end we extend the
% array parsing mechanism to include a hook which can be used by this
% (or another) package to do some additional parsing.
%
% \begin{macro}{\@tabarray}
% This macro tests for an optional bracket and then calls up
% "\@@array" or "\@@array[c]" (as default).
% \begin{macrocode}
%<*package>
\def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}}
% \end{macrocode}
% \end{macro}
% \begin{macro}{\@@array}
% This macro tests could then test an optional delimiter before the
% left brace of the main preamble argument. Here in the main package
% it simply is let to be "\@array".
% \begin{macrocode}
\let\@@array\@array
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\endarray}
% \begin{macro}{\@arrayright}
% We have to declare the hook we put into "\@array" above.
% A similar hook `"\@arrayright"' will be inserted into the
% "\endarray" to gain control. Both defaults to empty.
% \begin{macrocode}
\def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
\let\@arrayleft\@empty
\let\@arrayright\@empty
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Support for \texttt{\textbackslash firsthline} and
% \texttt{\textbackslash lasthline}}
%
% The Companion~\cite[p.137]{bk:GMS94} suggests two additional
% commands to control the allignments in case of tabulars with
% horizontal lines. They are now added to this package.
%
% \begin{macro}{\extratabsurround}
% The extra space around a table when "\firsthline" or "\lasthline"
% are used.
% \begin{macrocode}
\newlength{\extratabsurround}
\setlength{\extratabsurround}{2pt}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\backup@length}
% This register will be used internally by "\firsthline" and
% "\lasthline".
% \begin{macrocode}
\newlength{\backup@length}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\firsthline}
% \changes{v2.3h}{1996/05/25}{Complete reimplementation}
% This code can probably be improved but for the moment it should
% serve.
%
% We start by producing a single tabular row without any visible
% content that will produce the external reference point in case
% "[t]" is used.
% \begin{macrocode}
\newcommand{\firsthline}{%
\multicolumn1c{%
% \end{macrocode}
% Within this row we calculate "\backup@length" to be the height
% plus depth of a standard line. In addition we have to add the
% width of the "\hline", something that was forgotten in the
% original definition.
% \begin{macrocode}
\global\backup@length\ht\@arstrutbox
\global\advance\backup@length\dp\@arstrutbox
\global\advance\backup@length\arrayrulewidth
% \end{macrocode}
% Finally we do want to make the height of this first line be a bit
% larger than usual, for this we place the standard array strut
% into it but raised by "\extratabsurround"
% \begin{macrocode}
\raise\extratabsurround\copy\@arstrutbox
% \end{macrocode}
% Having done all this we end the line and back up by the value of
% "\backup@length" and then finally place our "\hline". This should
% place the line exactly at the right place but keep the reference
% point of the whole tabular at the baseline of the first row.
% \begin{macrocode}
}\\[-\backup@length]\hline
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\lasthline}
% \changes{v2.3h}{1996/05/25}{Complete reimplementation}
% For "\lasthline" the situation is even worse and I got it
% completely wrong initially.
%
% The problem in this case is that if the optional argument "[b]"
% is used we do want the reference point of the tabular be at the
% baseline of the last row but at the same time do want the the
% depth of this last line increased by "\extratabsurround" without
% changing the placement "\hline".
%
% We start by placing the rule followed by an invisible row.
% \begin{macrocode}
\newcommand{\lasthline}{\hline\multicolumn1c{%
% \end{macrocode}
% We now calculate "\backup@length" to be the height and depth of
% two lines plus the width of the rule.
% \begin{macrocode}
\global\backup@length2\ht\@arstrutbox
\global\advance\backup@length2\dp\@arstrutbox
\global\advance\backup@length\arrayrulewidth
% \end{macrocode}
% This will bring us back to the baseline of the second last row:
% \begin{macrocode}
}\\[-\backup@length]%
% \end{macrocode}
% Thus if we now add another invisible row the reference point of
% that row will be at the baseline of the last row (and will be the
% reference for the whole tabular). Since this row is invisible we
% can enlarge its depth by the desired amount.
% \begin{macrocode}
\multicolumn1c{%
\lower\extratabsurround\copy\@arstrutbox
}%
}
% \end{macrocode}
% \end{macro}
%
%
% \subsection{Getting the spacing around rules right}
%
% Beside a larger functionality \texttt{array.sty} has one
% important difference to the standard \texttt{tabular} and
% \texttt{array} environments: horizontal and vertical rules make a
% table larger or wider, e.g., \verb=\doublerulesep= really denotes
% the space between two rules and isn't measured from the middle of
% the rules.
%
% \begin{macro}{\@xhline}
% For vertical rules this is implemented by the definitions above,
% for horizontal rules we have to take out the backspace.
% \changes{v2.3d}{1995/11/19}{fix space between double rules pr/1945}
% \begin{macrocode}
\CheckCommand*\@xhline{\ifx\reserved@a\hline
\vskip\doublerulesep
\vskip-\arrayrulewidth
\fi
\ifnum0=`{\fi}}
\renewcommand*\@xhline{\ifx\reserved@a\hline
\vskip\doublerulesep
\fi
\ifnum0=`{\fi}}
%</package>
% \end{macrocode}
% \end{macro}
%
% \PrintIndex
% \PrintChanges
%
% \Finale
%
\endinput
|