summaryrefslogtreecommitdiff
path: root/info/apprendre-a-programmer-en-tex/source/apprendre-a-programmer-en-tex.tex
blob: 529d26e79809717e942ced80655fa6144dbce14d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
14652
14653
14654
14655
14656
14657
14658
14659
14660
14661
14662
14663
14664
14665
14666
14667
14668
14669
14670
14671
14672
14673
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
14702
14703
14704
14705
14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
15439
15440
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980
17981
17982
17983
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051
18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
18081
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
18101
18102
18103
18104
18105
18106
18107
18108
18109
18110
18111
18112
18113
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138
18139
18140
18141
18142
18143
18144
18145
18146
18147
18148
18149
18150
18151
18152
18153
18154
18155
18156
18157
18158
18159
18160
18161
18162
18163
18164
18165
18166
18167
18168
18169
18170
18171
18172
18173
18174
18175
18176
18177
18178
18179
18180
18181
18182
18183
18184
18185
18186
18187
18188
18189
18190
18191
18192
18193
18194
18195
18196
18197
18198
18199
18200
18201
18202
18203
18204
18205
18206
18207
18208
18209
18210
18211
18212
18213
18214
18215
18216
18217
18218
18219
18220
18221
18222
18223
18224
18225
18226
18227
18228
18229
18230
18231
18232
18233
18234
18235
18236
18237
18238
18239
18240
18241
18242
18243
18244
18245
18246
18247
18248
18249
18250
18251
18252
18253
18254
18255
18256
18257
18258
18259
18260
18261
18262
18263
18264
18265
18266
18267
18268
18269
18270
18271
18272
18273
18274
18275
18276
18277
18278
18279
18280
18281
18282
18283
18284
18285
18286
18287
18288
18289
18290
18291
18292
18293
18294
18295
18296
18297
18298
18299
18300
18301
18302
18303
18304
18305
18306
18307
18308
18309
18310
18311
18312
18313
18314
18315
18316
18317
18318
18319
18320
18321
18322
18323
18324
18325
18326
18327
18328
18329
18330
18331
18332
18333
18334
18335
18336
18337
18338
18339
18340
18341
18342
18343
18344
18345
18346
18347
18348
18349
18350
18351
18352
18353
18354
18355
18356
18357
18358
18359
18360
18361
18362
18363
18364
18365
18366
18367
18368
18369
18370
18371
18372
18373
18374
18375
18376
18377
18378
18379
18380
18381
18382
18383
18384
18385
18386
18387
18388
18389
18390
18391
18392
18393
18394
18395
18396
18397
18398
18399
18400
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412
18413
18414
18415
18416
18417
18418
18419
18420
18421
18422
18423
18424
18425
18426
18427
18428
18429
18430
18431
18432
18433
18434
18435
18436
18437
18438
18439
18440
18441
18442
18443
18444
18445
18446
18447
18448
18449
18450
18451
18452
18453
18454
18455
18456
18457
18458
18459
18460
18461
18462
18463
18464
18465
18466
18467
18468
18469
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
18485
18486
18487
18488
18489
18490
18491
18492
18493
18494
18495
18496
18497
18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
18523
18524
18525
18526
18527
18528
18529
18530
18531
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574
18575
18576
18577
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593
18594
18595
18596
18597
18598
18599
18600
18601
18602
18603
18604
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615
18616
18617
18618
18619
18620
18621
18622
18623
18624
18625
18626
18627
18628
18629
18630
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640
18641
18642
18643
18644
18645
18646
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667
18668
18669
18670
18671
18672
18673
18674
18675
18676
18677
18678
18679
18680
18681
18682
18683
18684
18685
18686
18687
18688
18689
18690
18691
18692
18693
18694
18695
18696
18697
18698
18699
18700
18701
18702
18703
18704
18705
18706
18707
18708
18709
18710
18711
18712
18713
18714
18715
18716
18717
18718
18719
18720
18721
18722
18723
18724
18725
18726
18727
18728
18729
18730
18731
18732
18733
18734
18735
18736
18737
18738
18739
18740
18741
18742
18743
18744
18745
18746
18747
18748
18749
18750
18751
18752
18753
18754
18755
18756
18757
18758
18759
18760
18761
18762
18763
18764
18765
18766
18767
18768
18769
18770
18771
18772
18773
18774
18775
18776
18777
18778
18779
18780
18781
18782
18783
18784
18785
18786
18787
18788
18789
18790
18791
18792
18793
18794
18795
18796
18797
18798
18799
18800
18801
18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816
18817
18818
18819
18820
18821
18822
18823
18824
18825
18826
18827
18828
18829
18830
18831
18832
18833
18834
18835
18836
18837
18838
18839
18840
18841
18842
18843
18844
18845
18846
18847
18848
18849
18850
18851
18852
18853
18854
18855
18856
18857
18858
18859
18860
18861
18862
18863
18864
18865
18866
18867
18868
18869
18870
18871
18872
18873
18874
18875
18876
18877
18878
18879
18880
18881
18882
18883
18884
18885
18886
18887
18888
18889
18890
18891
18892
18893
18894
18895
18896
18897
18898
18899
18900
18901
18902
18903
18904
18905
18906
18907
18908
18909
18910
18911
18912
18913
18914
18915
18916
18917
18918
18919
18920
18921
18922
18923
18924
18925
18926
18927
18928
18929
18930
18931
18932
18933
18934
18935
18936
18937
18938
18939
18940
18941
18942
18943
18944
18945
18946
18947
18948
18949
18950
18951
18952
18953
18954
18955
18956
18957
18958
18959
18960
18961
18962
18963
18964
18965
18966
18967
18968
18969
18970
18971
18972
18973
18974
18975
18976
18977
18978
18979
18980
18981
18982
18983
18984
18985
18986
18987
18988
18989
18990
18991
18992
18993
18994
18995
18996
18997
18998
18999
19000
19001
19002
19003
19004
19005
19006
19007
19008
19009
19010
19011
19012
19013
19014
19015
19016
19017
19018
19019
19020
19021
19022
19023
19024
19025
19026
19027
19028
19029
19030
19031
19032
19033
19034
19035
19036
19037
19038
19039
19040
19041
19042
19043
19044
19045
19046
19047
19048
19049
19050
19051
19052
19053
19054
19055
19056
19057
19058
19059
19060
19061
19062
19063
19064
19065
19066
19067
19068
19069
19070
19071
19072
19073
19074
19075
19076
19077
19078
19079
19080
19081
19082
19083
19084
19085
19086
19087
19088
19089
19090
19091
19092
19093
19094
19095
19096
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116
19117
19118
19119
19120
19121
19122
19123
19124
19125
19126
19127
19128
19129
19130
19131
19132
19133
19134
19135
19136
19137
19138
19139
19140
19141
19142
19143
19144
19145
19146
19147
19148
19149
19150
19151
19152
19153
19154
19155
19156
19157
19158
19159
19160
19161
19162
19163
19164
19165
19166
19167
19168
19169
19170
19171
19172
19173
19174
19175
19176
19177
19178
19179
19180
19181
19182
19183
19184
19185
19186
19187
19188
19189
19190
19191
19192
19193
19194
19195
19196
19197
19198
19199
19200
19201
19202
19203
19204
19205
19206
19207
19208
19209
19210
19211
19212
19213
19214
19215
19216
19217
19218
19219
19220
19221
19222
19223
19224
19225
19226
19227
19228
19229
19230
19231
19232
19233
19234
19235
19236
19237
19238
19239
19240
19241
19242
19243
19244
19245
19246
19247
19248
19249
19250
19251
19252
19253
19254
19255
19256
19257
19258
19259
19260
19261
19262
19263
19264
19265
19266
19267
19268
19269
19270
19271
19272
19273
19274
19275
19276
19277
19278
19279
19280
19281
19282
19283
19284
19285
19286
19287
19288
19289
19290
19291
19292
19293
19294
19295
19296
19297
19298
19299
19300
19301
19302
19303
19304
19305
19306
19307
19308
19309
19310
19311
19312
19313
19314
19315
19316
19317
19318
19319
19320
19321
19322
19323
19324
19325
19326
19327
19328
19329
19330
19331
19332
19333
19334
19335
19336
19337
19338
19339
19340
19341
19342
19343
19344
19345
19346
19347
19348
19349
19350
19351
19352
19353
19354
19355
19356
19357
19358
% !TeX spellcheck = fr_FR
% !TeX encoding = ISO-8859-1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                          %%
%%                           Code source du livre                           %%
%%                     « Apprendre à programmer en TeX »                    %%
%%                                                                          %%
%%                                   ___                                    %%
%%                                                                          %%
%%                        © 2014 Christian Tellechea                        %%
%%                                                                          %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ___________________________________________________________________________
%|                                                                           |
%|                    Encodage ISO 8859-1 (latin1)                           |
%|               À compiler avec pdflatex en mode pdf                        |
%|___________________________________________________________________________|

\RequirePackage{etex}
\documentclass[fontsize=10pt,chapterprefix=true]{scrbook}

\newwrite\wtest
\newread\rtest

\usepackage[latin1]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[
	paperwidth=16.8275cm,paperheight=26.035cm,
	headsep=.5cm,headheight=1cm,
	footskip=1cm,
	twoside,
	lmargin=2.2cm,
	rmargin=2.8775cm,
	tmargin=2.5cm,
	bmargin=3cm
	]{geometry}% largeur texte = 16.8275-(2.8775+2.2)=11,75 cm

\usepackage[table]{xcolor}
\definecolor{shadecolor}{rgb}{0.86078,0.86078,0.86078}% couleur de fond des environnements "regle"

\usepackage{
	metalogo,
	tikz,
	xspace,
	dashbox,
	fancybox,
	enumitem,
	longtable,
	framed,
	graphicx,
	amsmath,
	needspace
}
\xspaceaddexceptions{\footnote\verb)}
\usetikzlibrary{decorations}
\usepgflibrary{decorations.pathmorphing}
% ____________________________________________________________________________
%|                                                                            |
%|                     Macros définies dans le livre                          |
%|                                                                            |
\input progtexmacro.tex%                                                      |
%|                                                                            |
%|____________________________________________________________________________|

\makeatletter

% ____________________________________________________________________________
%|                                                                            |
%|                         environnements "liste"                             |
%|                                                                            |
\newlist{algo}{enumerate}{4}
\setlist[algo]{leftmargin=*,labelindent=\main@parindent,itemsep=0pt,topsep=4pt,parsep=1.5pt,before=\small}
\setlist[algo,1]{label=\arabic*),topsep=2pt,ref=\arabic*}
\setlist[algo,2]{label=\alph*),topsep=1pt,ref=\thealgoi.\alph*}
\setlist[algo,3]{label=\roman*),topsep=1pt,ref=\thealgoii.\roman*}
\setlist[algo,4]{label=--,topsep=1pt,ref=\thealgoiii.\roman*}

\setlist[enumerate]{leftmargin=*,labelindent=\main@parindent,itemsep=0.3pt,topsep=1pt,parsep=1pt,partopsep=0pt}

\setlist[itemize]{leftmargin=*,labelindent=\main@parindent,itemsep=0.3pt,topsep=1pt,parsep=1pt,partopsep=0pt,label=--}
%|                                                                            |
%|                        fin environnements "liste"                          |
%|____________________________________________________________________________|

\usepackage[bottom]{footmisc}

\usepackage{scrlayer-scrpage}
\pagestyle{scrheadings}
\clearscrheadfoot
\cehead{\leftmark}
\cohead{\rightmark}
\lehead{\llap{\normalfont\bfseries\thepage\kern4mm }}
\rohead{\rlap{\normalfont\bfseries\kern4mm \thepage}}
\automark[chapter]{part}
\renewcommand\partmarkformat{\ifnum\arabic{part}>0 \normalfont\biolinum\small\itshape\thepart. \fi}
\renewcommand\chaptermarkformat{\normalfont\biolinum\small\itshape\thechapter. }

% ____________________________________________________________________________
%|                                                                            |
%|                              Polices                                       |
%|                                                                            |
\usepackage{amssymb,textcomp,eurosym,libertine}
\usepackage[libertine]{newtxmath}
\renewcommand*\ttdefault{LinuxLibertineMonoTC-TLF}
\DeclareRobustCommand*\libLegacyGlyph[1]{{\ifcsname fxl@#1\endcsname\@nameuse{fxl@#1}\else\errmessage{glyphe fxl@#1 non défini}\fi}}
\DeclareRobustCommand*\bioLegacyKeyGlyph[1]{{\ifcsname fxk@#1\endcsname\@nameuse{fxk@#1}\else\errmessage{glyphe fxk@#1 non défini}\fi}}
\newcommand*\DeclareTextGlyphX[5]{\@namedef{#1@#4}{{\fontfamily{#3}\fontencoding{#2}\selectfont\char#5\relax}}}
\DeclareTextGlyphX{fxk}{U}{fxke1}{T_a_b}{117}
\DeclareTextGlyphX{fxk}{U}{fxke1}{E_n_t_e_r}{118}
\DeclareTextGlyphX{fxk}{U}{fxke1}{A_l_t_G_r}{114}
\DeclareTextGlyphX{fxk}{U}{fxk00}{A}{65}
\DeclareTextGlyphX{fxk}{U}{fxk00}{R}{82}
\DeclareTextGlyphX{fxk}{U}{fxk00}{seven}{55}
\DeclareTextGlyphX{fxl}{U}{fxle0}{Q_u}{72}
\DeclareTextGlyphX{fxl}{U}{fxle0}{uniE007}{7}
\newcommand*\Qu{\libLegacyGlyph{Q_u}}% <- pour éviter de créer une fonte virtuelle
%|                                                                            |
%|                            fin Polices                                     |
%|____________________________________________________________________________|

\usepackage{lettrine}
\usepackage[
	protrusion=true,
	expansion=true,
	stretch=10,
	shrink=5,
	tracking=true,
	final,
	babel=true]{microtype}
\usepackage[autolanguage]{numprint}
% ____________________________________________________________________________
%|                                                                            |
%|                               Mises en forme                               |
%|                                                                            |
\let\lcodedelim=\langle
\let\rcodedelim=\rangle
\DeclareRobustCommand\codeelement[1]{% met en forme <"#1">
	\ensuremath\lcodedelim\textit{#1}\ensuremath\rcodedelim
}
\let\Verb=\verb
\def\def@visible@space{%
	\setbox0\hbox{x}%
	\def\visible@space{%
		\leavevmode
		\kern.1ex
		\vrule width0.4pt height0.5ex depth0.2ex\relax
		\vrule width\dimexpr\wd0-.8pt-.2ex\relax height\dimexpr.4pt-.2ex\relax depth0.2ex\relax
		\vrule width0.4pt height0.5ex depth0.2ex\relax
		\kern.1ex
		}%
}
\def\verb{%
	\relax\ifmmode\hbox\else\leavevmode\null\fi
	\bgroup
		\ttfamily
		\hyphenchar\font=-1
		\for\ii=0 to 255 \do {\catcode\ii=12 }%
		\catcode`\~13
		\obeylines \verbatim@font \@noligs \hyphenchar\font=-1
		\ifstarred{\def@visible@space\letactive\ =\visible@space\catcode`\~12 \verb@i}{\letactive\ =\space\catcode`\~12\frenchspacing\verb@i}%
}
\def\verb@i#1{%
		\def\verb@ii##1#1{\verb@iii{##1}}%
		\verb@ii
}
\catcode`\>=13
\catcode`\<=13
\def\verb@element#1>{\codeelement{#1}}
\def\verb@iii#1{%
		\ifin{#1}<%
			{\def\temp@l{#1}\let\temp@r\temp@l%
			\leftofsc\temp@l<%
			\rightofsc\temp@r<%
			\exparg\ifin\temp@r>%
				{\addtomacro\temp@l\verb@element
				\eaddtomacro\temp@l\temp@r
				\exparg\verb@iii\temp@l
				}
				{#1\egroup}%
			}
			{#1\egroup}%
}
\catcode`\>=12
\catcode`\<=12

\newcount\exercice@cnt
\exercice@cnt\z@

\newmacro\defactive[\def]1{%
	\catcode`#2=13
	\begingroup
	\lccode`~=`#2
	\lowercase{\endgroup#1~}}

\newcounter{exemple}[part]

\newenvironment{centrage}[1][3.5pt]
	{\ifvmode\removelastskip\fi
	\list{}{\leftmargin\z@\parsep\z@\topsep#1\relax}%
	\centering\item\relax
	}%
	\endlist

\newcommand\boxtoken[2][\string]{%
	\begingroup
		\fboxsep\boxtokensep
		\fbox{\ttfamily\vphantom{Ailpj}#1#2}%
	\endgroup
	\xspace
}
\newcommand*\boxtokensep{0.3pt}

\newcommand*\TeXhead{$\ggg$}
\newcommand*\Hex[1]{\hbox{$\mathsf{#1}_{\scriptscriptstyle\mathsf h}$}}
\newcommand*\bin[1]{\textit{#1}}
\newcommand*\latin{\texttt{latin1}\xspace}
\newcommand*\utf{\texttt{UTF8}\xspace}

\newenvironment{exercice}
	{%
	\needspace{3.5\baselineskip}%
	\setlist[enumerate]{leftmargin=*,labelindent=\main@parindent,itemsep=0pt,topsep=1pt,parsep=1pt}%
	\parindent\z@
	\parskip2pt plus.5pt minus.5pt
	\global\advance\exercice@cnt\@ne
	\bigbreak
	\small\noindent
	\rule{1.25ex}{1.25ex}\kern1ex \textsc{\textbf{Exercice \number\exercice@cnt}}\par\nobreak
	}
	{\ifvmode
		\vskip\dimexpr2pt-\baselineskip-\lastskip\relax
	\fi
	\hfill\rule{1.25ex}{1.25ex}\bigbreak}

\FrameSep=5pt
\newcount\cnt@regle
\newwrite\reglewrite
\immediate\openout\reglewrite=regles.txt
\immediate\write\reglewrite{%
	\string\newcount\string\recapreglecnt\string^^J%
	\string\recapreglecnt=0\relax
	\string^^J%
}
\newenvironment{regle}[1][Règle]{%
	\global\advance\cnt@regle\@ne
	\begingroup
		\gdef\titre@regle{#1}%
		\for\xxx=0 to 255\do{\catcode\xxx=12 }%
		\captureregle
	}
	{}
\begingroup\edef\temp{\endgroup\def\noexpand\captureregle##1\string\end\detokenize{{regle}}}
\temp{%
	\endgroup
	\newlinechar`\^^M
	\immediate\write\reglewrite{%
		\string\begin{recapregle}#1\string\end{recapregle}\string^^J%
		}%
	\begingroup
		\parskip2pt plus.25pt minus.25pt
		\setlist[itemize]{leftmargin=2em,itemsep=0pt,topsep=1pt,parsep=1pt,label=--}%
		\newlinechar`\^^M
		\everyeof{\noexpand}%
		\makeatletter
		\scantokens{%
			\parindent\z@
			\shaded
				{\bfseries\scshape\number\cnt@regle{} - \titre@regle}%
				\par\nobreak
				#1%
			\endshaded
			}%
	\endgroup
	\end{regle}%
}%

\newenvironment{recapregle}%
	{\bigbreak
	\global\advance\recapreglecnt 1
	\let\label=\gobone
	\small
	\parindent=0pt
	\parskip1pt plus.25pt minus.25pt
	\setlist[itemize]{leftmargin=3.5em,itemsep=0pt,topsep=1pt,parsep=1pt,label=--}%
	\textbf{\number\recapreglecnt\relax.\kern0.33333em}%
	}
	{}

\newcommand\solution[1][]{%
	\needspace{3\baselineskip}%
	\smallbreak\noindent%\incorrectiontrue
	{\fboxsep\z@\fboxrule.5pt \fbox{\vrule height1ex width\z@\kern1ex }}%
	\hspace{1ex}\textsc{\textbf{Solution\ifempty{#1}{}{ #1}}}\par\nobreak
}

% Centre la ligne de code en mode verbatim
% Utilisation : \centrecode*-code-
% "*" facultative. Si présent, les espaces sont rendus visibles
% code est un code se trouvant entre 2 caractères identiques.
% Si * : ne tient pas compte des "<" et ">"
\def\centrecode{\def\space@def{\defactive\ {\space}}\centrecode@}

\def\centrecodespc{\def\space@def{\catcode`\ =12 }\centrecode@}

\def\centrecode@{%
	\par\unskip
	\begingroup
		\parskip\z@
		\catcode`\¤=13
		\begingroup
			\lccode`\~`\¤\relax
			\lowercase{\endgroup\long\def~##1~}{%
				\begingroup
					\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 \catcode`\\=0 \catcode`\$=3
					\catcode`\f=11
					\endlinechar=-1
					\scantokens{##1}%
				\endgroup
				}% échappement de ¤...¤
		\parindent\z@\let\do\@makeother\dospecials
		\defactive\,{\kern\z@\string,}%
		\defactive\-{\kern\z@\string-}%
		\defactive\^^M{\normalfont\ttfamily\color{black}\cr{}}%
		\defactive\^^I{{ }{ }{ }{ }}% tab = 4 espaces
		\defactive\%{\itshape\color{gray}\char`\% }%
		\space@def
		\@ifstar
			{\let\centrecode@iii=\centrecode@star
			\defactive\<{\string<{}}%
			\defactive\>{\string>{}}%
			\centrecode@i
			}
			{\let\centrecode@iii=\centrecode@nostar
			\centrecode@i
			}%
}

\def\centrecode@i#1{%
	\def\centrecode@ii##1#1{\centrecode@iii{##1}}%
	\centrecode@ii}

\def\centrecode@nostar#1{% #1 est le code
	\ifin{#1}<%
		{\def\temp@l{#1}\let\temp@r\temp@l%
		\leftofsc\temp@l<%
		\rightofsc\temp@r<%
		\exparg\ifin\temp@r>%
			{\addtomacro\temp@l\centrecode@element
			\eaddtomacro\temp@l\temp@r
			\exparg\centrecode@nostar\temp@l
			}%
			{\centrecode@star{#1}}%
		}%
		{\centrecode@star{#1}}%
}

\def\centrecode@star#1{%
	\centrage{}\leavevmode\vbox{\small\ttfamily\halign{##\hfill\cr#1\cr\crcr}}\endcentrage
	\endgroup\ignorespaces
}
\def\centrecode@element#1>{\codeelement{#1}}

% Utilisation : \indentcode*[dim]-code-
% "*" facultative. Si présente, les lignes sont numérotées
% [dim] est l'indentation du code par rapport au début des lignes. 3em par défaut
% code se trouve entre 2 caractères identiques et peut comporter des retours à la ligne
\newif\ifindencodenum
\indencodenumfalse
\newcount\indentcode@cnt
\newcommand*\indentcode{%
	\begingroup
	\indentcode@cnt=\z@
	\let\do\@makeother\dospecials
	\catcode`\?12 \catcode`\!12
	\@ifstar
		\indentcode@i
		{\defactive\ { }%
		 \indentcode@i
		 }%
}

\newcommand*\indentcodeactivechars[1]{%
	\defactive\^^M{\par\hspace{#1}}%
	\defactive\^^I{{ }{ }{ }{ }}% tab = 4 espaces
	\catcode`\¤=13
	\begingroup
		\lccode`\~`\¤\relax
		\lowercase{\endgroup\long\def~##1~}{%
			\begingroup
				\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 \catcode`\\=0 \catcode`\$=3
				\catcode`\f=11
				\endlinechar=-1
				\scantokens{##1}%
			\endgroup
			}% échappement ¤...¤
}

\newcommand*\indentcode@i[1][\main@parindent]{%
	\parindent\z@
	\parskip\z@
	\ttfamily\small
	\ifindencodenum
		\everypar{\advance\indentcode@cnt\@ne\llap{\footnotesize$\scriptstyle\number\indentcode@cnt$\space}}%
	\fi
	\par\smallskip\nobreak\noindent\hspace{#1}%
	\indentcodeactivechars{#1}%
	\indentcode@ii
}

\def\indentcode@ii#1{%
	\expandafter\defactive\csname#1\endcsname{\smallbreak\endgroup\ignorespaces}%
}

\newcommand*\boxcs[2]{%
	{\boxput*(0,1){\fboxsep\z@\colorbox{white}{\leavevmode\kern1pt\footnotesize\string#1\kern1pt}}{\fboxsep=7pt\fbox{#2}}}%
}

\newcount\node@cnt
\newcommand*\jumptok[2][\expandatfer]{%
	\begin{tikzpicture}[baseline,inner sep=1pt,outer sep=0pt]
		\def\exp@tok{\ttfamily\string#1}%
		\def\end@tok{#2}%
		\small
		\makeatletter
		\@makeother\{\@makeother\}\@makeother\#%
		\node@cnt\z@
		\def\previous@node{n@0}%
		\node[anchor=base,fill=black!25](n@0){\strut\exp@tok};
		\jump@tok
}

\def\jump@tok#1#2#3{%
	\advance\node@cnt\@ne
	\node[anchor=base west,at=(\previous@node.base east)](jumped@tok){\ttfamily\strut\string#1};
	\if\end@tok\noexpand#3%
		\node[draw,anchor=base west,at=(jumped@tok.base east)](n@\number\node@cnt){\ttfamily\strut\string#2};
		\draw[-stealth,shorten >=2pt](\previous@node) to[out=30,in=150] (n@\number\node@cnt);
		\end{tikzpicture}%
		\expandafter\@gobbletwo
	\else
		\node[fill=black!25,anchor=base west,at=(jumped@tok.base east)](n@\number\node@cnt){\strut\exp@tok};
		\draw[-stealth,shorten >=2pt](\previous@node) to[out=30,in=150] (n@\number\node@cnt);
		\edef\previous@node{n@\number\node@cnt}%
		\expandafter\jump@tok
	\fi{#2}{#3}%
}

\def\showcodes#1{%
	\hbox{%
		\texttt{\string#1}%
		(\number`#1\relax\thinspace\string;\thinspace\number\catcode`#1\relax)%
	}%
	\xspace
}

\newbox\testbox
\newif\ifshow@dimen
\newcommand*\dimenbox{\@ifstar{\show@dimenfalse\dimenbox@i}{\show@dimentrue\dimenbox@i}}
\newcommand*\dimenbox@i[2][100pt]{%
	\setbox\testbox\hbox{\fontsize{#1}{#1}\selectfont #2}%
	\begin{tikzpicture}[inner sep=0pt,outer sep=0pt,minimum size=0pt,baseline,line width=0.2pt]
		\node[anchor=base west,draw,inner sep=-0.1pt]at(0,0)(boite){\fontsize{#1}{#1}\selectfont#2};
		\ifshow@dimen
			\draw[gray,overlay]([xshift=-.8cm]boite.base west)--([xshift=.5cm]boite.base east)node[pos=0,anchor=south west,black,outer sep=1pt]{\tiny ligne de}node[pos=0,anchor=north west,black,outer sep=1pt]{\tiny base};
			\ifdim\dp\testbox>5pt
				\draw[stealth-stealth,overlay]([xshift=.4cm]boite.base east)--([xshift=.4cm]boite.south east)node[pos=0.5,anchor=west,outer sep=3pt]{\ttfamily\scriptsize\string\dp=\the\dp\testbox};
			\else
				\path([xshift=.4cm]boite.base east)--([xshift=.4cm]boite.south east)node[pos=0.5,anchor=west,outer sep=3pt]{\ttfamily\scriptsize\string\dp=\the\dp\testbox};
			\fi
			\draw[stealth-stealth,overlay]([xshift=.4cm]boite.base east)--([xshift=.4cm]boite.north east)node[pos=0.5,anchor=west,outer sep=3pt]{\ttfamily\scriptsize\string\ht=\the\ht\testbox};
			\draw[stealth-stealth]([yshift=.2cm]boite.north west)--([yshift=.2cm]boite.north east)node[pos=0.5,anchor=south,outer sep=3pt]{\ttfamily\scriptsize\string\wd=\the\wd\testbox};
		\fi
		\draw[fill,black,overlay](boite.base west)circle(1pt);%
	\end{tikzpicture}%
}
%|                                                                            |
%|                             fin mises en forme                             |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                             Commande \showcode                             |
%|                                                                            |
\newbox\strut@box
\newif\if@codeline
\newif\if@errcode
\newif\if@comment
\newcount\code@line
\newcount\code@count
\newwrite\codewrite
\immediate\openout\codewrite=progtexcode.txt
\exactwrite\codewrite|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                          %%
%%                        Codes donnés dans le livre                        %%
%%                    « Apprendre à programmer en TeX »                     %%
%%                                                                          %%
%%                           Encodage ISO 8859-1                            %%
%%                                   _____                                  %%
%%                                                                          %%
%%                        © 2014 Christian Tellechea                        %%
%%                                                                          %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Les codes et les macros commentés donnés dans ce fichier sont diffusés sous
% la licence LaTeX project public license (LPPL) 1.2
%
% https://www.latex-project.org/lppl/lppl-1-2/
% https://www.latex-project.org/lppl/lppl-1-2.txt
%
% Attention : ce fichier n'a pas vocation à être compilé
\endinput|
\let\shownumline\@codelinetrue
\let\hidenumline\@codelinefalse
\shownumline
\newcommand\encadre[2]{%0 = encadre 1=début 2=milieu 3=fin
	\leavevmode
	\frboxrule=0.4pt \frboxsep=3pt
	\setbox\z@\hbox{\kern\frboxsep#2\kern\frboxsep}%
	\hbox{%
		\vrule width\frboxrule
		\vtop{%
			\vbox{%
				\ifnum#1<2
					\hbox to\wd\z@{%
						\bfseries\footnotesize
						\hrulefill
						\kern.5em
						\setbox\z@\hbox{Code \ifnum\arabic{part}>\z@\no\thepart-\fi\number\code@count}%
						\ht\z@\z@ \dp\z@\z@
						\lower.5ex\box\z@
						\kern.5em
						\hrulefill
						}%
				\fi% réglure supérieure
				\kern\frboxsep% espace haut
				\box\z@
				}%
			\kern\dimexpr\frboxsep+.5ex\relax% espace bas
			\ifnum#1=0 \hrule height\frboxrule\fi% réglure inférieure
			\ifnum#1=3 \hrule height\frboxrule\fi
		}% réglure inférieure
		\vrule width\frboxrule
	}%
}

\newcommand*\showcode{\@errcodefalse\showcode@i}

\newcommand*\errcode{\@errcodetrue\showcode@i}

\def\showcodeactivechars{}

\newcommand*\showcode@i[1][]{%
	\needspace{3.5\baselineskip}%
	\global\advance\code@count1
	\edef\saved@state{%
		\tolerance=\the\tolerance\relax
		\emergencystretch=\the\emergencystretch\relax
		\hfuzz=\the\hfuzz
		\vfuzz=\the\vfuzz
		}%
	\medbreak
	\begingroup
		\parindent\z@
		\parskip\z@
		\code@line\z@
		\def\aux@code{#1}%
		\begingroup
			\for\xx=0 to 255 \do{\catcode\xx=12 }%
			\showcode@ii
}

\def\assign@execcode#1\@nil{\xdef\execcode@code{#1}}

\newcommand*\showcode@ii[1]{%
			\def\showcode@iii##1#1{% ##1 est le code où tous les catcodes sont de 12
					\catcode`\¤=13
					\begingroup
						\lccode`\~=`\¤
					\lowercase{\endgroup\def~####1~}{}%
					\newlinechar`\^^M
					\everyeof{\@nil}%
					\expandafter\assign@execcode\scantokens{##1}%
					\immediate\write\codewrite{^^J^^J%
						****************** Code \number\code@count \space******************^^J%
						\execcode@code
						****************** Fin code ******************}%
		\endgroup
		\def\showcode@code{##1}%
		\afterassignment\showcode@iv
		\if@errcode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
			{\def\err@message}
			{\let\err@message\@empty}%
		}%
		\showcode@iii
}
\definecolor{codegray}{gray}{0.375}% gris pour les commentaires dans \showcode
\newcommand*\showcode@iv{%
		\def\FrameCommand{\encadre0}%
		\def\FirstFrameCommand{\encadre1}%
		\def\MidFrameCommand{\encadre2}%
		\def\LastFrameCommand{\encadre3}%
		\topsep1.5ex %espace avant l'encadrement
		\par\nointerlineskip\nobreak
		\edef\restorevbadness{\vbadness=\the\vbadness\relax}%
		\vbadness=10000
		\MakeFramed{\advance\hsize-\width\FrameRestore}%
			\begingroup
				\footnotesize
				\everyeof{\noexpand}%
				\begingroup
					\if@codeline\everypar{\num@code}\fi
					\gray@line
					\let\do\@makeother\dospecials
					\catcode`\¤=13
					\begingroup
						\lccode`\~`\¤\relax
						\lowercase{\endgroup\long\def~##1~}{%
							\begingroup
								\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 \catcode`\\=0 \catcode`\$=3
								\catcode`\f=11 \catcode`\ =10
								\def\idxmp{%
									\relax
									\edef\saved@at@catcode{\the\catcode`\@}%
									\catcode`\@11
									\@ifstar
										{\let\print@idx\@gobble\index@macro@perso}
										{\let\print@idx\@gobble\index@macro@perso}%
								}%
								\def\idx{%
									\relax\makeatletter
									\@ifstar
										{\let\print@idx\@gobble\idx@}%
										{\let\print@idx\@gobble\idx@}%
								}%
								\scantokens{##1}%
							\endgroup
							}% échappement ¤...¤
					\defactive\%{\unexpanded{\@commenttrue\itshape\color{codegray}\%}}% commentaire
					\defactive\^^M{\unexpanded{\if@comment\normalfont\ttfamily\color{black}\fi\@commentfalse}\par\leavevmode}% retour charriot
					\normalfont\renewcommand*\ttdefault{LinuxLibertineMonoTCC-TLF}\ttfamily
					\setbox\z@\hbox{0}\edef\tt@spc{\hskip\the\wd\z@\relax}%
					\catcode`\ =13
					\begingroup
						\lccode`\~`\ \relax
						\lowercase{\endgroup\let~\tt@spc}%
					\defactive\^^I{\tt@spc\tt@spc}% tabulation
					\defactive\,{\string,{}}% ligatures
					\defactive\<{\string<{}}%
					\defactive\>{\string>{}}%
					\defactive\-{\string-{}}%
					\defactive\`{\string`{}}%
					\defactive f{\string f{}}%
					\showcodeactivechars% éventuelles modif de caractères actifs
					\endlinechar-1
					\scantokens\expandafter{\showcode@code}%
				\endgroup
				\removelastskip\par\nointerlineskip\nobreak
				\ligneH{\kern4pt }%
				\par%\nobreak
				\if@errcode\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
					{\ttfamily\err@message}
					{\catcode`\¤=13
					\begingroup
						\lccode`\~`\¤\relax
						\lowercase{\endgroup\def~##1~}{}%
					\xdef\showcodehisze{\the\hsize}%
					\newlinechar`\^^M
					\saved@state
					\microtypesetup{expansion=false,protrusion=false,tracking=false}%
					\aux@code
					\edef\nstiflevel@a{\number\currentiflevel}%
					\scantokens\expandafter{\execcode@code}\relax
					\edef\nstiflevel@b{\number\currentiflevel}%
					\ifnum\nstiflevel@a=\nstiflevel@b\relax\else\errmessage{Erreur de if : \number\code@count}\fi
					}%
				\par\nointerlineskip\nobreak
			\endgroup
		\endMakeFramed
		\restorevbadness
	\endgroup
	\medbreak
}

\newcommand*\ligneH[2][4pt]{%
	\vbox{\offinterlineskip\hsize\linewidth
		\null
		#2%
		\hrule width\linewidth\kern#1\relax\null% 4pt = espace entre ligne et ce qu'il y a dessous
	}%
}

\newcommand*\gray@line{%
	\everypar\expandafter{%
		\the\everypar
		\edef\color@line{\noexpand\colorbox{gray!\ifodd\code@line 35\else 20\fi}}% ou "50\else 35" pour l'impression
		\setbox\strut@box\hbox{\vphantom{Àpj}}%
		\dp\strut@box\dimexpr\dp\strut@box+1.25pt\relax
		\ht\strut@box\dimexpr\ht\strut@box+1.25pt\relax
		\setbox\strut@box\hbox{%
			\fboxsep\z@
			\color@line{\box\strut@box\kern\dimexpr\linewidth-7.5pt\relax}%
		}%
		\wd\strut@box\z@
		\dp\strut@box\dimexpr\dp\strut@box-1.25pt\relax
		\ht\strut@box\dimexpr\ht\strut@box-1.25pt\relax
		\box\strut@box
	}%
}

\newcommand*\num@code{%
	\hb@xt@7.5pt{%
		\hss
		\global\advance\code@line\@ne
		\tiny\number\code@line
		\kern2.5pt}%
}

\newcommand*\defline[1]{\xdef#1{\number\code@line}}
%|                                                                            |
%|                               fin \showcode                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                   Mise en forme tdm, sectionnement                         |
%|                                                                            |
\usepackage{titletoc}

\newcommand*\partminitoc{%
	\edef\parksip@saved{\the\parskip}\parskip0pt
	\vspace{1.5cm}%
	\normalsize\normalfont
	\startcontents[part]
	\begingroup
		\noindent\bfseries\large
		Sommaire\hfill\null\par\vskip3pt
	\endgroup
	\hrule height1pt depth0pt
	\smallskip
	\renewcommand*\l@chapter[2]{%
		\ifnum\c@tocdepth>\m@ne
			\addpenalty{-\@highpenalty}%
			\vskip 2pt \@plus\p@
			\@tempdima1.5em
			\begingroup
			\parindent \z@ \rightskip \@pnumwidth
			\parfillskip-\@pnumwidth
			\leavevmode \normalfont
			\advance\leftskip\@tempdima
			\hskip-\leftskip
			{##1}\nobreak\dotfill\nobreak\hb@xt@\@pnumwidth{\hss ##2}\par
			\penalty\@highpenalty
			\endgroup
		\fi
	}
	\printcontents[part]{part-}{0}{\setcounter{tocdepth}{0}}%
	\vskip5pt
	\hrule height1pt depth0pt%\titlerule[1pt]
	\parskip\parksip@saved\relax
}

\def\defpartcomment{\def\part@comment}
\defpartcomment{}

\renewcommand*\partformat{%
	\normalfont\large\sffamily\bfseries\scshape
	\hfill\MakeUppercase{\partname}\hfill\null
	\vskip.5cm
	\setbox\z@\hbox{\normalfont\Huge\sffamily\bfseries
			\libLegacyGlyph{uniE007}%
			}%
		\hfill
		\ifnum\c@part>0
			{\normalfont\Huge\sffamily\bfseries
			\libLegacyGlyph{uniE007}%
			}%
		\else
			\vphantom{\box\z@}%
		\fi
		\hfill\null\endgraf
		\fontsize{20}{20}\selectfont\centering
}

\renewcommand*\partheadendvskip{%
	\partminitoc
	\vfill
	\unless\ifx\part@comment\@empty
		\noindent\hfill
		\begin{minipage}{0.65\linewidth}
			\biolinum
			\rightskip0pt \leftskip0pt \parindent\z@
			\hsize5cm
			\small\null\part@comment\par
		\end{minipage}%
		\global\let\part@comment\@empty
		\vskip2cm
	\fi
}
\addtokomafont{chapterprefix}{\raggedleft}
\addtokomafont{chapter}{\huge\bfseries\scshape\raggedleft}
\renewcommand*\chapterformat{%
	\hfill
	\hbox{\normalfont\bfseries\Large\color{gray}\chapappifchapterprefix{\nobreakspace}\fontsize{72}{80}\selectfont\lower .5ex\hbox{\thechapter}}
	\vskip1cm
}%
\renewcommand*\chapterheadendvskip{\vskip2cm }
\renewcommand*\chapterheadstartvskip{\vskip0.2\vsize}
%|                                                                            |
%|                 fin mise en forme tdm, sectionnement                       |
%|____________________________________________________________________________|

\usepackage[french]{babel}
\frenchbsetup{StandardLists=true,og=«,fg=»}
\selectlanguage{french}

% ____________________________________________________________________________
%|                                                                            |
%|                   Mise en forme notes bas de page                          |
%|                                                                            |
\parindentFFN\parindent
%|                                                                            |
%|                 fin mise en forme notes bas de page                        |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Index                                     |
%|                                                                            |
\usepackage{imakeidx}% index multiples
\makeindex[
	title=Index général,
	columns=2,
	intoc=true,
	program=texindy,
	options=-M xindstyle.xdy -L french
]
\indexsetup{toclevel=part}
\makeindex[
	name=macros,
	title=Index des macros définies dans ce livre,
	columns=2,
	intoc=true,
	program=texindy,
	options=-M xindstyle.xdy -L french
]

\immediate\openout\wtest=xindstyle.xdy

\exactwrite\wtest|(require "page-ranges.xdy")
(define-location-class "arabic-page-numbers"
                       ("arabic-numbers") :min-range-length 1)
(markup-locclass-list :open "\quad " :sep ", ")
(define-attributes (("etc")))
(markup-locref :open "\hyperpage{" :close "}, \ldots" :attr "etc")
(define-crossref-class "voir" :unverified)
(markup-crossref-list :class "voir" :open "\textit{voir} " :sep ", ")
(define-crossref-class "voiraussi" :unverified)
(markup-crossref-list :class "voiraussi" :open "\textit{voir aussi} " :sep ", ")
(define-location-class-order (
   "roman-page-numbers"
   "arabic-page-numbers"
   "alpha-page-numbers"
   "Roman-page-numbers"
   "Alpha-page-numbers"
   "see"
   "voir"
   "voiraussi"))
(markup-locref :open "\hyperpage{" :close "}")
(markup-locref :open "\hyperpage{" :close "}" :attr "hyperpage")|

\immediate\closeout\wtest
\usepackage{xstring}

\let\list@macro@perso\empty% liste des macros perso déjà rencontrées

\catcode`\W=3
\def\noindexlist{W}% liste des entrées à ignorer lors de la mise en index

\long\def\forbidindex#1{% n'indexe plus l'entrée "#1" jusqu'à ordre contraire
	\expandafter\global\expandafter\long\expandafter\def\expandafter\noindexlist\expandafter{\noindexlist#1W}% ajoute l'entrée à la liste
}

\long\def\allowindex#1{% autorise l'index de l'entrée "#1"
	\long\def\allowindex@i##1W#1W##2\allowindex@i{\global\long\def\noindexlist{##1W##2}}%
	\expandafter\ifin\expandafter{\noindexlist}{W#1W}%
		{\allowindex@i#1\allowindex@i}%
		{}%
}
\catcode`\W=11

\newcommand\idxmp{%
	\relax
	\edef\saved@at@catcode{\the\catcode`\@}%
	\catcode`\@11
	\@ifstar{\let\print@idx\@gobble\index@macro@perso}{\let\print@idx\@firstofone\index@macro@perso}%
}

\let\oldparagraph=§
\letactive §\idxmp

\def\index@macro@perso#1{%
	\edef\temp@{\noexpand\substtocs\noexpand\temp@{\string#1}{\string @}}\temp@{\char64 }%
	\edef\temp@{\expandafter\gobone\temp@}%
	\exptwoargs\ifin\list@macro@perso{\string#1}%
		{\print@idx{\leavevmode\hbox{\texttt{\string#1}}}% macro déjà rencontrée
		}
		{\xdef\list@macro@perso{\list@macro@perso\string#1}% première apparition
		\print@idx{\leavevmode\hbox{\texttt{\string#1}${}^{{}\scriptscriptstyle\star{}}$}}%
		}%
	\index@macro@perso@i
}

\newcommand*\index@macro@perso@i[1][]{%
	\index[macros]{\temp@ @\texttt{\char92 \temp@}#1}%
	\restoreexpandmode
	\catcode`\@=\saved@at@catcode\relax
	\xspace
}

\edef\print@macro@list{\string\LaTeX\string\eTeX}

\let\list@indexentry\empty% liste des entrées d'index

\def\left@@of#1#2{% dans la sc #1, garde ce qui est à gauche de #2
	\def\left@@of@i##1#2##2\@nil{\def#1{##1}}%
	\expandafter\left@@of@i#1#2\@nil
}

\newcommand\add@toindexentry[1]{% ajoute #1 à la liste d'entrées ou pas
	\edef\temp@{\detokenize\expandafter{\string#1}}%
 	\expandafter\left@@of\expandafter\temp@\string|% ne prend que ce qui est avant |
 	\expandafter\left@@of\expandafter\temp@\string!% ne prend que ce qui est avant !
	\exptwoargs\ifin{\list@indexentry}{\temp@,}
		\relax
		{\xdef\list@indexentry{\list@indexentry\temp@, }}%
}

\newcommand\idx{\relax\makeatletter\@ifstar{\let\print@idx\@gobble\idx@}{\let\print@idx\@firstofone\idx@}}

\catcode`\W=3
\newcommand\idx@[2][]{%
	\saveexpandmode\expandarg
	\let\savedindex\index
	\expandafter\ifin\expandafter{\noindexlist}{W#2W}{\let\index\gobone}{}%
	\expandafter\if@controlsequence\expandafter{\firstto@nil#2\@nil}% si #2 est une séquence de contrôle¤§*\firstto@nil¤
		{\let\repeat\relax
		\add@toindexentry{#2}%
		\edef\temp@{\expandafter\gobone\string#2}%
		\long\edef\temp@a{\meaning#2}%
		\long\edef\temp@b{\string#2}%
		\let\xx@space\xspace
		\ifx\temp@a\temp@b% si #2 est une primitive
			\expandafter\ifx\firstto@nil#2\@nil\ % #2 = \<espace> ?
				\index{\char\number`#2 @\quitvmode\hbox to0pt {\hss${}^*$}\texttt{\char92 \char32 }#1}%
				\print@idx{\texttt{\char92 \char32 }}%
			\else
				\index{\temp@ @\quitvmode\hbox to0pt {\hss${}^*$}\texttt{\char92 \temp@}#1}%
				\print@idx{\texttt{\char92 \temp@}}%
			\fi
		\else
			\expandafter\expandafter\expandafter\ifempty
			\expandafter\expandafter\expandafter{\expandafter\gobtwo\string#2}% si caractère de contrôle
				{\index{\char\number\expandafter`\temp@ "@@\texttt{\char92 \char\number\expandafter`\temp@}#1}%
				\print@idx{\texttt{\char92 \temp@}}%
				\let\xx@space\relax
				}%
				{\StrSubstitute\temp@{\string @}{\char64 }[\temp@]% remplace les @
				\IfSubStr\print@macro@list{\string#2}%
					{\index{\temp@ @\protect#2#1}% si macro dans liste
					\print@idx{#2}%
					}%
					{\index{\temp@ @\texttt{\char92 \temp@}#1}%
					\print@idx{\texttt{\char92 \temp@}}%
					}%
				}%
		\fi
		\restoreexpandmode
		\let\repeat\fi
		\makeatother
		\let\index\savedindex
		\xx@space
		}%
		{\restoreexpandmode
		\index{#2\ifx\@empty#1\@empty\else #1\fi}%
		\print@idx{#2}%
		\let\index\savedindex
		\makeatother
		}%
}
\catcode`\W=11

\newcommand\if@controlsequence[1]{%
	\begingroup
		\escapechar`\\
		\edef\first@char{\expandafter\firstto@nil\string#1\@nil}%¤
		\edef\escape@char{\expandafter\firstto@nil\string\relax\@nil}%
		\ifx\first@char\escape@char
			\endgroup\expandafter\firstoftwo
		\else
			\endgroup\expandafter\secondoftwo
		\fi
}

\def\visiblespace{ }

% met en index un seul caractère de la forme <char> ou \<char>
\newcommand\cidx{\relax\@ifstar{\let\print@idx\@gobble\cidx@}{\let\print@idx\@firstofone\cidx@}}
\newcommand\cidx@[2][]{%
	\if@controlsequence{#2}% si c'est une macro
		{\ifnum`#2=`\ % espace ?
			\index{\char\number`#2 @\textvisiblespace#1}%
			\add@toindexentry{ }%
			\print@idx{\texttt{\char92 \char32 }}%
		\else
			\index{\char\number`#2 @\texttt{\char\number`#2}#1}%
			\expandafter\add@toindexentry\expandafter{\expandafter\char\number`#2}%
			\print@idx{\texttt{\char\number`#2}}%
		\fi
		\xspace
		}
		{\StrSubstitute{#2}"{""}[\temp@@]%
		\index{\temp@@ @\texttt{\string#2}#1}%
		\add@toindexentry{#2}%
		}%
}

\def\idxdetokenize{\begingroup\catcode`\^12 \idxdetokenize@i}
\def\idxdetokenize@i#1{\endgroup\detokenize{#1}}
% met en index le second argument "détokénizé"
\newcommand\verbidx{\begingroup\catcode`\^12 \@ifstar{\let\print@idx\@gobble\verbidx@}{\let\print@idx\@firstofone\verbidx@}}
\newcommand\verbidx@[2][]{%
	\index{#2@{\ttfamily\protect\idxdetokenize{#2}}#1}%
	\print@idx{{\ttfamily\idxdetokenize{#2}}}%
	\add@toindexentry{#2}%
	\endgroup
}

% met en index les primitives de test "\if...", "\else", "\fi"
\newcommand\tidx{\relax\@ifstar{\let\print@idx\@gobble\tidx@i}{\let\print@idx\@firstofone\tidx@i}}
\newcommand\tidx@i[2][]{% #2 est le nom de la primitive SANS le caractère d'échappement
	\index{#2@\quitvmode \hbox to0pt {\hss ${}^*$}\texttt{\char92 #2}#1}%
	\add@toindexentry{#2}%
	\print@idx{\texttt{\char92 #2}}%
}
%|                                fin index                                   |
%|____________________________________________________________________________|

\let\grandsaut\bigbreak
\newdimen\main@parindent

\usepackage[
	hyperindex    = false,
	plainpages    = true,
	pdfauthor     = {Christian~TELLECHEA},
	pdftitle      = {Apprendre~à~programmer~en~TeX},
	pdfsubject    = {Présentation~des~concepts~de~base~et~apprentissage~de~la~programmation~en~langage~TeX},
	pdfcreator    = {LaTeX}
	]{hyperref}

\@addtoreset{chapter}{part}

\makeatother
\begin{document}
\defactive«{\char19 \penalty10000 \FBguillspace\relax\ignorespaces}%
\defactive»{\unskip\penalty10000 \FBguillspace\relax\char20 }%
\pagestyle{scrheadings}%
\parindent=15pt
\parskip0pt plus.3pt
\hyphenation{cons-truire cons-truite cons-truites cons-truction cons-tructions cons-truit exem-ple exem-ples con-state con-stater con-sta-ta-tion}%
\widowpenalty=600
\clubpenalty=600
\interfootnotelinepenalty=10000
\csname main@parindent\endcsname=\parindent
\let\oldit=\it \let\it=\itshape
\let\oldbf=\bf \let\bf=\bfseries
\let\oldrm=\rm \let\rm=\normalfont
\let\oldtt\tt \let\tt=\ttfamily
\let\oldsc=\sc \let\sc=\scshape% éviter les avertissements d'obsolescence
\raggedbottom
\newcommand\drawbox[1]{%
	\leavevmode
	\begingroup
	\tikz\draw[fill,black,overlay](0.35pt,0pt)circle(1pt);%
	\fboxsep0pt \fboxrule0.2pt
	\kern-\fboxrule\fbox{#1}\kern-\fboxrule
	\endgroup}
\def\messageavert{message d'avertissement}
\startcontents[tableofcontents]
\startcontents[part]

% ____________________________________________________________________________
%|                                                                            |
%|                               Début du livre                               |
%|                                                                            |
\frontmatter
\pagestyle{empty}
\null\pagebreak
\null\pagebreak
%%%%%%%%%%%% Page de titre %%%%%%%%%
\title{\huge Apprendre à programmer en \TeX{}}
\author{\small Christian \textsc{Tellechea}}
\date{\small Septembre 2014}
\def\largeurtext{85}%
\uppertitleback{%
	\leavevmode\null\hfill
	\vtop{%
		\hsize=.\largeurtext\textwidth
		\footnotesize
		\parskip=3pt
		Ce livre est « autoédité », c'est-à-dire que la conception, les relectures et les corrections ont été faites par l'auteur. Malgré le soin qui y a été apporté, des fautes et des erreurs peuvent encore exister.

		Toute erreur, omission ou toute proposition d'amélioration peut être signalée.\medbreak

		Email de l'auteur :\par
		\href{mailto:unbonpetit@netc.fr}{\texttt{unbonpetit@netc.fr}}\bigbreak
		
		Dépôt du code source, fichiers pdf et fichiers annexes :\par
		\href{https://framagit.org/unbonpetit/apprendre-a-programmer-en-tex/}{\texttt{https://framagit.org/unbonpetit/apprendre-a-programmer-en-tex/}}\bigbreak
		
		Remontées de bugs, améliorations :\par
		\href{https://framagit.org/unbonpetit/apprendre-a-programmer-en-tex/issues}{\texttt{https://framagit.org/unbonpetit/apprendre-a-programmer-en-tex/issues}}
		\vskip1.5cm
		
		Les codes et algorithmes figurant dans ce livre sont donnés sans \emph{aucune garantie} en vue de leur utilisation dans le cadre d'une activité professionnelle ou commerciale.
	}%
	\hfill\null
}

\lowertitleback{%
	\leavevmode\null\hfill
	\vtop{%
		\hsize=.\largeurtext\textwidth
		\small
		ISBN 978-2-9548602-0-6\medskip

		\textcopyright{} Christian \textsc{Tellechea}, 2014\medskip
		
		\scriptsize
		Révision \no2a, 26/04/2019\medskip
		
		Photo couverture \textcopyright{} Christian~\textsc{Tellechea}\par
		Photo 4\ieme{} couverture \textcopyright{} Willi~\textsc{Heidelbach}.
		\medbreak
		Le code source au format texte, ce fichier au format pdf qui en résulte après compilation, les fichiers au format texte générés par la compilation ainsi que les fichiers texte et pdf nécessaires à la compilation sont placés sous la licence «LaTeX Project Public License Version 1.2» qui est consultable à l'adresse suivante \href{https://www.latex-project.org/lppl/lppl-1-2.txt}{\texttt{https://www.latex-project.org/lppl/lppl-1-2.txt}}
	}%
	\hfill\null
}

\dedication{%
	\vskip3cm
	\hfill
	\vtop{%
		\hsize=.47\linewidth
		\parindent=0pt
		\raggedleft\itshape\small
		Un langage de programmation est censé être une façon conventionnelle de donner des ordres à un ordinateur. Il n'est pas censé être obscur, bizarre et plein de pièges subtils (ça, ce sont les attributs de la magie).\medskip

		\normalfont Dave \textsc{Small}%
	}%
}

\extratitle{%
	\null\vskip0pt plus1fill
	\hfill
	\hbox{\Large\biolinum Apprendre à programmer en \TeX{}}%
	\hfill\null
	\vskip0pt plus3fill
	\null
}

\maketitle

\pagestyle{plain}\setcounter{page}{1}
\chapter*{Préface}

Il est déjà bien difficile de maitriser \TeX{} comme langage de composition\ldots{} C'est un vrai défi que d'en connaitre suffisamment les méandres pour l'utiliser comme langage de programmation\footnote{\TeX{} a été créé pour la composition et si son créateur l'a été doté de ce qu'il faut pour programmer, ce n'est pas par choix, mais parce qu'il a été obligé de le faire (un peu à contrec\oe ur) !}. Et, c'est une mission quasi impossible que d'écrire un livre là-dessus, j'en parle en connaissance de cause ! D'ailleurs, bien peu de choses existent sur le sujet. Non pas que les gens sachant programmer en \TeX{} soient rares, ils sont simplement assez sages et modestes pour ne pas s'embarquer dans une telle galère. Inconscient, insouciant et trop sûr de moi, j'ai commencé à écrire sans mesurer les difficultés auxquelles j'allais me heurter. Je ne sais toujours pas quelle folie m'a poussé à poursuivre cette aventure jusqu'au bout. Même si un peu de vanité a certainement joué un rôle, ma motivation n'a jamais été de montrer que « moi, je peux »; il ne s'agit pas d'un péché d'orgueil. Le but poursuivi, moteur plus fort que les difficultés rencontrées au cours de cette aventure, a été d'aider ceux qui, comme moi lorsque j'étais débutant en programmation \TeX, restent devant un code écrit en \TeX{} comme devant un texte en chinois ancien : plongés dans un abime d'incompréhension.

\Qu iconque connait un peu \TeX{} a dû sourire en lisant la citation de Dave~\textsc{Small}. Et a dû se dire qu'avec \TeX{} bien plus qu'avec d'autres langages, on allait forcément parler de magie noire à un moment ou à un autre ! Car il est vrai que \TeX{} est un langage difficile, tortueux et réputé comme tel. On ne compte plus ceux qui font tout pour ne pas s'y frotter, ceux qui le haïssent ou le rejettent ni ceux qui, bien que l'utilisant, se traitent de fous tant des choses apparemment simples sont en réalité compliquées. \TeX{} est bourré de défauts, collectionne les lacunes, a une syntaxe à coucher dehors tant elle est irrégulière, mais malgré tout cela, on se prend à l'apprécier un peu comme on pourrait apprécier les défauts d'un ami de longue date, taciturne et bourru. Tout comme cet ami pourrait envier certains côtés aux « nouveaux communicants » dont nous sommes désormais entourés, \TeX{} ne soutient pas non plus la comparaison avec les langages modernes. Mais, l'utiliser pour programmer procure un plaisir certain ainsi qu'une sensation de liberté et de créativité qu'on ne retrouve que dans une moindre mesure avec les langages de programmation récents.

J'invite donc mon lecteur, armé de patience et de persévérance, à entreprendre ce périple qui s'annonce ardu, mais riche de nouveautés et d'originalité. La meilleure chose que je lui souhaite est d'arriver à ses fins et par là même, atteindre aussi le but dans lequel ce livre a été écrit : acquérir une autonomie dans la programmation en \TeX. Ce livre, qui n'est qu'une simple introduction à la programmation en \TeX, sera peut-être un départ pour de nouveaux horizons qui, après beaucoup de pratique et sans utilisation de magie noire --~c'est garanti !~--, le mèneront, qui sait, à devenir un \TeX gourou\ldots

% ____________________________________________________________________________
%|                                                                            |
%|                             Table des matières                             |
%|                                                                            |
\cleardoublepage
%%%%%%%%% Table des matières %%%%%%%
\begingroup
	\huge\centering
	{\null\vspace{2cm}\bfseries\scshape Table des matières}\par
	{\Huge\bfseries\libLegacyGlyph{uniE007}}\bigbreak
	\normalfont\normalsize
	\makeatletter
	\renewcommand*\l@chapter{\@dottedtocline{0}{0em}{1.5em}}
	\printcontents[tableofcontents]{sommaire-}{-1}{\setcounter{tocdepth}{2}}
	\clearpage
\endgroup
%|                                                                            |
%|                           Fin table des matières                           |
%|____________________________________________________________________________|

\pagestyle{scrheadings}
\mainmatter

\chapter*{Conventions adoptées dans ce livre}
\addcontentsline{toc}{part}{Conventions adoptées dans ce livre}

\subsubsection{Les codes}
Par souci de pédagogie, les codes sont très nombreux. Ils sont présentés de telle sorte que le code précède l'affichage qu'il génère. En voici un, le premier d'une longue série :

\showcode/Voici le code en \TeX{} du premier exemple.% ceci est un commentaire

On peut observer l'affichage qu'il produit juste au-dessous !/%

Sauf pour des cas très exceptionnels qui seront signalés, il ne peut y avoir de «triche» sur l'affichage : il est très exactement le résultat du code qui se trouve au-dessus. En effet, les codes sont tapés \emph{une seule fois} dans le code source de ce livre. Une macro est chargée de stocker ce code pour ensuite fonctionner en deux temps. Elle l'affiche tel quel dans la partie haute du cadre puis laisse \TeX{} le compiler et afficher le résultat dans la partie basse.

Les codes donnés produisent donc les résultats affichés, mais le lecteur doit garder en tête les limitations suivantes :

\begin{itemize}
	\item malgré les relectures effectuées sur chaque code, ils ne sont pas garantis sans «bogue». Certains bogues étant particulièrement difficiles à débusquer, il serait même très étonnant que certains n'en contiennent pas !
	\item dans la plupart des cas, les codes donnés ne sont qu'une façon de faire \emph{parmi beaucoup d'autres}, le nombre d'alternatives tendant à augmenter avec la complexité de la tâche à exécuter. Ces codes sont donc à considérer comme \emph{une} solution et non pas comme \emph{la} solution. Ils n'ont donc pas valeur de méthode absolue qui serait meilleure que toute autre;
	\item ils ne fonctionnent que pour un certain domaine de validité (souvent implicite) des arguments de leurs macros, car élargir ce domaine suppose des complications qu'il est long et fastidieux de programmer. On peut donc toujours trouver des cas plus ou moins spéciaux où les arguments contiennent des choses qui feront «planter» une macro.
	
	Par exemple, si une macro attend un nombre entier et qu'on lui donne la lettre «a» comme argument, \TeX{} va protester avec l'erreur «\texttt{missing number}». Par ailleurs, des caractères spéciaux comme «\verb|#|» seul, «\verb|%|», etc. vont inévitablement provoquer des plantages s'ils sont écrits dans les arguments des macros. Sauf dans les cas où ces caractères spéciaux sont gérés, les macros attendent des arguments «gentils», c'est-à-dire constitués de caractères ayant un code de catégorie de 10, 11 ou 12 (voir page~\pageref{catcode.table}); 
	\item les codes proposés ne sont pas toujours \emph{optimisés}, c'est-à-dire que leur vitesse d'exécution tout comme la consommation de mémoire qu'ils requièrent peuvent être améliorées. Ils répondent avant tout à deux contraintes, celle d'illustrer la notion qui est en train d'être abordée tout en utilisant des notions précédemment vues et celle de ne pas inutilement compliquer le code.
\end{itemize}

J'invite le lecteur à \emph{lire} les codes proposés, même s'ils sont rébarbatifs. Lire n'est pas survoler ! Lorsque les codes deviennent assez complexes, il faut vraiment faire un effort mental important et se plonger dedans afin de comprendre comment ils fonctionnent. Les commentaires insérés dans le code, toujours très nombreux, fournissent une aide pour cela, mais la gymnastique mentale consistant à analyser l'enchainement des instructions et comprendre comment évoluent les arguments des macros reste nécessaire.

\subsubsection{Les exercices}
Les exercices, également en grand nombre et de difficulté variable, sont souvent proposés au lecteur au fur et à mesure que de nouvelles notions sont présentées. Ils sont précédés d'un «{\footnotesize\rule{1.25ex}{1.25ex}}» et immédiatement suivis de leur solution, choix discutable, mais qui s'est imposé. Voici à ce propos le premier exercice :

\begin{exercice}
\Qu el argument principal peut-on trouver pour justifier que les exercices soient immédiatement suivis de la solution ?

\solution
Se décider a été difficile, mais qu'y a-t-il de plus lassant que de passer son temps à tourner les pages pour aller débusquer à la fin du livre la solution d'un exercice que, bien souvent, on n'arrive pas à résoudre ? Ou qu'on ne \emph{souhaite} pas résoudre ! Sur ce point, l'expérience un peu pénible du \TeX book (que vous avez bien sûr déjà lu et relu !) a été décisive et m'a poussé à présenter les choses différemment. Il me semble que le lecteur, supposé adulte et ayant un certain contrôle de lui-même, peut se retenir de lire la solution s'il souhaite vraiment chercher un exercice.
\end{exercice}

\subsubsection{Éléments de code}
Les chevrons ''$\lcodedelim$`` et ''$\rcodedelim$`` ont vocation à symboliser des éléments dont la nature est exprimée par les mots se trouvant entre ces chevrons. Ainsi, \verb|<nombre>| est censé représenter\ldots{} un nombre ! Selon la même notation, on aurait \verb|\<macro>|, \verb|<texte>|, \verb|<code>| (pour du code source en \TeX{}), \verb|<car>| (pour un caractère), \verb|<dimension>|, etc.
\grandsaut

Un espace dans le code source peut être mis en exergue, soit parce qu'il revêt une importance particulière, soit parce sa présence est importante et qu'il doit être clairement être visible. Dans ces cas, il est noté «\verb*| |».

Un caractère isolé peut parfois être encadré pour qu'il soit aisément identifiable, comme l'apostrophe inverse «{\def\boxtokensep{0.5pt}\boxtoken `}».

Lorsqu'il peut y avoir ambigüité sur les caractères composant le nom d'une commande ou bien parce que nom contient des caractères inhabituels, le nom est encadré comme dans «\hbox{\verb|\|\fboxsep1pt \fbox{\ttfamily a\string_1\string\b7}}» (car une commande peut tout à fait porter un nom pareil !).

\subsubsection{Les macros propres à ce livre}
Tout au long de ce livre, des macros sont définies dans des codes ou dans des exercices. Lorsqu'elles sont définies, elles sont suivies du signe «$\star$» mis en exposant comme dans \verb|\gobone|${}^{{}\star{}}$. Elles disposent d'un index à part (voir page~\pageref{index.macros}) où l'on peut aisément trouver le numéro de page où chacune d'entre elles a été mentionnée. Lorsqu'elles sont mentionnées dans l'index général, elles sont également suivies de «$\star$».

\subsubsection{Anglicismes}
Si à mon grand regret l'anglais --~que dis-je, le \emph{globish} !~-- tend à s'imposer comme langue universelle de communication entre personnes ne parlant pas la même langue, il s'est depuis longtemps imposé comme langue en programmation. Il est en effet indéniable que les mots-clés de presque tous les langages de programmation sont en anglais. Ceci a conduit à employer des mots anglais pour désigner des notions couramment utilisées dans le monde de la programmation. J'ai donc fait le choix facile, pour quelques mots, d'utiliser la version anglaise.

\begin{centrage}
\footnotesize
\begin{tabular}{>\itshape llp{0.55\linewidth}}\\\hline
	\normalfont Anglais&Français&Signification\\\hline
	\idx{token}&entité lexicale&séquence d'un ou plusieurs caractères du code source reconnue et assimilée par \TeX{} comme un élément indivisible selon les règles de l'analyseur lexical qui seront exposées dans ce livre.\\
	tokenization&segmentation&s'applique à une portion du code source : transformation des caractères du code source en tokens.\\
	catcode&code de catégorie&s'applique à un token : entier sur 4 bits (0 à 15) affecté à un token lorsqu'il est lu par \TeX.\\
	\idx{package}&extension&mot générique signifiant « fichier externe permettant d'accroitre les possibilités de \TeX{} ». Bien souvent, il s'agit de code source mettant à disposition des macros permettant de réaliser des tâches complexes.\\\hline
\end{tabular}
\end{centrage}

\subsubsection{Les règles}
Au fur et à mesure de la progression, des règles précisant la façon de fonctionner de \TeX{} sont inscrites dans des cadres sur fond gris. Toutes ces règles sont reprises en annexe à partir de la page~\pageref{recapregle}.

\subsubsection{Orthographe rectifiée}
Lorsque j'ai vu la moue un peu dubitative des rares personnes ayant lu quelques passages de ce livre, j'y ai vu l'embarras de ceux qui, me découvrant incapable d'écrire quelques phrases sans faute, se préparaient à me faire des remarques sur mon orthographe fautive.

J'ai fait le choix, comme l'indique le logo ci-dessous, d'utiliser l'orthographe rectifiée de la réforme de 1990.

\begin{centrage}
	\includegraphics[scale=0.3333]{vignette.png}
\end{centrage}

Par conséquent, la phrase « \emph{nous sommes surs que la boite va disparaitre}» est orthographiquement correcte. Il ne manque aucun accent circonflexe, même s'il en fallait trois avant la réforme. \Qu e l'orthographe rectifiée soit encore actuellement considérée comme fautive par la majorité des personnes me laisse un peu interrogatif. Malgré plus de deux décennies pendant lesquelles elle a été \emph{recommandée}, le fait qu'elle soit si peu reconnue et pratiquement absente de l'enseignement ne s'explique pour moi que par le rapport excessivement rigide et crispé que nous entretenons avec notre orthographe.

Bien évidemment, ce livre étant 100\% \emph{fait-maison}, je ne peux le garantir exempt de coquilles, d'accords fautifs ou de lourdeurs. Je présente d'ores et déjà mes excuses à mes lecteurs pour les désagréments que cela leur procurera.
%|                                                                            |
%|                             Fin début du livre                             |
%|____________________________________________________________________________|


% ____________________________________________________________________________
%|                                                                            |
%|                                Introduction                                |
%|                                                                            |
\addpart{Introduction}
\chapter{\TeX{}, la brute et le truand}
\section{Les spécificités de \TeX}
Le programme \texttt{tex} est conçu pour lire du code source (le plus souvent enregistré dans un fichier de type «texte») puis «compiler» ce code afin de produire un document affichable disponible dans un fichier de type \texttt{dvi}\idx*{fichier!dvi}. Un tel programme, transformant du code source en document affichable, est appelé «\emph{\idx{moteur}}\footnote{On dit aussi parfois «\emph{compilateur}».}». Le langage \TeX{}\footnote{Il ne faut pas confondre le \emph{moteur} \texttt{tex}\idx*{moteur!tex} qui est exécuté par un ordinateur et le \emph{langage} \TeX{}. Ce langage met à disposition des commandes pour produire un document, mais aussi des commandes pour \emph{programmer}. C'est d'ailleurs le but de ce livre que d'expliquer comment utiliser ces dernières.} met à disposition des commandes qui sont appelées \emph{\idx{primitive}s}, tout en permettant de \emph{définir} d'autres commandes, appelées «\emph{macros-instructions}» ou «\emph{macros}». Compte tenu de leur puissance, ces dernières sont d'un emploi extrêmement courant et sont donc pratiquement indispensables. Elles peuvent être définies par l'utilisateur à l'intérieur même du code source, mais peuvent aussi être contenues dans un fichier externe appelé extension ou «\emph{\idx{package}}» qui sera lu à un endroit du code source choisi par l'utilisateur. Dernière possibilité, des macros peuvent également être précompilées pour être incorporées dans un exécutable appelé «\emph{\idx{format}}» qui embarque le langage \TeX{} dans sa totalité ainsi que des macros précompilées. Ainsi, lorsqu'on lance l'exécutable d'un format, ces macros sont déjà définies avant que le début du code source ne soit lu.

Les formats les plus connus et les plus utilisés\footnote{On ne peut pas vraiment parler de fréquence d'utilisation des formats les plus « célèbres », car n'importe qui peut se construire son propre \idx{format} à la carte. La man\oe uvre à suivre ne sera pas décrite dans ce livre.} sont :% TODO : vérifier qu'un saut de page n'a pas lieu ici

\begin{itemize}
	\item plain-\TeX\idx*{format!plain-\TeX}, dont l'exécutable est «\texttt{tex}», où les macros «\texttt{plain}» ont été définies par l'auteur de \TeX{} lui-même. Il est donc à noter que lorsqu'on lance le programme \texttt{tex}, en plus du langage \TeX{} \emph{nu}, on dispose aussi de toutes les macros de \texttt{plain};
	\item \LaTeX\idx*{format!\LaTeX}, dont l'exécutable est «\texttt{latex}», qui est un recueil de macros, écrites et mises en cohérence à l'origine par \idx*{Lamport Leslie}Leslie~\textsc{Lamport} et dont le but est de fournir des macros de haut niveau pour la composition;
	\item Con\TeX t\idx*{format!Con\TeX t} qui est un peu à part des deux précédents en ceci qu'il n'est pas basé sur le moteur \texttt{tex}\idx*{moteur!tex} mais sur un autre moteur permettant l'accès au langage \emph{\idx{lua}};
	\item pour mémoire, en voici de très peu connus ou très anciens, mais qui ont le mérite d'exister : \texttt{phyzzx}, \texttt{psizzl}, \texttt{Lollipop} et \texttt{TeXsis}. Le plus original de la bande est sans doute \texttt{StarTeX} qui a une approche très éloignée de tous les autres puisque la syntaxe des commandes se rapproche au plus près de celle de l'\texttt{HTML} !
\end{itemize}

Le langage \TeX{} et ses formats sont réputés produire des documents de grande qualité typographique, mais \TeX{} est vieux. Son concepteur, \idx*{Knuth Donald}Donald~\textsc{Knuth}, l'a publié en 1982\footnote{Une version plus récente «\TeX90» a été publiée en 1990 où de nouvelles primitives ont été incorporées et où la lecture du code est désormais sur 8 bits au lieu de 7 pour «\TeX82».}, époque où aucun des langages « modernes » n'existait encore. Pour le programmer, il a utilisé un vieux langage s'il en est, le Pascal. \TeX{} est assurément très stable, probablement exempt de bug, mais indéniablement \emph{très vieux} à l'échelle du temps informatique. On peut d'ailleurs s'étonner qu'entre 1982 et le début des années 2000, une aussi longue période se soit écoulée sans évolution majeure. Certes, entre temps, un nouveau moteur «\eTeX\idx*{moteur!etex}» a vu le jour où de nouvelles primitives ont ajouté des fonctionnalités bien pratiques qui n'existaient pas dans le langage \TeX{} initial. Plus récemment encore, le moteur «pdf\TeX\idx*{moteur!pdftex}» a été écrit par Hàn Th\'{ê} \textsc{Thành}\idx*{Hàn Thê Thành} et de nouvelles fonctionnalités ont été ajoutées, tout en conservant celles de \eTeX\idx*{moteur!etex}. Mais ce qui fait la particularité de pdf\TeX\idx*{moteur!pdftex} est qu'il est capable de produire \emph{directement} un fichier \verb|pdf|\idx*{fichier!pdf} à partir du code source sans passer par le fichier \texttt{dvi} jusqu'alors incontournable.
\grandsaut

Au-delà de son âge, mais peut-être en sont-ce des conséquences, \TeX{} a deux particularités qui le rendent peu attractif, voire carrément repoussant pour beaucoup de personnes qui s'y essaient.

Tout d'abord, la façon intrinsèque que \TeX{} a de fonctionner, certes très originale, ne ressemble pas à celle qui est devenue la norme dans la plupart des langages de programmation. Ceci est \emph{extrêmement} déroutant et conduit bien souvent à une incompréhension puis un rejet de ce langage, même pour des programmeurs avertis. Car avec \TeX{}, les méthodes de programmation changent et donc, c'est aussi la façon de penser un algorithme qui change !

Pour résumer à l'extrême, \TeX{} est un langage \emph{de macros}, c'est-à-dire que les appels aux macros provoquent le remplacement de ces macros (et de leurs arguments) par un nouveau code. Ce code --~ou « \idx{texte de remplacement} »~-- est celui qui a été donné à la macro lors de sa définition. De plus, et c'est une originalité supplémentaire en \TeX, lorsqu'on définit une macro, non seulement on définit son texte de remplacement, mais on définit \emph{aussi} la syntaxe avec laquelle elle devra être appelée. Enfin, et c'est là un des points les plus difficiles, \TeX{} ne procède à \emph{aucune évaluation}, ni du \idx{texte de remplacement} lors de la définition d'une macro, ni des arguments qui lui sont donnés lorsqu'elle est appelée.

Voici un exemple qui peut illustrer cette absence d'évaluation. Pour comprendre le problème, tenons-nous à l'écart de la syntaxe de \TeX{} où les commandes doivent commencer par «\verb|\|» et les arguments doivent être entre accolades. Adoptons plutôt une syntaxe «générique» où les commandes sont écrites normalement et où les arguments se trouvent entre parenthèses. Imaginons qu'une macro «\verb|left|» ait été créée et qu'elle admette deux arguments. Le premier de type chaine de caractères alphanumériques, noté «\verb|A|» et le second de type entier, noté «\verb|i|» : le résultat de cette macro est constitué par ce qui se trouve à gauche du caractère \no\verb|i| de la chaine \verb|A|. Par exemple, le code :

\centrecode-left(bonjour)(4)-

\noindent donnerait les caractères se trouvant à gauche de 4\ieme{} lettre, c'est-à-dire «\verb|bon|».

De la même façon, admettons qu'il existe aussi une macro «\verb|right|» qui elle, renvoie ce qui se trouve à droite du caractère \no\verb|i| dans la chaine \verb|A|. Et donc :

\centrecode-right(bonjour)(4)-

\noindent donnerait les caractères «\verb|our|».

Voici maintenant un raisonnement extrêmement répandu en programmation et c'est d'ailleurs le c\oe ur du problème. N'importe quel programmeur pense --~avec raison~-- que pour isoler ce qui se trouve entre les caractères \no2 et \no5 dans la chaine «\verb|bonjour|» (c'est-à-dire les caractères «\verb|nj|»), il suffit d'écrire :

\centrecode|right(left(bonjour)(5))(2)|

Ce raisonnement suppose que les arguments de \verb|right|--~ici en particulier le premier~-- ont
 été évalués \emph{avant} que la macro n'entre en jeu. Ce premier argument qui est «\verb|left(bonjour)(5)|» serait donc remplacé par son résultat «\verb|bonj|» et finalement, après cette évaluation, tout se passe comme si on avait l'appel :

\centrecode|right(bonj)(2)|

\noindent Or, cette évaluation n'a pas lieu avec \TeX{} ! Essayons de nouveau d'appréhender ce code, mais adoptons un esprit \TeX ien :

\centrecode|right(left(bonjour)(5))(2)|

\noindent \TeX{} exécute le code de gauche à droite donc, lorsqu'il exécute la macro \verb|right|, il va lui transmettre ses deux arguments qui sont «\verb|left(bonjour)(5)|» et «\verb|2|». Et donc, les caractères renvoyés seront tout ce qui se trouve à droite de la 2\ieme{} lettre du premier argument, c'est-à-dire «\verb|ft(bonjour)(5)|».

Le simple fait que le premier argument ne soit pas évalué conduit non seulement à un résultat radicalement différent, mais surtout implique que si l'on souhaite un comportement «normal», c'est au programmeur d'intégrer à la macro un mécanisme qui se charge d'évaluer cet argument avant que le code utile de la macro ne traite le résultat. Pour ceux qui viennent d'autres langages, cette charge de travail supplémentaire est souvent ressentie comme une corvée, sans compter que le code s'en trouve alourdi et donc moins lisible.

Une bonne partie des problèmes que rencontrent les personnes non habituées à \TeX{} vient de la confusion qu'ils font entre :
\begin{itemize}
	\item l'affichage qui résulte d'un code;
	\item ce code lorsqu'il est dans l'argument d'une macro.
\end{itemize}

L'explication de cette confusion tient au fait que la plupart des langages ont un mécanisme --~appelé «\idx{préprocesseur}»~-- qui \emph{lit, analyse, évalue puis remplace les arguments par leurs résultats}, et ce avant que la macro ne soit exécutée. Avec \TeX{}, ce préprocesseur est réduit à sa plus simple expression : il ne fait que \emph{lire} et \emph{tokenizer} cet argument\footnote{Dans ce cas, on a affaire à un préprocesseur de bas niveau, le plus bas qui soit, et on parle de «préprocesseur lexical».}.

\Qu elle que soit l'affinité --~ou l'adoration~-- que l'on éprouve envers \TeX{}, on est bien obligé de reconnaitre que cette façon de faire n'est pas \emph{naturelle}. Car notre cerveau est lui aussi doté d'un \idx{préprocesseur} intelligent qui agit de façon semblable à celui des langages de programmation «normaux». Par exemple, n'apprend-on pas en mathématiques que :

\[\text{si }f(x)=x^2\text{\quad alors\quad}f(2\times3-1)=25\]

\noindent Avant tout calcul concernant la fonction $f$, ne procède-t-on pas spontanément à l'évaluation de l'argument «$2\times3-1$» pour le remplacer par le résultat, c'est-à-dire le nombre $5$ ? Ce faisant, ne procède-t-on pas comme les langages de programmation modernes qui, eux aussi, évaluent les arguments des macros ?

Tout ceci conduit donc à une première règle, probablement une des plus importantes de toutes :

\label{regle.argument}\begin{regle}
Si un code quelconque, notons-le \hbox{\verb|<|$x$\verb|>|}, produit un affichage \hbox{\verb|<|$y$\verb|>|} alors, sauf cas très particulier, il n'est pas équivalent d'écrire \hbox{\verb|<|$x$\verb|>|} ou \hbox{\verb|<|$y$\verb|>|} dans l'argument d'une macro.
\end{regle}
\grandsaut

L'autre inconvénient de \TeX{} qui rebute les personnes habituées à des langages plus modernes est que, pris comme un langage de programmation, \TeX{} est doté du \emph{strict minimum} ! Pour parler avec modération, l'\emph{extrême minimalisme}\footnote{D'autres, moins bienveillants, parleraient de «pauvreté».} de ce langage est totalement déroutant, car toutes les facilités auxquelles les langages modernes nous ont habituées depuis longtemps ne sont tout simplement pas implémentées dans \TeX{}. On ne parle pas ici de structures évoluées comme de pointeurs ou pire, de programmation orientée objet. Non, on parle de structures de contrôle des plus \emph{basiques}. Il va falloir renoncer à la création de variables typées, aux opérateurs logiques bien pratiques lors des tests («\texttt{or}», «\texttt{and}», «\texttt{not}»), aux boucles («\texttt{for}», «\texttt{while}», etc.), aux tableaux, aux nombres décimaux et aux opérations scientifiques, ainsi qu'à beaucoup d'autres choses. En \TeX{}, on doit se contenter de récursivité, de tests simples, de nombres entiers et des quatre opérations arithmétiques, et encore avec quelques limitations pour ces dernières. Et si l'on veut profiter de structures plus évoluées, il faut les programmer soi-même ! Heureusement, cela est toujours possible, car \TeX{}, dans son minimalisme, a été doté de tout ce qu'il faut pour construire n'importe quel algorithme, aussi complexe soit-il. On qualifie un tel langage de «complet». On aborde d'ailleurs dans ce livre la programmation de structures de contrôle plus évoluées que celles directement accessibles par \TeX.

Évidemment, lorsqu'on programme en \TeX{}, on ne se trouve pas au niveau de l'assembleur\footnote{Le «langage machine» est le langage de plus bas niveau qui soit, c'est-à-dire le moins compréhensible par un humain : ce sont des commandes directement compréhensibles par le microprocesseur qui sont des assemblages de bits ou si l'on préfère, des suites de 0 et de 1.

Ces suites de bits, traduites en instructions aisément mémorisables par un humain, constituent le langage «assembleur».} car tout de même, \TeX{} est un langage de bien plus haut niveau. En revanche, ce qui est certain, c'est qu'on programme à un niveau beaucoup plus bas que celui de tous les langages actuels. Cela oblige donc à revenir aux fondamentaux de la programmation, et ce retour aux sources est parfois vécu comme une régression par les personnes venant d'autres langages. Pourtant, contrairement à ce que l'on peut penser, revenir aux concepts de base de la programmation aide à élaborer des algorithmes plus efficaces et mieux construits (ceci étant vrai quel que soit le langage utilisé), oblige à mieux comprendre les méthodes sous-jacentes aux structures complexes et en fin de compte, fait accomplir des progrès en algorithmique tout comme en compréhension de la façon dont fonctionne un ordinateur.

\section{La relève}
Ces contraintes intrinsèques à \TeX{} font que, petit à petit, de plus en plus de gens gravitant autour de la sphère \TeX{} --~des utilisateurs de \LaTeX{} pour la plupart~-- ont admis que ce langage était devenu obsolète, tant pour la composition que pour la programmation. À leurs yeux, il devenait convenable, sinon de le cacher aux yeux des utilisateurs, au moins de proposer des alternatives considérées comme viables.

Le problème est que le \idx[!\LaTeX]{format} \texttt{latex} offre une collection de macros précompilées appelées \LaTeX{} dont le but est de proposer des commandes de haut niveau pour la composition mais hélas, \emph{presque rien} pour la programmation ! Pour pallier ce manque, les utilisateurs de \LaTeX{} se sont vus proposer des extensions spécialisées qui rendent la vie du programmeur plus simple et qui mettent à disposition des commandes permettant de créer facilement des boucles ou autres structures de contrôle de plus haut niveau.

Le progrès que cela représente est considérable, car la facilité d'utilisation est au rendez-vous. Il devient ainsi \emph{très} facile de faire appel à une boucle de type «\verb|for|». Bien sûr, chaque \idx{package} a sa propre syntaxe et ses propres instructions. Mais finalement, beaucoup d'entre eux ont une intersection non vide qui est la mise à disposition de commandes sur les boucles et les tests notamment. Étant donné le grand nombre de packages disponibles pour la seule programmation, il est presque impossible de connaitre les instructions de tous les packages. Le travers que cela créé est que certains utilisateurs deviennent totalement dépendants d'un package auquel ils sont habitués, quitte à ce que cela confine parfois à l'absurde. Un des exemples les plus frappants est le package «ti\textit kz» dont le but est de proposer des commandes de très haut niveau pour faire des dessins vectoriels. C'est un package d'une taille absolument gigantesque qui compte à peu près \numprint{300000}\footnote{À comparer avec les \numprint{8000} lignes du code de \LaTeX{} !} lignes de code, écrit en \TeX{} et en perpétuelle évolution et qui propose, en plus de commandes de dessin vectoriel, des outils qui facilitent la vie en programmation. Bien entendu, on y trouve des commandes qui permettent de construire des boucles. L'absurde de la situation est que parfois, certains utilisateurs dépendants de ti\textit kz et incapables de programmer par ignorance des commandes de \TeX{}, en viennent à charger un \idx{package} aussi volumineux pour ne se servir que d'une instruction en vue de créer une boucle, le tout en dehors de tout contexte de dessin. Certes, la solution fonctionne, mais l'efficacité n'est pas vraiment optimale.
\grandsaut

Le projet qui est actuellement en pleine phase d'expérimentation est \LaTeX3\index{format!\LaTeX3|(}. Il s'agit d'un projet qui relève un défi très ambitieux, celui de remplacer et d'améliorer l'actuelle version de \LaTeX. Ce projet, en maturation intense depuis de nombreuses années et animé par une équipe de codeurs très expérimentés, arrive actuellement à un stade où des pans entiers, bien que toujours en évolution, deviennent utilisables. Le pan qui émerge en ce moment est carrément un nouveau langage de programmation entièrement écrit en \TeX{} ! Comme \TeX{} est un langage complet, tout est possible, même le plus inattendu ! Ce nouveau langage de programmation offre d'innombrables possibilités que \TeX{} ne proposait pas, certaines extrêmement ardues à programmer. De plus, les auteurs ont essayé autant qu'ils le pouvaient d'inclure un \idx{préprocesseur}, actionnable à volonté et agissant sur les arguments des macros individuellement. Un code écrit dans ce nouveau langage devient donc beaucoup plus épuré et lisible que du code \TeX{}, autant par la présence de ce \idx{préprocesseur} que par l'extraordinaire diversité des macros mises à disposition. Celles-ci couvrent des domaines aussi variés que :

\begin{itemize}
	\item toutes les structures de contrôle basiques : tests, boucles;
	\item nombres décimaux en virgule fixe ou flottante et les opérations arithmétiques et scientifiques sur ces nombres ;
	\item recherche, remplacement dans une chaine de caractères avec la possibilité de faire appel à des critères dont la syntaxe est proche de celle des «expressions régulières\footnote{Une expression régulière est une suite de signes, appelés «motif», qui décrit selon une syntaxe précise des règles auxquelles doit satisfaire une chaine de caractère lors d'une recherche.

	Un livre entier serait à peine suffisant pour explorer le monde des expressions régulières. Ce qu'il faut savoir est qu'elles sont très largement utilisées autant pour leur compacité que pour leur puissance.}»;
	\item tri de données ;
	\item etc.
\end{itemize}

Le revers de la médaille est qu'il faut apprendre ce nouveau langage dont la syntaxe est suffisamment éloignée de celle de \TeX{} pour dérouter, voire rebuter un grand nombre d'utilisateurs habitués depuis des années voire des décennies à celle de \TeX{} ou \LaTeX. Ce nouveau langage se veut en effet beaucoup plus régulier que ne l'est \TeX, à tel point qu'il peut apparaitre fade, aseptisé et domestiqué en regard de l'original qui, par ses défauts un peu folkloriques, peut être ressenti comme davantage original et attachant. Le point le plus discutable est que \TeX{}, le langage sous-jacent, est volontairement rendu totalement invisible pour l'utilisateur final de \LaTeX3, toujours selon la volonté que \TeX{} doit être caché à l'utilisateur, car jugé trop difficile, obsolète et contraignant. \LaTeX3 créé finalement une dichotomie entre les utilisateurs. Les uns, pragmatiques, désireux de savoir et prêts à apprendre un nouveau langage, se moquent éperdument du \emph{vrai} langage qui se trouve sous cette «couche», trop contents d'avoir enfin à leur disposition un langage au comportement quasi «normal». Les autres, par curiosité intellectuelle et par désir de comprendre, ou tout simplement par rejet de \LaTeX3, n'y adhèreront pas et préfèreront ouvrir le capot afin de voir ce qui se joue en coulisses.

Il va sans dire que ces derniers devront, si ce n'est déjà fait, se mettre à \TeX{} et que les autres doivent sans tarder lire la documentation de \LaTeX3\index{format!\LaTeX3|)}.

\section{La révolution}
Mais que ces utilisateurs ne se ruent pas trop vite sur \LaTeX3, car il y a autre chose. Depuis l'année 2005, un nouveau moteur est en train de voir le jour. Il s'agit de lua\TeX{}\idx*[|(]{moteur!luatex}, un moteur où bien sûr le langage \TeX{} est toujours accessible, mais où est également rendu possible l'accès au langage «\texttt{lua}». Ce langage, créé en 1993 a justement été écrit pour être embarqué dans des applications pour en étendre les possibilités. Lua\idx*{lua} est un langage \emph{interprété} mais surtout, il possède tout ce que \TeX{} n'a pas et donc tout ce que les langages modernes ont! Parmi les fonctionnalités les plus essentielles, on peut citer :

\begin{itemize}
	\item accès facile et «naturel» aux structures de contrôle habituelles : boucles (\texttt{repeat}, \texttt{while}, \texttt{for}), tests simples, tests composés avec des opérateurs logiques sur les conditions;
	\item fonctions dont les arguments sont évalués par un \idx{préprocesseur};
	\item nombres, qui sont d'un seul type, les décimaux à virgule flottante. Ceux-ci sont assortis des opérations arithmétiques et d'une bibliothèque de fonctions mathématiques;
	\item variables typées (chaines de caractères, booléens, tables);
	\item accès aux fonctions du système (accès aux entrées/sorties, aux fonctions de date, d'heure);
	\item etc.
\end{itemize}

L'accès à \texttt{lua} peut donc grandement faciliter la vie d'un programmeur pour écrire des algorithmes qui autrement, seraient difficiles à coder en \TeX. Cela ne doit tout de même pas faire oublier que certains algorithmes \emph{doivent} être codés en \TeX, car c'est le langage qui a le dernier mot en matière de composition.

Mais il y a bien plus important. Le plus étonnant est que \texttt{lua} permet aussi l'accès aux mécanismes les plus intimes de \TeX{}. Les auteurs ont réussi le tour de force d'implémenter \texttt{lua} à un niveau tellement bas qu'il est possible d'agir sur le programme \texttt{tex} lui-même et d'accéder à des endroits auparavant inaccessibles et non modifiables (on dit qu'ils sont codés «en dur»). Cet accès ouvre des possibilités inouïes, car lors de la compilation et par l'intermédiaire de \texttt{lua}, il devient possible de modifier ou contrôler des comportements très fins de \TeX, le rendant extrêmement configurable, bien plus qu'il ne l'était. Il devient possible, par exemple, d'effectuer ces actions qui étaient impossibles avant :

\begin{itemize}
	\item relever les positions de toutes les espaces inter-mots d'un paragraphe afin de vérifier que certaines d'entre elles, au-delà d'un certain nombre, ne soient pas adjacentes et alignées verticalement, créant ainsi ce que l'on appelle en typographie des «rivières» ;
	\item lors de l'affichage, remplacer chaque occurrence d'un groupe de caractères par un autre, par exemple, tous les «onsieur» par «adame»;
	\item etc.
\end{itemize}\idx*[|)]{moteur!luatex}

\section{Et le bon dans tout ça?}
Bien évidemment, de \TeX{}, \LaTeX3 et lua\TeX, aucun n'est le bon, la brute ou le truand ! Chacun a ses propres caractéristiques et chacun cohabite avec les deux autres sans qu'aucun ne soit en compétition avec un autre. Au contraire, il faut se réjouir puisque le monde de \TeX{}, déjà d'une extrême complexité, mais presque figé depuis 1982 est en pleine effervescence et promet maintenant de façon certaine que des choses impossibles auparavant ne le seront plus. L'avenir s'ouvre riche en perspectives et sans rêver, ne peut-on pas imaginer, d'ici quelques années, un \idx{format} basé sur le moteur lua\TeX{}\idx*{moteur!luatex} contenant les macros précompilées de \LaTeX3, le tout formant une unité réunissant les trois protagonistes qui sera d'une puissance et d'une souplesse jusqu'alors inconnues ? Peut-on déjà mesurer l'immense bond en avant que constituera cette symbiose ? Et que feront les packages de cette nouvelle ère s'ils savent exploiter les trois langages, quels miracles seront-ils capables de réaliser ?

\chapter{Avant de commencer}
\section{La programmation \TeX{} oui, mais pour qui ?}
Finalement, à qui s'adresse ce livre ?
\grandsaut

Tout d'abord aux utilisateurs de plain-\TeX, \LaTeX{} ou d'un autre \idx{format} qui souhaitent acquérir un peu d'autonomie dans la programmation en \TeX. Car un jour ou l'autre c'est inévitable, on en a besoin, ne serait-ce que parce que les packages disponibles n'ont pas ne couvrent pas tous les cas ou parce qu'on ignore qu'un package répondant à un besoin précis existe. \Qu 'y a-t-il de plus frustrant que de renoncer en se sachant incapable d'écrire le moindre code non linéaire, surtout lorsqu'on en a un urgent besoin ? \Qu elle satisfaction intellectuelle retire-t-on lorsqu'au moindre problème urgent et incontournable, on est contraint de poser une question de programmation \TeX{} sur un forum spécialisé ? Est-ce vraiment valorisant d'attendre une réponse, « copier-coller » le code donné par un connaisseur sans en comprendre le fonctionnement et se dire qu'au prochain problème, il faudra poser une question à nouveau ?

Ce livre s'adresse aussi aux curieux, à ceux désireux d'apprendre, ceux qui souhaitent soulever un coin du voile. En effet, \TeX{} est réputé comme étant un langage réservé à quelques «initiés», voire carrément inaccessible si l'on n'est pas «\TeX-compatible». La lecture de ce livre dissipera un peu l'aura quasi mystique qui l'enveloppe --~c'est en tout cas un des buts recherchés~--, assouvissant les légitimes interrogations que se posent les «non-initiés» à son sujet.

Il s'agit aussi de faire redécouvrir qu'il existe d'autres voies en programmation et celle que prend \TeX{} est des plus originales. Car finalement, tous les «poids lourds» des langages modernes ne tendent-ils pas à se ressembler tous ? Ne proposent-ils pas un peu tous les mêmes fonctionnalités, au moins jusqu'à un certain niveau ? Il est assez excitant de découvrir un langage de macros tellement ceux-ci sont rares\footnote{Le langage « \texttt{M4} » est également un langage de macros.}. L'apprentissage d'un tel langage est excitant d'abord parce que cela étend la culture informatique, mais surtout parce cela ouvre de nouvelles voies en programmation en suscitant des méthodes de programmation nouvelles. Il est d'ailleurs reconnu que les langages de macros sont puissants, même s'ils procèdent à des remplacements \emph{aveugles} de macros par leur \idx{texte de remplacement}. Ce manque d'évaluation se paie par des erreurs parfois difficiles à corriger, car surgissant à des moments ou à des endroits très éloignés de l'origine du problème.
\grandsaut

Bien sûr, nulle part nous n'apprendrons à programmer des macros aussi complexes que celles de \LaTeX3, nous resterons beaucoup plus modestes. Le but de ce livre est de donner les clés pour comprendre \emph{comment} il faut s'y prendre. La compréhension de quelques concepts doit pousser, au fur et à mesure de la lecture, à coder soi-même et essayer de voler de ses propres ailes. Il est en effet primordial, quel que soit le niveau atteint, de toujours expérimenter par soi-même, car se contenter d'une lecture linéaire ne peut suffire. Imaginerait-on qu'un joueur débutant de bridge, jeu complexe s'il en est, deviendrait subitement un bon joueur après avoir simplement lu d'un trait un ouvrage sur le sujet ? La réponse est évidemment négative, car tester, modifier, adapter, expérimenter, se « planter », apprendre de ses erreurs, recommencer, recommencer encore fait partie de tout apprentissage. Cela est valable dans tous les domaines, et en programmation --~surtout en \TeX~-- peut-être encore davantage !
\section{Ce qu'il faut savoir}
Il ne serait pas raisonnable d'aborder le côté langage de \emph{programmation} de \TeX{} sans avoir jamais pratiqué \TeX{}, \LaTeX{} ou un autre \idx{format} en tant que langage de \emph{composition}. Non, vraiment pas raisonnable. Cette pratique est indispensable, ne serait-ce que pour s'imprégner de la syntaxe et se familiariser avec l'outil. Ce livre ne s'adresse donc pas au débutant de la première heure, sauf inconscient ou masochiste qui souhaiterait se dégouter à tout jamais de \TeX{} !

Mais tout compte fait et nous allons le voir ci-dessous, les choses à savoir ne sont pas légion.

\subsection{\TeX{} et la composition}
Il faut avoir une petite idée de la façon dont \TeX{} compose du texte. Le schéma mental le plus proche de la réalité est de se dire que \TeX{} fonctionne par placement de boites sur la page. La géométrie des boites de \TeX{} est assez facile à comprendre. Voici la lettre «g», écrite en très grand et dont on a tracé les contours de la \emph{boite englobante}\idx*{boite!englobante} qui traduit les dimensions avec lesquelles \TeX{} voit une boite :

\begin{centrage}
\dimenbox[75]{g}\global\setbox\testbox\hbox{\unhbox\testbox}
\end{centrage}

Comme on peut le voir, la boite englobante\idx*{boite!englobante} a trois dimensions\idx*{boite!dimension}\idx*{boite!géométrie}, tout comme n'importe quelle boite dans le monde de \TeX{}\idx*{boite!géométrie} :%
\begin{itemize}
	\item une largeur qui est ici de \the\wd\testbox;
	\item une hauteur, de \the\ht\testbox
	\item une profondeur égale à \the\dp\testbox
\end{itemize}

\TeX{} exprime naturellement les dimensions en \emph{points}\idx*{pt (unité)}\idx*{unité!pt} (mais nous le verrons, il y a bien d'autres unités possibles), et un centimètre\idx*{unité!cm}\idx*{cm (unité)} contient exactement \texttt{\the\dimexpr1cm\relax}.

La hauteur et la profondeur s'étendent verticalement de part et d'autre de la \emph{\idx{ligne de base}}. C'est une ligne horizontale théorique autour de laquelle s'organise la géométrie d'une boite. Pour les boites contenant les caractères, sa position pratique coïncide avec le bas des caractères sans jambage comme «a,», «b», «c», etc.\medbreak

{%
\noindent\setbox0\hbox{\Large Programmer en \TeX{} est \emph{facile}.}%
\hfill
\rlap{\kern-1cm\vrule height0.2pt depth0.2pt width\dimexpr\wd0+2cm}%
\box0
\hfill\null
}%
\medbreak

Chaque boite a un point particulier, appelé \emph{\idx{point de référence}} situé sur la frontière gauche de la \idx*{boite!englobante}boite englobante. Ce point de référence est, dans la boite contenant «g», représenté par un point «\tikz\draw[fill,black](0.35pt,0pt)circle(1pt);». Les boites sont donc correctement placées verticalement parce que leur point de référence vient sur la \idx{ligne de base} de la ligne courante, et sont positionnées les unes à la suite des autres parce que le \idx{point de référence} de la boite suivante est situé sur la frontière droite de la boite précédente.

\TeX{} procède par à-coups, composant tour à tour des paragraphes\idx*[|(]{paragraphe!composition}. La mécanique fonctionne de cette manière : lorsque la commande \idx\par est rencontrée, le paragraphe qui vient d'être lu et qui est jusqu'alors stocké en mémoire est « composé ». C'est le moment où \TeX{} appréhende le paragraphe dans sa totalité pour décider où se feront les coupures de ligne. Chaque ligne de texte est ainsi constituée

\begin{itemize}
	\item de boites contenant les caractères\footnote{Pour être clair, \TeX{} ne connait à aucun moment le dessin de chaque caractère. Il ne connait que les dimensions de la boite qui le contient, qui est la boite englobante.}. Dans un mot, chaque boite est adjacente à la précédente;
	\item d'espaces qui peuvent, dans une certaine mesure, s'étirer ou se comprimer de telle sorte que la largeur de la ligne soit exactement celle de la largeur du paragraphe. La dernière ligne du paragraphe, moins large que ne l'est le paragraphe, a des espaces qui ont leur largeur naturelle.
\end{itemize}

Pendant tout le paragraphe, \TeX{} positionne cette \emph{liste} d'éléments à la suite les uns des autres de façon horizontale pour former chaque ligne : on dit qu'il fonctionne en «mode horizontal\idx*{mode!horizontal}». Ce mode est d'ailleurs celui dans lequel il se trouve pour la plupart du temps lorsqu'il compose du texte.

La composition proprement dite du paragraphe enferme chaque ligne dans une boite et les boites contenant les lignes sont positionnées \emph{verticalement} les unes sous les autres, chacune étant séparée de sa voisine par un « \idx{ressort d'interligne} » (page~\pageref{ressort.interligne}).

\begingroup
\clubpenalty=0 % pas de pénalité supplémentaire après la première ligne
\interlinepenalty=0 % pas de pénalité inter-ligne
\widowpenalty=0 % pas de pénalité supplémentaire avant la dernière ligne
\leftline{}
\let\formatline\frbox
\frboxrule=0.3pt
\frboxsep=-\frboxrule% encadrer vers "l'intérieur"
\numlines
On peut observer ce \idx{ressort d'interligne} dans ce paragraphe où la boite englobante\idx*{boite!englobante} de chaque ligne est tracée. On peut constater que la boite englobante d'une ligne ne touche pas celle de ses voisines : l'espace vertical qui les sépare est l'espace interligne. Si cet espace était nul, les lignes seraient beaucoup trop serrées et cela rendrait la lecture très pénible.
\endnumlines
\endgroup

Après avoir formé le paragraphe (et donc après avoir exécuté la commande \idx\par), le mode\idx*{mode!vertical} vertical est en vigueur, puisque \TeX{} vient de placer les lignes du paragraphe précédent verticalement : il est donc prêt à positionner d'autres éléments verticalement les uns sous les autres. Bien évidemment, si un nouveau paragraphe commence juste après, \TeX{} repasse en mode horizontal\idx*{mode!horizontal} dès le premier caractère rencontré.

Au fur et à mesure que les lignes et autres objets remplissent verticalement la page, il arrive un moment où un certain seuil de remplissage est atteint et \TeX{} décide où se situe la coupure de page.  La page destinée à être composée est à ce moment enfermée dans une ultime boite. Cette boite signe la fin de l'imbrication des boites en poupées gigognes et est envoyée vers le fichier de sortie.\idx*[|)]{paragraphe!composition}%

\subsection{\Qu elques commandes utiles}
\subsubsection{\texttt{\textbackslash par} et les changements de mode}
La plus courante de toutes les primitives est sans doute \idx\par puisque sans elle, il n'y aurait pas de \idx{paragraphe} et donc pas de typographie. Ajoutons à ce qui a été dit ci-dessus la règle suivante :

\label{par.consecutifs}\begin{regle}
Lorsque \TeX{} est en mode vertical\idx*{mode!vertical}, la commande \idx[!mode vertical]\par\idx*{mode!vertical} est sans effet.

Par conséquent, si l'on se trouve en mode horizontal\idx*{mode!horizontal} et si plusieurs commandes \idx[!consécutifs]\par se suivent, seule la première est utilisée pour composer le paragraphe en cours et les autres sont ignorées.
\end{regle}

On peut quitter le mode vertical\idx*{mode!vertical} sans afficher aucun caractère avec la macro de plain-\TeX{} \idx\leavevmode.

D'autres primitives commandent à \TeX{} le passage en mode horizontal\idx*{mode!horizontal}, mais font aussi autre chose :
\begin{itemize}
	\item \idx\indent insère au début de la liste horizontale une espace de valeur \idx\parindent, qui est la primitive contenant la dimension du retrait de la première ligne d'un paragraphe (plain-\TeX{} initialise cette dimension à \texttt{20pt} en procédant à l'assignation «\verb*|\parindent=20pt |»);
	\item \idx\noindent demande à ce que le prochain paragraphe\idx*{paragraphe!indentation} ne soit pas indenté, c'est-à-dire que sa première ligne ne commence pas en retrait.
\end{itemize}

\subsubsection{Espaces sécables et insécables}
La primitive \idx\kern, suivie d'une dimension, insère dans la liste courante une espace insécable\idx*{espace!insécable} de la dimension voulue. Cette espace est insécable, car aucune coupure (de page ou de ligne) ne pourra se faire sur cette espace. Il est important de noter que \idx\kern obéit au mode en cours; l'espace est horizontale si \TeX{} est en mode horizontal\idx*{mode!horizontal} et sera verticale sinon. Voici ce qu'il se passe si l'on écrit \verb|A\kern 5mm B| :

\begin{centrage}
	A\kern 5mm B
\end{centrage}

\noindent L'espace de \texttt{5mm} se trouve entre le bord droit de la boite englobante\idx*{boite!englobante} de « A » et le bord gauche de la boite englobante de « B ».

Pour insérer une espace verticale supplémentaire de \numprint[mm]5
 entre deux lignes, il suffit de passer en mode vertical\idx*{mode!vertical} avec \idx\par pour que \idx\kern agisse dans ce mode. Ainsi, \verb|A\par\kern 5mm B| se traduit par :

\begin{centrage}
	A\par\kern 5mm B
\end{centrage}
\grandsaut

L'espace entre le bas de la lettre «A» et le haut de la lettre «B» est légèrement supérieure à \numprint[mm]5 car le \idx{ressort d'interligne} s'ajoute à l'espace spécifiée par \idx\kern.\grandsaut

Si l'on veut insérer des espaces \emph{sécables}\idx*{espace!sécable}, c'est-à-dire susceptibles d'être \emph{remplacées}\footnote{Il faut bien lire « remplacées », car une espace sécable est supprimée si elle se trouve à un endroit de coupure. Les espaces sécables les plus courantes sont les espaces tapés dans le code pour séparer les mots.} par une coupure de ligne ou de page, il faut utiliser soit \idx\hskip, soit \idx\vskip. La première lettre désignant le mode dans lequel on veut que cette espace soit insérée et commandant le passage dans ce mode. Ces deux primitives doivent être suivies d'une dimension de ressort (voir page~\pageref{dimension.ressort}). Plain-\TeX{} met à disposition deux macros \idx\quad et \idx\qquad insérant respectivement une espace horizontale sécable\idx*{espace!sécable} de \verb|1em| et de \verb|2em|. L'unité \verb|em|\idx*{unité!em} dépend du contexte : c'est la dimension horizontale de la boite englobante\idx*{boite!englobante} de lettre «\verb|m|», composée dans la fonte en cours.

La macro \idx\smallskip insère verticalement à l'aide de \idx\vskip l'espace élastique stockée dans le registre \idx\smallskipamount et qui vaut dans plain-\TeX{} «\texttt{3pt plus 1pt minus 1pt}». Les variantes \idx\medskip et \idx\bigskip insèrent des espaces verticales égales respectivement à 2 fois et 4 fois \idx\smallskipamount.

Les macros \idx\smallbreak, \idx\medbreak et \idx\bigbreak se comportent comme leurs s\oe urs en «skip» mais elles vérifient tout d'abord que la précédente espace verticale qui les précède est inférieure à celle qui doit être insérée. Dans ce cas seulement, ces macros favorisent une coupure de page (par l'insertion d'une \idx{pénalité} de $-50$, $-100$ ou $-200$), suppriment la précédente espace verticale et insèrent l'espace par l'intermédiaire de \idx\smallskip, \idx\medskip et \idx\bigskip.

\subsubsection{\texttt{\textbackslash relax}}
La primitive \idx\relax est la plus simple à comprendre puisqu'elle ne provoque aucune action. Elle est cependant utile notamment pour marquer clairement la fin d'un nombre ou d'une dimension et évite que \TeX{} n'aille chercher des choses au-delà. Elle fait aussi partie, mais de façon optionnelle, de la syntaxe des primitives \idx\numexpr et \idx\dimexpr de \idx\eTeX{} (voir pages~\pageref{numexpr} et \pageref{dimexpr}).

\subsubsection{Commandes de fontes}
Les commandes suivantes, programmées dans le format plain-\TeX, agissent comme des « bascules » et sélectionnent une forme de fonte :

\begin{centrage}
\small
\begin{tabular}{ccc}\hline
	Commande \TeX & Équivalent \LaTeX & Exemple\\\hline
	\idx\bf & \idx\bfseries & \bf fonte en gras\\
	\idx\it & \idx\itshape & \it fonte italique\\
	\idx\tt & \idx\ttfamily & \tt fonte à chasse fixe\\
	\idx\sc & \idx\scshape & \sc fonte petite majuscule\\\hline
\end{tabular}
\end{centrage}

Par ailleurs, en \idx*{mode!mathématique}mode mathématique, la primitive \idx\scriptstyle fonctionne également comme une bascule au niveau de la taille de la fonte qui est affichée dans la taille des exposants. De la même façon, \idx\scriptscriptstyle sélectionne une taille encore plus petite, celle des « exposants d'exposants » :

\showcode/3 tailles : $% entre en mode mathématique (espaces ignorés)
1^{2^3}% 2 est en taille "\scriptstyle" et 3 en taille "\scriptscriptstyle"
$% fin du mode math¤\idx*{mode!mathématique}¤

normal $1$, petit $\scriptstyle 2$, très petit $\scriptscriptstyle 3$.¤\idx*\scriptstyle\idx*\scriptscriptstyle¤/

\subsubsection{Les boites}
Venons-en maintenant aux \idx{boite}s, non pas celles que \TeX{} construit automatiquement lors de la composition, mais de celles qui sont mises à disposition de l'utilisateur pour qu'il puisse enfermer dedans un contenu arbitraire.

\TeX{} met à disposition trois primitives permettant d'enfermer du matériel dans des boites :
\begin{itemize}
	\item \idx\hbox\verb|{<contenu>}| enferme le \verb|<contenu>| dans une boite horizontale, étant entendu que ce contenu ne peut être composé qu'en mode horizontal\idx*{mode!horizontal} et doit donc être exempt de commande spécifiquement verticale (\idx\par ou \idx\vskip y sont interdits puisque passant en mode vertical\idx*{mode!vertical});
	\item \idx\vbox\verb|{<contenu>}| construit une boite verticale dans laquelle chaque élément du \verb|<contenu>| est empilé sous l'élément précédent et où règne le mode vertical \emph{interne}\idx*{mode!vertical interne}. Le \idx{point de référence} de la boite ainsi obtenue coïncide avec celui du dernier élément (le plus bas donc). Autrement dit, la \idx{ligne de base} de la \idx\vbox coïncidera donc avec la \idx{ligne de base} de l'élément le plus bas. Par conséquent, s'il y a $n$ éléments dans la \idx\vbox, les $n-1$ premiers seront placés au-dessus de la \idx{ligne de base} de la ligne courante comme le montre la figure ci-dessous ;
	\item \idx\vtop\verb|{<contenu>}| procède comme \verb|\vbox| sauf que le \idx{point de référence} de la \idx\vtop coïncide avec celui du \emph{premier} élément (le plus haut). Les $n-1$ derniers éléments sont donc au-dessous de la \idx{ligne de base} de la ligne courante.
\end{itemize}

Voici deux constructions, l'une avec \idx\vbox et l'autre avec \idx\vtop où les frontières des boites ont été rendues visibles et où les points de références de chaque boite ont été symbolisés par un point «\tikz\draw[fill,black](0.35pt,0pt)circle(1pt);». Pour les besoins de l'exemple, chaque boite contient trois éléments.

\begin{centrage}\footnotesize
	Voici une \idx\vbox : \drawbox{\vbox{\hbox{\drawbox{La première ligne}}\hbox{\drawbox{La deuxième}}\hbox{\drawbox{Et la troisième}}}} puis une \idx\vtop : \drawbox{\vtop{\hbox{\drawbox{La première ligne}}\hbox{\drawbox{La deuxième}}\hbox{\drawbox{Et la troisième}}}}
\end{centrage}

Le mode en cours dans ces boites est le mode \emph{interne}\idx*{mode!interne}. Il s'agit du mode horizontal interne\idx*{mode!horizontal interne} pour \idx\hbox et du mode vertical interne\idx*{mode!vertical interne} pour \idx\vbox et \idx\vtop.\grandsaut

Une boite construite avec l'une des trois primitives \idx\hbox, \idx\vbox ou \idx\vtop est \emph{insécable}. Il n'existe donc aucun mécanisme qui permet de couper une boite ainsi construite\label{boite.insecable}. Il est donc nécessaire d'être prudent sur les débordements\idx*{dépassement (marge)} qui peuvent en résulter :

\begin{itemize}
	\item en mode horizontal\idx*{mode!horizontal}, ces débordements ont lieu dans la marge de droite ;
	\item en mode vertical interne\idx*{mode!vertical interne}, ils ont lieu dans la marge inférieure.
\end{itemize}

{\hfuzz=\maxdimen Pour illustrer ce propos, voici ce qui arrive si on tente d'enfermer ces \hbox{\bfseries mots en gras} dans une \idx\hbox. On peut constater que la coupure de ligne n'a pu se faire et que la boite dépasse dans la marge de droite. Cela signifie que malgré tous ses efforts pour comprimer ou étirer les espaces, couper des mots, mixer ces possibilités pour examiner plusieurs solutions, \TeX{} n'a pu composer le paragraphe\idx*{paragraphe!composition} pour faire en sorte que cette \idx\hbox se trouve entre les frontières du texte. Dans le cas présent, cet échec est dû à la trop grande largeur de la boite et au fait qu'elle se situe à un endroit proche du début du paragraphe, où la latitude d'organiser différemment ce qui précède est assez réduite. \TeX{} avertit l'utilisateur qu'une anomalie dans la composition du paragraphe a eu lieu par un message dans le \idx[!log]{fichier} \verb|log|: c'est le fichier produit par \TeX{} lors de la compilation d'un code source. Ce fichier contient des informations de compilation et a le même nom que le fichier compilé mais porte l'extension «\texttt{.log}». Concernant ce débordement, on lit dans ce ficher «\texttt{Overful \string\hbox{} (9.74199pt too wide) in paragraph}», ce qui signifie qu'une boite horizontale (la boite horizontale dont il est question est ici la ligne en cours) est trop large de 9.74199pt par rapport à la largeur du texte.\par}

\section{Demandez le programme}
Le chemin choisi pour aborder la programmation en \TeX{} va sembler, c'est sûr, long et ingrat. Il obéit cependant à une logique qui apparaitra plus tard au lecteur. Les parties I et II ne sont pas consacrées à la programmation, mais aux nombreuses spécificités du langage \TeX{} sans lesquelles il est impossible de construire le moindre programme. C'est par souci de clarté et pour bâtir des bases solides que ces spécificités sont abordées \emph{avant} d'entrer dans le vif du sujet. Renoncer à ces explications préliminaires aurait conduit à d'innombrables digressions, chacune apparaissant à une nouvelle spécificité, et troublant plus le discours qu'autre chose. Ainsi, la partie I montrera comment et selon quelles règles \TeX{} lit le code source pour le transformer en matière exploitable que sont les \idx{token}s. La partie suivante exposera les nombreuses spécificités des macros de \TeX{} et comment les construire afin de maitriser cet outil fondamental de programmation.

Ce n'est qu'ensuite, à la partie III, que nous nous lancerons dans le grand bain et commencerons à bâtir des algorithmes. Nous verrons, à l'aide d'algorithmes relativement peu complexes, quelles méthodes de programmation nous pouvons mettre en \oe uvre en \TeX{} et quels écueils nous devons éviter. La partie IV s'inscrit dans la continuité de la partie III, mais les méthodes employées diffèrent en ce sens que la granularité de la lecture du code effectuée par les macros sera plus fine.

Enfin, la dernière partie sera consacrée à des algorithmes un peu plus complexes mettant à profit les notions vues jusqu'alors.
%|                                                                            |
%|                              Fin introduction                              |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Partie 1                                  |
%|                                                                            |
\defpartcomment{\lettrine[lines=3,slope=4pt,nindent=0pt]{\libertineInitialGlyph{A}}{\kern -5pt vant} d'entrer dans le vif du sujet, il nous faut comprendre un des mécanismes fondamentaux de \TeX{}, le premier dont il est question lorsque \TeX{} fonctionne : comment lit-il le code qui est tapé par l'utilisateur ? Et qu'est-ce réellement du code tapé par l'utilisateur ? Les réponses à ces questions non triviales permettent non seulement de lever une petite partie du mystère qui entoure le fonctionnement de \TeX{} mais surtout posent des bases essentielles.}

\part{\TeX{} et le code source}
\chapter{Comment \TeX{} lit-il le code source ?}
Pour bien répondre à cette question, il faut d'abord définir ce qu'est du «code tapé par l'utilisateur». Ce code, la plupart du temps stocké dans un fichier, est considéré et lu par \TeX{} \idx{octet}\footnote{Un octet est une suite de 8 bits. Cette suite peut être comprise comme un nombre constitué de 8 chiffres en base 2. Si l'on convertit ce nombre en base 10 alors, ce nombre peut varier de $2^0-1$ à $2^8-1$, c'est-à-dire de 0 à 255 ou \Hex{00} à \Hex{FF} en hexadécimal.} par \idx{octet}; c'est d'ailleurs ainsi qu'il est stocké sur les disques durs de nos ordinateurs. Ainsi la résolution de lecture de \TeX{} est toujours la même, le code tapé par l'utilisateur est vu par \TeX{} comme une suite d'\idx{octet}s.
\grandsaut

Un «\idx{éditeur}» est un logiciel totalement indépendant de \TeX{} dont les fonctions les plus basiques sont de permettre la saisie de \emph{texte} et la sauvegarde de ce texte dans un fichier. Il existe des quantités d'éditeurs\footnote{Citons pour les plus reconnus vim et emacs du côté de UNIX/GNU-linux et notepad++ du côté de Windows.} différents, avec des fonctions plus ou moins nombreuses, parfois pléthoriques, certains étant même spécialisés dans la saisie de code \TeX\footnote{Là aussi, il y a du monde : auc\TeX{} qui est une extension d'emacs pour le spécialiser pour \TeX/\LaTeX, \TeX macs, kile, \TeX maker, \TeX works, etc.}. Lorsqu'on demande à l'éditeur d'enregistrer dans un fichier le texte que l'on a tapé, l'éditeur a la charge de \emph{convertir} les caractères tapés par l'utilisateur en une suite d'\idx{octet}s qui seront enregistrés sur le disque dur sous forme d'un fichier texte.

Pour comprendre comment cette conversion est faite et quelle est la signification de ces \idx{octet}s, il faut savoir à quel «\idx{encodage}» obéit l'éditeur lors de cette conversion. Un \idx{encodage} est une convention qui lie de façon biunivoque un caractère à un (parfois plusieurs) \idx{octet}. Il est important de comprendre que c'est l'\emph{utilisateur}, en paramétrant son éditeur, qui décide quel \idx{encodage} il désire utiliser, même si évidemment, un choix par défaut est toujours sélectionné si l'on n'a pas fait la démarche de modifier le paramètre adéquat.
\grandsaut

L'\idx{encodage} ASCII\idx*{encodage!ASCII}\footnote{ASCII est l'acronyme pour «American Standard Code for Information Interchange».} est commun à l'immense majorité des autres \idx{encodage}s ce qui fait que l'ASCII joue le rôle de plus petit dénominateur commun. Cette convention ASCII ne s'occupe que des \idx{octet}s compris entre 0 et 127 (ou \Hex{00} et \Hex{7F} en hexadécimal). \TeX{} reconnait nativement l'ASCII dont on voit dans la table ci-dessous la correspondance entre \idx{octet}s et caractères. Pour toutes les implémentations de \TeX{}, la relation entre \idx{octet} et caractère affichable qui figure dans cette table est valide :

\def\carnonaff{\itshape}
\begin{centrage}
	\noindent
	\footnotesize
	\def\?#1{\ttfamily\bfseries x#1}%
	\newcount\charcnt \charcnt=-17
	\def\!{\global\advance\charcnt1 }%
	\def\:{\char\charcnt}%
	\let\^\carnonaff% marque un caractère non affichable
	\newcolumntype G{m{\dimexpr(\linewidth-18\arrayrulewidth)/17\relax}}%
	\begin{tabular}{|@{}>{\columncolor{gray!40}[0pt][0pt]\hfill\ttfamily\bfseries}G<{x\hfill\null}@{}|*{16}{@{}>{\!\hfill\vrule height3.3ex depth.8ex width0pt }G<{\hfill\unless\ifnum\charcnt<0 \vtop{\kern1.5pt\normalfont\tiny\llap{\number\charcnt\kern.5pt}\kern1pt}\fi\null}@{}|}}
	\hline
		\rowcolor{gray!40}[0pt][0pt]\multicolumn1{|@{}G@{}|}{\cellcolor{white}}
		&\?0 &\?1 &\?2 &\?3 &\?4 &\?5 &\?6 &\?7 &\?8 &\?9 & \?A& \?B&\?C &\?D &\?E & \?F\\\hline
		0 & \^NUL&\^SOH &\^STX &\^ETX &\^EOT &\^ENQ &\^ACK &\^BEL & \^BS &\^HT  & \^LF & \^VT & \^FF & \^CR & \^SO & \^SI \\\hline
		1 & \^DLE&\^DCI & \^DC2& \^DC3& \^DC4& \^NAK& \^SYN& \^ETB& \^CAN& \^EM & \^SUB& \^ESC& \^FS & \^GS & \^RS & \^US \\\hline
		2 & SP & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: \\\hline
		3 & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: \\\hline
		4 & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: \\\hline
		5 & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: \\\hline
		6 & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: \\\hline
		7 & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \: & \^DEL\\\hline
	\end{tabular}
\end{centrage}

Dans ce tableau, les cases grisées portent les deux chiffres hexadécimaux qui formeront le numéro de l'octet. Le nombre en bas à droite de chaque case est le numéro de l'octet en base 10. Par exemple, le caractère «A» correspond à l'octet \Hex{41} dont la valeur décimale est 65.

On remarque que quelques octets codent des caractères non affichables. Ceux-ci sont affichés en italique\footnote{Les acronymes dans les cases des caractères non imprimables correspondent à des noms qui ont été donnés à ces octets lors de la création de cet \idx{encodage}. Pour la plupart, ces octets étaient insérés dans des flux de données lors de télétransmission et avaient une signification liée à la communication entre deux ordinateurs distants. Par exemple, l'octet {\carnonaff EOT\/} signifie « End Of Transmission» c'est-à-dire « Fin de Transmission», {\carnonaff NAK\/} signifie «Negative Acknowledge» pour «Accusé de réception négatif». Ces fonctions sont évidemment sans objet pour un traitement de texte comme \TeX{}. Ces caractères n'ont donc pas de signification particulière pour \TeX{} à l 'exception de quelques caractères non imprimables dont la fonction est restée la même : {\carnonaff HT\/} pour «tabulation horizontale» (le caractère inséré avec la touche «Tab» \bioLegacyKeyGlyph{T_a_b}), {\carnonaff LF\/} pour «saut de ligne» et {\carnonaff CR\/} pour «retour charriot».} dans la table. Ils ont des codes hexadécimaux compris entre \Hex{00} et \Hex{1F} inclus auxquels il faut rajouter le caractère de code \Hex{7F}.
\grandsaut

Pendant la compilation, à chaque fois que \TeX{} lit un \idx{octet} --~pour l'instant, disons par abus de langage un «caractère»~--, il lui affecte une bonne fois pour toutes un «code de catégorie» ou «\idx{catcode}» et de fait, chaque caractère lu dans le fichier a donc \emph{deux} codes pour \TeX:
\begin{itemize}
	\item le \idx{code de caractère}, c'est-à-dire la valeur de l'\idx{octet} lu dans le code source et qui est lié à la table ASCII vue précédemment;
	\item le code de catégorie\idx*{catcode} qui est affecté par \TeX{} lors de sa lecture. Ces codes de catégorie sont des entiers qui vont de 0 à 15 et qui donnent au caractère des propriétés qui sont celles de la catégorie à laquelle il appartient.
\end{itemize}

Voici les différentes \idx{catégories} ainsi que pour chacune, les caractères qui les peuplent par défaut :

\begin{centrage}
	\label{catcode.table}\small
	\let\^\carnonaff% marque un caractère non affichable
	\LTpre\parskip \LTpost\parskip\idx*{catcode!table des catcodes}
	\begin{longtable}{>{\leftskip0ptplus1fill \rightskip\leftskip}m{1.5cm}m{4.5cm}m{3cm}}\hline

 		N°{} de\par catégorie & Signification & Caractères\par concernés\\\hline\endhead
		0 & \idx{caractère d'échappement} & \texttt\textbackslash\\
		1 & début de groupe & \ttfamily\{\\
		2 & fin de groupe & \ttfamily\}\\
		3 & délimiteur de mode mathématique\idx*{mode!mathématique} & \ttfamily\$\\
		4 & tabulation d'alignement & \ttfamily\&\\
		5 & retour charriot & \^LF\\
		6 & caractère de paramètre & \ttfamily\#\\
		7 & exposant & \ttfamily\string^\\
		8 & indice & \ttfamily\string_\\
		9 & caractère ignoré & \^NUL\\
		10 & \idx{espace} & SP et \^HT\\
		11 & lettres & \texttt{A...Z}\quad et\quad\texttt{a...z}\\
		12 & autres caractères &\\
		&\qquad-- chiffres & \ttfamily0 1 2 3 4 5 6 7 8 9\\
		&\qquad-- signes de ponctuation & \ttfamily\string: . \string; , \string? \string! \string' \string"\\
		&\qquad-- signes mathématiques & \ttfamily + - * / = < >\\
		&\qquad-- autres signes &\ttfamily [ ] ( ) | @ \string`\\
		13 & caractère actif & \ttfamily\string~\\
		14 & caractère de commentaire & \ttfamily\%\\
		15 & caractère invalide & \^DEL\\
		\hline
	\end{longtable}
\end{centrage}

Dans toute la suite du livre, sauf indication contraire, lorsqu'il est dit par abus de langage « lettre » ou bien « accolade ouvrante », il est sous-entendu « caractère de catcode 11\idx*{catcode!11 (lettre)} » ou « caractère de catcode 1\idx*{catcode!1 (accolade)} ».

Comme on le voit, certaines catégories sont très peuplées (celles dont le numéro est 11 ou 12) alors que d'autres ne contiennent qu'un seul élément. Ceci s'explique par le fait que seules les catégories de numéro 10, 11 et 12 comportent des caractères \emph{affichables} pour \TeX. Les autres ne comportent que des caractères qui commandent une action à \TeX{}, par exemple de passer en mode mathématique\idx*{mode!mathématique} pour le caractère «\verb-$-». Comme il n'y a pas de raison pour que plusieurs caractères revêtent cette propriété, il est logique de ne trouver qu'un seul caractère dans la catégorie n°3. Le même raisonnement s'applique aux autres catégories ne comportant qu'un seul caractère.

L'\idx{espace}, bien qu'affichable, se trouve dans une catégorie à part, car il obéit à des règles différentes que celles des autres caractères affichables, notamment lors de la lecture du code source :

\label{espaces.consecutifs}\begin{regle}
Lorsque plusieurs espaces\idx*{espace!consécutifs} (ou plus généralement «caractères de catcode 10»\idx*{espace!catcode 10})\idx*{catcode!10 (espace)} se suivent dans le code source, \TeX{} ne prend en compte que le premier d'entre eux et ignore les autres.

Si une ligne de code source commence par des espaces\idx*{espace!début de ligne}, ceux-ci sont ignorés.

Plain-\TeX{} et \LaTeX{} assignent au caractère de tabulation ({\carnonaff HT\/}) le catcode de 10 ce qui signifie que ce caractère revêt toutes les propriétés de l'espace.
\end{regle}

Pour fixer les idées, supposons que \TeX{} ait à lire le code suivant :

\centrecodespc-\hbox{Et $x$ vaut  3,5.}-

\noindent Au fur et à mesure de sa lecture, il attribuera à chaque caractère le code de catégorie en vigueur au moment où il le lit et agira en conséquence. Ce code de catégorie est attribué de façon \emph{définitive} et ne peut pas être changé ensuite ; il s'agit d'un mécanisme incontournable sur lequel il faut insister :

\label{catcode.inalterable}\begin{regle}
	Dès que \TeX{} lit un caractère, il lui affecte de façon inaltérable un \idx*{catcode}code de catégorie.
\end{regle}

Si lors de la lecture, les catcodes en vigueur sont ceux exposés dans le tableau ci-dessus, voici sous chaque caractère, le catcode qui lui sera affecté :

\def\falsespcverb{\leavevmode\vrule width0.2pt height .5ex depth 0pt
	\vrule width.75em height0.4pt depth 0pt
	\vrule width0.2pt height .5ex depth 0pt }
\begingroup
	\hfill
	\def~#1#2{%
		\hbox{%
			\footnotesize
			\vtop{\offinterlineskip\hbox to1em{\hss\ttfamily\strut#1\hss}\hbox to1em{\hss\tiny#2\hss}}%
		}%
	}
	~\textbackslash0~h{11}~b{11}~o{11}~x{11}%
	~\{1~E{11}~t{11}~\falsespcverb{10}~{\string$}{3}~x{11}%
	~{\string$}{3}~\falsespcverb{10}~v{11}~a{11}%
	~u{11}~t{11}~\falsespcverb{10}~3{12}~,{12}~5{12}~.{12}%
	~\}2\hfill\null
\endgroup
\grandsaut

Un caractère peut être tapé sous forme habituelle comme lorsqu'on tape un «\verb-a-», mais on peut aussi utiliser «\verbidx[|(]{^^}». En effet, si \TeX{} voit deux caractères \emph{identiques} dont le code de catégorie est \number\catcode`\^{} (celui du caractère de mise en exposant) et si ces deux caractères sont suivis d'un caractère dont le code --~appelons-le $c$~-- est compris entre 0 et 63 inclus, alors \TeX{} lit le tout comme étant le caractère dont le code est $c+64$. Par exemple, «\verb-^^:-» est le caractère «^^:». Il est rigoureusement équivalent de taper «^^:» ou «\verb-^^:-» et ce, quel que soit l'endroit où l'on se trouve dans le code source.

Symétriquement, si le code de caractère $c$ est compris entre 64 et 127 inclus, \TeX{} remplace le tout par le caractère de code $c-64$. Et donc, il est équivalent de taper «\verb-^^z-» ou «\string^^z».

Ce qui est écrit dans les deux paragraphes précédents nous conduit donc à cette règle :

\begin{regle}
Lorsqu'on écrit «\verb-^^<car>-» dans le code source, tout se passe donc comme si \TeX{} voyait le caractère se trouvant 4 lignes plus haut ou plus bas dans la table ASCII, selon que \verb-<car>- se trouve dans la partie basse ou haute de cette table.

Si les \emph{deux} caractères qui suivent \verb-^^- forment un nombre hexadécimal à deux chiffres minuscules pris parmi «\verb-0123456789abcdef-», alors \TeX{} remplace ces 4 caractères par le caractère ayant le code hexadécimal spécifié. Avec cette méthode, on peut donc facilement accéder à n'importe quel caractère. Le caractère «z» peut aussi s'écrire «\verb-^^7a-».
\end{regle}

Ainsi, le caractère «t» étant apparié via \verb-^^- avec un caractère affichable (en l'occurrence «4» qui se trouve 4 lignes plus haut dans la table ASCII), «t» peut donc être tapé dans le code de 3 façons équivalentes : «\verb-t-» ou «\verb-^^4-» ou «\verb-^^74-». Si l'on voulait rendre le code mystérieux ou difficilement lisible, voici comment on pourrait écrire le mot «tex» :
\begin{itemize}
	\item \verb-^^4^^%^^8-
	\item \verb-^^74^^65^^78-
\end{itemize}

La seule petite ambigüité qui subsiste dans cette belle mécanique est que l'on ne peut pas écrire un «t» sous la forme «\verb|^^4|» puis le faire suivre du caractère «5». En effet, cela formerait la suite de caractères «\verb|^^45|» que \TeX{} interprèterait comme étant le caractère de code hexadécimal \Hex{45} qui est «E»\verbidx*[|)]{^^}.

Au-delà de l'originalité de cette méthode alternative pour écrire des caractères dans le code source, ce qu'il faut en retenir est qu'elle peut être très utile pour écrire des caractères non affichables qui de toute façon, seraient difficilement accessibles au clavier. Ainsi, le caractère de tabulation {\carnonaff HT} s'écrit «\verbidx[ (tabulation)]{^^I}», le retour charriot {\carnonaff CR} «\verbidx[ (retour charriot)]{^^M}», etc.
\grandsaut

On peut aussi \emph{afficher} un caractère avec la primitive \idx\char suivie du numéro du code de caractère. Ainsi, \verb|\char97| affiche un «\char97» mais au contraire de la méthode avec \verb|^^|, \verb|\char97| ne peut pas être utilisé dans le code source à la place d'une lettre. Autant «\verb|\p^^61r|» et «\verb|\par|» sont équivalents, autant il n'est pas question d'écrire «\verb|\p\char65r|» à la place de \verb|\par| dans le code source, car ceci serait interprété comme la commande \verb|\p|, suivie de \verb|\char65|, suivi de «r».
\grandsaut

Enfin, il faut définir ce qu'est une «ligne de code source». Pour \TeX{}, une ligne de code est constituée par les caractères qui se trouvent avant la prochaine « marque de \idx{fin de ligne} »\label{marque.fin.ligne}. Cette marque est une convention qui dépend du système d'exploitation :

\begin{itemize}
	\item pour Windows, une marque de fin de ligne est constituée des octets \Hex{0D}\Hex{0A}, c'est-à-dire de {\carnonaff CR} suivi de {\carnonaff LF} (noté «CRLF»);
	\item pour GNU-linux, cette marque est l'octet \Hex{0A} (LF);
	\item enfin, pour MAC OS X, cette marque est l'octet \Hex{0D} (CR).
\end{itemize}

L'exécutable \texttt{pdftex} considère comme marque de fin de ligne les séquences suivantes : LF, CR, CRLF et LFCR. Les \idx[!fin de ligne]{espace}s qui précèdent la marque de \idx{fin de ligne} sont supprimés en même temps que cette marque et \TeX{} insère à la place un caractère spécial dont le code de caractère est contenu dans la primitive \idx\endlinechar. Habituellement, ce code vaut \number`\^^M{}, celui du caractère retour charriot\verbidx*[ (retour charriot)]{^^M}.

\label{catcode.5}
\begin{regle}
Dans la ligne courante, si un caractère de catcode \number\catcode`\%\relax{} (caractère de commentaire, généralement \cidx[ (caractère de commentaire)]\%) ou \number\catcode`\^^M\relax{} (retour charriot, généralement \verb|^^M|\verbidx*[ (retour charriot)]{^^M}) apparait, alors, ce caractère ainsi que tout ce qui va jusqu'à la fin de la ligne est ignoré, y compris le caractère de code \idx\endlinechar inséré à la fin de la ligne.
\end{regle}

Les caractères de catcode 5 obéissent à une règle particulière :

\label{regle.catcode5}\begin{regle}
Un caractère de catcode 5 est interprété comme un \idx[!catcode 5]{espace}.\idx*{catcode!5 (retour charriot)}\idx*{espace!catcode 5}

Deux caractères de catcode 5 consécutifs sont transformés en la séquence de contrôle \idx\par\verbidx*[ consécutifs]{^^M}.
\medbreak

Cela signifie qu'un retour charriot\verbidx*[ (retour charriot)]{^^M} est vu comme un \idx[!fin de ligne]{espace}, sauf s'il est précédé du caractère \cidx\% et que deux retours charriots consécutifs (symbolisés dans le code source par une ligne vide) seront équivalents à \idx\par.
\end{regle}

On peut localement modifier le caractère de code \idx\endlinechar pour obtenir des effets spéciaux en tenant compte de la règle suivante :

\begin{regle}
Si \idx\endlinechar est négatif ou supérieur à 255, aucun caractère n'est inséré aux fins de lignes.
\end{regle}

Voici une illustration de cette règle où l'on teste le comportement normal, puis on met \idx\endlinechar à $-1$ et enfin à \number`\X{} (qui est le code de caractère de «X») :

{\endlinechar13
\showcode|%%% comportement normal %%%
a) comportement normal :
Ligne 1
Ligne 2

Ligne 3
\medbreak¤\idx*\medbreak¤
b) Aucun caractère de fin de ligne :¤\idx*{caractère de fin de ligne}¤
%%% aucune insertion en fin de ligne %%%
\endlinechar=-1 ¤\idx*\endlinechar¤
Ligne 1
Ligne 2

Ligne 3\endlinechar13

\medbreak¤\idx*\medbreak¤
c) "X" comme caractère de fin de ligne :¤\idx*{caractère de fin de ligne}¤
%%% "X" est inséré à chaque fin de ligne
\endlinechar=88
Ligne 1
Ligne 2

Ligne 3|}

On peut notamment remarquer que lorsque \idx\endlinechar est négatif, tout se passe comme si les lignes se terminaient toutes par le \idx[|voir{«\texttt{\char37}»}]{caractère de commentaire} \cidx\%, de catcode \number\catcode`\%.

\chapter{Octets dont le bit de poids fort est 1}
Venons-en maintenant à la partie de la table des caractères qui se situe après le numéro 128, c'est-à-dire dont la représentation en base 2 est \bin{1xxxxxxx} et dont le bit le le plus à gauche, celui qui a le plus de «poids\footnote{Dans l'écriture moderne des nombres, dite «de position», les chiffres ont une influence liée à leur position dans le nombre. En écriture décimale, nous avons pris comme convention qu'un nombre, par exemple écrit avec 3 chiffres «$\overline{\text{\textit{abc}}}$», est égal à la somme $a\times100+b\times10+c\times1$. Le coefficient d'un chiffre (ou son «poids») est une puissance de 10 dont l'exposant est d'autant plus grand que la place du chiffre est à gauche : $10^2$, $10^1$ et $10^0$. On dit que le chiffre $a$ a un «poids» fort puisque plus important que celui des chiffres $b$ ou $c$.

En binaire, c'est le même principe sauf que les poids sont les puissances de 2. Si un \idx{octet} s'écrit $\overline{\text{\textit{abcdefgh}}}$, sa valeur en base 10 est $a\times2^7+b\times2^6+\cdots+g\times2^1+h\times2^0$. Le bit \bin{a} est le bit de poids fort tandis que \bin{h} est celui de poids faible.}», vaut 1. Cette partie de la table n'est pas dans la convention ASCII et donc, dépend de la convention que l'on veut se donner. Pour nous en France, deux de ces conventions sont utilisées et dépendent du codage avec lequel a été enregistré le code source. Comme on l'a dit, cet \idx{encodage} doit être un surensemble de l'ASCII qui est commun à tous les \idx{encodage}s.

Historiquement, plusieurs façons de compléter la table ASCII ont vu le jour, chacune donnant naissance à un \idx{encodage} à part entière. Aucune harmonisation n'a jamais été faite et plusieurs \idx{encodage}s sur 8 bits cohabitent encore à l'heure actuelle. Les plus connus pour les langues occidentales sont :

\begin{itemize}
	\item \texttt{ansinew} a émergé comme \idx{encodage} des systèmes d'exploitation Windows;
	\item \texttt{applemac} a été choisi dans la sphère de la marque Apple jusqu'à un passé récent;
	\item \texttt{latin1}\idx*[|(]{encodage!latin1} a été utilisé dans le monde Unix/Linux.
\end{itemize}

Selon ces trois encodages, le caractère «é» est respectivement placé à l'octet \Hex{E9}, \Hex{8E} et \Hex{E9}.
\grandsaut

Intéressons-nous à l'\idx{encodage} «\latin» ou «\hbox{ISO 8859-1}»\idx*{encodage!latin1}. Cet \idx{encodage} a été créé pour être utilisé avec les langues européennes. Par exemple, l'octet \number"E0{} (ou \Hex{E0} en hexadécimal) code la lettre «à». On dispose ainsi de tous les caractères nécessaires pour la langue française\footnote{À l'exception notable de «\oe », «\OE » et «\"Y». Il manque également quelques caractères pour d'autres langues.}. Il faut noter que l'extension pour \LaTeX{} «\verb-inputenc-»\idx*{package!inputenc} chargée avec l'option «\verb-latin1-» rend plusieurs caractères actifs (et donc met leur catcode à 13) lorsque l'\idx{encodage} est \latin\idx*{encodage!latin1}. Le caractère «à» en fait partie et donc, ce caractère se comporte comme une commande : \verb-inputenc- lui fait exécuter un code qui au final, imprime le caractère «à». Il est immédiat que du fait qu'il est actif, le caractère «à» n'appartient pas à la catégorie des lettres.

Voici la table de l'\idx{encodage} \latin. Seuls les \idx{octet}s supérieurs ou égaux à 128 y figurent puisque ceux qui sont inférieurs à 128 sont ceux de la table ASCII :

\begin{centrage}
	\catcode`\µ=12
	\tabcolsep0pt
	\footnotesize
	\par\noindent
	\def\?#1{\ttfamily\bfseries x#1}%
	\charcnt=\numexpr128-17
	\def\:{\global\advance\charcnt1 }%
	\def\!{\cellcolor{gray!40}}%
	\let\^\carnonaff% marque un caractère non affichable
	\newcolumntype G{m{\dimexpr(\linewidth-18\arrayrulewidth)/17\relax}}%
	\begin{tabular}{|@{}>{\columncolor{gray!40}[0pt][0pt]\hfill\ttfamily\bfseries}G<{x\hfill\null}@{}|*{16}{@{}>{\:\hfill\vrule height3.3ex depth.8ex width0pt }G<{\hfill\unless\ifnum\charcnt<128 \vtop{\kern1.5pt\normalfont\tiny\llap{\number\charcnt\kern.5pt}\kern1pt}\fi\null}@{}|}}
	\hline
		\rowcolor{gray!40}[0pt][0pt]\multicolumn1{|@{}G@{}|}{\cellcolor{white}}
		&\?0 &\?1 &\?2 &\?3 &\?4 &\?5 &\?6 &\?7 &\?8 &\?9 & \?A& \?B&\?C &\?D &\?E &\?F \\\hline
		8 & \^PAD& \^HOP&\^BPH &\^NBH &\^IND &\^NEL &\^SSA &\^ESA &\^HTS &\^HTJ &\^VTS &\^PLD &\^PLU &\^RI  &\^SS2 &\^SS3 \\\hline
		9 & \^DCS& \^PU1& \^PU2& \^STS& \^CCH& \^MW &\^SPA& \^EPA& \^SOS& \^SGCI& \^SCI&\^CSI &\^ST  &\^OSC &\^PM & \^APC\\\hline
		A &\scalebox{0.8}[1]{NBSP}&^^a1&^^a2&^^a3&^^a4&^^a5&^^a6&\oldparagraph&^^a8&^^a9&^^aa&^^ab&\!$^^ac$&-&^^ae&^^af \\\hline
		B &^^b0&\!$^^b1$&\!$^^b2$&\!$^^b3$&^^b4&\!$^^b5$&$^^b6$&^^b7&^^b8&\!$^^b9$&^^ba&^^bb&^^bc&^^bd&^^be&^^bf\\\hline
		C &^^c0&^^c1&^^c2&^^c3&^^c4&^^c5&^^c6&^^c7&^^c8&^^c9&^^ca&^^cb&^^cc&^^cd&^^ce&^^cf\\\hline
		D &^^d0&^^d1&^^d2&^^d3&^^d4&^^d5&^^d6&\!$^^d7$&^^d8&^^d9&^^da&^^db&^^dc&^^dd&^^de&^^df\\\hline
		E &^^e0&^^e1&^^e2&^^e3&^^e4&^^e5&^^e6&^^e7&^^e8&^^e9&^^ea&^^eb&^^ec&^^ed&^^ee&^^ef\\\hline
		F &^^f0&^^f1&^^f2&^^f3&^^f4&^^f5&^^f6&\!$^^f7$&^^f8&^^f9&^^fa&^^fb&^^fc&^^fd&^^fe&^^ff\\\hline
	\end{tabular}
\end{centrage}
\grandsaut

Ici encore, cette partie de la table comporte des caractères non affichables. Ils se situent entre les codes \Hex{80} et \Hex{9F} inclus auxquels il faut rajouter le caractère de code \Hex{AD}. Ceux qui se trouvent dans des cases grisées sont affichables, mais ils doivent être utilisés en mode mathématique\idx*{mode!mathématique}.
\grandsaut

Bien sûr, certains de ces caractères ne sont pas directement accessibles au clavier. En fait, les caractères accessibles au clavier dépendent de la configuration de chacun. Par exemple, sur \emph{mon} clavier, avec \emph{mon} système d'exploitation et le pilote correspondant au modèle du clavier, avec le mappage du clavier sélectionné dans les options du système d'exploitation, je peux accéder au caractère «\textttæ» avec la combinaison de touches \bioLegacyKeyGlyph{A_l_t_G_r}+\bioLegacyKeyGlyph{A}. Pour le caractère «$¶$», c'est avec \bioLegacyKeyGlyph{A_l_t_G_r}+\bioLegacyKeyGlyph{R}. Et ainsi de suite\ldots{} En revanche, certains caractères dans la table ci-dessus me sont inaccessibles, sauf à les taper via \verb-^^-.
\grandsaut

L'\idx{encodage} «\utf\idx*[|(]{encodage!UTF8}\footnote{L'acronyme \texttt{UTF8} signifie «Unicode Transformation Format 8 bits».}» permet de coder beaucoup plus que 256 caractères avec l'inévitable conséquence que certains d'entre eux seront codés sur plusieurs octets. Le principe de cet \idx{encodage} est assez simple et on peut le décrire ici :
\begin{itemize}
	\item si un caractère a un code inférieur à 128, alors il est codé par le même \idx{octet} que dans le \idx{encodage} ASCII;
	\item sinon, il est codé sur plusieurs octets : le nombre de bits de poids fort non nuls (au maximum 4) du premier octet indique le nombre d'octets pris au total pour l'\idx{encodage} du caractère. Par exemple, si un \idx{octet} vaut \bin{1110xxxx} en binaire, les 3 bits de poids fort suivis d'un 0 indiquent que ce caractère est codé sur 3 octets, les 2 octets restants ayant obligatoirement les bits de poids fort \bin{10}, c'est-à-dire qu'ils sont de la forme \bin{10xxxxxx}.
	
	Finalement, ce caractère sera donc codé sur 3 octets ayant cette forme : \bin{1110xxxx 10xxxxxx 10xxxxxx}. Il y a donc 16 bits non contraints sur 24. Le «code propre» du caractère sera constitué des 16 bits \bin x.
\end{itemize}

Si l'on s'intéresse par exemple au caractère «à», celui-ci est codé en \utf par les 2 octets \Hex{C3} \Hex{A0}. Écrits en binaire, on obtient \bin{\textbf{110}00011} \bin{\textbf{10}100000} où les bits contraints sont écrits en gras. Il en résulte que le code propre du caractère «à» est \bin{00011100000}. Si on élimine les zéros inutiles de gauche, on obtient \bin{11100000} qui est l'\idx{octet} \Hex{E0}, celui que l'on retrouve dans la table de l'\idx{encodage} \latin pour la lettre «à». En effet, en \utf, les caractères ayant des codes propres compris entre 128 et 255 \emph{doivent} être les mêmes que les caractères qui ont ces codes dans la table de \latin. Enfin, le symbole «\geneuro» est codé sur 3 \idx{octet}s en UFT8 : \Hex{E2} \Hex{82} \Hex{AC} qui s'écrit en binaire \bin{\textbf{1110}0010} \bin{\textbf{10}000010} \bin{\textbf{10}101100} et qui donne un code propre de \bin{10000010101100} soit \Hex{20AC}.

Pour \TeX{}, le principe est le même qu'avec l'\idx{encodage} \latin, il faut rendre actifs tous les \idx{octet}s qui ont une écriture binaire \bin{110xxxxx} ou \bin{1110xxxx}  ou \bin{11110xxx} et dont les bits non contraints «\bin x» correspondent au début du code des caractères que \TeX{} va prendre en charge. Ensuite, ces caractères actifs vont lire le (ou les) \idx{octet}(s) suivant(s) et traduire le tout de façon à faire imprimer le caractère voulu.
\grandsaut

Ce qu'il faut retenir est que, aussi bien en \latin qu'en \utf, les lettres accentuées et les caractères ne figurant pas dans la table ASCII ne sont pas des octets dont le code de catégorie est 11 et n'appartiennent donc pas à la catégorie des lettres. De plus, pour ceux qui utilisent l'\idx{encodage} \utf qui tend à devenir la norme, il ne faut pas perdre de vue que lorsqu'on écrit la lettre «à» dans le code, nous ne voyons qu'un seul caractère, mais celui-ci est stocké sur \emph{deux} octets dans le fichier et donc, \TeX{} voit \emph{deux} choses. Il n'y a donc pas équivalence entre «octet» et «caractère» et dans tous les cas, \TeX{} ne lit pas le code caractère par caractère, mais octet par octet.

Cette dernière affirmation n'est vraie que pour les trois moteurs \TeX{} (celui écrit par \idx*{Knuth Donald}Donald~\textsc{Knuth}), $\varepsilon$\TeX{}\idx*{moteur!etex} et pdf\TeX{}\idx*{moteur!pdftex}. Outre ces « ancêtres », encore majoritairement utilisés malgré leur âge, il existe désormais des moteurs plus récents qui gèrent nativement l'\idx{encodage} \utf : \XeTeX{} et lua\TeX{}. Ces deux moteurs, entre autres possibilités, lisent le code source caractère \utf par caractère \utf et il peut donc arriver que plusieurs octets soient lus en un coup pour former une entité unique. Malgré le progrès que cela constitue, on considèrera dans ce livre que l'on utilise un moteur fonctionnant octet par \idx{octet}.\idx*[|)]{encodage!UTF8}\idx*[|)]{encodage!latin1}

\chapter{Codes de catégorie}\idx*[|(]{catcode}\idx*[|(]{\catcode}
Le sujet est vaste et technique puisqu'il touche à l'un des mécanismes les plus intimes de \TeX. Nous nous contenterons pour l'instant de voir l'essentiel, quitte à y revenir plus loin au fur et à mesure de nos besoins. Rappelons que les «catégories» de \TeX{} sont au nombre de 16 et regroupent des caractères ayant des propriétés communes aux yeux de \TeX{}. Le code de catégorie d'un octet lu est la première chose que \TeX{} examine, avant même le nombre correspondant à l'octet lui-même puisque le code de catégorie détermine la façon dont \TeX{} doit réagir face à cet \idx{octet}.
\grandsaut

Tout d'abord, pour accéder au code de catégorie d'un caractère, il faut utiliser la primitive \idx\catcode suivie du \emph{\idx{code de caractère}}. L'ensemble constitue une représentation interne de l'entier étant le code de catégorie du caractère concerné. La commande \idx\number\label{number} convertit la représentation interne d'un nombre en la représentation affichable habituelle, c'est-à-dire en base 10 et en chiffres arabes. Par exemple, si on veut afficher le code de catégorie de «\cidx\$» dont le code de caractère est \number`\$, on va écrire «\verb-\number\catcode36-» et on obtiendra «\number\catcode36 ».

On peut trouver gênant de mettre explicitement le code du caractère après la primitive \idx\catcode. En effet, cela oblige à aller le chercher dans la table des caractères ASCII puis le convertir en décimal. Cette dernière étape, la conversion hexadécimal vers décimal, n'a pas lieu d'être faite car \TeX{} comprend nativement les nombres hexadécimaux\footnote{Où les lettres qui le composent \emph{doivent} être majuscules.}. Pour indiquer qu'un nombre est écrit en base 16, il faut le faire précéder du caractère «\cidx[ (notation hexadécimale)]\"» et pour traduire le tout en nombre en écriture arabe en base 10, il faut mettre devant l'ensemble la primitive \idx\number{}:

\showcode/a) \number"1A \qquad b) \number"AB3FE \qquad c) \number"78 ¤\idx*\number\idx*\qquad¤/

Pour obtenir le code de catégorie du caractère «\cidx\$» dont le code de caractère est \Hex{24}, on peut donc écrire \verb-\number\catcode"24-.

Dans le même ordre d'idée et bien que cela soit assez rarement utile, il faut savoir que \TeX{} comprend aussi les nombres en notation \emph{octale}, c'est-à-dire écrits en base 8. Pour indiquer qu'un nombre est écrit en base 8, il faut le faire précéder de l'apostrophe «\cidx[ (notation octale)]\'» :

\showcode/a) \number'15 \qquad b) \number'674 \qquad c) \number'46¤\idx*\number\idx*\qquad¤/

Malgré ce côté pratique, il faut toujours aller voir la table ASCII pour chercher le code de caractère. Heureusement, on peut facilement convertir un caractère en son code écrit en base 10. Pour cela, s'agissant des caractères de catcode 11\idx*{catcode!11 (lettre)} ou 12\idx*{catcode!12 (autre)}, il faut faire précéder le caractère de l'apostrophe inverse \boxtoken{`}\cidx*[ (notation de nombre)]{\`} ce qui donnerait «\verb-\number`a-» pour afficher le code de caractère de «a». Un moyen encore plus sûr qui fonctionne pour \emph{tous} les caractères, quels que soient leurs catcodes, est de faire précéder le caractère de l'apostrophe inverse \emph{et} du caractère d'échappement comme dans cet exemple:

\showcode/a) \number`\a \quad %code de caractère de "a"¤\idx*\number\idx*\quad¤
b) \number`\\ \quad % code de caractère de "\"
c) \number`\$ \quad % code de caractère de "$"
d) \number`\  \quad % code de caractère de l'espace
e) \number`\5 \quad % code de caractère de "5"
f) \number`\{ \quad % code de caractère de l'accolade ouvrante
g) \number`\}       % code de caractère de accolade fermante/

Il devient facile d'afficher le code de catégorie de n'importe quel caractère :

\showcode/a) \number\catcode`\a \quad %code de catégorie de "a"¤\idx*\catcode¤
b) \number\catcode`\\ \quad % code de catégorie de "\"¤\idx*\number¤
c) \number\catcode`\$ \quad % code de catégorie de "$"
d) \number\catcode`\  \quad % code de catégorie de l'espace
e) \number\catcode`\5 \quad % code de catégorie de "5"
f) \number\catcode`\{ \quad % code de catégorie de l'accolade ouvrante¤\idx*\quad¤
g) \number\catcode`\}       % code de catégorie de accolade fermante/

Afficher un code de catégorie n'est pas réellement utile. Ce qui l'est plus est de \emph{modifier} le code de catégorie d'un caractère, nous verrons dans quels buts plus loin. Pour ce faire, on écrit\idx*{\catcode} :
\centrecode-\catcode`\<caractère>=<nombre>-

\noindent où \verb-<nombre>- est un entier de 0 à 15. Après que \TeX{} a exécuté ce code, à chaque fois que \TeX{} lira le \verb-<caractère>-, il lui assignera le code de catégorie égal au \verb-<nombre>-. Supposons par exemple que nous souhaitions que le caractère «\verb|W|» ne soit plus dans la catégorie des lettres, mais revête le code de catégorie de 3 pour utiliser indifféremment «\verb|W|» ou «\cidx\$» pour basculer en mode mathématique\idx*{mode!mathématique}. Voici comment procéder :

\showcode/Ici, W est une lettre...\par
\catcode`\W=3 % W devient le signe de bascule en mode math¤\idx*\catcode\idx*{mode!mathématique}¤
Wx+y=3W\par
$a+b=cW\par
W2^3=8$\par
\catcode`\W=11 % W redevient une lettre¤\idx*\catcode¤
De nouveau, W est une lettre.../

Il est important de restaurer le code de catégorie initial à la fin de la zone où l'on souhaite avoir le comportement voulu sous peine de s'exposer à des erreurs de compilation ou des effets indésirables plus tard.

Symétriquement, on aurait aussi bien pu assigner le code de catégorie 11 (ou 12) au caractère «\verb-$-» de façon à pouvoir l'afficher comme on le fait d'une lettre ou d'un caractère affichable :
\showcode/$3+4=7$ \par % $ est la bascule math
\catcode`\$=12 % $ devient un caractère affichable¤\idx*\catcode¤
$ s'affiche sans problème : $\par
\catcode`\$=3 % $ redevient la bascule math¤\idx*\catcode¤
$4+3=7$/

\begin{exercice}
Inventer un procédé pour que, dans une zone, seuls les premiers mots de chaque ligne soient affichés.
\solution
Il suffit de modifier le code de catégorie de l'\idx[!catcode 5]{espace} pour qu'il devienne 5. D'après la règle vue à la page~\pageref{catcode.5}, dans une ligne, tout ce qui se trouve après un caractère de catcode 5\idx*{catcode!5 (retour charriot)} est ignoré :

\showcode|Voici les premiers mots de chaque ligne :

\catcode`\ =5 % l'espace est déormais de catcode 5¤\idx*\catcode¤
Cette première ligne sera tronquée...

La deuxième aussi !

Et la dernière également.
\catcode`\ =10 % l'espace reprend son catcode¤\idx*\catcode¤

Le comportement normal est restauré.|
\end{exercice}

Il faut retenir que les codes de catégorie attachés à chaque caractère de la table des catcodes de la page~\pageref{catcode.table} ne sont que des valeurs \emph{par défaut} qui peuvent être facilement modifiées comme on l'a vu dans les exemples précédents. On peut donc parler de «régime de catcode», c'est-à-dire qu'à chaque moment, chacun des 256 octets aura un catcode qui lui sera attribué. En règle générale, si l'on modifie le catcode d'un octet, il est sage de restaurer les codes de catégorie de la table des catcodes au-delà de la zone où l'on veut faire des modifications. En effet, il est admis que les catcodes «naturels» de cette table doivent rester la règle.\idx*[|)]{catcode}\idx*[|)]{\catcode}
%|                                                                            |
%|                                Fin partie 1                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Partie 2                                  |
%|                                                                            |
\defpartcomment{\lettrine[lines=3,nindent=0pt]{\libertineInitialGlyph{D}}{ans} cette partie, nous allons nous intéresser à ce qui fait l'essentiel du code lorsqu'on programme, les commandes. Contrairement à d'autres langages de programmation où leur comportement est assez intuitif, elles revêtent avec \TeX{} des propriétés originales. Par leur intermédiaire, nous découvrirons l'essentiel de ce qu'il faut savoir pour commencer à programmer c'est-à-dire la façon intrinsèque qu'a \TeX{} de fonctionner et comment contrôler ce fonctionnement. Après ces prérequis, nous pourrons alors aborder la partie suivante où nous commencerons les premiers exercices de programmation.}
\part{Commandes}

\chapter[\Qu 'est-ce qu'une commande ?]{Qu'est-ce qu'une commande ?}
Lorsqu'on utilise \TeX{}, les séquences de contrôle\idx*{séquence de contrôle} sont des mots constitués de lettres (caractères de catcode 11) qui débutent par le \idx{caractère d'échappement} «\cidx[ (caractère d'échappement)]\\». Ce caractère spécial peut être changé pour en utiliser un autre, mais cette man\-\oe uvre ne sera pas décrite pour l'instant. Ainsi, lorsque \TeX{} lit le code que l'on a tapé, toujours linéairement de gauche à droite, forme une \idx{séquence de contrôle} à l'aide des lettres, majuscules ou minuscules, qui suivent le caractère d'échappement «\cidx\\», la casse étant prise en compte. \TeX{} considère que le nom de la \idx{séquence de contrôle} se termine au dernier caractère qui est une lettre . Une fois que ce nom est construit, il devient une entité unitaire indivisible, une «unité lexicale» ou «\emph{\idx{token}}» au même titre qu'un \idx{octet} dans le code si celui-ci ne sert pas à écrire une \idx{séquence de contrôle}.

\begin{regle}
Une \idx{séquence de contrôle} commence par le caractère d'échappement de catcode 0\idx*{catcode!0 (caractère d'échappement)} qui est habituellement «\cidx\\» et se termine à la fin de la plus longue série de lettres (caractères de catcode 11\idx*{catcode!11 (lettre)}) qui le suit.
\end{regle}

Les séquences de contrôle sont de deux types :
\begin{itemize}
	\item les «commandes», que l'on appellera aussi «macros», ont été définies soit par l'utilisateur, par un format ou par une extension. Ces commandes ont un \idx{texte de remplacement}, c'est le code \TeX{} qui les définit, ou si l'on préfère, le code \TeX{} qu'elles «contiennent». Ce texte de remplacement peut évidemment contenir d'autres séquences de contrôle ;
	\item les \idx{primitive}s, qui sont codées en dur dans le programme binaire \texttt{tex}, et qui représentent en fait le «vocabulaire» de base avec lequel on doit se débrouiller pour faire tout le reste. Les primitives n'ont pas de \idx{texte de remplacement} et sont destinées à être exécutées de façon binaire par le programme \texttt{tex}.
\end{itemize}

\label{regle.espace}\begin{regle}
Voici des règles concernant les espaces et les séquences de contrôle :
	\begin{enumerate}
		\item dans le code qui est tapé, tout \idx{espace} qui suit une unité lexicale de type \idx{séquence de contrôle} est ignoré;
		\item si plusieurs espaces \idx*{espace!consécutifs}se suivent \emph{dans le code}, seul le premier est pris en compte et les autres sont ignorés (ceci est un rappel de la règle page~\pageref{espaces.consecutifs});
		\item il découle des deux premiers points que, quel que soit le nombre d'espaces qui suivent une \idx{séquence de contrôle}, ceux-ci sont ignorés.
	\end{enumerate}
\end{regle}

Lorsqu'un utilisateur définit une commande, il lui donne un \emph{\idx{texte de remplacement}} qui sera utilisé à la place de cette commande lorsqu'elle sera « exécutée » par \TeX{}. La primitive qui permet de définir ce texte de remplacement est «\idx[|(]\def». Elle doit être suivie du nom de la commande et du texte de remplacement entre \idx{accolade}s :

\centrecode-\def\foo{Bonjour}-

Après cette définition, à chaque fois que \TeX{} «exécutera» le token \verb|\foo| dans le code source, il le remplacera dans sa mémoire par son texte de remplacement qui est «Bonjour» et continuera à lire le code obtenu en tenant compte de ce remplacement. Cet endroit dans sa mémoire s'appelle «\idx{pile d'entrée}». Pour écrire un espace après \verb-\foo- qui ne soit pas ignoré, il faut trouver un moyen, invisible à l'affichage, pour que l'espace affiché après la macro ne lui soit pas consécutif. On peut envelopper la macro dans des accolades ou la faire suivre de \verb-{}-\cidx*\{\cidx*\} de façon à ce que l'espace se situant \emph{après} l'accolade fermante ne soit pas ignoré comme il le serait après une \idx{séquence de contrôle}. On peut également mettre après \verb|\foo| la macro \idx\space dont le \idx{texte de remplacement} est un espace. Dans ce cas, le dernier point de la règle précédente ne s'applique pas, car ce qui suit \verb|\foo| n'est pas un espace mais une \idx{séquence de contrôle}, et peu importe son texte de remplacement.

\showcode/\def\foo{Bonjour}% définit le texte de remplacement de \foo
a) \foo Alice.\qquad% espace ignoré¤\idx*\qquad¤
b) {\foo} Bob.\qquad% espace non ignoré
c) \foo{} Chris.\qquad% espace non ignoré
d) \foo\space Daniel.% \space est remplacé par un espace¤\idx*\space¤/

\begin{regle}
Lorsque \TeX{} assigne un \idx{texte de remplacement} à une macro avec \idx\def, ce texte de remplacement n'est pas exécuté, il est juste converti en \idx{token}s et rangé quelque part dans la mémoire de \TeX{} pour être ressorti plus tard pour venir en replacement de la macro, et éventuellement être exécuté à ce moment.

Le texte de remplacement est très peu \emph{analysé} lorsqu'il est stocké avec \verb|\def|, ce qui veut dire que si une erreur est contenue dans le texte de remplacement, elle ne sera pas détectée au moment où \idx\def agit mais plus tard lors du remplacement et de l'exécution proprement dite.

Une des rares choses que \TeX{} vérifie dans le \idx{texte de remplacement} d'une macro est qu'un caractère de \idx*[!15 (invalide)]{\catcode}catcode 15\idx*{catcode!15 (invalide)} n'y figure pas (nous verrons plus loin les autres vérifications que \TeX{} effectue).
\end{regle}

\section{Accolades et groupes}
Les \cidx*\{\cidx*\{\idx{accolade}s des lignes 3 et 4 délimitent des «\idx[|(]{groupe}s\footnote{On dit aussi parfois «\idx[!simple]{groupe} simple».}». Un groupe est une zone où les modifications effectuées et où les définitions faites restent \emph{locales} à ce groupe et sont détruites lors de sa fermeture pour revenir à l'état antérieur à l'ouverture du groupe. En revanche, les \idx{accolade}s obligatoires utilisées avec la primitive \idx\def de la ligne 1 ne délimitent pas un groupe. Elles délimitent la portée du \idx{texte de remplacement}. On peut donc considérer qu'il y a deux types d'\idx{accolade}s. D'une part celles qui sont obligatoires et font partie de la syntaxe d'une primitive comme celles de la primitive \idx\def qui délimitent le \idx{texte de remplacement} et d'autre part celles, non obligatoires, qui servent de frontières à un groupe.

Un \idx[!semi-simple]{groupe} semi-simple\footnote{Le nom « groupe simple » étant déjà pris pour les groupes entre accolades, il y a fort à parier que D.~\textsc{Knuth}, par jeu et par affinité pour les mathématiques, ait baptisé « groupe semi-simple» un groupe délimité par \texttt{\textbackslash begingroup} et \texttt{\textbackslash endgroup}.} est compris entre les instants où \TeX{} exécute les primitives \idx\begingroup et \idx\endgroup. Comme dans les groupes, les modifications et les définitions dans un groupe semi-simple sont locales et sont restaurées à leur état antérieur à sa fermeture.

\begin{regle}
On peut créer des zones où les modifications faites aux macros et autres paramètres de \TeX{} sont locales. Ces zones portent le nom de \idx{groupe}s.

Un \idx{groupe} est délimité :
\begin{itemize}
	\item soit par une \idx{accolade} ouvrante et une accolade fermante auquel cas le groupe est qualifié de « simple » ;
	\item soit par les primitives \idx\begingroup et \idx\endgroup et dans ce cas, le groupe est dit « semi-simple».
\end{itemize}
Il est entendu qu'un groupe ouvert avec une accolade ne peut être fermé qu'avec une accolade et il en est de même avec \idx\begingroup et \idx\endgroup.

À l'intérieur d'un groupe, les assignations sont locales à ce groupe et sont restaurées à leur état antérieur lors de la fermeture du groupe. Pour qu'une assignation soit \emph{globale}, c'est-à-dire pour qu'elle survive à la fermeture du groupe, il faut faire précéder la commande d'assignation de la primitive \idx\global.

Les groupes délimités par accolades et les groupes semi-simples peuvent être emboités, mais \emph{ne doivent pas} se chevaucher.
\end{regle}

\begin{exercice}
Puisqu'un groupe délimité par accolades et un groupe semi-simple ont les mêmes fonctionnalités, pourquoi existe-t-il deux façons différentes de délimiter un groupe ?
\solution
Tout d'abord, abondance de biens ne nuit pas !

Ensuite, il y a des cas où une \idx{accolade} ne peut pas délimiter un début ou une fin groupe, c'est dans le texte de remplacement d'une macro. Par exemple, si l'on voulait qu'une macro \verb|\startbold| ouvre un groupe et écrive en gras et que la macro \verb|\stopbold| stoppe ce fonctionnement, on serait obligé d'utiliser \idx\begingroup et \idx\endgroup :

\showcode|\def\startbold{\begingroup \bf}
\def\stopbold{\endgroup}
Voici \startbold du texte en gras\stopbold{} et la suite.|

En effet, cela constituerait une erreur que d'écrire :

\centrecode|\def\startbold{{\bf}
\def\stopbold{}}|

\noindent car le texte de remplacement de \verb|\startbold| irait jusqu'à la prochaine accolade équilibrée et serait

\centrecode|{\bf} \def\stopbold{}|

\noindent Il n'y aurait pas d'erreur de compilation, mais la portée de \verb|\bf| serait nulle puisque cette macro est seule dans son groupe et \verb|\stopbold|, ayant un texte de remplacement vide, n'aurait aucune action.
\end{exercice}

\begin{exercice}
Décrire ce qui se passe exactement et quel va être l'affichage si l'on définit une macro \verb|\foo| dans ce contexte :

\centrecode-\begingroup
\def\foo{Hello \endgroup world !}
\foo-

\solution
Déjà, la définition sera \emph{locale} au groupe semi-simple initié par \idx\begingroup et la macro \verb|\foo| sera détruite dès qu'un \idx\endgroup sera exécuté pour revenir à ce qu'elle était avant le groupe semi-simple (éventuellement indéfinie). Le \idx\endgroup de la ligne 2 n'est pas «exécuté» par \TeX{} puisque ce \idx\endgroup est stocké dans le \idx{texte de remplacement} de la macro \verb|\foo|. Il ne ferme donc pas le groupe semi-simple lorsque \TeX {} exécute la ligne \no2 du code.

Lorsque \TeX{} rencontre \verb|\foo| à la 3\ieme{} ligne du code, il se trouve toujours dans le groupe semi-simple ouvert par \idx\begingroup et la définition faite la ligne au-dessus est toujours en vigueur. \TeX{} remplace donc \verb|\foo| par son texte de remplacement, ce remplacement se faisant dans la \idx{pile d'entrée} de \TeX{} :

\centrecode-Hello \endgroup world !-

\noindent \TeX{} va continuer à lire ce qu'il y a dans sa pile et va donc afficher \verb*|Hello | puis, en rencontrant \idx\endgroup, détruira la définition locale de \verb|\foo| enfin continuera à lire ce qui est dans sa pile et affichera : \verb|world !|.

On voit donc que dans ce cas, la macro \verb|\foo| porte dans son \idx{texte de remplacement} la primitive \idx\endgroup qui provoquera son autodestruction !\idx*[|)]{groupe}\idx*[|)]\def
\end{exercice}

\begin{regle}
La primitive \idx\aftergroup\verb|<token>| permet de stocker un \verb|<token>| dans une pile spéciale de la mémoire de \TeX pour que ce \idx{token} soit lu et exécuté juste après être sorti du groupe courant, que ce groupe soit simple ou semi-simple.

Si plusieurs commandes \idx\aftergroup sont rencontrées dans un même groupe, les \idx{token}s mis en mémoire seront lus dans l'ordre où ils ont été définis. Ainsi, écrire

\centrecode-\aftergroup<x>\aftergroup<y>-\idx*\aftergroup

se traduira par «\verb|<x><y>|» après la fermeture du groupe.
\end{regle}

\showcode/\def\foo{foo}
\begingroup A\aftergroup\foo B\endgroup\par
{A\aftergroup X\aftergroup\foo B}/

La primitive \idx\aftergroup trouve une utilité lorsque la composition en italique est demandée dans un groupe (qui en délimite la portée). En effet, pour éviter que le dernier caractère en italique (qui est donc penché vers la droite) ne soit trop près du caractère du mot suivant (qui est vertical), il convient d'insérer à la fin du groupe une \idx{correction d'italique}, surtout si les deux caractères sont des lettres hautes comme «l», «f» ou une parenthèse fermante. Cette correction, effectuée en \TeX{} par la primitive \idx[ (correction d'italique)]\/, augmente légèrement l'espace entre ces deux caractères. La différence est très fine, mais elle existe :

\showcode|1) (un {\it cheval})\par% sans correction d'italique¤\idx*\it¤
2) (un {\it\aftergroup\/cheval})\par% avec correction d'italique¤\idx*[ (correction d'italique)]\/\idx*\aftergroup\idx*\it¤
% on peut définir une macro \itacorr qui effectue automatiquement la correction
\def\itacorr{\it\aftergroup\/}¤\idx*\aftergroup¤
3) (un {\itacorr cheval})% avec correction d'italique|

\section{Primitive \ttfamily{\textbackslash let}}\label{let}
\idx*[|(]{\let}Pour copier le \idx[!copie]{texte de remplacement} d'une macro vers une autre, on utilise la primitive \verb-\let- qui prend comme arguments deux unités lexicales de type \idx{séquence de contrôle}. Par exemple, écrire \verb-\let\foo=\bar- copiera le texte de remplacement de la macro \verb-\bar- vers \verb-\foo- en écrasant celui de cette dernière si elle était déjà définie. Le signe «=» entre les deux séquences de contrôle est facultatif et sera souvent omis désormais\footnote{En réalité, le signe égal peut aussi être suivi d'\emph{un} espace facultatif.}. Une fois cette copie faite, peu importe ce que sera le futur de \verb-\bar-, la copie a lieu à l'instant où \verb-\let- est rencontré et si \verb-\bar- est redéfinie par la suite, cela n'affectera pas le texte de remplacement de \verb-\foo-.

\showcode/\def\bar{Je suis bar.}
\let\foo\bar % \foo devient égal à \bar
\def\bar{ABC}% \bar est redéfinie
\foo\par% affiche "Je suis bar"
\bar% affiche "ABC"/

Lorsqu'on écrit \verb-\let\foo=\bar-, si \verb-\bar- est une primitive, alors \verb-\foo- devient un \emph{alias} pour cette primitive et pour \TeX{}, elles sont identiques. Il est important de noter que ni \idx\def ni \verb-\let- ne préviennent d'aucune façon l'utilisateur qu'il écrase une \idx{séquence de contrôle} et que sa définition précédente sera perdue. Et tant pis si c'est une primitive. Si par malheur on écrit \verb-\let\def\foo-, alors, à partir de ce moment, la primitive \verb-\def- sera écrasée et il ne sera donc plus possible de définir de commande.
\begin{exercice}
\Qu e fait le code suivant : \verb-\let\foo\let\foo\bar\foo- ?
\solution
En procédant comme \TeX{} et en ne lisant que ce dont on a besoin, on a d'abord \verb-\let\foo\let- et donc \verb-\foo- devient égale à la primitive \verb-\let-.

Ensuite, on a \verb-\foo\bar\foo- mais comme \verb-\foo- est devenue un alias de \verb-\let-, tout se passe comme si l'on écrivait \verb-\let\bar\let- et donc, \verb-\bar- devient aussi égale à \verb-\let-.

Le code rend donc \verb-\foo- et \verb-\bar- égales à \verb-\let-.
\end{exercice}

La commande \verb-\let- peut aussi être utilisée pour définir des «caractères implicites\idx*{caractère implicite}». La syntaxe ne change pas, mais au lieu de la seconde \idx{séquence de contrôle}, on met un caractère. Si on écrit par exemple \verb-\let\foo=a-, la \idx{séquence de contrôle} \verb-\foo- devient un «\texttt a implicite». Cela signifie qu'elle produira un «\texttt a» à l'affichage et que lorsque \TeX{} teste cette \idx{séquence de contrôle} (nous verrons comment plus tard), il la voit égale à «\texttt a». Il est bien évident que \verb-\foo- ne peut pas être utilisée à la place de «\texttt a» n'importe où dans le code. Si on veut écrire \verb-\par-, on ne peut pas écrire \verb-\p\foo r- !

La définition d'un caractère implicite via \verb|\let| ne peut se faire que pour les caractères \emph{inoffensifs} que l'on peut rencontrer, c'est-à-dire ayant un catcode 11\idx*{catcode!11 (lettre)} ou 12\idx*{catcode!12 (autre)}, ainsi que pour ceux ayant le catcode 1\idx*{catcode!1 (accolade)}, 2, 3, 4, 6, 7, 8. Il est par exemple impossible de définir un «\verb|%|» ou un «\verb|\|» implicite avec \verb|\let|. Pour l'espace, cela requiert un plus haut niveau de \TeX nicité que nous verrons plus loin (page~\pageref{sptoken}).

Pour les \idx[!implicite]{accolade}s ouvrantes et fermantes (dont les catcodes sont respectivement 1\idx*{catcode!1 (accolade)} et 2), il existe des tokens implicites\idx*[!implicite]{token} prédéfinis très importants qui sont \idx\bgroup et \idx\egroup. Ils sont définis par plain-\TeX{} de la façon suivante :

\begin{centrage}
\small\verb-\let\bgroup={-\kern2cm\verb-\let\egroup=}-
\end{centrage}

\noindent Ces \emph{\idx[!implicite]{accolade}s implicites} peuvent jouer le même rôle de délimiteur de groupe que les accolades explicites «\verb-{-»\cidx*\{ et «\verb-}-»\cidx*\{ mais dans la grande majorité des cas, elles ne sont \emph{pas} interchangeables avec les accolades explicites. Par exemple, elles ne peuvent pas être utilisées pour dans la syntaxe de \idx\def pour délimiter le texte de remplacement d'une macro.
\grandsaut

À ce stade, on peut donc faire un point \TeX nique sur tout ce qui sert à délimiter un \idx{groupe} à savoir :
\begin{itemize}
	\item la paire \idx\begingroup\linebreak[1]\verb|...|\linebreak[1]\idx\endgroup;
	\item les accolades explicites «\cidx\{» et «\cidx\}» ;
	\item les accolades implicites \idx\bgroup\linebreak[1]\verb|...|\linebreak[1]\idx\egroup.
\end{itemize}

Tout d'abord, un \idx{groupe} ouvert par \idx\begingroup ne peut être refermé que par \idx\endgroup et donc, le \idx[!semi-simple]{groupe} semi-simple est totalement indépendant du groupe ouvert par des accolades. Les choses sont différentes pour les groupes ouverts et fermés par «\cidx\{» et «\cidx\}» ou par «\idx\bgroup» et «\idx\egroup». Tout d'abord, s'il n'existe aucune contrainte d'équilibrage d'accolades, «\cidx\{» et \idx\bgroup sont interchangeables pour ouvrir un groupe et «\cidx\}» et \idx\egroup le sont pour le fermer. Enfin, il y a quelques \emph{rares} primitives où les accolades explicites et implicites sont interchangeables dans leur syntaxe :

\begin{itemize}
	\item les primitives \idx\hbox, \idx\vbox et \idx\vtop attendent après elles un texte entre accolades pour le composer dans une boite (pour en savoir plus, voir la section \ref{boites} page~\pageref{boites} et suivantes).

	Ce sont les seules primitives où l'on peut indifféremment utiliser des accolades explicites ou implicites, aussi bien pour ouvrir que pour fermer. Par conséquent, «\verb|\hbox{a}|» et «\verb|\hbox\bgoup| \verb|a\egroup|» sont équivalents;
	\item certaines primitives que nous verrons et utiliserons plus loin ont une propriété encore plus curieuse\ldots{}
	
	Ces primitives doivent être immédiatement suivies d'une accolade ouvrante. Les plus connues sont \idx\toks\verb|<nombre>|, \idx\lowercase, \idx\uppercase et pour celles de \idx\eTeX{}, \idx\detokenize et \idx\unexpanded. Elles tolèrent indifféremment «\verb|{|» ou «\idx\bgroup» pour l'accolade ouvrante. En revanche, l'accolade fermante \emph{doit} être une accolade explicite.

	Ainsi, «\idx\lowercase\verb|{Foo}|» et «\idx\lowercase\verb|\bgroup Foo}|» sont acceptés et sont équivalents.
\end{itemize}

\begin{exercice}
Si l'on écrit le code ci-dessous, va-t-on obtenir «$a^3=b_5$» ?

\centrecode|\let\swichmath=$ \let\expo= ^ \let\ind _ \let\egal= =
\swichmath a\expo3\egal b\ind5$|

\solution
Oui car tous les tokens implicites\idx*[!implicite]{token} définis ici le sont avec la bonne syntaxe (le signe \verb-=- et l'espace facultatif qui le suit sont présents ou pas) et surtout, les catcodes des tokens implicites permettent une telle définition.
\end{exercice}

\begin{exercice}
\Qu e va t-il se passer si l'on définit la macro \verb-\foo- ainsi : \verb-\let\foo={hello}-
\solution
\TeX{} va d'abord lire \verb-\let\foo={- et donc, \verb-\foo- va devenir une accolade implicite.

Ensuite, le reste du code à lire est «\verb-hello}-». Tout va bien se passer jusqu'à l'accolade fermante. La première accolade ouvrante ayant été lue et absorbée par le \verb-\let-, celle-ci n'a pas été prise en compte dans le comptage interne à \TeX{} concernant l'équilibrage des accolades, l'accolade fermante devient orpheline et \TeX{} va nous gratifier d'un «\verb-Too many }'s-». Cette dernière erreur ne surviendra pas si auparavant, une accolade $x$ a été ouverte sans encore être fermée par une accolade fermante; dans ce cas, l'accolade qui suit «\verb|hello| équilibrera l'accolade $x$ ouverte préalablement à ce code.

Pour \emph{définir} une macro et lui donner un texte de remplacement, on ne doit utiliser que \idx\def puis le nom de la macro puis le texte de remplacement entre accolades.
\end{exercice}

La primitive \verb-\let- est parfois utile pour faire une sauvegarde d'une commande de façon à pouvoir la restaurer à son état initial après y avoir apporté des modifications. Prenons un mauvais exemple et décidons de modifier la macro \verb-\TeX- pour qu'elle n'affiche plus «\TeX» mais «tEx». Nous allons d'abord définir avec \verb-\let- un alias de \verb-\TeX- que nous appelons \verb-\TeXsauve- puis nous pourrons modifier la commande \verb-\TeX- et utiliser cette commande avec sa nouvelle définition. À la fin, avec \verb-\let- à nouveau, nous la restaurerons pour revenir au comportement initial :

\showcode/Initialement, c'est \TeX.\par
\let\TeXsauve\TeX% sauvegarde
\def\TeX{tEx}% redéfinition
Ici, on a modifié \TeX.\par
\let\TeX\TeXsauve% retauration
De nouveau, c'est \TeX./\idx*[|)]{\let}

\section{Les primitives \texttt{\textbackslash csname} et \texttt{\textbackslash endcsname}}\idx*[|(]\csname\idx*[|(]\endcsname
Pour écrire une \idx{séquence de contrôle}, on peut bien sûr faire précéder son nom du caractère «\verb|\|», c'est que nous avons fait jusqu'ici\ldots{} Mais il y a une autre méthode pour créer une \idx{séquence de contrôle}. On peut utiliser la paire de primitives \verb-\csname- et \verb-\endcsname- qui utilisent les caractères qui se trouvent entre elles pour les convertir en \idx{séquence de contrôle}. Par exemple, si \TeX{} rencontre \verb-\csname-\linebreak[1]\verb*- foo-\linebreak[1]\verb-\endcsname-\footnote{L'espace qui suit \texttt{\string\csname} est ignoré en vertu de la règle vue à la page~\pageref{regle.espace}}, dans un premier temps il construira l'unité lexicale «\verb|\foo|» et dans un deuxième temps, il lui substituera son texte de remplacement, tout ceci étant effectué dans la mémoire de \TeX{}, dans la \idx{pile d'entrée}. À l'affichage, l'effet est le même que si l'on avait directement écrit \verb-\foo-, mais dans les entrailles de \TeX{}, il y a une étape de plus, celle de former la \idx{séquence de contrôle} avec ce qui se trouve entre \verb-\csname- et \verb-\endcsname-. L'avantage de cette méthode est que l'on peut utiliser des caractères normalement interdits dans le nom de commandes, c'est-à-dire des tokens dont le catcode est différent de 11, celui des lettres. On peut donc construire des séquences de contrôle dont le nom comporte des espaces, des chiffres, des signes d'opérations, de ponctuation ainsi que d'autres caractères réservés dont les codes de catégorie sont spéciaux (\verb|&|, \verb|#|, \verb|^|, \verb|_|, \verb|$|).

Un autre avantage non négligeable est que si jamais la \idx{séquence de contrôle} formée par \verb-\csname-\ldots\verb-\endcsname- n'est pas définie, \TeX{} la rend égale à \idx\relax qui est une primitive dont l'action est de ne rien faire. Ainsi, écrire \verb-\foobar- dans le code alors que cette macro n'a pas été définie par \idx\def ou \idx\let provoquera une erreur de compilation «\texttt{Undefined control sequence}». En revanche, écrire \verb-\csname foobar\endcsname- revient à invoquer la primitive \idx\relax et il ne se passera donc rien.

Le revers de la médaille est que, pour \TeX{}, former une \idx{séquence de contrôle} avec \verb-\csname-\ldots\verb-\endcsname- est \emph{beaucoup} plus lent que de l'écrire directement avec le caractère d'échappement. Si c'est possible, il vaut donc mieux éviter d'utiliser cette méthode dans les boucles des programmes.

\begin{exercice}
Après avoir défini la macro \verb-\foo- avec \verb-\def\foo{Bonjour}-, pourquoi rien ne s'affiche lorsqu'on écrit «\verb-\csname foo \endcsname-»?
\solution
Parce que l'espace qui suit le «foo» est pris en compte pour construire le nom de la \idx{séquence de contrôle}. Ainsi, écrire \verb-\csname-\linebreak[1]\verb*- foo -\linebreak[1]\verb-\endcsname- construit la commande {\fboxsep0.3pt\fbox{\ttfamily\textbackslash foo\textvisiblespace}} qu'il serait fastidieux de construire autrement. Celle-ci étant indéfinie, la construire avec  \verb-\csname-\ldots\verb-\endcsname- la rend égale à \idx\relax et il ne se passe donc rien.
\end{exercice}
\begin{exercice}
\label{non.dev.csname}Pourquoi écrire \idx\let\verb-\salut\csname foo\endcsname- pour rendre égale \verb|\salut| à \verb|\foo| provoque une erreur de compilation ?
\solution
L'erreur survient parce que \TeX{} lit le code de gauche à droite en prenant en compte uniquement ce dont il a besoin. Il lit donc d'abord \idx\let\verb-\salut\csname-. Ce faisant, il rend donc la commande \verb-\salut- égale à \verb-\csname-. Ayant effectué cette opération, il poursuit avec la suite du code qui est \verb-foo\endcsname-. Les lettres «foo» ne vont pas lui poser de problème, il les affichera normalement, mais il va rencontrer la commande \verb-\endcsname- sans avoir rencontré le \verb-\csname- qui initiait le début de la construction du nom de la commande. Il va donc émettre le message d'erreur «\texttt{Extra \string\endcsname}».

Pour faire ce que nous voulions, il faudrait forcer \TeX{} à construire la \idx{séquence de contrôle} \verb|\foo| à partir de \verb*-\csname -\linebreak[1]\verb- foo-\linebreak[1]\verb-\endcsname- avant qu'il ne passe la main à \verb-\let-. Pour provoquer cette action, il faudrait sauter les deux tokens \verb-\let\salut- pour provoquer cette action et revenir où l'on était avant les sauts pour reprendre la lecture du code dans l'ordre normal. Pour effectuer cette man\-\oe uvre non linéaire qui déroge à la règle de lecture du code, il faut avoir recours à la primitive \idx\expandafter que nous verrons plus loin.
\end{exercice}
\begin{exercice}
On a vu comment définir une commande avec \idx\def. Existe-t-il un moyen d'annuler une définition et faire qu'une commande préalablement définie redevienne indéfinie ?
\solution
Il n'existe pas de primitive \verb-\undef- qui rendrait une commande indéfinie \emph{et} l'enlèverait de la table de hashage\footnote{Il s'agit d'une structure interne à \TeX{} où sont stockés les appariements entre les noms des macros et l'endroit de la mémoire où sont stockés leurs textes de remplacement.}.

On peut cependant combler ce manque. En effet, si l'on définit une commande à l'intérieur d'un \idx{groupe} simple ou semi-simple, la définition est locale au groupe et est perdue à sa fermeture. Par conséquent, si la commande était indéfinie avant l'ouverture du groupe, elle le redevient après sa fermeture.

Si l'on souhaite définir une commande de façon globale, la primitive \idx\global, lorsqu'elle est placée devant une assignation, rend cette assignation globale c'est-à-dire qu'elle survit à la fermeture du groupe. La primitive \idx\gdef se comporte comme \idx\global\verb|\def|.
\end{exercice}\idx*[|)]\csname\idx*[|)]\endcsname

\section{Caractère de contrôle}\idx*[|(]{caractère de contrôle}

\begin{regle}
Lorsque le caractère d'échappement «\cidx\\» est suivi d'un caractère dont le catcode n'est pas 11\idx*{catcode!11 (lettre)}, celui des lettres, seul ce caractère est pris en compte et \TeX{} forme ce que l'on appelle un «caractère de contrôle».
\end{regle}

Pour former un caractère de contrôle, on peut donc utiliser des caractères de catcode 12\idx*{catcode!12 (autre)} comme par exemple «\verb|\.|», «\verb|\*|», «\verb|\5|» ou «\verb|\@|». Il devient surtout possible d'employer des caractères dont le catcode est plus sensible comme «\verb|\\|», «\verb|\{|», «\verb|\}|», «\verb|\^|», «\verb|\_|», «\verb|\&|», «\verb|\~|», «\verb|\%|». Ces derniers, à l'exception de \verb|\\|\footnote{La macro \texttt{\string\\} est définie par plain-\TeX{} car elle est utilisée comme macro auxiliaire pour définir une autre macro et la définition qui lui est donnée à cette occasion est laissée en l'état. Toujours est-il qu'elle n'affiche pas «\texttt{\textbackslash}», qui s'obtient avec «\texttt{\textbackslash char\number`\\}» ou mieux avec «\texttt{\textbackslash char`\textbackslash\textbackslash}».

Du côté de \LaTeX{}, la macro \texttt{\string\\} est définie pour commander d'aller à la ligne pendant le paragraphe en cours et est redéfinie dans plusieurs environnements (centering, raggedright, raggedleft, eqnarray, tabbing, array, tabular).}, sont définis par plain-\TeX{} pour afficher le caractère qui forme leur nom, caractère qu'il serait plus difficile d'afficher sinon. Pour cela, la primitive \idx\chardef est employée avec cette syntaxe :

\centrecode-\chardef\<macro>=<code de caractère>-

\noindent Si l'on s'intéresse au code des macros du format plain-\TeX{} qui est contenu dans le fichier «\verb|plain.tex|»\idx*{fichier!plain.tex}, on découvre par exemple à la ligne \no 651 que le caractère de contrôle \idx\& est défini par

\centrecode-\chardef\&=`\&-

\noindent ce qui a pour effet de rendre équivalent (à la manière de \idx\let) le caractère de contrôle \verb|\&| à «\idx\char\verb|`\&|».

\begin{regle}
Contrairement aux séquences de contrôle dont le nom est formé de lettres, les \idx{espace}s qui suivent les « caractères de contrôle » ne sont pas ignorés. La seule exception est la primitive \idx\ , qui ajoute un espace à la liste courante. En effet, si cette dernière est suivie d'un espace, alors deux \idx[!consécutifs]{espace}s se suivent dans le code et une autre règle stipule que le second est ignoré.
\end{regle}

\begin{exercice}
En ayant fait les définitions «\verb*-\def\9{\ \:}-» et «\verb*-\def\:{ \  X}-», quel affichage obtiendra-t-on avec «\verb*-a\9 fin-» ?
\solution
On obtient la lettre «a» suivie du texte de remplacement de \verb-\9-. Celui-ci commence par \verb*-\ - (espace qui sera affiché) suivi de \verb-\:-. Le texte de remplacement de \verb|\:| commence par : \verb*- - (espace qui sera affiché) puis \verb*-\  - (le deuxième espace est ignoré) suivi d'un «\verb|X|». Et enfin, l'espace après \verb*-\9 - sera affiché avant le mot «fin». On obtient donc «a\verb*-   -X\verb*- -fin».
\end{exercice}

\begin{exercice}
\Qu elle différence y t-il entre «\verb-\+-» et «\idx\csname\verb|+|\idx\endcsname»
 ?
\solution
Il n'y a pas de différence à l'affichage sauf si le caractère qui suit dans le code est un espace. Il sera comptabilisé avec \verb-\+- et ignoré avec \idx\csname\verb|+|\idx\endcsname car l'espace qui suit la \idx{séquence de contrôle} \idx\endcsname est ignoré.

De plus, si le caractère de contrôle \verb-\+- n'a pas été défini, écrire \verb-\+- provoque une erreur à la compilation de type «\texttt{Undefined control sequence}». Au contraire, avec \idx\csname\verb|+|\idx\endcsname, il n'y aurait pas d'erreur car lorsque \idx\csname construit une \idx{séquence de contrôle} non définie, elle la rend égale à \idx\relax, et ici, tout se passerait comme si on avait écrit \idx\let\verb|\+=|\idx\relax.
\end{exercice}
\begin{exercice}
\Qu elle différence y a-t-il entre «\idx\def\verb-\foo{A}-» et «\idx\let\verb-\foo=A-» ?
\solution
À l'affichage, dans les deux cas, \verb-\foo- produit un «A». Par contre, en interne, les choses sont différentes\ldots

Lorsque \verb-\foo- est définie avec \idx\def, \TeX{} la \emph{remplace} par un «A».

Lorsque \verb-\foo- est définie avec \idx\let, aucun remplacement n'est fait puisque \verb-\foo- \emph{est} un «A» et n'a aucun texte de remplacement.
\end{exercice}

Le fait que les commandes caractères prennent en compte les espaces qui les suivent permet de définir un espace implicite §\sptoken de cette façon\footnote{C'est ainsi que \texttt{\string\@sptoken} est défini dans le code du noyau \LaTeX.} :\label{sptoken}

\centrecodespc/\def\:{\let\sptoken= }¤§*\sptoken¤
\: /

\noindent Toute l'astuce réside dans le fait que l'espace qui suit \verb|\:| à la 2\ieme{} ligne est pris en compte. La man\-\oe uvre mérite une petite explication. La première ligne définit un texte de remplacement pour la macro \verb|\:|. À la deuxième ligne, \TeX{} va remplacer \verb|\:| par son texte de remplacement ce qui va donner :

\begin{centrage}
\small\boxtoken{\let\string\sptoken= }\verb*| |%
\end{centrage}

Pour plus de clarté, le texte de remplacement de \verb|\:| est encadré. Dans ce texte de remplacement, l'espace qui suit le signe \verb|=| est l'espace facultatif qui est permis avec la primitive \idx\let. Cet espace, faisant partie de la syntaxe de \idx\let, est ignoré et donc, \idx\let rend §\sptoken égal au token suivant qui est «\verb*| |», l'espace qui suit le caractère de contrôle \verb|\:|.

Dans le code ci-dessus, le second espace n'est pas ignoré car les deux espaces ne sont pas consécutifs dans le code source. Ils sont consécutifs après que \TeX{} ait remplacé \verb|\:| par son texte de remplacement. La règle de la page~\pageref{regle.espace} ne s'applique donc pas.

\begin{exercice}
Comment serait défini §\sptoken si l'on écrivait naïvement \idx\let\verb*-\sptoken=  - ?
\solution
Comme on l'a vu, le premier espace, facultatif, fait partie de la syntaxe de \idx\let et ne peut donc pas servir à définir §\sptoken. Le second est ignoré puisque la règle veut que deux espaces consécutifs dans le code n'en forment qu'un.

Dans ce cas, §\sptoken sera un alias pour le token qui \emph{suivra dans le code} et que l'on n'a pas précisé dans l'énoncé de l'exercice. Il faut noter que si ce qui suit est un saut de ligne, §\sptoken sera un alias de la commande \idx\par car deux sauts de lignes consécutifs sont équivalents à la commande \idx\par :

\showcode/\let\sptoken=  %2 espaces avant le "%"¤§*\sptoken¤

La commande \sptoken compose le paragraphe/
\end{exercice}\idx*[|)]{caractère de contrôle}

\section{Caractères actifs}\idx*[|(]{caractère actif}
Un caractère est dit \emph{actif} lorsqu'il revêt les mêmes propriétés qu'une commande : on peut le définir avec \idx\def et, lorsqu'il est rencontré par \TeX{}, son texte de remplacement lui est substitué. En contrepartie, il ne fait plus partie de la catégorie de lettres et n'est donc pas autorisé dans les noms des séquences de contrôle.

\begin{regle}
Un caractère est \emph{actif} lorsque son code de catégorie vaut 13\idx*[!13 (actif)]\catcode. Dans ce cas, on peut lui donner un texte de remplacement comme on le fait pour une macro.
\end{regle}

Par défaut, aussi bien avec plain-\TeX{} qu'avec \LaTeX, seul le caractère «\cidx\~» est actif fait les choses suivantes :
\begin{enumerate}
	\item interdire une coupure en spécifiant une haute \idx{pénalité} (avec la primitive \idx\penalty suivie d'un entier élevé, par exemple \numprint{1000});
	\item appeler la primitive \idx\ qui affiche une espace.
\end{enumerate}
Ainsi, plain-\TeX{} dit :

\centrecode-\def~{\penalty1000 \ }-

\noindent La forte \idx{pénalité} de \texttt{1000} interdit toute coupure et le tout forme donc une « \idx[!insécable]{espace} insécable », où l'adjectif \emph{insécable} exprime que cette espace ne pourra donner lieu à une coupure de ligne.
\grandsaut

À notre tour, supposons que l'on souhaite rendre le caractère «\verb|W|» actif. Nous le ferons à l'intérieur d'un groupe, car il est prudent de limiter la portée des modifications des codes de catégorie.

Nous savons que \idx\catcode\verb-`\<car>=<nombre>- modifie le catcode d'un caractère, où \verb-<nombre>- est un nombre de 0 à 15\footnote{Le caractère «\texttt`» est l'apostrophe \emph{inverse} et s'obtient parfois en tapant la combinaison de touches \bioLegacyKeyGlyph{A_l_t_G_r}+\bioLegacyKeyGlyph{seven}. Pour exprimer le nombre égal au code de catégorie d'un caractère, on peut écrire \verb|\`<car>| ou \verb|`<car>|. La seconde écriture est cependant moins recommandable puisque l'on s'expose à des erreurs lorsque \verb|<car>| a un catcode spécial (0 ou \number\catcode`\%).}. Ici, on va donc écrire \verb-\catcode`\W=13-. Et ensuite, il suffit de définir le texte de remplacement du caractère actif \verb|W|, par exemple «wagons» :

\showcode/{% début du groupe
\catcode`\W=13 \def W{wagons}¤\idx*\catcode¤
Les W constituent le train.
}% fin du groupe/

Voici la règle corroborant ce que l'on constate dans l'exemple ci-dessus :

\begin{regle}
Un \idx{espace} après un caractère actif est pris en compte.
\end{regle}

Il est plus difficile est de créer une commande qui rende le caractère \verb|W| actif. Appelons \verb-\actiw- cette commande et donnons-nous le cahier des charges suivant : elle devra rendre le caractère \verb|W| actif et lui donner le texte de remplacement «wagons». Nous placerons un \idx\begingroup avant d'appeler cette macro et un \idx\endgroup à la fin du texte où l'on souhaite que le caractère \verb|W| soit actif.

Pour définir cette commande \verb-\actiw-, on ne peut pas écrire directement ceci :

\centrecode-\def\actiw{\catcode`\W=13 \def W{wagons}}-

\noindent En effet, lorsque \TeX{} remplace \verb|\actiw| par son texte de remplacement, \emph{tous} les tokens dans ce texte de remplacement ont leurs catcodes figés depuis que la définition a été faite. Et donc, le «\verb|W|» qui suit le \verb|\def| a un catcode de 11.

Par conséquent, lorsque ce texte de remplacement sera exécuté, \TeX{} va trouver \verb-\def W{wagons}- où \verb|W| est une lettre (de catcode 11\idx*{catcode!11 (lettre)}), et il va se plaindre de ne pas trouver une \idx{séquence de contrôle} après le \idx\def en affichant le message d'erreur «\texttt{Missing control sequence}».

Il faut comprendre que l'ordre «\verb|\catcode`\W=13|» qui est dans texte de remplacement ne peut pas agir sur les «\verb|W|» de ce texte de remplacement puisque leurs catcodes sont figés, mais agira sur le code qui reste à lire \emph{après} \verb|\actiw|.

Pour sortir de ce mauvais pas, il faut rendre \verb|W| actif \emph{avant} que \TeX{} ne lise le texte de remplacement de \verb-\wagon-. Pour limiter la portée de cette opération, on va donc le faire dans un groupe et utiliser \idx\gdef, pour que la définition soit globale et survive à la fermeture du groupe. Voici la façon correcte de définir \verb-\actiw- :

\showcode/\begingroup \catcode`\W=13 ¤\idx*\begingroup\idx*\endgroup¤
\gdef\actiw{%¤\idx*\gdef¤
	\catcode`\W=13 ¤\idx*\catcode¤
	\def W{wagons}}
\endgroup
a) Les trains ne sont pas constitués de W !\par
b) \begingroup\actiw Ici, les W forment les trains.\endgroup\par
c) Ici, les W sont redevenus des lettres./

\begin{exercice}
Définir deux séquences de contrôle \verb-\>- et \verb-\<- telles qu'entre elles, les mots soient espacés de \numprint[mm]5. Le comportement normal doit être rétabli ensuite.

On utilisera la primitive \idx\hskip suivie d'une dimension pour ordonner à \TeX{} d'insérer une espace horizontale de la valeur de la dimension.
\solution
Comme on l'a vu, on ne peut pas écrire directement ce code comme ci-dessous pour définir la macro \verb-\>- :

\centrecode-\def\>{\begingroup\catcode`\ =13 \def {\hspace{5mm}}}-

\noindent puisqu'au moment où cette ligne est lue par \TeX{}, l'espace a son code de catégorie naturel de 10. Celui-ci ne pourra plus être changé par la suite.

Voici la bonne façon de procéder : il suffit de rendre la commande \verb-\<- égale à \idx\endgroup ce qui clôturera le processus initié par \verb-\>- qui avait ouvert le groupe semi-simple :

\showcode/\begingroup¤\idx*\begingroup¤
	\catcode`\ =13 % rend l'espace actif¤\idx*\catcode¤
	\gdef\>{\begingroup¤\idx*\gdef¤
		\catcode`\ =13
		\def {\hskip5mm\relax}}¤\idx*\hskip\idx*\relax¤
\endgroup
\let\<=\endgroup¤\idx*\let¤
a) Du texte normal\par
b) \>Des mots très espacés\<\par
c) Du texte normal/
\end{exercice}

La présence d'un \idx\relax après la dimension de \verb|5mm| stoppe la lecture de la dimension. En effet, comme nous le verrons plus loin, une dimension peut avoir des composantes étirables qui commencent par le mot-clé «\verb|plus|». Sans le \idx\relax, si jamais un espace actif était suivi du mot «\verb|plus|», alors \TeX{} penserait que ce mot fait partie intégrante de la dimension et irait chercher encore plus loin la composante étirable. Le \verb|\relax| agit donc ici comme une sécurité.
\grandsaut

Une application utile des caractères actifs est de rendre les signes de ponctuation haute actifs. C'est ce que fait l'extension pour \LaTeX{} «\verb-babel-» chargée avec l'option «\verb-frenchb-» de Daniel \textsc{Flipo}\idx*{package!babel (frenchb)}. Les signes de ponctuation \emph{haute} «\string!», «\string?», «\string:» et «\string;» sont rendus actifs de façon à insérer une espace fine insécable avant eux. Nous allons imiter ce comportement et rendre la virgule active. L'idée est de la programmer pour qu'elle supprime un éventuel espace avant elle, affiche le caractère «\verb|,|», insère une espace justifiante (c'est-à-dire étirable) et enfin, ne tienne pas compte des espaces qui pourraient suivre. Pour effectuer ces actions, certaines primitives sont nécessaires :
\begin{itemize}
	\item si ce qui précède est un espace étirable, la primitive \idx\unskip le supprime ;
	\item \idx\string transforme le token qui suit en un ou plusieurs tokens dont les codes de catégorie sont 12. Cette primitive est utile pour rendre n'importe quel \idx{token} inoffensif et donc immédiatement affichable. Par exemple, «\verb-\string#-» produit «\string#» de même que «\verb-\string\def-» produit «\string\def». Lorsque la virgule sera active, «\verb-\string,-» affichera une virgule non active;
	\item \idx\ignorespaces demande à \TeX{} d'ignorer tous les espaces qui vont suivre et d'avancer sa tête de lecture jusqu'au prochain caractère qui n'est pas un espace.
\end{itemize}

\showcode/\begingroup¤\idx*\begingroup¤
	\catcode`\,=13 \def,{\unskip\string,\space\ignorespaces}¤\idx*\unskip\idx*\string\idx*\space\idx*\ignorespaces\idx*\catcode¤
	La rue assourdissante autour de moi hurlait.

	Longue , mince,en grand deuil  ,  douleur majestueuse ,

	Une femme passa   ,d'une main fastueuse

	Soulevant,balançant le feston et l'ourlet ;

\endgroup\medbreak\hfill Charles {\sc Baudelaire}¤\idx*\endgroup\idx*\medbreak\idx*\hfill\idx*\sc¤/

\begin{exercice}
Par défaut, le caractère inséré par \TeX{} à chaque \idx{fin de ligne} est le retour charriot, qui s'écrit «\verb-^^M-\verbidx*[ (retour charriot)]{^^M}» et qui a comme code de catégorie \number\catcode`\^^M. La règle de \TeX{} vue page~\pageref{regle.catcode5} veut que \emph{deux} retours charriots consécutifs (ou plus généralement deux tokens consécutifs de catcode \number\catcode`\^^M) soient équivalents à la commande \idx\par\idx*{catcode!5 (retour charriot)}.

Reprendre l'exemple précédent en faisant en sorte qu'un seul retour charriot suffise à aller à la ligne suivante.
\solution
Il suffit de rendre le caractère \verb-^^M- actif et le rendre égal à \idx\par avec un \idx\let :

\showcode/\begingroup¤\idx*[|etc]\begingroup\forbidindex\begingroup¤
	\catcode`\,=13 \def,{\unskip\string, \ignorespaces}¤\idx*\unskip\idx*\string\idx*\ignorespaces\idx*\catcode¤
	\catcode`\^^M=13 \let ^^M\par¤\idx*\let¤ % rend le retour charriot égal à \par
	La rue assourdissante autour de moi hurlait.
	Longue , mince,en grand deuil  , douleur majestueuse ,
	Une femme passa   ,   d'une main fastueuse
	Soulevant,balançant le feston et l'ourlet ;
\endgroup\medbreak\hfill Charles {\sc Baudelaire}¤\idx*[|etc]\endgroup\forbidindex\endgroup\idx*\medbreak\idx*\hfill\idx*\sc¤/
\end{exercice}

\begin{exercice}
Dans un texte à l'intérieur d'un groupe, inventer un procédé qui effectue un remplacement par permutation circulaire des voyelles, c'est-à-dire qui remplace a par e, e par i, i par o, o par u, u par y et y par a.
\solution
\label{permutation.voyelles}La difficulté vient du fait qu'une fois qu'un caractère est rendu actif, il devient semblable à une \idx{séquence de contrôle} et on ne peut plus s'en servir pour former le nom d'une \idx{séquence de contrôle}. C'est donc une méthode peu recommandable, il en existe d'ailleurs de meilleures. Il n'empêche qu'en l'état actuel de nos connaissances, nous ne pouvons procéder qu'en touchant aux codes de catégorie.

Avant de toucher aux catcodes des voyelles, on va donc définir des séquences de contrôle \verb-\AA-, \verb-\EE-, etc. qui, à l'aide de la commande \idx\let vont devenir des lettres implicites, «a» pour \verb-\AA-, «e» pour \verb-\EE-, etc.

Ensuite, les commandes \idx\catcode et \verb|\let| contenant des voyelles, on ne pourra pas y faire appel après avoir modifié les codes de catégorie. On va donc définir avec \verb-\let- des séquences de contrôle équivalentes dont les voyelles seront en majuscule. On aura donc \verb-\lEt- pour \verb-\let- et \verb-\cAtcOdE- pour \verb-\catcode-.

On peut ensuite rendre chaque voyelle active et la mettre \verb|let|-égale à \verb-\AA-, \verb-\EE-, etc. selon la lettre que l'on veut obtenir.

\showcode[\def\`##1{{\accent0 ##1}}\def\'##1{{\accent1 ##1}}]/{% ouvre un groupe
	\let\AA=a \let\EE=e \let\II=i \let\OO=o \let\UU=u \let\YY=y¤\idx*\let¤
	% sauvegarder avant de modifier le catcode de a et e :
	\let\lEt=\let \let\cAtcOdE=\catcode¤\idx*\catcode¤
	\cAtcOdE`\a=13 \lEt a=\EE \cAtcOdE`\e=13 \lEt e=\II
	\cAtcOdE`\i=13 \lEt i=\OO \cAtcOdE`\o=13 \lEt o=\UU
	\cAtcOdE`\u=13 \lEt u=\YY \cAtcOdE`\y=13 \lEt y=\AA
	Ce texte devenu \`a peine reconnaissable montre que le r\'esultat
	contient des sonorit\'es catalanes, corses ou grecques assez
	inattendues.
}% ferme le groupe/

Les contorsions nécessaires pour arriver à nos fins montrent que l'on ne touche pas aux codes de catégorie sans se créer de réelles difficultés et sans prendre de gros risques si l'on contrôle mal la portée des modifications. Changer un code de catégorie de caractère doit donc rester exceptionnel et rester réservé à des buts très spécifiques. En effet, des méthodes plus sures existent, même si elles ont aussi d'autres inconvénients.

Une optimisation du code serait d'utiliser le caractère déjà actif «\cidx\~» comme alias de \idx\catcode. Bien sûr, on y perd en lisibilité\ldots{} On peut aussi profiter de la permutation circulaire pour définir chaque voyelle rendue active comme alias de la prochaine voyelle, non encore rendue active. On économise ainsi des séquences de contrôle pour les lettres implicites. On n'en a besoin que d'une seule, \verb-\AA-, lettre implicite pour «a» :

\showcode[\def\`##1{{\accent0 ##1}}\def\'##1{{\accent1 ##1}}]/{%
	\let\AA=a \let\lEt=\let \let~=\catcode¤\idx*\catcode\idx*\let\cidx*\~¤
	~`a=13 \lEt a=e ~`e=13 \lEt e=i ~`i=13 \lEt i=o
	~`o=13 \lEt o=u ~`u=13 \lEt u=y ~`y=13 \lEt y=\AA
	Ce texte devenu \`a peine reconnaissable...
}/
\end{exercice}\idx*[|)]{caractère actif}

\section{Signification d'une commande}
Il est possible de demander à \TeX{} la « signification » d'une \idx[|etc]{séquence de contrôle}\forbidindex{séquence de contrôle}. Pour cela, la primitive \idx\show écrit dans le \idx[!log]{fichier} log le \idx{texte de remplacement} de la macro ou simplement son nom si c'est une primitive. Cette primitive, lorsqu'elle est utilisée à bon escient dans le code permet un débogage efficace par la lecture du \idx[!log]{fichier} \verb|log|. Pour diriger les informations délivrées par \idx\show dans le flux de lecture de \TeX{} pour par exemple les afficher dans le document final, il faut utiliser la primitive \idx\meaning.

\showcode/a) \def\foo{Bonjour}\meaning\foo\par¤\idx*\meaning¤
b) \let\bar=\foo\meaning\bar\par% \foo est "copiée" vers \bar
c) \def\baz{\foo}\meaning\baz\par
d) \catcode`\W=13 \def W{Wagons}% W est un caractère actif¤\idx*\catcode¤
   \meaning W\par
e) \meaning\def% \def est une primitive¤\idx*\meaning¤/

Il est important d'insister entre la différence qui existe entre \verb|\let\bar\foo| (cas b) et \verb|\def\baz{\foo}| (cas c). Dans le premier cas, \verb|\bar| est rendue égale à \verb|\foo| et à partir de ce moment, \verb|\bar| a comme texte de remplacement «Bonjour», indépendamment de ce que devient \verb|\foo|. En revanche, lorsqu'on écrit \verb|\def\baz{\foo}|, la macro \verb|\baz| a comme texte de remplacement \verb|\foo| et donc, à chaque fois qu'elle est exécutée, elle dépend de ce qu'est \verb|\foo| à ce moment-là.

\begin{exercice}
Mettre en évidence à l'aide de la primitive \idx\meaning que 2 retours charriots\verbidx*[ (retour charriot)]{^^M} consécutifs sont interprétés par \TeX{} comme étant la primitive \verb-\par-.
\solution
Il suffit de définir une commande dont le texte de remplacement est constitué de 2 retours charriots consécutifs et de faire afficher à \TeX{} la signification de cette commande, voire faire suivre \verb|\meaning| de deux retours à la ligne :

\showcode/a) \def\foo{

}Signification de \string\foo{} : \meaning\foo¤\idx*\string\idx*\meaning¤

b) Signification de deux retours charriots consécutifs : \meaning
 /
\end{exercice}

\begin{regle}
La primitive \idx\show écrit dans le \idx[!log]{fichier} \verb|log| la « signification » du token\idx*[!signification]{token} qui la suit :
	\begin{enumerate}
		\item si ce token est une macro (ou un caractère actif), le texte «\texttt{macro->}» suivi du \idx{texte de remplacement} de cette macro est écrit;
		\item si ce token est une primitive, qui par définition n'a pas de \idx{texte de remplacement}, le nom de la primitive est écrit;
		\item sinon, \TeX{} écrit un texte bref (caractérisant le catcode du token) suivi du token.
	\end{enumerate}
La primitive \idx\meaning écrit les mêmes choses que \idx\show sauf qu'elle les écrits dans le flux de lecture de \TeX{}, dans la \idx{pile d'entrée}.
\end{regle}

Voici ce que provoque \verb|\meaning| pour les tokens de chaque catégorie qu'il est possible de mettre après \verb|\meaning| :
\begingroup
\def~{\penalty\@M \ }
\showcode/a) \meaning\relax\par% primitive¤\idx*\meaning¤
b) \meaning {\par% catcode 1
c) \meaning }\par% catcode 2
d) \meaning $\par% catcode 3
e) \meaning &\par% catcode 4
g) \meaning #\par% catcode 6
h) \meaning ^\par% catcode 7¤\idx*{catcode!7\space(exposant)}¤
i) \meaning _\par% catcode 8
j) \meaning a\par% catcode 11 (une lettre)¤\idx*{catcode!11\space(lettre)}¤
k) \meaning +\par% catcode 12 (caractère "autre")¤\idx*{catcode!12\space(autre)}¤
l) \meaning ~\par% catcode 13 (caractère actif)¤\idx*{catcode!13\space(actif)}¤/%
\endgroup\iffalse$\fi

\begin{exercice}
On ne peut pas afficher la signification d'un espace (catcode 10\idx*{catcode!10 (espace)}) puisqu'écrire «\idx\meaning\verb*| |» ferait que l'espace qui suit la primitive serait ignoré et \idx\meaning prendrait le token d'après. Comment s'y prendre pour afficher la signification d'un espace avec \idx\meaning ?
\solution
On peut employer la même astuce qu'avec §\sptoken de la page~\pageref{sptoken}. On s'y prend
 ici avec \idx\let, en enfermant le tout dans un groupe semi-simple :

\showcode/\begingroup% dans un groupe¤\idx*\begingroup¤
	\let\*=\meaning% rendre \* égal à \meaning¤\idx*\meaning¤
	\* %<- espace pris en compte
\endgroup% fermer le groupe¤\idx*\endgroup¤/

En revanche, on ne peut pas écrire après \idx\meaning les caractères de catcode suivants :
\begin{itemize}
	\item 0 car le caractère d'échappement s'apparie toujours avec autre chose pour former une \idx{séquence de contrôle}. Un token de catcode 0\idx*{catcode!0 (caractère d'échappement)} ne peut exister comme entité seule;
	\item 5 car ce caractère est vu comme un espace;
	\item 9 car c'est le numéro de la catégorie des caractères «ignorés» et le token serait aussi ignoré, même après \idx\meaning;
	\item 14 car un caractère de commentaire est ignoré ainsi que tout ce qui va jusqu'à la fin de la ligne;
	\item 15 car un caractère « invalide » n'est pas permis et provoque une erreur de compilation lorsqu'il est vu par \TeX{}.
\end{itemize}
\end{exercice}

\section{Le caractère d'échappement}\idx*[|(]{caractère d'échappement}
Par défaut, le caractère d'échappement est «\cidx\\», c'est à ce caractère que \TeX{} reconnait le début d'une \idx{séquence de contrôle}. Comme presque tout dans \TeX{}, ce caractère est modifiable. En effet, tout caractère de catcode 0\idx*{catcode!0 (caractère d'échappement)} est, par définition, un caractère d'échappement. Supposons qu'à l'intérieur d'un groupe semi-simple, on donne à «\verb-*-» le code de catégorie 0 et à «\verb-\-» le code de catégorie 12 qui est celui des caractères «autres». Ayant fait ces modifications, nous devrons mettre «\verb-*-» devant les séquences de contrôle et pourrons alors afficher «\verb-\-» directement puisqu'il sera devenu un caractère inoffensif :

\showcode/\begingroup¤\idx*\begingroup¤
\catcode`\*0 ¤\idx*\catcode¤
\catcode`\\12 % \ n'est plus un caractère d'échappement
*def*foo{bar}
*LaTeX{} et la macro *string*foo : *foo.

L'ancien caractère d'échappement  "\" et \TeX.
*endgroup/

\begin{exercice}
Concernant l'exemple précédent :
\begin{enumerate}
	\item Aurait-on pu écrire à la ligne 3 ceci : «\verb-*catcode`*\12-»\idx*\catcode ?
	\item Si l'on avait utilisé \idx*\gdef\verb-*gdef- pour que la macro \verb-*foo- survive à la fermeture du groupe, aurait-on pu l'appeler par la suite avec \verb-\foo- ?
\end{enumerate}
\solution
\begin{enumerate}
	\item Après la ligne \no2, il y a 2 caractères d'échappement qui sont «\verb-\-» et «\verb-*-». Tant qu'ils ont ce pouvoir, ils sont interchangeables. La réponse est donc oui.
	
	En revanche, la ligne 2 fait perdre ce pouvoir au caractère «\verb-\-» ce qui fait qu'ensuite, seul «\verb-*-» peut être utilisé comme caractère d'échappement jusqu'à ce que le groupe soit fermé par \verb-*endgroup-\idx*\endgroup.
	\item N'importe quel caractère ayant le catcode 0\idx*{catcode!0 (caractère d'échappement)} peut être utilisé pour amorcer le nom d'une macro. En temps normal, seul «\verb-\-» est disponible donc la réponse est oui.
\end{enumerate}
\end{exercice}

On peut observer que \idx\string, qui convertit le nom d'une \idx{séquence de contrôle} en caractères de catcode 12\idx*{catcode!12 (autre)}, ne tient pas compte de la modification du caractère d'échappement puisque l'on obtient \verb-\foo- et non pas \verb-*foo-. Cela dit, ce comportement est un peu normal car s'il y avait plusieurs caractères d'échappement, \TeX{} serait bien ennuyé pour en choisir un. Pour schématiser, on peut considérer que le choix d'un caractère d'échappement par son catcode concerne un mécanisme d'\emph{entrée} pour \TeX{} puisqu'il s'agit d'une règle concernant la lecture du code tapé par l'utilisateur. La primitive \idx\string appliquée aux macros, au contraire, concerne un mécanisme de sortie puisqu'elle provoque la conversion d'une donnée interne de \TeX{} (le nom de la macro) en caractères immédiatement affichables. Ces deux mécanismes se représentent le caractère d'échappement par des moyens indépendants. Pour \idx\string, il faut le définir via la primitive \idx\escapechar qui attend après elle le code de caractère du caractère d'échappement que l'on souhaite. Dans l'exemple précédent pour que le caractère d'échappement affiché par \idx\string soit «\verb-@-», il suffit de rajouter juste après le \idx\begingroup :

\begin{centrage}
	 \small\verb|\espcapechar=64 |\qquad ou bien\qquad \verb|\escapechar=`\@|
\end{centrage}

Notons que tout comme \idx\string, les primitives \idx\meaning et \idx\show tiennent compte de la modification du \idx\escapechar. Enfin, si l'on assigne à \idx\escapechar un code inférieur à 0 ou supérieur à 255, alors aucun caractère d'échappement ne précèdera le nom de la macro.

\showcode/\def\foo{\bar}
\begingroup¤\idx*\begingroup¤
a) \escapechar=-1  \meaning\foo\qquad% pas de caractère d'échappement¤\idx*\escapechar\idx*\meaning\idx*\qquad¤
b) \escapechar=`\@ \meaning\foo\qquad% "@" est le caractère d'échappement
\endgroup¤\idx*\endgroup¤
c) \meaning\foo% caractère d'échappement par défaut/

\begin{exercice}\label{construction.nom.etrange}
Définir une commande dont le nom est \verb-\-\boxtoken{1\string\2\string\a} et dont le texte de remplacement est «foo» et vérifier en appelant cette commande que la définition est bien correcte.
\solution
Il va falloir agir dans un groupe, modifier les catcodes de 1, 2 et \cidx\\ pour les mettre à 11, catégorie des lettres, seules autorisées dans les noms de macros. Comme «\cidx\\» est le caractère d'échappement, il va aussi falloir en définir un autre, choisissons «\verb-|-». Comme toutes ces man\-\oe uvres ont lieu dans un groupe, nous utiliserons \verb-|gdef-\idx*\gdef pour que la définition de la macro survive à la fermeture du groupe.

Le problème ici est que l'on doit donner \emph{en dernier} à «\verb|1|» le catcode 11. En effet, si on le faisait avant, «\verb|1|» deviendrait pour \TeX{} une \emph{lettre} et lorsqu'il rencontrerait \verb-|catcode`|2=11-, le «\verb|11|» serait, à ses yeux, deux lettres qui ne peuvent former un nombre, car les tokens qui forment les nombres doivent avoir un catcode de 12\idx*{nombre!catcode des chiffres} ! Nous aurions droit à une erreur de compilation du type «\texttt{Missing number}».

Enfin, pour appeler la macro à l'extérieur du groupe, on doit utiliser la paire \idx\csname...\linebreak[1]\idx\endcsname dans laquelle on prendra soin de transformer le caractère d'échappement \verb-\- en un caractère inoffensif de catcode 12\idx*{catcode!12 (autre)} avec la primitive \idx\string.

\showcode/\begingroup
	\catcode`\|=0 |catcode`|\=11 |catcode`|2=11 |catcode`|1=11 ¤\idx*\catcode\forbidindex\catcode¤
	|gdef|1\2\a{foo}¤\idx*\gdef¤
|endgroup¤\idx*\endgroup¤
Voici la macro : \csname 1\string\2\string\a\endcsname¤\idx*\string\idx*\csname\idx*\endcsname¤/

Dans ce cas, ces manipulations de catcode, assez dangereuses et plutôt chatouilleuses, sont fort heureusement inutiles avec la primitive \idx\expandafter que nous verrons plus loin. Il s'agit d'un exemple purement pédagogique\ldots
\end{exercice}\idx*[|)]{caractère d'échappement}

\section{Une autre façon de stocker des tokens}
Arrivés à ce point, nous savons qu'une macro peut servir à stocker des tokens. Ces tokens sont placés dans le texte de remplacement de la macro lors de sa définition avec \verb|\def|. Bien qu'on les utilise aussi dans ce but, les possibilités d'une macro ne se limitent pas à ce simple stockage et c'est ce que nous allons découvrir dans les chapitres suivants.

Si l'on recherche uniquement le côté « stockage de tokens », \TeX{} propose un autre type de structure : les registres de tokens\idx*[|(]{registre!token}\idx*[|(]{token!registre}. Ce sont de zones de mémoire (au nombre de 256 pour \TeX{} et \numprint{32768} pour \idx\eTeX) auxquelles on accède à l'aide de la primitive \idx\toks suivie du numéro de registre. Ainsi, \verb|\toks17| fait référence au registre de token \no17. Il est admis que le registre \no0 sert de registre brouillon et peut être utilisé sans trop de risque n'importe où.

\TeX{} met aussi à disposition la primitive \idx\toksdef et par exemple, écrire

\centrecode-\toksdef\foo=17-\idx*\toks

\noindent rend \verb|\foo| équivalent à \verb|\toks17| de telle sorte que le registre \no17 peut être désigné par la \idx{séquence de contrôle} \verb|\foo|. L'équivalence dont il est question ici ressemble à celle de \idx\let en ce sens que \verb|\foo| n'aura pas de texte de remplacement, mais \emph{sera} \verb|\toks17|.

Il est déconseillé d'utiliser un numéro non nul arbitrairement et sans précaution, car il se pourrait que ce registre soit déjà utilisé et on pourrait écraser son contenu et provoquer des dysfonctionnements par la suite. Plain-\TeX{} propose la macro \idx\newtoks\verb-\<nom>- où le \verb-\<nom>- sera une \idx{séquence de contrôle} créée par \TeX{} et qui, par l'intermédiaire de la primitive \idx\toksdef, rendra \verb|\<nom>| équivalent à \idx\toks suivi du prochain numéro de registre inutilisé. Grâce à ce système, on peut donc demander en toute sécurité l'allocation d'un registre de tokens et y faire référence ensuite par un nom, ce qui est bien plus pratique à retenir qu'un numéro.

Pour effectuer une assignation à un registre de tokens, il faut écrire

\centrecode-<registre de token>= {<ensemble de token>}-
\noindent ou bien
\centrecode-<registre de token>= <registre de token>-

\noindent où \verb|<registre de token>| est soit une \idx{séquence de contrôle} définie par \idx\toksdef ou \idx\newtoks, soit explicitement \idx\toks\verb|<numéro>|. Le signe «=» et l'espace qui le suit sont facultatifs et seront souvent omis.

Pour extraire du registre ce qu'il contient, on doit faire appel à la primitive \idx\the suivie du \verb|<registre de token>|. Voici un exemple où est sont créés deux registres \verb-\foo- et \verb|\bar| :

\showcode/\newtoks\foo% allocation d'un nouveau registre¤\idx*\newtoks¤
\foo={Bonjour le monde}% assignation
Contenu du registre {\tt\string\foo} : \the\foo.¤\idx*\the\idx*\tt\idx*\string¤

\newtoks\bar% allocation d'un autre registre
\bar=\foo% assigne à \bar les tokens du registre \foo
Contenu du registre {\tt\string\bar} : \the\bar.¤\idx*\string¤/

Comme pour les séquences de contrôle, si l'assignation d'un registre à tokens se fait à l'intérieur d'un groupe, elle est annulée lors de sa fermeture à moins de faire précéder l'assignation de \idx\global\idx*[|)]{registre!token}\idx*[|)]{token!registre}\idx*{assignation!registre de tokens}.

\chapter{Arguments d'une commande}
Les commandes vues jusqu'à présent étaient immuables en ce sens que leur texte de remplacement était figé une bonne fois pour toutes. Avec cette limite, elles ne seraient ni très puissantes ni très intéressantes. Heureusement, les commandes peuvent admettre des « arguments », variables eux, qui seront lus chaque fois que la commande sera appelée et qui seront insérés à des endroits du texte de remplacement choisis par l'utilisateur.

\section{\Qu 'est ce qu'un argument ?}

\begin{regle}
	Un \idx*{argument}argument d'une macro est :
	
	\begin{itemize}
		\item soit un \idx{token} c'est-à-dire un caractère (un \idx{octet}) ou une \idx{séquence de contrôle};
		\item soit le code qui se trouve entre deux accolades, étant entendu que ce code est un ensemble de tokens équilibrés en accolades ouvrantes et fermantes.
	\end{itemize}
\end{regle}

\noindent Par exemple, si on les considère comme des arguments de commandes :
\begin{itemize}
	\item «\verb-a-» représente un argument qui est «\verb-a-»;
	\item «\verb-abc-» représente 3 arguments qui sont «\verb-a-», «\verb-b-» et «\verb-c-»;
	\item «\verb*-ab c-» constitue 3 arguments aussi, les mêmes que ci-dessus. En effet, dans une liste d'arguments, un espace sous forme d'unité lexicale est ignoré. Pour qu'il soit pris en compte l'espace \emph{doit} être mis entre accolades : «\verb*- -» n'est pas un argument alors que «\verb*-{ }-» en est un.
	\item «\verb-{abc}-» est un argument unique qui est «abc»;
	\item «\verb|\foo\bar|» sont deux arguments, «\verb|\foo|» et «\verb|\bar|»;
	\item «\verb|{\foo\bar}|» est un seul argument qui est «\verb|\foo\bar|»;
	\item enfin, «\verb*-{\def\AA{a}}{ }{c{d}e}{f}-» est constitué de quatre arguments :
	\begin{enumerate}
		\item \verb-\def\AA{a}-
		\item \verb*- -
		\item \verb-c{d}e-
		\item \verb-f-
	\end{enumerate}
\end{itemize}

\label{argument.espace}\begin{regle}
Un espace \emph{non entouré d'accolades} est ignoré en tant qu'argument.\idx*[!argument]{espace}\idx*[!espace]{argument}
\end{regle}

Il faut retenir que les accolades ne servent qu'à délimiter l'argument et n'en font pas partie. Lorsque \TeX{} lit cet argument, il lit le texte se trouvant à intérieur des accolades et dépouille donc l'argument de ses éventuelles accolades extérieures\idx*[!délimiteur d'argument]{accolade}.

\begin{regle}
Lorsque des accolades délimitent un argument d'une macro, elles ne jouent pas le rôle de délimiteur de \emph{groupe}\idx*{argument!accolades}.
\end{regle}\idx*[|(]{argument!accolades}

\begin{exercice}
Si on les considère comme arguments d'une macro, «\verb-a-» et «\verb-{a}-» sont-ils différents ? Et si oui, en quoi ?
\solution
Non, s'ils sont les arguments d'une macro, «\verb-a-» et «\verb-{a}-» sont des arguments rigoureusement identiques et donc, si \verb|\foo| est une macro admettant un seul argument, il sera équivalent d'écrire
\begin{itemize}
	\item \verb*|\foo a|
	\item \verb|\foo{a}|
\end{itemize}

En revanche, si l'on souhaite donner la macro \verb|\bar| comme argument, il y aura une différence entre
\begin{itemize}
	\item \verb*|\foo\bar|
	\item \verb|\foo{\bar}|
\end{itemize}
Dans le premier cas, si un espace est à suivre, il sera ignoré tandis qu'il sera bien pris en compte dans le second cas puisque venant à la suite d'une accolade et non pas d'une \idx{séquence de contrôle}.

Certains prennent l'habitude de ne jamais entourer d'accolades un argument constitué d'une seule unité lexicale. Il reste à savoir si cette habitude est bonne ou pas\ldots{} Je pencherais plutôt pour dire qu'elle est bonne puisqu'elle facilite la lisibilité en ne surchargeant pas le code d'accolades inutiles. Cependant, la présentation du code étant souvent une affaire de gouts personnels, d'autres trouveraient des arguments imparables pour préférer le contraire !
\end{exercice}\idx*[|)]{argument!accolades}

Pour définir une commande qui admet des arguments\idx*{argument!token de paramètre (\char`\#)|etc}, on utilise le token «\cidx[ (token de paramètre)]\#», de catcode \number\catcode`\#, dit «token de paramètre\idx*[!de paramètre]{token}» que l'on fait suivre d'un entier qui représente le numéro de l'argument. Cet entier doit être compris entre 1 et 9, ce qui signifie qu'une macro ne peut admettre que 9 arguments au maximum.

Voici une macro «\verb|\hello|», très simple, qui admet deux arguments et qui affiche « Bonjour \verb|<argument 1>| et \verb|<argument 2>|.» et qui compose le paragraphe courant à l'aide de \idx\par :

\showcode/\def\hello#1#2{Bonjour #1 et #2.\par}% définition
\hello ab% #1=a et #2=b
\hello a b% #1=a et #2=b
\hello{foo}{bar}% #1=foo et #2=bar
\hello foobar% #1=f et #2=o
% (le reste "obar" est lu après que la macro est terminée)/

Comme on le constate, écrire

\centrecode-\def\hello#1#2{Bonjour #1 et #2.\par}-

\noindent signifie que la commande \verb-\foo- admet deux arguments qui seront écrits «\verb-#1-» et «\verb-#2-» dans le \idx{texte de remplacement} de la macro. Lorsque \TeX{} va rencontrer \verb|\hello|, il lira \emph{aussi} les deux arguments qui suivent la commande. Il remplacera ces trois choses par le \idx{texte de remplacement} de la macro où chaque \verb-#1- sera l'exact contenu du premier argument et chaque \verb-#2- celui du second.
\grandsaut

Lorsqu'on utilise \idx\def pour définir une macro, ce qui est situé entre le nom de la macro et l'accolade ouvrante qui délimite son texte de remplacement est appelé «\idx{texte de paramètre}». Dans l'exemple ci-dessus, ce texte de paramètre est \verb-#1#2- et spécifie que la commande \verb-\foo- admet 2 arguments. Dans le texte de paramètre, les entiers qui suivent les caractères \verb-#- doivent commencer à 1 pour le premier et aller en croissant de un en un. Il faut également que les arguments rencontrés dans le \idx{texte de remplacement} existent \emph{aussi} dans le \idx{texte de paramètre} sinon, \TeX{} émet un message d'erreur «\verb|Illegal parameter number in definition of \<macro>|\footnote{Nombre de paramètres incorrect dans la définition de \texttt{\char`\\\codeelement{macro}}.}». On ne peut donc pas écrire

\centrecode-\def\foo#1#2{Bonjour #1, #2 et #3}-

\noindent car l'argument \verb|#3| n'est pas spécifié dans le \idx{texte de paramètre}.

\begin{regle}
Une macro peut accepter de 0 à 9 arguments\idx*{argument!nombre d'arguments}.

Pour le spécifier, on indique juste après \idx\def, dans le «\idx{texte de paramètre}», les arguments les uns à la suite des autres sous la forme «\verb|#1|», «\verb|#2|», et ainsi de suite jusqu'au nombre d'arguments que l'on veut donner à la macro.

Le \idx{texte de paramètre} est strict sur l'ordre des arguments, mais en revanche, il n'y a aucune contrainte sur l'ordre et l'existence des arguments dans le \idx{texte de remplacement} de la macro. On peut donc les y écrire dans l'ordre que l'on veut, autant de fois que l'on souhaite, voire ne pas en écrire certains.
\end{regle}

\begin{exercice}
Comment s'y prendre pour qu'une commande traite plus de 9 arguments, par exemple 10 ?

Programmer une macro \verb-\tenlist- qui lit 10 arguments (qui peuvent être par exemple les 10 premières lettres de l'alphabet) et les affiche de cette façon :

\begin{centrage}(a,b,c,d,e,f,g,h,i,j)\end{centrage}

\solution
On ne peut pas, \emph{stricto sensu}, programmer une macro qui admet 10 arguments, c'est une limitation intrinsèque à \TeX. Mais rien n'empêche d'en programmer une qui admet 9 arguments, traiter ces arguments comme on l'entend et une fois fini, passer la main à une autre commande qui admettra un argument, le lira et le traitera à son tour.

On va donc écrire :

\centrecode-\def\tenlist#1#2#3#4#5#6#7#8#9{%
	(#1,#2,#3,#4,#5,#6,#7,#8,#9\endlist
}
\def\endlist#1{,#1)}-

Lorsque \TeX{} rencontrera la macro \verb-\tenlist-, il l'absorbera ainsi que les 9 arguments suivants (et uniquement eux) et il aura donc avancé juste devant le 10\ieme{} argument. Il procèdera à la substitution de la macro et ses arguments par le texte de remplacement et poursuivra sa lecture en tenant compte de la substitution. Ce texte de remplacement va procéder à l'affichage des 9 premiers arguments en les séparant par une virgule, puis \TeX{} rencontrera à la fin du \idx{texte de remplacement} la macro \verb-\endlist-. Comme elle n'est suivie de rien dans le texte de remplacement, elle ira chercher son argument plus loin dans le code, et ce qu'il y a après justement, c'est le 10\ieme{} argument.

\showcode/\def\tenlist#1#2#3#4#5#6#7#8#9{(#1,#2,#3,#4,#5,#6,#7,#8,#9\endlist}
\def\endlist#1{,#1)}
Une liste \tenlist abcdefghij de lettres./
\end{exercice}

Voici l'exemple de la macro \verb-\foo- que l'on a défini précédemment et que l'on met à l'épreuve dans différents cas :

\showcode/\def\foo#1#2{Bonjour #1 et #2.\par}
\begingroup\tt% passer en fonte à chasse fixe¤\idx*\begingroup\idx*\tt¤
a) \foo{monsieur}{madame}
b) \foo{{\bf toi}}{moi}
c) \foo{}{{}}
d) \foo{ }{ }
e) \foo{$\pi$} {$\delta$}
f) \foo ab
g) \foo X       Y
\endgroup% fin de la fonte à chasse fixe¤\idx*\endgroup¤/

\noindent Le cas b contient un argument lui-même entre accolades, c'est-à-dire dans un groupe. En effet, si les accolades intérieures n'existaient pas, cet argument serait «\verb-\bf moi-» et la macro \idx\bf qui ordonne le passage en fonte grasse ne serait pas contenue dans un groupe pour en limiter sa portée. Tel qu'il est écrit à la ligne 4, le second argument est donc \verb-{\bf moi}- et donc le texte de remplacement de \verb-\foo{toi}{{\bf moi}}- est :

\centrecode-Bonjour toi et {\bf moi}.\par-

On remarque ensuite au cas c que les deux arguments ne produisent rien. Le premier parce que c'est un
 \idx[!vide]{argument} vide et le second parce que c'est \verb-{}- qui est un groupe vide qui lui non plus ne produit non plus aucun affichage. Pour mieux comprendre ce qui se passe à cette ligne 5, le texte de remplacement de \verb-\foo{}{{}}- est :

\centrecodespc-Bonjour  et {}.\par-

L'argument \verb|#1|, qui est vide, se trouve entre les deux premiers espaces qui par conséquent deviennent des espaces consécutifs, mais ils ne le sont pas \emph{dans le code source} ! La règle de \TeX{} concernant les \idx[!consécutifs]{espace} consécutifs ne s'applique donc pas comme on peut l'observer à l'affichage.

\begin{regle}
Si l'argument \verb|<i>| d'une macro est vide, cela équivaudra dans le texte de remplacement de la macro à ce que \verb-#<i>- n'existe pas\idx*{argument!vide}.
\end{regle}

Le sens d'un argument «vide» n'est pas évident. On entend ici que l'argument vide est ce qui est entre les accolades dans «\verb-{}-». Si l'on préfère, un argument vide n'est constitué d'aucun token.

Ce qui se passe au cas d est tout aussi intéressant. Les deux arguments sont des espaces \emph{entre accolades}, ils sont donc pris en compte. Le texte de remplacement est ici :

\begin{centrage}
\small\verb*-Bonjour -\fboxsep0.5pt\fbox{\ttfamily\vphantom A\textvisiblespace}\verb*- et -\fbox{\ttfamily\vphantom A\textvisiblespace}\verb-.-
\end{centrage}

\noindent Les arguments \verb-#1- et \verb-#2-, qui sont des espaces, ont été encadrés. L'espace du code «\verb*- -», suivi de l'espace qui provient de l'argument {\fboxsep0.5pt\fbox{\ttfamily\vphantom A\textvisiblespace}}, ne sont pas des espaces consécutifs \emph{du code}. La règle qui veut que deux espaces consécutifs du code n'en font qu'un \emph{ne s'applique pas}. À l'affichage, on a donc \emph{trois} espaces entre «Bonjour» et «et» puis deux entre «et» et le point final.
\grandsaut

Lorsque \TeX{} lit le \idx{texte de paramètre} puis le \idx{texte de remplacement} d'une macro pour la définir et stocker les tokens qui résultent de cette lecture, il entre dans ce qu'on appelle la \emph{\idx{lecture à grande vitesse}}. Très peu de vérifications sont faites à ce moment :

\begin{enumerate}
	\item dans le \idx{texte de paramètre}, la déclaration des arguments \verb|#<chiffre>| n'est acceptée que si les \verb|<chiffres>| commencent à 1 et vont en croissant de un en un;
	\item une occurrence de \verb|#<chiffre>| dans le \idx{texte de remplacement}, symbolisant l'emplacement d'un argument, est acceptée uniquement si cet argument a été déclaré dans le \idx{texte de paramètre};
	\item \TeX{} vérifie que les macros rencontrées dans le \idx{texte de remplacement} ne sont pas déclarées «\idx\outer» (voir page~\pageref{outer});
	\item la \idx{lecture à grande vitesse} s'arrête lorsque l'accolade ouvrante marquant le début du \idx{texte de remplacement} est équilibrée par une accolade fermante. À ce moment, le stockage du \idx{texte de remplacement} sous forme de tokens a lieu dans la mémoire de \TeX.
\end{enumerate}

L'argument d'une commande ne peut pas contenir la primitive \idx\par. Cette interdiction est en fait un mécanisme de sécurité pour que, si jamais on a oublié de fermer l'accolade qui marque la fin d'un argument, \TeX{} ne tente pas de lire indéfiniment (jusqu'à la fin du document) cet argument : au premier \idx\par rencontré, la compilation est stoppée avec affichage d'un message d'erreur, ce qui limite la zone où l'on doit chercher où il manque une accolade fermante dans le code source. Il est parfois nécessaire de passer outre cette protection si l'on souhaite écrire une macro dont un argument est susceptible de contenir \idx\par. Pour déclarer une macro de ce type, il faut faire précéder \idx[|etc]\def\forbidindex\def{} de la primitive \idx\long. Dans ce cas, on dit que la macro est « longue » par opposition aux autres macros « courtes ».

Il faut noter que si on définit un alias pour \idx\par comme plain-\TeX{} le fait avec \verb-\let\endgraf=\par-, alors, l'alias \idx\endgraf est permis dans l'argument d'une macro même si celle-ci n'est pas déclarée \idx\long. En effet, les arguments d'une macro sont eux aussi lus à grande vitesse\idx*{lecture à grande vitesse} avant d'être insérés sous forme de tokens aux endroits qui leur sont réservés dans le texte de remplacement. Lors de cette \idx{lecture à grande vitesse}, \TeX{} ne tient pas compte de la \verb|\let| égalité; il ne fait que chercher \verb|\par|. L'alias \verb|\endgraf| est parfois bien pratique puisqu'avec cet artifice, tout se passe comme si l'on pouvait mettre un \verb|\par| dans les macros courtes sans avoir besoin de les réécrire pour qu'elles soient longues.

\begin{regle}
Une macro ne peut admettre la primitive \idx\par dans aucun de ses arguments. Elle admet en revanche toute \idx{séquence de contrôle} \verb|\let|-équivalente à \verb|\par|, par exemple \idx\endgraf, définie par plain-\TeX.

Pour définir une macro capable d'accepter \idx\par dans ses arguments, on doit faire précéder \verb|\def| de la primitive \idx\long.
\end{regle}

\section{Perte d'informations lors de la « tokénization »}\label{perte.information.lecture}
Examinons maintenant comment et quand sont lues les « composantes » d'une macro, à savoir son texte de remplacement et ses arguments, et surtout quelles sont les conséquences de cette lecture.

Tout d'abord, il est utile de comprendre que plusieurs moments différents interviennent lorsqu'on utilise une macro :

\begin{itemize}
	\item le moment où elle est définie;
	\item le (ou les) moment(s) où elle est appelée.
\end{itemize}

\begin{regle}
Lorsqu'une macro est \emph{définie}, les arguments figurant dans le \idx{texte de remplacement} sous la forme \verb|#<chiffre>| (où «\verb|#|» symbolise un token ayant le catcode \number\catcode`\#\relax{} au moment de la définition) sont des endroits où \TeX{} mettra les arguments lus plus tard lorsque la macro sera appelée.

Lors de sa \idx{lecture à grande vitesse}, le reste du texte de remplacement est « tokénizé » c'est-à-dire que les caractères composant le code source sont transformés en tokens et les catcodes qui leur sont assignés obéissent au régime en cours lorsque la définition a lieu. Ces tokens sont stockés dans la mémoire de \TeX.
\medskip

Lorsqu'une macro est \emph{appelée} et qu'elle \emph{lit} ses arguments, ceux-ci sont lus à grande vitesse\idx*{lecture à grande vitesse} et sont tokénizés selon le régime de catcode en vigueur cette macro est appelée (et qui peut donc différer de celui en cours lors de sa définition). Ils sont ensuite insérés aux endroits où \verb|#<chiffre>| était écrit dans le texte de remplacement. Les tokens du \idx{texte de remplacement} ne sont pas modifiés et restent ce qu'ils étaient lors de la définition.
\end{regle}

Plus généralement, quels que soient le moment et les circonstances, lorsque \TeX{} lit du code source, les caractères du code source sont transformés en tokens. Cette transformation est faite selon le régime de catcode en vigueur au moment de la lecture et des règles spécifiques à chaque catégorie sont alors appliquées. Il est important de savoir que transformer des caractères en tokens provoque d'irréversibles pertes d'informations. En voici quelques-unes :

\begin{enumerate}
	\item plusieurs \idx[!consécutifs]{espace}s consécutifs sont lus comme un espace unique;
	\item les \idx[!début de ligne]{espace}s au début d'une ligne du code source sont ignorés ;
	\item les espaces qui suivent une \idx{séquence de contrôle} sont ignorés;
	\item un caractère de \idx*{catcode!5 (retour charriot)}catcode 5 (en général le retour charriot «\verb|^^M|») est lu comme un espace\idx*[!5 (retour charriot)]\catcode\verbidx*[ (retour charriot)]{^^M};
	\item deux caractères consécutifs de catcode 5 sont lus comme la primitive \idx\par\verbidx*[ consécutifs]{^^M};
	\item deux caractères identiques de catcode \number\catcode`\^{}\idx*{catcode!7 (exposant)} (en général le caractère de mise en exposant «\verb|^|») suivis d'un caractère ou de deux chiffres hexadécimaux sont lus comme un caractère unique\verbidx*{^^}\iffalse i\fi;
	\item le caractère de code \idx\endlinechar est inséré à chaque fois qu'une \idx{fin de ligne} de code source est rencontrée ;
	\item dans une ligne de code source, tout ce qui se trouve après un caractère de catcode \number\catcode`\%{} est ignoré (le caractère de commentaire est en général «\cidx\%»).
\end{enumerate}

Par exemple, supposons qu'une macro \verb|\foo| est définie de cette façon sous le régime de catcode par défaut :

\centrecodespc|\def\foo{Programmer  en \TeX {} est   facile}|

\noindent Par la suite, en examinant le texte de remplacement de \verb|\foo|, il est impossible de savoir combien d'espaces il y avait après «\texttt{est}» dans le code source. Il est également impossible de savoir si \verb|\TeX| était suivi d'un espace, de plusieurs ou d'aucun. Et donc, une façon \emph{strictement équivalente} de définir \verb|\foo| aurait été :

\centrecodespc|\def\foo{Program^^6der en   \TeX{} est facile}|

La primitive \idx\meaning peut nous aider à le constater.

\showcode|\def\foo{Programmer  en \TeX {} est   facile}
\meaning\foo\par¤\idx*\meaning¤
\def\foo{Program^^6der en   \TeX{} est facile}
\meaning\foo¤\idx*\meaning¤|

\begin{regle}
Lorsque \TeX{} lit du code source, d'irréversibles pertes d'informations ont lieu lorsque des \emph{caractères} sont transformés en \emph{\idx{token}s}.
\end{regle}

Cette règle s'applique bien évidemment lorsque \TeX{} lit du code pour le stocker (que ce soit dans une macro ou dans un registre de tokens) ou pour l'exécuter.

\begin{exercice}
Donner un autre exemple de perte d'information lorsque \TeX{} lit du code.
\solution
Si deux caractères ont le catcode 0\idx*{catcode!0 (caractère d'échappement)} (par exemple «\verb|\|» et «\verb-|-»), voici deux façons parfaitement équivalentes de définir une macro \verb|foo| :

\centrecodespc-\def\foo{Programmer en |TeX{} est facile}-

\noindent et

\centrecodespc-\def\foo{Programmer en \TeX{} est facile}-

Si par ailleurs, "\verb|<|" et "\verb|>|" ont comme catcode 1\idx*{catcode!1 (accolade)} et 2, alors, cette façon est également équivalente :

\centrecodespc*-\def\foo<Programmer en \TeX<> est facile}-

Une autre perte d'information est que les caractères ayant un catcode égal à 9 sont ignorés.
\end{exercice}

\begin{exercice}
Comment faudrait-il s'y prendre pour que la lecture du code soit \emph{réversible}, c'est-à-dire pour qu'aucune perte d'information n'ait lieu ?
\solution
Il faudrait que le régime de catcode en vigueur soit très spécifique et que tous les caractères ayant un catcode de 0, 1, 2, 5, 6, 9, 10, 13, 14 et 15 aient un catcode de 12. On peut aussi carrément utiliser le régime où \emph{tous} les octets ont un catcode égal à 12.
\end{exercice}

\section{\Qu elques commandes utiles}
Prenons maintenant le temps de définir des commandes utiles en programmation. Certes, il est encore tôt pour comprendre leur intérêt, mais nous le verrons plus tard, leur emploi est fréquent.

La plus simple de toutes est pourtant très utile : elle lit un argument qu'elle fait disparaitre. Appelons-la\footnote{Cette macro est appelée {\ttfamily\string\@gobble} dans le noyau \LaTeX.} §\gobone pour «gobble one» qui signifie «mange un». Le code qui permet sa définition est d'une simplicité extrême :

\centrecode-\def\gobone#1{}-

\noindent Le texte de remplacement est vide, ce qui revient à dire que lorsque \TeX{} rencontre \verb-\gobone-, il lit également l'argument qui suit et remplace le tout par le texte de remplacement, c'est-à-dire rien.

Pour rester dans la simplicité, voici une commande qui admet un argument et dont le texte de remplacement est cet argument. Appelons-la\footnote{Son nom dans le noyau \LaTeX{} est \texttt{\string\@firstofone}} §\identity\label{identity} :

\centrecode-\long\def\identity#1{#1}-

Voici maintenant deux commandes très utilisées. Elles admettent deux arguments. Le texte de remplacement de §\firstoftwo est son premier argument et celui §\secondoftwo est son second argument\footnote{Elles sont appelées \texttt{\string\@firstoftwo} et \texttt{\string\@secondoftwo} dans le noyau \LaTeX.}\label{firstoftwo}

\centrecode-\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}¤§*\secondoftwo¤-

On pourrait aller plus loin et définir, pourquoi pas, \verb|\thirdofsix| qui irait chercher le 3\ieme{} argument d'une série de 6 :

\centrecode-\long\def\thirdofsix#1#2#3#4#5#6{#3}-

\noindent Mais ces variantes sont un peu inutiles, car ce sont les macros §\firstoftwo et §\secondoftwo qui sont le plus souvent utilisées. Pourquoi est-il plus utile et fréquent de choisir entre \emph{deux} arguments ? L'explication tient au fait que ces macros sont utilisées après un test pour choisir une des alternatives, l'une correspondant au fait que le test est vrai et l'autre qu'il est faux.

\begin{exercice}
Pour manger les deux arguments \verb-{<arg1>}- et \verb-{<arg2>}-, le code suivant ne fonctionne pas :
\centrecode-\gobone\gobone{<arg1>}{<arg2>}-

Pourquoi ? Comment faudrait-il programmer la macro §\gobtwo pour qu'elle mange et fasse disparaitre les deux arguments qui la suivent ?
\solution
\TeX{} lit le code \emph{de gauche à droite}, il remplace donc dans un premier temps §\gobone et son argument, le deuxième §\gobone, par le texte de remplacement de §\gobone, c'est-à-dire rien. Les deux §\gobone disparaissent et il reste les deux arguments entre accolades qui seront affichés tous les deux !

La macro §\gobtwo se programme ainsi : \verb-\def\gobtwo#1#2{}-
\end{exercice}

\begin{exercice}
\Qu 'obtient-on à l'affichage si on écrit :

\centrecode-\gobone1\secondoftwo2{3\gobtwo}\firstoftwo45\secondoftwo{67}{\gobone890}¤§*\secondoftwo¤-

\solution
Procédons de gauche à droite, comme \TeX{} :
\begin{itemize}
	\item «\verb-\gobone 1-» disparait;
	\item «\verb-\secondoftwo2{3\gobtwo}-» a comme texte de remplacement son 2\ieme{} argument qui est «\verb-3\gobtwo-». «3» est donc affiché et le \verb-\gobtwo- va manger les 2 arguments qui le suivent. Ils se trouvent en dehors de l'argument en cours et ce sont «§\firstoftwo\verb-4-» qui sont donc mangés;
	\item «5» est affiché;
	\item «\verb-\secondoftwo{67}{\gobone890}-» a pour texte de remplacement son 2\ieme{} argument qui est «\verb-\gobone890-». Le \verb|\gobone| mange le «8» qui disparait et il reste donc les tokens «90» qui seront affichés.
\end{itemize}

On obtient donc «\verb-3590-»
\end{exercice}
\begin{exercice}
On constate que les macros §\gobone et §\secondoftwo donnent les mêmes résultats :

\showcode/a) \gobone XY - \secondoftwo XY\par¤§*\gobone§*\secondoftwo¤
b) \gobone{ab}{xy} - \secondoftwo{ab}{xy}\par
c) \gobone{123}4 - \secondoftwo{123}4\par
d) \gobone A{BCD} - \secondoftwo A{BCD}¤§*\gobone§*\secondoftwo¤/

Existe-t-il une différence entre les macros §\gobone et §\secondoftwo et si oui, laquelle ?
\solution
Il y a une différence, et de taille! On peut le voir sur cet exemple :

\showcode/\gobone     {a}{\catcode`\~12 Le <<~>> est un espace ?} Et ici <<~>> ?¤\cidx*\~¤

\secondoftwo{a}{\catcode`\~12 Le <<~>> est un espace ?} Et ici <<~>> ?¤§*\secondoftwo¤/

À la première ligne, lorsque §\gobone est développée, «\verb|\gobone{a}|» disparait et il reste ceci qui n'a pas encore été lu :

\centrecode*-{\catcode`\~12 Le <<~>> est un espace ?} Et ici <<~>> ?-

Il est clair que la modification de catcode a lieu \emph{à l'intérieur d'un groupe} et que dans ce groupe, \cidx\~ devient un caractère « autre » que l'on peut afficher tel quel. En revanche, une fois sorti du groupe, il reprend son catcode naturel de 13 et redevient donc actif pour afficher une espace insécable.

Tout est différent dans la deuxième ligne. La macro §\secondoftwo lit ses \emph{deux} arguments et «redonne» le second une fois qu'il a été lu. Voici donc ce qu'il reste après que §\secondoftwo ait été remplacé pare son 2\ieme{} argument :

\begin{centrage}
	\small\ttfamily\fboxsep2pt\fbox{\string\catcode`\string\~12 Le <{}<\string~>{}> est un espace \string?} \Verb|Et ici <<~>> ?|
\end{centrage}

Le 2\ieme{} argument, ici encadré et qui s'étend jusqu'au premier «\string?» a été lu par §\secondoftwo et donc, le \idx{catcode} de «\string~» est figé à 13. Par conséquent, «\string~» gardera dans tout l'argument encadré le \idx{catcode} 13\idx*{catcode!13 (actif)} qu'il avait lorsque §\secondoftwo a été appelé. L'ordre \idx\catcode\verb|`\~12| rencontré dans l'argument ne pourra agir qu'après cet argument : \cidx\~ prendra donc le \idx{catcode} 12\idx*{catcode!12 (autre)} après la fin de l'argument et ce en-dehors de tout groupe. Il gardera donc ce \idx{catcode} indéfiniment c'est-à-dire jusqu'à ce qu'il soit volontairement modifié.
\grandsaut 

Pour résumer :
\begin{itemize}
	\item de «§\gobone\verb|{<a>}{<b>}|», il reste \verb|{<b>}|qui n'est pas encore lu;
	\item tandis que §\secondoftwo\verb|{<a>}{<b>}| lit le second argument, le dépouille de ses accolades et le tout devient donc \verb|<b>| où les catcodes sont figés.
\end{itemize}
\end{exercice}

\begin{exercice}
Le but est d'afficher l'énoncé et la correction d'une courte interrogation de grammaire élémentaire, tous deux stockés dans la macro \verb-\interro- ainsi définie :

\centrecode-\def\interro{J'ai ét\?{é} invit\?{é} à goût\?{er} chez Max.
             On s'est bien amus\?{é} et ensuite, il a fallu
             rentr\?{er}.}-

Écrire une macro \verb-\?- qui admet un argument. Cet argument sera affiché tel quel si la commande \verb-\visible- a été rencontrée auparavant, et si c'est la commande \verb-\cache-, cet argument sera remplacé par «...». Les commandes \verb-\cache- et \verb-\visible- n'admettent pas d'argument.

On écrira «\verb-\cache\interro-» ou «\verb-\visible\interro-» selon que l'on souhaite afficher l'énoncé ou la correction.
\solution
L'idée est que le texte de remplacement de \verb-\?{<argument>}- doit être

\centrecode-\choix{<argument>}{...}-

\noindent où \verb-\choix- sera rendu égal à §\firstoftwo par \verb-\visible- et à §\secondoftwo par \verb-\cache- :

\showcode/\def\visible{\let\choix=\firstoftwo}¤§*\firstoftwo¤
\def\cache{\let\choix=\secondoftwo}¤§*\secondoftwo¤
\def\?#1{\choix{#1}{...}}%
\def\interro{J'ai ét\?{é} invit\?{é} à gout\?{er} chez Max. Après s'être
             bien amus\?{é}, nous avons rang\?{é} et il a fallu rentr\?{er}.}
Compléter avec << é >> ou << er >> :\par
\cache\interro\par\medskip¤\idx*\medskip¤
Correction :\par
\visible\interro/
\end{exercice}

\section{Définitions imbriquées}
À l'exercice précédent, on aurait pu procéder de façon plus « économique », sans avoir besoin de définir une macro auxiliaire \verb|\choix|. La macro \verb|\visible| aurait pu être programmée pour définir \verb|\?| \idx\let{}-égale à §\identity (qui affiche son argument tel quel) alors que la macro \verb|\cache| aurait défini la macro \verb|\?| de cette façon :

\centrecode-\def\?#1{...}-

\noindent Mais si on écrit

\centrecode-\def\cache{\def\?#1{...}}-

\noindent \TeX{} émet un message d'erreur : «\texttt{Illegal parameter number in definition of \string\cache}». L'explication est que l'argument \verb|#1| est compris comme étant celui de la macro \emph{extérieure} \verb|\cache| et non pas comme celui de la macro intérieure \verb|\?|. L'erreur survient, car la macro extérieure \verb|\cache| est définie comme n'ayant \emph{aucun} argument.

Lorsque des définitions de macros sont imbriquées, la règle veut que pour distinguer les arguments des macros, il faut doubler les tokens de paramètre \verb|#| à chaque niveau d'imbrication supplémentaire. Ainsi, la bonne façon de définir \verb|\cache| est :

\centrecode-\def\cache{\def\?##1{...}}-

Voici le code complet :

\showcode/\def\visible{\let\?=\identity}¤§*\identity¤
\def\cache{\def\?##1{...}}
\def\interro{J'ai ét\?{é} invit\?{é} à goût\?{er} chez Max. On s'est
             bien amus\?{é} et ensuite, il a fallu rentr\?{er}.}
Compléter avec << é >> ou << er >> :\par
\cache\interro\par\medskip¤\idx*\medskip¤
Correction :\par
\visible\interro/

\begin{regle}
Lorsqu'on définit une macro « fille »\idx*{macro fille} dans le \idx{texte de remplacement} d'une macro « mère », les \verb-#- concernant les arguments de la macro fille sont doublés, aussi bien dans le \idx{texte de paramètre} que dans le \idx{texte de remplacement}.

Ils seront doublés à nouveau à chaque imbrication
 supplémentaire pour éviter de confondre les arguments des macros imbriquées.
\end{regle}
\grandsaut

À la lumière de ce qui vient d'être dit, examinons maintenant le code suivant :

\centrecodespc-\def\makemacro#1#2{\def#1##1{##1 #2}}-

On constate que \verb|\makemacro| admet deux arguments et que le premier est nécessairement une \idx{séquence de contrôle} puisque cet argument \verb|#1| se trouve juste après le \verb|\def| dans le texte de remplacement.

Faisons mentalement fonctionner la macro \verb|\makemacro| lorsqu'on l'appelle de cette façon : \verb|\makemacro\foo{BAR}|. Comme on le sait, le texte de remplacement de ce code va être obtenu en remplaçant chaque \verb|#1| par \verb|\foo| et chaque \verb|#2| par \verb|BAR| ce qui donne :

\centrecodespc-\def\foo##1{##1 BAR}- 

\noindent Puisqu'on examine le code contenu dans le texte de remplacement, il devient inutile de doubler les tokens de paramètre et donc, tout se passe donc comme si la macro \verb|\foo| était définie par :

\centrecodespc-\def\foo#1{#1 BAR}-

Le code obtenu ne présente pas de difficulté particulière, l'argument \verb|#1| de \verb|\foo| est placé devant l'argument \verb|#2| de \verb|\makemacro| qui est \verb|BAR|. Par exemple, si l'on écrivait «\verb-\makemacro\mai{mai 2014}-», alors par la suite, \verb-\mai{10}- aurait comme texte de remplacement «\texttt{10 mai 2014}».

\showcode/\def\makemacro#1#2{\def#1##1{##1 #2}}
\makemacro\LL{Lamport}
\makemacro\juin{juin 2014}
Paris, le \juin{3}.\medbreak¤\idx*\medbreak¤
\LL{Cher Monsieur},\smallbreak¤\idx*\smallbreak¤
Vous êtes convoqué à un examen sur \TeX{} le \juin{21} à
9h00 précise dans le bureau de D. Knuth.\smallbreak¤\idx*\smallbreak¤
Veuillez croire, \LL{Monsieur}, en mes sentiments \TeX iens./

\section{Programmer un caractère actif}
Le niveau de \TeX nicité atteint dans cette section est plutôt relevé. On pourra donc, lors d'une première lecture, se dispenser de se plonger dans cette section, quitte à y revenir plus tard.
\grandsaut

Avant de rentrer dans le vif du sujet, rappelons ce qu'est réellement un caractère. Aux yeux de \TeX{} lorsqu'il le lit, un caractère (c'est-à-dire un token n'étant pas une \idx{séquence de contrôle}) est constitué de :
\begin{itemize}
	\item un code dit «\idx{code de caractère}» qui représente l'ordre du caractère dans la table des caractères. Par exemple, le caractère «\verb|A|» a le code de caractère \number`A{} tandis que «\verb|^|» a le code \number`\^. Il y a 256 codes\footnote{Pour les moteurs 8 bits, il y a effectivement 256 codes possibles. En revanche, pour les moteurs \utf, il y a en a bien plus.} possibles;
	\item un code dit «code de catégorie» ou «catcode» qui met le caractère dans une des 16 catégories et lui confère les propriétés communes à tous les caractères de cette catégorie. Ainsi, «\verb|A|» a le code de catégorie \number\catcode`A, et «\verb|^|» le code de catégorie \number\catcode`\^.
\end{itemize}

Chaque caractère lu possède donc intrinsèquement une \emph{paire de codes}. On peut convenir d'une notation et les mettre entre parenthèses, le premier étant le code de caractère et le second le catcode. Cela donnerait : \showcodes{A} et \showcodes^.
\grandsaut

L'objet ici est de découvrir comment on peut programmer une macro --~appelons-la §\defactive~-- qui rend actif un caractère choisi par l'utilisateur et qui lui donne un texte de remplacement donné. Ainsi, «\verb-\defactive W{wagons}-» fera qu'après cet appel, le caractère «\verb|W|» sera actif et son texte de remplacement sera «wagons».

Comme nous l'avons vu, si on modifie un catcode dans le texte de remplacement d'une macro, la modification n'entrera en vigueur qu'après ce texte de remplacement. En effet, la règle vue à la page~\pageref{catcode.inalterable} veut que lorsqu'un argument est lu, les catcodes des tokens qui le composent sont figés. Il est donc exclu de programmer la macro de cette façon

\centrecode-\def\defactive#1#2{\catcode`\#1=13 \def#1{#2}}-§*\defactive

\noindent car, malgré l'ordre \verb|\catcode`\#1=13|, le catcode de \verb-#1- ne serait pas modifié à l'intérieur du texte de remplacement de §\defactive. Par exemple, si \verb-#1- est «\verb|W|», son catcode restera 11 (celui que \verb|W| a par défaut) et \TeX{} va échouer lorsqu'il rencontrera \verb|\def|\verb- W{wagons}-, car «\verb|W|» ne sera pas encore actif.

Évidemment, on l'a vu aussi, on pourrait utiliser un \idx\gdef et agir dans un groupe où l'on aurait déjà modifié le catcode de «\verb|W|» à 13. Cette méthode est possible lorsqu'on connaît \emph{à l'avance} le caractère à rendre actif. Or, ce n'est pas le cas ici puisque l'argument \verb-#1- de la macro est choisi par l'utilisateur.
\grandsaut

Intéressons-nous par exemple à la primitive \idx\lowercase{} car les fonctionnements de \idx\lowercase{} et \idx\uppercase{} sont symétriques : il suffit de comprendre comment fonctionne l'une pour comprendre comment fonctionne de l'autre.

Avant d'entrer dans le vif du sujet, il faut mentionner qu'en plus du code de catégorie et du code de caractère, chaque caractère possède deux autres codes :

\begin{itemize}
 	\item le \idx{code minuscule} accessible par la primitive \idx\lccode;
 	\item le \idx{code majuscule} accessible par la primitive \idx\uccode.
\end{itemize}

Par exemple, le code de caractère de la lettre «A» est {\number`\A} et son code minuscule est {\number`\a} qui est celui de la lettre «a». Il en est ainsi pour chaque lettre majuscule de l'alphabet qui possède un code minuscule correspondant à celui de la lettre minuscule. Grâce à la primitive \idx\the ou \idx\number, on peut afficher les codes de caractère et les codes minuscules des lettres A, B, et même de a, b. On va utiliser ici une macro \verb-\showcodes- pour alléger le code :

\showcode/\def\showcodes#1{\string#1 : $\number`#1 \rightarrow \number\lccode`#1$}¤\idx*\string\idx*\number\idx*\rightarrow\idx*\the\idx*\lccode¤
\showcodes A\qquad \showcodes B\qquad¤\idx*[|etc]\qquad\forbidindex\qquad¤
\showcodes a\qquad \showcodes b\qquad \showcodes ^/

On observe que logiquement, le \idx{code minuscule} de «a» est le sien propre. \Qu ant au code minuscule de «\verb|^|», il est égal à 0 ce qui signifie que ce caractère n'a pas de code minuscule prédéfini.

\begin{regle}
La primitive \idx\lowercase doit être suivie de son argument entre accolades et cet argument, constitué d'un texte dont les accolades sont équilibrées, est lu de la façon suivante :

\begin{itemize}
	\item les séquences de contrôles restent inchangées;
	\item pour chaque caractère, le code de caractère est remplacé par le \idx{code minuscule}, étant entendu que le code de catégorie \emph{ne change pas}.
	
	Si le code minuscule d'un caractère est nul, ce caractère n'est pas modifié par \idx\lowercase.
\end{itemize}
\end{regle}

Voici la primitive \idx\lowercase en action :

\showcode/\lowercase{CACAO foobar}\par¤\idx*\lowercase¤
\lowercase{\def\foo{Bonjour}}% définit une commande \foo
\foo % la commande définie précédemment/

On peut détourner la primitive \idx\lowercase de son usage premier qui est de mettre un texte en minuscule. Pour cela, il suffit de modifier le code minuscule d'un caractère. Supposons que nous souhaitions que le \idx{code minuscule} de «A» ne soit plus {\number`\a} qui est celui de la lettre «a», mais {\number`\*} qui est celui de «\verb-*-». Pour cela, il va falloir modifier le \idx\lccode de «A» à l'intérieur d'un groupe semi-simple, puisqu'il est toujours prudent de confiner les modifications lorsqu'on touche aux mécanismes internes de \TeX{} :

\showcode/\begingroup¤\idx*\begingroup¤
	\lccode`A=`* % change le code minuscule de A¤\idx*\lccode¤
	\lowercase{CACAO ABRACADABRA}\par¤\idx*\lowercase¤
\endgroup¤\idx*\endgroup¤
\lowercase{CACAO ABRACADABRA}/

Les «*» que l'on obtient ont le catcode de A, c'est-à-dire 11.

\begin{regle}
Si l'on écrit «\verb|\lccode<entier1>=<entier2>|» alors, dans l'argument de \verb|\lowercase|, tous les caractères de code \verb|<entier1>| seront lus comme des caractères de code \verb|<entier2>| tout en gardant leur catcode originel.

En pratique, si l'on écrit

\centrecode-\lccode`\<car1>=`\<car2>-

puis

\centrecode-\lowercase{<texte>}-

alors, dans le \verb|<texte>|, tous les \verb|<car1>| sont lus comme \verb|<car2>|, mais en conservant le catcode de \verb|<car1>|.
\end{regle}

Nous sommes prêts pour écrire la macro §\defactive et nous allons exploiter le fait que le caractère «\cidx\~» est naturellement actif. Grâce à la primitive \idx\lowercase, on va le transformer dynamiquement pour qu'il devienne le caractère \verb-#1- \emph{actif} de notre macro §\defactive :

\centrecode|\def\defactive#1#2{%¤§*\defactive¤
    \catcode`#1=13 % #1 sera actif après la fin
                   % du texte de remplacement
    \begingroup
    \lccode`~=`#1  % dans \lowercase, changer les ~ (actifs)
                   % en "#1", ceux-ci étant actifs
    \lowercase{\endgroup\def~}{#2}%
}|

\begin{itemize}
	\item «\idx\catcode\verb|`#1=13|»\idx*[!13 (actif)]\catcode rend le caractère \verb-#1- actif, mais comme nous l'avons vu, cette modification n'entrera en vigueur qu'après être sorti du texte de remplacement;
    \item Le \idx\endgroup n'étant pas modifié par \idx\lowercase, le groupe semi-simple est donc bien refermé \emph{avant} d'effectuer la définition de \verb-#1-;
	\item on peut remarquer que l'argument \verb-#2- se trouve \emph{en dehors} de l'argument de \idx\lowercase car sinon, toutes les lettres majuscules de \verb|#2| seraient transformées en minuscules.
	
	D'ailleurs, comme \verb-{#2}- est à la fin du texte de remplacement de la macro, il devient inutile de le lire puisqu'il sera lu juste après. On peut optimiser la macro de cette façon\label{argument.def} :
	
	\centrecode-\def\defactive#1{%¤§*\defactive¤
	\catcode`#1=13
	\begingroup
	\lccode`~=`#1
	\lowercase{\endgroup\def~}}-
\end{itemize}

Voyons cette macro à l'\oe uvre dans un exemple :

\showcode/\def\defactive#1{%¤§*\defactive¤
	\catcode`#1=13
	\begingroup
	\lccode`~=`#1
	\lowercase{\endgroup\def~}%
}
\begingroup% les modifications restent locales¤\idx*\begingroup¤
	\defactive W{wagons}% définit le caractère actif "W"¤§*\defactive¤
	Les W constituent les trains.
\endgroup %fermeture du groupe, "W" redevient une lettre¤\idx*\endgroup¤
\par Les W sont des lettres/

\begin{exercice}
Supposons que «\verb-W-» soit rendu actif à l'aide de la macro §\defactive pour lui donner le texte de remplacement «wagons». Imaginons ensuite que l'on rende «\verb|W|» non actif avec \idx\catcode\verb-`\W=11-.

\Qu estion : si l'on rend à nouveau \verb|W| actif, le texte de remplacement précédemment défini existe-t-il encore ou faut-il redéfinir son texte de remplacement ?
\solution
Il suffit de faire l'expérience :

\showcode/\defactive W{wagon}¤§*\defactive¤
1) Les W constituent le train.\par
2) \catcode`W=11 Les W sont des lettres.\par¤\idx*\catcode¤
3) \catcode`\W=13 Les W constituent-ils le train ?/

La réponse est donc « oui ».

Le \idx[!caractère actif]{texte de remplacement} d'un caractère actif n'est pas perdu si ce caractère change de catcode et redevient actif ensuite.
\end{exercice}

\begin{exercice}
Décrire ce qui va se passer si on définit le caractère actif «\verb|W|» de la façon suivante :
\centrecode-\defactive W{Wagon}-

\solution
Tout dépend de la version de §\defactive. La réponse est très différente selon que §\defactive lit 1 ou 2 arguments, c'est-à-dire si elle lit le texte de remplacement du caractère actif ou pas.

Si elle le lit, le «\verb|W|» de «\verb|Wagon|» aura le catcode en vigueur au moment ou §\defactive lit son argument, c'est-à-dire 11\idx*{catcode!11 (lettre)}. Le texte de remplacement de «\verb|W|» sera «\verb|Wagon|» où toutes les lettres ont le catcode 11.

\showcode|\def\defactive#1#2{%¤§*\defactive¤
	\catcode`#1=13 % #1 sera actif après la fin du texte de remplacement
	\begingroup
	\lccode`~=`#1  % dans \lowercase, changer les ~ (actifs) en "#1", ceux-ci étant actifs
	\lowercase{\endgroup\def~}{#2}%
	}
\defactive W{Wagon}
Un W.|

Si §\defactive ne lit pas le texte de remplacement (version «optimisée»), le caractère «\verb|W|» sera actif à la fin du texte de remplacement et donc, lorsque \verb|\def W| lira le texte de remplacement entre accolades, le «\verb|W|» de «\verb|Wagon|» sera actif. On entrevoit ce qui va se passer lorsque \verb|W| sera exécuté. Dans un premier temps, \verb|W| va être remplacé dans la \idx{pile d'entrée} par

\centrecode-Wagon-

puis le premier «\verb|W|», actif, sera exécuté et donc, nous aurons dans la \idx{pile d'entrée}

\centrecode-Wagonagon-

Le \verb|W| actif généré sera à nouveau exécuté et ainsi de suite\ldots{} Une \idx{boucle infinie} va s'amorcer au cours de laquelle les caractères «\verb|agon|» seront ajoutés sur la \idx{pile d'entrée} à chaque boucle, provoquant rapidement le dépassement de sa capacité et générant le message d'erreur

\errcode|\def\defactive#1{%¤§*\defactive¤
	\catcode`#1=13 % #1 sera actif après la fin du texte de remplacement
	\begingroup
	\lccode`~=`#1 % dans \lowercase, changer les ~ (actifs) en "#1", ceux-ci étant actifs
	\lowercase{\endgroup\def~}%
	}
\defactive W{Wagon}
Un W.|{\ttfamily ! TeX capacity exceeded, sorry [input stack size=5000]}

La morale que l'on peut retirer de cet exercice est qu'une « optimisation », qui de prime abord peut sembler anodine (ne pas faire lire un argument par une macro), conduit à des limitations et à des erreurs de compilation qui n'existaient pas dans une version « non optimisée ». La programmation en \TeX{} est pavée d'embuches\ldots{} Il est donc nécessaire de parfaitement savoir ce que l'on fait, de connaitre le régime de catcodes en cours lorsqu'une lecture est faite et toujours rester vigilant dès lors qu'il est question de lecture d'argument.
\end{exercice}

Les man\oe uvres décrites dans cette section reposent sur la supposition que «\cidx\~» est actif lorsque la macro §\defactive est \emph{définie}. Si ce n'est pas la cas et si, pour une raison ou pour une autre, «\cidx\~» a été neutralisé et mis dans la catégorie des caractères « autres » de catcode 12\idx*{catcode!12 (autre)}, la macro §\defactive ne pourra et provoquera une erreur de compilation lors de son exécution.
\grandsaut

Tout ce qui a été dit avec les primitives \idx\lowercase et \idx\lccode est valable pour leurs symétriques, les primitives \idx\uppercase et \idx\uccode qui agissent sur le « \idx{code majuscule} » d'un caractère. On aurait d'ailleurs tout aussi bien pu procéder avec \idx\uppercase et \idx\uccode.

\showcode|\def\defactive#1#2{%¤§*\defactive¤
	\catcode`#1=13 % #1 sera actif après la fin du texte de remplacement
	\begingroup
	\uccode`~=`#1 % dans \uppercase, changer les ~ (actifs) en "#1", ceux-ci étant actifs¤\idx*\uccode¤
	\uppercase{\endgroup\def~}{#2}%¤\idx*\uppercase¤
}
\defactive W{Wagon}
Un W.|

Une macro à peu près similaire §\letactive\verb|<token><token>| est facile à programmer :

\showcode|\def\letactive#1{%¤§*\letactive¤
	\catcode`#1=13 % #1 sera actif après la fin du texte de remplacement
	\begingroup
	\uccode`~=`#1 % dans \uppercase, changer les ~ (actifs) en "#1", ceux-ci étant actifs¤\idx*\uccode¤
	\uppercase{\endgroup\let~}%¤\idx*\uppercase¤
}
\def\W{wagon}%
\letactive X\W¤§*\letactive¤
Un X.|

\section{Afficher du code tel qu'il a été écrit}\label{litterate}\idx*[|(]{verbatim}
Le but est d'inventer une commande qui désactive toutes les règles de \TeX{} pour que son argument soit affiché tel qu'il a été écrit dans le code source, ce que l'on appelle du «verbatim». Cette commande « §\litterate » va donc rendre inoffensifs tous les tokens de catcode autre que 11 ou 12, en changeant leur catcode pour 12. Ces tokens \emph{spéciaux} sont \boxtoken[]\textvisiblespace, \boxtoken[]\textbackslash, \boxtoken[]\{, \boxtoken[]\}, \boxtoken[]\$, \boxtoken[]\&, \boxtoken[]\#, \boxtoken[]{\char`\$}, \boxtoken[]\_, \boxtoken[]\% et \boxtoken[]{\char`\~}. Plain-\TeX{} définit\footnote{En plain-\TeX, les tokens \texttt{\string^\string^K} et  \texttt{\string^\string^A} sont des équivalents pour «\texttt{\string^}» et «\texttt{\string_}».} la macro \idx\dospecials de cette façon :

\indentcode[7em]-\def\dospecials{\do\ \do\\\do\{\do\}\do\$\do\&%
  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~}-

La macro \idx\do peut être programmée comme on l'entend pour agir sur son argument. Ici, comme le but est de changer le catcode de cet argument pour 12, on va donc la programmer ainsi :

\centrecode-\def\do#1{\catcode`#1=12 }-

\noindent et il suffira d'appeler \idx\dospecials pour qu'à partir de ce moment, tous les tokens spéciaux soient inoffensifs et deviennent affichables.

En ce qui concerne la syntaxe de §\litterate, il serait légitime d'écrire son argument entre accolades, mais cela rendrait la tâche compliquée. En effet, cette macro doit rendre tous les tokens spéciaux inoffensifs \emph{avant} de lire son argument. Par conséquent, les accolades délimitant l'argument ne seraient pas de \emph{vraies} accolades de catcode 1\idx*{catcode!1 (accolade)} et 2, mais des accolades de catcode 12\idx*{catcode!12 (autre)}. Pour savoir où se situe la fin de l'argument, il faudrait parcourir le code qui se trouve après §\litterate token par token, compter les accolades ouvrantes et fermantes jusqu'à obtenir l'égalité entre ces deux quantités qui signifierait la fin de l'argument. C'est faisable, mais inutilement compliqué et implique comme limitation que le code à afficher soit équilibré en accolades ouvrantes et fermantes. Le mieux est de décider à chaque fois d'un token (de catcode 11\idx*{catcode!11 (lettre)} ou 12\idx*{catcode!12 (autre)}) et de placer l'argument entre deux occurrences de ce token\footnote{C'est la syntaxe adoptée par la macro \texttt{\string\verb} de \LaTeX.}. On peut par exemple écrire

\centrecode-\litterate|\foo # #34{ ~} &_\ |-

\noindent et obtenir l'affichage «\verb|\foo # #34{ ~} &_\ |». La limitation évidente est que le token choisi comme délimiteur ne doit pas figurer dans l'argument.

Du côté de la programmation, la macro §\litterate doit ouvrir un groupe semi-simple puis rendre les tokens spéciaux inoffensifs. À l'aide de la macro §\defactive vue à la section précédente, elle doit aussi rendre actif le retour à la ligne «\verb-^^M-\verbidx*[ (retour charriot)]{^^M}» et lui donner comme texte de remplacement \idx\par\idx\leavevmode. Le \idx\leavevmode, en quittant le mode vertical\idx*{mode!vertical} mis en place par \idx\par{}, entre dans le mode horizontal\idx*{mode!horizontal} et commence un nouveau paragraphe. Sans ce \idx\leavevmode, deux retours à la ligne consécutifs seraient équivalents à deux \idx[!consécutifs]\par et le second serait ignoré (voir règle page~\pageref{par.consecutifs}). De plus, le token frontière choisi doit aussi être rendu actif et pour devenir \idx\let-égal à \idx\endgroup; ainsi, lorsque le second token frontière sera rencontré, le groupe semi-simple sera fermé et tous les catcodes seront restaurés comme avant que la macro §\litterate n'entre en action.

\showcode|\def\litterate#1{% #1=lit le token frontière choisi¤§*\litterate¤
	\begingroup% ouvre un groupe pour y faire les modifications¤\idx*\begingroup¤
		\def\do##1{\catcode`##1=12 }% \do change le catcode de son argument à 12¤\idx*\do\idx*\catcode¤
		\dospecials% rend inoffensifs tous les tokens spéciaux¤\idx*\dospecials¤
		\defactive\^^M{\leavevmode\par}% définit le retour charriot¤§*\defactive\idx*\leavevmode¤
		\letactive#1\endgroup% définit #1 qui sera un \endgroup¤§*\letactive¤
		\tt% passe en fonte à chasse fixe¤\idx*\tt¤
}
essai 1 : \litterate*\foo # #34{ ¤\%¤} &_\ *
\medbreak¤\idx*\medbreak¤
essai 2 : \litterate/une première ligne  ,, >>

un saut de ligne et la seconde --/|

L'ensemble fonctionne bien à part les espaces qui sont rendus avec le mauvais caractère et les certaines \idx{ligature}s qui sont faites à l'essai \no2.

Pour l'espace tout d'abord, cela s'explique car son catcode a été rendu égal à 12 par \idx\dospecials et le caractère «\verb*| |» se trouve à la position de l'espace dans la \idx{fonte} à chasse fixe. Pour contourner ce problème, il faut rendre l'espace actif après l'appel à \idx\dospecials et lui donner comme texte de remplacement la primitive \idx\ {}.

Ensuite, pour les \idx{ligature}s, il faut déjà identifier quels sont les caractères doublés qui forment une \idx{ligature} en fonte à chasse fixe. Ces caractères sont : \boxtoken{`}, \boxtoken{<}, \boxtoken{>}, \boxtoken{,}, \boxtoken{'} et \boxtoken{-}. Pour éviter qu'ils ne forment une \idx{ligature}, il va falloir les rendre actifs et les faire suivre soit de «\verb|{}|», soit de \idx\relax soit encore de \idx\kern\verb|0pt|, ou plus généralement de quelque chose ne se traduisant par aucun affichage. Ainsi, ils sembleront se suivre à l'affichage, mais aux yeux de \TeX{}, ils seront séparés par un n\oe ud\footnote{Un n\oe ud est un élément, visible ou pas, qui entre dans la liste horizontale ou verticale que \TeX{} est en train de construire.} qui empêchera la formation de la \idx{ligature}.

\showcode|\def\litterate#1{% #1=lit le token frontière choisi¤§*\litterate¤
	\begingroup% ouvre un groupe pour y faire les modifications¤\idx*\begingroup¤
		\def\do##1{\catcode`##1=12 }% \do change le catcode de son argument à 12¤\idx*\do\idx*\catcode¤
		\dospecials% rend inoffensifs tous les tokens spéciaux¤\idx*\dospecials¤
		\defactive\^^M{\leavevmode\par}% définit le retour charriot¤\idx*\leavevmode§*\defactive¤
		\defactive\ {\ }% l'espace est actif et devient "\ "
		\defactive<{\string<{}}\defactive>{\string>{}}% empêche¤\idx*\string¤
		\defactive-{\string-{}}\defactive`{\string`{}}% les
		\defactive,{\string,{}}\defactive'{\string'{}}% ligatures¤\idx*{ligature}\idx*\string§*\defactive¤
		\letactive#1\endgroup% #1 sera un \endgroup¤§*\letactive¤
		\tt% passe en fonte à chasse fixe¤\idx*\tt¤
}
essai 1 : \litterate*\foo # #34{ %} &_\ *
\medbreak¤\idx*\medbreak¤
essai 2 : \litterate/une première      ligne  ,, >>

un saut de ligne et la seconde --/¤§*\litterate¤|\idx*[|)]{verbatim}

\chapter{Arguments délimités}\idx*[|(]{argument!délimité}
\section{Théorie}\label{theorie}
Les commandes que l'on définit avec \verb|\def| peuvent également avoir des «arguments délimités». Ces arguments-là ne sont pas lus de la même façon que les arguments «non délimités» que nous avons vus précédemment. On indique à \TeX{} qu'une macro a un ou des arguments délimités lorsque son \idx{texte de paramètre} contient d'autres unités lexicales que \verb-#-$i$ où $i$ est un entier de 1 à 9. Ces unités lexicales sont appelées les délimiteurs.

\begin{regle}
Un argument \verb-#<-$i$\verb|>| est dit «délimité» si, dans le \idx{texte de paramètre}, il est suivi par autre chose que \hbox{\verb-#<-$i$+1\verb|>|} ou que l'accolade «\cidx\{» qui marque le début du \idx{texte de remplacement}.
\end{regle}

Voici un exemple :
\centrecode-\def\foo.#1**#2#3/{Bonjour #1, #2 et #3}-

\noindent Ici, \verb-#1- et \verb-#3- sont les arguments délimités puisqu'ils sont suivis par respectivement «\verb-**-» et «\verb-/-». Par la suite, lorsque \TeX{} va exécuter \verb-\foo-, il s'attendra à ce qu'elle soit immédiatement suivie de «\verb-.-» puis de quelque chose (qui sera l'argument \verb-#1-) qui s'étendra jusqu'à la première occurrence de «\verb-**-», puis autre chose (qui deviendra les arguments \verb-#2#3-) qui s'étendra jusqu'à la première occurrence de «\verb-/-». Ayant défini la commande  \verb-\foo- avec le code précédent, supposons que l'on écrive :
\centrecode-\foo.ab{123}c**xyz/-

\noindent Dans ce cas, \verb-#1- sera «\verb*-ab{123}c-». \Qu ant aux tokens «xyz», ils sont à répartir entre \verb-#2- et \verb-#3- selon la règle suivante :

\begin{regle}
Lorsqu'une macro est exécutée et qu'elle doit lire une suite de $n$ arguments dont le dernier est délimité, les $n-1$ premiers arguments sont assignés comme des arguments non délimités. Le dernier argument reçoit ce qui reste jusqu'au délimiteur, ceci étant éventuellement vide.
\end{regle}

D'après cette règle, l'argument \verb-#2- de l'exemple précédent n'est pas délimité et sera «\verb|x|». L'argument \verb-#3- qui est délimité sera donc qu'il reste jusqu'au délimiteur «\verb|/|» c'est-à-dire «\verb|yz|». Le texte de remplacement sera donc :
\centrecode-Bonjour ab123c, x et yz.-

\begin{regle}
Dans tous les cas, qu'il soit délimité ou pas, si un argument est de la forme \verb-{<tokens>}-, où \verb-<tokens>- est un ensemble d'unités lexicales où les accolades sont équilibrées, alors \TeX{} \emph{supprime les accolades extérieures} et l'argument lu est «\verb-<tokens>-».\idx*{argument!suppression d'accolades}
\end{regle}

Un cas particulier de cette règle engendre une autre règle :

\begin{regle}
Un argument délimité est vide si l'ensemble des tokens qui lui correspond est vide ou «\verb-{}-».\idx*{argument!vide}%
\end{regle}

Ainsi, si on définit la macro \verb|\bar| ainsi :

\centrecode-\def\bar#1#2#3+{L'argument délimité est : "#3".}-

\noindent Alors, l'argument \verb|#3| est vide dans ces deux cas :
\begin{itemize}
	\item «\verb-\bar{123}x+-» car «\verb|123|» et «\verb|x|» sont les 2 premiers arguments et il ne reste rien pour le troisième;
	\item «\verb-\bar{a}{b}{}+-» car \verb|#3| reçoit «\verb|{}|».
\end{itemize}
En revanche, si on avait écrit \verb-\bar{a}{b}{}{}+-, l'argument délimité aurait été «\verb-{}{}-» ce qui n'est pas un argument vide.
\grandsaut

Plutôt que d'envisager un par un de nombreux cas, voici un tableau qui affiche ce que seraient les arguments \verb-#1-, \verb-#2- et \verb-#3- dans plusieurs cas de figure avec la définition de \verb-\foo- rappelée en haut du tableau :

\begin{centrage}
\small
\makeatletter
\def\fooa.#1**#2#3/{\textvide#1|}
\def\foob.#1**#2#3/{\textvide#2|}
\def\fooc.#1**#2#3/{\textvide#3|}
\def\textvide#1|{%
	\ifx_#1_<vide>%
	\else\ttfamily{\everyeof{\relax}\endlinechar\m@ne\catcode`\{=12 \catcode`\}=12 \catcode32=12 \scantokens{#1\relax}}%
	\fi}
\makeatother

\makeatother
\tabcolsep1em
\begin{tabular}{lccc}
\multicolumn4c{\ttfamily\string\def\string\foo.\#1**\#2\#3/\{...\}}\\[1ex]\hline
 & \ttfamily\#1 & \ttfamily\#2 & \ttfamily\#3\\\hline
1. \verb*-\foo. abc**123/-& \fooa. abc**123/ & \foob. abc**123/ & \fooc. abc**123/\\
2. \verb*-\foo.**k/-&\fooa.**k/&\foob.**k/&\fooc.**k/\\
3. \verb*-\foo.1{**}2**{ab}{cd}/-&\fooa.1{**}2**{ab}{cd}e/&\foob.1{**}2**{ab}{cd}e/&\fooc.1{**}2**{ab}{cd}/\\
4. \verb*-\foo.{ab}**1{cd} /-&\fooa.{ab}**1{cd} /&\foob.{ab}**1{cd} /&\fooc.{ab}**1{cd} /\\
5. \verb*-\foo. **xy/-&\fooa. **xy/&\foob. **xy/&\fooc. **xy/\\
6. \verb*-\foo.xy** z/-&\fooa.xy** z/&\foob.xy** z/&\fooc.xy** z/\\
7. \verb*-\foo.xy** /-&\multicolumn3c{<Erreur de compilation>}\\
8. \verb*-\foo**/-&\multicolumn3c{<Erreur de compilation>}\\\hline
\end{tabular}
\end{centrage}
\noindent Voici maintenant quelques observations :
\begin{itemize}
	\item la ligne 1 met en évidence que \verb-#1- récolte ce qui est entre «\verb-.-» et «\verb-**-», espaces compris ;
	\item on observe à la ligne 2 que le «\verb-.-» est immédiatement suivi du délimiteur «\verb-**-» et donc, l'argument délimité \verb-#1- est vide\idx*{argument!vide}. L'argument \verb-#3-, qui est délimité, est vide puisqu'il ne reste rien après \verb-#2- qui est «k»;
	\item la ligne 3 montre que si le délimiteur «\verb-**-» est entre accolades, il n'est pas reconnu comme délimiteur et ne stoppe pas la lecture de l'argument \verb-#1-;
	\item à la ligne 4, l'argument délimité \verb-#1- est «\verb-{ab}-» et comme cet argument est un texte entre accolades, les accolades sont supprimées lors de la lecture de cet argument\idx*{argument!suppression d'accolades}. Par contre, l'autre argument délimité \verb-#3- est «\verb*-{cd} -» et lui n'est pas réduit à un texte entre accolades, il y a l'espace en plus. Les accolades ne sont donc pas supprimées ;
	\item à la ligne 6, on peut se demander pour quelle raison \verb-#2- n'est pas «\verb*- -» et \verb-#3- n'est pas «\verb-z-». En fait, l'argument non délimité \verb-#2- cherche son assignation dans «\verb*- z-» et comme on l'a vu au chapitre précédent, un espace est ignoré dans une liste d'arguments non délimités\idx*{argument!espace}. Donc \verb-#2- devient «\verb-z-», ce qui explique pourquoi l'argument délimité \verb-#3- est vide puisqu'il ne reste plus rien entre la fin de \verb-#2- et le délimiteur «\verb|/|»
	\item l'erreur qui survient à la ligne 7 est due à l'argument non délimité \verb-#2- qui cherche son assignation dans «\verb*- /-». Ignorant l'espace, \verb-#2- devient «\verb|/|» et capture le délimiteur qui ne sera plus vu par \verb-\foo-. \TeX{} va donc lire du code jusqu'à ce qu'il rencontre une autre «\verb|/|», ce qui est peu probable et qui, si cela arrivait, donnerait un argument \verb-#3- beaucoup plus étendu que prévu. Si \TeX{} ne trouve pas d'autre «\verb|/|», la lecture peut se poursuivre jusqu'à ce qu'il arrive sur un \idx\par et comme la macro n'est pas déclarée \idx\long, il va se plaindre d'un «{\ttfamily Paragraph ended before \verb-\foo- was complete}»\footnote{Le paragraphe s'est terminé avant que la lecture de \texttt{\string\foo} n'ait été achevée.}. Si l'on est proche de la fin du fichier, \TeX{} peut même vainement chercher son délimiteur «\verb|/|» jusqu'à la fin du fichier et émettre un «{\ttfamily File ended while scanning use of \verb-\foo-}»\footnote{Fichier terminé pendant la lecture de \texttt{\string\foo}.}.
	\item à la ligne 8, ce qui suit la commande \verb-\foo- n'est pas «\verb-.-» donc \TeX{} nous informe que ce qu'il trouve ne correspond pas à ce qu'il attend avec un «\texttt{Use of \string\foo{} doesn't match its definition}»\footnote{L'emploi de {\ttfamily\string\foo} ne correspond  pas à sa définition.}.
\end{itemize}

\begin{exercice}
Voici une commande à arguments délimités \verb-\bar-:
\centrecode-\def\bar#1#2:#3\relax#4{<code>}-

\begin{enumerate}
	\item \Qu els sont les arguments délimités ?
	\item \Qu e valent les 4 arguments dans les cas suivants :
\begin{enumerate}
	\item \verb-\bar 123:456\relax789-
	\item \verb-\bar\def\relax:\relax\relax\relax-
	\item \verb-\bar:\relax:{\bar\relax}\bar\relax\bar-
	\item \verb-\bar0:a\relax-
\end{enumerate}
\item Donner un cas où l'on est sûr d'obtenir une erreur de compilation.
\item Donner un cas où \verb-#1- vaut «\verb-\bar12:34\relax5-» et \verb-#3- vaut «\verb-\relax-».
\item Donner un cas où \verb-#1- et \verb-#4- sont des arguments vides, mais pas \verb-#2- et \verb-#3-.
\end{enumerate}

\solution
Rappelons la définition de \verb-\bar- : \verb-\def\bar#1#2:#3\relax#4{<code>}-
\begin{enumerate}
	\item Les arguments délimités sont le deuxième et le troisième. Il est important de noter que le 4\ieme{} n'est pas délimité.
	\item Voici les résultats présentés dans un tableau :
		\begin{centrage}\small
			\begin{tabular}[t]{lcccc}\hline
				& \verb-#1- & \verb-#2- & \verb-#3- & \verb-#4-\\\hline
				a) & \verb-1- &\verb-23-&\verb-456-&\verb-7-\\
				b) &\verb-\def- &\verb-\relax- &<vide> &\verb-\relax-\\
				c) &\verb-:-&\verb-\relax- &\verb-{\bar\relax}\bar- &\verb-\bar-\\
				d) &\verb-0-&<vide>&\verb-a-&<inconnu>\\\hline
			\end{tabular}
		\end{centrage}
		Les  chiffres 8 et 9 au premier exemple et le dernier \idx\relax au deuxième exemple ne sont pas pris en compte par la macro \verb-\bar-.
		
		L'argument \verb-#4- de la dernière ligne est qualifié d'«inconnu», car l'argument qui suit «\verb-\bar0:a\relax-» n'est pas précisé dans l'énoncé. Si cet argument est \idx\par ou deux retours à la ligne consécutifs (ce qui est la même chose), il y aura une erreur de compilation puisque dans ce cas, l'argument \verb-#4- serait ce \idx\par ce qui est interdit puisque la macro \verb-\bar- n'est pas déclarée \idx\long.
	\item Ce code «\verb-\bar:a\relax bcd\par-» provoquera une erreur de compilation, car l'argument \verb-#1- qui n'est pas délimité va capturer le «\verb-:-» qui ne sera plus visible par la macro \verb-\bar-. Celle-ci va donc poursuivre sa lecture jusqu'à trouver un autre «\verb-:-» pour affecter à l'argument délimité \verb-#2- ce qu'elle a emmagasiné jusque là. Ce faisant, elle va tomber sur le \verb-\par- et comme cette macro  \verb-\bar- n'a pas été définie \idx\long, \TeX{} va émettre une erreur de compilation.
	\item Par exemple «\verb-\bar{\bar12:34\relax5}X:{\relax}\relax Y-» où ici les arguments 2 et 4 sont «\verb-X-» et «\verb-Y-».
	\item Par exemple «\verb-\bar{}X:Y\relax{}-» où les arguments 2 et 3 sont «\verb-X-» et «\verb-Y-».
\end{enumerate}
\end{exercice}

\begin{exercice}
\Qu el sera l'affichage produit par le code suivant ?

\centrecode-\def\bar/#1#2/{*#1*#2*}
\bar////-

\solution
\TeX{} attend «\verb-/-» juste après \verb-\bar-. Ce caractère est donc absorbé. L'argument \verb-#1- n'est pas délimité, il reçoit donc le second «\verb-/-». Comme \verb-#2- est un argument délimité, il sera vide puisque le second délimiteur arrive immédiatement après \verb-#1-. Il reste le dernier «\verb-/-» qui n'a pas été lu avec la macro \verb-\bar- et ses arguments; il sera donc affiché tel quel juste après la fin du texte de remplacement de \verb-\bar-.

On obtient donc : {\ttfamily\def\bar/#1#2/{*#1*#2*}\bar////}
\end{exercice}

\begin{exercice}
Soit une macro \verb-\baz- définie de cette façon : \verb-\def\baz#1\relax{#1}-. Elle ressemble un peu à la commande §\identity que nous avons déjà vue à la page~\pageref{identity} sauf qu'ici, l'argument \verb-#1- est \emph{délimité}.

Lorsqu'elles sont exécutées, expliquer s'il y a des différences entre ces différentes lignes de code et si oui, lesquelles :

\centrecode-\baz\let\bar=A\let\bidule=B\relax
\baz{\let\bar=A\let\bidule=B}\relax
\baz{\let\bar=A}{\let\bidule=B}\relax-
\solution
Pour la première ligne, l'argument \verb-#1- est ce qui se trouve entre \verb-\baz- et \verb-\relax-, donc le texte de remplacement de ce code est «\verb-\let\bar=A\let\bidule=B-». \TeX{} va donc définir deux lettres implicites.

À la deuxième ligne, \TeX{} lit l'argument «\verb-{\let\bar=A\let\bidule=B}-». Comme il est réduit à un texte entre accolades, ces accolades sont supprimées\idx*{argument!suppression d'accolades} et donc cette ligne de code est strictement équivalente à la première.

Pour la troisième, l'argument est «\verb-{\let\bar=A}{\let\bidule=B}-» qui n'est pas réduit à un texte entre accolades et ces accolades ne seront donc pas supprimées lors de la lecture de l'argument. \TeX{} va donc définir des lettres implicites à l'intérieur de deux groupes. Ces définitions seront perdues à la fin de chaque groupe, c'est-à-dire immédiatement après avoir été définies. Cette troisième ligne de code n'a donc aucun effet qui survit à la fermeture des deux groupes.
\end{exercice}

Le délimiteur du dernier argument peut également être une accolade ouvrante. Lorsque la macro sera exécutée, cela signifiera que \TeX{} s'attendra à ce que cet argument s'étende jusqu'à la prochaine accolade ouvrante.

\begin{regle}
Pour spécifier que le dernier argument \verb|<i>| d'une macro doit être délimité par une accolade ouvrante, il faut écrire dans le \idx{texte de paramètre}

\centrecode-#<i>#{-

L'accolade qui suit le \cidx\# sert de délimiteur et marque aussi le début du texte de remplacement.

Lorsque la macro sera exécutée, l'argument \verb|#<i>| s'étendra jusqu'à la prochaine accolade ouvrante\idx*{argument!délimité!par accolade}.
\end{regle}

Voici une macro \verb-\baz- où son 3\ieme{} argument est délimité par une accolade ouvrante :

\showcode/\def\baz#1#2#3#{"#1", puis "#2" et enfin "#3".}
\baz{abc}def{gh}ij/

D'après les règles vues dans ce chapitre, \verb|#1| est «\verb|abc|», \verb|#2| est «\verb|d|» et l'argument délimité \verb-#3- est bien «\verb-ef-». La suite du code, «\verb-{gh}ij-», ne sera pas lu par la macro \verb-\baz-. C'est pourquoi l'affichage produit par ce code se trouve après le point qui marque la fin de texte de remplacement de la macro \verb|\baz|.
\grandsaut

Voici enfin deux macros à usage «généraliste» en programmation, toutes les deux à arguments délimités. La première §\firstto@nil lit tout ce qui se trouve jusqu'au prochain «\idx\@nil» et en prend le premier argument non délimité. La seconde, §\remainto@nil prend ce qui reste. Elles\footnote{Ces deux commandes sont \texttt{\string\@car} et \texttt{\string\@cdr} du noyau \LaTeX.} ne sont \emph{pas} à confondre avec §\firstoftwo et §\secondoftwo qui elles, ne sont pas à arguments délimités\label{firstto@nil}.

On remarque que le caractère  «\verb|@|»\idx*{"@ (nom de macros privées)} fait partie du nom de ces deux macros ainsi que de \idx\@nil, ce qui est normalement interdit. Pour que cela soit possible, il faut modifier le code de catégorie de l'arobase qui est naturellement 12 pour le mettre à 11, celui des lettres, afin qu'il puisse servir à constituer un nom de macro. En \TeX{}, on doit écrire «\texttt{\string\catcode`\string\@=11}» pour que \verb|@| devienne une lettre puis «\texttt{\string\catcode`\string\@=12}» pour revenir au régime de catcode de l'arobase par défaut. En \LaTeX{}, les macros \idx\makeatletter et \idx\makeatother effectuent ces actions.

La zone de ces modifications sera limitée aux définitions des macros de telle sorte qu'il ne sera plus possible de se référer à ces macros par la suite. L'intérêt est qu'elles deviennent « privées », terme qu'il faut comprendre au sens de « envers du décor réservé à un usage de programmation », ou encore « à ne pas mettre entre toutes les mains ». Ainsi, l'utilisateur final ne peut pas y accéder, sauf évidemment s'il effectue la man\oe uvre de modification du catcode de \verb|@|\footnote{\LaTeX3 utilise le caractère «\texttt{\string_}» pour ses macros privées.}.

Voici les définitions et quelques exemples d'utilisation de §\firstto@nil et §\remainto@nil :

\showcode/\catcode`\@11
\long\def\firstto@nil#1#2\@nil{#1}¤§*\firstto@nil¤
\long\def\remainto@nil#1#2\@nil{#2}¤§*\remainto@nil¤
a) \firstto@nil foobar\@nil   \qquad b) \remainto@nil foobar\@nil  \par¤\idx*\qquad¤
c) \firstto@nil {foo}bar\@nil \qquad d) \remainto@nil {foo}bar\@nil¤§*\firstto@nil§*\remainto@nil¤/

On voit souvent cette macro \idx\@nil dans le code de \LaTeX{} et on la verra aussi fréquemment dans les macros de ce livre. On peut se demander ce qu'elle fait vraiment et quelle est sa définition. La réponse est très simple : il est admis que \idx\@nil est une macro \emph{non définie} (et doit le rester) dont le seul usage est de servir de délimiteur pour argument délimité. Ici, une précision s'impose : le fait qu'elle ne soit pas définie \emph{n'implique pas} que, en tant que délimiteur, elle soit interchangeable avec une autre macro non définie.

\begin{regle}
Lorsqu'un délimiteur d'argument est une \idx{séquence de contrôle}, \TeX{} ne prend pas en compte la signification de cette \idx{séquence de contrôle} : seuls les caractères qui composent son nom sont examinés.
\end{regle}

Si par exemple, on définit une macro \verb|\foo| ainsi :

\centrecode-\def\foo#1\truc{<code>}-

\noindent alors par la suite, \TeX{} s'attendra à ce que \verb|\foo| soit suivie d'un code (qui deviendra l'argument \verb|#1|) dont la fin sera marquée par \verb|\truc| (c'est-à-dire le caractère d'échappement suivi des lettres \verb|t|, \verb|r|, \verb|u| et \verb|c|). Même si une autre macro \verb|\machin| est rendue \idx\let-égale à \verb|\truc|, cette macro \verb|\machin| ne sera pas comprise comme le délimiteur de la macro \verb|\foo|.

\begin{exercice}
Existe-t-il une différence de comportement entre ces deux lignes de code et si oui, laquelle :

\centrecode-\firstoftwo{<code1>}{<code2>}¤§*\firstoftwo¤
\firstto@nil{<code1>}{<code2>}\@nil¤§*\firstto@nil¤-

\solution
Il n'y a pas de différence de comportement. Ces deux lignes se comportent de façon identique. Dans les deux cas, l'argument \verb-#1- n'est pas délimité et va être dépouillé de ses accolades\idx*{argument!suppression d'accolades}. Leur texte de remplacement est donc pour toutes les deux : \verb-<code1>-. De plus, elles ont toutes les deux lu et absorbé l'argument \verb-<code2>- qui disparait dans leur texte de remplacement.

Cette équivalence serait également valable entre ces 3 lignes qui toutes exécutent \verb|<code2>|:

\centrecode-\secondoftwo{<code1>}{<code2>}¤§*\secondoftwo¤
\remainto@nil{<code1>}{<code2>}\@nil¤§*\remainto@nil¤
\remainto@nil{<code1>}<code2>\@nil¤§*\remainto@nil¤-
\end{exercice}

\section{Mise en pratique}
Les arguments délimités ne présentent pas de difficulté théorique spéciale, aussi il est temps de les utiliser sur un exemple.

\subsection{Afficher ce qui est à droite d'un motif}\label{rightof}
Nous allons nous employer à programmer une macro§\rightof[|(] dont la syntaxe est

\centrecode-\rightof{<chaine>}{<motif>}-

\noindent et qui affiche ce qui est à gauche du \verb|<motif>| dans la \verb|<chaine>|, étant entendu que si \verb|<motif>| ne figure pas dans la \verb|<chaine>|, rien ne doit être affiché.

Du côté de la mécanique interne, cette macro se contentera de lire ses deux arguments, de définir et d'appeler une macro \verb|\right@of|. Cette macro, à arguments délimités, sera chargée d'effectuer le travail.

L'intérêt du «\verb|@|» dans «\verb|\right@of| est de marquer la frontière entre macro publique et macro privée pour délimiter ce qui a une syntaxe clairement définie et stable dans le temps pour les macros publiques de ce qui est de la cuisine interne pour les macros privées. Ces dernières sont susceptibles d'être modifiées, voire supprimées pourvu que la syntaxe et les fonctionnalités de la macro publique soient conservées.
\grandsaut

Voici comment doit être définie la macro \verb|\right@of|:

\centrecode-\def\rightof#1<motif>#2\@nil{#2}-

\noindent où le délimiteur \verb|<motif>| est l'argument \verb|#2| de la macro principale.

Voici donc le code de \verb|\rightof| où, conformément à ce qui a été dit, les tokens de paramètre \verb|#| sont doublés pour la macro «fille» \verb|\right@of| :

\showcode/\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%¤§*\rightof¤
	\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire
	\right@of#1\@nil% appelle la macro auxiliaire où #1 est la <chaine>
}
\catcode`\@=12 %"@" redevient un signe¤\idx*\catcode¤
--\rightof{Programmation}{g}--\par¤\defline\aaa¤
--\rightof{Programmation}{gram}--\par
--\rightof{Programmation}{on}--/

\subsection{Les cas problématiques}
La macro fonctionne bien\ldots{} En apparence seulement, car le cas où \verb|<chaine>| ne contient pas le \verb|<motif>| n'a pas encore été examiné :

\errcode/\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%
	\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire
	\right@of#1\@nil% appelle la macro auxiliaire
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}/{! Paragraph ended before \string\right@of was complete. <to be read again>}

\TeX{} explique qu'un \idx\par a été rencontré avant que l'argument ne soit entièrement lu, ce qui est interdit puisque la macro n'est pas déclarée \idx\long. Le texte de remplacement de \verb-\rightof{Programmation}{z}- (cas de la ligne \no\aaa) permet d'analyser ce qui se passe. Le texte de remplacement est écrit ci-dessous (les doubles \verb-##- ont été remplacés par des simples puisque nous écrivons le texte de remplacement) :

\centrecode-\def\right@of#1z#2\@nil{#2}
\entre@ Programmation\@nil-

\noindent La première ligne spécifie donc que la macro \verb-\right@of- doit être suivie de quelque chose (l'argument \verb-#1-) qui s'étend jusqu'à «\verb|z|» puis de quelque chose (l'argument \verb-#2-) qui s'étend jusqu'au \idx\@nil. Or, «\verb|z|» ne figure pas entre \verb|\right@of| et \idx\@nil puisque ce qui s'y trouve est l'argument \verb|#1| de la macro \verb|rightof|, c'est-à-dire « Programmation» ! C'est pourquoi \TeX{} le cherche jusqu'à tomber sur le \idx\par qui stoppe cette vaine recherche puisque la macro n'est pas déclarée \idx\long.

Tout serait bien plus facile si on disposait d'une macro qui teste si le \verb|<motif>| est contenu dans \verb|<chaine>| : dans l'affirmative, il suffirait d'appeler la macro \verb|\right@of| précédemment définie et sinon, ne rien faire ce qui revient à ne rien afficher. Une telle macro, capable de faire un test, sera écrite plus tard (voir page~\pageref{ifin}). En attendant, il faut trouver une astuce pour se protéger de cet inconvénient.

En fait aucune erreur ne serait émise si, quelle que soit la \verb|<chaine>|, \verb|\right@of| voyait toujours le \verb|<motif>| avant le \idx\@nil. Afin qu'il en soit ainsi, on va délibérément écrire ce \verb|<motif>| quelque part entre \verb|\right@of| et \idx\@nil lors de l'appel à la macro \verb|\right@of|. L'écrire juste avant le \idx\@nil nous assure que rien ne sera renvoyé dans le cas où \verb|<chaine>| ne contient pas \verb|<motif>| puisque dans ce cas, \verb|##2| est vide :

\showcode/\catcode`\@=11 % "@" devient une lettre
\def\rightof#1#2{%¤§*\rightof¤
	\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire¤\defline\aaa¤
	\right@of#1#2\@nil% appelle la macro auxiliaire avec le motif #2¤\defline\bbb¤
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{ti}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}--/

L'inconvénient qui saute aux yeux est que le motif \verb|#2|, ajouté juste avant \idx\@nil, est dirigé vers l'affichage lorsque la \verb|<chaine>| contient le \verb|<motif>| ! Tout simplement parce que l'argument \verb|##2| de \verb|\right@of| qui est affiché est ce qui se trouve entre la \emph{première} occurrence du \verb|<motif>| et \idx\@nil.

Pour mieux comprendre ce qui se joue en coulisses, examinons ce qui se passe lorsque l'appel «\verb|\rightof{Programmation}{g}|» est exécuté :

\begin{enumerate}
	\item la macro \verb|\right@of| est définie par : \verb|\def\right@if#1g#2\@nil{#2}| à la ligne \no\aaa;
	\item écrire «\verb|\right@of Programmationg\@nil|» donne ce qui se trouve entre la première occurrence de «\verb|g|» et \idx\@nil, c'est donc «\verb|rammationg|» qui est affiché.
\end{enumerate}

Procédons de même avec l'appel «\verb|\rightof{Programmation}{z}|», cas où le \verb|<motif>| n'est pas contenu dans la \verb|<chaine>| :

\begin{enumerate}
	\item la macro \verb|\right@of| est définie par : \verb|\def\right@if#1z#2\@nil{#2}|;
	\item écrire «\verb|\right@of Programmationz\@nil|» donne ce qui se trouve entre «\verb|z|» et \idx\@nil, c'est-à-dire rien.
\end{enumerate}

Comment faire en sorte que le \verb|<motif>| rajouté juste avant le \idx\@nil ne soit pas affiché dans le cas où \verb|<motif>| est contenu dans \verb|<chaine>| ? Réponse : en incluant dans l'argument \verb|##2| de \verb|\right@of| une autre macro à argument délimitée qui fera disparaitre ce qui est indésirable. Cette macro à argument délimité sera §\gobto@@nil et absorbera tout ce qui se trouve entre elle et le prochain \verb|\@@nil| rencontré. On note ici qu'il ne s'agit pas de \idx[|etc]\@nil mais de \verb|\@@nil| afin que le délimiteur de cette macro lui soit spécifique :

\centrecode-\def\gobto@@nil#1\@@nil{}-

On va donc ajouter un \verb|\@@nil| lors de l'appel à la macro \verb|\right@of| :

\centrecode-\right@of#1#2\@@nil\@nil-

\noindent Et il nous reste à correctement placer la macro §\gobto@@nil. Pour que ce \verb|\@@nil| soit toujours apparié avec une macro §\gobto@@nil, que \verb|<motif>| soit contenu dans \verb|chaine| ou pas, il faut mettre §\gobto@@nil juste avant et juste après \verb|#2| :

\showcode/\catcode`\@=11 % "@" devient une lettre
\def\gobto@@nil#1\@@nil{}¤§*\gobto@@nil¤
\def\rightof#1#2{%
	\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire
	\right@of#1\gobto@@nil#2\gobto@@nil\@@nil\@nil% appelle la macro auxiliaire¤§*\gobto@@nil¤
}
\catcode`\@=12 %"@" redevient un signe
--\rightof{Programmation}{g}--\par¤§*\rightof¤
--\rightof{Programmation}{ti}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{Gram}--/

Faisons fonctionner la macro §\rightof dans le cas où \verb|<motif>| est contenu dans \verb|<chaine>|. Comme précédemment, examinons quels sont ses arguments lorsque l'on écrit «\verb|\rightof{Programmation}{g}|»:

\begin{enumerate}
	\item l'appel à la macro \verb|\right@of| se fait ainsi :
	
	\centrecode-\right@of Programmation\gobto@@nil g\gobto@@nil\@@nil\@nil-§*\gobto@@nil
	\item son argument \verb|#2|, qui est entre le premier «\verb|g|» et \verb|\@nil| est :
	
	\centrecode-rammation\gobto@@nil g\gobto@@nil\@@nil-
	\item l'affichage qui en résulte est bien «rammation» car la macro §\gobto@@nil absorbe tout ce qui se trouve jusqu'au \verb|\@@nil|. \TeX{} ne tient aucun compte de ce qu'il absorbe. \Qu e la macro §\gobto@@nil y figure ou pas n'y change rien : la macro à argument délimité effectue « bêtement » son travail sans analyser ce qui se trouve dans son argument.
\end{enumerate}

Voici maintenant le cas où \verb|<motif>| n'est contenu dans \verb|<chaine>|, comme lorsqu'on écrit «\verb|\rightof{Programmation}{z}|» :

\begin{enumerate}
	\item la macro \verb|\right@of| est appelée par
	
	\centrecode-\right@of Programmation\gobto@@nil z\gobto@@nil\@@nil\@nil-
	\item l'argument \verb|#2| se trouve entre le «\verb|z|» et le \verb|\@nil| :
	
	\centrecode-\gobto@@nil\@@nil-
	\item grâce à la définition de §\gobto@@nil, ce code ne se traduit par aucun affichage.
\end{enumerate}

Impliquer ainsi plusieurs macros à arguments délimités et faire en sorte que la suivante hérite de l'argument de la précédente pour le traiter à son tour est couramment utilisé en programmation et démontre, comme dans ce cas particulier, la puissance des arguments délimités. En revanche, la gymnastique mentale requise pour  mettre en place un tel dispositif et correctement envisager tous les cas est loin d'être naturelle et demande une certaine habitude\ldots{} Le plus difficile est d'analyser un code déjà écrit, voire de comprendre un code que l'on avait écrit soi-même et oublié entre temps. \Qu i peut se vanter de comprendre du premier coup d'\oe il l'appel à la macro auxiliaire mise au point précédemment ?

\centrecode-\right@of#1\gobto@@nil#2\gobto@@nil\@@nil\@nil-§*\gobto@@nil

Le manque de lisibilité est criant et démontre l'importance de commenter son code, autant pour soi-même que pour les autres. Pour augmenter la lisibilité du code, il serait préférable de recourir à une macro \verb|\ifin| (dont l'élaboration sera expliquée page~\pageref{ifin}) qui teste si l'argument \verb|#1| contient l'argument \verb|#2| et ayant pour syntaxe

\centrecode-\ifin{#1}{#2}
	{<code à exécuter si vrai>}
	{<code à exécuter si faux>}%-

\noindent On peut ainsi programmer plus confortablement et utiliser la toute première version de \verb|\rightof| et se dispenser d'envisager le cas problématique où \verb|<chaine>| ne contient pas le \verb|<motif>| :

\showcode/\catcode`\@=11 % "@" devient une lettre
¤\string\def\string\if{}in\#1\#2\#3\#4\string{<\textit{code vu plus tard}\string}>¤
\def\rightof#1#2{%¤§*\rightof¤
	\ifin{#1}{#2}%
		{% si #1 contient le #2
		\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire
		\right@of#1\@nil% appelle la macro auxiliaire
		}%
		{}% sinon, ne rien faire
}
\catcode`\@=12 %"@" redevient un signe¤\idx*\catcode¤
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{z}--\par
--\rightof{Programmation}{o}--/

\subsection{À gauche toute}\label{leftof}
Ne nous arrêtons pas en si bon chemin et venons-en à la macro symétrique de §\rightof, la macro §\leftof[|(] qui sera chargée d'afficher ce qui est à gauche du \verb|<motif>| dans la \verb|<chaine>|.

Pour se prémunir de l'erreur de compilation rencontrée dans le cas où le \verb|<motif>| (argument \verb|#2|) n'est pas contenu dans la \verb|<chaine>| (argument \verb|#1|), procédons comme avec §\rightof et ajoutons ce \verb|<motif>| lors de l'appel à la macro auxiliaire :

\showcode/\catcode`\@=11
\def\leftof#1#2{%¤§*\leftof¤
	\def\leftof@i##1#2##2\@nil{##1}% renvoie ce qui est à gauche de #2
	\leftof@i #1#2\@nil% ajoute #2 après #1
}
\catcode`\@=12
--\leftof{Programmation}{ram}--\par
--\leftof{Programmation}{zut}--¤§*\leftof¤/

Cela était attendu : lorsqu'on écrit \verb|\leftof@i #1#2\@nil|, si \verb|#1| ne contient pas \verb|#2|, alors le \verb|#2| ajouté en fin d'argument devient la première occurrence du \verb|<motif>| et donc, \verb|#1| est affiché en entier.

À nouveau, il va falloir déployer une méthode astucieuse pour que, lorsque \verb|#1| est renvoyé en entier (ce qui correspond au cas problématique), rien ne soit affiché. Pour cela, la macro auxiliaire \verb|\leftof@i| ne va pas afficher, \verb|##1| mais transmettre ce «\verb|##1#1|» à une autre macro auxiliaire \verb|\leftof@ii|. Cette dernière aura comme délimiteur d'argument est \verb|#1| tout entier et se chargera d'afficher ce qui est à gauche de la \verb|<chaine>| \verb|#1| :

\centrecode-\def\leftof@ii##1#1##2\@nil{##1}-

Ainsi, la macro \verb|\leftof@i| devient :

\centrecode-\leftof@i##1#2##2\@nil{\leftof@ii##1#1\@nil}-

\noindent et on ajoute ici aussi \verb|#1| après \verb|##1| pour que la macro \verb|\leftof@ii| voie toujours la \verb|<chaine>| \verb|#1| :

\showcode/\catcode`\@=11
\def\leftof#1#2{%¤§*\leftof¤
	\def\leftof@i##1#2##2\@nil{\leftof@ii##1#1\@nil}%
	\def\leftof@ii##1#1##2\@nil{##1}%
	\leftof@i #1#2\@nil
}
\catcode`\@=12 ¤\idx*\catcode¤
--\leftof{Programmation}{ram}--\par
--\leftof{Programmation}{zut}--/

Compte tenu de la faible lisibilité de ce code et de la difficulté à suivre comment se transmettent les arguments, voici un tableau montrant comment sont lus et isolés les arguments délimités dans le cas où \verb|<chaine>| contient \verb|<motif>|, c'est-à-dire le premier cas. On a encadré ce qui délimite les arguments des macros :

\begin{centrage}
	\footnotesize
	\frboxsep=0.5pt
	\def\mystrut{\vphantom{\normalfont Programmation}}
	\begin{tabular}{|r|c|}\hline
		Appel macro principale & \verb|\leftof{Programmation}{ram}|\\\hline
		Appel à \verb|\leftof@i|& \frbox{\ttfamily\mystrut\string\leftof@i}Prog\frbox{\mystrut ram}mationram\verb|\@nil|\\
		Argument \verb|##1| retenu par \verb|\leftof@i| & Prog\\\hline
		Appel à \verb|\leftof@ii|& \frbox{\ttfamily\mystrut\string\leftof@ii}Prog\frbox{\mystrut Programmation}\verb|\@nil|\\
		Argument \verb|##1| retenu par \verb|\leftof@ii| &\ttfamily Prog\\\hline
		Affichage & Prog\\\hline
	\end{tabular}
\end{centrage}

Voici maintenant le déroulement des opérations lorsque \verb|<chaine>| ne contient pas \verb|<motif>| :

\begin{centrage}
	\footnotesize
	\frboxsep=0.5pt
	\def\mystrut{\vphantom{\normalfont Programmation}}
	\begin{tabular}{|r|c|}\hline
		Appel macro principale & \verb|\leftof{Programmation}{zut}|\\\hline
		Appel à \verb|\leftof@i|& \frbox{\ttfamily\mystrut\string\leftof@i}Programmation\frbox{\mystrut zut}\verb|\@nil|\\
		Argument \verb|##1| retenu par \verb|\leftof@i| & Programmation\\\hline
		Appel à \verb|\leftof@ii|& \frbox{\ttfamily\mystrut\string\leftof@ii}\kern.5pt \frbox{\mystrut Programmation}Programmation\verb|\@nil|\\
		Argument \verb|##1| retenu par \verb|\leftof@ii| &\ttfamily <vide>\\\hline
		Affichage & \ttfamily <vide>\\\hline
	\end{tabular}
\end{centrage}

Il est bon de noter que la macro §\leftof, bien que requérant elle aussi deux macros auxiliaires, est programmé différemment de \verb|\rightof|. Dans le cas de §\leftof, la deuxième macro auxiliaire \verb|\leftof@ii| est appelée \emph{dans l'argument} de \verb|\leftof@i|. Dans le cas de \verb|\rightof|, la deuxième macro auxiliaire §\gobto@@nil était écrite dans l'appel à la macro \verb|\right@of|, ce qui est un cas particulier pas toujours faisable.

\begin{exercice}
Modifier la macro §\rightof pour utiliser la méthode employée avec §\leftof : la première macro auxiliaire \verb|\rightof@i| appellera \emph{dans son argument} une deuxième macro auxiliaire \verb|\rightof@ii|.

\solution
On utilise une astuce similaire à celle vue avec §\leftof : la deuxième macro auxiliaire \verb|\rightof@ii| va renvoyer ce qui est à \emph{gauche} du \verb|<motif>| puisque celui-ci, indésirable, était rajouté à la toute fin de l'appel à \verb|\rightof@i| :

\showcode/\catcode`\@=11
\def\rightof#1#2{%¤§*\rightof¤
	\def\rightof@i##1#2##2\@nil{\rightof@ii##2#2\@nil}%
	\def\rightof@ii##1#2##2\@nil{##1}%
	\rightof@i#1#2\@nil
}
\catcode`\@=12 ¤\idx*\catcode¤
--\rightof{Programmation}{g}--\par
--\rightof{Programmation}{z}--/

Il est intéressant de noter que lorsque le \verb|<motif>| est «\verb|z|», l'argument \verb|##2| de \verb|\rightof@i| est vide et donc, l'argument \verb|##1| de \verb|\rightof@ii| est vide aussi.
\end{exercice}§*\leftof[|)]

\subsection{Autre problème : les accolades dans le motif}\label{rightof.et.accolades}
On n'en a pas fini avec les cas problématiques\ldots{} Examinons maintenant pourquoi la macro \verb-\rightof- ne fonctionne pas lorsqu'elle est appelée avec un argument \verb|#2| contenant un (ou des) groupe(s) entre accolades. Voici un exemple simple où une erreur de compilation est produite :

\errcode/\catcode`\@=11
\def\gobto@@nil#1\@@nil{}¤§*\gobto@@nil¤
\def\rightof#1#2{%
	\def\right@of##1#2##2\@nil{##2}% définit la macro auxiliaire
	\right@of#1\gobto@@nil#2\gobto@@nil\@@nil\@nil% appelle la macro auxiliaire¤§*\gobto@@nil¤
}
\catcode`\@=12
\rightof{abc{1}def}{c{1}d}% affiche ce qui est à droite de "c{1}d"/{You can't use `macro parameter character \string##' in horizontal mode.}

\noindent Pour comprendre ce qu'il se passe avec le token «\verb-#-» qui est incriminé dans le message d'erreur, écrivons le texte de remplacement de \verb|\rightof{abc{1}def}{c{1}d}| :

\centrecode/\def\right@of##1c{1}d##2\@nil{##2}
\right@of abc{1}def\gobto@@nil c{1}d\gobto@@nil\@@nil\@nil¤§*\gobto@@nil¤/

Le problème se trouve à la première ligne. \TeX{} va lire «\verb-\def\right@of##1c{1}-» ce qui va définir la macro auxiliaire \verb-\rightof@- : elle sera donc à argument délimité par «\verb|c|» et son texte de remplacement sera «\verb|1|». Par la suite, les tokens qui restent à lire sont «\verb-d##2\@nil{##2}-». Ceux-ci n'étant plus dans le \idx{texte de paramètre} d'une macro, \TeX{} bute «\verb-#-», car ce token est justement attendu dans le texte de paramètre d'une macro\footnote{On le rencontre aussi dans le préambule d'un alignement initié par la primitive \texttt{\string\halign} ou \texttt{\string\valign}.}. Le message d'erreur signale donc que \TeX{} rencontre ce token dans un contexte (ici, le mode horizontal\idx*{mode!horizontal}) dans lequel il est interdit. D'ailleurs, si le mode en cours avait été le mode vertical\idx*{mode!vertical}, le message aurait été le même : «\texttt{You can't use `macro parameter character \#' in vertical mode.}»

Il est difficile de modifier la macro §\rightof[|)] pour qu'elle puisse aussi trouver ce qui est entre deux arguments qui comportent des groupes entre accolades, car dans ces cas, les arguments délimités sont interdits. Nous emploierons une tout autre méthode, bien plus lente, qui consisterait à s'y prendre token par token (voir page~\pageref{parser.code}).

\begin{regle}
Les délimiteurs figurant dans le \idx{texte de paramètre} d'une macro ne peuvent pas contenir de tokens de catcode 1\idx*{catcode!1 (accolade)} ou 2 équilibrés (accolade ouvrante et fermante) car celles-ci seraient interprétées non pas comme faisant partie d'un délimiteur, mais comme marquant les frontières du texte de remplacement.\medskip

La conséquence est donc que lorsqu'une macro définit une \idx{macro fille} à argument délimité où les délimiteurs sont les arguments de la macro mère, ceux-ci ne peuvent pas contenir un groupe entre accolades.
\end{regle}\idx*[|)]{argument!délimité}

\chapter{Développement}\idx*[|(]{développement}
\TeX{} est un langage particulier et parmi d'autres subtilités, le développement est un de ses mécanismes intimes. Maitriser le développement est nécessaire pour programmer, car cette notion occupe une place centrale dans la programmation \TeX. Certains diraient que la gestion du développement fait partie des choses assez pénibles, mais lorsqu'on programme, il est souvent nécessaire de savoir contrôler finement ce mécanisme fondamental. Ce chapitre, consacré à l'apprentissage des outils permettant de contrôler le développement, nous ouvrira la voie pour appréhender la programmation abordée dans les parties suivantes.

\section{Développement des commandes}
Intéressons-nous aux commandes (qui ont un texte de remplacement donc), par opposition aux \idx{primitive}s qui sont « codées en dur » dans \TeX{}. Le texte de remplacement est, en quelque sorte, la définition de la commande, c'est-à-dire la représentation interne qu'en a \TeX{}. Reprenons par exemple la commande très simple \verb-\foo- définie par :

\centrecode-\def\foo{Bonjour}-

\noindent Son texte de remplacement est « Bonjour », c'est-à-dire que dans le code, lorsque \TeX{} va rencontrer \verb-\foo-, alors il va aller chercher sa signification dans sa mémoire et va remplacer cette \idx{séquence de contrôle} par son texte de remplacement qui est « Bonjour ». Ce remplacement, cette substitution, cette transformation du code s'appelle le « développement », et on dit que la macro \verb-\foo- a été développée par \TeX{}. Pour être tout à fait clair, cette « transformation du code », a lieu dans la mémoire de \TeX{} (nommée « \idx{pile d'entrée} »). Le code source n'est bien évidemment pas modifié.

\begin{regle}[Règle et définition]
\TeX{} est un langage de macros, c'est-à-dire qu'il agit comme un outil qui \emph{remplace} du code par du code. Ce remplacement, aussi appelé développement, a lieu dans une zone de mémoire nommée \og \idx{pile d'entrée}\fg.

Ainsi, lorsque \TeX{} exécute une macro, elle (ainsi que ses éventuels arguments) est d'abord remplacée par le code qui lui a été donné lorsqu'on l'a définie avec \verb|\def|. Ce code est le \og \idx{texte de remplacement}\fg{}. Une fois que ce développement a été fait, \TeX{} continue sa route en tenant compte du remplacement effectué.
\end{regle}

Prenons le temps d'examiner en détail ce qui se passe réellement et définissons les conventions suivantes : le symbole \TeXhead{} représente l'endroit où \TeX{} s'apprête à lire la suite du code. On a vu qu'il ne lisait que ce dont il avait besoin, et on va donc encadrer en pointillés le ou les tokens que \TeX{} va lire à la prochaine étape. Lorsque le développement se fait, la pile est encadrée. Observons donc, étape par étape ce qui se passe lorsqu'on écrit «\verb-\foo le monde-» (l'espace après \verb-\foo- sera ignoré en vertu de la règle concernant les espaces du code vue à la page~\pageref{regle.espace}) :\smallbreak

\hspace{5em}\TeXhead\verb-\foo le monde-\par\nobreak
\hspace{5em}\TeXhead{\ttfamily\fboxsep1pt \dashbox{\string\foo}le monde}\par\nobreak
\hspace{5em}\TeXhead{\ttfamily\fboxsep1pt \fbox{ Bonjour}le monde}\smallbreak

\noindent Ayant développé la commande \verb-\foo- dans sa pile, \TeX{} continue à lire le code qu'il a obtenu. Ici, cela se solderait par la lecture des caractères «Bonjourle monde» et par leur affichage.

Il est important de comprendre que la notion de développement ne s'applique qu'à des séquences de contrôle ou des caractères actifs. On peut donner la définition suivante :

\begin{regle}[Définition]Une \idx{séquence de contrôle} est développable si \TeX{} peut la remplacer par un code différent.\end{regle}

Les primitives n'ont pas de \idx{texte de remplacement}. Cependant, certaines d'entre elles sont développables. Nous en avons rencontré une qui est la paire \idx\csname\linebreak[1]\verb-...-\linebreak[1]\idx\endcsname dont l'argument est le code qui se trouve entre elles. En effet, lorsque \TeX{} les exécute, il transforme leur argument en une \idx{séquence de contrôle}. Cette action recoupe la définition donnée juste au-dessus : le code qui est substitué est bien différent de ce qu'il y avait avant le développement.

La plupart des primitives ne sont pas développables en ce sens que si l'on force leur développement (nous verrons comment), on obtient la primitive elle-même. L'action de ces primitives est de provoquer une action par le processeur lorsqu'elles sont exécutées par \TeX{}. Par exemple, pour la primitive \verb|\def| qui n'est pas développable, son action est de ranger dans la mémoire de \TeX{} le texte de remplacement d'une macro. Les caractères de code de catégorie 11 comme «\verb-A-» ou même ceux dont le code de catégorie est moins inoffensif comme «\verb-$-» ne sont pas développables non plus. Comme les primitives non développables, ils provoquent une action via le programme \texttt{tex} qui est de placer ce caractère dans la page pour les lettres et passer en mode mathématique\idx*{mode!mathématique} pour \verb-$-. Seuls les caractères rendus actifs dont le code de catégorie est 13 peuvent se développer puisque leur comportement est similaire à celui des commandes.

Prenons maintenant l'exemple suivant où la macro \verb-\foo- admet 2 arguments :
\centrecode-\def\foo#1#2{Bonjour #1 et #2}-

\noindent Faisons l'hypothèse que l'on stocke deux prénoms «Alice» et «Bob» dans les deux macros suivantes :
\centrecode-\def\AA{Alice } \def\BB{Bob }-

\noindent Pour bien comprendre le mécanisme du développement, prenons à nouveau le temps d'examiner en détail ce qui va se passer lorsqu'on écrit :

\centrecode-\csname foo\ensdcsname\AA\BB et les autres-.

\noindent Dans ce cas, voici les étapes par lesquelles \TeX{} va passer :
\begingroup
\fboxsep1pt
\parskip1.5pt
\def\beforecode{\ttfamily\hspace{5em}}
\begin{enumerate}[parsep=0pt,itemsep=0pt]
	\item lecture du code dont il a besoin pour former la commande \boxtoken\foo{} :\par
		{\beforecode\TeXhead\dashbox{\string\csname\ foo\string\endcsname}\string\AA\string\BB\ et les autres.}
	\item développement de ce qui a été lu, ce qui provoque la construction de la macro \verb-\foo- dans la pile :\par
		{\beforecode\TeXhead\fbox{\string\foo}\string\AA\string\BB\ et les autres.}
	\item la pile ne contenant pas les deux arguments requis pour la macro \verb-\foo-, ceux-ci sont donc lus à l'extérieur de la pile :\par
		{\beforecode\TeXhead\fbox{\rlap{\dashbox{\phantom{\string\foo\string\AA\string\BB}}}\string\foo}\string\AA\string\BB\ et les autres.}
	\item développement de \verb-\foo- et ses deux arguments qui provoque sa substitution par son texte de remplacement ;\par
		{\beforecode\TeXhead\fbox{Bonjour \string\AA\ et \string\BB} et les autres.}
	\item affichage de «Bonjour» et lecture du code jusqu'à \verb-\AA- :\par
		{\beforecode Bonjour \TeXhead\fbox{\dashbox{\string\AA} et \string\BB} et les autres.}
	\item développement de \verb-\AA- :\par
		{\beforecode Bonjour \TeXhead\fbox{Alice et \string\BB} et les autres.}
	\item affichage de «Alice et » et lecture du code jusqu'à \verb-\BB- ;\par
		{\beforecode Bonjour Alice et \TeXhead\fbox{\dashbox{\string\BB}} et les autres.}
	\item développement de \verb-\BB- :\par
		{\beforecode Bonjour Alice et \TeXhead\fbox{Bob} et les autres.}
	\item lecture du code qui ne contient plus que des caractères inoffensifs jusqu'au «\verb-.-» :\par
		{\beforecode Bonjour Alice et Bob et les autres.\TeXhead}
\end{enumerate}
\endgroup
\grandsaut

Il arrive qu'une \idx{séquence de contrôle} puisse être développée plusieurs fois. Imaginons que l'on définisse deux séquences de contrôle \verb-\A- et \verb-\B- par ce code :

\centrecode-\def\A{\B}
\def\B{Salut}-

Si l'on écrit \verb-\A- dans le code, \TeX{} va procéder à son développement et va la remplacer par \verb-\B-. Cette \idx{séquence de contrôle} va être développée à son tour pour être remplacée par « Salut » dans la pile. Dans ce cas, on dit que la macro \verb-\A- a été 2-développée, c'est-à-dire qu'elle a dû subir 2 développements successifs. On pourrait se représenter la situation par des paquets cadeaux : la \idx{séquence de contrôle} est le paquet cadeau (le contenant) et son développement est le contenu. Pour les deux macros \verb-\A- et \verb-\B-, il s'agit d'un système de poupées gigognes où le paquet cadeau \verb-\A- contient le paquet \verb-\B- qui lui-même contient « Salut ». On comprend qu'il faut ouvrir 2 paquets pour prendre connaissance du contenu final :

\begin{centrage}
	\small\boxcs\A{\boxcs\B{Salut}}
\end{centrage}

Si au lieu de \verb-\A-, on avait écrit «\idx\csname\verb- A-\idx\endcsname», il aurait fallu ajouter un développement de plus au début pour transformer ce code en \verb-\A-. Et donc c'est après 3 développements que «\verb-\csname A\endcsname-» donne «Salut».

\begin{exercice}
On définit trois macros de cette façon :

\centrecode-\def\aa{\bb}
\def\bb{\csname cc\endcsname}
\def\cc{Bonjour}-

Si on écrit dans le code \idx\csname\verb- aa-\idx\endcsname, combien de développements successifs \TeX{} doit-il effectuer pour que le code dans la pile soit «Bonjour» ?
\solution
Il suffit de compter les développements. Dans le schéma suivant, les flèches signifient «se développe en\ldots{}» :

\begin{center}
\small
\verb-\csname aa\endcsname- $\longrightarrow$ \verb-\aa- $\longrightarrow$ \verb-\bb- $\longrightarrow$ \verb|\csname cc\endcsname| $\longrightarrow$ \verb|\cc| $\longrightarrow$ Bonjour
\end{center}

Il faut donc 5 développements.
\end{exercice}

\begin{exercice}
On redéfinit les macros \verb-\aa- et \verb-\bb- de cette façon :

\centrecode-\def\aa{\bb}
\def\bb{\def\cc{Bonjour}}-

\Qu el est le 2-développement de \verb-\aa-. Et le 3-développement ?
\solution
Le 2-développement de \verb-\aa- est «\verb-\def\cc{Bonjour}-».

Pour le 3-développement, la question n'est pas claire. En effet, le 2-développement que l'on voit à la ligne ci-dessus n'est pas un token unique est constitué de 11 tokens. D'ailleurs, le seul qui est susceptible de se développer est \verb|\cc| puisque les autres sont soit une primitive (\verb|\def|), soit des accolades, soit des lettres. On va considérer que le développement ne s'applique qu'au premier token du code obtenu et la réponse va donc être : le 3-développement est identique au 2-développement, car la primitive \verb|\def| se développe en elle-même.
\end{exercice}

\begin{exercice}
Redéfinissons les macros \verb-\aa-, \verb-\bb- et \verb|\cc| de cette façon :

\centrecode-\def\aa{X}
\def\bb{Y}
\def\cc{\secondoftwo\aa\bb 123}¤§*\secondoftwo¤-

\Qu el code est obtenu sur la pile après 1, 2 et 3 développements de la macro \verb-\cc- ?
\solution
État de la pile après :
\begin{itemize}
	\item 1 développement : \verb-\secondoftwo\aa\bb 123-§*\secondoftwo
	\item 2 développements : \verb-\bb 123-
	\item 3 développements : \verb-Y123-
\end{itemize}
\end{exercice}

\noindent Les règles suivantes découlent de ce qui a été dit :

\begin{regle}[Règles]
La lecture du code se fait séquentiellement de gauche à droite et \TeX{} ne cherche pas à lire plus de tokens que ce dont il a besoin.\medbreak

Lorsque \TeX{} rencontre une séquence de contrôle, il lit aussi ses éventuels arguments pour procéder à son développement qui consiste à remplacer le tout par du code. Si la pile ne contient pas assez d'arguments, \TeX{} va chercher ces arguments manquants juste après la pile, c'est-à-dire dans le code source.
\end{regle}

La première partie de cette règle concernant la lecture séquentielle du code est extrêmement contraignante et rend certaines choses impossibles. Par exemple définir une \idx{séquence de contrôle} formée avec \idx\csname et \idx\endcsname, comme la macro \texttt\textbackslash\boxtoken{ab1c}. En effet, comme on l'a vu à la page~\pageref{construction.nom.etrange}, c'est une erreur que d'écrire :

\centrecode-\def\csname ab1c\endcsname{<code>}-

\noindent Nous avons vu également à la page~\pageref{non.dev.csname} que l'on ne peut écrire

\centrecode-\let\salut\csname foo\endcsname-\idx*\let

\noindent pour rendre la macro \verb|\salut| égale à \verb|\foo|.

Concernant le développement, \TeX{} permet d'enfreindre la première partie de la règle en offrant la possibilité, dans une faible mesure, de développer le code \emph{non linéairement} et c'est ce que nous allons découvrir avec la primitive \verb|\expandafter|.

\section{La primitive \texttt{\textbackslash expandafter}}\idx*[|(]\expandafter
Il n'est pas exagéré de dire qu'aux yeux de débutants en \TeX, \verb|\expandafter| est une des primitives les plus mystérieuses qui soient. Certains lui prêtent des vertus quasi magiques et en viendraient presque à croire que disséminer quelques \verb|\expandafter| dans un code qui ne fonctionne pas le ferait fonctionner ! Ici encore, il ne sera pas question de magie, mais au contraire de démystification puisque cette  primitive \verb|\expanfafter| fait une chose extrêmement simple.

Tout d'abord, elle est développable, c'est-à-dire que lorsque \TeX{} va la développer, il va la remplacer par du code dans la pile. L'action de cette primitive se passe au niveau des tokens et non pas à celui des arguments. Si \verb|<x>| et \verb|<y>| sont deux tokens et si l'on écrit :

\centrecode-\expandafter<x><y>-

\noindent cela a pour effet de 1-développer le token \verb-<y>- avant de lire \verb-<x>-. En fait, tout se passe comme si le \verb-\expandafter- permettait de «sauter» \verb-<x>- pour 1-développer \verb-<y>- et revenir ensuite au point de départ.

\begin{regle}
Si \verb|<x>| et \verb|<y>| sont deux \emph{tokens}, écrire

\centrecode|\expandafter<x><y>|

a pour effet, lorsque \TeX{} développe \verb|\expandafter|, de 1-développer \verb|<y>| sans pour autant que la tête de lecture ne bouge de place (et donc reste devant \verb|<x>| qu'elle n'a toujours pas lu).

Le \verb|\expandafter| disparait après s'être développé et on obtient donc

\centrecode-<x><*y>-

où «\verb|*|» indique le 1-développement du token \verb|<y>|.
\end{regle}

Attention, \verb|<y>| a été 1-développé, mais n'a pas été \emph{lu}. La tête de lecture de \TeX{} n'a pas bougé dans l'opération. On peut se représenter la situation en imaginant que la tête de lecture dispose d'une « tête de développement », capable sur ordre de se désolidariser pour aller développer du code non encore lu. La tête de développement, une fois sa mission accomplie, revient sur la tête de lecture afin que cette dernière poursuive son travail.

Une application immédiate est que désormais, nous pouvons définir la \idx{séquence de contrôle} \verb|\|\boxtoken{ab1c} avec \idx\csname : il suffit de sauter le \verb|\def| avec un \verb-\expandafter- pour provoquer la formation du nom de la macro avant que \verb-\def- ne la voit :

\showcode/\expandafter\def\csname ab1c\endcsname{Bonjour}
Texte de remplacement de la macro : \csname ab1c\endcsname/

Au lieu d'écrire «\verb|\expandafter\def\csname ab1c\endcsname|», il est préférable de définir une macro §\defname dont l'argument est le nom de la macro. Il est facile de faire de même avec §\letname.

\showcode/\def\defname#1{\expandafter\def\csname#1\endcsname}¤§*\defname\idx*\csname\idx*\endcsname¤
\defname{ab1c}{Bonjour}¤§*\defname¤
Texte de remplacement de \litterate|\abc1| : \csname ab1c\endcsname\par¤§*\litterate¤
\def\letname#1{\expandafter\let\csname#1\endcsname}¤§*\letname¤
\def\foo{abc}\letname{foo1}=\foo% rend la macro "\foo1" égale à \foo
Texte de remplacement de \litterate|\foo1| : \csname foo1\endcsname¤\idx*\char\idx*\meaning§*\litterate¤/

Afin de comprendre l'utilité du développement, tentons maintenant une expérience en utilisant la macro à arguments délimités §\firstto@nil[|(]. Nous l'avons définie de la façon suivante à la page~\pageref{firstto@nil} :

\centrecode-\def\firstto@nil#1#2\@nil{#1}-

\noindent son texte de remplacement est donc le premier argument de ce qui se trouve entre cette macro et \verb-\@nil-.

Maintenant, si on définit la macro \verb-\foo- par \verb|\def\foo{Bonjour}| et que l'on écrit \verb|\firstto@nil\foo\@nil|, qu'obtient-on ?

\showcode/ \def\foo{Bonjour}\catcode`@=11
Résultat : \firstto@nil\foo\@nil¤§*\firstto@nil¤
\catcode`@=12/

Contrairement à ce que l'on pourrait penser, on n'obtient pas la lettre «B» mais le mot entier. C'est que, fort logiquement, \verb-\firstto@nil- a pris comme argument \verb-#1- la macro \verb-\foo- en entier tandis que l'argument délimité \verb|#2| est resté vide. Il \emph{essentiel} de ne pas confondre macro et texte de remplacement : dans un cas, il y a un seul token alors que dans l'autre, il y a tous les tokens du texte de remplacement, c'est-à-dire ici les 7 lettres du mot «Bonjour». Pour que \verb|\first@tonil| agisse sur le texte de remplacement de \verb|\foo| et non pas sur \verb|\foo| elle-même, il faut développer \verb-\foo- \emph{avant} que \TeX{} ne lise la macro \verb-\firstto@nil-. Nous allons utiliser \verb-\expandafter- pour sauter \verb-\firstto@nil- et provoquer ce développement :

\showcode/\def\foo{Bonjour}\catcode`@=11 
Résultat : \expandafter\firstto@nil\foo\@nil
\catcode`@=12/

\noindent Le mécanisme est schématisé ci-dessous :

\begin{centrage}
	\small\jumptok-\firstto@nil\foo-\verb-\@nil-
\end{centrage}

\noindent La flèche représente le développement du token encadré. Ici donc, le développement de \verb|\expandafter| va provoquer le 1-développement de \verb|\foo| et donne :

\centrecode-\firsto@nil Bonjour\@nil-

\noindent Cette expérience faite avec \verb|\firsto@nil| peut être généralisée à n'importe quelle autre macro :

\begin{regle}
Lorsqu'on stocke des tokens dans une \verb|\<macroA>| (comme cela arrive très souvent), si l'on veut mettre ces tokens dans l'argument d'une autre macro \verb|\<macroB>|, il \emph{faut} développer \verb|\<macroA>| avant que \verb|\<macroB>| n'agisse.
\end{regle}

\begin{exercice}
Au lieu d'une macro, utiliser un nouveau registre de token \verb|\testtoks| pour stocker les caractères « Bonjour ». Comment faut-il alors utiliser §\firstto@nil pour obtenir la lettre « B »?
\solution
Pour extraire le contenu du registre, il faut développer la primitive \idx\the lorsqu'elle précède le registre. Ici, au lieu de 1-développer la macro, il faut 1-développer \idx\the\idx\toks0 :

\showcode/\newtoks\testtoks \testtoks={Bonjour}¤\idx*\newtoks¤
\catcode`@=11
Résultat : \expandafter\firstto@nil\the\testtoks\@nil¤\idx*\the¤
\catcode`@=12/
\end{exercice}
\grandsaut

Afin de bien maitriser le développement, abandonnons la macro §\firstto@nil[|)]  pour construire une macro plus généraliste \verb|\>| qui agit comme un révélateur universel et qui affiche littéralement tout ce qui se trouve entre \verb|\>| et \verb|<| :

\centrecode|\>ensemble de tokens<|

On voudrait que \verb|\>12^&$~\foo$<| affiche «\detokenize{12^&$~\foo$}». Pour cela, la primitive \idx\detokenize va bien nous aider. Cette primitive développable admet un argument entre accolades et le transforme en caractères de code de catégorie 12 (et 10 pour l'espace). Par exemple, si on écrit \verb-\detokenize{12^&$~\foo$}-,  on obtient « \detokenize{12^&$~\foo$} ».

Il est utile de faire quelques remarques concernant \idx\detokenize : une espace est \emph{toujours} rajoutée après une \idx{séquence de contrôle}; ici, on peut la voir après \verb-\foo-. Enfin, l'argument doit contenir un texte où les accolades sont équilibrées. Voici le code qui permet de programmer la macro \verb|\>| évoquée plus haut\label{macro.>} :

\centrecode/\long\def\>#1<{\detokenize{#1}}/
\long\def\>#1<{\detokenize{#1}}

Expérimentons cette macro et profitons de \verb-\expandafter- pour « sauter » la macro \verb-\>- afin de développer le premier token qui se trouve juste après :

\showcode/\def\foo{bonjour}
a) \>\csname foo\endcsname< \par¤\idx*\csname\idx*\endcsname¤
b) \>\foo< \par
c) \expandafter\>\foo< \par
d) \>\foo\foo< \par
e) \expandafter\>\foo\foo</

Chaque fois qu'un \verb-\expandafter- précède \verb-\>- (cas c et e), on constate que le développement du \verb-\foo- a bien lieu tout de suite après la balise. À la dernière ligne, on voit que le premier \verb-\foo- est développé alors que le second, non concerné par le \verb-\expandafter- reste tel quel.

Maintenant, essayons de 1-développer le \emph{second} \verb-\foo- de la dernière ligne tout en laissant le premier intact. Le principe est que le développement d'un premier \verb|\expandafter| provoque le développement d'un autre situé un token après, et ainsi de suite pour finir par 1-développer le token voulu. Cette capacité que possèdent les \verb|\expandafter| à se transmettre de proche en proche le développement conduit à appeler ce genre de structure un « pont d'\verb|\expandafter|» :

\begin{centrage}
	\small\jumptok-\>\foo\foo-\verb-<-
\end{centrage}

Une fois que les \verb-\expandafter- se sont passé le relai pour développer le second \verb-\foo-, ceux-ci disparaissent, et le code qui est prêt à être lu est :

\centrecode-\>\foo Bonjour<-

\noindent ce que l'on vérifie dans cet exemple :

\showcode/\def\foo{Bonjour} \expandafter\>\expandafter\foo\foo</

La règle fondamentale est la suivante :

\begin{regle}
Pour 1-développer un token précédé de $n$ tokens, il faut mettre un \verb-\expandafter- devant chacun de ces $n$ tokens.
\end{regle}

Par exemple, en partant de \verb-\foo-, si l'on veut définir une macro \verb-\bar- dont le texte de remplacement soit «\verb-\foo Bonjour-», alors on doit mettre un \verb-\expandafter-, représenté par un « $\bullet$ » devant les 4 tokens \boxtoken{\def}, \boxtoken{\bar}, \boxtoken[]{\{} et \boxtoken{\foo} pour provoquer le 1-développement du second \verb-\foo- :

\begin{centrage}
	\small\ttfamily$\bullet$\string\def$\bullet$\string\bar$\bullet$\string{$\bullet$\string\foo\string\foo\string}
\end{centrage}

\showcode|\def\foo{Bonjour}
\expandafter\def\expandafter\bar\expandafter{\expandafter\foo\foo}
\meaning\bar|

Une application de ceci, très utile en programmation, est l'ajout d'un \verb|<code>| au texte de remplacement d'une macro. Appelons §\addtomacro[|(]\label{addtomacro} la commande qui admet deux arguments dont le premier est une macro et le second est un texte qui sera ajouté à la fin du texte de remplacement de la macro. On doit pouvoir écrire :

\centrecode-\def\foo{Bonjour}
\addtomacro\foo{ le monde}-§*\addtomacro

\noindent pour qu'ensuite, la macro \verb-\foo- ait comme texte de remplacement « Bonjour le monde ». La méthode consiste à partir de cette définition :

\centrecode-\long\def\addtomacro#1#2{\def#1{#1#2}}-

\noindent Si on écrit «§\addtomacro\verb-\foo{ le monde}-», le texte de remplacement devient

\centrecode-\def\foo{\foo Bonjour}-

\noindent On le voit, le texte de remplacement va conduire à une définition \emph{récursive} de \verb-\foo- puisque le texte de remplacement de \verb|\foo| contient \verb|\foo|. Ouvrons une parenthèse et intéressons-nous à ce qui va se passer.
\grandsaut

L'exécution de \verb|\foo| telle que définie ci-dessus va conduire à une erreur de compilation. En effet, à chaque développement, non seulement \verb|\foo| est créée dans la pile, mais 7 tokens (les 7 lettres du mot « Bonjour ») y sont aussi ajoutés. La pile va donc croitre très rapidement, voici son contenu lors des premiers développements :
\begin{enumerate}
	\item \verb|\foo|
	\item \verb|\foo Bonjour|
	\item \verb|\foo BonjourBonjour|
	\item \verb|\foo BonjourBonjourBonjour|
	\item etc.
\end{enumerate}

Cette pile n'étant pas infinie, le maximum va être rapidement atteint :

\errcode/\def\foo{\foo Bonjour}% définition récursive
\foo% l'exécution provoque un dépassement de la capacité de la pile/%
{! TeX capacity exceeded, sorry [input stack size=5000].}

Augmenter cette taille ne changerait pas l'issue, même si des développements supplémentaires étaient faits.
\grandsaut

Fermons la parenthèse et revenons à \verb|\def\foo{\foo Bonjour}|. Afin d'éviter l'écueil du dépassement de la capacité de la pile, il faut 1-développer \verb-\foo- à l'intérieur des accolades pour qu'elle soit remplacée par «Bonjour» et ce, \emph{avant} que \verb|\def| n'entre en action. Comme nous l'avons vu, il suffit de placer un \verb-\expandafter- devant chaque token qui précède ce \verb-\foo-. Voici le code correct qui permet de programmer la macro \verb-\addtomacro- :

\showcode|\long\def\addtomacro#1#2{%¤§*\addtomacro¤
	\expandafter\def\expandafter#1\expandafter{#1#2}%
}
\def\foo{Bonjour}
\addtomacro\foo{ le monde}¤§*\addtomacro¤
\meaning\foo¤\idx*\meaning¤|

\begin{exercice}
En utilisant §\addtomacro, écrire une macro §\eaddtomacro qui agit comme §\addtomacro sauf que le second argument est 1-développé. Ainsi, si on écrit

\centrecode-\def\foo{Bonjour} \def\world{ le monde}
\eaddtomacro\foo\world-

alors, le texte de remplacement de la macro \verb-\foo- doit être «Bonjour le monde».
\solution
Si nous partons de ceci :

\centrecode-\long\def\eaddtomacro#1#2{\addtomacro#1{#2}}-

le texte de remplacement est de §\eaddtomacro est

\centrecode-\addtomacro#1{#2}-

Pour que §\addtomacro accède au texte de remplacement de la macro \verb|#2|, nous savons qu'à l'intérieur des accolades, \verb-#2- doit être 1-développée. Pour ce faire, il faut placer un \verb-\expandafter- devant chacun des 3 tokens qui précèdent \verb-#2- :

\showcode|\long\def\eaddtomacro#1#2{%¤§*\eaddtomacro¤
	\expandafter\addtomacro\expandafter#1\expandafter{#2}%
}
\def\foo{Bonjour} \def\world{ le monde}
\eaddtomacro\foo\world¤§*\eaddtomacro¤
\meaning\foo¤\idx*\meaning¤|
\end{exercice}§*\addtomacro[|)]
\grandsaut

Nous allons maintenant construire les mêmes macros sauf qu'elles agiront sur le contenu de registres de tokens. Mais pour atteindre ce but, une règle va nous être utile\ldots{}

\begin{regle}\relax\label{primitive.suivie.par.accolade}
Les primitives qui doivent immédiatement être suivies d'une accolade ouvrante ont la particularité suivante : elles développent au maximum\idx*{développement maximal} jusqu'à trouver l'accolade ouvrante.

Nous connaissons :
\begin{itemize}
	\item \idx\lowercase et \idx\uppercase;
	\item \idx\detokenize;
	\item \idx\toks\verb*-<nombre>= - (ou \verb*-\<nom>= - si on est passé par \idx\newtoks\verb-\<nom>-), sachant que le signe \verb|=| et l'espace qui le suit sont facultatifs.
\end{itemize}

La conséquence est que l'on peut placer un (ou plusieurs) \verb|\expandafter| entre ces primitives et l'accolade ouvrante pour développer leur argument avant qu'elles n'agissent.
\end{regle}

La méthode va consister à tirer parti de cette règle. Si \verb|#1| est un registre de tokens, on va partir de

\centrecode-#1= {\the#1#2}-

\noindent et placer un \verb|\expandafter| entre \verb*|#1= | et l'accolade ouvrante pour 1-développer \verb|\the#1| afin de délivrer le contenu du registre \verb|#1| :

\showcode/\long\def\addtotoks#1#2{#1= \expandafter{\the#1#2}}¤§*\addtotoks\idx*\long¤
\newtoks\bar¤\idx*\newtoks¤
\bar={Bonjour}% met "Bonjour" dans le registre
\addtotoks\bar{ le monde}% ajoute " le monde"¤§*\addtotoks¤
\the\bar% affiche le registre¤\idx*\the¤/

En copiant la méthode utilisée avec §\eaddtomacro, il est facile de construire la macro §\eaddtotoks qui 1-développe son second argument avant de l'ajouter au contenu du registre à token \verb|#1| :

\showcode/\long\def\eaddtotoks#1#2{\expandafter\addtotoks\expandafter#1\expandafter{#2}}¤§*\eaddtotoks§*\addtotoks¤
\bar={Bonjour}
\def\macrofoo{ le monde}
\eaddtotoks\bar\macrofoo¤§*\eaddtotoks¤
\the\bar¤\idx*\the¤/

\section{Développer encore plus avec \texttt{\textbackslash expandafter}}
Jusqu'à présent, nous nous sommes limités à des \verb|\expandafter| provoquant des 1-développements, mais on peut 2-développer, voire plus. Pour voir comment, définissons les macros

\centrecode-\def\X{Bonjour} \def\Y{\X}-

\noindent et intéressons-nous au problème suivant : essayons de 2-développer le «\verb-\Y-» qui se trouve entre \verb-\>- et \verb-<- dans «\verb-\>\Y<-» de façon à obtenir l'affichage «Bonjour».

Ce que nous savons faire, c'est 1-développer \verb-\Y- :

\centrecode-\expandafter\>\Y<-

\noindent En l'état, ce code ne fait que 1-développer \verb|\Y|. Pour 2-développer, il faudrait que le \verb|\expandafter| ci-dessus agisse sur le 1-développement de \verb|\Y|. On va donc partir du code ci-dessus et faire en sorte que préalablement, le \verb|\Y| soit 1-développé. Nous savons comment placer les \verb-\expandafter- pour que la macro \verb-\Y- soit 1-développée, il suffit d'en mettre un devant chaque token qui précède \verb-\Y-. Il faut donc placer un \verb-\expandafter- devant le premier \verb-\expandafter- et un autre devant \verb-\>-. On arrive au code suivant :

\centrecode-\expandafter\expandafter\expandafter\>\Y<-

\noindent Pour nous assurer que ce code va conduire au résultat escompté, examinons ce qui se passe avec les conventions graphiques vues auparavant. Voici ce qui se passe dans un premier temps :

\begin{centrage}
	\small\jumptok-\expandafter\>\Y-\verb-<-
\end{centrage}

\noindent La macro \verb-\Y- est développée en \verb-\X- et on obtient le code « \verb-\expandafter\>\X<- » dans la pile. Voici maintenant le deuxième temps :

\begin{centrage}
	\small\jumptok-\>\X-\verb-<-
\end{centrage}

\noindent \verb-\X- se développe bien en «Bonjour» ce qui donne :

\centrecode-\>Bonjour<-

\noindent que nous cherchions à obtenir. Vérifions-le sur cet exemple :

\showcode/\def\X{Bonjour} \def\Y{\X}
\expandafter\expandafter\expandafter\>\Y</

Ce pont d'\verb|\expandatfer| a provoqué \emph{deux} développements pour arriver au code final et on peut parler de « pont à plusieurs niveaux ».
\grandsaut

Retenons que lorsque deux tokens \verb-<x><y>- sont dans le code, pour 2-développer \verb-<y>- avant de lire \verb-<x>-, nous devons placer trois \verb-\expandafter- devant \verb-<x>- de cette façon :
\centrecode-\expandafter\expandafter\expandafter<x><y>-

Et si nous voulions 3-développer \verb-<y>-, il faudrait ajouter des \verb|\expandafter| dans le code ci-dessus pour, au préalable, 1-développer \verb-<y>-. Pour cela, il faudrait placer un \verb-\expandafter- devant chaque token qui précède \verb-<y>- et donc en ajouter 4 (un devant chacun des 3 \verb-\expandafter- existants et un devant \verb-<x>-). Nous aurions alors 7 \verb|\expandafter| en tout :

\centrecode-\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter<x><y>-

Pour un développement de plus de \verb-<y>- de façon à le 4-développer, il faudrait 1-développer \verb|<y>| dans le code ci-dessus et donc, ajouter 8 \verb|\expandatfer| de plus (un devant les 7 \verb-\expandafter- existants plus un devant \verb-<x>-) ce qui en ferait 15.
\grandsaut

Essayons d'en tirer une règle générale : soit $u_k$ le nombre d'\verb-\expandafter- placés devant les tokens \verb-<x><y>- qui provoquent le $k$-développement de \verb|<y>|. Si on veut procéder à un développement de plus de \verb-<y>-, il faut ajouter $u_k+1$ \verb-\expandafter- devant \verb-<x><y>- (un devant chacun des $u_k$ \verb-\expandafter- existants et un devant \verb-<x><y>-). Pour traduire ceci par une relation de récurrence mathématique, il suffit de partir de $u_1=1$ puisque un \verb|\expandafter|
 placé devant \verb|<x><y>| provoque le 1-développement de \verb|<y>|. On a donc :

\begin{align*}
u_1&=1&u_{k+1}&=u_k+u_k+1\\
&&&=2u_k+1
\end{align*}

\noindent À l'aide d'une démonstration mathématique facile, on en tirerait que : 
\[u_k=2^k-1\]

Le raisonnement pourrait facilement être généralisé si plusieurs tokens précédaient \verb-<y>-. La règle générale est la suivante et il est bon de s'en souvenir :

\begin{regle}
Pour provoquer le $k$-développement d'un token \verb|<y>| précédé par $n$ autres tokens, il faut placer $2^k-1$ \verb-\expandafter- devant chacun des $n$ tokens qui le précèdent.
\end{regle}

\begin{exercice}
Reprenons les macros suivantes :

\centrecode-\def\X{Bonjour}
\def\Y{\X}-

Placer les \verb-\expandafter- dans le code ci-dessous pour que le texte de remplacement de la macro \verb-\foo- soit « Bonjour » :

\centrecode-\def\foo{\Y}-

\solution
La réponse se trouve dans la règle précédente : il faut 2-développer \verb-\Y- et donc ajouter $2^2-1$, c'est-à-dire 3 \verb-\expandafter- devant chaque token qui précède \verb-\Y-. Ces tokens sont au nombre de 3 («\verb|\def|», «\verb|\foo|» et «\verb|{|») et donc, il faut remplacer chaque « $\bullet$ » par 3 \verb-\expandafter- dans ce code :

\begin{centrage}
	\small$\bullet$\verb-\def-$\bullet$\verb-\foo-$\bullet$\verb-{\Y}-
\end{centrage}

\noindent Cela donne un code un peu indigeste :

\centrecode-\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\foo
\expandafter\expandafter\expandafter{\Y}-
\end{exercice}

\begin{exercice}
Placer correctement des \verb-\expandafter- dans la dernière ligne du code ci-dessous pour que \verb-\bar- ait comme texte de remplacement « Bonjour le monde » :

\centrecode-\def\foo{Bonjour}
\def\world{ le monde}
\def\bar{\foo\world}-
\solution
Si on part de

\centrecode-\def\bar{\foo\world}-

il faut 1-développer \verb|\foo| et 1-développer \verb|\world| dans le texte de remplacement de \verb|\bar|.

Nous allons construire un pont d'\verb|\expandafter| en deux passes : la première 1-développera une des deux macros et la deuxième 1-développera l'autre.

Dans un cas comme celui-ci qui est un cas particulier d'un cas plus général, il faut commencer par placer des \verb|\expandafter| pour 1-développer la macro la plus à gauche. Ceci étant fait, la passe suivante consistera à placer des \verb|\expandatfer| pour développer la macro suivante. Et ainsi de suite pour finir, lors de la dernière passe, par le développement de la macro la plus à droite. On progresse donc de gauche à droite, c'est-à-dire dans l'ordre inverse de celui dans lequel elles seront développées par \TeX{} lorsqu'il lira le code.

Ici donc, la première passe consiste à placer des \verb|\expandafter| pour 1-développer \verb|\foo|, ce qui revient à en placer un devant chaque token qui précède \verb|\foo| :

\centrecode-\expandafter\def\expandafter\foo\expandafter{\foo\world}-

Dans une deuxième passe, nous allons 1-développer \verb-\world- et placer aussi un \verb-\expandafter- devant chaque token qui la précède, en tenant compte de ceux déjà mis en place :

\centrecode-\expandafter\expandafter\expandafter\def
\expandafter\expandafter\expandafter\foo
\expandafter\expandafter\expandafter
{\expandafter\foo\world}-

Bien que ne répondant pas aux contraintes de l'énoncé, la macro §\eaddtomacro peut se révéler utile dans un cas comme celui-ci. En effet, elle améliore la lisibilité du code puisqu'elle évite ces nombreux \verb|\expandafter|. Une autre façon de faire aurait été :

\centrecode-\def\bar{}%
\eaddtomacro\bar\foo
\eaddtomacro\bar\world¤§*\eaddtomacro¤-
\end{exercice}

La primitive \verb|\expandafter| intervenant au niveau des \emph{tokens}, il est intéressant en programmation de disposer d'une macro, appelons-la §\expsecond[|(], qui intervient au niveau des \emph{arguments}. On voudrait qu'elle soit capable de sauter un argument entier pour 1-développer le premier token de l'argument qui suit. On pourrait donc écrire :

\centrecode-\expsecond{<arg1>}{<arg2>}-

\noindent pour que le code finalement lu par \TeX{} soit

\centrecode-<arg1>{*<arg2>}-

\noindent où l'étoile indique que le premier token de \verb|<arg2>| est 1-développé. 

\begin{exercice}\label{expsecond}
Construire la macro §\expsecond en utilisant la macro auxiliaire §\swaparg[|(] qui échange 2 arguments en mettant le premier entre accolades :

\centrecode-\long\def\swaparg#1#2{#2{#1}}-

\solution
La méthode consiste à partir de

\centrecode-\long\def\expsecond#1#2{\swaparg{#2}{#1}}-

qui, après que §\swaparg ait joué son rôle, donnerait «\verb|#1{#2}|». Pour que le premier token de \verb|#2| soit 1-développé, il faut placer des \verb|\expandafter| dans le texte de remplacement de §\expsecond pour provoquer ce développement. Cela donne :

\centrecode-\long\def\swaparg#1#2{#2{#1}}
\long\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}-
\end{exercice}

\begin{exercice}
Combien de développements doit subir §\expsecond\verb-{<arg1>}{<arg2>}- pour que le code qui soit effectivement à lire soit \verb-<arg1>{*<arg2>}- ?

Placer correctement des \verb|\expandafter| dans le 2\ieme{} ligne de ce code

\centrecode-\def\X{Bonjour}
\>\expsecond{\X}{\X}<-

pour qu'il affiche « \string\X{} Bonjour ». La macro \verb|\>|, programmée à la page~\pageref{macro.>}, affiche tel quel le code qu'elle rencontre jusqu'au prochain \verb|<|.
\solution
Développons §\expsecond\verb-{<arg1>}{<arg2>}- comme le fait \TeX{} :
\begin{enumerate}
	\item  \verb-\expandafter\swaparg\expandafter{<arg2>}{<arg1>}-
	\item \verb-\swaparg{*<arg2>}{<arg1>}- (les \verb|\expandafter| ont joué leur rôle)
	\item \verb-<arg1>{*<arg2>}-
\end{enumerate}
Il faut donc 3 développements.
\medskip

Dans «\verb-\>\expsecond{\X}{\X}<-», si l'on veut 3-développer §\expsecond, il faudra mettre $2^3-1=7$ \verb-\expandafter- devant \verb-\>- :

\showcode/\long\def\swaparg#1#2{#2{#1}}¤§*\swaparg\idx*\long¤
\long\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}¤§*\expsecond\idx*\long¤
\def\X{Bonjour}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>\expsecond{\X}{\X}<¤§*\expsecond¤/
\end{exercice}

\begin{exercice}
Dans quels cas §\expsecond ne fonctionne pas comme attendu ?
\solution
Si l'on examine la définition

\centrecode-\long\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}-§*\expsecond

on constate que le 1-développement de l'argument \verb|#2| a lieu alors que cet argument est déplacé et n'est plus en dernier, c'est-à-dire qu'il ne précède pas le code qui suit. Dès lors, si cet argument doit agir sur le code qui suit (avec §\gobone, §\identity, §\firstoftwo ou §\secondoftwo), il n'est plus en mesure de le faire. Dans l'exemple ci-dessous, on souhaite 1-développer §\gobone pour donner à \verb|\foo| le texte de remplacement «\verb|B|» :

\errcode/\expsecond{\def\foo}\secondoftwo{A}{B}¤§*\expsecond§*\secondoftwo¤/{Argument of \texttt{\string\secondoftwo} has an extra \char`\}}

Le 2\ieme{} argument de §\expsecond est §\secondoftwo donc, après avoir 1-développé §\expsecond dans «\verb|\expsecond{\def\foo}\secondoftwo{A}{B}|», voici ce que l'on obtient :

\centrecode-\expandafter\swaparg\expandafter{\secondoftwo}{\def\foo}-

Lorsque §\secondoftwo est 1-développé, en cherchant son premier argument, il voit «\verb|}|» et c'est là que \TeX{} proteste car une accolade fermante ne peut pas être le début d'un argument.

Pour que «B» soit le texte de remplacement de \verb|\foo|, il aurait fallu que «\verb|\secondoftwo{A}|\linebreak[1]\verb|{B}|» soit le 2\ieme{} argument de §\expsecond :

\showcode/\expsecond{\def\foo}{\secondoftwo{A}{B}}¤§*\expsecond§*\secondoftwo¤
\meaning\foo¤\idx\meaning¤/
\end{exercice}§*\expsecond[|)]§*\swaparg[|)]

La macro §\expsecond peut être utilisée si son premier argument est une macro :

\centrecode-\expsecond\<macro>{<argument>}-

\noindent Dans ce cas, §\expsecond 1-développe l'argument de la macro avant d'exécuter la macro. C'est pourquoi la macro §\expsecond a un alias «§\exparg» défini par \idx\let dont le nom suggère davantage que l'argument d'une macro a été développé.

\begin{exercice}
En reprenant le même principe que §\exparg, définir une macro §*\exptwoargs

\centrecode-\exptwoargs\<macro>{argument 1}{argument 2}-

\noindent qui 1-développe les 2 premiers tokens des deux arguments avant de lancer la \verb|\<macro>|
\solution
Deux appels imbriqués à §\exparg conduisent au résultat :

\centrecode-\def\exptwoargs#1#2#3{\expsecond{\expsecond{#1}{#2}}{#3}}-

\noindent Comme l'argument \verb|#3| se trouve une seule fois dans le texte de remplacement de la macro et à la fin de celui-ci, il est possible de ne pas le faire lire par §\exptwoargs :

\showcode/\def\exptwoargs#1#2{\expsecond{\expsecond{#1}{#2}}}¤§*\exptwoargs§*\expsecond¤
\def\foo{Bonjour}\def\bar{ le monde}
\def\displaytwoargs#1#2{\detokenize{#1#2}}% affiche tels quels les arguments
\exptwoargs\displaytwoargs\foo\bar¤§*\exptwoargs¤/
\end{exercice}

Une macro plus générale, capable de développer plusieurs arguments sera programmée plus loin (voir page~\pageref{eargs}).

\section{La primitive \texttt{\textbackslash edef}}\idx*[|(]\edef
On a vu que  \verb-\expandafter- permettait de contrôler finement la profondeur de développement moyennant, c'est vrai, de longs et laborieux ponts d'\idx[|)]\expandafter. Mais il existe des endroits où \TeX{} développe au maximum\idx*[|(]{développement maximal} ce qu'il rencontre. Attention, il s'agit bien d'un développement et non pas d'une exécution. Le plus célèbre de ces endroits est le texte de remplacement des macros définies avec la primitive \verb|\edef|. Cette primitive fonctionne comme sa s\oe ur \verb-\def- sauf que tout ce qui se trouve à entre les accolades est développé au maximum et ce qui en résulte est le \idx{texte de remplacement} de la macro définie par \verb|\edef|. Essayons :

\showcode/\def\aa{Bonjour}\def\bb{\aa}
\def\cc{ le monde}
\edef\foo{\bb\cc}
\meaning\foo¤\idx*\meaning¤/

On constate que le texte de remplacement de \verb-\foo- contient le 2-développement de \verb|\bb| et le 1-développement de \verb|\cc|. Ces développements sont les plus profonds que l'on puisse faire puisqu'ensuite on ne trouve plus que des lettres ou des espaces. Le texte de remplacement de \verb-\truc- est bien « Bonjour le monde ».

Comme pour \verb-\def-, on peut aussi spécifier qu'une macro définie avec \verb|\edef| admet des arguments, et on utilise pour cela la même syntaxe \verb|#<chiffre>|, aussi bien pour le \idx{texte de paramètre} que pour le texte de remplacement. Le développement maximal fait lors de la définition concerne tout ce qui se trouve dans le \idx{texte de remplacement} \emph{à l'exception} des emplacements des arguments qui ont la syntaxe \verb|#<chiffre>|. Les arguments, qui seront lus plus tard lorsque la macro sera appelée, seront insérés tels quels à la place de \verb|#<chiffre>| : ils ne sont donc pas soumis au développement maximal.

On peut le constater ici où la macro \verb-\ee- est définie avec un \verb-\edef- et admet un argument. À l'aide d'\verb-\expandafter-, on provoque le 1-développement de la macro \verb-\ee- dont l'argument est la macro \verb-\dd-. On peut constater que cet argument «\verb-\dd-» reste non développé bien qu'il soit l'argument d'une macro définie avec \verb-\edef- :

\showcode/\def\aa{Bonjour } \def\bb{\aa} \def\cc{le } \def\dd{ monde}
\edef\ee#1{\bb\cc#1 !!!}
\meaning\ee\par¤\idx*\meaning¤
\expandafter\>\ee{\dd}</

\begin{regle}
La primitive \verb-\edef- a la même syntaxe et les mêmes actions que \verb-\def-, c'est-à-dire qu'elle stocke un \idx[|etc]{texte de remplacement}\forbidindex{texte de remplacement} associé à une \idx{séquence de contrôle}. La différence réside dans le fait que la totalité du texte de remplacement est développée \emph{au maximum} avant que l'assignation soit faite.

Le développement s'applique au texte de remplacement \emph{hors arguments} symbolisés par \verb|#<chiffre>|. Ceux-ci, qu'ils soient délimités ou pas, seront insérés tels qu'ils seront lus dans le texte de remplacement (qui lui aura été préalablement développé).

La primitive \idx\xdef effectue les mêmes actions que \verb|\edef| sauf que la définition faite est globale.
\end{regle}

\subsection{\texttt{\char`\\noexpand} pour contrer \texttt{\char`\\edef}}\idx*[|(]\noexpand
Cette primitive \verb-\edef- se révèle fort utile, et rend de grands services. Mais dans son argument où tout est développé au maximum, on voudrait pouvoir bloquer le développement d'une \idx{séquence de contrôle}. Par exemple, si l'on écrit

\centrecode-\edef\foo{\aa\bb\cc}-

\noindent comment laisser \verb-\aa- et \verb-\cc- se développer au maximum tout en bloquant le développement de \verb-\bb- ? C'est là qu'une nouvelle primitive entre en jeu, il s'agit de \verb-\noexpand-.

\begin{regle}
La primitive développable \verb|\noexpand| bloque le développement du token $x$ qui la suit. Elle a pour effet, lorsqu'elle se 1-développe, d'être le token $x$ lui-même. Si $x$ est une séquence de contrôle qui aurait été développée, $x$ est rendu temporairement égal à \verb|\relax|.
\end{regle}

\showcode|\def\foo{123xyz}
a) signification du 1-développement d'un \litterate-\noexpand- :¤\idx*\string\idx*\noexpand§*\litterate¤
   \expandafter\meaning\noexpand\foo¤\idx*\meaning¤

b) exécution d'un \litterate-\noexpand- : \noexpand\foo% identique à \relax

c) 1-développement de \litterate-\noexpand- dans le texte de remplacement de
   \litterate-\bar- :¤§*\litterate¤
   \expandafter\def\expandafter\bar\expandafter{\noexpand\foo}
   \meaning\bar¤\idx*\meaning¤|

Le dernier cas montre qu'entre le moment du 1-développement de \verb|\noexpand|\linebreak[1]\verb|\foo| et le moment où \TeX{} lit ce 1-développement, plusieurs choses sont faites (lecture et exécution du \verb|\def| suivie de la lecture \verb|\bar| et de l'accolade ouvrante). Entre temps, le développement initié par le pont d'\verb|\expandafter| s'est arrêté, signant la mort du \verb|\relax| temporaire qui est donc redevenu \verb|\foo|.
\grandsaut

Dans le code « \verb-\edef\foo{\aa\bb\cc}-», tentons maintenant de bloquer le développement de \verb|\bb| :

\showcode/\def\aa{Bonjour}\def\bb{\aa}\def\cc{\bb}
a) \edef\foo{\aa\noexpand\bb\cc}\meaning\foo  \qquad b) exécution : \foo\par¤\idx*\meaning¤
c) \edef\foo{\aa\noexpand{\aa\cc}}\meaning\foo\qquad d) exécution : \foo/

Tout se passe comme prévu au a) pour la première définition de \verb-\foo- avec \verb-\edef- : le \verb-\noexpand- qui précède \verb-\bb- empêche bien son développement.

À la deuxième ligne (cas c), on a tenté bien maladroitement de bloquer le développement de ce qui se trouve entre accolades. Ceci échoue puisque \verb-\noexpand- bloque le développement du \emph{token} qui suit et qui est dans ce cas «\cidx\{». Cette accolade ouvrante n'a d'ailleurs nul besoin d'être protégée d'un développement puisqu'elle n'est pas développable (et elle se développe donc en elle-même). Pour bloquer le développement de plusieurs séquences de contrôle, il \emph{faut} mettre un \verb-\noexpand- devant chacune d'elles !

\subsection{\texttt{\char`\\unexpanded} pour contrer \texttt{\char`\\edef}}
Multiplier les \verb-\noexpand- et en écrire autant qu'il y a de tokens à protéger peut être lourd, voire impossible si on ne connait pas le nombre de tokens lorsqu'on manipule l'argument d'une macro par exemple. Pour contourner cette difficulté, on peut utiliser la primitive \idx\unexpanded de \eTeX{} dont le développement est de bloquer le développement du texte entre accolades qui suit la primitive.

Voici deux façons de faire équivalentes, la première en plaçant un \verb|\noexpand| devant \verb|\bb| et \verb|\aa| la seconde en mettant ces deux tokens dans l'argument de la primitive \verb|\unexpanded| :

\showcode/\def\aa{Bonjour}\def\bb{Au revoir}
a) \edef\truc{\aa\noexpand\bb\noexpand\aa\bb}\meaning\truc \par¤\idx*\meaning¤
b) \edef\truc{\aa\unexpanded{\bb\aa}\bb}\meaning\truc¤\idx*\meaning¤/\idx*[|)]\noexpand

La primitive \idx\unexpanded, tout comme \idx\detokenize et d'autres, fait partie des primitives qui doivent être suivies d'une accolade ouvrante. Ces primitives initient un développement maximal jusqu'à ce qu'elles rencontrent une accolade ouvrante (voir règle page~\pageref{primitive.suivie.par.accolade}). On peut donc intercaler un ou plusieurs \idx\expandafter entre ces primitives et l'accolade ouvrante de façon à procéder au développement du (ou des) premiers tokens du texte entre accolades.

\subsection{\texttt{\char`\\the\char`\\toks\codeelement{nombre}} pour contrer  \texttt{\char`\\edef}}\idx*\toks
Il existe un autre moyen qui ne fait pas appel à \eTeX{} et qui permet de bloquer le développement dans un \verb|\edef|. Il s'agit du contenu d'un registre de tokens : dans le texte de remplacement d'un \verb|\edef|, le contenu d'un registre de tokens obtenu par le développement de \idx\the\linebreak[1]\idx\toks\linebreak[1]\verb|<nombre>| (ou par «\verb|\the|\linebreak[1]\verb|<nom d'un registre>|») n'est pas développé.

Voici l'exemple précédent traité avec un registre à token (ici, nous prenons le registre \no0) :

\showcode|\def\aa{Bonjour}\def\bb{Au revoir}
\toks0={\aa\bb}¤\idx*\toks¤
\edef\foo{\aa\the\toks0 \bb}¤\idx*\toks¤
\meaning\foo¤\idx*\meaning¤|

\subsection{Protéger une macro avec \texttt{\char`\\protected}}
Tout comme on peut déclarer une macro «\idx\long» ou «\idx\global» lors de sa définition, on peut aussi déclarer qu'on souhaite définir une macro « protégée ». On entend « protégée contre le développement maximal dans l'argument d'une primitive ». Pour ce faire, il faut utiliser la primitive de \eTeX {} «\idx\protected» et la placer avant le \verb|\def| (ou \verb|\edef|) qui effectue la définition. La macro ainsi définie ne se développera pas dans un \verb|\edef| :

\showcode/\def\aa{Bonjour}
\protected\def\bb{ le}% \ bb est protégée !¤\idx*\protected¤
\def\cc{ monde}

\edef\foo{\aa\bb\cc}
Signification de \string\foo~: \meaning\foo \par¤\idx*\meaning¤
Exécution de \string\foo~: \foo¤\idx*\string¤/

Il faut bien comprendre que la macro est protégée \verb|\bb|d'un développement est maximal, mais pas de l'action de \verb|\expandafter|. Voici comment on peut 1-développer \verb|\bb| dans le texte de remplacement de \verb|\edef| avec un \verb|\expandafter| :

\showcode/\def\aa{Bonjour}
\protected\def\bb{ le}¤\idx*\protected¤
\def\cc{ monde}

\edef\foo{\expandafter\aa\bb\cc}% le \expandafter 1-développe \bb
\meaning\foo/

\subsection{Les moyens de bloquer le développement maximal}\label{bloquer.developpement.maximum}
Il faut savoir est que certaines primitives (\idx\edef, \idx\xdef, \idx\csname\linebreak[1]\verb|...|\linebreak[1]\idx\endcsname que nous connaissons mais aussi \idx\message, \idx\write et \idx\errmessage que nous verrons plus tard) développent au maximum ce qui est dans leur argument\footnote{Il y a aussi \texttt{\char`\\special}, \texttt{\char`\\mark} et \texttt{\char`\\marks} qui ne seront pas étudiées dans ce livre. Pour être complet, il faut signaler que  le développement maximal est aussi en marche dans un alignement lorsque \TeX{} recherche un \texttt{\char`\\omit} ou un \texttt{\char`\\noalign}.}. Les méthodes pour contrer ce développement maximal valent aussi bien pour \verb|\edef| que pour n'importe quelle autre de ces primitives. Voici le résumé des méthodes que nous avons vues :

\begin{regle}
Il existe 4 moyens de bloquer le développement maximal dans les arguments de certaines primitives :
\begin{enumerate}
	\item mettre un \idx\noexpand devant chaque token dont on veut bloquer le développement;
	\item placer les tokens dont on veut bloquer le développement dans l'argument de la primitive \idx\unexpanded de \eTeX{};
	\item stocker au préalable tous les tokens dont on veut bloquer le développement dans un \verb|<registre de token>|\idx*{registre!token} et écrire dans l'argument de la primitive \idx\the\verb|<registre de token>|;
	\item lorsqu'on définit une macro, il est possible de faire précéder le \verb|\def| de la primitive \idx\protected de \eTeX{} pour empêcher le développement maximal de cette macro.
\end{enumerate}
\end{regle}\idx*[|)]\edef{}\idx*[|)]{développement maximal}

\section{Code purement développable}\idx*[|(]{code purement développable}
On pourrait penser que la primitive \verb|\edef| peut simuler une « exécution » pour mettre dans la \idx{séquence de contrôle} qu'elle définit le « résultat » de l'exécution du \idx{texte de remplacement}\footnote{On peut stocker l'affichage résultant d'un code arbitraire à l'aide des registres de boites que nous verrons plus tard.}. Il s'agit généralement d'une erreur, et pour comprendre pourquoi, il faut parler de ce qu'est du « code purement développable ».

Afin de mieux comprendre de quoi il s'agit, prenons un exemple simple, n'ayant aucun intérêt si ce n'est pédagogique. Supposons que la macro \verb|\foo| a comme texte de remplacement «abc», ce qui suppose qu'un \verb|\def\foo{abc}| a été rencontré auparavant. Voici un code élémentaire qui définit une macro \verb|\foo| et qui l'exécute :

\showcode/\def\foo{Bonjour}% définition
\foo% exécution/

Ce code de deux lignes n'est pas purement développable. Essayons de comprendre pourquoi en le mettant dans un \verb|\edef| pour définir la macro \verb|\bar| :

\centrecode-\edef\bar{\def\foo{Bonjour}\foo}-

Voici ce que va faire \TeX{} lorsqu'il va développer au maximum le code dans le texte de remplacement de \verb|\edef| :

\begin{enumerate}
	\item la primitive non développable \verb|\def| se développe en elle-même et reste donc inchangée ;
	\item les deux occurrences de \verb|\foo| vont être développées et donc remplacées par « abc ».
\end{enumerate}

Le texte de remplacement de \verb|\bar| sera donc :

\centrecode-\def abc{Bonjour}abc-

Vérifions-le :

\showcode/\def\foo{abc}
\edef\bar{\def\foo{Bonjour}\foo}
\meaning\bar¤\idx*\meaning¤/

Ce texte de remplacement comporte une erreur, car après un \verb|\def|, on \emph{doit} trouver une \idx{séquence de contrôle} (et non pas des caractères normaux comme a, b et c). Mais cette erreur n'apparait pas lors de la définition de\verb|\bar| car \TeX{} effectue les assignations sans procéder à l'analyse du texte de remplacement. Ce n'est que si l'on cherche à exécuter la macro \verb|\bar|, et donc à exécuter son texte de remplacement que \TeX {} émettra le message d'erreur « \texttt{Missing control sequence} ».

\begin{exercice}
Décrire ce qui se passerait si l'on écrivait le code ci-dessous alors que la macro \verb|\foo| n'est pas définie.

\centrecode-\edef\bar{\def\foo{Bonjour}\foo}-

\solution

Lors du développement maximal de \verb|\foo|, celle-ci n'étant pas définie, \TeX{} émettrait le message d'erreur «\texttt{Undefined
 control sequence}».
\end{exercice}

La conclusion est donc sans appel : que \verb|\foo| soit définie ou pas, le code n'est pas purement développable. On pourrait rétorquer que pour ce code soit purement développable, il suffirait de bloquer le développement de \verb|\foo| en se servant de la primitive \idx\noexpand :

\showcode/\def\foo{abc}
\edef\bar{\def\noexpand\foo{Bonjour}\noexpand\foo}¤\idx*\noexpand¤
Signification : \meaning\bar\par¤\idx*\meaning¤
Exécution : \bar/

Peut-on dire que le code, enrichi de \idx\noexpand, est purement développable ? En fait, tout dépend de ce que l'on attendait ! Si l'on voulait simplement construire un code exécutable stocké dans une macro, alors oui. Mais dans la grande majorité des cas, on attend qu'un code purement développable se réduise, lors de son développement maximal, aux caractères affichés si ce code était exécuté.

\begin{regle}
Un code est purement développable si son développement maximal se réduit aux caractères qui auraient été affichés s'il avait été exécuté par \TeX.

Dans la majorité des cas, un tel code ne doit être constitué que caractères (ceux que l'on souhaite dans l'affichage final) ainsi que de séquences de contrôle ou caractères actifs \emph{développables}. Citons :
\begin{itemize}
	\item du côté des primitives : \idx\expandafter, \idx\number, \idx\the, \idx\string ainsi que les primitives de \eTeX{} \idx\detokenize et \idx\unexpanded. Tous les tests de \TeX{} que nous verrons plus tard sont développables. Il y a aussi deux primitives de \eTeX{}, \idx\numexpr et \idx\dimexpr qui seront étudiées dans la partie suivante;
	\item les macros définies par l'utilisateur, qu'elles soient à arguments délimités ou pas, pourvu que leur développement maximal soit constitué des caractères que l'on souhaite dans l'affichage final.
\end{itemize}
\end{regle}\idx*[|)]{code purement développable}

\section{Propager le développement}
\subsection{Lier des zones de développement maximal}
Dans certaines zones bien spécifiques, le développement est maximal\idx*{développement maximal} et donc, dans ces zones, le code doit être purement développable.

L'expression « propager le développement » signifie mettre en \oe uvre des méthodes pour que ces zones de développement maximal se transmettent de proche en proche le développement. Le but est de développer des territoires très éloignés de l'endroit où le premier développement a eu lieu.

Parfois, du code \TeX{} est constitué de zones de développement maximal entrecoupées de zones « normales » où ce développement maximal n'existe pas. Le schéma ci-dessous représente une de ces situations où les zones de développement maximal sont encadrées et les tokens des zones normales sont représentés par «$\ast$». La tête de lecture de \TeX{} est représentée par \TeXhead{} :

\begin{centrage}
\small\fboxsep0pt
\TeXhead$\ast$\fbox{\strut\kern1.5cm }$\ast$\fbox{\strut\kern1.5cm }$\ast\ast$\fbox{\strut\kern1.5cm }$\ast x$
\end{centrage}

Il est possible, sans déplacer la tête de lecture, de 1-développer le token $x$. Pour cela, on va amorcer le développement de la première zone de développement maximal en mettant un \idx\expandafter juste avant le premier token «$\ast$». Par la suite, il faudra exporter le développement hors des zones encadrées à l'aide d'un \verb|\expandafter| placé en dernière position. Un pont d'\verb|\expandafter| prend ensuite le relai dans la zone normale pour communiquer le développement à la zone encadrée suivante. À la fin de la dernière zone, un pont d'\verb|\expandafter| permettra d'atteindre le token $x$ pour le 1-développer. En notant «$\bullet$» la primitive \verb|\expandafter|, voici ce que devient le schéma :

\begin{centrage}
\small\fboxsep0pt
\TeXhead$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet$}$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet$}$\bullet\ast${}$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet$}$\bullet\ast${}$x$
\end{centrage}

\begin{exercice}
\Qu e faudrait-il modifier dans ce schéma pour provoquer le 2-développement du token $x$ ?

\solution
Tout restant égal par ailleurs, il faut initier un pont d'\verb|\expandafter| à deux passes à la fin de la dernière zone de développement maximal, c'est-à-dire mettre 3 \idx\expandafter au lieu d'un seul :

\begin{centrage}
\small\fboxsep0pt
\TeXhead$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet$}$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet$}$\bullet\ast${}$\bullet\ast$\fbox{\strut\kern1.5cm $\bullet${}$\bullet${}$\bullet$}$\bullet${}$\bullet${}$\bullet\ast${}$x$
\end{centrage}
\end{exercice}

\subsection{Étude d'un cas}
Pour illustrer ce propos, passons à un cas plus concret, quoiqu'encore très théorique. Supposons qu'avant de lire les macros \verb-\foo- et \verb-\bar-, nous devions provoquer le 2-développement de la macro \verb-\wee- et le 1-développement de \verb-\fin- dans le code suivant :

\centrecode-\foo\bar\wee\fin-

\noindent Le nombre d'\idx\expandafter nécessaires est assez important. Essayons de les compter ! Plaçons mentalement les \verb|\expandafter| pour provoquer tour à tour le développement des macros prises \emph{de gauche à droite}, c'est-à-dire que nous allons d'abord chercher à développer \verb|\wee| qui est la plus à gauche des deux macros. Ensuite, nous partirons du code obtenu et chercherons à développer \verb|\fin|.

Pour 2-développer \verb|\wee|, il faut placer $2^2-1=3$ \idx\expandafter devant chaque token qui la précède ce qui fait $3\times2=6$ \idx\expandafter, notés $\bullet$:

\begin{centrage}
\small$\bullet\bullet\bullet$\litterate-\foo-$\bullet\bullet\bullet$\litterate-\bar\wee\fin-
\end{centrage}

\noindent Dans ce code, le nombre de tokens qui précèdent \verb-\fin- devient égal à 9 : nous avons les 6 \idx\expandafter que nous venons de placer et les 3 séquences de contrôle \verb|\foo|, \verb|\bar| et \verb|\wee|. Pour 1-développer \verb|\fin|, il faut mettre un \verb|\expandafter| devant chaque token qui précède \verb|\fin| ce qui fait 9 \verb|\expandatfer| de plus et porte donc leur nombre total à $6+9=15$. Voici le code obtenu :

\begin{centrage}
\small$\bullet\bullet\bullet\bullet\bullet\bullet\bullet$\litterate-\foo-$\bullet\bullet\bullet\bullet\bullet\bullet\bullet$\litterate-\bar-$\bullet$\litterate-\wee\fin-
\end{centrage}

Venons-en maintenant aux zones de développement maximal et au lieu d'écrire directement le nom des 4 macros, aidons-nous de la paire \verb-\csname- et \verb-\endcsname- :

\centrecode-\csname foo\expandafter\endcsname
\csname bar\expandafter\endcsname
\csname baz\expandafter\endcsname
\csname fin\endcsname-

Le rôle des \idx\expandafter mis à chaque fin de zone de développement maximal (sauf la dernière) est de transmettre le développement en dehors de la zone de développement maximal pour toucher le \idx\csname suivant qui commande à son tour le développement maximal jusqu'au prochain \idx\endcsname. L'\verb|\expandafter| se trouvant en fin de zone transmet à son tour le développement au \verb|\csname| suivant, et ainsi de suite jusqu'au dernier \verb-\endcsname- qui n'est pas précédé d'un \idx\expandafter et stoppe donc cet enchainement. La structure est clairement celle que l'on voyait dans le schéma de la section précédente : externaliser le développement pour déclencher le développement d'une nouvelle zone de développement maximal pour, en réitérant la man\oe uvre, transmettre très loin la flamme du développement. Voici le schéma qui traduirait cette situation (ici, aucun token ne se trouve entre les zones de développement maximal) :

\begin{centrage}
\small\fboxsep0pt
\TeXhead\fbox{\strut\kern1.5cm $\bullet$}\thinspace\fbox{\strut\kern1.5cm $\bullet$}\thinspace\fbox{\strut\kern1.5cm $\bullet$}\thinspace\fbox{\strut\kern1.5cm }
\end{centrage}

Le code donné ci-dessus se 1-développe en « \verb-\foo\bar\wee\fin- ». En voici la preuve :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\expandafter\>% provoque le 1-développement de :
\csname foo\expandafter\endcsname¤\idx*\csname\idx*\endcsname¤
\csname bar\expandafter\endcsname
\csname wee\expandafter\endcsname
\csname fin\endcsname</

Dans le code ci-dessus, aucune \idx{séquence de contrôle} n'est développée. Pour provoquer le 1-développement de \verb-\fin-, il suffit de mettre 3 \idx\expandafter après «wee» au lieu d'un seul. En suivant le même raisonnement, pour 2-développer \verb-\wee-, il faut 3-développer \verb-\csname-\linebreak[1] \verb-baz-\linebreak[1]\verb-\endcsname- et donc placer 7 \idx\expandafter après «bar». Cela donne le code :

\centrecode-\csname foo\expandafter\endcsname
\csname bar\expandafter\expandafter\expandafter\expandafter
   \expandafter\expandafter\expandafter\endcsname
\csname wee\expandafter\expandafter\expandafter\endcsname
\csname fin\endcsname-

\noindent Pour nous assurer que ce code fonctionne correctement, définissons \verb-\wee- pour que son 2-développement soit «XX» et \verb-\fin- pour que son 1-développement soit «YY» :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\fin{YY} \def\wee{\weeA} \def\weeA{XX}
\expandafter\>%
\csname foo\expandafter\endcsname¤\idx*\csname\idx*\endcsname¤
\csname bar\expandafter\expandafter\expandafter\expandafter
           \expandafter\expandafter\expandafter\endcsname
\csname wee\expandafter\expandafter\expandafter\endcsname
\csname fin\endcsname</

Le premier \idx\expandafter qui précède \verb-\>- suffit à atteindre, de zone de développement en zone de développement, la toute fin de ce code avant même que le premier nom de \idx{séquence de contrôle} \verb-\foo- ne soit formé.

\begin{exercice}
Où faut-il placer des \idx\expandafter dans « \verb-\>\foo\bar\wee\fin<- » pour obtenir la même chose que dans l'exemple précédent ?
\solution
Il faut les 15 \idx\expandafter déjà vus sauf qu'il faut sauter le token \verb|\>| au départ. On a déjà calculé qu'il faut 7 \idx\expandafter avant \verb-\foo-, il en faut également 7 pour sauter \verb-\>- qui vient en première position. Cela nous fait $15+7=22$ \idx\expandafter (au lieu de 12 avec \idx\csname et \idx\endcsname) :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\fin{YYY} \def\wee{\weeA} \def\weeA{XXX}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>%
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\foo
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\bar
\expandafter\wee\fin</
\end{exercice}

\subsection{\Qu 'est-ce qu'un nombre ?}
La notion de nombre (compris comme nombre \emph{entier}) étant étroitement liée à celle de développement, il est temps d'aborder ce sujet.\grandsaut

Tout d'abord, il est faux de croire que lorsque \TeX{} exécute le code

\centrecode-le nombre 123 est impair-

\noindent il \emph{lit} le nombre 123. Il ne fait qu'afficher séquentiellement les caractères «1» puis «2» et «3» sans pour autant que ces caractères ne soient isolés et analysés comme un tout formant un nombre entier. Pour que \TeX{} déclenche la lecture d'un nombre, il faut qu'il se trouve à un endroit où il s'attend à en lire un.

Nous avons déjà rencontré plusieurs cas où \TeX{} doit lire un nombre. C'est le cas pour les primitives \verb|\catcode|, \idx\lccode et \idx\uccode dont la syntaxe complète est

\begin{centrage}
	\small$\left.\vcenter{\hbox{\verb|\catcode|}\par\hbox{\verb|\lccode|}\par\hbox{\verb|\uccode|}}\right\}$\verb-<nombre>= <nombre>-
\end{centrage}

\noindent où le signe \verb|=| et l'espace qui le suit sont facultatifs.

Nous avons vu qu'après la primitive \idx\toks, \TeX{} attend le \verb|<nombre>| correspondant au registre de tokens auquel on veut accéder. Nous savons également qu'après la primitive \verb|\number|, \TeX{} s'attend à lire un nombre pour le convertir en chiffres arabes et en base 10. Un \verb|<nombre>| est également attendu après la primitive \idx\char et le tout se traduit par l'affichage du caractère dont le code de caractère est \verb|<nombre>|.

Pour être complet concernant les caractères affichés via \idx\char, il est possible d'utiliser la primitive \idx\chardef dont la syntaxe est 

\centrecode-\chardef\<macro>= <nombre>-

\noindent Comme pour \verb|\catcode|, \idx\lccode et \idx\uccode, le signe «=» et l'espace qui le suit sont facultatifs. L'action qu'effectue ce code est de rendre la \verb|\<macro>| équivalente à \verb|\char<nombre>|. L'équivalence dont il est question ici ressemble à celle effectuée avec \verb|\let|. Ainsi, si on écrit :

\centrecode-\chardef\foo= 65-

\noindent alors, la macro \verb|\foo| sera équivalente à \idx\char\verb|65| et produira un «A» à l'affichage.

Une \verb|\<macro>| définie avec \idx\chardef revêt une dualité intéressante : lorsque \TeX{} s'attend à lire un nombre, cette \verb|\<macro>| est alors comprise comme un nombre. Avec la macro \verb|\foo| ci-dessus, le nombre lu serait 65.

\showcode/\chardef\foo65 ¤\idx*\chardef¤
a) |\foo|\qquad % employée seule, \foo affiche un A¤\idx*\qquad¤
b) |\number\foo|\qquad % si TeX lit un nombre, \foo est le nombre 65¤\idx*\number¤/

Comme il n'y a que 256 caractères possibles\footnote{Pour les moteurs 8 bits, car les moteurs \utf en ont beaucoup plus.}, les primitives \idx\char et \idx\chardef ne peuvent prendre en compte que des nombres compris entre 0 et 255. Le mode mathématique\idx*{mode!mathématique} requiert d'afficher beaucoup plus de caractères que ces 256, aussi il existe les primitives \idx\mathchar et \idx\mathchardef qui sont au mode mathématique\idx*{mode!mathématique} ce que sont \idx\char et \idx\chardef au mode texte. Le caractère dual d'une macro définie par \idx\mathchardef existe sauf que le nombre qu'elle peut représenter est compris entre 0 et \numprint{32767}\footnote{Voir le \TeX book, page 181.} et lorsqu'elle est utilisée pour afficher un caractère, le mode mathématique doit être en vigueur.

\showcode/\mathchardef\foo4944 ¤\idx*\mathchardef¤
a) |$\foo$|\qquad % en mode math, affiche le signe "somme" (uniquement en mode maths)¤\idx*\qquad¤
b) |\number\foo|\qquad % si TeX lit un nombre, \foo est 4944¤\idx*\number¤/

Il est temps de donner la définition d'un nombre et montrer en quoi elle est liée au développement.

\label{definition.entier}\begin{regle}
\relax\idx*{nombre!définition}Un «nombre» est un entier relatif compris entre $-2^{31}+1$ et $2^{31}-1$, c'est-à-dire entre $-\numprint{2147483647}$ et $\numprint{2147483647}$. Tout nombre hors de cet intervalle provoque une erreur de compilation.

Lorsque \TeX{} s'attend à lire un nombre, il entre dans une phase de développement maximal. Dans les résidus de ce développement, il cherche tout d'abord une série de signes optionnels de catcode 12 : «\verb|+|» et «\verb|-|». Le signe du nombre final dépendra de la parité du nombre de signes «\verb|-|» lus au total. Ensuite, plusieurs cas peuvent se présenter :
\begin{enumerate}
	\item le nombre est explicitement écrit en
	
	\begin{itemize}[topsep=0pt]
		\item base 8 sous la forme \verb|'<signes>|;
		\item base 10 sous la forme \verb|<signes>|;
		\item base 16 sous la forme \verb|"<signes>|,
	\end{itemize}

	où les \verb|<signes>| sont une suite de chiffres de catcode 12 allant de \verb|0| à \verb|7| pour la base 8, de \verb|0| à \verb|9| pour la base 10 et pour la base 16, de \verb|0| à \verb|9| auxquels s'ajoutent les lettres \emph{majuscules} de catcode 11 ou 12 allant de \verb|A| à \verb|F|.
	
	\TeX{} stoppe la lecture du nombre au premier token qui n'est pas un \verb|<signe>| valide. Si ce token est un espace, il sera absorbé. Le nombre lu comprend donc la plus longue série de \verb|<signes>| valides possible;
	\item un « compteur » se présente (nous verrons les compteurs plus loin). Le nombre qu'il contient est lu et la lecture du nombre est stoppée;
	\item un « registre de dimension » se présente. Dans ce cas, la dimension est convertie en entier (nous verrons comment plus loin) et la lecture du nombre s'achève;
	\item une \idx{séquence de contrôle} définie avec \idx\chardef pour les nombres compris entre 0 à 255 ou avec \idx\mathchardef pour ceux compris entre 0 à 32767 se présente, le nombre correspondant est lu et la lecture du nombre est stoppée;
	\item un nombre écrit sous la forme \verb|`<car>| ou \verb|`\<car>| se présente, où «\verb|`|» est l'apostrophe inverse. Le nombre lu est le code de caractère de \verb|<car>|. Le \emph{développement maximal se poursuit} jusqu'au premier token non développable qui signe la fin de la lecture du nombre. \emph{Si ce token est un espace, il est absorbé}.
\end{enumerate}
\end{regle}

Plain-\TeX{} définit la \idx{séquence de contrôle} \idx\z@ comme étant un registre de dimension égal à la dimension nulle \verb|0pt|. Cette \idx{séquence de contrôle} est souvent employée en programmation, car elle présente 3 avantages :

\begin{enumerate}
	\item elle est convertie en l'entier 0 lorsque \TeX{} lit un nombre entier;
	\item elle est la dimension \verb|0pt| lorsque \TeX{} lit une dimension;
	\item dans les deux cas précédents, elle stoppe la lecture et le développement maximal.
\end{enumerate}

La primitive \idx\number est développable et son 1-développement provoque un travail assez conséquent : lecture du nombre selon la règle vue ci-dessus et conversion de ce nombre en base 10 sous la forme la plus simple en tokens de catcode 12. Par «forme la plus simple», on entend que le signe du nombre n'est donné que s'il est négatif et que les 0 inutiles de gauche sont supprimés si le nombre était explicitement écrit.

Lorsque \idx\the est immédiatement suivi d'un compteur, d'un registre de dimension ou d'une séquence de contrôle définie avec  \idx\chardef ou \idx\mathchardef, elle se comporte comme \idx\number.

Les compteurs, les registres de dimensions et les séquences de contrôle définies avec \idx\chardef ou \idx\mathchardef sont des représentations \emph{internes} d'entiers qui nécessitent une primitive développable (\idx\the ou \idx\number) pour obtenir les chiffres formant ce nombre en base 10. C'est donc une erreur que de les en dépourvoir pour les afficher.

\subsection{Nombres romains}
Tout comme \idx\number et \idx\the sont capable de produire des nombres arabes, la primitive \idx\romannumeral produit des nombres romains.

\begin{regle}
La primitive \idx\romannumeral doit être suivie d'un \verb|<nombre>| valide.

Son 1-développement est
\begin{itemize}
	\item l'écriture en chiffres romains de catcode 12 si le \verb|<nombre>| est strictement positif;
	\item vide si le nombre est négatif ou nul.
\end{itemize}

Si le \verb|<nombre>| est supérieur à 1000, la lettre «\verb|m|» de catcode 12 sera produite autant de fois qu'il y a de milliers dans le nombre.
\end{regle}

Nous faisons fonctionner ici la primitive \idx\romannumeral en l'encadrant des caractères «\verb|"|» pour mettre en évidence que les espaces qui suivent les nombres disparaissent bien. Vérifions également que le développement maximal a bien lieu avec les macros \verb-\foo- et \verb-\bar- :

\showcode|a) "\romannumeral 27 "\quad¤\idx*\romannumeral\idx*\quad¤
b) "\romannumeral 4687 "\quad
c) "\romannumeral 0 "\quad% 0 donc développement vide
d) "\romannumeral -2014 "\quad% négatif donc développement vide
e) \def\foo{7}\def\bar{\foo}%
   "\romannumeral \foo\foo\bar"\quad% 777
f) "\romannumeral 1\bar8\foo"\quad% 1787
g) "\romannumeral 1\bar8 \foo"% 178 (stoppé par l'espace) puis 7¤\idx*\quad\idx*\romannumeral¤|

Remarquons la différence entre les cas f et g où le simple espace en plus après «8» au cas g stoppe la lecture du nombre et le développement maximal. On constate que cet espace est absorbé, car aucun espace n'existe à l'affichage entre «\verb|clxxviii|» et «7».

\subsection{Le développement de \texttt{\char`\\romannumeral}}\idx*[!développement|(]\romannumeral
La primitive \idx\romannumeral est très intéressante, car son 1-développement déclenche un développement maximal dont on peut contrôler la portée. Surtout, ce développement maximal peut ne laisser aucune trace si le nombre que lit finalement \idx\romannumeral est négatif ou nul.

Si dans ce schéma

\begin{centrage}
	\small\fboxsep1pt
	\fboxrule0.4pt
	\verb-\romannumeral-\fbox{\fboxsep0pt \fcolorbox{gray!60}{gray!60}{\strut\kern2.5cm }$x$\textvisiblespace}
\end{centrage}

\begin{enumerate}
	\item la zone grise ne contient que des tokens purement développables dont le développement est vide;
	\item $x$ est un nombre négatif ou nul
\end{enumerate}

\noindent alors, 1-développer \idx\romannumeral revient à développer au maximum tous les tokens se trouvant dans la zone grise et à supprimer le nombre $x$ et l'espace qui le suit.

La zone encadrée devient une zone de développement maximal dont la portée est contrôlée par le placement du nombre négatif ou nul $x$.

Certes, cela implique une contrainte forte : tous les tokens dans la zone grise doivent être purement développables et une fois ceci fait, ils ne doivent rien laisser. En pratique, cette zone grise contient des appels à des macros et des tests.
\grandsaut

Pour mettre en évidence l'utilité d'une telle structure, reprenons l'exercice de la page~\pageref{expsecond} où l'on a vu que §\expsecond\verb-{<arg1>}{<arg2>}- devait se développer 3 fois pour que le code effectivement dans la pile soit \verb-<arg1>{*arg2}- (l'étoile indique que le premier token de l'argument 2 est 1-développé). Nous avions calculé qu'il fallait placer 7 \idx\expandafter devant \verb-\>- pour parvenir à nos fins :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\swaparg#1#2{#2{#1}}¤§*\swaparg¤
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}¤§*\expsecond§*\swaparg¤
\def\X{Bonjour}
\expandafter\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\>\expsecond\X\X<¤§*\expsecond¤/

Avec \verb-\romannumeral-, un seul \verb|\expandafter| sera requis pour sauter \verb|\>| et provoquer le 1-développement de \verb-\romannumeral- qui va tout développer au maximum et s'arrêter au bon moment. Ce \emph{bon moment} sera juste avant le \verb|\X| observé à l'affichage. Comme ce \verb|\X| est l'argument \verb|#2| de §\swaparg, un simple \verb*|0 |, placé avant cet argument \verb|#2| stoppe le développement maximal initié par \verb|\romannumeral| :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\swaparg#1#2{0 #2{#1}}% le "0 " stoppe ici le développement maximal¤§*\swaparg¤
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}¤§*\expsecond§*\swaparg¤
\def\X{Bonjour}
\expandafter\>\romannumeral\expsecond\X\X<¤\idx*\romannumeral§*\expsecond¤/

\begin{exercice}
À quel autre endroit aurait-on pu placer «\verb*-0 -» pour que le développement se passe comme on le souhaite ?
\solution
On veut stopper la lecture du nombre juste avant l'argument \verb-#2- de la commande §\swaparg. Cet argument est l'argument \verb-#1- de la commande §\expsecond et il suffit donc de mettre «\verb*-0 -» au début du premier argument de §\expsecond lorsqu'elle est appelée.

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\swaparg#1#2{#2{#1}}¤§*\swaparg¤
\def\expsecond#1#2{\expandafter\swaparg\expandafter{#2}{#1}}¤§*\expsecond§*\swaparg¤
\def\X{Bonjour}
\expandafter\>\romannumeral\expsecond{0 \X}\X<¤\idx*\romannumeral§*\expsecond¤/

Contrairement à celle de l'exemple précédent, cette méthode présente l'avantage de ne pas avoir à modifier les macros §\swaparg et §\expsecond.
\medbreak

On aurait donc remplacer \verb*|0 | par \idx\z@ avec l'avantage pour ce dernier de stopper la lecture du nombre sans avoir à insérer un espace :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\def\X{Bonjour}
\catcode`\@=11
\expandafter\>\romannumeral\expsecond{\z@\X}{\X}<¤\idx*\romannumeral\idx\z@§*\expsecond¤
\catcode`\@=12 /
\end{exercice}\idx*{nombre}\idx*[!développement|)]\romannumeral

\section{Programmation d'une variable unidimensionnelle}
Finissons ce chapitre en programmant une « variable », constituée de cellules qui auront chacune un nom et qui contiendront un code choisi par l'utilisateur. Il s'agit ici de copier les variables de type tableau (ou array) à une dimension qu'offrent la plupart des langages de programmation.

Supposons que l'on veuille définir la variable unidimensionnelle \verb-\foobar-. Pour définir la variable et remplir les cases dont les noms sont «\texttt 0», «\texttt 1», «\texttt 3» et «\texttt{toto}», on doit pouvoir écrire :

\centrecode-\newunivar\foobar¤§*\newunivar¤
\defunivar\foobar[0]{abcd}
\defunivar\foobar[1]{1 23}
\defunivar\foobar[3]{XY Z}
\defunivar\foobar[toto]{Bonjour}¤§*\defunivar¤-

\noindent Et par la suite, il suffira que l'on écrive \verb-\foobar[0]- pour que le code «\verb|abcd|», contenu dans la cellule «\verb|0|» soit restitué et exécuté.
\grandsaut

Passons maintenant à la mécanique interne. Si la variable est «\verb|\foobar|», décidons que le contenu des cellules sera stocké dans des séquences de contrôle auxiliaires. Par exemple, le code de la cellule \verb|0| sera contenu dans la macro  \verb-\-\boxtoken{\foobar[0]}. Autrement dit, le \emph{nom} de la macro doit être constitué des 10 caractères (inoffensifs) \boxtoken{ \unskip\textbackslash}, \boxtoken f, \boxtoken o, \boxtoken o, \boxtoken b, \boxtoken a, \boxtoken r, \boxtoken{[}, \boxtoken 0 et \boxtoken]. Pour former un tel nom, nous ferons appel à la paire \idx\csname\linebreak[1]\verb-...-\linebreak[1]\idx\endcsname.

L'ordre «\verb-\newunivar\foobar-» doit donc définir la macro \verb-\foobar- de cette façon :

\centrecode-\def\foobar[#1]{\csname\string\foobar[#1]\endcsname}-\idx*\string

Si on place ce texte de remplacement dans la définition de §\newunivar, il suffit de remplacer \verb|\foobar| par l'argument \verb|#1| de §\newunivar et de doubler les «\verb|#|». La macro §\newunivar sera donc définie ainsi :

\centrecode-\def\newunivar#1{\def#1[##1]{\csname\string#1[##1]\endcsname}}-\idx*\string§*\newunivar

\noindent On pourra ainsi appeler par la suite \verb-\foobar[0]- qui se 2-développera en la macro \verb-\-\boxtoken{\foobar[0]} tout en offrant la protection, au cas où la cellule n'a pas été définie, que la paire \verb-\csname-\linebreak[1]\verb-...-\linebreak[1]\verb-\endcsname- génère l'inoffensif \idx\relax. Aucune erreur de compilation ne sera donc provoquée en cas d'appel à une cellule non définie.

Pour la macro §\defunivar\verb-\<macro>[<nom>]-, un \idx\expandafter forcera la formation de la \idx{séquence de contrôle} avant que \verb-\def-, qui procède l'assignation, ne voie cette \idx{séquence de contrôle}. Par conséquent, §\defunivar\verb-\foo[0]- doit avoir le texte de remplacement suivant :

\centrecode-\expandafter\def\csname\string\foo[0]\endcsname-\idx*\string§*\defunivar

\noindent Et donc, §\defunivar doit être définie comme suit :

\centrecode-\def\defunivar#1[#2]{\expandafter\def\csname\string#1[#2]\endcsname}-\idx*\string§*\defunivar

\noindent ou encore, en utilisant §\defname

\centrecode-\def\defunivar#1[#2]{\defname{\string#1[#2]}}-

\noindent Il est inutile de lire l'argument du \verb|\def| qui est le contenu de la cellule. En effet, comme on l'a déjà vu à la page~\pageref{argument.def}, lire cet argument serait redondant puisqu'il faudrait le placer entre accolades à la fin du texte de remplacement de §\defunivar. Voici donc comment procéder :

\showcode/\def\newunivar#1{\def#1[##1]{\csname\string#1[##1]\endcsname}}¤§*\newunivar\idx*\string¤
\def\defunivar#1[#2]{\defname{\string#1[#2]}}¤§*\defunivar\idx*\string§*\defname¤
\newunivar\foobar¤§*\newunivar¤
\defunivar\foobar[0]{abcd}
\defunivar\foobar[1]{1 23}
\defunivar\foobar[3]{XY Z}¤§*\defunivar¤
Cellule 0 : \foobar[0]\par
Cellule 1 : \foobar[1]\par
Cellule 2 : \foobar[2]\par% cellule non définie : \foobar[2] donne \relax
Cellule 3 : \foobar[3]\bigbreak

\newunivar\client¤§*\newunivar¤
\defunivar\client[nom]{M. Raymond {\sc  Tartempion}}¤\idx*\sc¤
\defunivar\client[adr]{5 rue de la paix}
\defunivar\client[cod_post]{75000}
\defunivar\client[ville]{Paris}¤§*\defunivar¤
% fin des définitions, affichage de l'adresse :
\client[nom]\par
\client[adr]\par
\client[cod_post] \client[ville]/

On remarque que la programmation de cette variable unidimensionnelle est ici, grâce à la richesse et la puissance des instructions de \TeX{}, relativement facile et extrêmement concise puisqu'elle tient en deux lignes !

\begin{exercice}
Comment modifier les macros §\newunivar et §\defunivar vues précédemment pour que les cellules ne soient pas stockées dans la macro \verb-\-\boxtoken{\foobar[0]} mais dans la macro \verb-\-\boxtoken{foobar@0} ?
\solution
Faisons la supposition fondée que \idx\escapechar définit «\verb|\|» comme \idx{caractère d'échappement}. Lorsque \idx\string est développée à l'intérieur de \verb-\csname-\linebreak[1]\verb-...-\linebreak[1]\verb-\endcsname-, il con\-vertit le token \boxtoken{\foobar} en 7 tokens de catcode 12\idx*{catcode!12 (autre)} qui sont \boxtoken{ \unskip\textbackslash} \boxtoken{f} \boxtoken{o} \boxtoken{o} \boxtoken{b} \boxtoken{a} \boxtoken{r}. Il suffit de manger le premier token \boxtoken{ \unskip\textbackslash} avec un §\gobone en ayant pris soin de 1-développer \idx\string avant que §\gobone n'entre en action :

\centrecode-\def\newunivar#1{%¤§*\newunivar¤
	\def#1[##1]{\csname\expandafter\gobone\string#1@##1\endcsname}}¤\idx*\string§*\gobone¤
\def\defunivar#1[#2]{%¤§*\defunivar¤
	\defname{\expandafter\gobone\string#1@#2}}¤\idx*\string§*\gobone§*\defname¤-
\end{exercice}

\begin{center}
$\star$\par
$\star\quad\star$
\end{center}

Voici la fin de cette longue et difficile partie où, en nous intéressant aux commandes, nous avons découvert comment \TeX{} fonctionne. Pour résumer à l'extrême, \TeX{} est un langage de macros et donc, se comporte comme une machine qui remplace du code par du code jusqu'à arriver à des tokens non développables qui seront «exécutés» (des primitives, des caractères ordinaires de catcode 10, 11 ou 12 qui seront affichés ou des caractères revêtant des propriétés liées à leur catcode, comme \verb|$|).

Si l'on entre un peu plus dans les détails et en résumant ce qui a été dit, voici comment on peut se représenter le fonctionnement de \TeX{} : comme nous l'avons vu à la première partie, le code \TeX{} est constitué de cases chacune formée d'un \idx{octet} pour les \idx*{moteur!8 bits}moteurs 8 bits ou par une séquence d'octets codant un caractère \utf pour les moteurs \utf.\idx*{moteur!utf8} Lorsqu'ils sont transformés en tokens lorsque \TeX{} les lit, chacun de ces caractères obéit à des règles particulières propres à leurs catégories. Voici les cas particuliers qui sont transformés lors de la lecture :

\begin{itemize}
	\item lorsque des lettres sont précédées du \idx{caractère d'échappement} «\verb-\-» de catcode 0\idx*{catcode!0 (caractère d'échappement)}, le tout ne forme qu'un seul token, une \idx{séquence de contrôle};
	\item lorsqu'un \idx{espace} (catcode \number\catcode`\ )\idx*{catcode!10 (espace)} dans le code est suivi d'autres espaces\idx*{espace!consécutifs}, les autres espaces sont ignorés;
	\item un seul retour charriot \verbidx[ (retour charriot)]{^^M} (catcode 5) est compris comme étant un espace;
	\item deux retours charriots consécutifs sont équivalents au token \idx\par;
	\item deux caractères identiques de catcode \number\catcode`\^\idx*{catcode!7 (exposant)} consécutifs (comme «\verbidx{^^}») sont convertis en un caractère selon les règles exposées à la 1\iere{} partie;
	\item le caractère «\cidx\%» (catcode \number\catcode`\%) ainsi que tous les caractères jusqu'au retour charriot suivant sont ignorés.
\end{itemize}

Ainsi, on peut considérer le code \TeX{} comme étant des caractères écrits les uns à la suite des autres comme s'ils étaient sur un ruban et, après leur lecture, ces caractères sont transformés en de la matière assimilable par \TeX{}, les tokens. \TeX{} fonctionne à la manière d'une tête de lecture qui se déplace toujours linéairement de gauche à droite sur le ruban où est écrit le code. Voici, comment on peut se représenter schématiquement le fonctionnement de \TeX{} :

\begin{enumerate}
	\item lire un token : utiliser en priorité les tokens stockés dans la pile d'entrée si elle n'est pas vide et dans le cas contraire, construire le token à partir des caractères du code source en appliquant les règles de lecture du code en vigueur à ce moment-là.
	
	Si ce token lu requiert la lecture d'autres tokens (lecture d'un nombre, cas d'une macro à plusieurs arguments, cas de \verb|\def| qui doit être suivi d'une macro, d'un texte de paramètre et d'un texte de remplacement, etc.), recommencer en 1 jusqu'à ce que les tokens requis soient lus;
	\item figer les catcodes de tous les tokens lus et les stocker en mémoire;
	\begin{enumerate}
	\item si ce qui vient d'être lu n'est pas développable, exécuter l'action que commande le tout;
	\item sinon, 1-développer le premier token et insérer devant la tête de lecture (dans la \idx{pile d'entrée}) ce qui en résulte;
	\end{enumerate}
	\item retourner en 1.
\end{enumerate}

Lorsque \TeX{} est en phase de développement et si \verb|\expandfter| est la primitive à développer, convenons que 0 est la position de cet \verb|\expandafter| dans la liste des tokens à lire. Lorsque \verb|\expandafter| est développé, la tête de lecture de \TeX{} a la capacité, sans bouger de place, de «détacher» une «tête de développement». Celle-ci, en se désolidarisant de la tête de lecture, ira 1-développer le token se trouvant plus loin dans le code à la position 2 et suivra éventuellement les ordres de développement que son 1-développement implique. Une fois qu'il n'y a plus d'ordre de développement à suivre, la tête de développement revient sur la tête de lecture qui reprend son travail où elle l'avait laissé et tiendra compte, dans le futur, des développements effectués par sa tête de développement.
\grandsaut

On peut donc énoncer que le fonctionnement de \TeX{} s'apparente à celui d'une «\idx*{Turing (machine)}machine de Turing».\idx*[|)]{développement}
%|                                                                            |
%|                                Fin partie 2                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Partie 3                                  |
%|                                                                            |
\defpartcomment{\lettrine[lines=3,slope=4pt,nindent=0pt]{\libertineInitialGlyph{A}}{\kern -5pt près} avoir abordé la plus grosse partie des spécificités de \TeX{}, nous pouvons entrer dans le vif du sujet avec de la programmation non linéaire. Aucun algorithme complexe ne sera abordé dans cette partie, bien au contraire, nous nous en tiendrons aux plus élémentaires et aux plus passepartouts. Malgré leur simplicité, ils sont néanmoins difficiles à cause des spécificités du langage \TeX{}.}

\part{Structures de contrôle et récursivité}
\chapter{Les outils de programmation de \TeX}
Le langage \TeX{} a été doté des structures de contrôles nécessaires pour élaborer n'importe quel algorithme, aussi compliqué soit-il. À ce titre, c'est donc un langage \emph{complet}\idx*{langage complet}. Bien sûr, il ne viendrait à l'idée de personne de coder en \TeX{} un décompresseur zip ou un algorithme de jeu d'échecs\footnote{Il faut tout de même signaler une récente extension appelée « reverxii » pour \TeX{} qui joue au jeu d'Othello et qui tient en moins de 1000 octets ! Cette très faible taille tient au fait que l'auteur a utilisé toutes les astuces \TeX{}iennes (programmation de caractères actifs notamment) pour que la taille soit la plus petite possible, au prix d'une lisibilité nulle à un tel point qu'il est presque impossible de dire s'il s'agit de code \TeX{} ou pas !\par Le programme comporte une intelligence artificielle qui, bien que loin d'être redoutable, peut tenir tête à un joueur débutant.} ! Dans le monde de \TeX{}, le mot « compilation » signifie « traduction de la totalité code source en document affichable ». En \TeX{}, lorsqu'on parle de programmation, ce mot devient ambigu, car dans le monde de la programmation, « compilation» signifie « transformation du code source en code exécutable », le fichier binaire exécutable obtenu étant d'une grande rapidité. Ce qu'il faut comprendre est que le langage \TeX{} est \emph{interprété}, c'est-à-dire « exécuté au fur et à mesure » lors de la compilation ce qui le rend lent !
\grandsaut

Les principales structures de contrôle dont \TeX{} est doté sont les suivantes :

\begin{itemize}
	\item l'assignation, c'est-à-dire la possibilité de stocker des informations dans des « registres » (le mot « variables » est plus couramment utilisé dans d'autres langages), qui sont en quelque sorte des endroits de la mémoire accessibles et lisibles facilement. En \TeX{}, les structures les plus couramment utilisées capables de stocker de l'information sont les suivants :
	\begin{itemize}
		\item les séquences de contrôle;
		\item les registres de tokens;
		\item les registres d'entiers ou « compteurs » qui accueillent les entiers et sont dotés des 4 opérations où la division n'est possible que par un entier, étant entendu que cette division donne la partie entière;
		\item les registres de dimensions stockent des longueurs et qui permettent, sous certaines réserves que nous verrons, de manipuler des nombres décimaux. Les 4 opérations sont disponibles, mais la division n'est possible que par un \emph{entier};
		\item les registres de boites qui stockent un contenu arbitraire sous forme affichable, mais il n'est plus possible d'accéder au code qui a généré ce contenu.
	\end{itemize}
	\item les tests ;
	\item la \idx{récursivité}, c'est-à-dire la possibilité pour une macro de s'appeler elle-même, que ce soit directement ou par l'intermédiaire d'une ou plusieurs autres macros ;
	\item la localité, c'est-à-dire la possibilité de définir une zone où les assignations resteront valables dans cette zone pour être détruites une fois sorti de cette zone, tout en permettant de procéder à des assignations \emph{globales} qui survivent une fois que la zone est fermée ;
	\item la possibilité d'écrire dans un fichier, c'est-à-dire d'y stocker des \emph{caractères};
	\item la possibilité de lire les caractères stockés dans un fichier.
\end{itemize}

Et c'est à peu près tout ! Cette liste est \emph{minimaliste} et n'a rien à voir le pléthore de moyens que propose un langage de programmation actuel. Pour faire une comparaison dans les moyens simples et basiques, il n'y a par exemple, aucune structure de boucle (for, loop, while, etc.). Ni de « variables » de type évolué comme les tableaux à plusieurs dimensions par exemple. Aucune trace non plus d'opérations scientifiques. Mais qu'à cela ne tienne, les structures énoncées ci-dessus sont bien suffisantes pour en programmer soi-même. Il faut s'y habituer, en \TeX{}, on ne dispose que du strict minimum et bien souvent, on doit construire soi-même des structures de contrôle plus évoluées comme les boucles. La plupart du temps avec \TeX, tout est question d'assignations, de lecture raisonnée d'arguments, de comparaison, de développement et de récursivité. Pour autant que ça soit pénible au début, en contrepartie, c'est extrêmement souple puisqu'on peut bâtir des boucles sur mesure. C'est ce que nous allons apprendre à faire dans cette partie en étudiant plus spécialement les tests et la récursivité.

Mais avant de les aborder, il nous faut revenir aux nombres entiers et comprendre comment \TeX{} calcule.

\chapter{\TeX{} et les entiers}\idx*[|(]{nombre}%
S'il y a bien un domaine où \TeX{} n'excelle pas, c'est celui du calcul. On ne pourrait lui en vouloir puisque, conçu pour composer du texte, il n'était pas nécessaire de le doter de puissants outils de calcul. Mais depuis que \TeX{} a été écrit, beaucoup de temps s'est écoulé à l'échelle informatique et désormais, tout langage embarque pléthore d'outils de calcul. Par conséquent, un programmeur habitué à ces outils ressent à un moment ou à un autre une légitime frustration envers \TeX{} qui ne les propose pas. Voyons tout de même ce que \TeX{} offre en matière de calculs arithmétiques.

\section{L'arithmétique \TeX{}ienne}
\subsection{Les entiers}
\idx*[|(]{compteur}\TeX{} manipule des entiers signés sur $32$ bits. Ils sont donc compris entre $-2^{31}+1$ et $2^{31}-1$ c'est-à-dire entre $-\numprint{2147483647}$ et $\numprint{2147483647}$. Ces entiers sont stockés dans des registres spéciaux appelés « compteurs ». 256 de ces registres sont disponibles avec \TeX{} et $\numprint{65536}$ avec $\varepsilon$\TeX{}. Ainsi, \verb|\count42| fait référence au compteur \no42. Contrairement aux registres de tokens avec \idx\toks\verb|0|, aucune convention n'existe quant à un compteur portant un numéro spécial qui serait non utilisé et qui servirait de « compteur brouillon ».

\TeX{} met aussi à disposition la primitive \idx\countdef, qui ressemble à \idx\chardef ou \idx\toksdef. Par exemple, écrire

\centrecode-\countdef\foo=42-\idx*\countdef

\noindent rend \verb|\foo| équivalent à \verb|\count42| de telle sorte que le registre \no42 peut être désigné par la \idx{séquence de contrôle} \verb|\foo|. L'équivalence dont il est question ici ressemble à celle de \idx\let en ce sens que \verb|\foo| n'est pas développable et n'a pas de texte de remplacement mais \emph{sera} \verb|\count42|.

Comme pour les registres de tokens avec \idx\toksdef, plain-\TeX{} fournit une macro \idx\newcount qui, suivie d'une \verb-\<macro>-, permet d'allouer un compteur pour y faire ensuite référence avec une macro plutôt que par un numéro. La macro \idx\newcount se charge de trouver le numéro du prochain registre de compteur libre. Si par exemple, on écrit \verb-\newcount\foo- et si 89 est le numéro du prochain registre libre, alors la macro \idx\newcount procèderait à l'assignation suivante :

\centrecode-\global\countdef\foo=89-\idx*\global\idx*\countdef

\noindent La primitive \idx\global, placée devant l'assignation, rend celle-ci globale : on ne peut donc pas allouer localement un registre de compteur qui serait ensuite libéré après la sortie d'un groupe\footnote{Bien évidemment, mobiliser un compteur localement est possible, mais il faudrait écrire une nouvelle macro le permettant. Ceci est fait par le \idx[!etex]{package} \texttt{etex.sty} pour \LaTeX{} qui, entre autres fonctionnalités, fournit une macro \texttt{\char`\\loccount\char`\\\codeelement{macro}} par laquelle le compteur est défini de façon \emph{locale}.}.

\begin{regle}
Un compteur a vocation à contenir un nombre entier de $-2^{31}+1$ à $2^{31}-1$. On y fait référence par

\centrecode-\count<nombre>-

Il est aussi possible d'utiliser la commande

\centrecode-\newcount\<macro>-

qui fait le nécessaire pour lier la \verb|\<macro>| au prochain numéro de compteur non utilisé. Par la suite, la \verb|\<macro>| se comporte exactement comme \idx\count\verb|<nombre>|. Comme les registres de tokens, les \verb|<compteurs>| peuvent donc indifféremment être désignés selon ces deux possibilités.
\grandsaut

Pour assigner un \verb|<entier>| (voir la définition d'un entier à la page~\pageref{definition.entier}) à un compteur, il faut écrire\idx*{assignation!compteur}

\centrecode-<compteur>= <entier>-

\noindent où le signe \verb-=- ainsi que l'espace qui le suit sont facultatifs.
\end{regle}

Rappelons que pour \emph{afficher} la valeur du compteur, nous ne pouvons pas écrire \verb|<compteur>| dans le code sans risquer de provoquer une erreur de compilation. En effet, \TeX{} attendrait une assignation qui commence de cette façon et si ce \verb|<compteur>| n'était pas suivi d'un \verb|<nombre>|, \TeX{} se plaindrait d'un «\texttt{Missing number, treated as zero} ». Un compteur étant une représentation interne d'un entier, pour \emph{afficher} sa valeur, il faut traduire cette représentation interne en caractères affichables, et faire précéder le \verb|<compteur>| de \idx\the, \idx\number ou \idx\romannumeral :

\showcode/\newcount\foo \newcount\bar¤\idx*\newcount¤
\foo=42 \bar=\foo \string\bar\ vaut : \the\bar \par¤\idx*\string\idx*\the¤
\bar=\foo57 \string\bar\ vaut : \number\bar\par¤\defline\aaa\idx*\number¤
\bar=2014 \string\bar\ vaut : \romannumeral\bar¤\idx*\romannumeral\idx*\string¤/

\noindent La ligne \no\aaa{} montre que les caractères «\verb|57|» ne sont pas pris en compte pour l'affectation. Comme cela est dit à la page~\pageref{definition.entier}, si le \verb|<nombre>| que \TeX{} lit est un registre de compteur, le nombre qu'il contient est lu, et la lecture du nombre s'arrête (laissant ici «\verb|57|» hors du nombre pris en compte).

\begin{exercice}
\Qu e fait le code suivant ?

\centrecode-\newcount\foo
\newcount\bar
\foo=57
\bar=9\foo8\relax-

\solution
Tout d'abord, deux compteurs sont créés. Le nombre \verb|57| est affecté au compteur \verb|\foo|. Puis, à la dernière ligne, à droite de \verb|\bar=|, l'entier lu est \verb|9| car la lecture du nombre s'arrête sur \verb|\foo| qui n'est pas développable et n'est pas un chiffre.

Le compteur \verb|\bar| vaut donc 9 et ce qui est à la suite «\verb|\foo8\relax|» est une affectation qui rendrait le compteur \verb|\foo| égal à 8, écrasant la valeur \verb|57| qu'il avait auparavant. Le code proposé fait 3 assignations et ne produit aucun affichage.

À la dernière ligne, si nous avions voulu assigner 9578 au compteur \verb|\bar| (où 57 est la valeur du compteur \verb|\foo|), il aurait fallu écrire  :

\centrecode-\bar=9\number\foo8\relax-

de telle sorte que le développement mis en  place pour la lecture du nombre convertisse \idx\number\verb|\foo| en caractères valides pour un \verb|<nombre>|.
\end{exercice}

\subsection{Les opérations}\idx*[|(]{opérations arithmétiques}
Venons-en aux opérations arithmétiques à notre disposition. Celles-ci opèrent sur des compteurs, c'est-à-dire qu'il n'est pas possible de faire des opérations sur des nombres explicitement écrits en chiffres.

\begin{regle}
Dans les lignes ci-dessous, \verb|<n>| est un nombre entier au sens de \TeX{} :

\begin{itemize}
	\item \idx\advance\verb-<compteur> by <n>- : ajoute \verb-<n>- au \verb-<compteur>-;
	\item \idx\multiply\verb-<compteur> by <n>-  : multiplie le \verb-<compteur>- par \verb-<n>-;
	\item \idx\divide\verb-<compteur> by <n>- : divise le \verb-<compteur>- par \verb-<n>- en lui assignant la troncature à l'unité si le résultat de la division n'est pas entier.
\end{itemize}

Dans tous les cas, le mot «\verb-by-» et l'espace qui le suit sont facultatifs.
\end{regle}

Avec ces trois opérations, il est possible de programmer une macro \verb-\fonction- dont l'argument est un entier $n$ et qui calcule et affiche la valeur de $(3n-4)^2$. Le principe est d'assigner l'entier $n$ à un compteur et effectuer les opérations sur ce compteur (le multiplier par 3, lui ajouter $-4$, puis le multiplier par lui-même) pour l'afficher ensuite :

\showcode/\newcount\foo¤\idx*\newcount¤
\def\fonction#1{%
  \foo=#1 % assigne l'entier #1 au compteur puis
  \multiply\foo3 % multiplie par 3¤\idx*\multiply¤
  \advance\foo-4 % soustrait 4¤\idx*\advance¤
  \multiply\foo\foo% élève au carré (lmultiplie \foo par lui même)¤\idx*\multiply¤
  \number\foo% enfin, afficher le résultat¤\idx*\number¤
}
a) \fonction5\qquad b) \fonction{-13}/

La macro donne bien les résultats attendus, mais l'inconvénient est qu'elle nécessite un compteur et surtout qu'elle n'est pas purement développable. En effet, si nous écrivons \verb-\edef\bar{\fonction5}-, la macro \verb-\bar- n'aura pas 121 comme texte de remplacement. La raison est que le texte de remplacement de \verb-\fonction- contient des primitives qui ne se développent pas (\idx\multiply, \idx\advance) et la séquence de contrôle \verb|\foo| qui n'est pas développable non plus. Il s'agit ici d'un cas qui illustre la fondamentale différence entre « affichage produit par une macro après exécution » et « texte de remplacement de cette macro ». Ce n'est pas parce que «\verb|\fonction5|» affiche \verb|121| que tout se passe comme si «\verb|\fonction5|» était équivalent (même après développement) aux caractères \verb|121|. Nous pouvons le constater sur cet exemple :

\showcode/\newcount\foo¤\idx*\newcount¤
\def\fonction#1{%
  \foo=#1 \multiply\foo3 \advance\foo-4 \multiply\foo\foo¤\defline\aaa\idx*\multiply\idx*\advance¤
  \number\foo}¤\idx*\number¤
\edef\bar{\fonction{5}}%
a) Signification : \meaning\bar\par¤\idx*\meaning¤
b) Exécution : \bar¤\defline\bbb¤/

Pourquoi obtenons-nous \verb|0| lorsque \verb|\bar| est exécutée ? Parce que le code contenu dans \verb|\bar| (et affiché au cas a) effectue dans un premier temps les calculs sur le compteur \verb|\foo|, mais au lieu d'afficher le ce que contient ce compteur, elle affiche 0, qui est le résidu du développement de \idx\number\verb|\foo|.
\grandsaut

Non contente de créer une macro non purement développable, la méthode précédente peut rapidement rendre l'enchainement des opérations lourd, fastidieux et peu lisible, pour peu que les expressions à calculer soient plus complexes. En l'état de \TeX{} tel qu'il a été écrit par \idx*{Knuth Donald}D.~\textsc{Knuth}, il n'est pas possible de s'y prendre autrement. Heureusement, avec le moteur \idx\eTeX\idx*{moteur!etex}, une autre alternative est possible.

\subsection{La primitive \texttt{\char`\\numexpr}}\idx*[|(]{\numexpr}
Pour les entiers, la primitive \idx\numexpr\label{numexpr} permet d'effectuer un enchainement d'opérations arithmétiques via une écriture mathématique en notation infixée où les priorités arithmétiques habituelles sont respectées. Dans ces expressions, les espaces sont ignorés, les signes d'opérations sont \verb|+|, \verb|-|, \verb|*| et \verb|/| et des entiers explicitement écrits en chiffres peuvent y figurer. Pour la division, la seule différence avec la division \TeX ienne réside dans le fait qu'elle donne \emph{l'entier le plus proche} au lieu de \emph{la troncature}\idx*{opérations arithmétiques!troncature (division)}. Les expressions aussi contenir des parenthèses.

\begin{regle}
La primitive \idx\numexpr permet de calculer des enchainements d'opérations sur les entiers, pris au sens de la définition de la page~\pageref{definition.entier}. Elle doit être suivie d'une expression arithmétique où les espaces sont ignorés, les signes opératoires sont \verb|+|, \verb|-|, \verb|*|, \verb|/| et où les parenthèses sont admises .

Elle cherche à évaluer ce qui la suit en amorçant un développement maximal jusqu'à rencontrer un token qui ne peut figurer dans une expression arithmétique. Si l'expression arithmétique est suivie d'un \idx\relax, alors ce \idx\relax est mangé par \idx\numexpr. Ceci constitue une spécificité de la primitive \texttt{\string\numexpr} puisqu'avec \TeX, seuls les \emph{espaces} sont mangés après les nombres. C'est donc une excellente habitude de faire suivre une expression arithmétique évaluée par \idx\numexpr d'un \idx\relax.

La structure

\centrecode-\numexpr<expression arithmétique>\relax>-

est un entier au sens de \TeX{}, mais un peu comme l'est un compteur, c'est une représentation \emph{interne} d'un entier et donc, pour l'afficher, il faut recourir à une primitive qui transforme la représentation interne en caractères affichables telle que \idx\the, \idx\number ou \idx\romannumeral.
\end{regle}

L'exemple suivant montre comment, avec \idx\number, on peut afficher une expression évaluée par \idx\numexpr :

\showcode|a) \number\numexpr2+3*4\relax\qquad¤\idx*\number\idx*\numexpr¤
b) \romannumeral\numexpr2*3\relax\qquad¤\idx*\romannumeral¤
c) \number\numexpr(6-2*4)*(1-(2-6))\relax\qquad
d) \number\numexpr7/4\relax\qquad %7/4 vaut 1,75
e) \edef\foo{\number\numexpr2+3*4\relax}\meaning\foo¤\idx*\meaning¤|

Une expression évaluée par \idx\numexpr peut contenir une sous-expression, elle-même évaluée par un autre \idx\numexpr. Voici comment calculer 3*(1+2*5)+2, en évaluant l'expression entre parenthèses avec un \idx\numexpr imbriqué dans l'expression à calculer et en prenant soin de stopper sa portée par un \idx\relax :

\showcode/\number\numexpr3*\numexpr1+2*5\relax+2\relax/

L'emploi de \idx\numexpr peut rendre la macro \verb-\fonction- vue précédemment \emph{purement développable} :

\showcode/\def\fonction#1{\number\numexpr(3*#1-4)*(3*#1-4)\relax}¤\idx*\number\idx*\numexpr¤
a) \fonction5\qquad
b) \fonction{-13}\qquad
c) \edef\bar{\fonction5}\meaning\bar¤\idx*\meaning¤/

\begin{exercice}
Dans le code ci-dessus, l'expression «\verb|3*#1-4|» est évaluée \emph{deux} fois, ce qui est inutile et consommateur de temps. Comment modifier le code pour qu'elle ne soit évaluée qu'une seule fois ?
\solution
L'idée est de provoquer le calcul de «\verb|3*#1-4|» et passer le résultat à une macro auxiliaire \verb|\carre| qui affichera le carré de son argument:

\showcode/\def\fonction#1{\exparg\carre{\number\numexpr3*#1-4\relax}}¤\idx*\numexpr§*\exparg¤
\def\carre#1{\number\numexpr#1*#1\relax}¤\idx*\number\idx*\numexpr¤
a) \fonction{5}\qquad
b) \fonction{-13}\qquad
c) \edef\bar{\fonction5}\meaning\bar¤\idx*\meaning¤/

Ici, la macro §\exparg 1-développe et force le calcul de \verb|\number\numexpr3*#1-4\relax| en un nombre signé explicitement écrit, qui est transmis à la macro \verb|\carre| qui se charge de le multiplier par lui-même.
\end{exercice}

Il est parfois gênant que la primitive de \TeX{} \idx\divide sur les compteurs et la division «\verb|/|» de \idx\numexpr ne donnent pas les mêmes résultats. En effet, cela rompt la cohérence qui existe entre les trois autres opérations. Comment réconcilier les deux et faire en sorte d'inventer une division pour \idx\eTeX{} qui donne aussi la troncature ? Pour cela, il existe une formule générale. Si $x$ et $y$ sont deux entiers \emph{positifs}, si «\verb|/|» représente la division donnant l'entier le plus proche (la division de \idx\numexpr donc), la troncature du quotient de $x$ par $y$ est

\[(x-(y-1)/2)/y\]

À l'aide de \idx\numexpr, il est facile de programmer une macro \verb|\truncdiv{|$x$\verb|}{|$y$\verb|}| qui calcule la troncature du quotient de $x$ par $y$. Le résultat est donné sous la forme d'un entier \emph{non explicite}, c'est-à-dire qu'il faut \idx\number pour transformer cet entier en nombre affichable :

\showcode|\def\truncdiv#1#2{\numexpr(#1-(#2-1)/2)/#2\relax}¤\idx*\numexpr§*\truncdiv\idx*\number¤
8/3 :
a) \number\truncdiv83\qquad      % doit donner 2
b) \number\truncdiv{-8}3\qquad   % doit donner -2
c) \number\truncdiv8{-3}\qquad   % doit donner -2
d) \number\truncdiv{-8}{-3}\par  % doit donner 2
4/3 :
e) \number\truncdiv43\qquad      % doit donner 1
f) \number\truncdiv{-4}3\qquad   % doit donner -1
g) \number\truncdiv4{-3}\qquad   % doit donner -1
h) \number\truncdiv{-4}{-3}      % doit donner 1¤§*\truncdiv¤|

La macro donne bien des résultats erronés lorsque les nombres sont de signes contraires. Nous verrons au prochain chapitre comment la modifier pour que le résultat soit correct dans tous les cas.

Bien entendu, §\truncdiv peut être écrite dans une expression numérique évaluée par \idx\numexpr puisque les \idx\numexpr peuvent être imbriqués sous réserve que les \idx\numexpr internes aient leur portée limitée par \idx\relax, ce qui est le cas ici.\idx*[|)]{opérations arithmétiques}\idx*[|)]{\numexpr}

\section{Le test \texttt{\textbackslash{}ifnum}}\label{ifnum}\tidx*[|(]{ifnum}%
Le test \tidx{ifnum} est le premier test abordé puisqu'il a un étroit rapport avec le chapitre en cours sur les nombres entiers. Il est aussi l'un des plus fréquents.  Il n'est cependant qu'un test parmi beaucoup d'autres et avant de s'intéresser plus en détail à \tidx{ifnum}, un peu de théorie sur les tests de \TeX{} doit être abordée.

\subsection{Structure des tests}

\begin{regle}
Les tests de \TeX{} sont exécutés par des primitives qui obéissent aux contraintes suivantes :

\begin{enumerate}
	\item le nom des primitives exécutant un test commence par les lettres «\verb|if|» suivies d'autres lettres notées \verb|<test>| déterminant de quel test il s'agit;
	\item si \verb|\if<test>| est une primitive exécutant un test sur ses \verb|<arguments>|, sa structure est la suivante :

\centrecode-\if<test><arguments>
	<code exécuté si le test est vrai>
\else
	<code exécuté si le test est faux>
\fi-

	La branche entre \tidx{else} et \tidx{fi} est facultative et donc, un test peut également avoir la structure suivante :

\centrecode-\if<test><arguments>
	<code exécuté si le test est vrai>
\fi-
\end{enumerate}

Au lieu de \tidx{else} et \tidx{fi}, on peut mettre toute séquence de contrôle rendue \idx\let-égale à \tidx{else} ou \tidx{fi}.

Les tests et les primitives \tidx{else} et \tidx{fi} sont développables.
\end{regle}

Les codes exécutés selon l'issue du test peuvent aussi contenir des tests sans que \TeX{} ne s'y perde dans les appariements entre les primitives \verb|\if<test>| et leur \tidx{else} ou \tidx{fi}. En effet, un peu comme le compteur d'accolades, \TeX{} est doté d'un compteur interne d'imbrication de tests qui assure que chaque primitive de test est correctement appariée avec le bon \tidx{else} ou \tidx{fi}.

Il est en outre primordial de comprendre qu'à l'occasion d'un test, la tête de lecture de \TeX{} \emph{ne lit pas} tout le code dépendant du test (jusqu'au \tidx{fi}) pour stocker en mémoire les codes à exécuter selon l'issue du test afin de mettre l'un ou l'autre sur la pile juste après avoir effectué le test. Non, après avoir exécuté le test elle continue sa lecture linéaire, mais elle \emph{sait} qu'elle se trouve dans la portée d'un test et qu'à un moment ou à un autre, elle aura à lire \tidx{fi}, éventuellement précédé d'un \tidx{else}.

Pour que ce point soit clair, mettons-nous à la place de la tête de lecture de \TeX{} qui doit exécuter le test suivant (cas \no1) :

\centrecode-\if<test><arguments><code vrai>\else <code faux>\fi-

\noindent ou (cas \no2) :

\centrecode-\if<test><arguments><code vrai>\fi-

\subsubsection{Test vrai}
Supposons pour l'instant que le test est vrai. Voici l'enchainement des opérations qui vont avoir lieu :

\begin{enumerate}
	\item tout va commencer par le 1-développement de «\verb|\if<test><arguments>|» qui va disparaitre à l'occasion de ce développement;
	\item ce qui est à suivre, le \verb|<code vrai>| est exécuté normalement;
	\item le 1-développement de qui suit est vide. Il s'agit de 
	\begin{centrage}\small
		\verb|\else <code faux>\fi|\quad(cas \no1)\kern1cm ou\kern1cm \verb|\fi|\quad(cas \no2)
	\end{centrage}
\end{enumerate}

\subsubsection{Test faux}
Supposons à présent que le test est faux. Voici ce qui va se passer :

\begin{itemize}
	\item cas \no1 : 
	\begin{enumerate}
		\item le 1-développement de «\verb-\if<test><arguments><code vrai>\else-»\linebreak[4] est vide (où le \tidx{else} est apparié avec le test initial);
	\item ce qui suit, c'est-à-dire \verb|<code faux>| est exécuté normalement;
	\item le \tidx{fi} final qui reste est 1-développé et disparait.
	\end{enumerate}
	\item cas \no 2 : le 1-développement de «\verb-\if<test><arguments><code vrai>\fi-» est vide et la totalité de ce code disparait donc en 1-développement.
\end{itemize}

\begin{regle}
Lorsqu'un test est exécuté par une primitive de test \verb|\if<test>|, les primitives \tidx{else} et \tidx{fi} ne sont \emph{pas} supprimées lorsque le test est fait. Elles restent en place et lorsqu'elles seront rencontrées plus tard, elles s'autodétruiront par un simple développement.
\end{regle}

\subsection{Comparer des entiers}
\subsubsection{Le test \texttt{\char`\\ifnum}}
\begin{regle}
La primitive \tidx{ifnum}  effectue une comparaison entre deux entiers. La syntaxe est de la forme

\centrecode-\ifnum<entier1><signe><entier2>
	<code exécuté si le test est vrai>
\else
	<code exécuté si le test est faux>
\fi-

\noindent où le \verb-<signe>-, de catcode 12\idx*{catcode!12 (autre)}, est soit «\verb-=-» si l'on veut tester l'égalité entre les deux entiers, soit «\verb-<-» ou «\verb->-» s'il l'on cherche à tester une inégalité stricte.
\end{regle}

\showcode/a) \ifnum 15=14 vrai\else faux\fi\qquad% test faux¤\tidx*{ifnum}¤
b) \ifnum4<200 vrai\else faux\fi\qquad% test vrai
c) \newcount\foo \foo=9
   \ifnum\foo>9 nombre\else chiffre\fi% test faux¤\idx*\newcount¤/

Vérifions maintenant ce qui a été exposé en théorie sur le 1-développement d'un test. Pour ce faire, mettons à contribution la macro \verb|\>...<| vue à la partie précédente :

\showcode/\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
\expandafter\>\ifnum5=5 vrai\else faux\fi<\par% test vrai
\expandafter\>\ifnum5=6 vrai\else faux\fi<% test faux
\fi\fi% rétablir l'équilibre \ifnum et \fi¤\defline\aaa¤/

Les trois premières lignes de ce code permettent de visualiser les choses, mais rompent l'équilibre entre les \tidx{ifnum} et les \tidx{fi}. En effet, les \tidx{ifnum} sont exécutés par \verb|\expandafter|, mais les \tidx{fi}, détokénisés par \verb|\>|, ne seront jamais exécutés par \TeX. Pour rétablir l'équilibre et éviter que ce bug ne se propage jusqu'à la fin du code source de ce livre, deux \tidx{fi} ont été rajoutés à la ligne \no\aaa.

\begin{exercice}
Vérifier que les appariements des tests avec leur \tidx{else} et \tidx{fi} sont corrects en programmant une macro \verb-\numtest- qui admet un argument de type entier et qui affiche «chiffre» si son argument est compris entre $-9$ et $9$ inclus. Dans les autres cas, la macro doit afficher «nombre positif»  ou «nombre négatif».
\solution
Voici une façon  de programmer la macro \verb|\numtest| qui, compte tenu de ce qui a été dit sur le développement des tests, est purement développable :

\showcode/\def\numtest#1{%
	\ifnum#1>-10 ¤\tidx*{ifnum}¤
		\ifnum#1<10
			chiffre%
		\else
			nombre positif%
		\fi
	\else
		nombre négatif%
	\fi
}
a) \numtest{3}\qquad
b) \numtest{-67}\qquad
c) \numtest{-8}\qquad
d) \numtest{21}\qquad
e) \edef\foo{\numtest{2014}}\meaning\foo¤\idx*\meaning¤/
\end{exercice}
\begin{exercice}
Écrire une macro \verb-\normalise- qui admet un argument de type entier positif. Si l'entier est compris entre 0 et 999 compris, cette macro devra afficher son argument avec 3 chiffres, quitte à rajouter des 0 inutiles à gauche pour satisfaire cette exigence. Dans les autres cas, aucun affichage ne sera fait.

Par exemple, l'argument «17» donnera un affichage de «017» et «8» sera affiché «008».
\solution
Il suffit d'imbriquer des tests comme à l'exemple précédent et afficher 00 ou 0 juste avant l'argument \verb-#1- selon le cas. Ici par contre, la branche \tidx{else} n'est pas nécessaire :

\showcode/\def\normalise#1{%
	\ifnum#1>-1 % ne faire quelque chose que si #1 est positif ou nul¤\tidx*{ifnum}¤
		\ifnum#1<100 % si <100
			0% afficher un 0
			\ifnum#1<10 % si <10
				0%afficher un autre 0
			\fi
		\fi
		\number#1 %afficher le nombre¤\idx*\number¤
	\fi}% affiche le nombre
a) \normalise{749}\qquad
b) \normalise{0017}\qquad
c) \normalise8\qquad
d) \normalise{1789}\qquad
e) \normalise{-18}\qquad
f) \normalise{0}/

Le \idx\number qui se trouve devant l'entier \verb-#1- a deux fonctions :
\begin{itemize}
	\item celle d'afficher \verb-#1- sans provoquer d'erreur de compilation si \verb-#1- est un compteur;
	\item purger les éventuels 0 inutiles qui se trouvent à gauche de \verb-#1- si celui-ci est écrit explicitement. Ainsi, écrire \verb-\normalise{0017}- mène au résultat correct.
\end{itemize}

Il reste à remarquer que la macro \verb|\normalise|, puisque son texte de remplacement n'est constitué que de tests et de caractères affichables, est purement développable.
\end{exercice}

\subsubsection{Le test \texttt{\char`\\ifcase}}\tidx*[|(]{ifcase}%
Pour seconder le test \tidx{ifnum}, \TeX{} met à disposition le test \tidx{ifcase} qui opère également sur des entiers. Ce test fait un peu chambre à part dans le monde des tests, car sa syntaxe échappe à la syntaxe générale des tests et c'est pourquoi elle est expliquée en détail ici.

\tidx*[|(]{or}\begin{regle}
Le test \tidx{ifcase} teste si un entier est successivement égal à 0, 1, 2, ... selon la syntaxe suivante :

\tidx{or}\centrecode-\ifcase<nombre>
	<code exécuté> si <nombre> = 0
\or
	<code exécuté> si <nombre> = 1
\or
	<code exécuté> si <nombre> = 2
etc...
\else
	<code alternatif>% exécuté si aucune égalité précédente n'est vérifiée
\fi-

Les entiers auxquels le \verb|<nombre>| est comparé commencent nécessairement à 0, sont consécutifs et vont aussi loin qu'il y a de branches \tidx{or}. Il est donc nécessaire d'écrire autant de \tidx{or} que l'on veut envisager de cas.

La branche \verb|\else<code alternatif>| est facultative.
\end{regle}

Voici comment nous pourrions programmer une macro \verb|\mois{<entier>}| qui affiche en toutes lettres le nom du mois dont le numéro est passé en argument. Il est même possible de donner le mois en cours comme argument avec la primitive \idx\month, se comportant comme un compteur, qui contient le numéro du mois en cours :

\showcode/\def\mois#1{%
	\ifcase#1\relax¤\tidx*{ifcase}¤
	    \char`\#\char`\#% afficher "##" si argument = 0
	\or janvier\or f\'evrier\or mars\or avril%¤\tidx{or}¤
	\or mai\or juin\or juillet\or aout%
	\or septembre\or octobre\or novembre\or d\'ecembre%
	\else
	    \char`\#\char`\#% afficher "##" sinon
	\fi
}
a) \mois{-4}\qquad
b) \mois{3}\qquad
c) \mois{11}\qquad
d) \mois{20}\qquad
e) \edef\foo{\mois{\month}}\meaning\foo% mois en cours¤\idx*\month¤/\tidx*[|)]{ifcase}\tidx*[|)]{or}%

\subsection{Programmer un test : syntaxe}
Les primitives de \TeX{} ne suffisent pas --~et de loin~-- à couvrir tous les tests qu'il est possible de faire. On est donc parfois amené à programmer des \emph{macros} qui effectuent des tests plus complexes à l'aide notamment d'imbrications de tests primitifs. Décidons dès à présent que les noms de ces macros commencent aussi par les lettres «\verb|if|» suivies d'autres lettres notées \verb|<test>|. C'est un choix \emph{arbitraire} et tout autre choix aurait également été légitime : certains font commencer les \emph{macros} de test par les lettres \emph{majuscules} «\verb|IF|» pour ne pas qu'elles soient confondues avec les \emph{primitive}s qui commencent avec des lettres \emph{minuscules}.

La syntaxe de ces macros, différente de celle des primitives de test, fait davantage consensus. Si \verb|\if<test>| est une macro effectuant un test sur ses \verb|<arguments>| (pris comme argument d'une macro), il est extrêmement courant d'adopter la syntaxe suivante, très facile d'utilisation :

\centrecode-\if<test><arguments>
	{<code exécuté si le test est vrai>}
	{<code exécuté si le test est faux>}-

Basons-nous sur cette syntaxe pour programmer une macro §\ifletter[|(] qui teste si son argument, que l'on suppose constitué d'un seul caractère, noté \verb|<car>|, est une lettre \emph{minuscule}. Par souci de concision, notons \verb|<code vrai>| et \verb|<code faux>| les codes exécutés selon les issues des tests :

\centrecode-\ifletter{<car>}
	{<code vrai>}
	{<code faux>}-

Pour effectuer le test avec \tidx{ifnum}, seule primitive de test que nous connaissons pour l'instant, il va falloir exploiter une façon d'écrire un entier qui est \verb|`<car>| où \verb|<car>| est un caractère. L'entier que cela représente est le code du caractère \verb|<car>| (voir page~\pageref{definition.entier}). Nous allons également tirer parti du fait que les codes des caractères de «\verb|a|» à «\verb|z|» sont des entiers consécutifs. Par conséquent, \verb|<car>| est une lettre minuscule si l'entier \verb|`<car>| est compris entre les entiers \verb|`a| et \verb|`z| (bornes comprises).

\subsection{Programmer un test : méthodes}
Compte tenu du fait qu'il existe plusieurs méthodes pour programmer la \emph{structure} d'une telle macro, nous allons en envisager plusieurs et elles seront numérotées pour pouvoir facilement y faire référence plus tard.

\subsubsection{Méthode \no1 : intuitive}
Une façon intuitive de le faire est de faire lire les trois arguments par la macro :

\begin{enumerate}[label={}]
	\item \verb|#1| : le caractère \verb|<car>| à tester;
	\item \verb|#2| : le \verb|<code vrai>|, exécuté si le test est vrai;
	\item \verb|#3| : le \verb|<code faux>|, exécuté si le test est faux.
\end{enumerate}

Ensuite, il suffit d'imbriquer 2 tests comme nous l'avons déjà fait et selon l'issue de ces tests, écrire à l'intérieur des branches des tests les arguments \verb-#2- ou \verb-#3- :

\showcode/\def\ifletter#1#2#3{%
	\ifnum`#1<`a% si le caractère est avant "a"¤\tidx*{ifnum}¤
		#3% exécuter "<code faux>"
	\else% sinon
		\ifnum`#1>`z% si le caractère est après "z"
			#3% exécuter "<code faux>"
		\else% dans tous les autres cas
			#2% "#1" est une lettre : exécuter "<code vrai>"
		\fi
	\fi}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}/

Il y a une certaine inutilité dans ce code qui est de lire \verb-#2- et \verb-#3- par la macro \verb|\ifletter| pour les réécrire plus loin dans le code. L'idéal serait de ne lire que l'argument \verb-#1-, de faire le test et selon l'issue, de lire l'un des deux arguments qui suivent (et qui n'ont pas encore été lus).

\subsubsection{Méthode \no2 : \texttt{\char`\\firstoftwo} et {\char`\\secondoftwo}}
Les macros §\firstoftwo et §\secondoftwo que nous avons écrites à la page~\pageref{firstoftwo} permettent de sélectionner un argument parmi deux. C'est d'ailleurs parce qu'elles sont utilisées à l'issue d'un test qu'elles sont si fréquemment rencontrées en programmation. La façon naïve de les placer dans les branches des tests serait d'écrire :

\centrecode*-\def\ifletter#1{%
	\ifnum`#1<`a
		\secondoftwo
	\else
		\ifnum`#1>`z
			\secondoftwo
		\else
			\firstoftwo
		\fi
	\fi}-

\noindent Mais agir de cette façon provoquerait des résultats inattendus et des erreurs de compilation. Il ne faut surtout pas oublier que les \tidx{else} et les \tidx{fi} ne sont pas résorbés lorsque le test est fait, mais restent en place pour être développés (et éliminés) plus tard ! Il faut donc faire disparaitre les \tidx{else} et les \tidx{fi} \emph{avant} que §\firstoftwo ou §\secondoftwo n'entrent en jeu et ne les prennent à tort comme leurs arguments ! Pour cela, nous savons qu'il faut les 1-développer. Le cas du premier §\secondoftwo est le plus simple : nous mettrons donc un \idx\expandafter avant lui pour faire disparaitre les 7 dernières lignes.

Pour le test imbriqué, c'est un peu plus compliqué. Mettre un \idx\expandafter devant §\firstoftwo et §\secondoftwo fait disparaitre que le \tidx{else} ou le \tidx{fi} intérieur. Il restera encore le \tidx{fi} de la dernière ligne à 1-développer. Nous devons donc créer un pont d'\idx\expandafter à deux passes pour 1-développer d'abord le \tidx{else} ou le \tidx{fi} intérieur puis le \tidx{fi} final.

Voici donc comment coder la macro \verb|\ifletter| :

\showcode/\def\ifletter#1{%¤\tidx*{ifnum}¤
	\ifnum`#1<`a
		\expandafter\secondoftwo% \expandafter 1-développe "\else...\fi"¤§*\secondoftwo¤
	\else
		\ifnum`#1>`z
			\expandafter\expandafter\expandafter% 1-développe "\else...\fi" puis "\fi"
			\secondoftwo¤§*\secondoftwo¤
		\else
			\expandafter\expandafter\expandafter%1-développe "\fi" puis "\fi"
			\firstoftwo¤§*\firstoftwo¤
		\fi
	\fi}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}/

La macro \verb|\ifetter| est purement développable (à condition bien sûr que les instructions contenues dans \verb|<code vrai>| et \verb|<code faux>| le soient).

\subsubsection{Méthode \no3 : \texttt{\char`\\romannumeral}}
La méthode précédente produit une macro purement développable, mais le nombre de développements à faire pour arriver au \verb|<code vrai>| ou \verb|<code faux>| dépend du nombre de tests faits et donc, dépend de l'argument. Ne pas savoir à l'avance combien de développements sont nécessaires pour arriver au résultat escompté peut se révéler gênant dans certains cas particuliers.

\Qu el que soit son argument, faisons en sorte que la macro \verb-\ifletter- se développe en \verb-<code vrai>- ou  \verb-<code faux>- en deux développements. L'astuce, nous l'avons déjà vu, consiste à initier une zone de développement maximal avec la primitive \idx\romannumeral et stopper ce développement maximal au bon moment en ajoutant \verb*|0 | ou \idx\z@ (ou tout autre nombre négatif). Ce moment est ici le début de \verb-<code vrai>- ou  \verb-<code faux>- et donc, pour insérer cet ajout, il faut lire les deux derniers arguments de la macro \verb|\ifletter| :

\showcode/\def\ifletter#1#2#3{%
	\romannumeral % <- initie le développement maximal¤\idx*\romannumeral¤
	\ifnum`#1<`a
		\expandafter\secondoftwo¤§*\secondoftwo¤
	\else
		\ifnum`#1>`z
			\expandafter\expandafter\expandafter\secondoftwo¤§*\secondoftwo¤
		\else
			\expandafter\expandafter\expandafter\firstoftwo¤§*\firstoftwo¤
		\fi
	\fi{0 #2}{0 #3}% <- "0 " stoppe le développement maximal
}
\long\def\>#1<{\detokenize{#1}}¤\idx*\detokenize\idx*\long¤
a) \expandafter\expandafter\expandafter\>\ifletter{0}{vrai}{faux}<\qquad
b) \expandafter\expandafter\expandafter\>\ifletter{x}{vrai}{faux}</

\subsubsection{Méthode \no4 : macro auxiliaire}
Pour s'épargner tous ces \idx\expandafter et si nous n'avons pas besoin d'une macro purement développable, il est judicieux de s'aider d'une macro auxiliaire --~appelons-la \verb|\donext|~-- que l'on rend \idx\let-égale à §\firstoftwo ou §\secondoftwo dans les branches des tests. Cette macro sera appelée à la fin, après être sorti des branches des tests :

\showcode/\def\ifletter#1{%¤\tidx*{ifnum}¤
	\ifnum`#1<`a
		\let\donext=\secondoftwo¤§*\secondoftwo¤
	\else
		\ifnum`#1>`z
			\let\donext=\secondoftwo¤§*\secondoftwo¤
		\else
			\let\donext=\firstoftwo¤§*\firstoftwo¤
		\fi
	\fi
	\donext% exécuter l'action décidée ci-dessus
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}/

\subsubsection{Méthode \no5 : \texttt{\char`\\csname} et \texttt{\char`\\endcsname}}
La méthode de loin la plus élégante, mais hélas la plus lente est d'écrire les tests \emph{à l'intérieur} de la paire \idx\csname\linebreak[1]\verb-...-\linebreak[1]\idx\endcsname. Une fois que les tests seront développés, que les branches inutiles auront disparu suite au développement maximal initié par \idx\csname, il devra rester entre \idx\csname et \idx\endcsname soit «\texttt{firstoftwo}», soit «\texttt{secondoftwo}». La fin du mot «\verb|oftwo|» étant commune à toutes les issues possibles, il est possible de \emph{factoriser} le code en mettant cette partie de mot à la toute fin, juste avant le \idx\endcsname. Cette méthode présente l'avantage de donner \verb|<code vrai>| ou \verb|<code faux>| en trois développements, quel que soit l'argument donné à \verb|\ifletter| :

\showcode/\def\ifletter#1{%¤\idx\csname\tidx{ifnum}¤
	\csname
		\ifnum`#1<`a
			second% <- commenter la fin de ligne pour éviter un
		\else%          espace parasite dans le nom de la macro créée
			\ifnum`#1>`z
				second%
			\else
				first%
			\fi
		\fi
		oftwo%
	\endcsname
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}/

\begin{exercice}
Comment faudrait-il modifier ce dernier code pour que \verb|\ifletter| teste si son argument est une lettre de l'alphabet, aussi bien minuscule que majuscule ?
\solution
La primitive \idx\lowercase est utile dans ce cas puisqu'elle change toutes les lettres en lettres minuscules et laisse inchangées les séquences de contrôle :

\showcode/\def\ifletter#1{%¤\idx*\lowercase\idx*\csname\tidx*{ifnum}¤
	\lowercase{\csname
		\ifnum`#1<`a second%
		\else
			\ifnum`#1>`z second\else first\fi
		\fi
	oftwo\endcsname¤\idx*\endcsname¤
	}%
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}/

Hélas, la primitive \idx\lowercase n'est \emph{pas} développable ! Autrement dit, elle n'a pas vocation à être \emph{développée,} mais \emph{exécutée} c'est-à-dire que le remplacement des lettres par des lettres minuscules n'est pas fait sur la pile de \TeX{} mais plus tard, en interne, lors de l'exécution. Le code suivant montre qu'un \idx\edef ne provoque aucun développement sur cette primitive :

\showcode/\edef\foo{\lowercase{AbCd}}\meaning\foo/

Pour en revenir à la macro \verb|\ifletter|, si nous souhaitons qu'elle reste purement développable, il faut lui faire exécuter deux tests de plus (ce qui suppose autant d'imbrications supplémentaires) pour tester la place qu'occupe l'entier \verb|`<car>| par rapport aux entiers \verb|`A| et \verb|`Z| :

\showcode/\def\ifletter#1{%¤\idx*\csname¤
	\csname
		\ifnum`#1<`A second%
		\else
			\ifnum`#1<`Z first%¤\tidx*{ifnum}¤
			\else
				\ifnum`#1>`a
					\ifnum`#1<`z
						first%
					\else
						second%
					\fi
				\else
					second%
				\fi
			\fi
		\fi
		oftwo%
	\endcsname
}
a) \ifletter{4}{vrai}{faux}\qquad
b) \ifletter{t}{vrai}{faux}\qquad
c) \ifletter{D}{vrai}{faux}\qquad
d) \edef\foo{\ifletter{x}{vrai}{faux}}\meaning\foo\qquad¤\idx*\meaning¤
e) \edef\foo{\ifletter{=}{vrai}{faux}}\meaning\foo/

Ici encore, 3 développements sont nécessaires pour que \verb|\ifletter{<car>}{<vrai>}{<faux>}| se développe en \verb|<vrai>| ou \verb|<faux>| comme le montre ce schéma où une flèche représente un développement :

\begin{centrage}
\small
\verb|\ifletter{<car>}|%
$\longrightarrow$%
\verb|\csname...\endcsname|%
$\longrightarrow
\vcenter{\hbox{§\firstoftwo}\hbox{ou}\hbox{§\secondoftwo}}
\longrightarrow
\vcenter{\hbox{\verb|<vrai>|}\hbox{ou}\hbox{\verb|<faux>|}}$
\end{centrage}
\end{exercice}

\subsubsection{Retour sur la méthode \no1}
Bien que la méthode \no1 (dont le code est rappelé ci-dessous) semble identique aux autres méthodes, il n'en est rien !

\centrecode*-\def\ifletter#1#2#3{%
	\ifnum`#1<`a
		#3%
	\else
		\ifnum`#1>`z
			#3%
		\else
			#2%
		\fi
	\fi}-

Le fait que les arguments \verb|#2| et \verb|#3| soient insérés \emph{dans} les branches du test (alors qu'avec §\firstoftwo et §\secondoftwo, ils restent au dehors pour les autres méthodes) signifie que ces arguments peuvent agir sur ce qui se trouve après eux dans ces mêmes branches\ldots{} Et éventuellement tout casser ! Imaginons par exemple que l'argument \verb|#3| soit la macro §\gobtwo et que le premier test soit vrai. Lorsque \verb|#3|, c'est-à-dire la macro §\gobtwo va être exécutée, elle va capturer les deux arguments qui la suivent pour les faire disparaitre. Tout va se passer comme si un \tidx{else} et un \tidx{ifnum} étaient retirés du texte de remplacement. Ces deux primitives n'existant plus, l'équilibre entre les \tidx{fi} et les primitives de test est rompu et \TeX{}, lorsqu'il rencontrera un \tidx{fi} excédentaire, émettra l'erreur de compilation «\texttt{Extra \char`\\fi}».

Il est donc particulièrement important qu'une macro effectuant un test avec la syntaxe

\centrecode-\if<test><arguments>{<code vrai>}{<code faux>}<code qui suit>-

\noindent rejette \emph{au-dehors} des branches des tests les arguments \verb|<code vrai>| et \verb|<code faux>| de telle sorte que le code qu'ils contiennent puisse éventuellement agir sur le \verb|<code qui suit>|. La méthode \no1, puisque contrevenant à ce principe, est une méthode à déconseiller.§*\ifletter[|)]%

\subsection{Exercices sur les entiers}
\begin{exercice}
Programmer une macro §\ifinside[|(] dont voici la syntaxe :

\begin{centrage}
	\small§\ifinside $n$\verb|[|$a$\verb|,|$b$\verb|]{<code vrai>}{<code faux>}|
\end{centrage}

où $n$, $a$ et $b$ sont 3 entiers avec $a\leqslant b$. La macro §\ifinside teste si $n$ appartient à l'intervalle fermé $[a\;\string;\;b]$.
\solution

La première idée est d'imbriquer des tests sur les inégalités. Il faut exécuter \verb|<code faux>| si $n<a$ ou si $n>b$, et exécuter \verb|<code vrai>| sinon :

\showcode/\def\ifinside#1[#2,#3]{%
	\csname
		\ifnum#1<#2 second% si n<a, <code faux>
		\else
			\ifnum#1>#3 second% si n>b, <code faux>
			\else       first%  sinon, <code vrai>
			\fi
		\fi
	oftwo%
	\endcsname
}
a) \ifinside 3[1,8]{oui}{non}\qquad
b) \ifinside -7[-20,-11]{oui}{non}\qquad
c) \ifinside 9[0,6]{oui}{non}\qquad
d) \ifinside -1[-5,1]{oui}{non}/

Une autre approche serait de considérer l'entier

\[(n-a)(n-b)\]

Si cet entier est négatif ou nul, $n$ est dans l'intervalle. Autrement dit, §\ifinside doit exécuter \verb|<code faux>| lorsque cet entier est strictement positif. En s'aidant de \idx\numexpr, un seul test \tidx{ifnum} devient alors nécessaire pour décider si $n$ est dans l'intervalle ou pas\label{ifinside} :

\showcode/\def\ifinside#1[#2,#3]{%
	\ifnum\numexpr(#1-#2)*(#1-#3)\relax>0
		\expandafter\secondoftwo
	\else
		\expandafter\firstoftwo
	\fi
}
a) \ifinside 3[1,8]{oui}{non}\qquad
b) \ifinside -7[-20,-11]{oui}{non}\qquad
c) \ifinside 9[0,6]{oui}{non}\qquad
d) \ifinside -1[-5,1]{oui}{non}/§*\ifinside[|)]
\end{exercice}

\begin{exercice}
Programmer une macro §\absval\verb-{entier}-, purement développable et qui se développe en la valeur absolue de l'entier.
\solution
La première idée est de tester si l'entier est négatif auquel cas, nous prendrons l'opposé de ce nombre en mettant un signe «\verb+-+» devant :

\showcode/\def\absval#1{%¤\idx*\number\tidx*{ifnum}§*\absval¤
	\ifnum#1<0 \number-#1
	\else      \number#1
	\fi}
a) \absval{-87}\qquad b) \absval{75}\qquad c) \absval{0}¤§*\absval¤/

Mais la meilleure solution serait de se servir du fait que la primitive \idx\number développe au maximum tout ce qu'elle trouve jusqu'à trouver un caractère qui ne peut pas appartenir à un nombre. Nous pouvons donc mettre le test \emph{dans} le nombre évalué par \idx\number, c'est-à-dire après cette primitive. Le développement maximal de ce test laissera «\verb+-+» si le nombre est négatif et rien sinon :

\showcode/\def\absval#1{\number\ifnum#1<0 -\fi#1 }¤§*\absval¤
a) \absval{-87}\qquad b) \absval{75}\qquad c) \absval{0}¤§*\absval¤/

Un fonctionnalité intéressante est d'autoriser des expressions arithmétiques dans l'argument de §\absval. Pour ce faire, nous pouvons évaluer cet argument avec \idx\numexpr :

\showcode/\def\absval#1{\number\ifnum\numexpr#1\relax<0 -\fi\numexpr#1\relax}¤\idx*\numexpr\idx*\relax§*\absval¤
a) \absval{-87}\qquad
b) \absval{75}\qquad
c) \absval{0}\qquad
d) \absval{-20+13}\qquad% -7 affiché 7
e) \absval{5-3*(-4)+10-50}% -23 affiché 23¤§*\absval¤/

Le seul inconvénient est que nous évaluons \emph{deux} fois l'expression arithmétique \verb|#1| ce qui est redondant et source de ralentissement. Un  programmeur rigoureux décomposerait le travail et écrirait deux macros. La première serait chargée d'évaluer l'expression arithmétique et de passer comme argument à la seconde macro le \emph{nombre explicitement écrit} qui a été obtenu. Celle-ci serait chargée de donner la valeur absolue de son argument :

\showcode/\catcode`\@11
\def\absval#1{\exparg\absval@i{\number\numexpr#1\relax}}¤\idx*\numexpr\idx*\relax§*\absval§*\exparg¤
\def\absval@i#1{\number\ifnum#1<\z@-\fi#1 }¤\idx*\number\idx*\z@¤
\catcode`\@12
a) \absval{-87}\qquad
b) \absval{75}\qquad
c) \absval{0}\qquad
d) \absval{-20+13}\qquad% résultat -7 qui est affiché 7
e) \absval{5-3*(-4)+10-50}% résultat -23 qui est affiché 23¤§*\absval¤/
\end{exercice}

\label{intdiv}\begin{exercice}
Nous avions vu au chapitre précédent la macro §\truncdiv qui appliquait la formule suivante pour calculer la troncature du quotient de $x$ par $y$ en utilisant la division de \idx\numexpr :

\[\frac{x-\frac{y-1}2}y\]

Voici le code de la macro tel que nous l'avions élaboré:

\centrecode|\def\truncdiv#1#2{\numexpr(#1-(#2-1)/2)/#2\relax}|§*\truncdiv

La formule n'étant valable que pour $x$ et $y$ positifs, cette macro donnait des résultats erronés pour des arguments négatifs. Modifier la macro §\truncdiv pour qu'elle donne le bon résultat, quels que soient les signes de ses deux arguments.
\solution
Déjà, la formule donnée est équivalente à
\[\frac{2x-y+1}{2y}\]
qui sera sans doute un peu plus rapide puisqu'il n'y a qu'une seule division.

Puisqu'elle n'est valable que pour les entiers positifs, nous allons reprendre le code de la macro §\truncdiv donné dans l'énoncé en remplaçant les arguments par leur valeur absolue. Pour que le quotient final tienne compte des signes des arguments, nous allons multiplier le quotient par 1, précédé du signe du premier argument et du signe du second. De cette façon, s'ils sont tous les deux positifs, nous aurons \verb|--1| et la primitive \idx\number sait que ce nombre est 1. Si l'on note $\sigma_x$ le signe de $x$, cela donne

\[\sigma_x\sigma_y1\times\frac{2|x|-|y|+1}{2|y|}\]

Pour cela, reprenons la macro §\absval et créons une macro §\sgn qui se développe en «\verb|-|» si son argument est strictement négatif :

\showcode|\def\sgn#1{\ifnum#1<0 -\fi}¤§*\sgn¤
\def\truncdiv#1#2{%¤§*\truncdiv§*\absval§*\absval§*\truncdiv¤
	\numexpr
		\sgn{#1}\sgn{#2}1*% multiplie le quotient ci-dessous par +1 ou -1¤§*\sgn¤
		(2*\absval{#1}-\absval{#2}+1)/(2*\absval{#2})¤§*\absval¤
	\relax
}
a) \number\truncdiv{-8}3\qquad
b) \number\truncdiv{-8}{-3}\qquad
c) \number\truncdiv8{-3}\qquad
d) \number\truncdiv{0}{-5}¤§*\truncdiv¤|

Une optimisation possible de la formule est d'écrire au dénominateur $2y$ (qui contient le signe de $y$) et supprimer $\sigma_y$ au début. Il est aussi possible de déplacer $\sigma_x$ au dénominateur :

\[\frac{2|x|-|y|+1}{\sigma_x2y}\]

Si $y$ est une expression arithmétique, il est plus prudent de mettre \verb|#2| (qui représente $y$) entre parenthèses au dénominateur. Cela nous donnerait la macro

\centrecode|\def\truncdiv#1#2{%¤§*\truncdiv¤
	\numexpr(2*\absval{#1}-\absval{#2}+1)/(\sgn{#1}2*(#2))\relax¤§*\absval§*\sgn¤
}|

En l'état, elle n'est pas satisfaisante, car si \verb|#1| est une expression arithmétique, §\sgn\verb|{#1}| va provoquer une erreur puisque rien n'est prévu pour évaluer l'argument de §\sgn. De plus, l'argument \verb|#2| est évalué \emph{deux} fois : une fois par §\absval et une autre dans la parenthèse au dénominateur.

Il faut mettre un peu d'ordre et décider que les deux arguments de §\truncdiv doivent tout d'abord être calculés par une première macro puis être transmis en tant que nombres explicitement écrits à une seconde macro qui fera le calcul. Comme les arguments sont déjà calculés, il ne faut pas que \verb|absval| ne les calcule à nouveau. Abandonnons donc cette version de §\absval pour écrire «§\sgn\verb|{<entier>}<entier>|» ce qui arithmétiquement, est la valeur absolue de l'\verb|<entier>| :

\showcode|\catcode`\@11
\def\sgn#1{\ifnum#1<\z@-\fi}¤\idx*\z@§*\sgn¤
\def\truncdiv#1#2{%
	\exptwoargs\truncdiv@i{\number\numexpr#1\relax}{\number\numexpr#2\relax}%¤§*\truncdiv§*\exptwoargs\idx*\number§*\truncdiv¤
}
\def\truncdiv@i#1#2{%¤§*\truncdiv¤
	\numexpr(2*\sgn{#1}#1-\sgn{#2}#2+1)/(\sgn{#1}2*#2)\relax¤§*\sgn¤
}
\catcode`\@12
a) \number\truncdiv{-8}3\qquad
b) \number\truncdiv{-8}{-3}\qquad
c) \number\truncdiv8{-3}\qquad
d) \number\truncdiv{0}{-5}\qquad
e) \number\truncdiv{20+2*3}{4-5*2}% 26/(-6) doit donner -4¤§*\truncdiv¤|
\end{exercice}

\begin{exercice}
\def\siecle#1{%
	\ifnum#1=0 \else
		\uppercase\expandafter{\romannumeral\ifnum#1<0-\fi#1 }%
		\raise1ex \hbox{e\ifnum#1=1 r\fi}
		siècle \ifnum#1<0 avant J.C.\fi
	\fi
}
Élaborer une macro §\siecle\verb|{<nombre>}| qui, selon le nombre contenu dans son argument, adapte l'écriture des siècles :\medbreak
\begin{tabular}{>{\ttfamily\hfill}m{0.5\linewidth}<{\kern1em \normalfont affiche\kern1em}@{}l}
\string\siecle\{19\}&\siecle{19}\\
\string\siecle\{-3\}&\siecle{-3}\\
\string\siecle\{1\}&\siecle{1}\\
\string\siecle\{0\}&\siecle{0}<vide>
\end{tabular}

Pour surélever un texte enfermé dans une boite (ici une \idx\hbox), on aura recours à la primitive \idx\raise et on écrira :

\centrecode-\raise1ex \hbox{<exposant>}-

pour élever l'\verb|<exposant>| de \verb|1ex|.
\solution
Il s'agit de faire quelque chose sauf si l'argument est nul. Nous pouvons donc écrire

\centrecode-\ifnum#1=0 \else<action à faire>\fi-

\noindent mais le moteur \idx\eTeX{}\idx*{moteur!etex} dispose de la primitive \tidx{unless} qui, placée devant un test, échange les branches correspondant aux issues du test : ce qui est entre le test et \tidx{else} est échangé avec ce qui est entre \tidx{else} et \tidx{fi}. Nous écrirons donc ici :

\centrecode-\unless\ifnum#1=0 <action à faire>\fi-

Pour obtenir des chiffres romains en majuscule, nous allons utiliser la primitive \idx\uppercase en ayant pris soin de développer au préalable son argument traduit en chiffres romains par \idx\romannumeral. Pour être surs que le nombre évalué est toujours positif, nous écrirons \idx\romannumeral§\absval\verb|{#1}|.

Pour l'« exposant », nous allons donc utiliser la primitive \idx\raise qui a la faculté d'élever --~ici d'\verb|1ex|~-- la boite horizontale qui la suit. Cette boite contiendra «\verb|e|» suivi, si la valeur absolue de l'argument est 1, d'un «\verb|r|». Il faudra ensuite insérer «av. J.-C.» si l'argument \verb|#1| est strictement négatif. Le code est finalement assez facilement lisible :

\showcode/\def\siecle#1{%¤§*\siecle¤
	\unless\ifnum#1=0 % ne faire quelque chose que si #1 différent de 0¤\tidx*{unless}¤
		\uppercase\expandafter{\romannumeral\absval{#1}}% chiffres romains majuscules¤\defline\aaa\idx*\uppercase\idx*\romannumeral§*\absval¤
		\raise 1ex \hbox{e\ifnum\absval{#1}=1 r\fi} siècle% affiche l'exposant puis "siècle"
		\ifnum#1<0 {} av. J.-C.\fi% affiche si besoin "av. J.-C."¤\idx*\raise\idx*\hbox§*\absval\tidx*{ifnum}¤
	\fi
}
a) \siecle{19}\qquad
b) \siecle{-3}\qquad
c) \siecle{1}\qquad
d) \siecle{0}\qquad
e) \siecle{-1}¤§*\siecle¤/

Le \idx\expandafter de la ligne \no\aaa{} est automatiquement développé puisque \idx\uppercase fait partie de ces macros qui doivent être suivie d'une accolade ouvrante et qui donc, développe au maximum ce qui est entre elle et cette accolade. Le développement de cet \idx\expandafter provoque celui de \idx\romannumeral qui convertit le nombre en chiffres romains avant que \idx\uppercase ne joue son rôle et écrive les chiffres romains en majuscule.
\end{exercice}

\begin{exercice}
Programmer une macro §\hdif[|(]\verb|{h:m:s}{h':m':s'}| qui calcule le temps qui s'est écoulé entre l'heure \verb|h:m:s| et l'heure \verb|h':m':s'| qui lui est antérieure. L'affichage se fera en heures, minutes et secondes :\medbreak

\begin{tabular}{>{\ttfamily\hfill}m{0.6\linewidth}<{\kern1em \normalfont affiche\kern1em}@{}l}
\verb|\hdif{18:51:20}{9:20:10}|&\hdif{10:51:20}{9:20:10}\\
\verb|\hdif{14:20:0}{13:50:0}|&\hdif{14:20:0}{13:50:0}\\
\verb|\hdif{7:50:20}{5:50:20}|&\hdif{7:50:20}{5:50:20}\\
\verb|\hdif{7:50:10}{6:50:20}|&\hdif{7:50:10}{6:50:20}\\
\verb|\hdif{20:00:00}{19:59:15}|&\hdif{20:00:00}{19:59:15}\\
\verb|\hdif{17:13:15}{14:12:45}|&\hdif{17:13:15}{14:12:45}
\end{tabular}
\solution
La soustraction de durées exprimées en heures, minutes et secondes se fait comme au collège :
\begin{enumerate}
	\item effectuer les soustractions indépendamment entre les heures, les minutes et les secondes ;
	\item si le nombre de secondes est strictement négatif, l'augmenter de 60 et soustraire 1 au nombre de minutes ;
	\item puis, si le nombre de minutes est strictement négatif, l'augmenter de 60 et soustraire 1 au nombre d'heures ;
\end{enumerate}

L'algorithme s'annonce finalement assez simple.

Comme pour nous en France, le caractère «\verb|:|» est parfois rendu actif\footnote{Afin qu'il insère une espace insécable du type \texttt{\string\kern\codeelement{dimension}} juste avant  «\texttt{\string\string\string\:}».}, il faut ouvrir un groupe semi-simple et changer son code de catégorie \emph{avant} de lire l'argument de \verb|\hdif|. Le groupe semi-simple sera fermé à la fin, après l'affichage.

La principale méthode de programmation ici consiste à passer les arguments à une macro à arguments délimités \verb|\hdiff@ii| qui isolera les heures, minutes et secondes, effectuera les soustractions entre nombres exprimés dans la même unité et ajustera les résultats s'ils sont négatifs. Pour ce qui est de l'affichage du résultat, les nombres d'heures, minutes et secondes ne seront affichés que s'ils ne sont pas nuls. Enfin, du côté de la typographie, une macro temporaire \verb|\inter@space|, vide au début, sera rendue \idx\let-égale à un espace dès qu'un nombre (d'heures ou de minutes) sera affiché. Elle sera insérée avant le nombre suivant et ainsi créera une espace avant minutes ou avant les secondes si celles-ci ont été précédées par l'affichage d'un nombre.

Voici le code commenté :

\showcode|\catcode`\@11
\edef\saved@catcode{\number\catcode`\:}% sauvegarde du catcode de ":"
\catcode`\:12 % ":" est désormais un caractère non actif normal
\def\hdif{%
	\begingroup% ouvrir un groupe semi-simple¤\idx*\begingroup¤
		\catcode`\:12 % modifier le catcode de ":"
		\hdif@i% aller lire les deux arguments
}

\def\hdif@i#1#2{% lit les 2 arguments
		\hdif@ii#1-#2\@nil% et les transmet à la macro à argument délimités
}

\def\hdif@ii#1:#2:#3-#4:#5:#6\@nil{%
		%%%%%% calcul des nombres à afficher %%%%%%
		\edef\nb@hrs{\number\numexpr#1-#4\relax}% différence des heures¤\idx*\number\idx*\numexpr¤
		\edef\nb@min{\number\numexpr#2-#5\relax}% différence des minutes
		\edef\nb@sec{\number\numexpr#3-#6\relax}% différence des secondes
		\ifnum\nb@sec<\z@ % si la différence des secondes est <0¤\tidx*{ifnum}\idx*\z@¤
			\edef\nb@sec{\number\numexpr\nb@sec+60\relax}% ajouter 60 sec
			\edef\nb@min{\number\numexpr\nb@min-1\relax}% enlever 1 aux minutes
		\fi
		\ifnum\nb@min<\z@ % si les minutes sont <0
			\edef\nb@min{\number\numexpr\nb@min+60\relax}% ajouter 60 min
			\edef\nb@hrs{\number\numexpr\nb@hrs-1\relax}% enlever 1 aux heures
		\fi
		%%%%%% affichage du résultat %%%%%%
		\let\inter@space\empty% pas d'espace avant un nombre pour l'instant
		\ifnum\nb@hrs>\z@ % si les heures sont >0
			\nb@hrs h% afficher les heures et "h"
			\let\inter@space\space% espace pour plus tard
		\fi
		\ifnum\nb@min>\z@ % si les minutes sont >0
			\inter@space% afficher une espace éventuelle
			\nb@min min% afficher les minutes et "min"
			\let\inter@space\space¤\idx*\space¤
		\fi
		\ifnum\nb@sec>\z@ % si les secondes sont >0¤\idx*\z@¤
			\inter@space% afficher une espace éventuelle
			\nb@sec s% afficher les secondes et "s"
		\fi
	\endgroup% fermer le groupe ouvert au début¤\idx*\endgroup¤
}
\catcode`\:=\saved@catcode\relax% restaure le code de catégorie de ":"
\catcode`\@12
a) \hdif{10:51:20}{9:20:10}\par
b) \hdif{14:20:0}{13:50:0}\par
c) \hdif{7:50:20}{5:50:20}\par
d) \hdif{7:50:10}{6:50:20}\par
e) \hdif{20:00:00}{19:59:15}\par
f) \hdif{17:13:15}{14:12:45}|
\end{exercice}\idx*[|)]{nombre}§*\hdif[|)]\tidx*[|)]{ifnum}%

\chapter{Une première récursivité}\idx*[|(]{récursivité}
Le moment est venu de se jeter dans le grand bain de la récursivité ! En effet, nous en savons assez pour sortir de la programmation linéaire et passer au stade suivant.

La définition la plus communément admise, même si elle est un peu laconique tient en ces mots : un algorithme est récursif\idx*{récursivité} s'il s'appelle lui-même. Dans le cas d'une macro, cela signifie qu'une macro est récursive si elle s'appelle elle-même, que ce soit directement ou par le truchement d'autres macros intermédiaires. On comprend bien que cela implique qu'une \emph{boucle} se met en place, c'est-à-dire qu'une portion de code sera lue plusieurs fois.

Pour prendre une analogie, nous mettrions en place une \idx{récursivité} si, pour parcourir un trajet rectiligne de A vers B, nous nous fixions comme règle de reculer de 10 mètres à chaque fois que nous passons sur un point précis C du parcours. Le simple bon sens montre que nous n'arriverons jamais à la fin du parcours. En effet, nous serions prisonniers d'une \idx{boucle infinie}, condamnés à parcourir éternellement la même portion de 10 mètres ! Pour éviter cet écueil, il faudrait une règle supplémentaire, appelée «\idx{point d'arrêt}» qui permet de sortir de cette boucle. Par exemple

\begin{itemize}
	\item ne rebrousser chemin si le nombre de fois que l'on a vu le point C est inférieur à 20;
	\item au point C, continuer sans rebrousser chemin si l'on marché plus d'une heure;
	\item ne rebrousser chemin au point C que si l'on a parcouru moins de \numprint[km]{1}.
\end{itemize}

Il en va de même en informatique. Une récursivité \emph{doit} comporter un \idx{point d'arrêt} sans quoi elle devient une \idx{boucle infinie}. Un point \idx{point d'arrêt} est un test sur un paramètre qui évolue avec les itérations de telle sorte qu'à un moment, ce test change d'état et valide la sortie de boucle.
\grandsaut

Ne nous lançons pas dans une macro de grande ampleur et dans un premier temps, restons tout de même modestes. Fixons-nous comme objectif de programmer une commande §\ncar[|(] qui admet 2 arguments, le premier est un nombre positif $n$ et le second un caractère. Le but de cette macro sera d'afficher le caractère $n$ fois.

Cette macro, effectuant un travail très simple, sera un prétexte pour envisager plusieurs méthodes de programmation.

\subsubsection{Une première approche}
Il suffit d'un peu de réflexion pour bâtir un algorithme effectuant l'action voulue. L'approche la plus naturelle fait appel à une variable qui, dans le monde de \TeX{} sera un compteur :

\begin{algo}
	\item assigner 0 au \idx{compteur};
	\item si le compteur est strictement inférieur à $n$
	\begin{algo}
	\item afficher le caractère;
	\item incrémenter le compteur de 1;
	\item retourner en 2;
	\end{algo}
	\item fin de l'algorithme
\end{algo}

Comment s'y prendre pour coder un tel algorithme en \TeX{}? Tout d'abord, nous voyons que le code correspondant au point 2 est parcouru plusieurs fois avec des valeurs différentes du compteur. Cette portion de code sera donc nécessairement \emph{récursive}. Par conséquent, le point 1 sera dévolu à une macro qui initialisera le compteur à 0 et passera la main à une deuxième macro, amenée à s'appeler elle-même. Une macro qui procède à des initialisations et passe la main à la \emph{vraie} macro principale s'appelle une macro «chapeau»\idx*{macro chapeau}. Décidons de nommer la macro chapeau \verb|\ncar| et la macro récursive \verb|\ncar@i|. Voici l'algorithme précédent présenté sous une forme d'un \emph{\idx{pseudocode}}, plus proche de la syntaxe avec laquelle on rédige un programme sans toutefois s'encombrer des subtilités syntaxiques :

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}\label{algo1}
\algorithm[\#]{Afficher $n$ fois un caractère}/
macro ~ncar~#1#2
	ii:=0% initialise le compteur à 0
	val@max:=#1% stocke la valeur maximale
	car@save:=#2% stocke le caractère à afficher
	~ncar@i~% appeler la macro récursive
~fin~\medskip
macro ~ncar@i~
	~si~ ii < val@max% si la valeur maxi n'est pas atteinte
		afficher car@save
		ii:=ii + 1% incrémenter le compteur
		ncar@i% recommencer
	~finsi~
~fin~/
\endgroup

Il est utile de remarquer que la boucle mise en place dans la macro \verb|ncar@i| est de type « tant que». En effet, dans un pseudocode adapté à un langage de plus haut niveau que ne l'est \TeX\footnote{Le format \LaTeX{} fournit une macro \texttt{\string\@whilenum} qui est un « tant que » où le test fait est une comparaison sur des entiers.}, on aurait pu écrire :

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}
\algorithm[\#]{Macro ncar@i}/
macro ~ncar@i~
	~tant que~ ii < val@max% tant que la valeur maxi n'est pas atteinte
		afficher car@save
		ii:=ii + 1% incrémenter le compteur
	~fin tant que~
~fin~/
\endgroup

Il suffit maintenant de traduire en \TeX{} le premier \idx{pseudocode}, plus proche du niveau de \TeX{} que ne l'est le second :

\showcode/\newcount\ii¤\idx*\newcount¤
\catcode`\@=11
\def\ncar#1#2{%
    \ii=0 % initialise le compteur à 0
    \def\val@max{#1}% stocke la valeur maximale
    \def\car@save{#2}% stocke le caractère à afficher
    \ncar@i% appelle la macro récursive
}
\def\ncar@i{%¤\tidx*{ifnum}¤
  \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
    \car@save% afficher le caractère
    \advance\ii 1 % incrémenter le compteur¤\idx*\advance¤
    \ncar@i% recommencer¤\defline\aaa¤
  \fi
}
\catcode`\@=12
\ncar{7}{*}\par
\ncar{13}W\par
\ncar{10}{foobar }/\idx*[|)]{compteur}

Cela fonctionne comme attendu, et même au-delà puisque le code à reproduire est stocké dans une macro et donc, ce code peut être constitué de plusieurs caractères et pourrait aussi bien contenir des séquences de contrôle. Ce code comporte néanmoins un défaut : la récursivité mise en place n'est pas terminale!

\begin{regle}
Une \idx[!terminale]{récursivité} est terminale lorsque rien n'est laissé sur la pile lors de l'appel récursif.

Pratiquement, la récursivité est terminale si l'appel récursif intervient \emph{en dernier} dans le code de la macro qui s'appelle elle-même ou intervient après avoir supprimé par développement tout ce qui se trouve après cet appel.
\end{regle}

Ici ce n'est pas le cas puisque lorsque la macro \verb-\ncar@i- s'appelle elle même à la ligne \no\aaa{}, il reste encore le \tidx{fi} avant la fin du code de la macro. Ce \tidx{fi}, résidu non encore résorbé du test \tidx{ifnum}, va rester sur la pile pour être lu plus tard. Par conséquent, dans les exemples ci-dessus, il y aura 7, 13 ou 10 \tidx{fi} qui vont s'accumuler sur la pile pour qu'après le dernier test (qui sera négatif), ils soient tous lus ce qui provoquera leur disparition par développement. Pour ne pas surcharger inutilement la pile de \TeX{}, il faut supprimer le \tidx{fi} \emph{avant} d'effectuer l'appel récursif. Il suffit ici de placer un \idx\expandafter avant l'appel récursif \verb-\ncar@i- pour 1-développer le \tidx{fi}.

Mais il y a plus grave\ldots{} En plus de la récursivité non terminale\idx*{récursivité!terminale}, le code donné ci-dessus comporte une faute de programmation. Comme nous l'avons vu, lorsque \TeX{} lit le nombre qui suit le signe de comparaison \verb-<-, il développe au maximum\idx*{développement maximal} tout ce qu'il trouve jusqu'à trouver quelque chose qui ne peut entrer dans la composition d'un nombre. Il va donc développer \verb-\val@max- (dont le développement est constitué de chiffres) et va poursuivre en développant \emph{aussi} \verb-\car@save-. Si jamais le développement de \verb-\car@save- est un chiffre ou commence par un ou plusieurs chiffres, ceux-ci vont entrer dans la composition du nombre et, étant absorbés lors de cette lecture, ils ne seront plus disponibles pour l'affichage. Non seulement le test se fera sur une valeur fausse, mais un ou plusieurs caractères prévus pour être affichés seront capturés par le test et rendus indisponibles pour l'affichage.

Nous pouvons en faire l'expérience avec ce code :

\showcode/\newcount\ii¤\idx*\newcount¤
\catcode`\@=11
\def\ncar#1#2{%
    \ii=0 % initialise le compteur à 0
    \def\val@max{#1}% stocke la valeur maximale
    \def\car@save{#2}% stocke le caractère à afficher
    \ncar@i% appelle la macro récursive
}
\def\ncar@i{%
  \ifnum\ii<\val@max% si la valeur maxi n'est pas atteinte
    \car@save% afficher le caractère
    \advance\ii 1 % incrémenter le compteur¤\idx*\advance¤
    \ncar@i% recommencer
  \fi
}
\catcode`\@=12
\ncar{2}{3a}/

Ici, le premier test qui est fait, alors que \verb|\ii| vaut 0, est :

\centrecode-\ifnum\ii<23-

\noindent où le 2 est le développement de \verb|\val@max| et le 3 est le début de celui de \verb|\car@save|. Ce test est vrai et le restera jusqu'à ce que le compteur vaille 23. La macro \verb|\ncar@i| va donc s'appeler 23 fois, et le «\verb|a|», qui stoppe la lecture du nombre, sera donc affiché 23 fois.

Pour éviter que \TeX{} ne développe trop loin, il \emph{faut} mettre un \idx\relax\footnote{On pourrait aussi mettre une macro qui se développe en un espace puisqu'un espace stoppe la lecture du nombre et, contrairement à \idx\relax, est absorbé par cette lecture. On peut donc remplacer \idx\relax par \texttt{\string\space}.} après \verb-\val@max- pour stopper la lecture du nombre. La bonne façon de coder la macro \verb-\ncar@i- est donc :

\centrecode-\def\ncar@i{%
  \ifnum\ii<\val@max\relax
    \car@save
    \advance\ii 1
    \expandafter\ncar@i
  \fi}-
\grandsaut

Voici maintenant deux autres variantes pour coder cette macro :

\begin{enumerate}
	\item on peut utiliser une macro auxiliaire \verb-\donext- qui sera égale, selon l'issue du test, aux instructions à effectuer s'il est positif et à \idx\relax sinon. La macro sera appelée après être sorti des branches du test :

\centrecode-\def\ncar@i{%
	\ifnum\ii<\val@max\relax
		\def\donext{\car@save \advance\ii 1 \ncar@i}%
	\else
		\let\donext\relax
	\fi
	\donext
}-
	\item une autre méthode, plus élégante et plus économe, car elle se passe d'une macro temporaire consisterait, selon l'issue du test, à lire l'argument entre accolades se trouvant juste après le \tidx{fi} ou à manger cet argument. Pour ces deux actions, on utilise les macros déjà définies §\identity et §\gobone (voir page~\pageref{identity}) :

\centrecode-\def\ncar@i{%
	\ifnum\ii<\val@max\relax
		\expandafter\identity% exécute...¤§*\identity¤
	\else
		\expandafter\gobone% ou mange...
	\fi
	{\car@save \advance\ii 1 \ncar@i}%... ce code
}-
\end{enumerate}

\begin{exercice}
Trouver un moyen pour programmer la macro \verb-\ncar{n}{<car>}- sans programmer aucune boucle ni aucune récursivité.

L'exercice est vraiment difficile et tient davantage lieu de curiosité ou d'acrobatie \TeX nique que de vraie méthode.
\solution
Nous allons mettre à contribution la primitive \idx\romannumeral et utiliser une de ses propriétés : si un nombre est supérieur à 1000, alors cette macro produit un nombre en chiffres romains qui commence avec autant de fois le caractère «\verb|m|» (de catcode 12\idx*{catcode!12 (autre)}) qu'il y a de milliers dans le nombre passé en argument :

\showcode/a) \romannumeral 9600 \qquad b) \romannumeral 12000/

Lorsque nous allons appeler la macro \verb-\ncar{#1}{#2}- il va suffire d'ajouter «000» après le nombre \verb-#1- pour obtenir \verb-#1- fois le caractère «\verb|m|» via la primitive \idx\romannumeral. Il ne nous restera plus qu'à « transformer » le caractère «\verb|m|» vers le caractère que nous souhaitons afficher. Nous avons déjà vu comment le faire à l'aide de \idx\lccode et la primitive \idx\lowercase :

\showcode/\def\ncar#1#2{%
	\begingroup¤\idx*\begingroup\idx*\lccode¤
	\lccode`\m=`#2 % dans \lowercase, les "m" deviennent des "#2"
	\lowercase\expandafter{\expandafter\endgroup\romannumeral#1000 }%¤\idx*\lowercase\idx*\endgroup\idx*\romannumeral¤
}
a) \ncar{7}{*}\qquad
b) \ncar{15}{\%}\qquad
c) \ncar{10}{4}/

Comme toutes les primitives devant être suivies d'une accolade ouvrante, \idx\lowercase développe au maximum\idx*{développement maximal} tout ce qui se trouve entre elle et cette accolade. Le développement d'un pont d'\idx[|etc]\expandafter\forbidindex\expandafter{} exploite ici cette propriété pour propager le développement et 1-développer \verb*-\romannumeral#1000 -. Ce développement est \emph{nécessaire} car sans lui, l'argument de \idx\lowercase serait :

\centrecode-\endgroup\romannumeral#1000 -

\noindent et comme cet ensemble de tokens ne contient pas le token «\verb|m|», \idx\lowercase n'aurait aucune action et ce code serait lu tel quel.

Nous répondons bien à l'énoncé de l'exercice, aucune récursivité ou boucle \emph{explicite} n'a été utilisée. Il est évident qu'en coulisses, \TeX{} utilise une boucle lorsqu'il exécute la primitive \idx\romannumeral.
\end{exercice}

\Qu elle que soit la méthode employée pour parvenir à nos fins, aucune d'entre elles n'est \emph{purement développable}. Si nous écrivions

\centrecode-\edef\foo{\ncar{3}{*}}-

\noindent le texte de remplacement de \verb|\foo| ne serait pas «\verb|***|».. La raison tient au fait que les textes de remplacements de \verb|\ncar| ou \verb|\ncar@i| contiennent des séquences de contrôle non développables :

\begin{itemize}
	\item un compteur \verb|\ii|;
	\item la primitive \idx\def;
	\item la primitive \idx\advance.
\end{itemize}

\subsubsection{Une approche purement développable}
Pour construire une macro purement développable, il faut proscrire toutes les primitives non développables contenues dans le code actuel : \idx\advance, \idx\relax, \idx\def et les appels aux compteurs. La question qui se pose naturellement est : « sans compteur, comment compter » ?

Le réponse tient dans la primitive de \idx\eTeX : \idx\numexpr. L'idée est de programmer \verb-\ncar- pour que cette macro s'appelle elle-même en décrémentant son premier argument avec \idx\numexpr; cet argument ira donc \emph{en décroissant} de la valeur maxi à 0, alors que c'était l'inverse pour les versions vues jusqu'alors. Le fait que \verb|\ncar| s'appelle directement elle-même rend inutile toute macro auxiliaire. Voici ce que devient l'algorithme, toujours du type « tant que », qui tend vers une extrême simplicité :

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}
\algorithm[\#,\{,\}]{Décrémenter le 1\ier{} argument}/macro ~ncar~#1#2
		~si~ #1 > 0
			afficher #2
			appeler ~ncar~{#1-1}{#2}
		~fin si~
~fin~/
\endgroup

Du côté de \TeX{}, l'appel récursif prendra la forme suivante :

\centrecode/\exparg\ncar@i{\number\numexpr#1-1}{#2}/

\noindent où §\exparg 1-développe \idx\number qui lance \idx\numexpr qui à son tour, effectue le calcul \verb/#1-1/. Tout cela donnera un argument de «5» si \verb-#1- vaut «6». Regardons le code fonctionner sur un exemple :

\showcode/\def\ncar#1#2{%
  \ifnum#1>0 % <- espace après le "0"
    #2% affiche le caractère
    \exparg\ncar{\number\numexpr#1-1}{#2}% appel récursif¤\idx*\number\idx*\numexpr§*\exparg¤
  \fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}{7}}\meaning\foo/

La première chose importante à noter que le 0 est suivi d'un espace ce qui stoppe la lecture du nombre et qui met à l'écart \verb-#2-, même s'il commence par des chiffres. La seconde remarque est que cette récursivité n'est pas terminale\idx*{récursivité!terminale} puisque le \tidx{fi} n'est pas mangé avant l'appel récursif. Comme cela a été vu précédemment, les macros §\identity et §\gobone règlent ce problème :

\showcode/\def\ncar#1#2{%
	\ifnum#1>0 \expandafter\identity% si #1>0 exécuter...¤§*\identity¤
	\else      \expandafter\gobone% ...sinon manger¤§*\gobone¤
	\fi% ce qui est entre ces accolades :
		{#2% afficher le caractère
		\exparg\ncar{\number\numexpr#1-1}{#2}% appel récursif¤\idx*\number\idx*\numexpr§*\exparg¤
		}%
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo/

\subsubsection{Jouer avec le \texttt{\char`\\fi}}
Une autre ruse de \TeX pert consiste à écrire une macro à argument délimité qui \emph{inverse} l'ordre d'un \verb-<code>- quelconque et du prochain \tidx{fi}, sous réserve que le \verb|<code>| ne contienne pas un \tidx{fi} :

\centrecode-\long\def\antefi#1\fi{\fi#1}-§*\antefi

\noindent La macro §\antefi lit tout le code \verb-#1- jusqu'au prochain \tidx{fi} qui sert de délimiteur. Ce \tidx{fi}, partie intégrante de la macro, n'est pas exécuté et n'est donc pas pas pris en compte par le compteur interne de \tidx{fi}. Ce n'est que lorsque §\antefi se développera que le \tidx{fi}, token rendu en premier, marquera pour \TeX{} la fin de la portée du test.

\showcode/\long\def\antefi#1\fi{\fi#1}¤§*\antefi\idx*\long¤
\def\ncar#1#2{%
	\ifnum#1>0
		\antefi% comme si le \fi était "déplacé" ici¤§*\antefi¤
		#2% affiche le caractère
		\exparg\ncar{\number\numexpr#1-1}{#2}% appel récursif¤\idx*\number\idx*\numexpr¤
	\fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo/

La présence d'un \tidx{else} provoquerait une erreur si le §\antefi se trouvait avant le \tidx{else}. Dans ce cas, le §\antefi se développerait en \tidx{fi} suivi d'un code \verb|#1| contenant un \tidx{else} qui du coup, se retrouverait orphelin, en dehors du territoire du test. En revanche, §\antefi fonctionne bien dans la branche \tidx{else}\linebreak[1]\verb-...-\tidx{fi} d'un test.

\begin{exercice}
Comment peut-on modifier la définition de §\antefi pour que l'astuce fonctionne aussi bien avec la présence d'un \tidx{else} que sans ?
\solution
Nous pouvons définir comme argument \emph{non délimité} le code à mettre après le \tidx{fi}. Appelons §\afterfi cette macro qui aura pour mission de placer après le \tidx{fi} son argument :

\centrecode/\long\def\afterfi#1#2\fi{#2\fi#1}/

\noindent De cette façon, si l'argument délimité \verb-#2- contient un \tidx{else}, ce \tidx{else} est recopié tel quel et se trouve devant le \tidx{fi} et donc n'occasionnera aucune erreur de compilation.

\showcode/\long\def\afterfi#1#2\fi{#2\fi#1}¤§*\afterfi\idx*\long¤
\def\ncar#1#2{%
	\ifnum#1>0
		\afterfi{\exparg\ncar{\number\numexpr#1-1}{#2}}% <- argument renvoyé après le \fi¤\idx*\number\idx*\numexpr§*\afterfi¤
		#2% <- ceci reste avant le \fi
	\fi
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo/
\end{exercice}

\subsubsection{Une solution avec \texttt{\char`\\expandafter}}
Si nous étions était \emph{certains} que l'argument \verb|#2| était composé d'un unique token, nous pourrions nous passer de §\antefi ou §\afterfi et sauter ce token pour aller développer le \tidx{fi} et rendre la récursivité terminale\idx*{récursivité!terminale}. Il suffirait de propager le développement avec des \idx\expandafter :

\centrecode/\def\ncar#1#2{%
  \ifnum#1>0%
    #2%
    \expandafter\ncar\expandafter{\number\numexpr#1-1\expandafter}%
    \expandafter{\expandafter#2\expandafter}%
  \fi
}/

Mais l'appel \verb|\ncar{5}{foobar}| ne serait pas une récursivité terminale\idx*{récursivité!terminale} puisque dans

\centrecode/{\expandafter foobar\expandafter}/

\noindent le pont d'\idx\expandafter est très insuffisant pour sauter tous les tokens de « foobar ». Si nous voulons nous passer de §\antefi, ce qu'il y a de mieux à faire est de mettre l'argument \verb|{#2}| après le \tidx{fi}. Si le test est faux, il faudra manger cet argument avec §\gobone et s'il est vrai, \verb|{#2}| reste en place et devient le 2\ieme{} argument de §\ncar. Pour cela, l'astuce consiste à exploiter le fait que la primitive \idx\numexpr engage un développement maximal. Il suffit donc de placer un \idx\expandafter à la fin de cette zone pour développer (et donc faire disparaitre) la branche \verb|\else...\fi| :

\showcode/\def\ncar#1#2{%
  \ifnum#1>0
    #2% afficher le caractère
    \expandafter\ncar\expandafter% le pont d'\expandafter lance \number et \numexpr
		{\number\numexpr#1-1\expandafter}% le dernier \expandafter mange "\else...\fi"¤\idx*\number\idx*\numexpr¤
  \else
    \expandafter\gobone% si le test est faux, manger {#2} ci-dessous¤§*\gobone¤
  \fi{#2}%
}
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \edef\foo{\ncar{5}X}\meaning\foo/

\subsubsection{Définir une sous-macro}
Examinons une dernière méthode pour construire une récursivité terminale\idx*{récursivité!terminale}. À l'intérieur de la macro \verb-\ncar-, nous allons définir une « sous-macro » nommée \verb-\ncar@i- qui elle, n'admettra qu'un seul argument, le nombre noté \verb|i| qui compte les itérations. Grâce à l'imbrication des macros, les arguments de la macro mère \verb-\ncar- seront accessibles dans le texte de remplacement de \idx{macro fille} \verb-\ncar@i-. Rappelons-nous que le token \verb-#- doit être doublé à chaque niveau d'imbrication de \verb|\def| pour distinguer les arguments de la macro mère de ceux de la macro fille.

Nous compterons dans \emph{l'ordre croissant}, de 0 la valeur maxi.

\showcode/\catcode`\@11
\def\ncar#1#2{%
	\def\ncar@i##1{%
		\ifnum##1<#1 % si i < valeur maxi
		#2% afficher le caractère
		\exparg\ncar@i{\number\numexpr##1+1\expandafter}% puis recommencer avec i+1¤\idx*\number\idx*\numexpr¤
		\fi% \fi mangé par le \expandafter en fin de zone de \numexpr
	}%
	\ncar@i{0}% commence avec la valeur "compteur" 0
}
\catcode`\@12
a) \ncar{7}{*}\qquad
b) \ncar{13}{W}\qquad
c) \ncar{5}{X}/

L'inconvénient de cette méthode est que la macro \verb-\ncar- n'est pas purement développable puisque son texte de remplacement contient la primitive \idx\def§\ncar[|)].

\begin{exercice}\label{compte}§*\compte[|(]%
Écrire une macro \verb-\compte{<nombre>}- qui affiche les entiers de 1 à \verb-<nombre>-, séparés les uns des autres par une virgule et une espace. Si le \verb-<nombre>- est négatif ou nul, aucun affichage ne sera produit.

On écrira un code non purement développable utilisant un compteur et un code purement développable. Dans tous les cas, la récursivité devra être terminale.
\solution
Voici un code qui n'est pas purement développable. Comme au premier exemple vu avec \verb-\ncar-, nous utilisons un compteur et nous stockons la valeur maximale dans la séquence de contrôle \verb-\val@max-. 

\showcode/\catcode`\@11 \newcount\compte@cnt¤\idx*\newcount¤
\def\compte#1{%
	\def\val@max{#1}\compte@cnt=0 % effectue les initialisations
	\compte@i% appelle la macro principale
}
\def\compte@i{%
	\ifnum\compte@cnt<\val@max% si compteur < valeur maxi
		\advance\compte@cnt1 % incrémenter le compteur¤\idx*\advance¤
		\number\compte@cnt, % afficher le nombre, la virgule et l'espace¤\idx*\number¤
		\expandafter\compte@i %recommencer
	\fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \compte{2}/

Le problème saute aux yeux et révèle une erreur de programmation : la virgule et l'espace sont aussi affichés après le dernier nombre, ce qui ne devrait pas être le cas.

La méthode la plus immédiate est de tester à l'intérieur du test principal si, après incrémentation, \verb-\compte@cnt- est inférieur à \verb-\val@max- et si tel est le cas, afficher «\verb*-, -». Voici donc le code corrigé :

\showcode/\catcode`\@11 \newcount\compte@cnt¤\idx*\newcount¤
\def\compte#1{\def\val@max{#1}\compte@cnt=0 \compte@i}
\def\compte@i{%
	\ifnum\compte@cnt<\val@max\relax
		\advance\compte@cnt1 ¤\idx*\advance¤
		\number\compte@cnt
		\ifnum\compte@cnt<\val@max , \fi% afficher ", " si le maxi n'est pas atteint¤\defline\aaa¤
		\expandafter\compte@i
	\fi
}
\catcode`\@12
a) \compte{9}\qquad
b)\compte{-4}\qquad
c) \compte{2}/

Bien qu'il fonctionne parfaitement, ce code n'est pas satisfaisant parce que le test de la ligne \no\aaa{} est fait à chaque itération. Certes, le ralentissement qu'il occasionne à chaque fois est insignifiant, mais il est réel et il se cumule au fur et à mesure des appels. Un programmeur rigoureux optimiserait ce code.

Essayons de supprimer ce test. Nous allons tout d'abord rajouter un test dans la macro \verb-\compte- pour tester si son argument est strictement positif, seul cas où quelque chose sera affiché. Ce test ne sera donc fait qu'une fois. Dans le cas où il est positif, la macro récursive \verb|\coompte@i| sera appelée et elle produira l'affichage en deux étapes :

\begin{itemize}
	\item la valeur du compteur sera affichée;
	\item le test décidant si la macro s'appelle elle-même sera fait et s'il est positif, cela signifie qu'il reste encore des valeurs à afficher. La virgule et l'espace seront donc affichés avant que le compteur ne soit incrémenté et l'appel récursif ne soit exécuté.
\end{itemize}

\showcode/\catcode`\@11 \newcount\compte@cnt¤\idx*\newcount¤
\def\compte#1{%
  \ifnum#1>0 % ne faire quelque chose que si l'argument est positif
    \def\val@max{#1}\compte@cnt=1 % faire les initialisations
    \expandafter\compte@i% appeller la macro récrusive
  \fi
}
\def\compte@i{%
  \number\compte@cnt\relax % afficher le nombre
  \ifnum\compte@cnt<\val@max\relax % si valeur maxi n'est pas atteinte
    , % afficher la virgule et l'espace
    \advance\compte@cnt1 % incrémenter le compteur¤\idx*\advance¤
    \expandafter\compte@i % recommencer
  \fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \compte{2}/

Passons maintenant à une solution purement développable dans laquelle, pour compter les itérations, nous allons utiliser la primitive \idx\numexpr. Nous allons traduire l'algorithme vu ci-dessus de façon à nous passer de compteur. Il suffit de passer à la macro \verb-\compte@i- deux arguments, l'un qui contient la valeur à afficher (et qui compte les itérations à partir de 1) et l'autre la valeur maximale qui est l'argument \verb-#1- de \verb-\compte-. Comme vu dans un exemple précédent, nous rendons cette fois-ci la récursivité terminale\idx*{récursivité!terminale} en mettant le code \emph{entier} contenant l'appel récursif dans un argument après le \tidx{fi} : cet argument sera lu tel quel avec §\identity si le test est positif et sera mangé avec §\gobone dans le cas contraire.

\showcode/\catcode`\@11
\def\compte#1{%
	\ifnum#1>\z@% ne faire quelque chose que si #1 > 0¤\idx*\z@¤
		\antefi\compte@i{1}{#1}%¤§*\antefi¤
	\fi
}

\def\compte@i#1#2{%
	#1% afficher le nombre
	\ifnum#1<#2 % si le maxi n'est pas atteint
		\expandafter\identity% exécuter...¤§*\identity¤
	\else
		\expandafter\gobone% sinon, manger...¤§*\gobone¤
	\fi% le code entre accolades ci-dessous
		{, % afficher la virgule et l'espace
		\exparg\compte@i{\number\numexpr#1+1}{#2}% appel récursif¤\idx*\number\idx*\numexpr§*\exparg¤
		}%
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \edef\foo{\compte{2}}\meaning\foo/

Une variante plus concise aurait été possible en utilisant §\antefi dans la macro auxiliaire :

\showcode/\catcode`\@11
\def\compte#1{%
	\ifnum#1>\z@% ne faire quelque chose que si #1 > 0¤\idx*\z@¤
		\antefi\compte@i{1}{#1}%¤§*\antefi¤
	\fi
}

\def\compte@i#1#2{%
  #1% afficher le nombre
  \ifnum#1<#2 % si le maxi n'est pas atteint
    \antefi% déplace le \fi ici¤§*\antefi¤
    , % affiche la virgule et l'espace
    \exparg\compte@i{\number\numexpr#1+1}{#2}% appel récursif¤\idx*\number\idx*\numexpr§*\exparg¤
  \fi
}
\catcode`\@12
a) \compte{9}\qquad
b) \compte{-4}\qquad
c) \edef\foo{\compte{2}}\meaning\foo/
§*\compte[|)]\end{exercice}

Il faut tirer une leçon de ce chapitre. La programmation de macros récursives purement développables, disqualifiant de fait tout stockage d'information via un compteur, \idx\def ou \idx\toks, oblige à transmettre ces informations sous forme d'arguments. Il devient donc nécessaire de fournir à chaque itération tous les arguments nécessaires au fonctionnement de la macro même si parfois, des arguments invariables (comme la valeur maximale \verb|#2| ci-dessus) doivent être lus à chaque fois.

Rendre une macro récursive purement développable est l'assurance qu'elle va fonctionner comme on l'attend dans tous les cas et à ce titre, tend à devenir le Graal que certains recherchent à tout prix. Il est cependant bon de garder à l'esprit que la facilité et la sécurité que l'on gagne d'un côté cachent une certaine lourdeur dans les mécanismes mis en jeu dans sa programmation. Les contorsions que l'on doit faire notamment au niveau des arguments pour rendre une macro purement développable impliquent généralement une programmation beaucoup plus délicate que si elle ne n'était pas.\idx*[|)]{récursivité}

\chapter{Une boucle « for »}§*\for[|(]
\label{for}Nous savons à présent suffisamment de choses pour programmer une structure de contrôle de type « \verb|for| » où une « variable » --~une macro en réalité~-- va prendre les valeurs entières successives entre deux entiers $n_1$ et $n_2$. Fixons-nous par exemple la syntaxe sera la suivante :

\begin{centrage}
	\small\verb|\for\<macro>=|$n_1$\verb| to |$n_2$\verb|\do{<code>|
\end{centrage}

\noindent où le \verb-<code>- pourra contenir la \verb-\<macro- qui tient lieu de variable et qui prend successivement toutes les valeurs de $n_1$ à $n_2$. Compte tenu de sa syntaxe, il est bien évident que la macro \verb-\for- doit avoir un texte de paramètre contenant des arguments délimités par «=», «\verb|to|» et par «\verb-\do-».

\subsubsection{Une première version}
Voici un premier jet, assez intuitif :

\showcode/\catcode`\@11
\def\for#1=#2to#3\do#4{% #1=\<macro>   #2=n1   #3=n2   #4=<code>
	\def#1{#2}% initialise la \<macro> à l'entier n1¤\defline\aaa¤
	\def\val@max{#3}% stocke n2
	\def\loop@code{#4}% stocke le <code>
	\for@i#1% appelle la macro récursive et passe la \<macro> en argument
}
\def\for@i#1{%
	\unless\ifnum#1>\val@max\relax% tant que la \<macro> est <= n2¤\tidx*{unless}¤
		\loop@code% effectue le code précédemment sauvegardé
		\edef#1{\number\numexpr#1+1}% incrémenter la \<macro>¤\idx*\number\idx*\numexpr¤
		\expandafter\for@i\expandafter#1% et recommencer après avoir mangé le \fi
	\fi
}
\catcode`\@=12
\for\ii=1to5\do{Maintenant \string\ii\ vaut : \ii.\endgraf}\medbreak¤\idx*\medbreak\idx*\string¤
"\for\ii=1to0\do{A}"\medbreak% boucle parcourue 0 fois
"\for\ii=1to1\do{A}"\medbreak% boucle parcourue 1 fois¤\idx*\medbreak¤
\for\ii = 0 to 10 \do {[\ii]}.¤\defline\bbb¤/

Remarquons tout d'abord que la séquence de contrôle \idx\do n'est jamais définie et peu importe qu'elle le soit\footnote{Comme nous l'avons vu, elle est bel et bien définie dans plain-\TeX{} notamment pour seconder la macro \idx\dospecials.} : elle ne sert que de délimiteur à l'argument \verb-#3- de la macro \verb-\for-.

À la ligne \no\aaa, l'argument \verb|#2|, qui est l'entier $n_1$, est assigné à \verb-#1- qui est la \verb|\<macro>|. C'est une mauvaise idée si on laisse des espaces --~toujours utiles pour la lisibilité~-- comme c'est le cas à l'appel de la ligne \no\bbb. Dans ce cas, lors de la première itération, \verb-#1- a comme texte de remplacement «\verb*- 0 -». Pour se prémunir de cet inconvénient, il aurait fallu écrire à la ligne \no\aaa{}

\centrecode-\edef#1{\number\numexpr#2\relax}-

\noindent et ainsi tirer parti du fait que non seulement \idx\numexpr évalue l'éventuelle expression arithmétique \verb|#1|, mais le fait en \emph{ignorant les espaces}. La même méthode doit être utilisée pour stocker l'entier $n_2$ dans \verb|\val@max|.

Plutôt que de définir une macro auxiliaire récursive \verb-\for@i- \emph{à l'extérieur} de la macro principale comme c'est le cas ici, nous avons tout à gagner à la définir à l'intérieur en tant que « \idx{macro fille}». De cette façon, tous les arguments de la macro chapeau sont accessibles. Nous économisons donc la macro \verb-\loop@code-.

Remarquons enfin que la macro \verb-\for- n'était pas déclarée \idx\long, interdisant donc la primitive \idx\par dans ses arguments. Ceci explique pourquoi il faut utiliser \idx\endgraf (une macro \idx\let-égale à \idx\par) pour provoquer la fin du paragraphe.

\showcode/\catcode`\@11
\long\def\for#1=#2to#3\do#4{%¤§*\for\idx*\long¤
	\def\for@i{%
		\unless\ifnum#1>\val@max\relax% tant que la \<macro> <= n2¤\tidx*{unless}¤
			#4% code à exécuter
			\edef#1{\number\numexpr#1+1}% incrémenter \<macro>¤\idx*\number\idx*\numexpr¤
			\expandafter\for@i% et recommencer après avoir mangé le \fi
		\fi
	}%
	\edef#1{\number\numexpr#2\relax}% initialise la variable à n1
	\edef\val@max{\number\numexpr#3\relax}% stocke n2
	\for@i% appelle la sous-macro récursive
}
\catcode`\@=12
\for\ii = 1 to 5 \do {Maintenant \string\ii\ vaut : \ii.\par}\medbreak¤\idx*\medbreak\idx*\string¤
"\for\ii=1to0\do{A}"\medbreak% boucle parcourue 0 fois
"\for\ii=1to1\do{A}"\medbreak% boucle parcourue 1 fois¤\idx*\medbreak¤
\for\ii = 0 to 10 \do {[\ii]}./

\subsubsection{Mise en place d'un incrément}
En l'état actuel, la macro \verb-\for- incrémente sa « variable » de 1 à chaque itération. Comment s'y prendre pour que cet incrément puisse être spécifié par l'utilisateur ce qui constituerait en quelque sorte un argument « optionnel »? Il est naturel de penser à cette syntaxe :

\begin{centrage}
	\small\verb|\for\<macro>=|$n_1$\verb| to |$n_2$ \verb|\do| $i$ \verb|{<code>}|
\end{centrage}

Nous allons modifier la macro \verb-\for- pour que l'incrément $i$, qui est un entier signé, soit pris en compte. Si celui-ci n'est pas spécifié, il sera pris égal à $1$ si $n_1<n_2$ et à $-1$ sinon. L'exercice est difficile, d'autant que nous ne savons pas encore tester si un argument est vide, il faudra donc trouver une autre méthode !

Il faut déjà modifier le texte de paramètre de la macro \verb-\for- pour qu'elle prenne un 4\ieme{} argument après le \verb-\do-, suivi ensuite du 5\ieme{} qui sera le code à exécuter à chaque itération. Ce serait une erreur que de la définir ainsi :

\centrecode-\def\for#1=#2to#3\do#4#5{...}-

\noindent Le problème avec cette définition est que \TeX{} va toujours lire \emph{deux arguments} après le \verb-\do- ! Et si nous omettons l'argument optionnel, \verb-#4- va devenir le \verb-<code>- et \verb-#5- sera l'argument suivant, non destiné à être lu par la macro ! Pour éviter un tel mélange d'arguments, l'argument optionnel recevant $i$ \emph{doit} être délimité par l'accolade ouvrante\idx*{argument!délimité!par accolade} qui marque le début du \verb-<code>-. Nous allons donc écrire :

\centrecode-\def\for#1=#2to#3\do#4#{...}-

\noindent Ce faisant, \verb-#4- sera donc tout ce qui se trouve entre \verb-\do- et la prochaine accolade ouvrante, cet ensemble étant éventuellement vide. Mais en procédant de cette façon, l'argument \verb-{<code>}- ne sera pas encore lu. Il faudra appeler une macro auxiliaire chargée de lire le code devant être exécuté à chaque fois.

L'autre problème qui surgit est que l'argument \verb-#4- peut être vide, ou égal à +4, -2 ou n'importe quel entier signé. Comment s'y prendre pour transformer cet argument en un nombre, même s'il est vide ? L'astuce consiste à mettre un 0 devant cet argument et évaluer le tout avec \idx\numexpr. Nous aurions donc :

\centrecode-\edef\for@increment{\number\numexpr0#4\relax}-

\noindent Par acquit de conscience, assurons-nous que cette astuce fonctionne. Voici les cas qui peuvent se présenter :

\begin{itemize}
	\item si \verb-#4- est vide ou réduit à des espaces, alors le «0» ajouté sera évalué par \idx\numexpr et donc, \verb-\for@increment- vaudra 0 ;
	\item si \verb-#4- vaut «5» alors, «05» sera évalué et nous obtiendrons 5;
	\item si \verb-#4- vaut «+4» alors, «0+4» sera évalué et nous obtiendrons 4 ;
	\item enfin, si \verb-#4- vaut «-10» alors, «0-10» sera évalué et vaudra -10.
\end{itemize}

Une fois ceci fait, si \verb-\for@increment- est nul, cela traduit une absence d'argument optionnel ou pire, un incrément explicitement donné égal à 0 par l'utilisateur joueur ou inconscient! Dans ces cas, il suffit de le redéfinir à 1 si $n1<n_2$ (soit si \verb-#2-${}<{}$\verb-#3-) et à $-1$ sinon.

Passons à l'étape suivante : il faut vérifier que le signe de l'incrément (lorsqu'il est explicitement écrit) est « compatible » avec les valeurs de \verb-#2- et \verb-#3-. En effet, si \verb-#2- vaut 4, \verb-#3- vaut 10 et l'incrément vaut $-2$, on comprend bien qu'additionner l'incrément $-2$ à 4 est une tâche vaine. On n'arrivera jamais à 10 et, après un \emph{très grand} nombre d'itérations, on va dépasser la borne inférieure $-2^{31}+1$ permise pour un nombre, provoquant à ce moment (ou même avant) une erreur de compilation.

Un peu d'analyse montre que l'incrément est « incompatible » avec les bornes \verb-#2- et \verb-#3- si les entiers $\#3-\#2$ et \verb-\for@increment- sont de signes contraires, c'est-à-dire lorsque le signe de l'expression arithmétique suivante est strictement négatif :

\centrecode/\for@increment*(#3-#2)/

Voici le code :

\showcode/\catcode`\@11
\def\for#1=#2to#3\do#4#{%
	\edef\for@increment{\number\numexpr0#4}% lit et normalise l'argument optionnel¤\defline\aaa¤
	\ifnum\for@increment=\z@% s'il est nul,¤\idx*\z@¤
		\edef\for@increment{% le redéfinir :
			\ifnum\numexpr#3\relax<\numexpr#2\relax¤\defline\bbb\idx*\numexpr¤
				-% ajoute un signe - si #3<#2
			\fi
			1% devant "1"
		}% \for@increment vaut donc 1 ou -1
	\fi
	\ifnum\numexpr\for@increment*(#3-#2)\relax<\z@% si l'argument est incompatible¤\defline\ccc\idx*\z@¤
		\expandafter\firstoftwo% exécuter le 1er argument qui suit¤§*\firstoftwo¤
	\else
		\expandafter\secondoftwo% sinon le second¤§*\secondoftwo¤
	\fi
		{Incrément incompatible !\gobone %\gobone mangera le <code> qui à lire¤\defline\ddd¤
		}%
		{\edef#1{\number\numexpr#2\relax}% initialise la \<macro>
		\edef\cmp@sgn{\ifnum\for@increment<\z@<\else>\fi}% stocke "<" ou ">" pour plus tard¤\idx*\z@¤
		\expandafter\for@i\expandafter#1\expandafter% appelle la macro récursive
			{\number\numexpr#3\relax}% et lui lui passe la \<macro> (#1) et n2 (#3)
		}%
}

% #1 = \<macro>   #2 = n2
\long\def\for@i#1#2#3{% l'argument #3 (le <code>) est lu à ce moment-là¤\idx*\long¤
	\def\for@ii{%
		\unless\ifnum#1\cmp@sgn#2\relax% tant que la \<macro> n'a pas dépassé n2¤\defline\fff\tidx*{unless}¤
			#3% exécute le <code>¤\defline\eee¤
			\edef#1{\number\numexpr#1+\for@increment}% incrémente la \<macro>¤\idx*\number\idx*\numexpr¤
			\expandafter\for@ii% recommence après avoir mangé le \fi
		\fi
	}%
	\for@ii% appelle la sous-macro récursive¤\defline\ggg¤
}%
\catcode`\@=12
a) \for\ii = -4 to 7 \do{(\ii)}\par
b) \for\jj = 20 to -50\do-10 {(\jj)}\par
c) \for\xx = 8 to 185\do 20 {[\xx]}\par
d) \for\yy = 0 to 10\do -2{(\yy)}\par
e) "\for\ii = 1 to 0 \do1{XX}"\par
f) "\for\ii = 1 to 1 \do{A}"\par% boucle parcourue 1 fois
g) \for\ii=1to4\do{\for\jj=0to2\do{(\ii,\jj)}\par}% imbrication de boucles/

Il est utile de reprendre ce code en détail, car il comporte beaucoup d'astuces\ldots{} Laissons pour l'instant le cas g où le problème de l'imbrication de boucles sera résolu un peu plus loin.

À la ligne \no\aaa{}, si le nombre \verb|\for@increment|, résultat de l'évaluation de \verb|0#4| est nul, cela signifie que l'argument optionnel \verb|#4| est absent ou égal à \verb|0|. Dans ce cas, la macro \verb|\for@increment| est redéfinie par un \idx\edef et un signe «\verb|-|» est ajouté si \verb|#3| est inférieur à \verb|#2| (ligne \no\bbb) de telle sorte que \verb|\for@increment| contienne \verb|1| ou \verb|-1|.

La ligne \no\ccc{} teste si \verb|\for@increment| est « compatible » avec les valeurs \verb|#2| et \verb|#3|. À l'aide des macros §\firstoftwo et §\secondoftwo, un des 2 arguments qui suit est exécuté :

\begin{itemize}
	\item le premier argument se contente d'afficher « Incrément incompatible » et appelle la macro §\gobone qui mange le \verb-<code>- qui n'a pas encore été lu ce qui termine tout le processus. Bien évidemment, il est possible de ne rien afficher et se contenter de mettre §\gobone dans le deuxième argument;
	\item le deuxième argument définit la séquence de contrôle \verb-\cmp@sgn- pour que son texte de remplacement soit «\verb-<-» si l'incrément est négatif et «\verb->-» sinon. Ce signe sera utilisé dans un test plus tard. Il ne reste plus ensuite qu'à appeler la macro auxiliaire \verb-\for@i- en lui passant la \verb|\<macro>| (argument \verb-#1-) et l'entier $n_2$ (argument \verb-#3-) préalablement évalué par \idx\numexpr.
\end{itemize}

La macro \verb|\for@i| lira \emph{trois} arguments, les deux que lui passe la macro \verb-\for- et le \verb-<code>- qui doit être exécuté à chaque itération puisque celui-ci n'a pas été lu par la macro chapeau \verb-\for-. Comme la macro \verb-\for@i- est appelée à être récursive, il est très peu commode --~et maladroit~-- d'installer une récursivité avec trois arguments à lire à chaque appel. Pour éviter cette lourdeur, la macro \verb-\for@i- ne sert que de macro chapeau pour la vraie macro récursive \verb-\for@ii- qui n'admet aucun argument puisque, étant \emph{dans} la macro \verb-\for@i-, elle peut accéder à ses arguments.

Le code de la macro \verb-\for@ii- est assez simple, le \verb|<code>| est exécuter à la ligne \no\eee{} puis la \verb|\<macro>| est incrémentée de la valeur signée \verb-\for@increment-. La ligne \no\fff{} nécessite un petit commentaire : le test \tidx{ifnum} s'attend à lire un nombre et développe tout au maximum jusqu'à trouver un token qui ne puisse pas constituer un entier : la macro \verb|#1| va être développée et la lecture du nombre ne va pas s'arrêter. Le développement va continuer et la macro \verb-\cmp@sgn- va être développée à son tour. Comme son texte de remplacement est «\verb|<|» ou «\verb|>|», la lecture du nombre va être stoppée, mais le but recherché, c'est-à-dire le développement de \verb|\cmp@sgn| est effectué. Enfin, le test est construit avec \tidx{unless} ce qui signifie que ce qui se trouve jusqu'au \tidx{fi} est exécuté si le test \emph{contraire} est vérifié. Ce test contraire correspond à une inégalité \emph{large} ($\leqslant$ ou $\geqslant$) ce qui implique qu'une itération sera faite lorsque la \verb|\<macro>| est égale à $n_2$.

\subsubsection{Imbrication de boucles : analyse du problème}
Comme le cas g l'a mis en évidence dans le code précédent, lorsque deux boucles \verb-\for- sont imbriquées le fonctionnement attendu n'est pas obtenu et il semble qu'une seule itération de la boucle la plus extérieure est faite entièrement :

\centrecode-\for\ii=1to4\do{\for\jj=0to2\do{(\ii,\jj)}\par}-

\noindent se traduit par «(1,0)(1,1)(1,2)».

Il faut inventer un remède qui permet d'imbriquer autant de boucles \verb-\for- que l'on veut. Mais tout d'abord, il faut analyser le problème. Par chance, c'est assez simple ici. Dans un premier temps, \verb-\for@i- est appelée par \verb-\for- ce qui a pour effet de définir la macro \verb-\for@ii- avec le texte de remplacement (auquel nous donnons le numéro~1) suivant :

\centrecode-\unless\ifnum\ii\cmp@sgn4\relax
  \for\jj=0to2\do{(\ii,\jj)}\par
  \edef\ii{\number\numexpr\ii+\for@increment}%
  \expandafter\for@ii
\fi-

Lorsque la macro \verb|\for@ii| est exécutée à la ligne \no\ggg, elle est développée et donc, tout ce code est placé sur la pile pour y être exécuté. Lorsque la 2\ieme{} ligne de la pile est exécutée, une nouvelle boucle §\for démarre:

\centrecode-\for\jj=0to2\do{(\ii,\jj)}-

Comme \verb|\ii| vaut 1, cette boucle va afficher «(1,0)(1,1)(1,2)» mais en coulisse, l'irréparable s'est déjà produit ! Ce nouvel appel à §\for a redéfini la macro \verb|\for@ii| avec ce texte de remplacement (appelé \no2) :

\centrecode-\unless\ifnum\jj\cmp@sgn2\relax
  (\ii,\jj)%
  \edef\jj{\number\numexpr\jj+\for@increment}%
  \expandafter\for@ii
\fi-

\Qu e va-t-il se passer quand la boucle interne (dont la variable est \verb|\jj|) sera terminée et que «(1,0)(1,1)(1,2)» sera affiché? La macro \verb|\jj| vaudra 3 et \TeX{} va continuer à lire le code sur sa pile qui est le texte de remplacement \no1 amputé de ses deux premières lignes :

\centrecode-\edef\ii{\number\numexpr\ii+\for@increment}%
  \expandafter\for@ii
\fi-

\noindent Par conséquent, \verb|\ii| va être incrémenté (et vaudra 2). La macro \verb|\for@ii| (dont le texte de remplacement est le \no2) va être appelée et le test

\centrecode-\unless\ifnum\jj\cmp@sgn2\relax-

\noindent sera faux car \verb|\jj| (qui vaut 3) a dépassé $n_2$ qui est 2. Par conséquent, aucun code ni aucune récursivité ne seront exécutés. Ce test faux signe donc la fin de la boucle extérieure.

\subsubsection{Imbrication de boucles : résolution du problème}
Tous les problèmes viennent donc de la redéfinition de \verb-\for@ii- par la boucle intérieure et du fait que cette redéfinition survive à la fin de la boucle intérieure. Certes, exécuter chaque boucle dans un groupe règlerait le problème, mais cette solution de facilité empêcherait toute globalité au code qui est exécuté à chaque itération et donc diminuerait les fonctionnalités de la boucle.

Le remède serait donc de définir une macro \verb-\for@ii- spécifique à chaque « variable ». Pour cela, la macro chapeau \verb|\for| va appeler une macro \verb|\for@i| chargée de définir la macro récursive \verb|\|\boxtoken{for@ii@\string\<macro>} où \verb|\<macro>| est le développement de \verb|\string#1|. Par exemple, si l'on exécute

\centrecode-\for\xx=1to5\do{X}-

\noindent la macro \verb|\for| va appeler \verb|\for@i| qui va se charger de définir et lancer la macro récursive \verb-\-\boxtoken{for@ii@\string\xx}. Plus aucun risque de redéfinition n'existe, sauf si l'utilisateur fait preuve d'inconscience et utilise le même nom de variable pour deux boucles imbriquées.

Du côté de la méthode à utiliser, nous allons faire en sorte que \verb|\for| passe à la macro \verb|\for@i| les arguments suivants :

\begin{enumerate}[label={{\ttfamily\char`\#\arabic*} :}]
	\item la macro récursive \verb-\-\boxtoken{for@ii@\string\<macro>};
	\item le signe de comparaison explicitement écrit "\verb|<|" ou "\verb|>|";
	\item l'incrément sous forme d'un entier explicitement écrit;
	\item la \verb|\<macro>| qui est l'argument \verb|#1| de \verb|\for|;
	\item l'entier $n_2$ qui est l'argument \verb|#3| de \verb|\for|.
\end{enumerate}

Par exemple, si nous écrivons

\centrecode-\for\xx=1to20\do4{X}-

\noindent la macro \verb|\for@i| doit être appelée ainsi :

\begin{centrage}
	\small\verb-\for@i\-\boxtoken{for@ii@\string\xx}\verb-<{4}\xx{20}-
\end{centrage}

Le fait que les arguments \verb|#2|, \verb|#3| et \verb|#5| soient transmis explicitement sous forme de tokens de catcode 12 évite de créer une macro pour les stocker et nous met donc à l'abri de toute redéfinition de cette macro par une boucle imbriquée.

Prenons le parti de stocker ces 5 arguments dans une macro \verb|\macro@args| définie avec \verb|\edef|. Rappelons-nous que dans le texte de remplacement d'un \verb|\edef|, un \idx\noexpand est nécessaire pour bloquer le développement d'une séquence de contrôle : les arguments \verb|#1| et \verb|#4| sont ici concernés. Une fois la macro \verb|\macro@args| définie, l'appel à \verb|\for@i| se fera donc par

\centrecode|\expandafter\for@i\macro@args|

\showcode/\catcode`\@11
\def\for#1=#2to#3\do#4#{%
	\edef\for@increment{\number\numexpr0#4}% lit et normalise l'argument optionnel
	\ifnum\for@increment=\z@% s'il est nul,¤\idx*\z@¤
		\edef\for@increment{% le redéfinir à -1 (si #3<#2) et 1 sinon
			\ifnum\numexpr#3-#2\relax<\z@ -1\else 1\fi¤\idx*\numexpr\idx*\z@¤
		}% \for@increment vaut donc 1 ou -1
	\fi
	\ifnum\numexpr\for@increment*(#3-#2)\relax<\z@
		\expandafter\gobone% si argument optionnel incompatible, manger le {<code>}¤§*\gobone[|etc]\forbidindex\gobone¤
	\else
		\edef#1{\number\numexpr#2}% initialise la \<macro>
		\edef\macro@args{% définit et développe les arguments à passer à \for@i
			%#1=nom de la macro récursive :
			\expandafter\noexpand\csname for@ii@\string#1\endcsname¤\idx*\csname\idx*\endcsname\idx*\string¤
			\ifnum\for@increment<\z@ <\else >\fi% #2=signe de comparaison¤\idx*\z@¤
			{\for@increment}% #3=incrément
			\noexpand#1% #4=\<macro>¤\idx*\noexpand¤
			{\number\numexpr#3\relax}% #5=entier n2¤\idx*\number\idx*\numexpr¤
		}%
		\antefi% externalise la ligne ci-dessous de la portée du test¤§*\antefi¤
		\expandafter\for@i\macro@args% appelle \for@i avec les arguments définis ci-dessus
	\fi
}

% #1=nom de la macro récursive de type "\for@ii@\<macro>"
% #2=signe de comparaison  % #3=incrément
% #4=\<macro>  % #5=entier n2  % #6=<code> à exécuter
\long\def\for@i#1#2#3#4#5#6{%¤\idx*\long¤
	\def#1{% définit la sous macro récursive
		\unless\ifnum#4#2#5\relax% tant que la \<macro> variable n'a pas dépassé n2¤\tidx*{unless}¤
			\afterfi{% rendre la récursivité terminale¤§*\afterfi\idx*{récursivité!terminale}¤
				#6% exécute le code¤\defline\bbb¤
				\edef#4{\number\numexpr#4+#3\relax}% incrémente la \<macro>
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro récursive¤\defline\ccc¤
}%
\catcode`\@=12
\for\ii=1to4\do{\for\jj=0to2\do{(\ii,\jj)}\par}\medbreak¤\idx*\medbreak¤

\for\carA= `\A to `\E \do{\for\carB= `w to `z \do{\char\carA\char\carB}\quad}¤\idx*[|etc]\quad\forbidindex\quad¤/

\begin{exercice}
En l'état, la boucle est parcourue autant de fois que l'imposent les bornes et l'incrément. Or, dans certains cas, une condition programmée par l'utilisateur devient vraie au cours des itérations et à partir de ce moment, exécuter les itérations suivantes devient indésirable. Comment programmer une macro §\exitfor qui, insérée dans le \verb|<code>| à exécuter, permette de sortir prématurément de la boucle ?
\solution
La macro §\exitfor est susceptible de se trouver dans le \verb|<code>| à la ligne \no\bbb. Cette macro doit donc annuler l'appel récursif de la ligne \no\ccc. Il y a plusieurs moyens de le faire, le plus simple est de charger §\exitfor de redéfinir la macro récursive \verb|#1| comme ayant un texte de remplacement vide :

\showcode/\catcode`\@11
\long\def\for@i#1#2#3#4#5#6{%¤\idx*\long¤
	\def\exitfor{\def#1{}}%¤§*\exitfor¤
	\def#1{% définit la sous macro récursive
		\unless\ifnum#4#2#5\relax% tant que la variable n'a pas dépassé l'entier max¤\tidx*{unless}¤
			\afterfi{% rendre la récursivité terminale¤§*\afterfi\idx*{récursivité!terminale}¤
				#6% exécute le code¤\defline\bbb¤
				\edef#4{\number\numexpr#4+#3\relax}% incrémente la variable #1¤\idx*\number\idx*\numexpr¤
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro récursive
}%
\catcode`\@=12
\for\ii= 1 to 9 \do{\string\ii{} vaut \ii.\ifnum\ii=5 \exitfor\fi\par}¤\idx*\string§*\exitfor¤/

Cela fonctionne correctement car il n'y a aucune boucle \verb|for| imbriquée.

Dans le cas de boucles imbriquées, la macro §\exitfor va être définie plusieurs fois (une fois par imbrication). Par conséquent, la dernière définition, celle de la boucle la plus intérieure, écrase les autres. On peut donc sortir de la boucle la plus intérieure, mais plus des boucles de niveau supérieur.

Le remède le plus simple est de donner comme argument à §\exitfor la \verb|\<macro>| correspondant à la boucle de laquelle on souhaite sortir. Ainsi, §\exitfor\verb|#1| redéfinirait la macro \verb-\-\boxtoken{for@ii@\string#1} comme ayant un texte de remplacement vide. Pour être complets sur le sujet, nous créerons aussi la macro §\ifexitfor de syntaxe

\centrecode-\ifexitfor\<macro>{<code vrai>}{<code faux>}-

\noindent Ainsi, §\ifexitfor\verb|\<macro>| permet de savoir, en dehors de la boucle de variable \verb|\<macro>|, si on en est prématurément sorti ou pas. Définir §\ifexitfor fait appel au test \verb|\ifx| et à la macro \idx\empty et devient donc, en anticipant un peu, une bonne transition vers le chapitre suivant qui aborde d'autres tests que propose \TeX.

Le code ci-dessous permet de voir plusieurs façons, plus ou moins rapides, de sortir de 2 boucles imbriquées :

\showcode/\def\exitfor#1{% #1=\<macro> correspondant à la boucle de laquelle on veut sortir¤§*\exitfor¤
	\defname{for@ii@\string#1}{}¤\idx*\csname\idx*\endcsname\idx*\string§*\defname¤
}

\def\ifexitfor#1{% envoie vrai si on est prématurément sorti de la boucle de \<macro> #1¤§*\ifexitfor¤
	% si la macro récursive est égale à la macro "\empty"
	\expandafter\ifx\csname for@ii@\string#1\endcsname\empty¤\idx*\string\idx*\empty¤
		\expandafter\firstoftwo% c'est qu'on est sortir prématurément, renvoyer "vrai"¤§*\firstoftwo¤
	\else
		\expandafter\secondoftwo% sinon, renvoyer "faux"¤§*\secondoftwo¤
	\fi
}

% on ne sort QUE de la boucle intérieure quand \ii=3 donc
% les boucles sont normalement exécutées pour \ii=4 et \ii=5
a. \for\ii=1 to 5\do1{%
     \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\jj\fi}%¤§*\exitfor¤
     \qquad
   }

% on sort de la boucle extérieure lorsque \ii=3 donc la boucle
% intérieure est faite entièrement même lorsque \ii=3
b. \for\ii=1 to 5\do1{%
     \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\ii\fi}%¤§*\exitfor¤
     \qquad
   }

% on sort de la boucle intérieure lorsque \ii=3
% et aussi de la boucle extérieure à l'aide de \ifexitfor
c. \for\ii=1 to 5\do1{%
     \for\jj=1 to 3\do1{(\ii,\jj) \ifnum\ii=3 \exitfor\jj\fi}%¤§*\exitfor¤
     \ifexitfor\jj{\exitfor\ii}{}% si on est sorti de \jj, sortir aussi de \ii¤§*\exitfor§*\ifexitfor¤
     \qquad
   }/
\end{exercice}§*\for[|)]{}

\chapter[\Qu elques autres tests]{Quelques autres tests}
Après avoir touché du doigt la syntaxe générale des tests et leurs particularités concernant la façon dont ils se développent, après avoir examiné plus particulièrement le test \tidx{ifnum}, nous allons dans ce chapitre découvrir quelques autres tests de \TeX{}. Le but n'est pas de les passer tous en revue, mais d'examiner ceux qui sont le plus utiles et les utiliser pour en créer d'autres.

\section{Le test \texttt{\textbackslash{}ifx}}\tidx*[|(]{ifx}
\subsection{\Qu e teste \texttt{\char`\\ifx} ?}
Un des tests les plus utilisés est sans doute le test \tidx{ifx}.

\begin{regle}
Le test \tidx{ifx} compare les significations des deux \emph{tokens} qui le suivent. Il a la syntaxe suivante :

\centrecode-\ifx<token1><token2>
	<code vrai>
\else
	<code faux>
\fi-

Il est vrai si la signification des deux tokens est la même. Parmi toutes les possibilités qui se présentent selon la nature des deux tokens, les trois cas suivants sont les plus courants :

\begin{enumerate}
	\item si les deux tokens sont des caractères, alors le test est positif si les caractères sont identiques, c'est-à-dire si leur \idx{code de caractère} \emph{et} leur catcode sont égaux;
	\item si les deux tokens sont des \idx{primitive}s, le test est positif si les primitives sont les mêmes;
	\item si les deux tokens sont des macros ou des caractères actifs\idx*{caractère actif}, le test \verb-\ifx- compare leurs textes de remplacement : le test est positif si les textes de remplacement sont identiques, c'est-à-dire constitués des mêmes tokens avec les mêmes catcodes. La comparaison tient également compte des propriétés de ces macros, notamment si elles sont \idx\long ou \idx\outer.
	
	Deux macros non définies sont égales pour \verb-\ifx-, quels que soient leurs noms.
\end{enumerate}
\end{regle}

Contrairement à \tidx{ifnum}, le test \tidx{ifx} ne déclenche pas un développement maximal et donc, les deux tokens sont comparés tels quels.

Si deux tokens appartiennent à deux catégories différentes parmi les trois listées dans la règle ci-dessus, le test sera faux. Par exemple, si une macro \verb-\foo- a le texte de remplacement «\verb|a|», alors le test \verb-\ifx a\foo- est faux :

\showcode/\def\foo{a}\ifx a\foo vrai\else faux\fi/

En effet, le premier token «\verb|a|» est un caractère, une sorte de primitive pour \TeX{} alors que le second \verb-\foo- est une macro. Notons que la primitive \idx\meaning donne une bonne idée de ce qu'est la \emph{signification} d'un token, même si elle ne dit rien sur les catcodes des tokens composant le texte de remplacement d'une macro (voir les cas \nos6 et 7 ci-dessous) :

\showcode/1) \meaning9\par% un caractère de catcode 12¤\idx*\meaning\idx*{catcode!12\space(autre)}¤
2) \meaning a\par% une lettre
3) \def\foo{a}\meaning\foo\par% une macro
4) \long\def\foo{a}\meaning\foo\par% une macro déclarée \long¤\idx*\long¤
5) \meaning\sdlkfj\par% une macro indéfinie
6) \edef\foo{\string a}\meaning\foo\par%\foo contient un "a" de catcode 12¤\idx*\string¤
7) \def\foo{a}\meaning\foo\par%\foo contient un "a" de catcode 11/

Pour fixer les idées, effectuons quelques autres tests qui montrent comment réagit \verb|\ifx| :

\showcode/a) \ifx abvrai\else faux\fi\quad% a est n'est pas égal à b
b) \ifx++vrai\else faux\fi\quad% le caractère "+" est égal à "+"
c) \ifx\relax\par vrai\else faux\fi\quad% \relax n'est pas la même primitive que \par
d) \ifx\par\par vrai\else faux\fi\quad% \par et \par sont les mêmes primitives
e) \ifx\sdfk\qlms vrai\else faux\fi\quad% 2 macros non définies sont égales
f) \def\foo{abcd}\def\bar{abc}% \foo et \bar ont des textes de remplacement différents
   \ifx\foo\bar vrai\else faux\fi\quad
g) \def\foo{abcd}\def\bar{abcd }% \foo et \bar ont des textes de remplacement différents
   \ifx\foo\bar vrai\else faux\fi\quad
h) \def\foo{abcd}\def\bar{abcd}
   \ifx\foo\bar vrai\else faux\fi\quad% \foo et \bar ont les mêmes textes de remplacement
i) \long\def\foo{a}\def\bar{a}¤\idx*[|etc]\long\forbidindex\long¤
   \ifx\foo\bar vrai\else faux\fi\quad% \foo est \long, \bar ne l'est pas
j) \edef\foo{\string a}% \foo contient un "a" de catcode 12¤\idx*{catcode!11\space(lettre)}\idx*{catcode!12\space(autre)}\idx*\string¤
   \def\bar{a}% \bar contient un "a" de catcode 11
   \ifx\foo\bar vrai\else faux\fi/

\begin{exercice}
Il a été dit que le test \verb-\ifx- était sensible aux codes de catégorie. Écrire une macro§*\cmpmacro

\centrecode-\cmpmacro<\macroA><\macroB>{<code vrai>}{<code faux>}-

\noindent qui comparera les macros contenues dans ses deux premiers arguments sans tenir compte des codes de catégorie des tokens qui composent leurs textes de remplacement.
\solution
L'idée et de détokéniser le texte de remplacement des deux macros, d'assigner ces deux textes détokénisés à des macros auxiliaires et enfin, de comparer ces deux macros avec \verb-\ifx-. Pour ne pas laisser ces deux macros auxiliaires derrière nous, créons-les dans un groupe semi-simple que nous refermerons après la comparaison. Remarquons à cette occasion que la paire \idx\begingroup et \idx\endgroup peut être « imbriquée » avec les \verb-\ifx-, \tidx{else} et \tidx{fi} d'un test.

\showcode/\def\cmpmacro#1#2{%¤§*\cmpmacro¤
	\begingroup¤\idx*\begingroup¤
	\edef\tempa{\detokenize\expandafter{#1}}\edef\tempb{\detokenize\expandafter{#2}}%¤\idx*\detokenize¤
	\ifx\tempa\tempb% si égalité
		\endgroup\expandafter\firstoftwo% ferme le groupe et lit 1er argument¤\idx*\endgroup§*\firstoftwo¤
	\else
		\endgroup\expandafter\secondoftwo% sinon, ferme le groupe et lit le 2e argument¤§*\secondoftwo¤
	\fi
}
a) \edef\foo{\string a}\def\bar{a}¤\idx*\string¤
   \cmpmacro\foo\bar{vrai}{faux}\qquad
b) \edef\foo{\detokenize{$i^2=-1$\relax}}\def\bar{$i^2=-1$\relax}
   \cmpmacro\foo\bar{vrai}{faux}¤§*\cmpmacro¤/
\end{exercice}

\subsection{Le test \texttt{\char`\\ifx}, la \texttt{\char`\\let}-égalité et les quarks}
Voici une règle particulière qu'il est utile de connaitre :

\begin{regle}
Le test \tidx{ifx} ne distingue pas deux tokens \idx\let-égaux.
\end{regle}

Autrement dit, si un token de type \verb|\<macro>| est rendu égal au token $x$ avec \idx\let, alors, \verb-\ifx- verra \verb|\<macro>| et $x$ égaux.

Nous pouvons l'observer ci-dessous où des tokens, à chaque fois \idx\let-égaux, rendent tous les tests vrais :

\showcode/a) \let\rien\relax      \ifx\rien\relax vrai\else faux\fi\qquad
b) \let\AA=a            \ifx a\AA vrai\else faux\fi\qquad
c) \let\foo=_\let\bar=_ \ifx\foo\bar vrai\else faux\fi/

Pour exploiter la règle précédente, il est parfois commode de créer des macros spéciales dont le développement est elles-mêmes, autrement dit \emph{invariantes} par développement ! Elles portent le nom de «\idx[|(]{quark}s». Voici comment nous pourrions définir un quark nommé §\quark :

\centrecode-\def\quark{\quark}-

\noindent Bien évidemment, il ne faut jamais qu'un quark ne soit exécuté puisqu'en se développant, il ne change pas : cette propriété mènerait à une \idx{boucle infinie} dont on ne peut sortir que par interruption manuelle. À vrai dire, les quarks ne sont utiles que pour les comparaisons via \tidx{ifx}. Essayons de comprendre pourquoi en prenant par exemple une macro \verb-\test- définie comme suit :

\centrecode-\def\test{\quark}-

\noindent Dans ce cas, le test «\verb|\ifx\test\quark|» est vrai parce que §\quark est un quark. Il serait faux s'il ne l'était pas. En effet, \tidx{ifx} compare le texte de replacement de \verb|\test| et celui de §\quark : ce texte de remplacement est bien §\quark dans les deux cas.

Le test est également positif si \verb|\test| est défini par

\centrecode-\let\test=\quark-

\noindent puisque dans ce cas, deux macros \idx\let-égales sont comparées.

\showcode/\def\quark{\quark}% définit un quark¤§*\quark¤
1) \def\test{\quark} \ifx\quark\test vrai\else faux\fi
\qquad
2) \let\test=\quark  \ifx\quark\test vrai\else faux\fi¤§*\quark¤/

Le fait que \tidx{ifx} donne un test vrai aussi bien pour une macro définie par \idx\def ou par \idx\let se révèle bien pratique et constitue une particularité des quarks.

\begin{regle}[Définition et propriétés]
Un quark est une macro dont le texte de remplacement est constitué de la macro elle-même.

Un quark ne doit \emph{jamais} être exécuté, car étant invariant par développement, son traitement par \TeX{} engendrerait une \idx{boucle infinie}.\medbreak

Si \verb|\<quark>| est un quark et si \verb|\<macro>| est définie par

\begin{centrage}
\small\verb|\def\<macro>{\<quark>}|\quad {\normalsize ou par}\quad\verb|\let\<macro> = \<quark>|
\end{centrage}

\noindent alors, le test \verb|\ifx\<macro>\<quark>| sera vrai dans les deux cas.
\end{regle}\idx*[|)]{quark}

\section{Applications du test \texttt{\textbackslash ifx}}
\subsection{Tester si un argument est vide}\idx*[|(]{argument!vide}
Il arrive souvent qu'il faille tester si un argument est vide (c'est-à-dire constitué de 0 token). La méthode naïve, mais aussi la plus efficace est la suivante : on assigne avec \verb|\def| cet argument à une \verb|\<macro>| temporaire. Ensuite, on compare avec \verb-\ifx- cette \verb|\<macro>| et la macro nommée \idx\empty, définie dans plain-\TeX{}\footnote{La macro équivalente \texttt{\string\@empty} est définie dans le format \LaTeX.}, dont le texte de remplacement est vide:§*\ifempty[|(]

\centrecode-\def\empty{}-

Cela donne le code suivant :

\showcode/\def\ifempty#1{%¤§*\ifempty¤
	\def\tempa{#1}% stocke l'argument #1 dans \tempa¤\defline\aaa¤
	\ifx\tempa\empty% si \tempa = \empty
		\expandafter\firstoftwo% 1er argument¤§*\firstoftwo¤
	\else
		\expandafter\secondoftwo% sinon, second¤§*\secondoftwo¤
	\fi
}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\empty}{vide}{pas vide}¤\defline\bbb¤/

\begin{exercice}\label{argument.vide}
Expliquer pourquoi le test est négatif à la ligne \no\bbb{} du code ci-dessous
\solution
La ligne \no\aaa{} effectue l'action suivante :

\centrecode-\def\tempa{\empty}-

Le test \verb|\ifx\tempa\empty| compare donc les deux textes de remplacement de ces macros qui sont \idx\empty pour la première et un texte vide pour la seconde. Ces deux textes de remplacement ne sont pas égaux ce qui explique que le test est négatif.
\end{exercice}

La macro §\ifempty fonctionne parfaitement, mais elle n'est \emph{pas} purement développable à cause de la présence du \idx\def dans son texte de remplacement. Pour rendre la macro développable, l'astuce consiste à utiliser le fait que lorsqu'un argument \verb|#1| d'une macro est vide, tout se passe comme s'il n'existait pas dans son texte de remplacement.  Dans ce cas, les tokens qui sont juste avant et juste après \verb|#1| deviennent consécutifs. Il suffit que ces deux tokens soient les mêmes (par exemple «\verb|_|») pour que le test «\verb|\ifx_#1_|» devienne positif lorsque \verb|#1| est vide :

\showcode/\def\empty{}
\long\def\ifempty#1{%¤§*\firstoftwo§*\secondoftwo§*\ifempty¤
  \ifx_#1_\expandafter\firstoftwo
  \else\expandafter\secondoftwo
  \fi}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\empty}{vide}{pas vide}\qquad
e) \edef\foo{\ifempty{abc}{vide}{pas vide}}\meaning\foo/

Bien évidemment, au lieu de «\verb-_-», nous aurions aussi pu utiliser «\verb-|-», \idx\empty ou tout autre token. La macro fonctionne bien, mais il va se trouver des cas particuliers où elle va donner des faux positifs ! En effet, le test \verb-\ifx<token>#1<token>- est vrai si \verb|#1| est vide, mais il sera \emph{aussi} vrai si \verb-#1- commence par le \verb|<token>|. Nous pouvons l'observer ici où «\verb|W|» est pris comme token de comparaison qui, contrairement à «\verb|_|» peut être \emph{affiché} par \TeX{}. Le cas \no4 met en évidence le problème :

\showcode/\long\def\ifempty#1{%¤§*\firstoftwo§*\secondoftwo§*\ifempty¤
  \ifx W#1W\expandafter\firstoftwo
  \else    \expandafter\secondoftwo
  \fi}
1) \ifempty{foobar}{vide}{pas vide}\qquad
2) \ifempty{}{vide}{pas vide}\qquad
2) \ifempty{\empty}{vide}{pas vide}\qquad
4) \ifempty{Wagons}{vide}{pas vide}/

On peut observer que le test \verb|\ifx| a comparé le «\verb|W|» qui le suit et le «\verb|W|» de « \verb|Wagons|». Comme il est vrai, tout ce qui est jusqu'au \verb|\else| a été affiché.

Pour se prémunir de cet inconvénient, la méthode la plus communément utilisée consiste à \emph{détokéniser} l'argument \verb|#1| et l'entourer de deux tokens qui ne sont pas de catcode 12 (\idx\relax est habituellement utilisé dans ce cas). Pour que cela fonctionne, «\verb|\detokenize{#1}|» doit être développé avant que le test n'entre en jeu et nécessite donc un pont d'\idx\expandafter :

\centrecode-\expandafter\ifx\expandafter\relax\detokenize{#1}\relax-

Avec cette méthode, le test n'est positif \emph{que} lorsque \verb|#1| est vide. En effet,

\begin{enumerate}
	\item si \verb|#1| commence par un espace, \verb|\detokenize{#1}| se développe en un espace (de catcode 10) suivi d'autres tokens. Le test se fera donc entre \idx\relax et \verb*| | et sera faux;
	\item si \verb|#1| commence par un autre token, le développement de \idx\detokenize\verb|{#1}| commence par un caractère de catcode 12. La comparaison entre \idx\relax et ce token est fausse ;
	\item enfin, si \verb|#1| est vide, \verb|\detokenize{}| se développe en 0 token et donc, les primitives \idx\relax deviennent consécutives et sont vues égales par le test \tidx{ifx} qui est alors positif.
\end{enumerate}

\showcode/\long\def\ifempty#1{%¤§*\firstoftwo§*\secondoftwo§*\ifempty¤
	\expandafter\ifx\expandafter\relax\detokenize{#1}\relax¤\idx*\detokenize¤
		\expandafter\firstoftwo
	\else
		\expandafter\secondoftwo
	\fi
}
a) \ifempty{abc}{vide}{pas vide}\qquad
b) \ifempty{}{vide}{pas vide}\qquad
c) \ifempty{ }{vide}{pas vide}\qquad
d) \ifempty{\relax}{vide}{pas vide}\qquad
e) \edef\foo{\ifempty{abc}{vide}{pas vide}}\meaning\foo/§*\ifempty[|)]%

Utiliser \idx\detokenize est la seule méthode développable qui soit vraiment infaillible, mais elle a le désavantage d'être un peu lourde à écrire, c'est pourquoi on lui préfère souvent

\centrecode-\ifx\empty#1\empty-

\noindent tout en restant conscient des faux positifs qu'elle peut engendrer dans les cas --~le plus souvent improbables~-- où \verb-#1- commence par la macro \idx\empty ou toute autre macro \idx\let-égale à \idx\empty.
\grandsaut

\begin {exercice}
\label{reverse}Programmer une macro §\reverse, admettant comme argument un \verb|<mot>| et dont le développement maximal est le \verb|<mot>| écrit dans l'ordre inverse.

Par exemple, §\reverse\verb|{foobar}| donne «\verb|raboof|».
\solution
Pour y parvenir, il faut imaginer deux réservoirs, A et B recevant des caractères. L'algorithme est le suivant :
\begin{algo}
	\item mettre le \verb|<mot>| dans le réservoir A et initialiser le réservoir B à \verb|<vide>| ;
	\item prendre le premier caractère du réservoir A et le mettre en \emph{première} position dans le réservoir B ;
	\item si le réservoir A n'est pas vide, retourner au point 2.
\end{algo}

Avec des arguments délimités, il est très facile de construire de tels réservoirs tout en gardant la macro purement développable. Décidons pour l'instant que ces délimiteurs sont des points. La structure des arguments sera donc :

\centrecode-<réservoir A>.<réservoir B>.-

\noindent Voici ce que sont les étapes pour inverser le texte « abcd » :
\begin{center}
	\verb|abcd..|${}\longrightarrow{}$\verb|bcd.a.|${}\longrightarrow{}$\verb|cd.ba.|${}\longrightarrow{}$\verb|d.cba.|${}\longrightarrow{}$\verb|.dcba.|
\end{center}

Le choix du point interdit que le \verb|<mot>| en contienne, ce qui n'est pas absurde en soi. Cependant, pour plus de sécurité, nous prendrons \verb|\@nil| comme délimiteur. Le code de la macro §\reverse ne présente aucune difficulté particulière :

\showcode/\catcode`\@11
\def\reverse#1{%¤§*\reverse¤
	\ifempty{#1}
		{}% s'il n'y a rien à inverse, ne rien faire
		{\reverse@i#1\@nil\@nil}% initialisation des réservoirs et appeler \reverse@i
}
\def\reverse@i#1#2\@nil#3\@nil{% #1 est le 1er caractère du réservoir A
	\ifempty{#2}% si ce qui reste après ce 1er caractère est vide¤§*\ifempty¤
		{#1#3}% renvoyer #1#3 qui est le résultat final
		{\reverse@i#2\@nil#1#3\@nil}% sinon, recommencer en déplaçant #1
		                            % en 1re position du réservoir B
}
\catcode`\@12
a) \reverse{foobar}\qquad
b) \edef\foo{\reverse{Bonjour}}\meaning\foo\qquad
c) \reverse{Bonjour le monde}\qquad
d) \reverse{Bonjour{ }le{ }monde}¤§*\reverse¤/

Selon la règle de la page~\pageref{argument.espace}, les espaces qui ne sont pas entre accolades sont ignorés lorsque lus comme argument par une macro. Il est donc normal que « Bonjour le monde » donne un résultat inversé sans espace.
\end {exercice}

Le simple fait pour pouvoir tester de façon fiable si un argument est vide ouvre déjà la voie à d'autres tests\ldots{}\idx*[|)]{argument!vide}

\subsection{Tester si un code contient un motif}\label{test.code.contient.motif}
Le but est d'élaborer un test qui vérifie si un \verb-<code>- contient un autre code que l'on appelle \verb-<motif>-. Nous allons tenter d'écrire une macro §\ifin[|(] dont voici la syntaxe :\label{ifin}

\centrecode-\ifin{<code>}{<motif>}{<vrai>}{<faux>}-

\noindent Le code \verb-<vrai>- sera exécuté si \verb-<code>- contient \verb-<motif>- et le code \verb|<faux>| le sera dans le cas contraire.

Comme nous l'avions fait avec les macros §\rightof et §\leftof du chapitre \ref{rightof} et \ref{leftof} de la partie 2, nous allons utiliser une macro auxiliaire à arguments délimités. Cette macro \verb-\ifin@i- sera située à l'intérieur du texte de remplacement de §\ifin de telle sorte qu'elle puisse accéder aux arguments de §\ifin. Elle aura le \idx{texte de paramètre} suivant :

\centrecode-\def\ifin@i##1#2##2\@nil{code à définir}-

\noindent Ainsi, les arguments délimités \verb|##1| et \verb|##2| collectent ce qui se trouve respectivement avant et après le \verb|<motif>| qui est l'argument \verb|#2| de la macro chapeau.

L'idée est que la macro §\ifin appelle la macro \verb-\ifin@i- de cette façon :

\centrecode-\ifin@i#1#2\@nil-

\noindent où le \verb|<motif>| (argument \verb-#2-) est ajouté après le \verb|<code>| (argument \verb|#1|) afin de satisfaire la macro à argument délimité \verb|\ifin@i| même dans le cas où \verb|#1| ne contient pas \verb|#2|. Avec cet appel, de deux choses l'une :

\begin{itemize}
	\item soit \verb-#1- contient déjà \verb-#2- et donc la première occurrence de \verb-#2- est dans \verb-#1- et nous pouvons donc affirmer que ce qui se trouve après cette première occurrence (qui est l'argument \verb|##2| de \verb|\ifin@i|) n'est pas vide puisqu'au moins constitué de \verb-#2- que nous avons rajouté;
	\item soit \verb-#1- ne contient pas \verb-#2-, ce qui fait que la première occurrence de \verb-#2- est le \verb-#2- que nous avons ajouté juste devant le \verb|\@nil|. Par conséquent, ce qui se trouve après cette occurrence est vide.
\end{itemize}

Il suffit donc de tester si ce qui est après la première occurrence de \verb-#2- est vide ou pas, ce que fait la ligne \no4 du code ci-dessous :

\showcode/\catcode`\@11
\def\ifin#1#2{%¤§*\ifin¤
	\def\ifin@i##1#2##2\@nil{% définit la macro auxiliaire
		\ifempty{##2}% si ce qu'il y a derrière le motif est vide¤§*\ifempty¤
			\secondoftwo% aller à "faux"¤§*\secondoftwo¤
			\firstoftwo% sinon à "vrai"¤§*\firstoftwo¤
	}%
	\ifin@i#1#2\@nil% appel de la macro auxiliaire
}
\catcode`\@12
a) \ifin{abc\relax1}{bc}{vrai}{faux}\qquad
b) \ifin{abc \relax1}{c\relax}{vrai}{faux}\qquad
c) \ifin{abc \relax1}{ }{vrai}{faux}\qquad
d) \ifin{abc \relax1}{}{vrai}{faux}\qquad
e) \ifin{}{a}{vrai}{faux}/

Le gros inconvénient des arguments délimités est le défaut que nous avions signalé avec la macro §\rightof à la page~\pageref{rightof.et.accolades}. Le \verb|<motif>| ne peut pas contenir d'accolades ouvrantes puisqu'elles se retrouveraient dans le texte de paramètre de \verb|\ifin@i| et en fausseraient la définition. Nous allons donc nous limiter à un code et un motif sans accolades\ldots{} Avant de trouver mieux !§*\ifin[|)]

\begin{exercice}\label{ifstart}
Écrire une macro §\ifstart[|(] de syntaxe

\centrecode-\ifstart{<code>}{<motif>}{<vrai>}{<faux>}-

\noindent qui teste si le \verb|<code>| commence par le \verb|<motif>| et exécute \verb|<vrai>| si c'est le cas et \verb|<faux>| sinon.
\solution
La méthode est très similaire à celle déployée dans §\ifin. Dans l'homologue de \verb-\ifin@i- qui est \verb|\ifstart@i|, il suffira de tester si ce qui est \emph{avant} la première occurrence du motif (c'est-à-dire \verb-##1-) est vide ou pas. Ce qui donne ce code :

\showcode/\catcode`\@11
\def\ifstart#1#2{%
	\def\ifstart@i##1#2##2\@nil{\ifempty{##1}}%¤§*\ifempty¤
	\ifstart@i#1#2\@nil
}
\catcode`\@12
a) \ifstart{abc}{bc}{vrai}{faux}\qquad
b) \ifstart{abc}{ab}{vrai}{faux}\qquad
c) \ifstart{ abc}{ }{vrai}{faux}\qquad
d) \ifstart{abc}{}{vrai}{faux}\qquad
e) \ifstart{}{a}{vrai}{faux}/

Les deux derniers cas sont problématiques. Il serait logique que l'avant-dernier soit vrai puisque «\verb|abc|» commence bien par un argument vide. Pour le dernier au contraire, il faudrait qu'il soit faux, car un argument vide ne contient pas le motif «\verb|a|».

Pour faire en sorte qu'un \verb|<motif>| vide donne toujours le code \verb|<vrai>|, il suffit à la ligne \no4 de tester si \verb|#2| est vide et exécuter §\firstoftwo si c'est le cas et appeler \verb-\ifstart@i- sinon :

\centrecode-\ifempty{#2}\firstoftwo{\ifstart@i#1#2\@nil}-

Si le \verb|<code>| est vide, l'appel à \verb-\ifstart@i- est \verb-\ifstart@i#2\@nil- et donc, l'argument délimité \verb-##1- de \verb-\ifstart@i- est logiquement vide. On peut artificiellement le remplir en mettant un \idx\relax juste avant le \verb-#2- de la ligne 4. Cela donne le code :

\showcode/\catcode`\@11
\def\ifstart#1#2{%
	\def\ifstart@i##1#2##2\@nil{\ifempty{##1}}%¤§*\ifempty¤
	\ifempty{#2}% si motif vide¤§*\ifempty¤
		\firstoftwo% exécuter code "vrai"¤§*\firstoftwo¤
		{\ifstart@i#1\relax#2\@nil}% sinon, aller à la macro auxiliaire
}
\catcode`\@12
a) \ifstart{abc}{bc}{vrai}{faux}\qquad
b) \ifstart{abc}{ab}{vrai}{faux}\qquad
c) \ifstart{ abc}{ }{vrai}{faux}\qquad
d) \ifstart{abc}{}{vrai}{faux}\qquad
e) \ifstart{}{a}{vrai}{faux}/
§*\ifstart[|)]\end{exercice}

\subsection{Tester si un code se termine par un motif}
Il est bien plus difficile de tester si un \verb|<code>| se termine par un \verb|<motif>|. Cela est dû à la façon qu'ont de fonctionner les arguments délimités qui ne s'intéressent qu'à la \emph{première} occurrence d'un délimiteur et non pas à la dernière. Si nous souhaitons écrire une macro §\ifend[|(] dont la syntaxe est

\centrecode-\ifend{<code>}{<motif>}{<vrai>}{<faux>}-

\noindent nous allons devoir recourir à un algorithme récursif.

\begin{algo}
	\item ajouter le \verb|<motif>| au début du \verb|<code>| et dans le résultat obtenu,
	\item appeler \verb|<code>| ce qui est après la première occurrence du \verb|<motif>|;
	\item si \verb|<code>| est vide exécuter \verb|vrai|;
	\item sinon
	\begin{algo}
		\item si \verb|<code>| contient le \verb|<motif>|, retourner en 2;
		\item sinon, exécuter \verb|faux|.
	\end{algo}
\end{algo}

Le point \no1 sera l'appel initial à une macro auxiliaire récursive \verb|\ifend@i| à argument délimité. Cette macro occupera les points suivants (de 2 à 4).

Traduisons cet algorithme en code \TeX{} et vérifions qu'il fonctionne sur quelques exemples. Le point 1 sera codé de cette façon :

\centrecode-\ifend@i#2#1\@nil-

La macro auxiliaire \verb-\ifend@i- va se charger, grâce à son argument délimité, d'isoler ce qui se trouve après la première occurrence de \verb|<motif>|. Voici ce que sera son \idx{texte de paramètre} :

\centrecode-\def\if@end##1#2##2\@nil{...}-

\noindent À l'intérieur de la macro \verb|\if@end|, il suffira de tester si \verb-##2- est vide auquel cas, §\firstoftwo sera exécuté. Dans le cas contraire, il faudra tester avec §\ifin si le \verb|##2| contient le \verb|<motif>| qui est \verb|#2| et appeler récursivement \verb|\ifend@i| dans l'affirmative et exécuter §\secondoftwo sinon :

\showcode/\catcode`\@11
\def\ifend#1#2{%
	\def\ifend@i##1#2##2\@nil{% ##2 = ce qui reste après le motif
		\ifempty{##2}% si ##2 est vide¤§*\ifempty¤
			\firstoftwo% exécuter l'argument "vrai"¤\defline\bbb§*\firstoftwo¤
			{\ifin{##2}{#2}% sinon, si ##2 contient le <motif>¤§*\ifin¤
				{\ifend@i##2\@nil}% appeler \ifend@i avec ce qui reste
				\secondoftwo% sinon, exécuter l'argument "faux"¤§*\secondoftwo¤
			}%
	}%
	\ifend@i#2#1\@nil% appelle la macro récursive¤\defline\aaa¤
}
\catcode`\@12
1) \ifend{abc de}{de}{vrai}{faux}\qquad
2) \ifend{abd de }{de}{vrai}{faux}\qquad
3) \ifend{abc de }{ }{vrai}{faux}\qquad
4) \ifend{}{a}{vrai}{faux}\qquad
5) \ifend{abc de}{}{vrai}{faux}/

\begin{exercice}
Expliquer pourquoi le code ci-dessus renvoie le contraire de ce que l'on attend aux cas \nos4 et 5 et proposer des solutions pour y remédier.
\solution
Dans le cas où le \verb|<code>| est vide (cas \no4), l'appel de la ligne \no\aaa{} devient

\centrecode-\ifend@i a\@nil-

\noindent et l'argument \verb|##2| de \verb|\ifend@i| qui se trouve après la première occurrence de «\verb|a|» est vide. Pour s'en prémunir, nous pouvons artificiellement meubler avec \idx\relax ce qui se trouve après cette première occurrence. L'appel à la ligne \no\aaa{} deviendrait donc :

\centrecode-\ifend@i#2\relax#1\@nil-

Pour le cas \no5, le \verb|<motif>| est vide, l'appel de la ligne \no\aaa{} est

\centrecode-\ifend@i abc de\@nil-

\noindent et le texte de paramètre de \verb|\ifend@i| est «\verb-\def\ifend@i##1##2\@nil{...}-» ce qui signifie que l'argument \verb|##1| n'est plus un argument délimité : il devient le premier argument (ici «\verb|a|») et \verb|##2| est le reste jusqu'au \verb|\@nil| (c'est-à-dire «\verb|bc de|»). Continuons à faire fonctionner la macro mentalement : le test §\ifempty\verb|{##2}| est faux, le test suivant §\ifin\verb|{##2}{#2}| est faux aussi puisque \verb|##2| est vide : la macro §\secondoftwo va donc exécuter le code \verb|faux|.

Le meilleur remède est sans doute de tester dès le premier appel (ligne \no\aaa) si \verb|#2| est vide, cas où §\firstoftwo doit être exécuté.

\showcode/\catcode`\@11
\def\ifend#1#2{%
	\def\ifend@i##1#2##2\@nil{% ##2 = ce qui reste après le motif
		\ifempty{##2}% si ##2 est vide¤§*\ifempty¤
			\firstoftwo% exécuter l'argument "vrai"¤§*\firstoftwo¤
			{\ifin{##2}{#2}% sinon, si ##2 contient le <motif>¤§*\ifin¤
				{\ifend@i##2\@nil}% appeler \ifend@i avec ce qui reste
				\secondoftwo% sinon, exécuter l'argument "faux"¤§*\secondoftwo¤
			}%
	}%
	\ifempty{#2}% si le motif est vide¤§*\ifempty¤
		\firstoftwo% exécuter "vrai"¤§*\firstoftwo¤
		{\ifend@i#2\relax#1\@nil}% sinon, appelle la macro récursive
}
\catcode`\@12
1) \ifend{abc de}{de}{vrai}{faux}\qquad
2) \ifend{abd de }{de}{vrai}{faux}\qquad
3) \ifend{abc de }{ }{vrai}{faux}\qquad
4) \ifend{}{a}{vrai}{faux}\qquad
5) \ifend{abc de}{}{vrai}{faux}/
§*\ifend[|)]\end{exercice}

\subsection{Remplacer un motif par un autre}\substin
Nous allons maintenant construire une macro §\substin[|(], capable de remplacer un \verb|<motif1>| par un \verb|<motif2>| dans un \verb|<code>| :

\centrecode-\substin{<code>}{<motif1>}{<motif2>}-

La méthode va consister à parcourir le \verb|<code>| un peu de la même façon que nous le faisions avec la macro §\ifend. Voici l'algorithme :

\begin{algo}
	\item si le \verb|<code>| est vide, ne rien faire et fin du processus;
	\item sinon
	\begin{algo}
		\item si le \verb|<code>| contient le \verb|<motif1>|, aller au point \no3;
		\item sinon afficher le \verb|<code>| et fin du processus;
	\end{algo}
	\item afficher la partie du \verb|<code>| qui se trouve avant la 1\iere{} occurrence de \verb|<motif1>|;
	\item afficher \verb|<motif2>|;
	\item retourner au point \no1 en appelant \verb|<code>| ce qui se trouve après \verb|<motif1>|.
\end{algo}

Les points \nos1 et 2 vont être effectués par une macro auxiliaire dont le seul argument non délimité sera le 
\verb|<code>| en cours d'examen. Les points \nos3 à 5 seront dévolus à une autre macro auxiliaire qui elle, sera à argument délimité puisqu'il faut séparer ce qui se trouve avant et après le \verb|<motif1>|. Voici ce que cela donne en \idx{pseudocode} :

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}\label{algo2}
\algorithm[\#]{Remplacer toutes les occurrences d'un motif}|
macro ~substin~#1#2#3% #1=<code>, #2=<motif1>, #3=<motif2>
	macro ~substin@i~##1
		~si~ ##1 est vide
			relax% ne rien faire
		~sinon~
			~si~ ##1 contient #3
				~substin@ii~##1@nil% appeler la macro à argument délimités
			~sinon~
				##1% afficher le <code>
			~finsi~
		~finsi~
	~fin~\medbreak
	macro ~substin@ii~##1#2##2@nil% ##1 et ##2=ce qui est avant/après <motif1>
		afficher "##1#3"
		appeler ~substin@i~(##2)% puis recommencer avec le code qui reste
	~fin~\medbreak
	appeler ~substin@i~(#1)% engage le processus
~fin~|
\endgroup

La traduction de ce \idx{pseudocode} en \TeX{} ne pose pas de problème particulier :

\showcode/\catcode`\@11
\def\substin#1#2#3{%
	\def\substin@i##1{%
		\ifempty{##1}% si le <code> est vide¤§*\ifempty¤
			\relax% ne rien faire -> fin du processus
			{\ifin{##1}{#2}% sinon, si le <code> contient <motif1>¤§*\ifin¤
				{\substin@ii##1\@nil}% appeler la macro à argument délimités
				{##1}% sinon, afficher le <code>
			}%
	}%
	\def\substin@ii##1#2##2\@nil{%
		##1#3% afficher ##1 et #3 (qui est <motif2>)
		\substin@i{##2}% et recommencer avec ce qui reste
	}%
	\substin@i{#1}%
}
\catcode`\@12
a) \substin{abracadabra}{a}{A}\qquad
b) \substin{abracadabra}{x}{W}\qquad
c) \substin{abracadabra}{br}{}\qquad
d) \substin{1\relax3}\relax{222}\qquad/§*\substin[|)]

\begin{exercice}
Modifier cette macro en une macro §\substtocs[|(] pour qu'elle n'affiche pas le résultat, mais le mette dans le texte de remplacement d'une \verb|\<macro>| dont l'utilisateur pourra choisir le nom :

\centrecode-\substtocs\<macro>{<code>}{motif1}{motif2}-

\solution
Au lieu d'afficher des morceaux de code, il faudra les ajouter au texte de remplacement d'une macro chargée de collecter le code résultant de ces substitutions. Pour ajouter du code au texte de remplacement d'une macro, §\addtomacro, programmée à la page~\pageref{addtomacro} sera utile.

\showcode/\catcode`\@11
\def\substtocs#1#2#3#4{%
	\def\substtocs@i##1{%
		\ifempty{##1}% si le <code> est vide¤§*\ifempty¤
			\relax% ne rien faire -> fin du processus
			{\ifin{##1}{#3}% sinon, si le <code> contient <motif1>¤§*\ifin¤
				{\substtocs@ii##1\@nil}% appeler la macro à argument délimités
				{\addtomacro#1{##1}}% sinon, ajouter le <code>¤§*\addtomacro¤
			}%
	}%
	\def\substtocs@ii##1#3##2\@nil{%
		\addtomacro#1{##1#4}% ajouter ##1#4¤§*\addtomacro¤
		\substtocs@i{##2}% et recommencer avec ce qui reste
	}%
	\let#1=\empty% initialise la macro à vide¤\idx*\empty¤
	\substtocs@i{#2}%
}
\catcode`\@12
\substtocs\foo{abracadabra}{a}{A}\meaning\foo\par
\substtocs\foo{abracadabra}{x}{W}\meaning\foo\par
\substtocs\foo{abracadabra}{br}{}\meaning\foo\par
\substtocs\foo{1\relax3}\relax{222}\meaning\foo\par
\substtocs\foo{\ifnum1=2 test vrai\fi}{2}{1}\meaning\foo/
\end{exercice}§*\substtocs[|)]

\begin{exercice}\label{exo.majuscules}
Écrire une macro §\majmot[|(]\verb|{<phrase>}| qui met en majuscule tous les mots de la \verb|phrase|.
\solution
Pour que §\majmot effectue son travail, dans la \verb|<phrase>|, chaque espace doit être remplacé par «\verb*| \majuscule|», où la macro §\majuscule lit un argument (qui sera la lettre du mot suivant) et la met en majuscule. En coulisses, nous utiliserons la primitive \idx\uppercase.

Nous allons mettre §\substin à contribution pour effectuer ces remplacements, en ayant pris soin de mettre §\majuscule tout au début de la phrase afin de traiter la première lettre du premier mot.

\showcode/\def\majuscule#1{\uppercase{#1}}¤\idx*\uppercase§*\majuscule¤
\def\majmot#1{\substin{\majuscule#1}{ }{ \majuscule}}¤§*\substin§*\majuscule¤
\majmot{un petit texte}\par
\majmot{Un grand texte sans importance}/

Conclusion : ça ne fonctionne pas du tout !

Une petite analyse montre que tout vient de la façon dont est faite la substitution et il faut revenir au code de §\substin :

\begingroup
\renewcommand*\indentcodeactivechars[1]{%
	\defactive\^^M{\par\hspace{#1}}%
	\defactive\^^I{{ }{ }}% tab = 4 espaces
	\catcode`\¤=13
	\begingroup
		\lccode`\~`\¤\relax
		\lowercase{\endgroup\long\def~##1~}{%
			\begingroup
				\catcode`\{=1 \catcode`\}=2 \catcode`\#=6 \catcode`\\=0 \catcode`\$=3
				\catcode`\f=11
				\endlinechar=-1
				\scantokens{##1}%
			\endgroup
			}% échappement ¤...¤
	\footnotesize
}\indencodenumtrue
\indentcode/\def\substin#1#2#3{%¤§*\substin¤
	\def\substin@i##1{%
		\ifempty{##1}% si le code est vide¤§*\ifempty¤
			\relax% ne rien faire -> fin du processus
			{\ifin{##1}{#2}% sinon, si le code contient motif1¤§*\ifin¤
				{\substin@ii##1\@nil}% appeler la macro à argument délimités
				{##1}% sinon, afficher le code
			}%
	}%
	\def\substin@ii##1#2##2\@nil{%
		##1#3% afficher ##1 et #3 (qui est <motif2>)
		\substin@i{##2}% et recommencer avec ce qui reste
	}%
	\substin@i{#1}%
}/\endgroup

Constatons à ligne \no11 que le code \verb|#2| est substitué par le motif \verb|#3| donc, \verb|##1#3| est exécuté par \TeX{} dans la foulée. C'est de cette exécution \emph{au fur et à mesure} que vient le problème. Ici en effet, le motif de substitution \verb|#3| est «\verb*| \majsucule|». Notre processus échoue parce que lors de l'exécution au fur et à mesure, la macro §\majuscule va lire son argument qui est \verb|\substin@i| de la ligne \no12. Cet argument sera traité par \idx\uppercase qui le laisse intact puisque \idx\uppercase n'a aucun effet sur les séquences de contrôle. Le code ci-dessus ne produit donc aucun effet.

Nous allons nous en sortir en utilisant la macro §\substtocs de façon à stocker le code obtenu dans une macro temporaire \verb|\temp| que nous afficherons à la toute fin du processus, avant de sortir du groupe semi-simple dans lequel elle a été créée :

\showcode/\def\majuscule#1{\uppercase{#1}}¤\idx*\uppercase§*\majuscule¤
\def\majmot#1{%
	\begingroup¤\idx*\begingroup¤
		\substtocs\temp{\majuscule#1}{ }{ \majuscule}%¤§*\substtocs§*\majuscule¤
		\temp% exécute la macro temporaire
	\endgroup¤\idx*\endgroup¤
}
\majmot{un petit texte}\par
\majmot{Un grand texte Sans importance}/

La leçon à retenir ici est que faire exécuter par \TeX{} de morceaux de code dans une macro récursive n'est pas équivalent à les mettre tous dans une séquence de contrôle que l'on exécute en une fois à la fin.§*\majmot[|)]
\end{exercice}

\begin{exercice}
Écrire une macro §\cnttimes[|(]\label{cnttimes}\verb|{<code>}{<motif>}| qui affiche combien de fois le \verb|<motif>| est contenu dans le \verb|<code>|.
\solution
Nous allons procéder comme dans §\substtocs. La macro chapeau initialisera un compteur à 0 et passera la main à une macro auxiliaire, chargée de l'incrémenter à chaque fois que le motif sera rencontré :

\showcode/\catcode`\@11
\newcount\cnt@occ¤\idx*\newcount¤
\def\cnttimes#1#2{%¤§*\cnttimes¤
	\def\cnttimes@i##1{%
		\ifempty{##1}% si le <code> est vide¤§*\ifempty¤
			{\number\cnt@occ}% afficher le nombre d'occurrences¤\idx*\number¤
			{\ifin{##1}{#2}% sinon, si le <code> contient <motif1>¤§*\ifin¤
				{\cnttimes@ii##1\@nil}% appeler la macro à argument délimités
				{\number\cnt@occ}% sinon, afficher le nombre d'occurrences
			}%
	}%
	\def\cnttimes@ii##1#2##2\@nil{%¤\idx*\advance¤
		\advance\cnt@occ1
		\cnttimes@i{##2}% et recommencer avec ce qui reste
	}%
	\cnt@occ=0 % initialise le compteur
	\cnttimes@i{#1}%
}
\catcode`\@12
a) \cnttimes{abracadabra}{a}\qquad
b) \cnttimes{abracadabra}{ra}\qquad
c) \cnttimes{abracadabra}{w}\qquad
d) \cnttimes{abc def ghijk l }{ }\qquad
e) \cnttimes{\ifnum1=2 vrai\else faux\fi}{\ifnum}¤§*\cnttimes¤/§*\cnttimes[|)]

Juste pour le plaisir de se compliquer la vie, essayons de modifier la macro en §\cnttimestocs[|(] pour qu'elle réponde aux contraintes suivantes :

\begin{enumerate}
	\item ne pas utiliser de compteur;
	\item n'écrire qu'une seule macro intérieure au lieu de deux;
	\item stocker le résultat dans une macro spécifiée par l'utilisateur.
\end{enumerate}

Si nous nous interdisons l'utilisation d'un compteur, nous devrons recourir à la primitive \idx\numexpr pour remplacer \idx\advance afin d'incrémenter le nombre d'itérations. Il est évidemment possible de stocker le nombre d'itérations dans une séquence de contrôle, mais dans ce cas, se priver d'un compteur pour basculer vers une macro n'a pas vraiment de sens, autant conserver un compteur. Il est plus original de stocker le nombre d'itérations dans un argument qui s'ajoutera à ceux de la macro récursive \verb|\cnttimes@i| vue dans le code précédent. Pour pouvoir facilement incrémenter cet argument (qui implique le 1-développer) avant de lancer l'appel récursif, il est judicieux de le placer comme premier argument. L'idée la plus pratique est donc d'ajouter cet argument (et de le délimiter par un \verb|\@nil|) avant ceux de \verb-\cnttimes@ii-. La macro récursive \verb|\cnttimestocs@i| aura donc le texte de paramètre suivant :

\centrecode-\def\cnttimestocs@i##1\@nil##2#2##3\@nil{...}-

\noindent Il faudra spécifier «\verb|0|» comme argument \verb|##1| lors du premier appel.

Ensuite, comme cette macro récursive à est à argument délimité par le \verb|<motif>|, elle \emph{doit} recevoir un \verb|<code>| qui contient ce \verb|<motif>|. Il est donc nécessaire de tester la présence de ce \verb|<motif>| lors du premier appel et également à l'intérieur de la macro récursive avant qu'elle ne s'appelle elle-même avec le \verb|<code>| restant.

\showcode|\catcode`\@11
\long\def\cnttimestocs#1#2#3{% #3=macro recevant le résultat¤§*\cnttimestocs¤
	\long\def\cnttimestocs@i##1\@nil##2#2##3\@nil{%
		% ##1=nb d'occurrences rencontrées jusqu'alors
		% ##2 et ##3=ce qui est avant/après le <motif>
		\ifin{##3}{#2}% si le <motif> est dans ce qui reste¤§*\ifin¤
			{\expandafter\cnttimestocs@i% appeler la macro récursive
				\number\numexpr##1+1\relax\@nil% avec une occurrence de plus¤\idx*\number\idx*\numexpr¤
				##3\@nil% et ce qui reste
			}%
			{\edef#3{\number\numexpr##1+1\relax}}% sinon, stocker 1 occurrence de plus dans #3
	}%
	\ifin{#1}{#2}% si le <motif> est dans le <code>¤§*\ifin¤
		{\cnttimestocs@i 0\@nil#1\@nil}% appeler la macro récursive avec 0 occurrence
		{\def#3{0}}% sinon, mettre 0 dans #3
}
\catcode`\@12
a) \cnttimestocs{abracadabra}{a}\foo \meaning\foo\qquad
b) \cnttimestocs{abracadabra}{ra}\foo \meaning\foo\qquad
c) \cnttimestocs{abracadabra}{w}\foo \meaning\foo\qquad
d) \cnttimestocs{abc def ghijk l }{ }\foo \meaning\foo\qquad
e) \cnttimestocs{\ifnum1=2 vrai\else faux\fi}{\ifnum}\foo \meaning\foo|
§*\cnttimestocs[|)]\end{exercice}

\subsection{Substitutions successives}
Nous allons maintenant écrire une macro §\multisubst[|(], généralisation de la macro §\substin où nous pourrons spécifier plusieurs substitutions successives :

\centrecode-\multisubst{<code>}{{<motif1>}{<motif2>}{<motif3>}{<motif4>}{<motif5>}...}-

\noindent Cette macro substituera toutes les occurrences de \verb|<motif1>| par \verb|<motif2>| puis toutes celles de \verb|<motif3>| par \verb|<motif4>| et ainsi de suite jusqu'à ce que la liste des substitutions soit vide dans le deuxième argument. Les motifs utilisés dans la substitution seront donc lus par \emph{paires}. L'idée est de se servir de la macro §\substin précédemment écrite en lui envoyant comme second et troisième argument les motifs de substitution pris deux par deux dans la liste. Comme un espace non entouré d'accolades est ignoré en tant qu'argument, les motifs peuvent être groupés par paires \emph{séparées par un espace} dans la liste des motifs afin d'en améliorer la lisibilité.

\showcode/\catcode`\@11
\def\multisubst#1#2{%
	\def\subst@code{#1}% stocke le <code>
	\multisubst@i#2\@nil% appelle la macro récursive avec la liste de motifs
}

\def\multisubst@i#1#2#3\@nil{% #1 et #2=paire de motifs  #3=motifs restants
	\expandafter\substtocs\expandafter\subst@code\expandafter% 1-développe¤§*\substtocs¤
		{\subst@code}{#1}{#2}% le <code> et effectue la substitution en cours
	\ifempty{#3}% si la liste des motifs est vide¤§*\ifempty¤
		\subst@code% exécuter le <code> obtenu
		{\multisubst@i#3\@nil}% recommencer avec les motifs qui restent
}
\catcode`\@12
1) \multisubst{abracadabra}{aA rR}\par
2) \multisubst{Ce texte devenu \`a peine reconnaissable montre que le¤\defline\aaa¤
   r\'esultat contient des sonorit\'es catalanes, corses ou grecques
   assez inattendues.}{a{AA} ya uy ou io ei {AA}e}/

La macro chapeau \verb|\multisubst| de la ligne \no2 se contente de lire le \verb|<code>| et l'assigne à la macro \verb|\subst@code| avant de passer la main à la véritable macro récursive \verb|\multisubt@i|, à argument délimité. La liste des motifs de substitutions est passée comme argument pour s'étendre jusqu'au \verb|\@nil|. Les arguments non délimités \verb|#1| et \verb|#2| deviennent les deux motifs de substitution de l'itération en cours tandis que \verb|#3| est la liste des paires restantes.

Le cas \no2 des lignes \nos\aaa{} à \number\numexpr\aaa+2\relax{} traite d'une façon différente le problème de la permutation circulaire des voyelles déjà résolu à la page~\pageref{permutation.voyelles}. On ne touche plus à aucun code de catégorie, mais on effectue tour à tour les substitutions désirées. La méthode est cependant \emph{lente}, car l'argument est ici un texte assez long et celui-ci sera parcouru par §\multisubst autant de fois qu'il y a de substitutions à faire, c'est-à-dire 7 fois. La « propreté » que l'on gagne à ne pas modifier les codes de catégorie se paie en lenteur.
\grandsaut

Au-delà ce ce défaut lié à la méthode utilisée, le code présente une autre redondance : chaque paire est lue \emph{plusieurs fois}. Elle est lue une première fois par la macro chapeau \verb|\multisubst| puisqu'elle lit toutes les paires. Par la suite, à chaque itération, la macro récursive \verb|\multisubst@i| lit (et mange) la première paire de son argument, mais lit \emph{aussi que la totalité des paires restantes}. La totalité des paires est donc lue deux fois : une fois par la macro chapeau et une fois par la macro récursive lors de la première itération (qui ensuite supprime la paire \no1). À la 2\ieme{} itération, la macro récursive lit la totalité des paires restantes et supprime la paire \no2, etc. Ainsi, s'il y a $n$ paires, la première est lue 2 fois, la 2\ieme{} est lue 3 fois, et ainsi de suite jusqu'à la $n$\ieme{} qui est lue $n+1$ fois.

Il s'agit donc de changer de méthode afin de limiter le nombre de lectures des paires. Envisageons le scénario suivant : 

\begin{itemize}
 \item lire la liste de toutes les paires une fois afin de les transmettre à la macro récursive en les faisant suivre d'une paire spéciale, constituée de deux arguments spéciaux;
 \item cette macro récursive, au lieu de lire tous les arguments, n'en lit que deux : pour savoir si elle doit les prendre comme une paire de motifs ou comme condition d'arrêt, il faut qu'elle les teste et les compare aux arguments spéciaux;
 \item si le test est positif, cela signifie que la fin de la liste des couples de motifs a été complètement lue et que la fin du processus doit être exécutée;
 \item dans le cas d'un test négatif, la substitution est exécutée et la macro s'appelle elle même pour une nouvelle itération.
\end{itemize}

Cette façon de procéder implique que chaque paire est lu exactement deux fois; une fois par la macro chapeau et une fois par la macro récursive.

Un dernier détail doit être décidé : que sont des arguments \emph{spéciaux}? Ce sont des arguments qui ne sont pas susceptibles d'être un des deux motifs. Tout est imaginable, mais il semble assez sûr de prendre un \idx{quark} tant ce genre de macro est improbable dans une liste de motifs de substitution. Voici comment modifier le code :

\showcode/\catcode`\@11
\def\quark{\quark}¤§*\quark¤

\def\multisubst#1#2{% #1 = <code>   #2 = <liste des paires>
	\def\subst@code{#1}% stocke le <code>
	\multisubst@i#2\quark\quark% appelle la macro récursive avec ¤§*\quark¤
	                           % 2 arguments spéciaux en fin de liste
}

\def\multisubst@i#1#2{% #1#2 = paire de motifs en cours
	\def\arg@a{#1}% stocke le <motif1> dans une macro
	\ifx\arg@a\quark% si le motif spécial est atteint¤§*\quark¤
		\expandafter\subst@code% exécuter le code obtenu
	\else
		\expandafter\substtocs\expandafter\subst@code\expandafter% 1-développe¤§*\substtocs¤
			{\subst@code}{#1}{#2}% le <code> et effectue la substitution en cours
		\expandafter\multisubst@i% puis lis la paire de motifs suivants
	\fi
}
\catcode`\@12
\multisubst{abracadabra}{aA rR}\par
\multisubst{Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des
  sonorit\'es catalanes, corses ou grecques assez inattendues.}{a{AA} ya uy ou io ei {AA}e}/§*\multisubst[|)]

\label{lire.arguments}\begin{regle}[Méthode de programmation]
	Lorsqu'une liste d'arguments consécutifs doit être lue au fur et à mesure par une macro récursive, deux méthodes de lecture sont envisageables. Elles ont en commun une première lecture de tous les arguments afin de les passer à la macro récursive et c'est cette dernière qui a deux façons de fonctionner :

	\begin{enumerate}
		\item lire la totalité des arguments restants à chaque itération, utiliser ceux qui sont utiles à l'itération en cours et recommence1r avec tous les arguments restants. S'arrêter lorsque la liste d'arguments restants est vide;
		\item ne lire \emph{que} les arguments utiles à l'itération en cours, les utiliser et recommencer. S'arrêter lorsque l'un des arguments lus est égal à un argument spécifique préalablement placé en fin de liste par la macro chapeau.
	\end{enumerate}
	\end{regle}

Il est inutile de dire qu'un programmeur rigoureux choisit de préférence la deuxième méthode même si souvent, le nombre d'arguments à lire est peu élevé auquel cas la première méthode est parfaitement acceptable.\tidx*[|)]{ifx}

\section{Autres tests}
\subsection{Pseudotests et variables booléennes}\idx*[|(]{pseudotest}
\TeX{} dispose des pseudotests \tidx{iftrue} et \tidx{iffalse}, le premier est toujours vrai et le second toujours faux. Bien qu'elles en partagent la syntaxe et les subtilités de développement, ces primitives n'effectuent pas de tests. Cependant, nous allons le voir un peu plus bas, elles n'en sont pas moins utiles.

\showcode/\iftrue foobar\else ceci n'est jamais lu par \TeX\fi\par
\iffalse ceci n'est jamais lu par \TeX\else foobar\fi/

On peut bien sûr rendre une macro \idx\let-égale à \tidx{iftrue} ou \tidx{iffalse} pour, au choix, disposer d'une macro simulant un test toujours vrai ou toujours faux. C'est d'ailleurs exactement ce que fait la macro de plain-\TeX{} \idx\newif\verb|<macro>| qui construit 3 macros qui ont un comportement identique à celui de variables « booléennes » que l'on trouve dans d'autres langages.

Ainsi, si nous écrivons \idx\newif\verb|\ifbar| alors, 3 séquences de contrôle seront créées :
\begin{itemize}
	\item \verb|\bartrue|  qui rend \verb|\ifbar| \idx\let-égale à \tidx{iftrue} ;
	\item \verb|\barfalse| qui rend \verb|\ifbar| \idx\let-égale à \tidx{iffalse} ;
	\item \verb|\ifbar| qui tient lieu de \tidx{iftrue} ou \tidx{iffalse} selon la « valeur booléenne » qui lui aura été donnée par l'une des deux premières macros.
\end{itemize}

\showcode/\newif\ifhomme¤\idx*\newif¤
\def\debutlettre{Ch\ifhomme er Monsieur\else ère Madame\fi}%

\hommetrue
\debutlettre
\medbreak¤\idx*\medbreak¤

\hommefalse
\debutlettre/

Le \idx[!plain-\TeX]{format} plain-\TeX{} fait en sorte que lorsqu'on écrit \idx\newif\verb|\<nom>|, le \verb|<nom>| commencer \emph{obligatoirement} par «\verb|if|». Il est intéressant de noter que \LaTeX{} ré-implémente la macro \idx\newif en autorisant le \verb|<nom>| à commencer par deux caractères quelconques qui seront enlevés lorsque \verb|\<nomtrue>| ou \verb|\<nomfalse>| sont crées.

\begin{regle}
Les \idx{pseudotest}s \tidx{iftrue} et \tidx{iffalse} n'effectuent aucun test et donc n'admettent aucun argument. Ils sont respectivement toujours vrai et toujours faux. En dépit de ce caractère invariable, ils se comportent comme n'importe quel test, notamment en ce qui concerne l'éventuelle présence du \tidx{else} et celle, obligatoire, du \tidx{fi}.

La macro \idx\newif, suivie d'une macro \verb|\if<nom>| crée 3 nouvelles macros dont le comportement est identique à celui des variables booléennes. Le test \verb|\if<nom>| sera vrai si la macro \verb|\<nom>true| a été exécutée auparavant et sera faux si c'est la macro \verb|\<nom>false|.
\end{regle}\idx*[|)]{pseudotest}

\subsection{Le test \texttt{\textbackslash ifcat}}\tidx*[|(]{ifcat}
Le test \verb|\ifcat<token1><token2>| compare les codes de catégorie des deux tokens qui le suivent immédiatement. Ce test se comporte un peu comme \tidx{ifnum} en ce sens qu'il lance un développement maximal \emph{avant} de faire le test. Sans action visant à empêcher le développement (utilisation de \idx\noexpand ou \idx\unexpanded), le test compare donc les deux premiers tokens non développables résultant du développement maximal.

Il faut savoir que pour \verb|\ifcat|, un token de type séquence de contrôle est vu comme ayant un code de catégorie égal à 16. Cette 17\ieme{} catégorie, spécifique au test \verb|\ifcat|, vient s'ajouter aux 16 autres catégories déjà existantes pour la primitive \idx\catcode. En revanche, si une séquence de contrôle ou un caractère actif a été préalablement rendu \idx\let-égal à un \verb|<token>|, \verb|\ifcat| prend en compte le code de catégorie du \verb|<token>|.

\showcode/\catcode`\*=13 \catcode`\+=13 % "*" et "+" sont actifs
1) \def*{xyz}\def+{abc}% définit les caractères actifs
   \ifcat *+vrai\else faux\fi\qquad ¤\tidx*{ifcat}¤
2) \ifcat \noexpand *\noexpand +vrai\else faux\fi\qquad¤\idx*\noexpand¤
3) \def\foo{foobar}%
   \ifcat \noexpand\foo\relax vrai\else faux\fi\qquad% \foo et \relax sont vus égaux   ¤\idx*\noexpand¤
4) \ifcat = vrai\else faux\fi\qquad% "=" et " " n'ont pas le même catcode
5) \ifcat _^vrai\else faux\fi\qquad% "_" et "^" n'ont pas le même catcode
6) \let\foo=&
   \ifcat &\foo vrai\else faux\fi% "&" et \foo (let-égal à "&") sont vus égaux¤\tidx*{ifcat}¤/

Ce qui arrive lors du test \no1 est facilement compréhensible : le caractère actif «\verb-*-» est développé au maximum pour donner «\verb-xyz-». Le test \verb|\ifcat| comparera donc les deux premiers tokens issus de ce développement, «\verb-x-» et «\verb-y-», et comme ils ont le même catcode, le test sera vrai et tout ce qui est avant le \tidx{else} sera exécuté. Le «\verb|z|» restant va être dirigé vers l'affichage. Ensuite, le caractère actif «\verb|+|» va se développer et afficher «\verb|abc|». Enfin, «\verb|vrai|» sera affiché. On obtient bien l'affichage «\verb|zabcvrai|».

Le \idx\noexpand du test \no3 bloque le développement de la macro \verb|\foo| et la comparaison qui est faite est bien entre les catcodes de «\verb-\foo-» et «\verb-\relax-».

\begin{regle}
Le test \verb|\ifcat| lance le développement maximal et dès qu'il obtient deux tokens non développables (ou dont le développement est bloqué par \idx\noexpand ou \idx\unexpanded), il effectue la comparaison des codes de catégorie.

Si un token testé par \verb|\ifcat| est une séquence de contrôle ou un caractère actif rendu \idx\let-égal à un \verb|<token>|, \verb|\ifcat| prend en compte le code de catégorie du \verb|<token>|.

Si un token testé par \verb|\ifcat| est une séquence de contrôle, son code de catégorie est vu égal à 16.
\end{regle}

\begin{exercice}\label{ifcs}
Écrire une macro §\ifcs[|(], de syntaxe

\centrecode|\ifcs<token>{<vrai>}{<faux>}|

qui teste si le \verb|<token>| est une séquence de contrôle au sens de \verb|\ifcat|. Selon l'issue du test, \verb|<vrai>| ou \verb|<faux>| seront exécutés.
\solution
La comparaison sera faite entre le \verb|<token>| dont on aura bloqué le développement et \idx\relax. Voici le code :

\showcode/\catcode`\@11
\def\ifcs#1{%¤§*\firstoftwo§*\secondoftwo\idx*\noexpand¤
	\ifcat\noexpand#1\relax\expandafter\firstoftwo
	\else                  \expandafter\secondoftwo
	\fi
}
\catcode`\@12
1) \def\foo{bar}\ifcs\foo{vrai}{faux}\qquad
2) \ifcs\def{vrai}{faux}\qquad
3) \ifcs A{vrai}{faux}\qquad
\catcode`\*=13 
4) \let*=W \ifcs*{vrai}{faux}\qquad
5) \let*=\relax \ifcs*{vrai}{faux}\qquad
6) \let\foo=A \ifcs\foo{vrai}{faux}\qquad
7) \ifcs\bgroup{vrai}{faux}/

Remarquons aux cas \nos5, 6 et 7 que si l'on s'en tient à la vraie définition d'une séquence de contrôle (suite de caractères qui commence par le caractère d'échappement), le test §\ifcs que nous avons écrit n'est pas satisfaisant.
\end{exercice}§*\ifcs[|)]\tidx*[|)]{ifcat}

\subsection{Le test \texttt{\textbackslash if}}\tidx*[|(]{if}
Le test \verb|\if| est en tous points semblable au test \verb|\ifcat| sauf que ce sont les codes de \emph{caractère} des deux tokens qui sont comparés.

\begin{regle}
Le test \verb|\if| instaure un développement maximal et dès qu'il obtient deux tokens non développables (ou dont le développement est bloqué par \idx\noexpand ou \idx\unexpanded), il effectue la comparaison de leurs codes de caractère.

Si un token testé par \verb|\if| est une séquence de contrôle ou un caractère actif rendu \idx\let-égal à un \verb|<token>|, \verb|\if| prend en compte le code de caractère du \verb|<token>|.

Si un token testé par \verb|\if| est une séquence de contrôle, son code de caractère est vu égal à 256.
\end{regle}

\showcode/1) \def\foo{xxy}\def\bar{aab}
   \if\foo\bar vrai\else faux\fi\qquad
2) \if aA vrai\else faux\fi\qquad% "a" et "A" n'ont pas les mêmes charcode
3) \if\relax\noexpand\foo vrai\else faux\fi\qquad% \relax et \foo ont un charcode=256¤\idx*\noexpand¤
4) \let\foo=&\if\foo &vrai\else faux\fi\qquad% \foo est vue comme "&"
5) \if\string~\noexpand~vrai\else faux\fi¤\idx*\string\cidx*\~¤/

\begin{exercice}\label{ifcs.la.vraie}
Utiliser le test \verb|\if| pour que la macro §\ifcs[|(]\verb|<token>{<vrai>}{<faux>}| vue précédemment ne renvoie \verb|<vrai>| que si le \verb|<token>| est une séquence de contrôle, c'est-à-dire lorsqu'il commence par le caractère d'échappement.
\solution
Il est inévitable que nous allons devoir tester le caractère d'échappement. Pour cela, nous allons ouvrir un groupe semi-simple et imposer un caractère d'échappement avec \idx\escapechar. Nous le prendrons égal à «\verb|@|» mais tout autre choix conviendrait; l'essentiel est de se prémunir d'un régime spécial où l'\idx\escapechar serait négatif ou nul. Il suffit ensuite de tester si les deux caractères qui se trouvent au début de «\idx\string\verb|#1a|» (le «\verb|a|» protège d'un argument vide) et «\idx\string\idx\relax» sont les mêmes. Après avoir fermé le groupe, les classiques §\firstoftwo ou §\secondoftwo renvoient \verb|<vrai>| ou \verb|<faux>|. Pour isoler le premier caractère d'une chaine arbitraire, la macro §\firstto@nil sera utilisée.

\showcode/\catcode`\@11
\def\ifcs#1{%¤§*\ifcs¤
	\begingroup¤\idx*\begingroup¤
		\escapechar=`\@ % prend "@" comme caractère d'échappement¤\idx*\escapechar¤
		\if% les premiers caractères de
			\expandafter\firstto@nil\string#1a\@nil% "#1a"¤§*\firstto@nil\idx*\string¤
			\expandafter\firstto@nil\string\relax\@nil% et "\relax" sont-ils égaux ?¤\idx*\string§*\firstto@nil¤
			\endgroup\expandafter\firstoftwo% si oui, fermer le groupe et renvoyer "vrai"¤§*\firstoftwo\idx*\endgroup¤
		\else% sinon, fermer le groupe et renvoyer "faux"
			\endgroup\expandafter\secondoftwo¤§*\secondoftwo¤
		\fi
}
\catcode`\@12
1) \def\foo{bar}\ifcs\foo{vrai}{faux}\qquad
2) \ifcs\def{vrai}{faux}\qquad
3) \ifcs A{vrai}{faux}\qquad
\catcode`\*=13 
4) \let*=W \ifcs*{vrai}{faux}\qquad
5) \let*=\relax \ifcs*{vrai}{faux}\qquad
6) \let\foo=A \ifcs\foo{vrai}{faux}\qquad
7) \ifcs\bgroup{vrai}{faux}¤\idx*\bgroup¤/
§*\ifcs[|)]\end{exercice}\tidx*[|)]{if}

\subsection{Test incomplets}\idx*[|(]{test incomplet}
Entrons à présent au plus profond de la mécanique \TeX ienne des tests et examinons les tests incomplets. Un test est dit incomplet lorsque les choses à comparer sont en nombre insuffisant et font intervenir les primitives du test lui-même, à savoir \tidx[|etc]{else} et \tidx[|etc]{fi}.
\grandsaut

Demandons-nous quelle est la comparaison faite dans ce test :

\centrecode-\ifx a\fi-

\noindent Si l'on s'en tient à la définition de \tidx{ifx}, le «\verb|a|» est comparé au \verb|\fi| mais ce même \verb|\fi|, capturé par la comparaison et dès lors indisponible, ne casse-t-il pas l'équilibrage entre le \tidx{ifx} et le \verb|\fi| ?

Dans le même ordre d'idée, que se passe-t-il lors de ce test ?

\centrecode-\ifnum1=2\else3\fi 4-

\noindent Lorsque le \verb|2| est lu, \TeX{} est en train de lire un nombre et se trouve donc en phase de \idx{développement maximal}. Va-t-il développer le \verb|\else|, puis lire \verb|3| puis poursuivre son développement et manger le \verb|\fi|? Ensuite, continue-t-il son développement plus loin avec le 4 et avec ce qui se trouve après ? Le \verb|\else| et le \verb|\fi|, mangés par la lecture du nombre, rompent-ils l'équilibrage entre le \tidx{ifnum} et le \verb|\fi| ?

\idx*[!spécial|(]{\relax}\begin{regle}
\relax Lorsqu'un \verb|\else| ou un \verb|\fi| apparié avec un test est rencontré lors de l'évaluation de ce test, \TeX{} insère un \verb|\relax| spécial afin que le \verb|\else| ou le \verb|\fi| demeurent hors de l'évaluation faite par le test.
\end{regle}

Ainsi, le test «\verb|\ifx a\fi|» devient «\verb|\ifx a|\boxtoken\relax\verb|\fi|» où le \boxtoken\relax est un \idx\relax spécial inséré par \TeX{} et qui sera comparé avec «\verb|a|». De même, le test «\verb|\ifnum1=2\else3\fi|» devient «\verb|\ifnum1=2|\boxtoken\relax\verb|\else3\fi|» où le \idx\relax spécial interrompt la lecture du nombre 2.
\grandsaut

Voici comment définir une macro §\specialrelax dont le texte de remplacement est un \idx\relax spécial :

\centrecode-\edef\specialrelax{\ifnum1=1\fi}-

\noindent Ici, un \boxtoken\relax sera inséré avant le \verb|\fi| et comme le test est vrai, ce \boxtoken\relax sera tout ce qui reste dans la branche du test.

\showcode/\edef\specialrelax{\ifnum1=1\fi}¤§*\specialrelax¤
\meaning\specialrelax¤\idx*\meaning¤/

Pourquoi dit-on \idx\relax \emph{spécial} et non pas \idx\relax tout court ? Les \idx\relax spéciaux insérés par \TeX{} sont différents des \idx\relax ordinaires lus dans le code source aux yeux de \TeX{} lui-même. En voici la preuve :

\showcode/\edef\specialrelax{\ifnum1=1\fi}% texte de remplacement = \relax spécial¤§*\specialrelax¤
\edef\normalrelax{\relax}% texte de remplacement = \relax normal
\meaning\specialrelax\par¤\idx*\meaning¤
\meaning\normalrelax\par
Les 2 \string\relax{} sont \ifx\specialrelax\normalrelax identiques\else différents\fi.¤\idx*\string§*\specialrelax¤/

 Ils sont différents car \boxtoken\relax n'est \emph{pas} une primitive. C'est un token interne défini dans le programme \texttt{tex} lui-même qui se donne l'apparence de \idx\relax mais qui est codé en dur et qui n'est pas modifiable par l'utilisateur. Autant on pourrait vivre dangereusement et redéfinir la primitive \idx\relax, autant il est impossible de redéfinir \boxtoken\relax :

\errcode/\edef\specialrelax{\ifnum1=1\fi}¤§*\specialrelax¤
\expandafter\def\specialrelax{foobar}% redéfinition un \relax spécial¤§*\specialrelax¤/{Missing control sequence inserted}%
\idx*[!spécial|)]\relax\idx*[|)]{test incomplet}

\section{Tests successifs}
\subsection{Programmation du test \texttt{\textbackslash ifnumcase}}§*\ifnumcase[|(]%
Nous avons vu le test \tidx{ifcase}\verb|<nombre>|, cousin de \tidx{ifnum}, qui permettait de décider que faire selon des valeurs entières du \verb|<nombre>|. L'inconvénient est que ces valeurs doivent commencer à 0 et se suivre de 1 en 1. Cette contrainte rend ce test inutilisable si l'on souhaite tester si le \verb|<nombre>| est successivement égal à des valeurs non consécutives et distantes les unes des autres. L'idée est donc de créer un test qui décide que faire selon des valeurs entières précisées par l'utilisateur (par exemple $-5$, 14, $-16$, 20) et offrir une branche facultative §\elseif où un code alternatif sera exécuté si aucune égalité n'a été rencontrée.

Nous allons nous fixer la syntaxe suivante :

\centrecode/\ifnumcase{<nombre>}%
	{<valeur 1>}{<code 1>}
	{<valeur 2>}{<code 2>}
	...
	{<valeur n>}{<code n>}
\elseif
	<code alternatif>
\endif¤§*\endif¤/

Le §\elseif et le \verb|<code alternatif>| qui le suit sont facultatifs.

De plus, nous allons nous imposer une contrainte : lorsqu'un \verb|<code>| est exécuté, il doit pouvoir accéder aux tokens qui suivent le §\endif. Autrement dit, ce \verb|<code>| doit être exécuté à la toute fin du traitement, juste avant que la macro ne rende la main.

L'idée directrice est de lire tout d'abord le \verb|<nombre>| puis de passer la main à une macro récursive qui va lire ensuite \emph{un seul} argument. Si cet argument est :

\begin{itemize}
	\item une \verb|<valeur k>|, lire le \verb|<code k>| et l'exécuter si le test est vrai après avoir tout mangé jusqu'au §\endif. S'il est faux, recommencer;
	\item §\elseif, aucun test n'a été vrai et il faut exécuter le \verb|<code alternatif>| après avoir tout mangé jusqu'au §\endif;
	\item §\endif, cela signifie la fin du processus et correspond au cas où §\elseif n'est pas présent et aucun test n'a été vrai.
\end{itemize}

Comme nous ne savons pas encore tester si un argument est une \verb|<valeur>| (c'est-à-dire un entier), nous allons d'abord tester si l'argument est §\elseif puis s'il est §\endif et si les deux tests précédents sont négatifs, nous considèrerons que c'est un entier.

Afin d'être propre dans la programmation, l'ensemble du processus se déroulera dans un groupe semi-simple. Il conviendra de le fermer au bon moment. Pour faciliter la comparaison avec \tidx{ifx}, les macros §\elseif et §\endif seront des \idx[|(]{quark}s locaux à ce groupe.

\begin{algo}
	\item ouvrir un groupe, lire le \verb|<nombre>|, définir les quarks \verb|\elseif| et \verb|\endif|;
	\item lire le premier argument $x$ qui suit ;
	\begin{algo}
		\item si $x={}$§\elseif, fermer le groupe et exécuter tout ce qui reste jusqu'à §\endif ;
		\item sinon
		\begin{itemize}
			\item si $x={}$§\endif fermer le groupe;
			\item sinon, cela signifie que $x$ est une \verb|<valeur>|
			\begin{algo}%[label=(\roman*)]
				\item si $x={}$\verb-<nombre>-, fermer le groupe, exécuter l'argument suivant après voir tout supprimé tout jusqu'à §\endif ;
				\item si $x\neq{}$\verb-<nombre>-, manger l'argument suivant et retourner en 2.
			\end{algo}
		\end{itemize}
	\end{algo}
\end{algo}

Nous aurons besoin d'une macro auxiliaire récursive pour le point 2 ainsi que d'une macro auxiliaire qui s'occupe du point 2a que nous appellerons \verb|\idto@endif| :

\centrecode-\def\idto@endif#1\endif{#1}-§*\endif

\noindent et d'une autre pour le point 2bi) que nous appellerons \verb|\firstto@endif|. Elle sera chargée de lire l'argument suivant (argument non délimité \verb|#1|) et de lire tout ce qui se trouve jusqu'au §\endif (qui sera un argument délimité). Son texte de remplacement sera le premier argument :

\centrecode-\def\firstto@endif#1#2\endif{#1}-§*\endif

Voici le code :

\showcode/\catcode`\@11
\def\ifnumcase#1{%¤§*\ifnumcase¤
	\begingroup¤\idx*\begingroup¤
	\def\elseif{\elseif}\def\endif{\endif}% définir deux "quarks" locaux¤§*\elseif§*\endif¤
	\def\nombre@{#1}% stocker le nombre à comparer dans \nombre@
	\ifnumcase@i% appeller la macro récursive
}

\def\ifnumcase@i#1{%
	\def\nxt@arg{#1}% stocker l'argument suivant
	\ifx\nxt@arg\elseif% si c'est \elseif¤§*\elseif¤
		\def\next@todo{\endgroup\idto@endif}% fermer le groupe et aller à \idto@endif
	\else
		\ifx\nxt@arg\endif% si c'est \endif¤§*\endif¤
			\let\next@todo\endgroup% fermer le groupe
		\else
			\ifnum\nombre@=\nxt@arg% s'il y a égalité
				\def\next@todo{\endgroup\firstto@endif}% fermer le groupe puis \firstto@endif
			\else% sinon
				\let\next@todo=\ifnumcase@ii% aller à \ifnumcase@ii
			\fi
		\fi
	\fi
	\next@todo% exécuter l'action décidée ci-dessus
}

\def\ifnumcase@ii#1{\ifnumcase@i}
\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\swaptwo#1#2{#2#1}¤§*\swaptwo¤
\def\testenombre#1{%
	\ifnumcase{#1}
		{1}{C'est "un" et je prends le premier argument: \firstoftwo}¤§*\firstoftwo¤
		{3}{J'ai vu un "trois" et je mange les deux arguments : \gobtwo}¤§*\gobtwo¤
		{15}{L'argument est "15" et je prends le second argument : \secondoftwo}¤§*\secondoftwo¤
	\elseif¤§*\elseif¤
		ni 1, ni 3, ni 5 et j'inverse les deux arguments : \swaptwo¤§*\swaptwo¤
	\endif¤§*\endif¤
}
\testenombre{3}{foo}{bar}\par
\testenombre{16}{foo}{bar}\par
\testenombre{15}{foo}{bar}\par
\testenombre{1}{foo}{bar}/

Pour mettre en évidence que chaque \verb|<code>| a accès à ce qui se trouve immédiatement après le §\endif, les macros §\firstoftwo, §\secondoftwo sont appelées à la fin des \verb|<code>| pour qu'elles agissent sur les arguments qui suivent le §\endif. Une nouvelle macro §\swaptwo qui inverse l'ordre des deux arguments suivants est également utilisée.

\begin{exercice}
En l'état, la macro §\ifnumcase n'est pas purement développable, c'est-à-dire qu'on ne peut pas la mettre dans un \idx\edef. Comment pourrait-on la modifier pour qu'elle le devienne (à condition bien sûr que les \verb|<code>| le soient) ?
\solution
Les primitives non développables doivent être supprimées : \idx\begingroup, \idx\endgroup, \idx\def et \idx\let. Il n'y aura plus de groupe semi-simple et les \idx{quark}s seront donc définis de façon globale, à l'extérieur de la macro §\ifnumcase.

Dans les branches des tests de \verb|\ifnumcase@i|, nous pouvons facilement nous passer de la macro \verb|\next@todo| à condition de recourir aux macros §\firstoftwo et §\secondoftwo qui rejettent hors des branches les codes exécutés selon l'issue du test. En revanche, il est plus difficile de se passer de \verb|\nombre@| qui a stocké le \verb|<nombre>| dans la macro chapeau. La seule alternative est de passer le \verb|<nombre>| comme argument supplémentaire à la macro récursive.

Le code tend à se simplifier : l'essentiel est désormais fait par la macro récursive §\ifnumcase qui à chaque fois, va lire le même premier argument (le \verb|<nombre>|) ainsi qu'un second argument qui devra être testé pour décider que faire. Dans le cas où ce second argument est une \verb|<valeur>|, il faudra aller lire le \verb|<code>| correspondant, soit pour l'exécuter, soit pour le manger avant de repartir pour un tour.

\showcode/\catcode`\@11
\def\endif{\endif}\def\elseif{\elseif}% définit les quarks¤§*\elseif§*\endif¤

\def\ifnumcase#1#2{% #1=<nombre>   #2=prochain argument
	\ifx\elseif#2% si #2 est \elseif¤§*\elseif¤
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\firstoftwo§*\secondoftwo¤
		\idto@endif% aller à \idto@endif, sinon :
		{\ifx\endif#2% si #2 est \endif¤§*\endif¤
		\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\secondoftwo¤
			{}% ne rien faire. Sinon #2 est une <valeur i>:
			{\ifnum#1=#2 % s'il y a égalité entre <nombre> et <valeur i>
			\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\secondoftwo¤
				\firstto@endif% aller à \firstto@endif
				{\ifnumcase@i{#1}}% sinon aller à \ifnumcase@i
			}%
		}%
}

\def\ifnumcase@i#1#2{% #1=<nombre>  #2=<code i> à suivre qui est mangé
	\ifnumcase{#1}% retourner à \ifnumcase en transmettant #1
}

\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\swaptwo#1#2{#2#1}¤§*\swaptwo¤
\def\testenombre#1{%
	\ifnumcase{#1}
		{1}{C'est "un" et je prends le premier argument: \firstoftwo}¤§*\firstoftwo¤
		{3}{J'ai vu un "trois" et je mange les deux arguments : \gobtwo}¤§*\gobtwo¤
		{15}{L'argument est "15" et je prends le second argument : \secondoftwo}¤§*\secondoftwo¤
	\elseif¤§*\elseif¤
		ni 1, ni 3, ni 5 et j'inverse les deux arguments : \swaptwo¤§*\swaptwo¤
	\endif¤§*\endif¤
}
\testenombre{3}{foo}{bar}\par
\testenombre{16}{foo}{bar}\par
\testenombre{15}{foo}{bar}\par
\edef\macro{\testenombre{1}{foo}{bar}}\meaning\macro/
\idx*[|)]{quark}§*\ifnumcase[|)]\end{exercice}

\subsection{Programmation du test \texttt{\textbackslash ifxcase}}§*\ifxcase[|(]%
Il ne nous reste plus qu'à faire la même chose avec le test \tidx{ifx} en programmant une macro \verb|\ifxcase| dont voici la syntaxe :

\centrecode/\ifxcase <token>
	<token 1>{<code 1>}
	<token 2>{<code 2>}
	...
	<token n>{<code n>}
\elseif%¤§*\elseif¤
	<code alternatif>
\endif¤§*\endif¤/

\noindent qui compare successivement \verb|<token>| avec \verb|<token 1>|, \verb|<token 2>|, etc, où les comparaisons sont faites au sens de \tidx{ifx}. Si un des tests est positif, le \verb|<code i>| correspondant sera exécuté et sinon, ce qui se trouve après la macro facultative §\elseif le sera.

Il n'y a rien de bien difficile, il suffit de recopier le code de §\ifnumcase en remplaçant le test \tidx{ifnum} par \tidx{ifx}: \label{ifxcase}

\showcode/\catcode`\@11
\def\endif{\endif}\def\elseif{\elseif}%¤§*\elseif§*\endif¤
\def\ifxcase#1#2{% #1=<token>   #2=prochain argument
	\ifx\elseif#2% si #2 est \elseif¤§*\elseif¤
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\firstoftwo§*\secondoftwo¤
		\idto@endif% aller à \idto@endif, sinon :
		{\ifx\endif#2% si #2 est \endif¤§*\endif¤
		\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\secondoftwo¤
			{}% ne rien faire. Sinon #2 est un <token i>:
			{\ifx#1#2% s'il y a égalité entre <token> et <token i>
			\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤§*\secondoftwo¤
				\firstto@endif% aller à \firstto@endif
				{\ifxcase@i{#1}}% sinon aller à \ifnumcase@i
			}%
		}%
}
\def\ifxcase@i#1#2{% #1=<token>  #2=<code i> à suivre (qui est mangé)
	\ifxcase{#1}% retourner à \ifxcase en transmettant #1
}
\def\idto@endif#1\endif{#1}
\def\firstto@endif#1#2\endif{#1}
\catcode`\@12
\def\testtoken#1{%¤§*\testtoken¤
	\ifxcase{#1}
		a{Le token est "a"}
		+{J'ai vu un "+"}
		\relax{L'argument est "\string\relax"}¤\idx*\string¤
	\elseif¤§*\elseif¤
		Tous les tests sont négatifs%
	\endif¤§*\endif¤
}
1) \testtoken a\par
2) \let\foo=a\testtoken\foo\par
3) \testtoken+\par
4) \testtoken\relax\par
5) \edef\foo{\testtoken\relax}\meaning\foo\par¤\idx*[|etc]\meaning\forbidindex\meaning¤
6) \edef\foo{\testtoken W}\meaning\foo¤§*\testtoken¤/

On constate aux cas \nos1 et 2 que le test est positif aussi bien lorsque le \verb|<token>| est un «\verb|a|» explicite que lorsqu'il est une macro \idx\let-égale au caractère «\verb|a|».§*\ifxcase[|)]%

\chapter{Une boucle « loop repeat »}
\section{Implémentation de plain-\TeX}
Plain-\TeX{} définit lui-même sa boucle « \idx\loop\ldots\idx\repeat » dont voici l'implémentation telle qu'elle a été écrite par \idx*{Knuth Donald}D.~\textsc{Knuth} :

\centrecode-\def\loop#1\repeat{\def\body{#1}\iterate}¤\idx*\iterate\idx*\loop¤
\def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}
\let\repeat=\fi-

Il est clair que la macro \idx\loop est à argument délimité (le délimiteur est \idx\repeat) et stocke dans la macro \idx\body tout ce qui se trouve entre \idx\loop et \idx\repeat (que l'on appelle « corps de la boucle») avant d'appeler la macro \idx\iterate. On remarque également qu'aucune macro n'est déclarée \idx\long et donc il faudra proscrire la primitive \idx[|etc]\par\forbidindex\par{} entre \idx\loop et \idx\repeat. Ensuite, l'idée est que ce qui se trouve entre \idx\loop et \idx\repeat, stocké dans \idx\body, \emph{doit} contenir un test. Ce test, s'il est positif, autorisera la boucle exécuter une itération de plus tandis que s'il est négatif, il constitue la \emph{condition d'arrêt} de la boucle qui lui commande de s'arrêter. Cela suppose que le corps de la boucle modifie un paramètre pris en compte par le test afin que ce dernier devienne à un moment négatif pour permettre la sortie de la boucle et éviter ainsi une boucle infinie.

Le mécanisme est assez facile à saisir : ce test sera exécuté lorsque \idx\iterate puis \idx\body seront développés. Si ce test est positif, \verb|\next| est rendue \idx\let-égale à \idx\iterate et sinon, elle est rendue \idx\let-égale à \idx[|etc]\relax\forbidindex\relax. Cette macro \verb|\next| est ensuite appelée après être sorti du test, ce qui rend la récursivité terminale\idx*{récursivité!terminale}.

La structure de la boucle est donc la suivante :

\centrecode-\loop
	<code a>
	<test>
	<code b>
\repeat-

\noindent où les \verb|<code a>| et \verb|<code b>| sont facultatifs, c'est-à-dire que l'un ou l'autre peuvent être réduit à 0 token. Il est en revanche important de comprendre que \verb|<code a>| est toujours exécuté au moins une fois puisqu'il vient avant le test.

De par sa construction, il est également important de remarquer que ce qui se trouve entre \idx\loop et \idx\repeat ne doit pas contenir un test accompagné d'un \verb|\else| puisqu'un \verb|\else| est déjà écrit en dur dans la macro \idx\iterate. Si l'utilisateur écrivait un \verb|\else| par mégarde, cela provoquerait une erreur de type «\verb|extra \else|» lorsque \TeX{} atteindrait le second \verb|\else|. Malgré cette petite contrainte, cette structure est très souple du fait que le test peut se trouver où l'on veut entre \idx\loop et \idx\repeat.

Enfin, on constate à la dernière ligne que \idx\repeat est rendu \idx\let-égal à \verb|\fi| ce qui a pour conséquence que \idx\repeat sera vu par \TeX{} comme un \verb|\fi| et donc pris en compte lors du comptage interne de \TeX{} des tests, \verb|\else| et des \verb|\fi|. En d'autres termes, le \idx\repeat sera bien apparié avec le \verb|<test>| se trouvant entre \idx\loop et \idx\repeat et par conséquent, la boucle peut être mise dans les branches d'un test sans provoquer de mauvais appariements entre les tests et les \verb|\fi|. Une structure de ce type est donc tout à fait envisageable :

\centrecode-<test>
	<code 1>
	\loop
		...
	\repeat
	<code 2>
\else
	<code 3>
	\loop
		...
	\repeat
	<code 4>
\fi-

Voici à titre d'exemple comment on peut programmer la macro §\compte vue dans un exercice du chapitre~\ref{compte} :

\showcode/\newcount\xx % définit un compteur utilisé dans la boucle¤\idx*\newcount¤
\def\compte#1{%¤§*\compte¤
	\xx=0 % initialise le compteur
	\loop% début de la boucle¤\idx*\loop¤
		\advance\xx1 % incrémente le compteur¤\idx*\advance¤
		\ifnum\xx<#1 % s'il est inférieur à la borne
		  \number\xx , % affiche le nombre et la virgule¤\idx*[|etc]\number\forbidindex\number¤
	\repeat% et recommence¤\idx*\repeat¤
	\ifnum#1>0 \number\xx\relax\fi% si le nombre #1 est >0, afficher le dernier nombre
	}
a) \compte{1}.\qquad b) \compte{-3}.\qquad c) \compte{7}.¤§*\compte¤/

\section{Implémentation de \LaTeX}
Le \idx[!\LaTeX]{format}\LaTeX{} redéfinit la boucle \idx\loop\ldots\idx\repeat de cette façon :

\centrecode-\long\def\loop#1\repeat{%¤\idx*\long\idx*\loop\idx*\repeat¤
  \def\iterate{#1\relax\expandafter\iterate\fi}%¤\idx*\iterate¤
  \iterate
  \let\iterate\relax}¤\idx*\iterate¤
\let\repeat=\fi-

La macro \idx\loop est déclarée \idx\long et l'on fait l'économie de la macro \idx\body en déclarant \idx\iterate comme une « sous-macro » de \idx\loop de telle sorte que l'argument \verb|#1| lui soit accessible. En considérant que \verb|#1| contient un test, on voit clairement que ce test peut être accompagné d'un \verb|\else| puisque le code de la macro \idx\iterate ne comporte pas cette primitive mais seulement un \verb|\fi|. Le plus simple est de faire fonctionner la boucle dans les cas où son corps contient un \verb|\else| ou pas :\medbreak

\noindent
\begin{minipage}[t]{.5\linewidth}
\footnotesize
\hfill Sans \verb|\else|\hfill\null
\centrecode-\loop
	<code a>
	<test>
		<code b>
\repeat-
\end{minipage}%
\begin{minipage}[t]{.5\linewidth}
\footnotesize
\hfill Avec \verb|\else|\hfill\null
\centrecode-\loop
	<code a>
	<test>
		<code b>
	\else
		<code c>
\repeat-
\end{minipage}\medbreak

Voilà ce qui est stocké dans la macro \idx\iterate dans chaque cas :\medbreak

\noindent
\begin{minipage}[t]{.5\linewidth}
\footnotesize
\hfill Sans \verb|\else|\hfill\null
\centrecode-<code a>
<test>
	<code b>\relax
	\expandafter\iterate
\fi-
\end{minipage}%
\begin{minipage}[t]{.5\linewidth}
\footnotesize
\hfill Avec \verb|\else|\hfill\null
\centrecode-<code a>
<test>
	<code b>
\else
	<code c>\relax
	\expandafter\iterate
\fi-
\end{minipage}\medbreak

Il est maintenant facile de constater que si le corps de la boucle contient un \verb|\else|, c'est la branche du test négatif (après le \verb|\else|) qui maintiendra la récursivité. En revanche, s'il n'y a pas de \verb|\else|, c'est la branche du test positif qui la maintient. Autrement dit, la condition d'arrêt est un test \emph{négatif} s'il n'y a pas de \verb|\else| alors que c'est un test \emph{positif} s'il y en a.

Malgré ce petit manque de cohérence, on peut dire que l'implémentation \LaTeX{} est supérieure à celle de plain-\TeX{} puisque la souplesse de pouvoir mettre de \verb|\else| dans la boucle rend parfois service, sans compter que l'on peut également faire appel à \tidx{unless} pour échanger les branches du test.

\section{Imbrications de boucles}
Malgré leur côté pratique, ni l'implémentation \TeX{} ni celle de \LaTeX{} ne permettent l'imbrication de boucles \idx\loop\ldots\idx\repeat, principalement à cause de deux choses :

\begin{itemize}
	\item si deux boucles étaient imbriquées, le \idx\repeat de la boucle intérieure serait pris comme fin de la boucle extérieure puisqu'avec les arguments délimités, la première occurrence du délimiteur est prise en compte ;
	\item la macro \idx\iterate serait redéfinie par la boucle intérieure.
\end{itemize}

Avec la syntaxe actuelle, aucune implémentation facile à programmer et n'utilisant pas de groupe permet d'imbriquer des boucles \idx\loop \idx\repeat n'est faisable. La difficulté est de trouver ce qui se trouve entre un \idx\loop et son \idx\repeat apparié ! Nous allons donc tenter de bâtir une boucle §\xloop\verb|...|§\xrepeat, fonctionnant de la même façon que \verb|\loop...\repeat| sauf que l'imbrication des boucles sera possible.

Pour commencer, nous allons nous attacher à collecter le code compris entre un §\xloop et son §\xrepeat apparié. Ce code sera stocké dans la macro \verb|\xiterate| et simplement \emph{affiché}  :

\begin{algo}
	\item définir un compteur \verb|\cnt@repeat| qui comptabilisera les occurrences de §\xrepeat rencontrées, et l'initialiser à 0. Initialiser \verb|\xiterate| à vide;
	\item ajouter à \verb|\xiterate| tout le code qui se trouve jusqu'au prochain §\xrepeat;
	\item stocker dans \verb|\cnt@loop| le nombre de fois que §\xloop est contenu dans le texte de remplacement de \verb|\xiterate|;
	\item tester si \verb|\cnt@loop|${}={}$\verb|\cnt@repeat|;
	\begin{algo}
		\item si le test est positif, afficher le texte de remplacement de \verb|\xiterate| à l'aide \idx\detokenize;
		\item sinon, incrémenter \verb|\cnt@repeat|, ajouter §\xrepeat à \verb|\xiterate| et retourner en 2.
	\end{algo}
\end{algo}

Voici un code \TeX{} qui transcrit cet algorithme, où nous nous servons des macros §\addtomacro et §\ifin vues précédemment. Nous utiliserons aussi la macro \verb|\cnttimestocs| vue dans la solution à la page~\pageref{cnttimes} :

\showcode/\catcode`\@11
\newcount\cnt@repeat % définit le compteur de \xrepeat¤\idx*\newcount¤

\def\xloop{%¤§*\xloop¤
	\def\xiterate{}% initialiser \xiterate à vide
	\cnt@repeat\z@% initialiser le compteur de \xrepeat¤\idx*\z@¤
	\xloop@i% aller à la macro récursive
}

\long\def\xloop@i#1\xrepeat{%¤\idx*\long §*\xrepeat¤
	\addtomacro\xiterate{#1}% ajoute ce qui est avant le premier \xrepeat¤§*\addtomacro¤
	\exparg\cnttimestocs{\xiterate}\xloop\cnt@loop
	% combien de \xloop dans \xiterate¤§*\cnttimestocs¤
	\ifnum\cnt@loop=\cnt@repeat\relax
		\expandafter\firstoftwo\else\expandafter\secondoftwo¤§*\firstoftwo§*\secondoftwo¤
	\fi
		{% autant que de \xrepeat -> \detokenize pour afficher
		"\detokenize\expandafter{\xiterate}"%
		}
		{\addtomacro\xiterate\xrepeat% sinon, ajouter ce \xrepeat
		\advance\cnt@repeat by 1% incrémenter le compteutr de \xrepeat¤\idx*\advance¤
		\xloop@i% et chercher le prochain \xrepeat
		}%
}
\let\xrepeat\fi
\catcode`\@12
\xloop a\xloop b\xloop 12\xrepeat c\xrepeat \xloop X\xrepeat\xrepeat¤§*\xloop§*\xrepeat¤/

Cela fonctionne bien : tout ce qui se trouve entre le premier §\xloop et son §\xrepeat apparié (qui est le dernier ici) est bien affiché. Maintenant, au lieu de simplement détokénizer le texte de remplacement de \verb|\xiterate|, nous allons mimer avec cette macro ce que fait l'implémentation \LaTeX{}. De plus, au lieu d'écrire \verb|\xiterate|, il faudra écrire partout dans le code \verb|\xiterate@<n>| de telle sorte que les imbrications de boucles ne redéfinissent pas cette macro et aient chacune la leur. Le nombre \verb|<n>| est le compteur d'imbrications stocké dans le compteur \verb|\cnt@nested|. Celui-ci est initialisé à 0 en dehors de toute macro, incrémenté à chaque fois que §\xloop est rencontré et décrémenté lors de la sortie de boucle.

Bien entendu, pour former la macro \verb|\xiterate@<n>|, il va falloir faire appel à la paire \idx\csname\ldots\verb|\endcsname| et donc, alourdir sensiblement le code :

\showcode/\catcode`\@11
\newcount\cnt@repeat¤\idx*\newcount¤
\newcount\cnt@nested
\cnt@nested=0 % compteur d'imbrications
\def\xloop{%¤§*\xloop¤
	\global\advance\cnt@nested by 1 % augmente le compteur d'imbrications¤\idx*\global\idx*\advance¤
	\expandafter\def\csname xiterate@\number\cnt@nested\endcsname{}%
	\cnt@repeat\z@% initialise le compteur de \xrepeat à 0¤\idx*\z@¤
	\xloop@i% aller à la macro \xloop@i
}
\long\def\xloop@i#1\xrepeat{%¤§*\xrepeat\idx*\long¤
	\expandafter\addtomacro\csname xiterate@\number\cnt@nested\endcsname{#1}%¤\defline\eee§*\addtomacro¤
	\expandafter\expandafter\expandafter\cnttimestocs\expandafter\expandafter\expandafter¤§*\cnttimestocs¤
		{\csname xiterate@\number\cnt@nested\endcsname}\xloop\cnt@loop¤\idx*\csname\idx*\endcsname¤
	\ifnum\cnt@loop=\cnt@repeat\relax
		\expandafter\firstoftwo\else\expandafter\secondoftwo¤§*\firstoftwo§*\secondoftwo¤
	\fi
		{\expandafter\eaddtomacro\csname xiterate@\number\cnt@nested\expandafter\endcsname¤\defline\bbb§*\eaddtomacro¤
			{\expandafter\expandafter\csname xiterate@\number\cnt@nested\endcsname\fi}%
		%\expandafter\show\csname xiterate@\number\cnt@nested\endcsname¤\defline\aaa\idx*\show¤
		\csname xiterate@\number\cnt@nested\endcsname¤\defline\ddd¤
		\letname{xiterate@\number\cnt@nested}\relax¤§*\letname¤
		\global\advance\cnt@nested by -1¤\defline\ccc\idx*\global\idx*\advance¤
		}
		{\expandafter\addtomacro\csname xiterate@\number\cnt@nested\endcsname\xrepeat¤§*\addtomacro§*\xrepeat¤
		\advance\cnt@repeat by 1 ¤\idx*\advance¤
		\xloop@i
		}%
}%
\let\xrepeat\fi¤§*\xrepeat¤
\catcode`\@12

\newcount\cntxx \cntxx=1 % compteur des lignes
\newcount\cntyy¤\idx*\newcount¤
\xloop¤§*\xloop¤
	\cntyy=1 % compteur des colonnes
	\xloop¤§*\xloop¤
		(\number\cntxx,\number\cntyy)% affiche "(ligne,colonne)"
		\ifnum\cntyy<5 % tant que colonne<5
		\advance\cntyy1 % incrémente colonne
		, % <- affiche ", "
	\xrepeat% et recommence
	\ifnum\cntxx<3 % tant que ligne<3
	\advance\cntxx1 % incrémente ligne
	\par % va à la ligne
\xrepeat% et recommence¤§*\xrepeat¤/

L'utilisation de \verb|\csname...\endcsname| rend la lecture du code bien plus difficile puisqu'elle implique le développement d'un pont d'\idx\expandafter pour faire naitre une macro puis pour accéder à son texte de remplacement d'une macro (lignes \nos\eee{} à \number\eee+3\relax). Malgré cela, intrinsèquement, le code est identique à celui vu précédemment. La seule différence se trouve entre les lignes \nos\bbb{} à \no\ccc. En effet, aux lignes \nos\bbb{}-\number\numexpr\bbb+1\relax{}, au lieu de détokénizer la macro \verb|\xiterate@<n>| pour simplement l'afficher comme on le faisait en analyse préalable, on ajoute au texte de remplacement de cette macro «\idx\expandafter» suivi du nom de la macro, c'est-à-dire \verb|\xiterate@<n>| que l'on fait suivre d'un \verb|\fi|. Ainsi, le texte de remplacement de \verb|\xiterate@<n>| est finalement :

\centrecode-<ce qui est entre \xloop et \xrepeat> \expandafter\xiterate@<n> \fi-

On peut d'ailleurs prendre connaissance du texte de remplacement de la macro \verb|\xiterate@<n>| en dé-commentant la ligne \no\aaa{} pour laisser à la primitive \idx\show l'écrire dans le \idx[!log]{fichier} \verb|log|. Pour \verb|\xiterate@1|, on obtient :

\centrecode|\xiterate@1=macro:->
\cntyy =1
\xloop¤§*\xloop¤
	(\number \cntxx ,\number \cntyy )
	\ifnum \cntyy <5 ,
	\advance \cntyy 1
\xrepeat¤§*\xrepeat¤
\ifnum \cntxx <3
	\advance \cntxx 1
	\par
	\expandafter\xiterate@1
\fi.|

\noindent et pour \verb|\xiterate@2| :

\centrecode|\xiterate@2=macro:->
(\number \cntxx ,\number \cntyy )
\ifnum \cntyy <5 ,
\advance \cntyy 1
	\expandafter\xiterate@2
\fi.|

\noindent C'est exactement ce que fait l'implémentation \LaTeX{} de la boucle \idx\loop\ldots\idx\repeat avec la macro \idx\iterate. En poursuivant le parallèle avec la boucle \LaTeX{}, il suffit ensuite de lancer la macro \verb|\xiterate@<n>| à la ligne \no\ddd{} et une fois la boucle terminée, on rend \verb|\iterate@<n>| \idx\let-égale à \idx\relax à la ligne \no\number\numexpr\ddd+1\relax. Le tout se termine avec la décrémentation du compteur d'imbrication à la ligne \no\ccc.

\chapter{Une boucle « foreach in »}\label{doforeach}
\section{Une première approche}
Nous allons construire une boucle où une « variable » --~qui sera comme précédemment une séquence de contrôle~-- prendra successivement toutes les valeurs d'une liste de valeurs, pas nécessairement numériques, séparées par des virgules et à chaque itération, un code sera exécuté. La syntaxe de cette boucle, initiée par la macro §\doforeach[|(], sera\footnote{La commande \texttt{\string\foreach} est définie par le \idx[!pgf]{package} «\texttt{pgf}» et pour éviter tout conflit, il vaut donc mieux choisir un autre nom.} :

\centrecode-\doforeach\<macro>\in{<valeur 1>,<valeur 2>,...,<valeur n>}{<code>}-

\noindent où bien entendu, le \verb|<code>| peut contenir la \verb|\<macro>|.

La méthode, relativement simple, va être de lire toutes les valeurs une première fois, y ajouter à la fin une valeur reconnaissable (un \idx{quark}) et par la suite, lire les valeurs une par une jusqu'à ce qu'apparaisse le \idx{quark}. Nous mettons ici en \oe uvre la méthode recommandée pour lire une série d'arguments (voir page~\pageref{lire.arguments}) :

\begin{algo}
	\item lire la liste des valeurs et lui ajouter «\verb-,\end@foreach,-», où \verb-\end@foreach- est un \idx{quark}.

	Sauvegarder le \verb|<code>| dans une macro (que nous appelons \verb|\loop@code|);
	\item lire la valeur qui se trouve avant la virgule et l'assigner à \verb|\<macro>| ,
	\item si \verb|\<macro>|=\verb-\end@foreach-, finir le processus ;
	\item sinon exécuter le \verb|<code>| et retourner en 2.
\end{algo}

Le point 1 sera dévolu à une macro chapeau chargée de faire les assignations préalables. Les autres points seront contenus dans une macro récursive à argument délimité. Choisissons d'externaliser la macro récursive (c'est-à-dire de la définir en dehors du texte de remplacement de la macro chapeau). Assurons-nous que la macro récursive peut accéder à tous les arguments de la macro chapeau. Aucun problème pour la liste des valeurs qu'elle lira comme argument au fur et à mesure. Le \verb|<code>| ne pose pas de problème puisqu'il est sauvegardé dans \verb|\loop@code|. La variable \verb|\<macro>| n'étant pas sauvegardée, prenons comme solution de la transmettre comme argument à la macro récursive : cette macro (qui n'est qu'un seul token) viendra comme premier argument non délimité, avant la liste des valeurs.

\showcode/\catcode`\@11
\def\end@foreach{\end@foreach}% définit un quark¤\idx*{quark}¤
\long\def\doforeach#1\in#2#3{%¤\idx*\long¤
	\def\loop@code{#3}% assigne le <code> à \loop@code
	% appel à \doforeach@i : mettre la macro #1 en premier, puis la liste de valeurs #2
	\doforeach@i#1#2,\end@foreach,% ajouter à la fin ",\end@foreach,"
	% une fois les boucles finies, neutraliser les macros déjà définies
	\let#1\relax \let\loop@code\relax
}

\long\def\doforeach@i#1#2,{% #1=\<macro>  #2=valeur courante¤\defline\aaa\idx*\long¤
	\def#1{#2}% stocke la valeur en cours dans la \<macro>
	\unless\ifx\end@foreach#1% si \end@foreach n'est pas atteint
		\antefi% amène le \fi ici¤§*\antefi¤
		\loop@code% exécute le code
		\doforeach@i#1% et recommencer
	\fi
}
\catcode`@12
\doforeach\x\in{a,bcd,{efg},hi}{\meaning\x.\par}/

La ligne \no\aaa{} montre que la macro \verb|\doforeach@i| admet comme argument \emph{non délimité} \verb|#1| alors que la valeur en cours est l'argument \verb|#2| délimité par la virgule. L'inconvénient, lié à la lecture d'argument, est que si une \verb|<valeur>| est constituée d'un texte entre accolades, ce texte est dépouillé de ses accolades et assigné à la variable. Si l'on souhaitait éviter cet écueil, il faudrait mettre un token (par exemple un \idx\relax) avant chaque \verb|<valeur>| et faire en sorte de manger ce \idx\relax avec \verb|\gobone| avant d'assigner la \verb|<valeur>| à la variable. Par souci de simplicité, cette man\oe uvre ne sera pas programmée.

\begin{exercice}
On pourrait vouloir modifier le séparateur de liste (qui est la virgule par défaut) pour mettre des nombres décimaux dans la liste d'arguments, par exemple.

Créer une macro §\defseplist dont l'argument est le séparateur voulu et modifier le code vu ci-dessus pour que la macro §\doforeach tienne compte du séparateur ainsi défini.
\solution
L'idée est de faire de §\defseplist\verb|<séparateur>| une macro «enveloppante» qui va définir, à chaque fois qu'elle sera appelée, les deux macros §\doforeach et \verb|\doforeach@i|, toutes les deux dépendantes de l'argument \verb|#1| de §\defseplist. Dans le code déjà vu, la virgule va être replacée par \verb|#1| et les autres «\verb|#|» qui s'appliquent aux arguments de §\doforeach et \verb|\doforeach@i| vont être doublés pour tenir compte de l'imbrication des macros :

\showcode/\catcode`\@11
\def\end@foreach{\end@foreach}
\def\defseplist#1{%¤§*\defseplist¤
	\long\def\doforeach##1\in##2##3{%¤\idx*\long¤
		\def\loop@code{##3}% assigne le <code> à \loop@code
		\doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller à \doforeach@i
		% après être sorti des boucles, neutraliser les macros déjà définies
		\let\loop@code\relax \let##1\relax
	}%
	\long\def\doforeach@i##1##2#1{%¤\idx*\long¤
		\def##1{##2}% stocke la valeur en cours dans la \<macro>
		\unless\ifx\end@foreach##1% si la fin n'est pas atteinte¤\tidx*{unless}¤
			\antefi% amène le \fi ici¤§*\antefi¤
			\loop@code% exécute le code
			\doforeach@i##1% et recommencer
		\fi
	}%
}
\defseplist{,}% définit les macros avec le séparateur par défaut¤§*\deseplist¤
\catcode`@12

\doforeach\x\in{a,bcd,efg}{Argument courant : "\x".\par}\medbreak¤\idx*\medbreak¤

\defseplist{--}% séparateur "--"¤§*\deseplist¤
\doforeach\nn\in{4,19--0,5--8,575}{Nombre lu : "\nn"\par}/
\end{exercice}

\section{Rendre possible l'imbrication}
Il nous reste à rendre possible l'imbrication de boucles §\doforeach et pour cela, comme précédemment avec §\for et §\xloop, nous allons définir un compteur qui sera chargé de compter le niveau d'imbrication et qui fera partie du nom de la macro chargée de stocker le \verb|<code>|. Nous prendrons «\verb|\loop@code@<n>|» :

\showcode/\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % définit et initialise le compteur d'imbrication¤\idx*\newcount¤
\def\end@foreach{\end@foreach}

\def\defseplist#1{%¤§*\deseplist¤
	\long\def\doforeach##1\in##2##3{%¤\idx*\long¤
		\global\advance\cnt@nest1 % entrée de boucle : incrémenter le compteur d'imbrication¤\idx*\global¤
		\defname{loop@code@\number\cnt@nest}{##3}% assigne le <code> à \loop@code@<n>¤§*\defname¤
		\doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller à \doforeach@i
		% une fois fini :
		\let##1\empty% dans ce cas, neutraliser les macros déjà définies¤\idx*\empty¤
		\letname{loop@code@\number\cnt@nest}\empty%¤§*\letname¤
		\global\advance\cnt@nest-1 %sortie de boucle : décrémenter le compteur d'imbrication¤\idx*\global\idx*\advance¤
	}%
	\long\def\doforeach@i##1##2#1{%¤\idx*\long¤
		\def##1{##2}% stocke la valeur en cours dans la \<macro>
		\unless\ifx\end@foreach##1% tant que la fin n'est pas atteinte¤\tidx*{unless}¤
			\antefi% amène le \fi ici¤§*\antefi¤
			\csname loop@code@\number\cnt@nest\endcsname% exécute le code¤\defline\aaa¤
			\doforeach@i##1% et recommencer
		\fi
	}%
}
\catcode`@12
\defseplist{,}¤§*\deseplist¤

\doforeach\xxx\in{1,2,3}{%
	Ligne \xxx{} : \doforeach\yyy\in{a,b,c,d,e}{(\xxx,\yyy)}.\par
}/

Profitons également de la simplicité relative de ce code pour implémenter une fonctionnalité qui pourrait être d'un grand secours. Si la « variable » est déjà définie lorsque la boucle est rencontrée, il serait judicieux de la sauvegarder pour la restaurer une fois la boucle terminée. Imaginons en effet qu'un utilisateur imprudent --~ou inconscient~-- nomme sa variable \idx\par par analogie avec le mot « paramètre » et construise une boucle de cette façon :

\centrecode-\doforeach\par\in{a,b,c,y,z}{$\par_i$}-

La primitive \idx\par serait silencieusement redéfinie à l'entrée de la boucle, pour être rendue \idx\let-égale à \idx\relax à la fin ce qui aurait pour effet de rendre \TeX{} incapable de former un paragraphe. On imagine les dégâts, d'autant plus incompréhensibles que le tout se passe silencieusement. Il nous faut donc tester si la variable existe au début de la boucle et si tel est le cas, la sauvegarder avec \idx\let pour la restaurer à la fin du processus.

Il existe un test \tidx{ifdefined}\verb|\<commande>| de \idx\eTeX qui est vrai si la \verb|\<commande>| est définie et faux sinon. Ce test ne modifie pas la table de hashage\footnote{Les tests \texttt{\textbackslash @ifundefined\{\codeelement{nom}\}} et \texttt{\textbackslash @ifdefinable\textbackslash\codeelement{nom}} de \LaTeX{} forment la séquence de contrôle \texttt{\textbackslash\codeelement{nom}} à l'aide de \texttt{\textbackslash csname} et testent si elle est égale à \texttt{\textbackslash relax} auquel cas, la séquence de contrôle est considérée non définie. Cette méthode présente deux gros inconvénients :
\begin{itemize}
	\item toute macro existante et \texttt{\textbackslash let}-égale à \texttt{\textbackslash relax} est considérée par ces tests comme étant non définie;
	\item par l'utilisation de \texttt{\textbackslash csname}, une macro non définie devient définie et \texttt{\textbackslash let}-égale à \texttt{\textbackslash relax}. Un autre dégât collatéral est que la table de hashage est modifiée puisqu'une nouvelle macro est créée.
\end{itemize}}. Il existe aussi un test de \idx\eTeX un peu similaire \tidx{ifcsname}\verb|<nom d'une commande>|\idx\endcsname, qui forme la \verb|<commande>| comme le ferait \idx\csname puis teste si elle existe, sans modifier la table de hashage.

La méthode sera ici de mettre à profit \tidx{ifdefined} pour tester si la variable existe et la sauvegarder dans \verb|\saved@var@<n>| si le test est positif. À la sortie de la boucle, il suffira de faire la man\oe uvre inverse pour restaurer la variable soit à \idx\relax, soit à ce qu'elle était avant si elle existait auparavant.

Dans le code ci-dessous, la variable a été nommée «\verb|\par|» ce qui est une chose à ne pas faire. Même si un dispositif a été prévu pour que \verb|\par| soit restaurée à la fin du processus, redéfinir une primitive, surtout aussi primordiale que \verb|\par|, \emph{est un danger qu'il faut à tout prix éviter de courir}.

\showcode/\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % définit et initialise le compteur d'imbrication¤\idx*\newcount¤
\def\end@foreach{\end@foreach}
\long\def\save@macro#1{% sauvegarde la macro #1¤\idx*\long¤
	\ifdefined#1% si la macro #1 est déjà définie...¤\tidx*{ifdefined}¤
		\letname{saved@var@\number\cnt@nest}#1% ...la sauvegarder¤§*\letname¤
	\fi
}
\long\def\restore@macro#1{% restaure la macro #1¤\idx*\long¤
% le \csname donne \relax si la sauvegarde n'a pas été faite
	\expandafter\let\expandafter#1\csname saved@var@\number\cnt@nest\endcsname
}
\def\defseplist#1{%¤§*\deseplist¤
	\long\def\doforeach##1\in##2##3{%¤\idx*\long¤
		\global\advance\cnt@nest1 % entrée de boucle : incrémenter le compteur d'imbrication¤\idx*\global\idx*\advance¤
		\save@macro##1% sauvegarde la macro ##1
		\defname{loop@code@\number\cnt@nest}{##3}% assigne le <code> à \loop@code@<n>¤§*\defname¤
		\doforeach@i##1##2#1\end@foreach#1% ajouter ",\end@foreach," et aller à \doforeach@i
		% une fois fini, neutraliser la macro contenant le <code>
		\letname{loop@code@\number\cnt@nest}\empty¤\idx*\empty§*\letname¤
		\restore@macro##1% restaurer la \<macro>
		\global\advance\cnt@nest-1 % et décrémenter le compteur d'imbrication¤\idx*\global¤
	}%
	\long\def\doforeach@i##1##2#1{%¤\idx*\long¤
		\def##1{##2}% stocke la valeur en cours dans la \<macro>
		\unless\ifx\end@foreach##1% si la fin n'est pas atteinte¤\tidx*{unless}¤
			\antefi% amène le \fi ici¤§*\antefi¤
			\csname loop@code@\number\cnt@nest\endcsname% exécute le code¤\defline\aaa¤
			\doforeach@i##1% et recommencer
		\fi%
	}%
}
\catcode`@12
\defseplist{,}¤§*\deseplist¤
\doforeach\par\in{a,b,c,y,z}{$\par_i$}

\meaning\par% \par doit être redevenu une primitive¤\idx*\meaning¤

\doforeach\xxx\in{1,2,3}{%
	Ligne \xxx{} : \doforeach\yyy\in{a,b,c,d,e}{(\xxx,\yyy)}.\par
}/

\section{Boucle à deux variables}
Une amélioration de la macro §\doforeach serait de détecter si la variable est seule, comme envisagé précédemment, ou si l'utilisateur souhaite avoir un \emph{couple} de variables auquel cas, il écrirait :

\centrecode-\doforeach\<macro1>/\<macro2>\in{x1/y1,x2/y2,...,xn/yn}{<code>}-

\noindent Chacune des variables \verb|\<macro1>| et \verb|\<macro2>| prendrait successivement les valeurs appariées spécifiées dans l'argument qui suit le \verb|\in|.

L'idée va être de se servir de la macro §\ifin vue précédemment pour tester si l'argument délimité par «\verb|\in|» contient le caractère «\verb|/|» et agir en conséquence. Si le test est positif, il faut s'orienter vers une macro à argument délimité du type \verb|#1/#2| qui sépare les deux variables. Nous allons donc, selon l'issue du test \verb|\ifin{#1}{/}|, nous orienter vers la macro vue précédemment si le test est négatif ou vers une macro \verb|\doforeach@ii| avec des arguments délimités appropriés. Nous allons profiter de cette nouvelle fonctionnalité pour améliorer et optimiser le code.
\grandsaut

En premier lieu, la macro \verb|\save@macro| effectuera \emph{dans tous les cas} la sauvegarde de la (ou des) variables avec \verb|\let|, que ces variables soient définies ou pas. La raison de ce choix, qui implique de se passer du test \tidx{ifdefined}, réside dans le fait que la variable est rendue \verb|\let|-égale à \idx\relax à la fin du processus : cela sera \emph{aussi} le cas si la variable est une macro indéfinie. En effet, si une macro $x$ est rendue \verb|\let|-égale à une macro $y$ non définie, $x$ devient également non définie. Par la suite, si $y$ est rendue \verb|\let|-égale à $x$ où la macro $x$ est construite via \idx\csname, la macro $y$ devient \verb|\let|-égale à \idx\relax

\showcode/\let\foo=\djfhdsldv% \foo est rendue \let-égale à une macro indéfinie
a) \meaning\foo\par
% puis \djfhdsldv est rendue \let-égale à \foo (ou \foo est construit avec \csname)
\expandafter\let\expandafter\djfhdsldv\csname foo\endcsname
b) \meaning\djfhdsldv/

L'optimisation que nous pouvons envisager est d'éviter que la macro  \idx\csname (qui est lente) ne se trouve dans une boucle comme c'était le cas à la ligne \no\aaa{} du code précédent. Pour cela, nous allons donner le code à exécuter comme argument des macros récursives. L'appel initial aux macros récursives aura donc la structure suivante :

\centrecode-\doforeach@i{<code>}<var>x1,x2,...,xn,<quark>,-

\noindent ou

\centrecode-\doforeach@ii{<code>}<var1>/<var2>x1/y1,x2/y2,...xn/yn,<quark>/<quark>,-

Ces macros ne liront à chaque itération que le \verb|<code>|, la (ou le couple de) variable(s), ainsi que la valeur courante \verb|xi| ou le couple de valeurs courant \verb|xi/yi|. Par conséquent, l'appel récursif sera de la forme

\begin{centrage}
	\small\verb|\doforeach@i{#1}#2|\quad ou\quad \verb|\doforeach@i{#1}#2/#3|
\end{centrage}

\noindent où \verb|#2| est la variable et \verb|#2/#3| est le couple de variables. Comme les récursivités sont terminales, les valeurs sont prises dans le code qui reste à lire.

Comme ces macros récursives effectuent un test \verb|\ifx| à chaque itération pour déterminer si le \idx{quark} marquant la fin des valeurs est atteint, nous devons nous garder de l'erreur qui consisterait à utiliser §\antefi alors que le \verb|<code>| se situe en §\antefi et \verb|\fi|. Il s'agirait d'une erreur, car si le \verb|<code>| contient un test, l'§\antefi (dont l'argument est délimité par \verb|\fi|) prendrait le \verb|\fi| du \verb|<code>| comme délimiteur et romprait l'appariement correct entre \verb|\ifx| et son \verb|\fi|.

Enfin, il nous faut inventer un moyen de créer la macro §\doforeachexit[|(], que l'utilisateur peut écrire dans le \verb|<code>| et qui termine prématurément toutes les boucles §\doforeach en cours d'exécution. Cette macro doit annuler l'appel récursif vu ci-dessus. L'idée directrice est de modifier ces appels récursifs de cette manière :

\begin{centrage}
	\small\verb|\allow@recurse{\doforeach@i{#1}#2}|\par ou\par \verb|\allow@recurse{\doforeach@i{#1}#2/#3}|
\end{centrage}

\noindent La macro \verb|\allow@recurse| sera rendue \idx\let-égale à §\identity au début de la boucle pour permettre par défaut que l'appel récursif se fasse. Si l'utilisateur insère §\doforeachexit dans le \verb|<code>|, \verb|\allow@recurse| doit être modifiée pour que cette dernière mange tout ce qui reste. « Tout » signifie l'appel récursif \emph{et} toutes les valeurs (ou couples de valeurs) restant à lire. Comme ce « tout» se termine forcément par le \idx{quark} \verb|\end@foreach| et le séparateur qui ont été insérés par l'appel initial, une macro \verb|\fordib@recurse| à argument délimité effectuant cette tâche est facile à créer :

\centrecode-\long\def\fordib@recurse##1\end@foreach#1{}-

\noindent Une fois tout ceci mis en place, la macro §\doforeachexit n'a plus qu'à rendre \verb|\allow@recurse| \idx\let-égale à \verb|\fordib@recurse|.

\showcode|\catcode`\@11
\newcount\cnt@nest \cnt@nest=0 % définit et initialise le compteur d'imbrication¤\idx*\newcount¤
\def\end@foreach{\end@foreach}
\long\def\save@macro#1#2{\letname{saved@var@\number\cnt@nest#1}#2}¤\idx*\long§*\letname¤
\long\def\save@macro@i#1/#2{\save@macro{a}#1\save@macro{b}#2}
\long\def\restore@macro#1#2{%¤\idx*\long¤
	\expandafter\let\expandafter#2\csname saved@var@\number\cnt@nest#1\endcsname
}
\long\def\restore@macro@i#1/#2{\restore@macro{a}#1\restore@macro{b}#2}¤\idx*\long¤
\def\defseplist#1{%¤§*\deseplist¤
	\long\def\doforeach##1\in##2##3{%¤\idx*\long §*\doforeach\idx*\long¤
		\global\advance\cnt@nest1 % entrée de boucle : incrémenter le compteur d'imbrication¤\idx*\global\idx*\advance¤
		\global\let\allow@recurse\identity% permet l'appel récursif plus bas¤\idx*\global§*\identity¤
		\ifin{##1}{/}% si ##1 contient "/"¤§*\ifin¤
			{\save@macro@i##1% sauvegarde les macros
			\doforeach@ii% appeler la macro récursive avec les arguments
				{##3}% 1) code à exécuter
				##1%   2) variables sous la forme \<macro1>/\<macro2>
				##2#1\end@foreach/\end@foreach#1% puis la liste ##2 suivie de
				                                % ",\end@foreach/\end@foreach,"
			\restore@macro@i##1% une fois sorti de toutes les boucles, restaurer les macros
			}% si ##1 ne contient pas "/"
			{\save@macro{}##1% sauvegarde la macro
			\doforeach@i% appeler la macro récursive
				{##3}% mettre en premier le <code>
				##1% puis la variable ##1 en 2e position
				##2#1\end@foreach#1% enfin la liste ##2 suivie de ",\end@foreach,"
			\restore@macro{}##1% une fois sorti de toutes les boucles, restaurer la macro
			}%
		\global\advance\cnt@nest-1 % décrémente le compteur d'imbrications¤\idx*\global\idx*\advance¤
	}%
	% ##1 = code à exécuter, ##2= variable, ##3=valeur courante
	\long\def\doforeach@i##1##2##3#1{%¤\idx*\long¤
		\ifx\end@foreach##3% si la fin est atteinte
		\expandafter\gobone\else\expandafter\identity\fi% manger sinon exécuter:¤§*\identity¤
			{\def##2{##3}% fait l'assignation à la variable
			##1% le code puis
			\allow@recurse{\doforeach@i{##1}##2}% recommencer
			}%
	}%
	% ##1 = code à exécuter, ##2/##3= variables, ##4/##5=valeurs courantes
	\long\def\doforeach@ii##1##2/##3##4/##5#1{%¤\idx*\long¤
		\ifx\end@foreach##4% si la fin est atteinte
		\expandafter\gobone\else\expandafter\identity\fi% manger sinon exécuter:¤§*\identity¤
			{\def##2{##4}\def##3{##5}% fait l'assignation des deux variables
			##1% le code puis
			\allow@recurse{\doforeach@ii{##1}##2/##3}% recommencer
			}%
	}%
	% macro qui, si elle remplace \allow@recurse, annule l'appel récursif
	\long\def\forbid@recurse##1\end@foreach#1{}% tout manger jusqu'à "\end@foreach,"¤\idx*\long\defline\aaa¤
}
\def\doforeachexit{\global\let\allow@recurse\forbid@recurse}¤\idx*\global¤
\catcode`\@12
\defseplist{,}¤§*\deseplist¤
\doforeach\par\in{a,b,c,y,z}{$\par_i$}\medskip¤\idx*\medskip¤

\doforeach\sujet/\terminaison\in{Je/e,Tu/es,Il/e,Nous/ons,Vous/ez,Ils/ent}
	{\sujet\ programm\terminaison{} en \TeX\par}\medskip¤\idx*\medskip¤

Les voyelles lues sont :
\doforeach\ii\in{a,e,i,o,u,y}{\ii\if o\ii\doforeachexit\fi}.\medskip¤\idx*\medskip¤

\doforeach\xx\in{a,b,c,d,e,f}
	{\doforeach\ii\in{1,2,3,4}{\xx\ii{} \ifnum\ii=3 \doforeachexit\fi}\par}|

\begin{exercice}
La dernière boucle imbriquée montre que §\doforeachexit sort prématurément de toutes les boucles en cours.

Comment faudrait-il modifier le code pour que §\doforeachexit ne sorte prématurément \emph{que} de la boucle dans laquelle elle a été appelée, sans modifier le déroulement des boucles de niveau supérieur ?
\solution
Il faut que \verb|\forbid@recurse|, en plus de manger tout jusqu'à la fin de la liste, rende de nouveau possibles les appels récursifs à venir dans d'éventuelles boucles mères. Par conséquent, elle doit redonner à \verb|\allow@recurse| l'équivalence avec §\identity qu'elle a par défaut. La ligne \no\aaa{} doit donc être

\centrecode-\long\def\forbid@recurse##1\end@foreach#1{\global\let\allow@recurse\identity}-\medskip
\end{exercice}§*\doforeach[|)]§*\doforeachexit[|)]%

\chapter{Dimensions et boites}\idx*[|(]{dimension}
Avec \TeX, tout ce qui touche de prés ou de loin à la typographie a une étroite proximité avec la géométrie et le placement des boites qui elles-mêmes, entretiennent de proches rapports avec les dimensions.

Le parti a été pris de présenter les dimensions (fixes et étirables) dans un premier temps, quitte à ce que cette théorie, dénuée des objets auxquels elle s'applique, soit un peu rébarbative. Une fois que ces outils et leurs propriétés ont été décrits, les boites et les réglures seront examinées dans un deuxième temps.

\section{Les dimensions fixes}\idx*[|(]{dimension fixe}
\idx*[!dimension|(]{registre}\begin{regle}
Une dimension fixe est utilisée pour mesurer une longueur prise au sens géométrique du terme. \TeX{} dispose de 256 \idx[!dimension]{registre}s de dimension (\numprint{32768} avec \idx\eTeX), chacun capable d'héberger une dimension. Pour faire référence à l'un de ces registres, on utilise la primitive \idx\dimen suivie de son numéro (sous la forme d'un \verb|<entier>|).

Il est possible de demander l'allocation d'un registre inutilisé avec la macro de plain-\TeX{} \idx\newdimen\verb|\<macro>|. La \verb|\<macro>|, définie en coulisse par la primitive \idx\dimendef avec

\centrecode-\global\dimendef\<macro>=<nombre>-

sera par la suite équivalente à \idx\dimen\verb|<nombre>| où le \verb|<nombre>| est celui du prochain registre libre au moment de l'allocation.

Un \verb|<registre de dimension>| est donc soit une \verb|\<macro>| préalablement définie à l'aide de \idx\newdimen, soit «\verb|\dimen<nombre>|» où \verb|<nombre>| est le numéro du registre de dimension auquel on souhaite faire référence.

Pour assigner une dimension à un registre de dimension, la syntaxe est

\centrecode-<registre de dimension>= <dimension>-

\noindent où le signe \verb|=| et l'espace qui le suit sont facultatifs. Pour lire la \verb|<dimension>|, le développement maximal se met en marche et après développement, une \verb|<dimension>| est :

\begin{itemize}
	\item une dimension explicitement écrite, c'est-à-dire un \verb|<nombre>| (entier) ou un nombre décimal suivi d'espaces facultatifs et de deux lettres de catcode 11 ou 12 représentant une des unités de dimensions qu'accepte \TeX{} à savoir \texttt{pt},  \texttt{pc}, \texttt{in}, \texttt{bp}, \texttt{cm}, \texttt{mm}, \texttt{dd}, \texttt{cc}, \texttt{sp}, \texttt{em} et \texttt{ex}. Le séparateur décimal peut indifféremment être le point ou la virgule pourvu que son catcode soit 12. La lecture de la dimension s'arrête au premier token qui suit les deux caractères d'unité. Si ce token est un espace, celui est absorbé.
	\item un \verb|<registre de dimension>|. Si ce registre est précédé d'un nombre décimal signé, la dimension obtenue sera celle du registre multipliée par le nombre signé ;\label{multiplication.dimension}
	\item un \verb|<registre de ressort>| (voir la définition à la section suivante) auquel cas, la dimension retenue est égale à la composante non étirable du registre de ressort. Si ce registre est précédé d'un nombre décimal signé, la dimension obtenue sera la composante fixe du ressort multipliée par le nombre signé.
\end{itemize}

La valeur absolue maximale d'une \verb|<dimension>| est contenue dans le registre de dimension \idx\maxdimen et vaut \texttt{16383.99999pt}, ce qui représente \texttt{\convertunit{\maxdimen}{cm}cm}.
\end{regle}

Pour ses dimensions, \TeX{} n'est pas avare d'unités\idx*[!table des unités]{dimension}. Il en manipule 11 dont voici les définitions :

\begin{centrage}
\small
\begin{tabular}{c>\ttfamily cr@{${}={}$}lr@{${}={}$}l}
	\idx*{unité!table} Unité & \multicolumn1c{Abréviation} & \multicolumn2c{Définition} & \multicolumn2c{Exemple}\\\hline
	point\idx*{unité!pt}\idx*{pt (unité)} & pt& \multicolumn2c{}&1 \verb|pt| & \showdim{1pt}\\
	pica\idx*{unité!pc}\idx*{pc (unité)} & pc & \numprint[pc]1&\numprint[pt]{12} & 1 \verb|pc| & \showdim{1pc}\\
	pouce\idx*{unité!in}\idx*{in (unité)} & in & \numprint[in]1&\numprint[pt]{72,27} & 1 \verb|in| & \showdim{1in}\\
	gros point\idx*{unité!bp}\idx*{bp (unité)} & bp & \numprint[bp]{72}&\numprint[in]1 & 1 \verb|bp| & \showdim{1bp}\\
	centimètre\idx*{unité!cm}\idx*{cm (unité)} & cm & \numprint[cm]{2,54}&\numprint[in]1 & 1 \verb|cm| & \showdim{1cm}\\
	millimètre\idx*{unité!mm}\idx*{mm (unité)} & mm & \numprint[mm]{10}&\numprint[cm]1 & 1 \verb|mm| & \showdim{1mm}\\
	point didot\idx*{unité!dd}\idx*{dd (unité)} & dd & \numprint[dd]{1157}&\numprint[pt]{1238} & 1 \verb|dd| & \showdim{1dd}\\
	cicéro\idx*{unité!cc}\idx*{cc (unité)} & cc & \numprint[cc]1&\numprint[dd]{12} & 1 \verb|cc| & \showdim{1cc}\\
	point d'échelle\idx*{unité!sp}\idx*{point d'échelle}\idx*{sp (unité)} & sp & \numprint[sp]{65536}&\numprint[pt]1 & $10^6$ \verb|sp| & \showdim{1000000sp}\\
	cadrat\idx*{unité!em}\idx*{em (unité)} & em & \multicolumn2c{} & \verb|1em| & \showdim{1em}\\
	hauteur d'\oe il\idx*{unité!ex}\idx*{ex (unité)} & ex & \multicolumn2c{} & \verb|1ex| & \showdim{1ex}\\\hline
\end{tabular}
\end{centrage}

Les deux dernières unités dépendent de la police utilisée et de sa taille. Historiquement, \verb|1em| est la largeur de la lettre «M», mais le créateur de la fonte peut en décider autrement et donner au \verb|em| une valeur différente. Par exemple, dans la police en cours dans ce paragraphe, \verb|1em| vaut \texttt{\convertunit{1em}{mm}mm} alors que la largeur de la boite englobante de la lettre «M» vaut {\setbox0=\hbox{M}\texttt{\convertunit{\wd0}{mm}mm}}.

La hauteur d'\oe il, ou \verb|ex| est censée représenter la hauteur des lettres sans hampe, ni jambage ni signe diacritique. Dans la police en cours, \verb|1ex| vaut \texttt{\convertunit{1ex}{mm}mm} et la hauteur de la boite englobante de la lettre «x» vaut \texttt{\setbox0=\hbox{x}\convertunit{\dimexpr\ht0 + \dp0 }{mm}mm}.
\grandsaut

Les \verb|<registres de dimension>|\idx*[!dimension|)]{registre} sont comme les autres registres que nous avons déjà vus (registres d'entiers ou de tokens) : ce ne sont que des sortes de pointeurs vers une zone de mémoire où sont écrits les octets capables, selon un procédé interne à \TeX, de stocker le contenu du registre. Par conséquent, dans le code source, un \verb|<registre de dimension>| ne peut être écrit seul \emph{que} lorsque \TeX{} s'apprête à lire une dimension ou lors d'une assignation. Dans les autres cas, la primitive développable \idx\the, lorsqu'elle précède le registre, en donne le contenu sous forme de tokens de catcode 12\idx*{catcode!12 (autre)}. Lorsqu'on invoque \idx\the pour faire remonter le contenu d'un registre de dimension des entrailles de \TeX{}, on obtient toujours une dimension en points\idx*{unité!pt}\idx*{pt (unité)} où les caractères d'unité «\verb|pt|» ont un catcode de 12. La partie décimale est toujours affichée et éventuellement réduite à un 0, et le séparateur décimal est le point. Le nombre de chiffres est au maximum de 5 après la virgule :

\showcode/\newdimen\dimA \newdimen\dimB% alloue deux registres de dimension¤\idx*\newdimen¤
a) \dimA=59.5pt
   \the\dimA\qquad% doit afficher 59.5pt¤\idx*\the¤
b) \dimA=1.5cm
   \the\dimA\qquad% convertit à l'affichage 1.5cm en pt
c) \dimB=7pt % assigne 7pt à \dimB
   \dimA\dimB% rend \dimA égal à dimB
   \the\dimA\qquad 
d) \dimA=6\dimB% rend \dimA égal à 6 fois \dimB
   \the\dimA¤\idx*\the¤/\grandsaut

Bien qu'étant traduites en points, toutes ces dimensions ne sont que des multiples de l'unité de longueur que \TeX{} manipule en interne, le « \idx{point d'échelle} » (abréviation «\verb|sp|\idx*{unité!sp}\idx*{sp (unité)}» pour « scale point »\idx*{unité!sp}\idx*{sp (unité)}), plus petite dimension que \TeX{} peut manipuler et dont la longueur vaut approximativement \hbox{$5{,}4\times10^{-9}$}~mètre (soit 5,4 nanomètres). C'est extrêmement petit, de l'ordre de la dimension d'un petit virus. Cette dimension insécable, bien évidemment invisible à l'\oe il nu, donne aux calculs sur les longueurs de \TeX{} une grande précision qui restera très inférieure à ce qui peut être décelé à l'\oe il nu, même après plusieurs arrondis.

\subsection{Opérations sur les dimensions}
Comme pour les entiers, des opérations sont disponibles pour les dimensions via les primitives \idx[|etc]\advance\forbidindex\advance{} pour l'addition, \idx\multiply et \idx\divide pour la multiplication et la division par un entier.

Pour calculer $(25\text{\ttfamily pt}\div4+1,72\text{\ttfamily pt})\times3$, voici comment nous pourrions partir d'une dimension de 25pt, la diviser par 4, ajouter 1.72pt et multiplier le tout par 3 :

\showcode|\newdimen\foo¤\idx*\newdimen¤
\foo=25pt % assigne 25pt au registre \foo
\divide\foo 4 % le multiplie par 4¤\idx*\divide¤
\advance\foo1.72pt % lui ajoute 1.72pt¤\idx*\advance¤
\multiply\foo3 % le multiplie par 3¤\idx*\multiply¤
\the\foo% affiche la dimension obtenue¤\idx*\the¤|

\begin{exercice}
Écrire une macro §\removept qui retire l'unité d'une dimension explicite obtenue avec \idx\the. Si la partie décimale est nulle, elle ne sera pas affichée.

\solution
Le premier réflexe est d'écrire une macro à argument délimité par «\verb|pt|» :

\centrecode-\def\removept#1.#2pt{#1\ifnum#2>0 .#2\fi}-§*\removept

Mais cela ne fonctionnera pas puisque les caractères «\verb|pt|» du \idx{texte de paramètre} n'ont pas le catcode 12\idx*{catcode!12 (autre)}. Il faut donc ruser un peu pour définir la macro. Nous pouvons par exemple utiliser une macro temporaire pour stocker «\verb|\def\removept#1.#2pt|» où les délimiteurs «\verb|pt|» ont un catcode égal à 12. Cette macro temporaire sera définie par un \idx\edef pour développer «\idx\string\verb| p|» et «\verb|\string t|» qui donnent les caractères «\verb|pt|» de catcode 12\idx*{catcode!12 (autre)} :

\showcode/\begingroup% ouvrir un groupe
	\edef\temp{\endgroup\def\noexpand\removept##1.##2\string p\string t}%¤§*\removept\idx*\string¤
\temp{#1\ifnum#2>0 .#2\fi}% et le fermer avant de définir \removept
\newdimen\foo¤\idx*\newdimen¤
a) \foo=15pt \expandafter\removept\the\foo\qquad¤\idx*\the¤
b) \foo=3.14pt \expandafter\removept\the\foo¤§*\removept¤/

L'astuce consiste à inclure le \idx\endgroup dans le texte de remplacement de \verb|\temp| de telle sorte que lorsque \verb|\temp| se développe puis s'exécute, ce \idx\endgroup provoque la destruction de cette macro temporaire avant même d'avoir fini de lire son texte de remplacement.

Il est naturel de créer la macro §\dimtodec qui transforme un registre de dimension en nombre décimal :

\showcode/\def\dimtodec{\expandafter\removept\the}¤§*\dimtodec§*\removept¤
\newdimen\foo¤\idx*\newdimen¤
a) \foo=15pt \dimtodec\foo \qquad
b) \foo=3.14pt \dimtodec\foo¤§*\dimtodec¤/
\end{exercice}

\subsection{La primitive \texttt{\textbackslash dimexpr}}
La primitive \idx\dimexpr\label{dimexpr} de \idx\eTeX{} est aux calculs sur dimensions ce que \idx\numexpr est aux calculs sur les entiers. Elle rend possibles des calculs sur les dimensions de \TeX{} sans passer par les registres de dimension et les primitives \idx\advance, \idx\multiply et \idx\divide qui donnent un code assez fastidieux. 

\begin{regle}
La primitive \idx\dimexpr de \idx\eTeX{} doit être suivie d'un enchainement d'opérations sur des dimensions qui est évalué selon les règles mathématiques habituelles : parenthèses, opérations (\verb|+|, \verb|*|, \verb|/|), priorités. Cette primitive possède les propriétés suivantes :

\begin{itemize}
	\item tout comme \idx\numexpr, \idx\dimexpr amorce un développement maximal pour évaluer l'\verb|<expression>| qui la suit. L'\verb|<expression>| prend fin au premier caractère qui ne peut faire partie d'un calcul sur les dimensions. La primitive \idx\relax peut marquer la fin d'une \verb|<expression>| et dans ce cas, elle est absorbée par \idx\dimexpr;
	\item les espaces dans l'\verb|<expression>| sont ignorés ;
	\item dans l'\verb|<expression>|, une \verb|<dimension>| ne peut être multipliée ou divisée (avec \verb|*| ou \verb|/|) que par un \emph{entier}. Dans ce cas, l'entier \emph{doit} être l'opérateur c'est-à-dire qu'il doit suivre la dimension. On doit donc écrire
	
	\begin{centrage}\verb-<dimension>*<entier>- ou \verb-<dimension>/<entier>-\end{centrage}
	\item une \verb|<expression>| évaluée par \idx\dimexpr est du même type qu'un registre de dimension, il s'agit donc d'une représentation \emph{interne} d'une dimension. On peut convertir cette représentation interne en caractères de catcode 12\idx*{catcode!12 (autre)} en faisant précéder \idx\dimexpr de la primitive développable \idx\the.
\end{itemize}
\end{regle}

Voici quelques exemples où la primitive \idx\dimexpr est mise à contribution :

\showcode|a) \the\dimexpr 1cm + 0.5cm\relax \qquad¤\idx*\dimexpr¤
b) \the\dimexpr 1pt + 1pt\relax \qquad¤\idx*\the¤
c) \the\dimexpr 1pt + 2pt * 3\relax\qquad
d) \the\dimexpr (1pt + 2pt) * 3\relax\qquad
e) \the\dimexpr (1.2pt + 0.8pt) * 5\relax\qquad
f) \newdimen\foo \foo=15pt ¤\idx*\newdimen¤
   \the\dimexpr\foo-(\foo + 1pt) / 4\relax|

\subsection{Les limites du calcul sur les dimensions}\label{arrondis.sur.dimensions}\idx*[|(]{dimension!arrondi}\idx*[|(]{arrondi (dimension)}
Tout semble se passer pour le mieux et il serait tentant de penser qu'une fois libérée de son unité en \verb|pt|, une dimension se comporte exactement comme un nombre décimal tandis que de son côté, \idx\dimexpr joue le rôle de machine à calculer. La simple addition ci-dessous va tempérer ce jugement :

\showcode/\the\dimexpr0,7pt + 0.4pt\relax¤\idx*\the\idx*\dimexpr¤/

\Qu e se passe-t-il et pourquoi le simple calcul «\texttt{0,7pt + 0.4pt}» ne donne-t-il pas comme résultat \texttt{1.1pt}? Les calculs de dimensions seraient-ils bogués ? La réponse est bien évidemment non, mais c'est le revers de la médaille : puisque toutes les dimensions sont converties en «\verb|sp|\idx*{unité!sp}\idx*{sp (unité)}» en interne pour effectuer les calculs puis sont à nouveau converties en «\verb|pt|» pour le résultat, des arrondis sont inévitablement faits lors de ces deux conversions. Il faut donc s'attendre à ce que ces arrondis viennent dans certains cas se cumuler défavorablement. Voici l'explication de l'erreur constatée :

\begin{itemize}
	\item \verb|0,7pt| vaut $0,7\times\numprint{65536}=\numprint[sp]{45875.2}$ qui est arrondi à \numprint[sp]{45875}\idx*{unité!sp}\idx*{sp (unité)};
	\item \verb|0.4pt| vaut $0.4\times\numprint{65536}=\numprint[sp]{26214.4}$ qui est arrondi à \numprint[sp]{26214};
	\item en tenant compte des arrondis, la somme vaut $\numprint{45875}+\numprint{26214}=\numprint[sp]{72089}$;
	\item convertie en pt, cette somme vaut $\numprint{72089}\div65536=\numprint{1,09999084473}$ et \TeX{} donne 5 chiffres après la virgule ce qui fait bien \numprint[pt]{1.09999}.
\end{itemize}

Le résultat attendu, \verb|1.1pt| vaut $\numprint{1.1}\times{65536}=\numprint[sp]{72089.6}$ qui serait arrondi par \TeX{} à \numprint[sp]{72090}\idx*{unité!sp}\idx*{sp (unité)}.

Si une dimension est considérée comme une mesure de ce qui doit être affiché, ces erreurs d'arrondis sont absolument insignifiantes puisqu'invisibles à l'\oe il nu; insistons sur le fait qu'il ne s'agit ici que d'une minuscule erreur d'\verb|1sp|\idx*{unité!sp}\idx*{sp (unité)} c'est-à-dire de quelques nanomètres ! Mais pour le programmeur, c'est la douche froide et c'est l'assurance que les dimensions ne peuvent pas jouer le rôle de nombres décimaux pris en tant que nombres \emph{mathématiques}, car une erreur sur une simple addition est inacceptable. On peut donc affirmer que \TeX{} ne dispose de rien qui pourrait tenir lieu de nombres décimaux comme en disposent les autres langages. Bien évidemment, on peut \emph{programmer} le fonctionnement de nombres décimaux (en virgule fixe ou flottante) avec les outils de base de \TeX{} que sont les entiers et les 4 opérations. Construire des opérations sur ces nombres est extrêmement fastidieux\footnote{L'extension «\texttt{\idx*{package!fp}fp}» (pour «fixed point») a relevé ce défi. Cette extension est programmée en \TeX{} et utilise les compteurs pour parvenir à ses fins. Elle définit et manipule des nombres en virgule \emph{fixe} avec une partie entière et une partie décimale de 18 chiffres chacune et effectue toutes les opérations arithmétiques et scientifiques habituelles sur ces nombres en virgule fixe (puissances, exponentielles, logarithmes, lignes trigonométriques, tests, nombres pseudoaléatoires, etc.). Ainsi, il est très facile de calculer que

\[\frac{\mathrm e^4 \ln\left(1+\cos\frac\pi7\right)}{1-3\arctan(0.35)}+4\sqrt[3]{5+\sqrt{2}}\approx-3491.19785321755\mathbf{4299238}
\]

Du fait d'arrondis successifs dans cette expression complexe, les décimales en gras sont fausses% et devraient être 5016987
.}\idx*[|)]{dimension!arrondi}\idx*[|)]{arrondi (dimension)}. Il faut mentionner la macro purement développable §\decadd, programmée en annexe (voir page~\pageref{decadd}), qui permet d'additionner de façon \emph{exacte} deux nombres décimaux signés.

Il est primordial de comprendre qu'une dimension et un nombre entier ne sont que deux facettes d'une même chose : puisque tous les calculs se font en nombre entier de points d'échelle\idx*{point d'échelle}, une dimension en \TeX{} n'est en réalité que le nombre \emph{entier} de \verb|sp|\idx*{unité!sp}\idx*{sp (unité)} qu'elle représente !

\begin{regle}
Toutes les dimensions fixes que \TeX{} manipule sont converties en interne en le nombre \emph{entier} de \idx*{point d'échelle}points d'échelle (\verb|sp|\idx*{unité!sp}\idx*{sp (unité)}) qu'elles représentent. Une dimension s'apparente donc à un entier.

Si \TeX{} est à un endroit où il s'attend à lire un \verb|<nombre>| entier et qu'il lit un \verb|<registre de dimension>|, il convertit la dimension contenue dans le registre en « \idx{entier contraint} » qui est le nombre de \verb|sp|\idx*{sp (unité)}\idx*{unité!sp} qu'elle représente. Cet entier contraint est le \verb|<nombre>| qui sera  pris en compte.
\end{regle}

Constatons-le avec ce code où la primitive \idx\number qui, attendant un nombre entier, force la conversion de la dimension en \idx{entier contraint} :

\showcode/a) \newdimen\foodim \foodim=1cm \number\foodim\relax\qquad¤\idx*\newdimen¤
b) \number\dimexpr 0.7pt + 0.4pt\relax\qquad¤\idx*\number¤
c) \number\dimexpr 1.1pt\relax/

\begin{exercice}
La macro \verb|\for|, programmée à la page~\pageref{for}, ne peut manipuler que des nombres \emph{entiers}.

Sur le modèle de §\for, créer une macro §\FOR où les nombres (borne mini, maxi et incrément) peuvent être décimaux.

On utilisera le test \tidx{ifdim}, de syntaxe

\centrecode-\ifdim<dimension1><signe de comparaison><dimension2>
	<code vrai>
\else
	<code faux>
\fi-

qui est aux \verb|<dimensions>| ce que le test \verb|\ifnum| est aux entiers.
\solution
Il y a peu de changements à faire. Il faudra remplacer les tests \tidx{ifnum} par \tidx{ifdim} et rajouter l'unité \verb|pt| lorsque c'est nécessaire.

\showcode/\catcode`\@11
\def\FOR#1=#2to#3\do#4#{%
	\ifempty{#4}¤§*\ifempty¤
		{\let\FOR@increment\z@}
		{\edef\FOR@increment{\the\dimexpr#4pt\relax}}% lit et normalise l'argument optionnel
	\ifdim\FOR@increment=\z@% s'il est nul,¤\idx*\z@¤
		\edef\FOR@increment{% le redéfinir à -1pt (si #3<#2) et 1pt sinon
			\ifdim\dimexpr#3pt-#2pt\relax<\z@ -1\else 1\fi pt¤\idx*\numexpr\idx*\z@¤
		}% \FOR@increment vaut donc 1 ou -1
	\fi
	\ifdim\dimtodec\dimexpr#3pt-#2pt\relax\dimexpr\FOR@increment\relax<\z@¤\defline\aaa¤
		\expandafter\gobone% si argument optionnel incompatible, manger le {<code>}
	\else
		\edef#1{\dimtodec\dimexpr#2pt\relax}% initialise la \<macro>
		\edef\macro@args{% définit et développe les arguments à passer à \FOR@i
			%#1=nom de la macro récursive :
			\expandafter\noexpand\csname FOR@ii@\string#1\endcsname¤\idx*\csname\idx*\endcsname\idx*\string¤
			\ifdim\FOR@increment<\z@ <\else >\fi% #2=signe de comparaison¤\idx*\z@¤
			{\FOR@increment}% #3=incrément
			\noexpand#1% #4=\<macro>¤\idx*\noexpand¤
			{\the\dimexpr#3pt\relax}% #5=dimension n2¤\idx*\number\idx*\numexpr¤
		}%
		\antefi% externalise la ligne ci-dessous de la portée du test¤§*\antefi¤
		\expandafter\FOR@i\macro@args% appelle \FOR@i avec les arguments définis ci-dessus
	\fi
}

% #1=nom de la macro récursive de type "\FOR@ii@\<macro>"
% #2=signe de comparaison  % #3=incrément
% #4=\<macro>  % #5=dimension n2  % #6=<code> à exécuter
\long\def\FOR@i#1#2#3#4#5#6{%¤\idx*\long¤
	\def#1{% définit la sous macro récursive
		\unless\ifdim#4pt#2#5\relax% tant que la \<macro> variable n'a pas dépassé n2¤\tidx*{unless}¤
			\afterfi{% rendre la récursivité terminale¤§*\afterfi\idx*{récursivité!terminale}¤
				#6% exécute le code¤\defline\bbb¤
				\edef#4{\dimtodec\dimexpr#4pt+#3\relax}% incrémente la \<macro>
				#1% recommence
			}%
		\fi
	}%
	#1% appelle la sous-macro récursive¤\defline\ccc¤
}%
\def\exitFOR#1{% #1=\<macro> correspondant à la boucle de laquelle on veut sortir¤§*\exitFOR¤
	\defname{FOR@ii@\string#1}{}%¤\idx*\csname\idx*\endcsname\idx*\string§*\defname¤
}

\def\ifexitFOR#1{% envoie vrai si on est prématurément sorti de la boucle de \<macro> #1¤§*\ifexitFOR¤
	% si la macro récursive est \empty
	\expandafter\ifx\csname FOR@ii@\string#1\endcsname\empty¤\idx*\string\idx*\empty¤
		\expandafter\firstoftwo% c'est qu'on est sortir prématurément, renvoyer "vrai"¤§*\firstoftwo¤
	\else
		\expandafter\secondoftwo% sinon, renvoyer "faux"¤§*\secondoftwo¤
	\fi
}
\catcode`\@=12
a) \FOR\xx=1.5 to -5\do-1{"\xx" }\par

b) \FOR\ii=1 to 2.742\do.25{"\ii" }\par

c) \FOR\ii=0 to 1\do0.1{"\ii" \ifdim\ii pt>0.5pt \exitFOR\ii\fi}¤§*\FOR¤/

La ligne \no\aaa{} mérite tout de même quelques explications. Il s'agit de trouver le signe de

\[(\hbox{\verb|#3|}-\hbox{\verb|#2|})\times\hbox{\verb|\for@increment|}\]

Pour calculer cette expression sous forme de dimension, nous avons tout d'abord transformé \verb|#3-#2| en un décimal sans unité avec la macro §\dimtodec. La macro \verb|\for@increment| est transformée en une dimension de type \verb|<registre>| avec \idx\dimexpr. Le test \tidx{ifdim} voit donc \verb|<x><registre de dimension>| où \verb|<x>| est un décimal signé. Comme l'explique la règle vue précédemment, le tout forme une \verb|<dimension>| égale au produit de \verb|#3-#2| par \verb|\for@increment|.

Comme le montre le cas c, additionner à chaque itération l'incrément à la dimension précédente conduit parfois à des erreurs d'arrondi gênantes. Pour une addition décimale \emph{exacte}, voir en annexe la macro §\decadd, page~\pageref{decadd}.
\end{exercice}

\subsection{Étendre les calculs sur les dimensions}
Puisqu'il n'est pas question d'écrire une extension aussi complexe que \verb|fp|, nous allons accepter les erreurs d'arrondis dues à la méthode de calcul sur les dimensions. Aussi, nous allons confondre dimension en \verb|pt| sans unité et nombre décimal; en effet, passer de l'une à l'autre est facile. Il suffit d'appeler la macro §\dimtodec pour le sens \emph{dimension vers décimal} ou d'ajouter l'unité \verb|pt| pour le sens inverse.

Nous allons essayer de tirer parti de \idx\dimexpr et des règles que nous avons vues pour étendre un peu les possibilités de calcul de \TeX{} sur les nombres décimaux. Si l'addition et la soustraction opèrent sur \emph{deux} nombres décimaux, il n'en est pas de même pour la multiplication et la division qui ne sont capables de multiplier ou diviser par un \emph{entier}.

\subsubsection{Multiplier deux décimaux}
Essayons tout d'abord de programmer une macro §\decmul qui permet de multiplier deux nombres \emph{décimaux}, chacun se trouvant dans un argument.

Nous allons exploiter le fait que \verb|<décimal><registre de dimension>| est vue comme une dimension égale au produit des deux quantités.

\showcode/\newdimen\foo¤\idx*\newdimen¤
\foo=15.2pt \foo=1.5\foo \the\foo% vaut 15.2*1.5¤\idx*\the¤/

Aux erreurs d'arrondi près auxquelles nous nous sommes résignés, le résultat est correct. Voici donc comment programmer la macro §\decmul\label{decmul} :

\showcode/\catcode`\@11
\newdimen\dim@a¤\idx*\newdimen¤
\def\decmul#1#2{%¤§*\decmul¤
	\dim@a=#2pt    % range la dimension #2pt dans le registre de dimension
	\dim@a=#1\dim@a% multiplier le registre par le décimal #1
	\dimtodec\dim@a% convertir la dimension en décimal¤§*\dimtodec¤
}
\catcode`\@12
a) \decmul{15.2}{1.5}\qquad
b) \decmul{48.2}{.375}¤§*\decmul¤/

\begin{exercice}
La macro §\decmul programmée ci-dessus n'est pas purement développable. Utiliser la primitive \idx\dimexpr pour qu'elle le devienne.
\solution
La méthode va être de donner à §\dimtodec non pas un vrai registre de dimension, mais une expression évaluée par \idx\dimexpr, puisque cette primitive est du même type qu'un registre de dimension :

\centrecode-\dimtodec\dimexpr<expression>\relax-

En ce qui concerne l'\verb|<expression>|, nous allons utiliser la même méthode vue ci-dessus, à savoir \verb|#1<registre>| où le \verb|<registre>| sera remplacé par \idx\dimexpr\verb|#2\relax|. Cela donne :

\showcode/\def\decmul#1#2{\dimtodec\dimexpr#1\dimexpr#2pt\relax\relax}¤§*\decmul §*\dimtodec\idx*\dimexpr¤

a) \decmul{15.2}{1.5}\qquad
b) \edef\foo{\decmul{48.2}{.375}}\meaning\foo¤§*\decmul¤/
\end{exercice}

\subsubsection{Diviser par un décimal}
Si nous souhaitons écrire une macro analogue §\decdiv[|(]\verb|{<nba>}{<nbb>}| qui effectue la division du décimal \verb|<nba>| par le décimal \verb|<nbb>|, l'astuce consiste à évaluer avec \idx\numexpr l'entier suivant :

\[
\frac{\text{\texttt{\codeelement{nba}pt}}\times\text{\ttfamily 1pt}}{\text{\texttt{\codeelement{nba}pt}}}
\]

\noindent Comme \idx\numexpr s'attend à des opérations sur des entiers, chaque dimension, préalablement mise sous forme de registre avec \verb|\dimexpr|, sera convertie en entier contraint. Le risque de dépassement de l'entier maximal au numérateur est improbable, car lorsque \idx\numexpr (tout comme \idx\dimexpr) effectue une multiplication immédiatement suivie d'une division, les calculs internes se font sur 64 bits et non sur 32.

Une fois cet entier calculé, nous lui donnerons l'unité \verb|sp|\idx*{unité!sp}\idx*{sp (unité)} et évaluerons le tout avec \idx\dimexpr. Le résultat, expurgé de son unité avec §\dimtodec, donnera le quotient cherché.

Pour éviter un \idx\dimexpr inutile, la dimension \verb|1pt|, qui vaut \verb|65536sp|, a été directement convertie en l'entier contraint \verb|65536| :

\showcode|\def\decdiv#1#2{% divise le décimal #1 par le décimal #2¤§*\decdiv¤
	\dimtodec¤§*\dimtodec\idx*\dimexpr\idx*\numexpr¤
	\dimexpr
		\numexpr
			\dimexpr #1pt \relax * 65536 / \dimexpr #2pt \relax
		\relax
		sp¤\idx*{sp (unité)}\idx*{unité!sp}\idx*{sp (unité)}¤
	\relax
}

1) \decdiv{4.5}{0.075}\qquad% doit donner 60
2) \decdiv{8}{0.1}\qquad% doit donner 80
3) \decdiv{3.14}{1.6}\qquad% doit donner 1.9625
4) \decdiv{687.59829}{5.29871}\qquad% doit donner 129.76706
4) \edef\foo{\decdiv{0.37}{2.5}}\foo% doit donner 0.148¤§*\decdiv¤|

Ici encore, il ne s'agit que d'arithmétique \TeX ienne, c'est-à-dire que comme avec §\decmul, les résultats sont entachés d'erreurs d'arrondis et donc, ces macros ne pourront être utilisées que pour des calculs de dimensions et non pas pour des calculs sur des nombres pris en tant qu'entités mathématiques§*\decdiv[|)].

\begin{exercice}
Écrire une macro §\convertunit[|(] de syntaxe

\centrecode-\convertunit{<dimension>}{<unité>}-

qui convertit la \verb|<dimension>| dans l'\verb|<unité>| spécifiée par les deux caractères caractérisant chaque unité, et d'afficher le résultat sans unité. La macro devra être purement développable.

\solution
Nous allons procéder comme nous l'avons fait avec la macro §\decdiv : nous allons mettre \idx\numexpr à contribution pour transformer en \idx{entier contraint} toutes les dimensions et multiplier la \verb|<dimension>| par \verb|1pt| et diviser le tout par
 \verb|1<unité>| :

\showcode|\def\convertunit#1#2{%¤§*\dimtodec¤
	\dimtodec
	\dimexpr
		\numexpr
			\dimexpr #1 \relax * 65536 / \dimexpr 1#2 \relax
		\relax
		sp
	\relax
}

a) \convertunit{15cm}{mm}\qquad
b) \convertunit{9,14in}{cm}\qquad
c) \convertunit{100000sp}{mm}\qquad
d) \convertunit{160.5pt}{cm}\qquad
e) \edef\foo{\convertunit{2,5cm}{cc}}\meaning\foo|
§*\convertunit[|)]\end{exercice}\idx*[|)]{dimension fixe}

\section{Les dimensions étirables ou ressorts}\idx*[|(]{registre!ressort}\idx*[|(]{dimension étirable (ressort)}
\subsection{\Qu'est-ce qu'un ressort ?}
Intéressons-nous maintenant aux ressorts qui ont vocation à remplir des zones susceptibles d'avoir des tailles variables (souvent pour des raisons typographiques).

\begin{regle}
Un ressort est une dimension assortie de composantes étirables optionnelles (éventuellement infinies) de sorte qu'il peut, selon le contexte et sa définition, se comprimer ou s'étirer. \TeX{} offre 256 registres de ressorts et ce nombre monte à \numprint{32768} avec \idx\eTeX. La primitive \idx\skip suivie d'un \verb|<nombre>| permet d'accéder à un registre spécifique par son numéro.

Plain-\TeX{} fournit la macro \idx\newskip\verb|\<macro>| qui met à profit la primitive \idx\skipdef selon cette syntaxe

\centrecode-\skipdef\<macro>=<nombre>-

pour rendre cette \verb|\<macro>| équivalente à \idx\skip\verb|<nombre>|, où le \verb|<nombre>| est celui du prochain registre libre. Dès lors, un \verb|<registre de ressort>|\idx*{registre!ressort} est soit \idx\skip suivi d'un numéro, soit une \verb|\<macro>| préalablement définie par \idx\newskip.

Pour assigner un ressort à un \verb|<registre de ressort>|, il faut écrire :

\centrecode-<registre de ressort>= <ressort>-

\noindent où le signe «\verb|=|» et l'espace qui le suit sont optionnels. Pour lire le \verb|<ressort>|, le développement maximal se met en marche. Un \verb|<ressort>| est une \verb|<dimension>| éventuellement suivie d'une composante d'étirement optionnelle de la forme «\verb|plus <étirement>|» puis d'une composante de compression optionnelle de la forme «\verb|minus <étirement>|».

Si elles sont présentes toutes les deux, ces deux composantes optionnelles doivent \emph{nécessairement} être déclarées dans cet ordre. Si elles ne sont pas spécifiées, les composantes étirables valent \verb|0pt| par défaut.

Un \verb|<étirement>| est :\label{dimension.ressort}\idx*{registre!ressort!étirement}
\begin{itemize}
	\item soit une composante fixe qui est une \verb|<dimension>| comme «\verb|1.5pt|» ou «\verb|0.25cm|»;
	\item soit une composante infinie qui prend la forme d'un coefficient d'infini suivi de «\verb|fil|», «\verb|fill|» ou «\verb|filll|», où ces 3 mots-clé représentent des infinis de \emph{forces} différentes : «\verb-filll-» est infiniment plus grand que «\verb|fill|», quels que soient les coefficients qui les précèdent et de la même façon, «\verb|fill|» est infiniment plus grand que «\verb|fil|».
	
	Le coefficient d'infini est un décimal signé dont la valeur absolue peut prendre toutes les valeurs entre 0 et \verb|16383.99999|.
\end{itemize}
\end{regle}\idx*[|(]{registre!ressort!étirement}

À la manière de \idx\dimexpr qui fait des calculs sur les dimensions, la primitive \idx\glueexpr effectue des calculs sur les ressorts :

\showcode|\the\glueexpr 5pt plus 2pt minus 1.5pt + 7pt plus0.5pt minus 3pt\relax \par¤\idx*\glueexpr\idx*\the¤
\the\glueexpr 25pt plus2fil + 35pt plus 0.1fill\relax|
\grandsaut

Envisageons maintenant quelques exemples pour mieux comprendre comment les ressorts fonctionnent et quelles sont leurs « forces » relatives.

Intéressons-nous tout d'abord aux composantes d'étirement finies. Le ressort «\texttt{10pt plus1.5pt minus 2.5pt}» a une longueur naturelle de \numprint[pt]{10} mais peut s'allonger jusqu'à \numprint[pt]{11.5} et se comprimer jusqu'à \numprint[pt]{7.5}. De la même façon, le ressort «\texttt{0pt minus5pt}» a une longueur naturelle nulle, mais peut se comprimer jusqu'à une longueur négative de \numprint[pt]{-5}.

Venons-en aux composantes d'étirement infinies. Supposons qu' un ressort $R_1$ soit égal à «\texttt{1.5cm plus2fill}». Il a une longueur naturelle de \numprint[cm]{1.5} et peut s'allonger autant que nécessaire comme le spécifie sa composante étirable. Si un autre ressort $R_2$ est défini par «\texttt{2.5cm plus3fill}» et si nous demandons à ces deux ressorts de remplir un espace de \numprint[cm]{10}, la longueur à combler est de \numprint[cm]{6} puisque la somme des deux longueurs naturelles vaut \numprint[cm]{4}. Le ressort $R_1$ s'allongera de 2/5 la longueur à combler et $R_2$ de 3/5 de cette longueur, comme le spécifient les coefficients d'infini. $R_1$ mesurera  $1.5+6\times2/5=\numprint[cm]{3.9}$ alors que $R_2$ mesurera $2.5+6\times3/5=\numprint[cm]{6.1}$. En voici l'illustration ci-dessous où les dimensions naturelles sont en traits pleins et les étirements en pointillés. Si aucune opération dans l'impression de ce livre n'a provoqué d'altération d'échelle, les dimensions données ci-dessus doivent exactement se retrouver dans ce schéma :

\begingroup
\medbreak
\ttfamily
\small
\hfill
\leavevmode\lower5pt\hbox{\hbox to1.5cm{\hss 1.5cm\kern2pt}\hbox to2.4cm{\kern2pt plus 2fill\hss}\hbox to2.5cm{\hss2.5cm\kern2pt}\hbox to 3.6cm{\kern2pt plus 3fill\hss}}\hfill\null

\hfill\vrule width0.4pt height 1ex depth 0pt
\vrule width1.5cm height0.4pt depth 0pt
\vrule width0.2pt height 1ex depth 0pt
\hbox to2.4cm{\xleaders\hbox{\vrule width2pt height.4pt\kern1pt }\hfill}%
\vrule width0.4pt height 1ex depth 0pt
\vrule width2.5cm height0.4pt depth 0pt
\vrule width0.4pt height 1ex depth 0pt
\hbox to3.6cm{\xleaders\hbox{\vrule width2pt height.4pt\kern1pt }\hfill}%
\vrule width0.4pt height 1ex depth 0pt \hfill\null
\medbreak\endgroup

Enfin, si un ressort $R_3$ égal à «\texttt{3cm plus 20fil}» et un ressort $R_4$ égal à «\texttt{2cm plus 0.1fill}» doivent combler un espace de \numprint[cm]{20}, seul $R_4$ s'allongera pour mesurer \numprint[cm]{17} car son infini «\verb|fill|» est infiniment plus grand que «\verb|fil|».\idx*[|)]{registre!ressort!étirement}

\subsection{Insérer des espaces de dimensions choisies}
\subsubsection{Insertion d'espaces insécables}
\begin{regle}
Pour insérer une espace insécable, on utilise la primitive \idx\kern suivie d'une \verb|<dimension>| qui sera celle de l'espace insérée.

L'espace sera insérée dans le mode en cours : elle sera horizontale si \TeX{} est en mode horizontal\idx*{mode!horizontal} à ce moment-là et sera verticale s'il est en mode vertical\idx*{mode!vertical}.

L'espace ainsi créé est \emph{insécable} car aucune coupure de ligne ou de page ne pourra s'y faire.
\end{regle}

\showcode/foo% les caractères font entrer TeX en mode horizontal¤\idx*{mode!horizontal}¤
\kern0.5cm % espace insérée en mode horizontal¤\idx*{mode!horizontal}¤
bar\par% \par fait passer en mode vertical¤\idx*{mode!vertical}¤
\kern0.5cm % espace insérée en mode vertical
boo/

L'espace verticale entre la frontière basse de «bar» et la frontière haute de «boo» n'est pas \verb|0.5cm|, car le ressort d'interligne vient s'ajouter à la dimension insécable insérée par \idx\kern.

\subsubsection{Insertion d'espaces sécables}
À la différence des espaces insécables, un espace est dit « \emph{sécable} » s'il peut céder sa place à une coupure (de ligne ou de page). Le verbe « céder » suggère que si une coupure est faite, l'espace est retiré de la liste en cours et est remplacé par une coupure.

\begin{regle}
La primitive \idx\hskip, suivie d'un \verb|<ressort>| insère une espace (dont les dimensions sont celles permises par le ressort\idx*{registre!ressort}) dans la liste horizontale en cours. La primitive \idx\vskip en est le pendant pour le mode vertical\idx*{mode!vertical}.

Si \TeX{} rencontre une de ces deux primitives et ne se trouve pas dans le mode qu'elles exigent, alors le mode courant se termine et \TeX{} passe dans le mode requis.

Les espaces ainsi insérées sont sécables, c'est-à-dire susceptibles d'être remplacées par des coupures de ligne ou de pages. De plus, elles sont ignorées lorsqu'elles se trouvent immédiatement avant la fin du \idx[!espaces ignorés]{paragraphe} pour \idx\hskip ou de la fin de la page pour \idx\vskip.
\end{regle}

Il est utile de savoir qu'en mode horizontal\idx*{mode!horizontal}, le token espace (de catcode 10\idx*{catcode!10 (espace)} et de code de caractère 32) se comporte comme un ressort\idx*{registre!ressort} : il a une dimension naturelle et peut, dans une certaine mesure, se comprimer ou se dilater (lire page~\pageref{espace.dimensions.fonte}).
\grandsaut

Certaines primitives sont en réalité des ressort\idx*{registre!ressort}s. Il est important de distinguer deux types de « ressorts-primitives » :

\begin{itemize}
	\item ceux qui sont \emph{modifiables} et qui se comportent comme une macro définie avec \idx\newskip. Ces ressorts-primitives sont susceptibles de recevoir un \verb|<ressort>| par assignation. La plupart de ces ressorts-primitives concernent des réglages typographiques;
	\item ceux, non modifiables, dont la valeur est prédéfinie et invariable.
\end{itemize}

Le tableau ci-dessous, sans être exhaustif, liste quelques ressorts utilisés par \TeX{}, qu'ils soient de simples macros définies avec \idx\newskip (partie du haut), des ressorts-primitives modifiables (écrits en gras dans la partie du milieu) ou ressorts-primitives non modifiables (précédés d'une «$*$» dans la partie basse).

Dans chaque catégorie, la valeur par défaut assignée par plain-\TeX{} ou le comportement (pour les ressorts-primitives non modifiables) est donné dans la colonne « Définition »  tandis que le mode dans lequel le \idx*{registre!ressort}ressort est utilisé est donné dans la colonne de droite.\medbreak

\begingroup
	\small
	\LTpre2\parskip \LTpost\parskip\label{tableau.ressort}%
	\begin{longtable}{>\ttfamily r@{}c@{}>\ttfamily l@{\kern1em}c}\hline
		Nom && Définition & Mode\\\hline\endhead
		\idx\hideskip&${}={}$&-1000pt plus 1fill& h\\
		\idx\centering&${}={}$&0pt plus 1000pt minus 1000pt& h\\
		\idx\z@skip&${}={}$&0pt plus0pt minus0pt& h ou v\\
		\idx\smallskipamount&${}={}$&3pt plus 1pt minus 1pt&v\\
		\idx\medskipamount&${}={}$&6pt plus 2pt minus 2pt&v\\
		\idx\bigskipamount&${}={}$&12pt plus 4pt minus 4pt&v\\\hline
		\bfseries\idx\baselineskip&${}={}$&12pt&v\\
		\bfseries\idx\lineskip&${}={}$&1pt&v\\
		\bfseries\idx\leftskip&${}={}$&0pt&h\\
		\bfseries\idx\rightskip&${}={}$&0pt&h\\
		\bfseries\idx\parskip&${}={}$&0pt plus 1pt& v\\
		\bfseries\idx\parfillskip&${}={}$&0pt plus 1fil& h\\\hline
		\llap{${}^*$}\idx\hfil&${}\equiv{}$&\string\hskip{} 0pt plus 1fil&h\\
		\llap{${}^*$}\idx\hfilneg&${}\equiv{}$&\string\hskip{} 0pt plus -1fil&h\\
		\llap{${}^*$}\idx\hfill&${}\equiv{}$&\string\hskip{} 0pt plus 1fill&h\\
		\llap{${}^*$}\idx\vfil&${}\equiv{}$&\string\vskip{} 0pt plus 1fil&v\\
		\llap{${}^*$}\idx\vfilneg&${}\equiv{}$&\string\vskip{} 0pt plus -1fil&v\\
		\llap{${}^*$}\idx\vfill&${}\equiv{}$&\string\vskip{} 0pt plus 1fill&v\\
		\llap{${}^*$}\idx\hss&${}\equiv{}$&\string\hskip{} 0pt plus1fil minus1fil&h\\
		\llap{${}^*$}\idx\vss&${}\equiv{}$&\string\vskip{} 0pt plus1fil minus1fil&v\\\hline
	\end{longtable}
\endgroup

\subsection{Les ressorts typographiques}
Intéressons-nous aux ressorts-primitives écrits en gras dans le tableau précédent. Ces ressorts sont examinés lorsque le paragraphe est composé\idx*{paragraphe!composition}, c'est-à-dire lorsque \idx\par est exécuté. Il est donc inutile de modifier plusieurs fois ces ressorts dans le même paragraphe puisque seule la dernière valeur sera prise en compte.

Cela implique en particulier que si un paragraphe\idx*{paragraphe!composition} est composé dans un groupe (semi-simple ou non) dans lequel certains de ces ressorts sont modifiés, il est nécessaire de composer le paragraphe \emph{avant} de fermer le groupe. En écrivant \idx\par avant la fin du groupe, on s'assure que les valeurs des ressorts, modifiées dans le groupe, seront bien prises en compte. En revanche, rejeter le \idx\par hors du groupe constitue une erreur, car les valeurs, restaurées trop tôt à ce qu'elles étaient avant les modifications, rendent inutiles ces modifications internes au groupe.

\subsubsection{Ressort d'interligne}\label{ressort.interligne}\idx*[|(]{paragraphe!espace interligne}
Les boites contenant deux lignes consécutives d'un paragraphe ne sont généralement pas jointives. Le schéma ci-dessous illustre la situation : la distance entre les lignes de base des deux lignes consécutives est notée $\Delta$ tandis que la distance entre les frontières des deux boites est notée $\delta$.

\begin{centrage}
	\begin{tikzpicture}[inner sep=0pt,outer sep=0pt,minimum size=0pt,baseline,line width=0.4pt]
		\node[anchor=base west,draw,inner sep=-0.2pt]at(0,0)(boiteA){\vrule width0pt height.6cm depth.3cm \vrule height0pt width 3cm depth0pt };\draw[fill,black,overlay](boiteA.base west)circle(1pt);%
		\draw[gray,overlay]([xshift=-1cm]boiteA.base west)--([xshift=1cm]boiteA.base east)node[pos=1,anchor=south east,black,outer sep=1pt]{\tiny ligne de}node[pos=1,anchor=north east,black,outer sep=1pt]{\tiny base};
		\node[anchor=base west,draw,inner sep=-0.1pt]at(0,-1.2)(boiteB){\vrule width0pt height.5cm depth.2cm \vrule height0pt width 4cm depth0pt };
		\draw[fill,black,overlay](boiteB.base west)circle(1pt);%
		\draw[gray,overlay]([xshift=-1cm]boiteB.base west)--([xshift=1cm]boiteB.base east)node[pos=1,anchor=south east,black,outer sep=1pt]{\tiny ligne de}node[pos=1,anchor=north east,black,outer sep=1pt]{\tiny base};
		\draw[stealth-stealth]([xshift=-1.2cm]boiteA.base west)--([xshift=-1.2cm]boiteB.base west)node[pos=.5]{\footnotesize\llap{$\Delta$}\kern.75em };
		\draw[stealth-stealth]([xshift=-.2cm]boiteA.south west)--([xshift=-.2cm]boiteB.north west)node[pos=.5]{\footnotesize\llap{$\delta$}\kern.75em };
		\draw[stealth-stealth]([xshift=-.6cm]boiteA.south west)--([xshift=-.6cm]boiteA.base west)node[pos=.5]{\footnotesize\llap{$p$}\kern.75em };
		\draw[stealth-stealth]([xshift=-.6cm]boiteB.north west)--([xshift=-.6cm]boiteB.base west)node[pos=.5]{\footnotesize\llap{$h$}\kern.75em };
	\end{tikzpicture}
\end{centrage}

Plus généralement, si des boites sont empilées les unes au-dessous des autres en mode vertical, un ressort-primitive vertical «\idx\baselineskip» est inséré entre elles. Ce ressort-primitive, appelé « \idx{ressort d'interligne} », mesure l'espace insérée entre les \emph{lignes de base} de ces boites.

Si la géométrie des boites (précisément la quantité $p+h$) fait que $\delta$ devient strictement inférieur à une certaine limite stockée dans la dimension-primitive \idx\lineskiplimit, alors les deux boites sont empilées verticalement de telle sorte que $\delta$ soit égal au ressort-primitive \idx\lineskip. Mathématiquement, si

\[\Delta-(p+h)<\text{\ttfamily\char`\\lineskiplimit}\]\idx*\lineskiplimit
\noindent alors l'insertion de \idx\baselineskip entre les lignes de base est abandonnée et le ressort-primitive \idx\lineskip est inséré \emph{entre les frontières des boites}.

Plain-\TeX{} effectue les initialisations suivantes :

\centrecode-\baselineskip=12pt    \lineskiplimit=0pt    \lineskip=1pt-

La macro \idx\nointerlineskip doit être appelée en mode vertical et annule l'insertion du prochain \idx{ressort d'interligne} entre deux boites. Cette macro est à « un seul coup » et devra être appelée à nouveau si plus tard, on souhaite annuler l'insertion du ressort d'interligne entre deux autres boites.

\showcode/Une première ligne\par
\nointerlineskip% n'insère pas de ressort d'interligne ici¤\idx*\nointerlineskip¤
Un second paragraphe constitué de plusieurs lignes.
Un second paragraphe constitué de plusieurs lignes.
Un second paragraphe constitué de plusieurs lignes.
\par% le ressort d'interligne sera inséré ici
Une dernière ligne/

La macro \idx\offinterlineskip, désactive durablement l'insertion du ressort d'interligne. Il est prudent de l'utiliser dans un groupe afin d'en limiter la portée.

\showcode/\begingroup
\offinterlineskip¤\idx*\offinterlineskip¤
La macro \litterate-\offinterlineskip-, en modifiant de façon appropriée les trois¤\idx*\offinterlineskip§*\litterate¤
primitives \litterate-\baselineskip-, \litterate-\lineskip- et¤\idx*\offinterlineskip¤
\litterate-\lineskiplimit-, rend les boites consécutives jointives.¤\idx*\baselineskip\idx*\lineskip\idx*\lineskiplimit¤

On peut constater dans ces deux paragraphes où \litterate-\offinterlineskip- a été¤\idx*\offinterlineskip§*\litterate¤
appelée, que les lignes sont placées verticalement au plus près les unes des autres ce
qui rend la lecture très pénible et démontre que le ressort d'interligne est une¤\idx*{ressort d'interligne}¤
nécessité typographique !\par
\endgroup
Désactiver le ressort d'interligne ne se justifie que lorsque l'on doit composer¤\idx*{ressort d'interligne}¤
des boites contenant autre chose que du texte, sauf à vouloir des effets
typographiques spéciaux./

Les deux cas les plus courants où la quantité $p+h$ est élevée sont :

\begin{enumerate}
	\item la boite du haut est très profonde et $p$ est grand (boite de type \idx\vtop);
	\item la boite du bas est très haute et $h$ est grand (boite de type \idx\vbox).
\end{enumerate}

En voici l'illustration où nous allons construire une boite du haut profonde et où nous augmentons \idx\baselineskip afin de mieux visualiser le problème :

\showcode/\baselineskip=12pt
début \vtop{\hbox{ligne du haut ligne du haut ligne du haut}¤\idx*\vtop¤
\hbox{ligne du bas ligne du bas ligne du bas}
}
\par
Et la suite du texte suite du texte suite du texte/

On constate que l'espace vertical entre la « ligne du bas » de la \idx\vtop et la ligne suivante n'est pas \idx\baselineskip. En effet, \idx\lineskip a été inséré entre la frontière de la \idx\vtop et la première ligne du paragraphe qui suit. Pour rétablir un espacement correct, il faut mentir à \TeX{} sur la profondeur de la boite précédente. En mode vertical\idx*{mode!vertical}, la primitive \idx\prevdepth (qui mesure la longueur $p$ du schéma), ayant le type d'une dimension, contient la profondeur de la précédente boite placée dans la liste verticale. Après être sorti de la \idx\vtop, cette valeur est élevée du fait de la profondeur de la boite. L'astuce consiste à sauvegarder $p$ dans une macro à la fin de la \idx\vtop de telle sorte que cette macro contienne la profondeur \emph{de la dernière ligne} de la boite. Comme on ne peut accéder à \idx\prevdepth qu'en mode vertical\idx*{mode!vertical}, il suffit donc après le \idx\par d'assigner à \idx\prevdepth la valeur sauvegardée.

\showcode/\baselineskip=12pt
début \vtop{\hbox{ligne du haut ligne du haut ligne du haut}¤\idx*\vtop¤
\hbox{ligne du bas ligne du bas ligne du bas}
\xdef\sprevdepth{\the\prevdepth}% sauvegarde la valeur de \prevdepth¤\idx*\xdef¤
}
\par\prevdepth=\sprevdepth\relax% ment sur la boite précédente¤\idx*\prevdepth¤
Et la suite du texte suite du texte suite du texte/\idx*[|)]{paragraphe!espace interligne}

\subsubsection{Les ressorts de paragraphe}\idx*[|(]{paragraphe!ressorts de paragraphe}
Avant de commencer un paragraphe, \TeX{} ajoute à la liste verticale l'espace mesuré par le ressort-primitive \idx\parskip (il n'est pas ajouté si la liste verticale est vide, c'est-à-dire au début d'une page ou d'une boite verticale). Ce ressort vient donc s'additionner au \idx{ressort d'interligne} vu précédemment. Plain-\TeX{} procède à l'assignation suivante :

\centrecode-\parskip= 0pt plus 1pt-

Après la fin de la dernière ligne d'un paragraphe, \TeX{} insère horizontalement le ressort-primitive \idx\parfillskip. Plain-\TeX{} demande à ce que

\centrecode-\parfillskip= 0pt plus1fil-

\begingroup
\hbadness=10000 % pour éviter une avertissement de boite insuffisemment remplie
\parfillskip=0pt\relax
\noindent ce qui signifie qu'un ressort d'étirement infini est inséré en fin de paragraphe. L'effet d'un tel ressort est de « pousser » le texte de la dernière ligne de façon à ce qu'il ne se justifie pas. On peut bien sûr modifier ce ressort pour obtenir des effets typographiques comme dans ce paragraphe où ce ressort a été rendu nul sans étirement afin que la dernière ligne soit justifiée. Cet effet doit être utilisé avec parcimonie, car les espaces intermots de cette dernière ligne, beaucoup trop larges ici, démontrent que cet effet peut parfois être très inesthétique.
\par
\endgroup
\medbreak

Afin de bien voir la modification de la composition du paragraphe que cela entraine, voici le paragraphe précédent avec un ressort de fin de paragraphe ayant sa valeur par défaut :\smallbreak

\noindent ce qui signifie qu'un ressort d'étirement infini est inséré en fin de paragraphe. L'effet d'un tel ressort est de « pousser » le texte de la dernière ligne de façon à ce qu'il ne se justifie pas. On peut bien sûr modifier ce ressort pour obtenir des effets typographiques comme dans ce paragraphe où ce ressort a été rendu nul sans étirement afin que la dernière ligne soit justifiée. Cet effet doit être utilisé avec parcimonie, car les espaces intermots de cette dernière ligne, beaucoup trop larges ici, démontrent que cet effet peut parfois être très inesthétique.

\subsubsection{Ressorts d'extrémités de ligne}
Les ressorts \idx\leftskip et \idx\rightskip sont insérés avant et après le contenu de chaque ligne (\idx\rightskip est ajouté après \idx\parfillskip à la dernière ligne du paragraphe). Lorsqu'ils sont égaux à \verb|0pt| comme c'est le cas par défaut, le début et la fin de la ligne coïncident avec les limites de la zone de texte et le texte est dit « justifié » : ce sont les espaces entre les mots qui s'ajustent pour permettre cet effet typographique. La modification de ces ressorts d'extrémités de ligne permet des compositions qui contrarient cette justification.

Ainsi, donner une composante infinie à ces ressorts revient à les faire « pousser » avec une force infinie de telle sorte que les espaces entre les mots seront contraints à prendre leur dimension \emph{naturelle} ce qui cassera la justification. Il est cependant plus judicieux de donner comme étirement une composante \emph{finie} de telle sorte que celle-ci ne contraigne pas les espaces intermots. Il est utile de savoir qu'une composante \emph{infinie} des ressorts d'extrémité de ligne décourage \TeX{} d'effectuer une seconde passe lors de la composition du paragraphe. Seule la première passe est donc faite et les coupures de mots, envisagées à la seconde passe, ne seront donc jamais faites (lire page~\pageref{provoquer.toutes.les.coupures}).

On voit que les ressorts d'extrémités de ligne entretiennent un rapport avec les espaces intermots dont il est temps de parler. Chaque police possède des registres internes définissant la largeur naturelle de l'espace intermot, son possible étirement et sa possible compression (lire page~\pageref{espace.dimensions.fonte}). Le ressort-primitive \idx\spaceskip permet, lorsqu'il reçoit une assignation, d'écraser localement le contenu des registres de la police concernant les dimensions de l'espace intermot. Il est donc possible de supprimer la composante étirable de l'espace intermot afin que des espaces intermots trop longs et disgracieux soient évités dans une composition non justifiée.
\grandsaut

Les effets typographiques les plus courants obtenus à l'aide des ressorts d'extrémité de ligne sont :

\begin{itemize}
	\item composition au fer à gauche en donnant une composante étirable finie (par exemple 2 ou 3 \verb|em|) à \idx\rightskip et en laissant \idx\leftskip nul;
	\item composition au fer à droite en inversant les rôles des deux ressorts dans la man\oe uvre décrite au point précédent;
	\item centrage du contenu des lignes en donnant la \emph{même} composante étirable aux deux ressorts. Cette composante doit ici être assez grande pour permettre le centrage de lignes très courtes. Le choix de \verb|1000pt| est fait par plain-\TeX{} tandis que \LaTeX{} fait le choix de \texttt{0pt plus 1fil} pour sa macro \idx\centering. On peut également choisir \verb|0.5|\idx\hsize où \idx\hsize est la dimension-primitive qui contient la largeur de composition. Enfin, pour que la dernière ligne soit centrée, il faut également annuler \idx\parfillskip qui sinon, deviendrait prépondérant par rapport à \idx\leftskip et \idx\rightskip.
\end{itemize}

Voici un exemple de méthode pour centrer deux paragraphes\idx*{paragraphe!centrage} entiers :

\showcode/\def\dummytext{Voici un texte qui ne revêt aucune importance
	et dont le seul but est de meubler artificiellement un paragraphe. }
\begingroup% à l'intérieur d'un groupe,¤\idx*\begingroup¤
	\leftskip=0pt plus 0.5\hsize\relax¤\idx*\leftskip\idx*\hsize¤
	\rightskip=\leftskip\relax % modifier les ressort d'extrémités¤\idx*\rightskip\idx*\leftskip¤
	\spaceskip=0.3em plus 0.05em\relax% dimension de l'espace intermot¤\idx*\spaceskip¤
	\parfillskip=0pt \relax% annuler le ressort de fin de paragraphe¤\idx*\parfillskip¤
	\dummytext\dummytext\dummytext% corps du paragraphe
	\par% compose la paragraphe courant
	Juste une phrase%
	\par% compose la paragraphe courant
\endgroup% avant de sortir du groupe¤\idx*\endgroup¤/

En suivant cette méthode, il est facile de construire une macro §\narrowtext qui compose le paragraphe précédent et qui diminue désormais la largeur de composition de 20\% de la largeur totale\idx*{paragraphe!diminuer la largeur}, sachant que cette largeur est contenue dans la dimension-primitive \idx\hsize. Le « bloc » de composition ainsi constitué devra être centré par rapport aux frontières de la zone de texte. Il faut pour cela augmenter (via la primitive \idx\advance) chacun des deux ressorts d'extrémités de ligne de \verb|.1\hsize|. La macro \verb|\endnarrowtext| signera la fin de la composition en largeur diminuée; elle composera le paragraphe en cours avec \idx\par et fermera le groupe semi-simple ouvert par §\narrowtext.

\showcode/\def\narrowtext{%¤§*\narrowtext¤
	\par
	\begingroup
		\advance\leftskip 0.1\hsize¤\idx*\advance\idx*\leftskip¤
		\advance\rightskip 0.1\hsize¤\idx*\advance\idx*\rightskip¤
}
\def\endnarrowtext{\par\endgroup}
\def\dummytext{Ceci est un texte sans
 importance destiné à meubler un paragraphe. }

\dummytext\dummytext\dummytext
\narrowtext
	\dummytext\dummytext\dummytext
 \narrowtext
		\dummytext\dummytext\dummytext
 \endnarrowtext
	\dummytext\dummytext\dummytext
\endnarrowtext/

Comme aucune des macros §\narrowtext ou \verb|\endnarrowtext| n'admet d'argument, il n'y a aucun risque de mettre entre elles un contenu très long qui aurait pu inutilement surcharger la mémoire de \TeX{} s'il avait été maladroitement incorporé dans un argument. L'autre avantage est que la lecture d'arguments est assortie du gel des catcodes qui n'existe pas ici.\idx*[|)]{paragraphe!ressorts de paragraphe}

\subsection{Ressorts prédéfinis}
Les ressorts-primitives modifiables --~ceux qui étaient précédés d'une étoile dans le tableau de la page~\pageref{tableau.ressort}~-- se comportent exactement comme s'ils étaient des macros définies avec \idx\newskip. La seule différence est que leur valeur est figée. On remarque que \idx\hfil et \idx\vfil sont compensés (c'est-à-dire annulés) par \idx\hfilneg et \idx\vfilneg.

Les ressorts \idx\hss et \idx\vss sont eux encore plus curieux puisque, de dimension nulle, ils peuvent s'étirer ou se comprimer infiniment. Nous verrons leur intérêt plus loin.

Voici comment nous pouvons utiliser \idx\hfill pour composer au fer à droite, au fer à gauche, centrer une ligne ou bien encore, régulièrement espacer zones de texte sur une ligne :

\showcode/a) \hfill Composition au fer à droite\par
b) Composition au fer à gauche\hfill\kern0pt\par
c) \hfill Centrage\hfill\kern0pt\par
d) Des \hfill mots\hfill régulièrement\hfill espacés/

Comment se justifie la présence de ces « \idx\kern\verb|0pt|» après les \idx\hfill en \idx{fin de ligne} ? Tout vient de la règle précédente qui stipule qu'un ressort qui se situe juste avant la fin d'un paragraphe (autrement dit juste avant \idx\par) est \emph{ignoré}. Ce \verb|\kern0pt| n'a d'autre but que de mettre quelque chose (on appelle cela un n\oe ud) entre le ressort et \idx\par. Bien évidemment, la dimension de ce n\oe ud doit être nulle afin que son encombrement ne fausse pas la largeur des éléments pris en compte. Au lieu d'écrire \verb|\kern0pt|, il est également courant d'employer la macro \idx\null définie par plain-\TeX{} dont le texte de remplacement est une boite horizontale vide, c'est-à-dire \idx\hbox\verb|{}|\idx*[|)]{registre!ressort}\idx*[|)]{dimension étirable (ressort)}\idx*[|)]{dimension}.

\section{Les boites}\label{boites}\idx*[|(]{boite}
Dans le monde de \TeX{}, presque tout ce qui concerne la composition est lié aux boites. Les dimensions sont notamment utilisées pour mesurer les caractéristiques géométriques de ces boites. Les ressorts eux, sont chargés de remplir des zones dans ces boites.

Avant de commencer, il est important de comprendre qu'une boite reçoit du code source transmis sous la forme d'un argument, mais prend en compte le résultat typographique de ce code \emph{une fois qu'il a été composé}. Les assignations sont mises à part pour être exécutés lorsque la boite est affichée. Ainsi, mettre quelque chose dans une boite implique donc au préalable le travail complet de composition.

\subsection{Fabriquer des boites}
Si \TeX{}, de par son fonctionnement lors de la composition, fabrique automatiquement des boites pour les placer sur la page, des primitives permettent à l'utilisateur de fabriquer ses propres boites avec la possibilité d'y mettre un contenu arbitraire.

\begin{regle}
	\relax\TeX{} dispose de trois primitives pour enfermer un matériel dans une boite :
	
	\begin{itemize}
		\item \idx\hbox\verb|{<code>}| construit une boite \emph{horizontale} contenant du matériel (qui est le résultat de la composition du \verb|<code>|) disposé en mode horizontal\idx*{mode!horizontal} et compatible avec ce mode;
		\item \idx\vbox\verb|{<code>}| et \idx\vtop\verb|{<code>}| bâtissent des boites \emph{verticales}, susceptibles donc de recevoir du matériel disposé en mode vertical\idx*{mode!vertical} et compatible avec ce mode.
	\end{itemize}

	Dans les trois cas, l'intérieur d'une boite tient lieu de groupe, c'est-à-dire que les assignations faites dans le \verb|<code>| restent locales à la boite.
	
	Le \verb|<code>| n'est pas lu en une fois comme s'il était l'argument d'une macro; il est lu \emph{au fur et à mesure} que la boite se remplit et donc au fil de cette lecture, des changements de catcode sont permis.

	Une boite ainsi construite peut être :
	
	\begin{itemize}
		\item affichée lorsque \idx\hbox, \idx\vbox ou \idx\vtop sont placés dans le flux d'entrée de \TeX. Dans ce cas, la boite est ajoutée à la liste en cours selon le mode dans lequel \TeX{} travaille à ce moment (\idx*{boite!mode}horizontal\idx*{mode!horizontal} ou vertical\idx*{mode!vertical}). Il est important de noter que ni \idx\hbox ni \idx\vbox ou \idx\vtop ne provoquent de changement de mode, même si à l'intérieur de ces boites, un mode «interne»\idx*{mode!interne} est imposé;
		\item stockée dans un registre de boite (voir la section suivante).
	\end{itemize}
\end{regle}

Le code ci-dessous démontre que les boites s'affichent selon le mode en cours :

\showcode/a% le caractère "a" fait passer en mode horizontal¤\idx*{mode!horizontal}¤
\hbox{b}c\hbox{d}% les \hbox sont ajoutées en mode horizontal¤\idx*{mode!horizontal}¤
\medbreak
...à comparer avec...
\medbreak
a \par% \par fait passer en mode vertical¤\idx*{mode!vertical}¤
\hbox{b}% \hbox est ajoutée à la liste verticale
c% "c" fait passer en mode horizontal¤\idx*{mode!horizontal}¤
\hbox{d}% la \hbox est ajoutée en mode horizontal/

Il est important de se souvenir de cette règle lorsqu'on construit une macro dont le premier acte est d'afficher une boite construite avec une des trois primitives vues ci-dessus. En effet, on souhaite souvent placer d'autres choses à droite de cette boite (en mode horizontal donc). Si la macro est appelée en mode vertical, le placement se fera \emph{en dessous}, et non pas \emph{après} comme attendu. Pour se prémunir de ce risque, il est \emph{très sage} de mettre un \idx\leavevmode avant la boite pour quitter le mode vertical\idx*{mode!vertical}. Ce faisant, la boite sera composée en mode horizontal\idx*{mode!horizontal} et le comportement recherché sera obtenu.
\grandsaut

Les boites construites avec \idx\vbox ou \idx\vtop empilent verticalement des éléments. Ces éléments sont susceptibles d'être mis dans une liste verticale car, à l'intérieur de \idx\vbox ou \idx\vtop, on est dans le mode vertical (plus exactement en mode vertical \emph{interne}\idx*{mode!vertical interne}). Ce sont par exemple des paragraphes (qui ont une largeur égale à \idx\hsize), des boites formées avec une des trois primitives, des ressorts verticaux insérés avec \idx\vskip, des réglures (que nous verrons un peu plus loin), etc.

Autant la largeur d'une \idx\hbox est clairement la largeur du matériel que l'on y a mis, autant celle d'une \idx\vbox ou \idx\vtop est moins évidente; La largeur d'une boite verticale est celle de l'élément empilé verticalement qui a la plus grande largeur. Mais attention, si on écrit  «\verb|\vbox{foobar}|» ou «\verb|\vtop{foobar}|», \TeX{} composera un paragraphe pour ce seul mot et mettra cet élément dans la boite. Or, la largeur des paragraphes est égale à la dimension-primitive \idx\hsize qui, dans le mode vertical principal, contient la largeur de la zone de texte. L'intérieur d'une boite jouant le rôle de groupe, on peut certes modifier \idx\hsize dans une boite verticale pour imposer aux paragraphes une largeur choisie. Sans cette man\oe uvre pour modifier \idx\hsize, la largeur de la boite sera la même que celles des paragraphes de la page, ce qui est peut-être un peu surdimensionné pour un paragraphe aussi court que «foobar» ! Au contraire, si l'on écrit «\verb|\vbox{\hbox{foobar}}|» ou «\verb|\vtop{\hbox{foobar}}|», l'élément qu'est la \idx\hbox sera inséré (en mode vertical\idx*{mode!vertical}) et au final, la boite verticale aura la largeur de cet élément, c'est-à-dire la largeur du mot « foobar ».

\begin{regle}
Les primitives \idx\vbox et \idx\vtop définissent des boites dans lesquelles des éléments sont empilés verticalement.

La différence entre \idx\vbox et \idx\vtop réside dans le \idx{point de référence} de la boite finale. Dans les deux cas, les éléments sont empilés verticalement, le premier étant en haut et le dernier en bas. Avec \idx\vbox, le point de référence de la boite est le point de référence du \emph{dernier} élément (celui du bas) alors qu'avec \idx\vtop, son point de référence est celui du \emph{premier} élément (celui du haut).
\end{regle}

Le \idx{point de référence} d'une boite étant sur la \idx{ligne de base}, on comprend donc que \idx\vbox construit des empilements ayant des éléments au-dessus de cette ligne et donc produit en général des boites de grande hauteur et faible profondeur. À l'opposé, \idx\vtop produit des empilements ayant des éléments sous cette \idx{ligne de base} et donc des boites de petite hauteur et grande profondeur.
\grandsaut

Dans l'exemple ci-dessous, on met dans une \idx\vbox et une \idx\vtop des éléments dont la largeur est contrôlé puisque ce sont des \idx\hbox. On peut observer, grâce aux points qui représentent approximativement la \idx{ligne de base} la différence fondamentale entre une \idx\vbox et une \idx\vtop :

\showcode/Ligne de base : .........%
\vbox{\hbox{ligne du haut}\hbox{ligne du milieu}\hbox{ligne du bas}}%¤\idx*\vbox¤
.........%
\vtop{\hbox{ligne du haut}\hbox{ligne du milieu}\hbox{ligne du bas}}.........¤\idx*\vtop¤/

Voici ce qui se passe en dessinant les boites et leur \idx{point de référence} :

\begin{centrage}
\footnotesize
\leavevmode\setbox0=\hbox{ligne du milieu}
Ligne de base.........%
\drawbox{\vbox{\raggedright\hsize\wd0 \drawbox{ligne du haut}\par\drawbox{ligne du milieu}\par\drawbox{ligne du bas}}}%
.........%
\drawbox{\vtop{\raggedright\hsize\wd0 \drawbox{ligne du haut}\par\drawbox{ligne du milieu}\par\drawbox{ligne du bas}}}%
.........%
\end{centrage}

Nous allons maintenant faire de même avec un élément dont la largeur n'est pas contrôlée, c'est-à-dire un paragraphe entier composé de deux phrases identiques contenues dans la macro \verb|\dummytext|. Afin que les deux boites tiennent horizontalement dans l'espace qui leur est réservé, la largeur des boites verticales sera imposée par \idx\hsize à \numprint[cm]4 :

\showcode/\def\dummytext{Bla, bla, bla, un texte sans importance. }
Ligne de base.........%
\vbox{\hsize=4cm \dummytext\dummytext}%¤\idx*\vbox¤
.........%
\vtop{\hsize=4cm \dummytext\dummytext}.........¤\idx*\vtop¤/

\subsection{Registres de boite}\idx*[|(]{boite!registre}
Une boite simplement affichée avec \idx\hbox, \idx\vbox ou \idx\vtop ne permet pas de travailler sur cette boite. En revanche, une boite \emph{stockée} dans un registre ouvre d'autres perspectives puisqu'elle est mémorisée par \TeX. Dès lors, il devient possible d'effectuer des opérations sur ces boites.

Avant de poursuivre, il encore une fois est important de clarifier le sens du mot « stockage ». Autant les macros et les registres de tokens stockent du \emph{code source tokénizé} c'est-à-dire du matériau brut initial, autant les registres de boites stockent d'un côté le résultat typographique d'un \verb|<code>| une fois qu'il a été composé et de l'autre les assignations faites dans ce \verb|<code>|. Le stockage par macro et par boite sont deux stockages opposés en ce sens que chacun effectue une sauvegarde à l'un des deux bouts de la chaine qui mène du code source à l'affichage final.
\grandsaut

Nous commençons à être familiers avec les registres puisque, hormis les macros, il en existe pratiquement pour chaque type de donnée que manipule \TeX{} (tokens, entiers, dimensions, ressorts). Les boites ne font évidemment pas exception à la règle, même si la syntaxe des registres de boites est légèrement différente de celle des autres registres. La raison incombe au fait que \TeX{} ne possède pas de primitive \verb|\boxdef| alors qu'il possède \idx\toksdef, \idx\countdef, \idx\dimendef et \idx\skipdef.

\begin{regle}
\relax\TeX{} dispose de 256 registres de boites (\numprint{32768} avec \idx\eTeX).

On demande à \TeX{} d'allouer un numéro de registre de boite par l'intermédiaire de la macro \idx\newbox\verb|\<macro>| et ce faisant, l'assignation suivante est faite

\centrecode-\global\chardef\<macro>=<nombre>-

où le \verb|<nombre>| est un numéro de registre de boite libre.

Ce faisant, la \verb|\<macro>| devient équivalente à \idx\char\verb|<nombre>|. Ainsi, \verb|\<macro>| produit le caractère de code \verb|<nombre>|, mais lorsque \TeX{} s'attend à lire un nombre (comme c'est le cas lorsqu'il attend un numéro de boite), \verb|\<macro>| est lue comme l'entier \verb|<nombre>|. Du point de vue de la mécanique interne, un \verb|<registre>| de boite est donc un \verb|<nombre>|.

On accède à la boite contenue dans un registre par \idx\box\verb|<registre>|.

Pour procéder à l'assignation, on écrit\idx*{assignation!registre de boite}\idx*\setbox :

\centrecode-\setbox<registre>= <boite valide>-

\noindent où une \verb|<boite valide>| est soit une boite contenue dans un registre et écrite sous la forme \idx\box\verb|<registre>|, soit une boite construite avec les primitives \idx\hbox, \idx\vbox ou \idx\vtop. Le signe \verb|=| et l'espace qui le suit sont facultatifs.

Pour afficher une boite stockée dans un \verb|<registre>|, on écrit \idx\box\verb|<registre>|. La boite est affichée selon le mode en cours (horizontal ou vertical) : le type de boite n'a pas d'influence sur le mode dans lequel elle est affichée.

Lorsqu'on utilise la primitive \idx\box pour accéder à la boite stockée dans un registre, la boite contenue dans le registre est irrémédiablement perdue et le registre devient vide, c'est-à-dire qu'il ne contient aucune boite. Si on souhaite conserver la boite dans le registre, on doit utiliser la primitive \idx\copy au lieu de \idx\box.
\end{regle}

\begin{regle}
Le test\tidx*{ifvoid}%

\centrecode-\ifvoid<registre><code vrai>\else<code faux>\fi-

se comporte comme les autres tests de \TeX. Il revoit \verb|<code vrai>| si le \verb|<registre>| de boite est vide (c'est-à-dire s'il ne contient aucune boite).
\end{regle}

Il est admis que la boite \no0\idx*{boite!\no0} est une boite « brouillon » qui peut être utilisée ponctuellement si l'on ne veut pas mobiliser un nouveau registre de boite.
\grandsaut

L'exemple ci-dessous illustre ce que nous venons d'aborder. Nous allons tout d'abord allouer un nouveau registre \verb|\foobox| par \idx\newbox et nous y stockerons une boite horizontale contenant le mot « foobar ». Ensuite, nous allons utiliser le test \tidx{ifvoid} dans plusieurs cas de figure afin de montrer que le registre devient vide après avoir exécuté la primitive \idx\box.

\showcode/\newbox\foobox¤\idx*\newbox¤
a) \setbox\foobox=\hbox{foobar}% registre non vide¤\idx*\setbox¤
   Le registre est \ifvoid\foobox vide\else non vide\fi\par
b) \setbox\foobox=\hbox{foobar}
   "\box\foobox" et le registre est \ifvoid\foobox vide\else non vide\fi\par
c) \setbox\foobox=\hbox{foobar}
   "\copy\foobox" et le registre est \ifvoid\foobox vide\else non vide\fi\par
d) \setbox\foobox=\hbox{}
   Le registre est \ifvoid\foobox vide\else non vide\fi¤\tidx*{ifvoid}¤/

On remarque que \idx\box vide le registre (cas b) tandis que \idx\copy le préserve (cas c). Il est également important de noter que le registre n'est pas vide (cas d) s'il contient une boite vide.
\grandsaut

Deux autres tests sur les registres de boite méritent d'être signalés :

\begin{centrage}
\small\tidx{ifhbox}\verb|<registre>|\quad et\quad\tidx{ifvbox}\verb|<registre>|
\end{centrage}

\noindent sont vrais si le \verb|<registre>| contient respectivement une boite horizontale ou verticale.\idx*[|)]{boite!registre}

\subsection{Dimensions des boites}\idx*[|(]{boite!dimension}
\begin{regle}
Les dimensions d'une boite stockée dans un \verb|<registre>| sont :
\begin{itemize}
	\item sa longueur horizontale, accessible par \idx\wd\verb|<registre>| ;
	\item sa hauteur, qui s'étend au-dessus de la \idx{ligne de base}, accessible par \idx\ht{}\linebreak[1]\verb|<registre>| ;
	\item enfin, sa profondeur qui s'étend au-dessous de la \idx{ligne de base} et qui est accessible par \idx\dp\verb|<registre>|.
\end{itemize}

Les primitives \idx\wd, \idx\ht et \verb|\dp| suivies d'un \verb|<registre>| se comportent comme des registres de dimension.
\end{regle}

\noindent Pour fixer les idées, voici un schéma où les \idx*{boite!englobante}boites englobantes, rectangles qui représentent l'encombrement d'une boite tel qu'il est pris en compte par \TeX, sont tracées et les trois dimensions sont écrites pour quatre lettres différentes :\medbreak

\noindent\hskip0.1\linewidth\hbox to0pt{\dimenbox{g}\hss}\hskip0.5\linewidth\hbox to0pt{\dimenbox{o}\hss}\medbreak
\noindent\hskip0.1\linewidth\hbox to0pt{\dimenbox{P}\hss}\hskip0.5\linewidth\hbox to0pt{\dimenbox{\itshape f}\hss}\medbreak

On peut observer notamment avec la lettre «\textit{f}\kern1pt» que la boite englobante\idx*{boite!englobante} ne correspond pas à la plus petite boite qui contient les contours de la lettre. Pour d'évidentes raisons de typographie, il est \emph{nécessaire} que certaines parties de la lettre «\textit{f}» dépassent de la boite englobante\idx*{boite!englobante} sinon, au lieu de «\textit{foo}», nous aurions un horrible «\textit{f\kern1.65ptoo}» !

De plus, contrairement à ce que l'on pourrait croire, la profondeur de lettres comme «o» ou «P» n'est pas nulle ! Très faible certes, mais pas nulle\ldots{} Le concepteur de la \idx{fonte} «Libertine» avec laquelle est écrit ce livre en a décidé ainsi.
\grandsaut

Passons à la pratique et mesurons maintenant les dimensions de boites construites successivement avec les trois primitives \idx\hbox, \idx\vbox et \idx\vtop. Les boites verticales seront des empilements de \idx\hbox, chacune contenant un mot de la phrase «Programmer est facile.»

\showcode/\newbox\foobox¤\idx*\newbox¤
\setbox\foobox=\hbox{Programmer est facile.}¤\idx*\setbox¤
<<\copy\foobox>>¤\idx*\copy¤
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.¤\idx*\the\idx*\wd\idx*\dp¤
\medbreak¤\idx*\medbreak¤

\setbox\foobox=\vbox{\hbox{Programmer}\hbox{est}\hbox{facile.}}¤\idx*\setbox¤
<<\copy\foobox>>
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.
\medbreak¤\idx*\medbreak¤

\setbox\foobox=\vtop{\hbox{Programmer}\hbox{est}\hbox{facile.}}¤\idx*\setbox\idx*\vtop¤
<<\copy\foobox>>
mesure \the\wd\foobox\ de long, \the\dp\foobox\ de profondeur et \the\ht\foobox\ de haut.¤\idx*\the\idx*\wd\idx*\dp¤/

La faible profondeur de la \idx\vbox provient une fois encore du design de la \idx{fonte} Libertine qui donne une faible profondeur à certaines lettres qui composent le mot du bas «facile». La verticalité \emph{totale} des boites verticales (c'est-à-dire la somme de leur hauteur et de leur profondeur) \idx\vbox et \idx\vtop est la même dans les deux cas.

\begin{exercice}
Programmer une macro §\vdim\verb|{<registre>}| qui calcule la verticalité de la boite contenue dans le \verb|<registre>|.
\solution
Il suffit de donner à \idx\dimexpr l'addition de sa hauteur et sa profondeur :

\showcode/\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}¤§*\vdim¤
a) \setbox\foobox=\vbox{\hbox{Programmer}\hbox{est}\hbox{facile.}}¤\idx*\setbox¤
   Verticalité de la \litterate-\vbox- = \the\vdim\foobox\par¤§*\litterate\idx*\the¤
b) \setbox\foobox=\vtop{\hbox{Programmer}\hbox{est}\hbox{facile.}}¤\idx*\setbox¤
   Verticalité de la \litterate-\vtop- = \the\vdim\foobox¤§*\litterate\idx*\the¤/
\end{exercice}

\begin{exercice}
Inventer un procédé qui permette de compter combien de caractères affichables contient un argument. On appellera la macro §\countallchar\verb|{<texte>}| et on supposera que le \verb|<texte>| est uniquement constitué de caractères affichables (catcodes 11 et 12) et d'espaces.
\solution
Au point où nous en sommes, la solution la plus immédiate est de mettre cet argument dans une boite \idx\hbox où la \idx{fonte} sera à chasse fixe. Il suffit de mesurer cette boite, de mesurer un caractère et d'effectuer la division entre les entiers contraints de ces deux dimensions pour afficher le nombre de caractères. Ici, nous allons même afficher la division conduisant au résultat :

\showcode|\def\countallchar#1{%¤§*\countallchar¤
	Il y a %
	\setbox0=\hbox{\tt#1}% met #1 dans la boite¤\idx*\setbox¤
	\edef\arglength{\number\wd0 }% stocke la largeur de la boite en sp¤\idx*\number\idx*\wd\idx*{sp (unité)}¤
	\setbox0=\hbox{\tt A}% met "A" dans la boite¤\idx*\setbox¤
	\edef\charlength{\number\wd0 }% stocke la largeur d'un caractère
	$\number\arglength/\charlength % affiche la division¤\idx*\wd¤
	=\number\numexpr\arglength/\charlength\relax$ % affiche le quotient¤\idx*\wd¤
	caractères%
}
\countallchar{abcd efgh}\par
\countallchar{A5 xW5 64 a1}\par
\countallchar{affligeant}¤§*\countallchar¤|

Une méthode similaire peut être déployée pour compter combien de fois figure un caractère affichable $\alpha$ dans un argument. L'idée est de mesurer la boite contenant l'argument composé en fonte à chasse fixe et stocker cette longueur dans $L$. Ensuite, le caractère $\alpha$ est supprimé avec la macro §\substin et la man\oe uvre est répétée : $l$ est la nouvelle longueur. Le nombre d'occurrences de $\alpha$ est la différence $L-l$ divisée par la longueur de la boite contenant $\alpha$ :

\showcode|\catcode`@11
\def\countchar#1#2{%
		\setbox\z@\hbox{\tt#2}% met #2 dans boite 0¤\idx*\setbox\idx*\tt §*\defactive\idx*\string\idx*\hbox\idx*\z@¤
		\edef\len@a{\number\wd\z@}% mesure la boite¤\idx*\wd¤
		\setbox\z@\hbox{\tt\substin{#2}{#1}{}}% recommencer sans "#1"¤\idx*\setbox§*\defactive¤
		\edef\len@b{\number\wd\z@}% mesure la boite
		\setbox\z@\hbox{\tt A}% met "A" dans la boite¤\idx*\setbox\idx*\string¤
		\edef\charlength{\number\wd\z@}% stocke la largeur du caractère
		\number\numexpr(\len@a-\len@b)/\charlength% et affiche le quotient
}
\catcode`@12
a) \countchar{a}{abracadabra}\qquad
b) \countchar{b}{zigzag}\qquad
c) \countchar{ }{a bc de f ghi j k }¤§*\countchar¤|
\end{exercice}\idx*[|)]{boite!dimension}

\subsection{Déplacer des boites}\idx*[|(]{boite!déplacement}
\TeX{} met à disposition des primitives pour déplacer des boites dans la direction que l'on veut (haut, bas, gauche, droite).

\begin{regle}
Les primitives \idx\lower ou \idx\raise doivent être suivies d'une \verb|<dimension>|, le tout devant précéder une boite horizontale, qu'elle soit écrite par l'intermédiaire de \idx\hbox ou d'un registre. L'effet est d'abaisser pour \idx\lower ou d'élever pour \idx\raise la boite de la \verb|<dimension>| spécifiée.

Les primitives \idx\moveleft et \idx\moveright partagent la même syntaxe, mais agissent sur des boites \emph{verticales} en les déplaçant vers la gauche ou vers la droite.
\end{regle}

Voici comment on peut enfermer des mots dans une \idx\hbox et les élever ou les abaisser d'une dimension arbitraire :

\showcode/Programmer \raise1ex\hbox{en} \lower1ex\hbox{\TeX} \lower2ex\hbox{est} facile.¤\idx*\raise\idx*\lower\idx*\hbox¤/

Il faut d'ailleurs noter que le logo «\TeX», obtenu en exécutant la macro \index{TeX@\texttt{\char92 TeX}}\verb|\TeX|, est construit en utilisant \idx\lower pour abaisser la lettre «E» après rebroussé chemin vers la gauche à l'aide de \idx\kern. La lettre «X» est également déplacée vers la gauche avec un autre \idx\kern. Voici comment est définie la macro \index{TeX@\texttt{\char92 TeX}}\TeX{} par plain-\TeX :

\centrecode|\def\TeX{T\kern-.1667em\lower.5ex\hbox{E}\kern-.125emX}|
\grandsaut

Il peut sembler frustrant que l'on ne puisse pas « centrer » une boite contenant du matériel vertical par rapport à l'axe qu'est la \idx{ligne de base} puisque \idx\vbox et \idx\vtop empilent ce matériel respectivement au-dessus ou au-dessous de cette ligne. L'idée serait d'abaisser ces boites avec \idx\lower de la dimension égale à

\[\frac{\hbox{hauteur}-\hbox{profondeur}}2\]

\noindent étant entendu que si cette quantité est négative, abaisser d'une dimension négative revient à élever la boite. En coulisses, cette méthode nous contraint à mettre la boite dans un registre pour pouvoir la mesurer afin d'accéder à sa hauteur et sa profondeur. La macro §\cbox va mettre en application cette méthode et sera amenée à recevoir du matériel vertical dans les mêmes conditions que \idx\vbox afin de centrer la boite par rapport à la \idx{ligne de base} :

\showcode|\def\cbox#1{%¤§*\cbox¤
	\setbox0\vbox{#1}% met le contenu dans une \vbox¤\idx*\setbox\idx*\vbox¤
	\lower\dimexpr(\ht0-\dp0)/2\relax\box0 % l'abaisse¤\idx*\lower\idx*\dimexpr\idx*\ht\idx*\dp\idx*\box¤
}

......\cbox{\hbox{$x^2$}}......\cbox{\hbox{foo}\hbox{et bar}}......%
\cbox{\hbox{Programmer}\hbox{en \TeX}\hbox{est facile}}.......¤§*\cbox¤|

\TeX{} dispose de la primitive \idx\vcenter, qui fonctionne en mode mathématique\idx*{mode!mathématique}, dont l'argument est constitué de matériel vertical (comme l'est celui de \idx\vbox ou \idx\vtop) et qui place la boite ainsi créé de telle sorte que ses frontières haute et basse soient équidistantes de «l'axe mathématique». Deux précisions doivent être apportées :

\begin{itemize}
	\item la primitive ne peut être appelée qu'en mode mathématique\idx*{mode!mathématique}, mais le contenu de la boite n'hérite pas de ce mode, c'est-à-dire qu'il sera composé en mode texte, sauf si bien sûr, on demande explicitement à passer en mode mathématique\idx*{mode!mathématique} à l'intérieur de la boite (les boites \idx\hbox, \idx\vbox et \idx\vtop partagent aussi cette propriété) ;
	\item l'axe mathématique \emph{n'est pas} à la même hauteur que la \idx{ligne de base}; il s'agit de deux axes différents. L'axe mathématique est horizontal et se trouve approximativement à équidistance des traits horizontaux du signe «$=$». Il représente l'axe de symétrie horizontal de plusieurs signes mathématiques alors que la \idx{ligne de base} est approximativement tangente au bas des lettres qui n'ont pas de jambage comme on le voit dans l'égalité ci-dessous :
	\begin{centrage}
		\begingroup\huge
		\setbox0\hbox{$\vcenter{}$}%
		\xdef\htmath{\the\ht0}%
		\endgroup
		\begin{tikzpicture}[inner sep=0pt,outer sep=0pt,minimum size=0pt,baseline,line width=0.2pt]
			\node[anchor=base west](equation){\huge $a\kern.125em(b+c)=ab+ac$};
			\draw[gray]([xshift=-2cm]equation.base west)--([xshift=0.2cm]equation.base east)node[pos=0,anchor=south west,outer sep=1pt,black]{\scriptsize ligne}node[pos=0,anchor=north west,outer sep=1pt,black]{\scriptsize de base};
			\draw[gray]([xshift=-0.2cm,yshift=\htmath]equation.base west)--([xshift=2cm,yshift=\htmath,black]equation.base east)node[pos=1,anchor=south east,outer sep=1pt,black]{\scriptsize axe}node[pos=1,outer sep=1pt,anchor=north east,black]{\scriptsize math};
		\end{tikzpicture}
	\end{centrage}
\end{itemize}

Par conséquent, une boite centrée avec \idx\vcenter ne sera pas exactement à la même hauteur que la même boite centrée avec la macro §\cbox vue précédemment. La différence se voit sans peine à l'\oe il nu dans cet exemple :

\showcode|......\cbox{\hbox{foo}\hbox{et bar}}......$\vcenter{\hbox{foo}\hbox{et bar}}$......¤\idx*\vcenter§*\cbox¤|\idx*[|)]{boite!déplacement}

\begin{exercice}
Inventer un procédé pour que la macro §\htmath affiche à quelle distance de la ligne de base se trouve l'axe mathématique.
\solution
Si une \idx\hbox contient une \idx\vcenter vide, la hauteur de la \idx\hbox sera précisément la distance cherchée.

\showcode/\def\htmath{\begingroup¤§*\htmath¤
	\setbox0=\hbox{$\vcenter{}$}\the\ht0 ¤\idx*\setbox\idx*\vcenter\idx*\the\idx*\ht¤
\endgroup
}
L'axe mathématique se trouve à \htmath{} de la ligne de base./
\end{exercice}

\subsection{Choisir la dimension d'une boite}\idx*[|(]{boite!dimension choisie}
\begin{regle}
On peut imposer une dimension aux boites en le spécifiant avec le mot-clé «\idx*{boite!mot-clé «to»}\verb|to|» suivi d'un espace optionnel puis d'une \verb|<dimension>|. Et donc, si l'on écrit

\centrecode-\hbox to 3cm{<contenu>}-

\noindent cela créera une boite horizontale de longueur \numprint[cm]{3}, quel que soit le \verb|<contenu>|. Si le contenu ne mesure pas \emph{exactement} \numprint[cm]{3} et ne contient aucun élément étirable, il y aura soit un débordement, soit un sous-remplissage de boite, chacun respectivement signalé par les messages d'avertissement\idx*{message d'avertissement} «\texttt{Overfull \string\hbox}» ou «\texttt{Underfull \string\hbox}» dans le \idx[!log]{fichier} \verb|log|. La même syntaxe s'applique pour \idx\vbox et \idx\vtop sauf que la dimension est imposée dans le sens \emph{vertical}.

On peut également écrire le mot-clé «\idx*{boite!mot-clé «spread»}\verb|spread|» utilisé à la place de «\verb|to|» si l'on souhaite construire une boite dont la dimension finale sera sa dimension naturelle augmentée de la \verb|<dimension>|. Si cette dimension est négative, la boite créée aura une dimension inférieure à sa dimension naturelle.
\end{regle}

Voici un exemple qui montre comment une boite est affichée avec sa largeur naturelle puis étirée de \verb|5pt| et \verb|10pt| grâce à un ressort \idx\hfil placé entre les syllabes «\verb|foo|» et «\verb|bar|»:

\showcode/1) \hbox{foobar}\par¤\idx*\hbox¤
2) \hbox spread 5pt{foo\hfil bar}\par
3) \hbox spread10pt{foo\hfil bar}/

\Qu e ce soit via «\verb|to|» ou «\verb|spread|», il est nécessaire que contenu de la boite ait un ou plusieurs ressorts. Ils devront avoir des composantes étirables convenablement choisies pour qu'en s'étirant ou en se comprimant, ils puissent compenser l'excès ou le manque de place pour le contenu. Un des ressorts les plus utilisés dans ce cas est \idx\hss pour les boites horizontales et \idx\vss pour les boites verticales. Rappelons qu'ils ont une longueur nulle et peuvent s'étirer ou se comprimer infiniment.
\grandsaut

On peut facilement créer des macros qui affichent du texte \emph{en surimpression} soit à droite, soit à gauche de la position courante. Ces deux macros, \idx\rlap et \idx\llap, dont le nom signifie « right overlap » (surimpression vers la droite) ou « left overlap » (surimpression vers la gauche) sont ainsi définies dans le \idx[!plain-\TeX]{format} plain-\TeX :

\centrecode-\def\rlap#1{\hbox to\z@{#1\hss}}¤\idx*\z@¤
\def\llap#1{\hbox to\z@{\hss#1}}-

Examinons tout d'abord \idx\rlap. Son argument \verb|#1| est mis dans une boite horizontale de longueur nulle (\idx\z@ représente la dimension \verb|0pt|). Un sur-remplissage de la boite semble inévitable, car le contenu \verb|#1| prend une certaine place horizontale. C'est là que le ressort \idx\hss placé en fin de boite va intervenir : pour satisfaire la longueur de la boite nulle, il va se comprimer pour atteindre une longueur négative exactement égale à l'opposé de la longueur de l'argument \verb|#1|. La somme des longueurs de \verb|#1| et de \idx\hss satisfait bien la dimension nulle imposée.

\begin{centrage}
	\footnotesize
	\begin{tikzpicture}
		\useasboundingbox (-3,-2) rectangle (4,1);
		\draw[line width=1pt](0,-2)--(0,0)node[above,align=center,text width=1.5cm]{Position courante};
		\node[draw,anchor=mid west,align=center,text width=3cm,inner sep=0pt,outer sep=0pt](arg1)at(0,-.5){\vrule height2.5ex depth1.5ex width0pt Argument \ttfamily \#1}node[anchor=mid west] at(4,-.5){Étape \no1};
		\draw [-stealth](.15,-1.5)--(0,-1.5);
		\draw[decorate,decoration={zigzag,segment length=0.3cm,amplitude=1mm}] (.15,-1.5)--(3cm,-1.5)
			node[below,pos=.5,yshift=-.1cm]{ressort \ttfamily\string\hss}
			node[anchor=mid west] at(4,-1.5){Étape \no2};
	\end{tikzpicture}
\end{centrage}

Son homologue \idx\llap fonctionne de la même façon sauf que le ressort \idx\hss est placé en début de boite : il va donc se comprimer en premier ce qui se traduit à l'affichage par un recul vers la gauche de la longueur de \verb|#1|. Ensuite, \verb|#1| est composé et rattrape exactement la longueur négative de \idx\hss.

\begin{centrage}
	\footnotesize
	\begin{tikzpicture}
		\useasboundingbox (-3,-2) rectangle (4,1.5);
		\draw[line width=1pt](0,-2)--(0,0.5)node[above,align=center,text
 width=1.5cm]{Position courante};
		\node[draw,anchor=mid east,align=center,text width=3cm,inner sep=0pt,outer sep=0pt](arg1)at(0,-1.5){\vrule height2.5ex depth1.5ex width0pt Argument\ttfamily  \#1}node[anchor=mid west] at(.5,-1.5){Étape \no2};
		\draw [-stealth](-2.85,-.5)--(-3,-.5);
		\draw[decorate,decoration={zigzag,segment length=0.3cm,amplitude=1mm}] (-2.85cm,-0.5)--(0,-0.5)
			node[above,pos=.5,yshift=.1cm]{ressort \ttfamily\string\hss}
			node[anchor=mid west] at(.5,-0.5){Étape \no1};
	\end{tikzpicture}
\end{centrage}

L'exemple ci-dessous montre comment ces deux macros peuvent utilisées pour écrire soit à gauche, soit à droite de la position courante en surimpression. Dans les deux cas, le caractère «|» est utilisé pour symboliser la position courante lorsque \TeX{} rencontre ces deux macros :

\showcode=foobar|\rlap{/////}123456\qquad foobar|\llap{/////}123456¤\idx*\rlap\idx*\llap¤=

Il est curieux que \idx*{Knuth Donald}D.~\textsc{Knuth} n'ait pas implémenté la macro §\clap qui permettrait de centrer le contenu de son argument sur la position courante sans que l'encombrement horizontal ne soit pris en compte :

\centrecode-\def\clap#1{\hbox to0pt{\hss#1\hss}}-§*\clap

Bien sûr, le fonctionnement de cette macro est en tout point semblable à \idx\rlap et \idx\llap sauf que les deux ressorts se compriment de façon identique ce qui donne un centrage du contenu par rapport à la position courante:

\begin{centrage}
	\footnotesize
	\begin{tikzpicture}
		\useasboundingbox (-3,-3) rectangle (4,1);
		\draw[line width=1pt](0,-3)--(0,0)node[above,align=center,text width=1.5cm]{Position courante};
		\draw [-stealth](-1.35,-.5)--(-1.5,-.5);
		\draw[decorate,decoration={zigzag,segment length=0.3cm,amplitude=1mm}] (-1.35cm,-0.5)--(0,-0.5)
			node[below,pos=.5,yshift=-.1cm]{\ttfamily\string\hss}
			node[anchor=mid west] at(2,-0.5){Étape \no1};
		\node[draw,align=center,text width=3cm,inner sep=0pt,outer sep=0pt](arg1)at(0,-1.5){\vrule height2.5ex depth1.5ex width0pt Argument \ttfamily\#1}node[anchor=mid west] at(2,-1.5){Étape \no2};
		\draw [-stealth](0.15,-2.5)--(0,-2.5);
		\draw[decorate,decoration={zigzag,segment length=0.3cm,amplitude=1mm}] (1.5,-2.5)--(.15,-2.5)
			node[below,pos=.5,yshift=-.1cm]{\ttfamily\string\hss}
			node[anchor=mid west] at(2,-2.5){Étape \no3};
	\end{tikzpicture}
\end{centrage}

Des effets d'empilement peuvent être créés avec les macros \idx\raise et \idx\lower qui déplacent verticalement la prochaine boite horizontale d'une dimension choisie :

\showcode/\def\clap#1{\hbox to0pt{\hss#1\hss}}¤\idx*\hss§*\clap¤
a) avant la macro|\clap{SURIMPRESSION}après la macro\medbreak
b) avant la macro|\raise2.5ex\clap{Au-dessus}\lower2.5ex\clap{Au-dessous}%
   après la macro\medbreak¤\idx*\raise\idx*\lower§*\clap¤
c) avant la macro|\raise2.5ex\llap{Au-dessus avant}\lower2.5ex\rlap{Au-dessous après}%
   après la macro¤\idx*\rlap\idx*\llap¤/\idx*[|)]{boite!dimension choisie}

\newpage% TODO : pour ne pas que le titre de la sous section soit orphelin en bas de page
\subsection{Redimensionner une boite}\idx*[|(]{boite!redimensionnement}
\begin{regle}
Une fois qu'une boite est stockée dans un \verb|<registre>|, il est possible de modifier une ou plusieurs de ses dimensions. Il suffit d'écrire

\begin{centrage}
\small$\left.\vcenter{\ttfamily\hbox{\string\wd}\hbox{\string\ht}\hbox{\string\dp}}\right\}$\verb|<registre>= <dimension>|\idx*\wd\idx*\ht\idx*\dp
\end{centrage}

\noindent pour que la largeur, hauteur ou profondeur de la boite prenne la dimension indiquée, indépendamment de ce qu'est le contenu de la boite. Ces assignations sont toujours \emph{globales}\idx*{assignation!toujours globale}. En procédant de cette façon, le contenu reste intact, mais \TeX{} est trompé et voit désormais la boite avec les nouvelles dimensions.
\end{regle}

Un peu à la manière de \idx\rlap, il devient ainsi possible de superposer une boite au texte qui la suit :

\showcode |\setbox0=\hbox{\tt//////////}¤\idx*\tt\idx*\setbox¤
\wd0=0pt % fait croire à TeX que la larguer de la boite est nulle¤\idx*\wd¤
Voici \copy0 du texte partiellement barré...¤\idx*\copy¤|

Est-il possible de redonner au contenu d'une boite ainsi modifiée une nouvelle virginité quant à ses dimensions, et faire en sorte que ce contenu occupe à nouveau ses dimensions naturelles ?

\begin{regle}
Si un \verb|<registre>| de boite contient une boite horizontale ou verticale, il est possible d'extraire le contenu de la boite avec \idx\unhbox\verb|<registre>| ou \idx\unvbox\verb|<registre>|. La liste horizontale ou verticale contenue dans la boite est alors ajoutée à la liste courante en cours. Après cette opération, le registre de boite devient vide, c'est à dire positif au sens de \tidx{ifvoid}.

Pour ne pas vider le registre de boite, il faut employer \idx\unhcopy ou \idx\unvcopy.
\end{regle}

L'important à retenir de cette règle est que la liste ainsi extraite retrouve ses dimensions naturelles, même si les dimensions de la boite avaient été modifiées après coup.

\showcode/\def\printdim{largeur=\the\wd0 \qquad hauteur=\the\ht0 \qquad profondeur = \the\dp0 }¤\idx*\the\idx*\wd\idx*\ht¤
\setbox0=\hbox{Programmer en \TeX{} est facile}¤\idx*\setbox¤
a) \printdim\par
b) \wd0=0pt \ht0=0pt \dp0=0pt% rend toutes le dimensions nulles¤\idx*\wd\idx*\ht\idx*\dp¤
   \printdim\par
c) \setbox0=\hbox{\unhbox0 }% reprend les dimensions d'origine¤\idx*\hbox\idx*\unhbox\idx*\setbox¤
   \printdim/

Le point essentiel est que

\centrecode-\setbox<registre>=\hbox{\unhbox<registre>}-\idx*\unhbox

\noindent redonne au \verb|<registre>| de boite les dimensions naturelles de la boite qu'il contient. La méthode donnée pour une boite horizontale est également valable pour une boite verticale en remplaçant \idx\hbox par \idx\vbox ou \idx\vtop et \idx\unhbox par \idx\unvbox.\idx*[|)]{boite!redimensionnement}

\subsection{Tester si un registre de boite est vide}\label{tester.boite.vide}\idx*[|(]{boite!registre!vide}
Nous avons vu que le test \tidx{ifvoid}\verb|<registre>| est vrai si le registre de boite est vide. Il est tout de même très important d'insister sur la différence entre un registre vide (c'est à dire ne contenant aucune boite) et un registre contenant une boite vide.

Voici un exemple qui illustre le fait que si un registre contient une boite vide, il n'est pas vide !

\showcode/\setbox0=\hbox{}% le registre 0 contient une boite vide¤\idx*\setbox¤
Le registre \ifvoid0 est vide\else n'est pas vide\fi¤\tidx*{ifvoid}¤/

Dès lors se pose la question : « comment tester si un registre de boite est vide ?» La réponse dépend de ce qu'on entend par « vide ». Le parallèle devient évident avec un argument de macro qui n'était pas « vide » s'il contenait une macro vide telle que \idx\empty (voir page~\pageref{argument.vide}). Pour répondre à la question « comment tester si un registre de boite est vide », nous allons construire un test purement développable §\ifzerodimbox de syntaxe

\centrecode-\ifzerodimbox{<nombre>}{<code vrai>}{<code faux>}-

qui renvoie \verb|<code vrai>| si le registre est vide ou s'il contient une boite dont toutes les dimensions sont nulles, et faux dans tous les autres cas.

\showcode/\catcode`\@11
\def\ifzerodimbox#1{% #1=registre de boite¤§*\ifzerodimbox¤
% revoie vrai si le registre est vide ou contient une boite de dimensions nulles
	\csname% former la macro "\firstoftwo" ou "\secondoftwo"
	\ifvoid#1first%% si le registre est vide "first"¤\tidx*{ifvoid}¤
	\else% sinon
		\ifdim\wd#1=\z@% si la largeur¤\idx*\wd\idx*\z@¤
			\ifdim\ht#1=\z@% la hauteur¤\idx*\ht¤
				\ifdim\dp#1=\z@ first% et la profondeur=0pt, "first"¤\idx*\dp\idx*\z@¤
				\else second% dans les autres cas "second"
				\fi
			\else second%
			\fi
		\else second%
		\fi
	\fi
	oftwo% compléter avec "oftwo"
	\endcsname
}
\catcode`\@12
a) \setbox0=\hbox{}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox\tidx*{ifvoid}¤
b) \box0 % affiche la boite vide, le registre est maintenant "void"
   \ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
c) \setbox0=\hbox{x}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox¤
d) \wd0=0pt \ht0=0pt \dp0=0pt % rend toutes les dimensions nulles
   \ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox¤
e) \setbox0=\vbox{}\ifzerodimbox0{vrai}{faux} (et \ifvoid0 void\else non void\fi)¤\tidx*{ifvoid}§*\ifzerodimbox¤/

Le test est négatif dans le cas c, seul cas où le registre contient une boite de dimensions non nulles. Il est positif ailleurs, que la boite soit vide (cas a et e), que la boite soit non vide mais redimensionnée (cas d) ou que le registre soit vide (cas b).
\grandsaut

Le moteur \idx\eTeX{}\idx*{moteur!etex} nous donne une autre méthode, plus rapide et plus fiable pour tester si un registre de boite contient une boite \emph{vide}. Nous nous mettrons à l'abri du faux positif de l'exemple précédent (cas d) d'une boite non vide, mais redimensionnée pour que toutes ses dimensions soient nulles.

La primitive \idx\lastnodetype de \idx\eTeX{} est de type registre d'entier et à tout moment, selon sa valeur qui varie de $-1$ à 15, caractérise la nature du dernier n\oe ud composé. Les différents types sont exposés dans le manuel d'\idx\eTeX. Le type qui nous intéresse ici est celui qui est qualifié par l'entier $-1$ et qui caractérise un n\oe ud vide, c'est-à-dire résultant d'une liste vide.

L'idée est donc de composer le contenu de la boite, et de tester hors de cette boite si \idx\lastnodetype est strictement négatif, seul cas où la boite sera vide. Nous allons mettre en \oe uvre cette méthode pour construire une macro \emph{non développable} §\ifvoidorempty de syntaxe

\centrecode|\ifvoidorempty<registre>{<code vrai>}{<code faux>}|

\noindent qui renverra \verb|<code vrai>| si le \verb|<registre>| est vide ou contient une boite vide :

\showcode/\def\ifvoidorempty#1{% teste si le registre #1 est vide ou contient une boite vide¤§*\ifvoidorempty¤
	\ifvoid#1\relax¤\tidx*{ifvoid}¤
		\expandafter\firstoftwo
	\else
		\begingroup% dans un groupe
			\setbox0=% affecter à la boite 0¤\idx*\setbox¤
				\ifhbox#1\hbox\bgroup\unhcopy% un boite horizontale¤\idx*\hbox\tidx*{ifhbox}\idx*\unhcopy¤
				\else    \vbox\bgroup\unvcopy% ou verticale¤\idx*\vbox\idx*\unvcopy¤
				\fi% dans laquelle on compose
				#1\relax% #1 en dimensions naturelles
				\expandafter\egroup% sauter la fin de la boite
				\expandafter% et le \endgroup
		\endgroup
		\ifnum\lastnodetype=-1 % et tester si le dernier noeud est vide¤\idx*\lastnodetype¤
			\expandafter\expandafter\expandafter\firstoftwo
		\else
			\expandafter\expandafter\expandafter\secondoftwo
		\fi
	\fi
}
a) \setbox0=\hbox{}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox\tidx*{ifvoid}¤
b) \box0 % affiche la boite vide, le registre est maintenant "void"
   \ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par
c) \setbox0=\hbox{x}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox¤
d) \wd0=0pt \ht0=0pt \dp0=0pt % rend toutes les dimensions nulles
   \ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)\par¤\idx*\setbox¤
e) \setbox0=\vbox{}\ifvoidorempty0{vrai}{faux} (et \ifvoid0 void\else non void\fi)¤\tidx*{ifvoid}\idx*\setbox§*\ifvoidorempty¤/\idx*[|)]{boite!registre!vide}

\subsection{Mise en application}
Comment pourrions-nous enfermer dans une boite \idx\vtop des éléments mis dans des \idx\hbox qui soient tous centrés horizontalement les uns par rapport aux autres ? Le but est d'écrire

\centrecode/\cvtop{Ligne du haut,Très grande ligne du milieu,Ligne du bas pour finir}/

\noindent pour obtenir ceci

\begin{centrage}
\small
texte avant...\vtop{\halign{\hfil#\hfil\cr
Ligne du haut\cr Très grande ligne de milieu\cr Ligne de bas pour finir\crcr}}...texte après
\end{centrage}

Si nous empilons des \idx\hbox dans une \idx\vtop, nous ne pouvons pas centrer les \idx\hbox, car nous ne pouvons écrire ni \idx\hfill ni \idx\hss dans une \idx\vtop puisque le matériel y est vertical et que ces primitive, exclusivement horizontales, y sont interdites. Agir sur les ressorts de paragraphe \idx\leftskip et \idx\rightskip est sans effet puisque dans cette boite, \TeX{} ne compose pas de paragraphe, il ne fait qu'empiler des \idx\hbox verticalement.

La solution va consister à trouver la longueur $l$ de la plus longue \idx\hbox, puis composer toutes les boites \idx\hbox avec une longueur imposée $l$ en ayant pris soin de centrer le contenu avec des ressorts \idx\hss placés en début et en fin de boite. La macro \verb|\doforeach| vue précédemment nous sera d'un grand secours. La variable, que nous appelons \verb|\htext|, contiendra tout à tour à tour chaque élément de la liste, mais il faudra procéder en deux passes successives :

\begin{itemize}
	\item la première trouvera, en les examinant tour à tour, la \idx\hbox la plus longue et cette dimension maximale sera stockée dans le registre de dimension \verb|\maxhsize|;
	\item lors de la deuxième passe, nous écrirons à chaque itération
	
	\centrecode-\hbox to\maxhsize{\hss\htext\hss}-
	
	pour enfermer l'élément courant dans une \idx\hbox de longueur \verb|\maxhsize| et centré dans celle-ci à l'aide des ressorts-primitives \idx\hss.
\end{itemize}

Pour tester si la longueur de l'élément considéré est plus grande que celle du précédent, il faut d'abord initialiser \verb|\hmaxsize| à la plus petite dimension permise qui est l'opposé de la plus grande dimension \idx\maxdimen, registre de dimension défini dans plain-\TeX{} et qui vaut \verb|16383.99999pt|. Ensuite, si la dimension de l'élément est strictement supérieure à \verb|\hmaxsize|, nous actualiserons \verb|\hmaxsize| à la longueur de l'élément examiné. En fin de boucle, nous serons assurés que \verb|\hmaxsize| est la plus grande longueur.§*\cvtop[|(]

\showcode|\newdimen\hmaxsize¤\idx*\newdimen¤
\def\cvtop#1{%¤§*\cvtop¤
	\hmaxsize=-\maxdimen% initialise à la plus petite longueur¤\idx*\maxdimen¤
	\doforeach\htext\in{#1}% pour chaque élément :¤§*\doforeach¤
		{\setbox0=\hbox{\htext}% stocker l'élément "\htext" dans une \hbox¤\idx*\hbox\idx*\setbox¤
		\ifdim\wd0 >\hmaxsize% si sa longueur est supérieure à \hmaxsize¤\tidx*{ifdim}¤
			\hmaxsize=\wd0 % mettre à jour \hmaxsize¤\idx*\wd¤
		\fi
		}%
	\vtop{% dans une \vtop...¤\idx*\vtop¤
		\doforeach\htext\in{#1}% pour chaque élément :¤§*\doforeach¤
			{\hbox to\hmaxsize{\hss\htext\hss}% le centrer dans une \hbox de longueur \hmaxsize¤\idx*\hss¤
			}%
	}%
}

texte avant...\cvtop{Ligne du haut,Très grande ligne du milieu,Ligne du bas pour finir}%
...texte après|

\begin{exercice}
Proposer une autre façon de faire sans enfermer \verb|\htext| dans une \idx\hbox.
\solution
Chaque élément peut être composé comme un paragraphe. Pour cela, la longueur de la \idx\vtop doit être égale à \verb|\hmaxsize|, l'indentation doit être nulle et pour que les paragraphes soient centrés, \idx\leftskip et \idx\rightskip sont rendus égaux à \texttt{0pt plus 1fil}.

Cela donne :

\showcode|\newdimen\hmaxsize¤\idx*\newdimen¤
\def\cvtop#1{%¤§*\cvtop¤
	\hmaxsize=-\maxdimen% initialise à la plus petite longueur¤\idx*\maxdimen¤
	\doforeach\htext\in{#1}% pour chaque élément :¤§*\doforeach¤
		{\setbox0=\hbox{\htext}% stocker l'élément "\htext" dans une \hbox¤\idx*\hbox\idx*\setbox¤
		\ifdim\wd0 >\hmaxsize% si sa longueur est supérieure à \hmaxsize¤\tidx*{ifdim}¤
			\hmaxsize=\wd0 % mettre à jour \hmaxsize¤\idx*\wd¤
		\fi
		}%
	\vtop{% dans une \vtop...¤\idx*\vtop¤
		\hsize\hmaxsize % longueur de la \vtop = \maxhsize
		\parindent=0pt % pas d'indentation¤\idx*\parindent¤
		\leftskip=0pt plus1fil minus0pt \rightskip=\leftskip% ressorts de centrage¤\idx*\leftskip\idx*\rightskip¤
		\doforeach\htext\in{#1}% pour chaque élément :¤§*\doforeach¤
			{\htext\par}% le composer et finir le paragraphe
	}%
}

texte avant...\cvtop{Ligne du haut,Très grande ligne du milieu,Ligne du bas pour finir}%
...texte après|§*\cvtop[|)]
\end{exercice}

Ces façons de faire sont un peu tirée par les cheveux. En effet, nous venons de programmer ce que fait (entre autres) la primitive de \TeX{} « \idx\halign\verb|{<code>}| ». Le but ici n'est pas d'en décrire toutes ses fonctionnalités, car elles sont très nombreuses et pour certaines, très techniques\footnote{Pour en savoir plus, il est sage de se tourner vers le \TeX book, chapitre 22.}.

Pour aller à l'essentiel, cette primitive opère en mode vertical\idx*{mode!vertical} et construit des alignements (autrement dit, des tableaux) constitués de lignes, elles-mêmes partagées en cellules. Ce qui est remarquable, c'est que lorsque \idx\halign lit son argument, elle compose \emph{tous} les contenus des cellules et par conséquent, fixe comme longueur d'une colonne la plus grande des longueurs rencontrées dans cette colonne.

Du côté de la syntaxe, chaque ligne s'achève par la primitive \idx\cr et il est prudent de placer \idx\crcr en fin de tableau. Au sein d'une ligne, le token  «\verb|&|» (de catcode \number\catcode`\&) signifie « passer à la colonne suivante». La syntaxe d'une ligne est donc :

\centrecode-<cellule 1>&<cellule 2>& ... &<cellule n>\cr-

Raffinement supplémentaire, il est possible pour toutes les cellules d'une même colonne de définir un code qui sera inséré avant leur contenu et un code qui sera inséré après. Pour cela, la primitive \idx\halign admet un \emph{préambule} qui est placé avant le premier \idx\cr. La syntaxe de ce préambule reprend la syntaxe d'une ligne, mais le \verb|<contenu>| d'une cellule est symbolisé par le token «\cidx\#». Ainsi, pour une colonne (c'est-à-dire compris entre deux «\cidx[ (caractère d'alignement)]\&»), si on écrit dans le préambule

\centrecode-<code avant>#<code après>-

\noindent alors, le texte \verb|<code avant>| sera inséré avant le code contenu dans les cellules et \verb|<code après>| sera inséré après.

Dans l'exemple ci-dessous, la colonne \no1 est définie pour que «\verb|X|» soit affiché avant chaque cellule et «\verb|**\ignorespaces|» après, où \idx\ignorespaces nous assure qu'en dehors du préambule, les espaces insérés avant le premier \verb|&| ne compteront pas. Pour la deuxième colonne, \cidx\# est seul et donc les cellules de cette colonne seront composées sans aucun ajout. Enfin, la colonne \no3 est composée au fer à droite en insérant \idx\hfil à gauche de \cidx\# :

\showcode/\halign{X#**\ignorespaces&#&\hfil #\cr % préambule¤\idx*\halign\idx*\ignorespaces¤
foo            &foo bar&123 456\cr % première ligne¤\idx*\cr¤
deuxième ligne &1      &12\cr % deuxième ligne
a              &\TeX   &1 2 3 4 5 6\cr % troisième ligne
\crcr}¤\idx*\crcr¤/

Pour tirer parti de \idx\halign dans le code de §\cvtop[|(], nous allons définir un alignement à une colonne et nous spécifierons «\idx\hfil{}\cidx\#{}\idx\hfil» en préambule afin que les contenus soient centrés. À l'aide de §\substtocs, nous stockerons dans une macro \verb|\temp| l'argument de §\cvtop où les virgules auront été remplacées par \idx\cr. Il suffira ensuite de placer la macro \verb|\temp| juste après le \idx\cr qui marque la fin du préambule pour que \TeX{} la développe (car le début de chaque cellule est développé) pour constituer le corps du tableau :

\showcode|\def\cvtop#1{%¤§*\cvtop¤
	\vtop{% \vtop assure que l'on est en mode vertical¤\idx*\vtop\idx*{mode!vertical}¤
		\substtocs\temp{#1}{,}{\cr}% dans \temp, remplacer les "," par "\cr"¤§\substtocs\idx*\cr¤
		\halign{%¤\idx*\halign¤
			\hfil##\hfil\cr% préambule : centrer le contenu¤\idx*\hfil¤
			\temp\crcr}% mettre \temp dans l'alignement¤\idx*\crcr¤
	}% \temp est détruite en sortant de la boite
}

texte avant...\cvtop{Ligne du haut,Très grande ligne du milieu,Ligne du bas pour finir}%
...texte après|

Ce code en suggère un autre, capable de calculer à l'aide de \idx\halign, la plus grande longueur de textes. Pour cela, la macro §\calcmaxdim, de syntaxe

\centrecode-\calcmaxdim\<macro>{<texte 1>,texte 2>,...,<texte n>}-

\noindent stockera dans la \verb|\<macro>| la plus grande longueur des \verb|<texte>|.

\showcode/\def\calcmaxdim#1#2{%¤§*\calcmaxdim¤
	\setbox0=\vtop{% \vtop assure que l'on est en mode vertical (interne)¤\idx*\vtop\idx*\setbox¤
		\substtocs\temp{#2}{,}{\cr}% dans \temp, remplacer les "," par "\cr"¤§*\substtocs\idx*\cr¤
		\halign{##\hfil\cr% préambule : composer au fer à gauche¤\idx*\halign\idx*\hfil¤
			\temp\crcr}% mettre \temp dans l'alignement¤\idx*\crcr¤
	}% \temp est détruite en sortant de la boite
	\edef#1{\the\wd0 }%¤\idx*\the\idx*\wd¤
}
a) La plus grande longueur vaut
   \calcmaxdim\foo{Ligne du haut,Très grande ligne du milieu,Ligne du bas pour finir}\foo

b) Vérification : \setbox0=\hbox{Très grande ligne du milieu}\the\wd0 ¤\idx*\setbox\idx*\the\idx*\wd¤/§*\cvtop[|)]\idx*[|)]{boite}

\section{Les réglures}\idx*[|(]{réglure}
\subsection{Tracer des lignes}
Nous allons maintenant nous intéresser à des boites un peu particulières, les boites de réglure ou «réglures», c'est-à-dire des boites entièrement remplies de noir.

\begin{regle}
Les primitives \idx\hrule et \idx\vrule, qui opèrent respectivement en \idx*{mode!vertical}mode \emph{vertical} et \emph{horizontal}\idx*{mode!horizontal}, tracent des réglures. Par défaut, les dimensions de ces réglures sont :

\begin{centrage}
	\small
	\begin{tabular}{rcc}\hline
		&\idx\hrule&\idx\vrule\\\hline
		largeur (width) & \verb|*| & 0.4pt\\
		hauteur (height)& 0.4pt&\verb|*|\\
		profondeur (depth)&0pt&\verb|*|\\\hline
	\end{tabular}
\end{centrage}

L'étoile signifie que la dimension est celle de la boite qui contient la réglure.

Si l'on souhaite passer outre les valeurs par défaut et imposer une ou plusieurs dimensions, on doit faire suivre ces deux primitives  d'un (ou plusieurs) mots-clés parmi «\verb|width|», «\verb|height|» ou «\verb|depth|» et en respectant cet ordre. S'ils sont présents, ces mots-clés doivent être suivis de la \verb|<dimension>| que l'on souhaite imposer.

Si plusieurs spécifications contradictoires sur une dimension sont spécifiées, la dernière est prise en compte.
\end{regle}

Voici par exemple ce que l'on obtient si on écrit «\idx\vrule» dans le code source immédiatement après ces deux points :\vrule. On constate que la réglure, qui opère en mode horizontal, a la largeur par défaut de \verb|0.4pt| et a pour hauteur et profondeur celles de la boite dans laquelle elle est enfermée. Cette boite est la ligne en cours de composition.

Passons maintenant à \idx\hrule et voici l'effet de «\idx\hrule» juste après ces deux points :\hrule
La réglure prend la totalité de la largeur de la boite qui la contient. La boite dont il est question dans ce cas est la page elle-même, de largeur \idx\hsize, dans laquelle les éléments sont empilés verticalement. On remarque que pour satisfaire son mode de fonctionnement, \idx\hrule passe en mode vertical\idx*{mode!vertical}. Puisque nous étions à l'intérieur d'un paragraphe, celui-ci a été composé avant le passage en mode vertical. Par ailleurs, le \idx{ressort d'interligne} n'est pas inséré, ni avant la réglure ni après. Une réglure \idx\hrule est donc dessinée \emph{au plus près} verticalement de ce qui la suit et de ce qui la précède.

L'exemple suivant montre que les primitives de réglures utilisées sans mot-clé adaptent leurs dimensions à celles de la boite qui les contient. Ici, on dessine des \idx\hrule au sommet et au bas d'une \idx\vbox dans la première ligne alors que l'on trace des \idx\vrule avant et après une \idx\vtop à la deuxième ligne :

\showcode/a) .......\vbox{\hrule\hbox{foo}\hbox{ligne du bas}\hrule}.......\medbreak¤\idx*\vbox\idx*\hrule\idx*\hbox¤
b) .......\vrule\vtop{\hbox{foo}\hbox{ligne du bas}}\vrule.......¤\idx*\vtop\idx*\vrule¤/

On voit clairement au cas a que les \idx\hrule à l'intérieur de \idx\vbox prennent chacune la largeur totale de la boite. En ce qui concerne les \idx\vrule qui se trouvent avant et après la \idx\vtop au cas b, elles ont adapté leur profondeur et hauteur pour s'étendre sur la hauteur totale de la boite qui ici est la ligne en cours.

Voici maintenant des réglures dont les dimensions sont imposées par mots-clés :

\showcode/Une réglure de 1.5cm :\hrule width1.5cm
foo\vrule width 2pt height .5cm depth .2cm bar/

Ici encore, la \idx\vrule est en contact avec la \idx\hrule puisque le \idx{ressort d'interligne} n'est pas inséré.

\begin{exercice}
Écrire une macro §\showdim[|(], opérant en mode horizontal\idx*{mode!horizontal}, dont l'argument est une dimension et qui représente sous forme d'une réglure horizontale la dimension donnée.

Par exemple, «§\showdim\verb-{1.5cm}-» produit «\showdim{1.5cm}» où les traits verticaux de début et de fin ont une hauteur de \verb|1ex|. Toutes les réglures ont une épaisseur de \verb|0.4pt|.

\solution
Voici le code de cette macro :

\showcode/\def\showdim#1{%¤§*\showdim¤
	\vrule width 0.4pt height 1ex  depth 0pt % trait vertical gauche¤\idx*\vrule\defline\aaa¤
	\vrule width #1    height0.4pt depth 0pt % réglure horizontale de longueur #1¤\defline\bbb¤
	\vrule width 0.4pt height 1ex  depth 0pt % trait vertical droit¤\idx*\vrule\defline\ccc¤
	\relax% stoppe la lecture de la précédente dimension
}

a) une longueur de 1 cm : \showdim{1cm}\par
b) une longueur de 137,4 pt : \showdim{137,4pt}\par
c) une longueur de 2 mm : \showdim{2mm}/

Le code est très simple. En premier lieu (ligne \no\aaa), la primitive \idx\vrule qui opère en mode horizontal\idx*{mode!horizontal} trace une barre verticale d'\verb|1ex| de hauteur et de \verb|0.4pt| d'épaisseur. Ensuite, à la ligne \no\bbb, nous la faisons suivre d'une ligne horizontale dont la longueur a été forcée à la dimension contenue dans l'argument et dont la hauteur est \verb|0.4pt|. Nous finissons à la ligne \no\ccc{} avec la même barre verticale qu'au début.§*\showdim[|)]
\end{exercice}

\subsection{Encadrer}\idx*[|(]{encadrer}
On commence à deviner qu'il serait assez facile de programmer une macro §\FRbox qui encadre tout ce qui est dans son argument, argument devant être composé en mode horizontal\idx*{mode!horizontal} :

\centrecode|\FRbox{<contenu>}|§*\FRbox

Les deux paramètres importants pour l'aspect visuel sont l'épaisseur des réglures et l'espacement entre elles et le contenu. Chacun de ces paramètres sera un registre de dimension; §\frboxrule pour l'épaisseur et §\frboxsep pour l'espacement\footnote{Ne pas confondre les noms de ces registres avec \texttt{\string\fboxrule} et \texttt{\string\fboxsep} qui sont les registres définis par \LaTeX{} pour les boites encadrées avec la macro \texttt{\string\fbox}.}.

En ce qui concerne la méthode pour encadrer un contenu arbitraire, il y a deux façons différentes de tracer les réglures :

\begin{centrage}
	\leavevmode
	\frboxrule=0.2pt \frboxsep=1pt
	\small
	\vbox{%
		\offinterlineskip
		\hbox{\FRbox{\vrule height 1mm width\dimexpr2.2cm+2\frboxsep+2\frboxrule}}%
		\hbox{%
			\FRbox{\vrule width1mm height\dimexpr1cm-2\frboxsep-2\frboxrule }%
			\vbox to1cm{\vss\hbox to2cm{\hss\verb|<contenu>|\hss}\vss}%
			\FRbox{\vrule width1mm height\dimexpr1cm-2\frboxsep-2\frboxrule }%
			}%
		\hbox{\FRbox{\vrule height 1mm width\dimexpr2.2cm+2\frboxsep+2\frboxrule}}%
	}\hskip0pt plus1fil
	\hbox{%
		\FRbox{\vrule width1mm height\dimexpr1.2cm+2\frboxsep+2\frboxrule }%
		\vbox to\dimexpr1.2cm+4\frboxsep+4\frboxrule{%
			\hbox{\FRbox{\vrule height1mm width\dimexpr2cm-2\frboxsep-2\frboxrule }}%
			\vskip 0pt plus 1fil
			\hbox to2cm{\hss \verb|<contenu>|\hss}%
			\vskip 0pt plus 1fil
			\hbox{\FRbox{\vrule height1mm width\dimexpr2cm-2\frboxsep-2\frboxrule }}%
		}%
		\FRbox{\vrule width1mm height\dimexpr1.2cm+2\frboxsep+2\frboxrule }%
	}%
\end{centrage}

\noindent Décidons-nous par exemple pour la structure de droite. Pour arriver à nos fins, nous allons construire une \idx\vbox dans laquelle nous allons insérer, de haut en bas :

\begin{itemize}
	\item une réglure horizontale ;
	\item une espace verticale égale à §\frboxsep ;
	\item le contenu (précédé et suivi d'espaces égales à §\frboxsep);
	\item une espace verticale égale à §\frboxsep ;
	\item une réglure horizontale.
\end{itemize}

\noindent Nous obtiendrons donc :

\begin{centrage}
	\leavevmode
	\small
	\frboxrule=0.2pt \frboxsep=1pt
	\hbox{%
		\vbox to\dimexpr1.2cm+4\frboxsep+4\frboxrule{%
			\hbox{\FRbox{\vrule height1mm width\dimexpr2cm-2\frboxsep-2\frboxrule }}%
			\vskip 0pt plus 1fil
			\hbox to2cm{\hss\verb|<contenu>|\hss}%
			\vskip 0pt plus 1fil
			\hbox{\FRbox{\vrule height1mm width\dimexpr2cm-2\frboxsep-2\frboxrule }}%
		}%
	}%
\end{centrage}

\Qu 'ils soient horizontaux ou verticaux, tous les espaces seront insérés avec la primitive \idx\kern qui agit selon le mode en cours. Voici la construction obtenue pour un contenu égal au mot « Programmation » :

\showcode/¤\verb-\newdimen\frboxrule \newdimen\frboxsep-\idx*\newdimen§*\frboxrule§*\frboxsep¤
\frboxsep=5pt \frboxrule=1pt ¤§*\frboxsep §*\frboxrule¤
\leavevmode¤\idx*\leavevmode¤
...%
\vbox{%¤\idx*\vbox¤
	\hrule height\frboxrule% réglure supérieure¤\idx*\hrule¤
	\kern\frboxsep% espace verticale haute¤\idx*\kern¤
	\hbox{\kern\frboxsep Programmation\kern\frboxsep}% contenu + espaces horizontales¤\idx*\hbox¤
	\kern\frboxsep% espace verticale basse¤§*\frboxsep¤
	\hrule height\frboxrule% réglure inférieure¤§*\frboxrule¤
	}%
.../

\noindent Il ne reste plus qu'à envelopper le tout dans une boite horizontale \idx\hbox, après avoir fait précéder la \idx\vbox de \idx\vrule qui seront les réglures verticales à droite et à gauche de l'encadrement§*\FRbox :

\showcode|¤\verb-\newdimen\frboxrule \newdimen\frboxsep-\idx*\newdimen§*\frboxrule§*\frboxsep¤
\frboxsep=5pt \frboxrule=0.6pt
\def\FRbox#1{% /!\ ne change pas le mode H ou V en cours¤§*\FRbox¤
	\hbox{% mettre à la suite horizontalement les 3 choses suivantes :¤\idx*\hbox¤
		\vrule width\frboxrule% 1) réglure gauche¤\idx*\vrule¤
		\vbox{%                 2) un empilement vertical comprenant¤\idx*\vbox¤
			\hrule height\frboxrule% a) réglure supérieure¤\idx*\hrule ¤
			\kern\frboxsep%          b) espace verticale haute¤\idx*\kern ¤
			\hbox{%                  c) contenu + espaces en mode H
				\kern\frboxsep#1\kern\frboxsep¤\defline\ccc¤
			}%
			\kern\frboxsep%          d) espace verticale basse¤\defline\aaa§*\frboxsep¤
			\hrule height\frboxrule% e)réglure inférieure¤\defline\bbb¤
			}%
		\vrule width\frboxrule% 3) réglure droite¤\idx*\vrule§*\frboxrule¤
	}%
}
Ligne de base : ...\FRbox{Programmation}...%
\frboxrule=2pt \FRbox{Programmation}...%
\frboxsep=0pt \FRbox{Programmation}...%
\frboxrule0.4pt \FRbox{Programmation}...¤§*\FRbox¤|

On constate que la \idx{ligne de base} du contenu des boites n'est pas alignée avec la \idx{ligne de base} de la ligne en cours. En fait, comme la \idx\vbox empile les éléments au-dessus de la \idx{ligne de base} du dernier élément, le \idx{point de référence} de la \idx\vbox se trouve sur la \idx{ligne de base} de la réglure inférieure tracée à la ligne \no\bbb, c'est-à-dire au niveau du bord \emph{inférieur} de cette réglure\footnote{Si nous avions écrit \texttt{depth} au lieu de \texttt{height} à la ligne \no\bbb, le point de référence aurait été au niveau du bord \emph{supérieur} de la réglure du bas.}. Le problème qui se pose est le suivant : comment construire une boite verticale où l'on place des listes de matériels verticaux

\centrecode-<liste a>
<liste b>-

\noindent et faire en sorte que le \idx{point de référence} de la boite ainsi construite soit sur la \idx{ligne de base} du dernier élément vertical de \verb|<liste a>| ? Faire appel à \idx\vbox ou \idx\vtop seules ne peut convenir. Il fait \emph{combiner} ces deux boites. L'idée est d'enfermer \verb|<liste a>| dans une \idx\vbox et mettre cette \idx\vbox comme premier élément vertical d'une \idx\vtop qui englobe le tout. La boite ainsi construite a la structure suivante\label{frbox.ligne.de.base} :

\centrecode-\vtop{%¤\idx*\vtop¤
	\vbox{<liste a>}
	<liste b>
}-

De par les définitions de \idx\vbox et \idx\vtop, le \idx{point de référence} de la boite externe \idx\vtop se trouvera sur la \idx{ligne de base} du dernier élément vertical de \verb|<liste a>|. Voici un exemple qui illustre cette manipulation :

\showcode/Persuadez-vous que :
\vtop{¤\idx*\vtop¤
	\vbox{¤\idx*\vbox¤
		\hbox{Programmer}¤\idx*\hbox¤
		\hbox{en}
		\hbox{\TeX}
		\hbox{est}% <- ligne de base de la \vtop
	}
	\hbox{\it tout sauf}¤\idx*\it¤
	\hbox{facile.}
}/

Nous allons appliquer cette structure pour créer une nouvelle macro §\frbox[|(] afin que, contrairement à §\FRbox, le point de référence du cadre soit au niveau de la \idx{ligne de base} du contenu. Il faut donc rejeter hors de la \idx\vbox les matériels verticaux des lignes \nos\aaa{} et \bbb{} :

\showcode/%\newdimen\frboxrule \newdimen\frboxsep
\frboxrule=0.4pt \frboxsep=2pt
\def\frbox#1{% ne pas changer le mode H ou V en cours¤§*\frbox¤
	\hbox{% enferme dans une \hbox¤\idx*\hbox¤
		\vrule width\frboxrule% réglure gauche¤\idx*\vrule§*\frboxrule¤
		\vtop{%¤\idx*\vtop¤
			\vbox{% 1er élément de la \vtop¤\idx*\vbox¤
				\hrule height\frboxrule% réglure supérieure¤\idx*\hrule¤
				\kern\frboxsep% espace haut¤\idx*\kern¤
				\hbox{%¤\idx*\hbox¤
					\kern\frboxsep% espace gauche
					#1% contenu
					\kern\frboxsep% espace droite¤ §*\frboxsep¤
					}%
			}% puis autres éléments de la \vtop, sous la ligne de base
			\kern\frboxsep% espace bas
			\hrule height\frboxrule% réglure inférieure
		}%
		\vrule width\frboxrule% réglure droite¤\idx*\vrule §*\frboxrule¤
	}%
}
Ligne de base : ......\frbox{Programmation}......%
\frboxrule=2pt \frbox{Programmation}......%
\frboxsep=0pt \frbox{Programmation}......%
\frboxrule0.4pt \frbox{Programmation}......¤§*\frbox¤/

\begin{exercice}
Créer une macro §\centretitre\verb|{<texte>}| dont l'argument doit être composé dans un cadre (via §\frbox) qui prend toute la largeur de composition, c'est-à-dire \idx\hsize. L'argument doit être centré dans ce cadre.
\solution
Tout d'abord, nous allons placer en début de macro un \verb|\medbreak| ce qui aura pour effet de composer le paragraphe en cours si la macro est appelée en mode horizontal\idx*{mode!horizontal} et sautera une espace verticale. Ensuite, la primitive \idx\noindent interdira le placement de la boite d'indentation en début de paragraphe, et provoquera le passage en mode horizontal\idx*{mode!horizontal}.

Nous allons composer le \verb|<texte>| dans une boite verticale \idx\vbox. Sa dimension horizontale, spécifiée par \idx\hsize, doit tenir compte des réglures droite et gauche (chacune de dimension §\frboxrule) ainsi que les espaces à droite et à gauche entre le \verb|<texte>| et les réglures (chacun de dimension §\frboxsep). La dimension horizontale de la boite sera donc

\begin{centrage}
	\small$\hbox{\verb|\hsize|}-2\hbox{§\frboxrule}-2\hbox{§\frboxrule}$\idx*\hsize
\end{centrage}

Pour que le centrage soit effectif, nous jouerons sur les ressorts \idx\leftskip et \idx\rightskip sans oublier d'annuler le ressort de fin de paragraphe\idx*{paragraphe!centrage} \idx\parfillskip.

\showcode/\def\centretitre#1{%¤§*\centretitre¤
	\medbreak% passe en mode v puis saute une espace verticale¤\idx*\medbreak¤
	\noindent% pas d'indentation et passe en mode horizontal¤\idx*\noindent\idx*{mode!horizontal}¤
	\frbox{% encadre¤§*\frbox¤
		\vbox{% une boite verticale¤\idx*\vbox¤
			\hsize=\dimexpr\hsize-2\frboxrule-2\frboxsep\relax¤\idx*\hsize\idx*\dimexpr §*\frboxsep §*\frboxrule¤
			\parindent=0pt % pas d'indentation¤\idx*\parindent¤
			\leftskip=0pt plus1fil \rightskip=\leftskip% ressorts de centrage¤\idx*\leftskip\idx*\rightskip¤
			\parfillskip=0pt % annule le ressort de fin de paragraphe¤\idx*\parfillskip¤
			#1% insère le titre
			\endgraf% et le compose¤\idx*\endgraf¤
			}%
	}%
	\medbreak% passe en mode v puis saute une espace verticale¤\idx*\medbreak¤
	\ignorespaces% mange les espaces situés après la macro \centretitre¤\idx*\ignorespaces¤
}
\frboxrule=0.8pt \frboxsep=5pt
Voici un
\centretitre{Titre}
puis un
\centretitre{Texte très long pour composer un titre qui va prendre plusieurs
lignes et pour s'assurer que la composition s'effectue correctement}¤§*\centretitre¤/
\end{exercice}§*\frbox[|)]\idx*[|)]{encadrer}

\idx*[|(]{souligner}\begin{exercice}
Programmer une macro §\souligne\verb|{<texte>}| qui souligne d'un trait de 0.4pt d'épaisseur le \verb|<texte>|. Le trait de soulignement devra se situer à \verb|1pt| au-dessous du \verb|<texte>| :

\begin{centrage}
\small
\begin{tabular}{>{\ttfamily\hfill}r<{\kern1.5em \normalfont affiche\kern1.5em}@{}l}
\string\souligne\{Du texte\}&\souligne{Du texte}\\
\string\souligne\{Du texte profond\}&\souligne{Du texte profond}
\end{tabular}
\end{centrage}

Proposer une variante §\Souligne où le trait devra se situer à 1pt au-dessous de la \idx{ligne de base}, quelle que soit la profondeur du texte à souligner :

\begin{centrage}
\small
\begin{tabular}{>{\ttfamily\hfill}r<{\kern1.5em \normalfont affiche\kern1.5em}@{}l}
\string\Souligne\{Du texte\}&\Souligne{Du texte}\\
\string\Souligne\{Du texte profond\}&\Souligne{Du texte profond}
\end{tabular}
\end{centrage}

\solution
Nous devons tracer une réglure ayant comme dimension horizontale celle de la \idx\hbox dans laquelle est placé l'argument. Afin de pouvoir mesurer cette boite, nous allons stocker \verb|\hbox{#1}| dans le registre de boite \no0\idx*{boite!\no0}.

Mais avant de poursuivre, regardons d'un peu plus près les dimensions qui suivent les mots-clés \verb|height|, \verb|width| et \verb|depth|, et considérons-les comme des dimensions \emph{signées}. Car c'est ainsi que \TeX{} travaille; rien ne dit qu'une dimension, fût-elle de réglure, doit être positive ! Par exemple, pour tracer une réglure de \verb|0.4pt| d'épaisseur à \verb|10pt| de hauteur, nous pouvons fixer sa hauteur à \verb|10.4pt| et sa profondeur à \verb|-10pt| :

\showcode/Une réglure en hauteur : \vrule width 1cm height 10.4pt depth -10pt ¤\idx*\vrule¤/

De même, pour tracer une réglure d'épaisseur \verb|0.4pt| à \verb|2pt| sous la \idx{ligne de base}, il suffit de fixer sa profondeur à \verb|2.4pt| et sa hauteur à \verb|-2pt| :

\showcode/Une réglure en dessous: \vrule width 1cm depth 2.4pt height -2pt ¤\idx*\vrule¤/

Revenons à notre problème\ldots{} Nous stockerons la \idx\hbox dans le registre de boite \no0\idx*{boite!\no0}. Puis, nous allons appliquer l'astuce exposée ci-dessus pour tracer une réglure de \verb|0.4pt| d'épaisseur à une distance de \verb|\dp0+1pt| sous la \idx{ligne de base}. Pour cela, nous allons stocker dans ce même registre \no0\idx*{boite!\no0} une \idx\vrule dont la longueur est celle du texte à souligner, soit \verb|\wd0|, de profondeur \verb|\dp0+1.4pt| et de hauteur négative égale à \verb|-\dp0-1pt|. Nous allons ensuite rendre nulles toutes les dimensions de la boite afin que son encombrement soit nul dans toutes les directions. Enfin, après être éventuellement sorti du mode vertical\idx*{mode!vertical}, nous affichons cette boite \no0\idx*{boite!\no0} avant le texte  :

\showcode/\def\souligne#1{%¤§*\souligne¤
	\setbox0=\hbox{#1}% stocke le contenu dans le registre no 0¤\idx*\setbox¤
	\setbox0=\hbox{% puis, dans une \hbox, construit une réglure¤\idx*\setbox¤
		\vrule width\wd0 % de la longueur du contenu¤\idx*\vrule\idx*\wd¤
			depth\dimexpr\dp0 + 1.4pt\relax % dp = profondeur texte + 1.4pt¤\idx*\dimexpr¤
			height\dimexpr-\dp0 - 1pt\relax % ht = -profondeux texte - 1pt
	}%
	\wd0=0pt \dp0=0pt \ht0=0pt % annule toutes les dimensions¤\idx*\wd\idx*\ht\idx*\dp¤
	\leavevmode \box0 % affiche la réglure¤\idx*\leavevmode\idx*\box¤
	#1% puis le contenu
}
Voici \souligne{du texte normal}.\par
Voici \souligne{du texte profond}.¤§*\souligne¤/

Compte tenu des dimensions utilisées, le bord supérieur de la réglure est très exactement à \verb|1pt| sous la plus basse partie du texte à souligner.

La variante §\Souligne est plus simple : il ne faut pas tenir compte de la profondeur du registre \no0\idx*{boite!\no0}.

\showcode/\def\Souligne#1{%¤§*\Souligne¤
	\setbox0=\hbox{#1}%¤\idx*\setbox¤
	\setbox0=\hbox{\vrule width\wd0 depth1.4pt height-1pt }%¤\idx*\vrule\idx*\wd¤
	\wd0=0pt \dp0=0pt \ht0=0pt ¤\idx*\wd\idx*\ht\idx*\dp¤
	\leavevmode \box0 #1%¤\idx*\leavevmode\idx*\box¤
}
Voici \Souligne{du texte normal}.\par
Voici \Souligne{du texte profond}.¤§*\Souligne¤/

Les macros présentées ici ne permettent pas de souligner un texte trop long ou trop proche d'une \idx{fin de ligne}, car une réglure, \emph{a fortiori} enfermée dans une \idx\hbox, ne peut franchir une coupure de ligne.

Une autre méthode, impliquant \idx\lower, aurait également été envisageable :

\showcode/\def\Souligne#1{%
	\setbox0=\hbox{#1}%¤\idx*\setbox¤
	\lower 1pt % abaisser à 1pt sous la ligne de base¤\idx*\lower¤
		\rlap{% une \hbox en surimpression vers la droite¤\idx*\rlap¤
			\vrule width\wd0 height0pt depth0.4pt % contenant le soulignement
		}%
	#1% puis afficher le <texte>
}
Voici \Souligne{du texte normal}.\par
Voici \Souligne{du texte profond}.¤§*\Souligne¤/

La méthode n'est pas équivalente car dans ce dernier cas, la réglure qui tient lieu de soulignement est prise en compte dans la boite englobante de §\Souligne\verb|<texte>|, ce qui n'était pas le cas dans le premier code.
\end{exercice}\idx*[|)]{souligner}

\subsection{Empiler des boites}\idx*[|(]{boite!empilement}
Essayons maintenant de jouer avec les boites et pour cela, créons une macro §\stackbox capable d'empiler des boites encadrées, toutes identiques, aussi bien horizontalement que verticalement. Le fait qu'elles soient identiques implique évidemment que les dimensions de leurs contenus ne sont pas trop différentes. La syntaxe de la macro §\stackbox pourrait être :

\centrecode-\stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}-

\noindent Et le résultat serait :

\begin{centrage}
\small\vbox{\frboxsep=3pt \stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}}
\end{centrage}

En ce qui concerne les dimensions des boites, on pourrait parcourir lors d'une première passe tous les arguments afin de trouver la plus grande des hauteurs, largueurs et profondeurs et ensuite prendre ces maximums comme dimension de chaque boite, qui seraient alors composées lors d'une seconde passe. Afin de ne pas inutilement compliquer le code\footnote{La vraie et inavouable raison est que renoncer à faire deux passes va nous donner l'occasion de découvrir les « \idx{strut}s » !}, nous allons plutôt décider que l'utilisateur va lui-même fixer la largueur \emph{interne} des cadres à l'aide d'un registre de dimension \verb|\stackwd| créé pour l'occasion : ceci suppose évidemment qu'aucune boite ne doit avoir un contenu dont la largeur excède \verb|\stackwd|.

Parcourir l'ensemble des contenus va être facilitée avec la macro §\doforeach à qui nous donnerons la liste d'éléments d'une même ligne. Tout cela se fait aisément avec une macro \verb|\stackbox@i| à arguments délimités par «\verb|\\|» dont le but est d'isoler et lire  la ligne en cours. Son texte de paramètre sera :

\centrecode-\def\stackbox@i#1\\{...}-

En premier lieu, la macro chapeau se contentera d'appeler la macro récursive \verb|\stackbox@i| de cette façon :

\centrecode-\stackbox@i#1\\\quark\\-§*\quark

\noindent Ceci a deux avantages : c'est l'assurance que \verb|\\| est présent dans l'argument, car après tout, on pourrait ne pas l'écrire dans l'argument de §\stackbox si on ne voulait qu'une seule ligne. L'autre avantage est que la dernière ligne à lire est le \idx{quark} «§\quark». Si la \tidx[|etc]{ifx}-égalité de l'argument \verb|#1| avec §\quark est vraie, nous serons alors surs que la ligne précédente était la dernière et donc, finir le processus. Nous aurons donc lu la totalité des lignes une première fois dans la macro chapeau puis chaque ligne une seule fois dans la macro récursive. Chaque ligne a été donc lue deux fois exactement. C'est la méthode préconisée par la règle de la page~\pageref{lire.arguments} pour lire une série d'arguments.

La macro \idx\nobreak, insérée avant chaque ligne restante, interdit toute coupure de page entre deux lignes de boites consécutives. Cette macro est définie dans plain-\TeX{} et son texte de remplacement est « \idx\penalty\verb|10000| ». Sachant que toute pénalité supérieure à \numprint{10000} est comprise comme \numprint{10000}, il s'agit là de la plus forte \idx{pénalité} possible ce qui explique qu'une coupure de page ne se fera jamais à cet endroit.

\showcode/\newdimen\stackwd \stackwd=3em % dimension horizontale interne des cadres¤\idx*\newdimen¤
\catcode`@11
\def\stackbox#1{%¤§*\stackbox¤
	\par% termine le paragraphe en cours
	\noindent¤\idx\noindent¤
	\stackbox@i#1\\\quark\\% ajoute "\\\quark\\" à la fin et appelle \stackbox@i¤§*\quark¤
	\par
}

\def\stackbox@i#1\\{% #1=ligne courante
	\def\temp@{#1}% stocke la ligne courante
	\unless\ifx\quark\temp@% si ce n'est pas la fin¤\tidx*{unless}§*\quark¤
		\hfill % ressort infini de centrage (et fait passer en mode horizontal)¤\idx*\hfill\idx*{mode!horizontal}¤
		\noindent¤\idx*\noindent¤
		\doforeach\current@item\in{#1}% pour chaque élément dans la ligne courante...¤§*\doforeach¤
			{\frbox{% ...encadrer¤§*\frbox¤
				\hbox to\stackwd{% une \hbox de largeur \stackwd¤\idx*\hbox¤
					\hss% ressort de centrage¤\idx*\hss¤
					\current@item% l'élément courant
					\hss% ressort de centrage
					}
				}% fin de la \frbox
			}% fin \doforeach
		\hfill% ressort infini de centrage¤\idx*\hfill¤
		\null% assure que le dernier ressort est pris en compte¤\idx*\null¤
		\par% finir le paragraphe
		\nobreak% interdire une coupure de page¤\idx*\nobreak¤
		\nointerlineskip% ne pas insérer le ressort d'interligne¤\idx*\nointerlineskip¤
		\expandafter\stackbox@i% et recommencer
	\fi
}
\catcode`@12

\frboxrule=0.5pt \frboxsep=3pt ¤§*\frboxsep §*\frboxrule¤
\stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}¤§*\stackbox¤/

Le résultat est loin d'être celui escompté ! \Qu oique pas si loin que ça, après tout : les positions horizontales sont bonnes. Le bug vient du fait que nous n'avions pas prévu que les dimensions verticales (hauteur et profondeur) des éléments influaient naturellement sur la boite encadrée construite. On peut y remédier en insérant un « \idx{strut}\footnote{On dit « poutre » en français mais ce mot est assez peu usité.} » : c'est une réglure invisible, mais qui s'étend sur une dimension horizontale ou verticale. La question que l'on se pose immédiatement est « comment rendre une réglure invisible ?» Tout simplement en mettant sa largeur à \verb|0pt|, auquel cas elle aura une dimension verticale ou bien en mettant sa hauteur et profondeur à \verb|0pt| et dans ce cas, elle aura alors une dimension horizontale. Comme il est assez difficile de montrer des choses invisibles, voici une réglure de type \idx\vrule rendue visible (son épaisseur est \verb|0.2pt|) après la lettre « a » :

\showcode/a\vrule width0.2pt height15pt depth0pt \quad¤\idx*\vrule¤
a\vrule width0.2pt height0pt depth5pt \quad
a\vrule width0.2pt height10pt depth10pt \quad
a\vrule width1cm height0.2pt depth0pt¤\idx*\vrule¤/

Il suffit d'imposer \verb|0pt| comme dimension d'épaisseur pour rendre cette réglure invisible, mais bien réelle en ce qui concerne son encombrement. Voici comment la mettre en évidence en encadrant au plus proche l'ensemble formé par la lettre «a» et le \idx{strut} :

\showcode/\frboxsep0pt %encadrement au plus proche¤§*\frboxsep¤
\leavevmode¤\idx*\leavevmode¤
\frbox{a\vrule width0pt height15pt depth0pt }\quad¤§*\frbox\idx*\vrule¤
\frbox{a\vrule width0pt height0pt depth5pt }\quad
\frbox{a\vrule width0pt height10pt depth10pt }\quad
\frbox{a\vrule width1cm height0pt depth0pt }¤\idx*\vrule§*\frbox¤/

\begin{exercice}
Construire une macro §\rectangle\verb|{<x>}{<y>}| où \verb|<x>| et \verb|<y>| sont des dimensions et qui construit un rectangle dont les dimensions internes (c'est-à-dire de bord interne à bord interne) sont \verb|<x>| et \verb|<y>|.
\solution
Il faut construire une §\frbox dans laquelle nous allons mettre \emph{deux} \idx{strut}s, l'un pour la dimension verticale et l'autre pour l'horizontale.

\showcode/\def\rectangle#1#2{%¤§*\rectangle¤
	\begingroup% dans un groupe
		\frboxsep = 0pt % encadrer au plus proche¤§*\frboxsep¤
		\frboxrule= 0.4pt % en traits assez fins
		\frbox{%¤§*\frbox¤
			\vrule width#1 height0pt depth0pt %strut horizontal¤\idx*\vrule¤
			\vrule width0pt height#2 depth0pt %strut vertical¤\idx*\vrule¤
		}%
	\endgroup% fermer le groupe
}
Carré de 0.5 cm : \rectangle{0.5cm}{0.5cm}\smallskip¤\idx*\smallskip¤

Rectangle de 2.5cm par 3pt : \rectangle{2.5cm}{3pt}¤§*\rectangle¤/
\end{exercice}

Pour nos boites créées avec §\stackbox, nous allons mettre dans chacune d'elles un \idx{strut} dont les dimensions verticales sont les plus grandes que l'on peut rencontrer dans un texte « normal ». Nous prendrons les dimensions verticales d'une \idx\hbox contenant «Àgjp». Bien évidemment, si un élément contient un texte dont les dimensions verticales excèdent celles du \idx{strut}, le problème réapparaitra.

Il y a un autre défaut, plus difficile à détecter dans notre macro §\stackbox : les réglures des boites adjacentes ne se superposent pas, aussi bien horizontalement que verticalement, ce qui fait que leurs épaisseurs s'additionnent. Lorsque §\frboxrule est faible (\verb|0.5pt| ici), cela n'a pas d'influence visuelle notable, mais ce défaut serait beaucoup plus visible si §\frboxrule valait 2pt par exemple. Nous allons donc insérer une espace négative avec \verb|\kern-\frboxrule| entre chaque boite horizontalement et entre chaque ligne verticalement. Le dernier \idx\kern horizontal, qui viendra après la dernière boite dans la boucle, sera annulé par la primitive \idx\unkern que nous mettons après la boucle :

\showcode|\newdimen\stackwd \stackwd=3em ¤\idx*\newdimen¤
\catcode`\@11
\def\stackbox#1{%¤§*\stackbox¤
	\par% termine le paragraphe en cours
	\begingroup% dans un groupe semi-simple
		\parindent=0pt% pas d'indentation¤\idx*\parindent¤
		\parskip=0pt% annuler le \parskip¤\idx*\parskip¤
		\setbox0\hbox{Àgjp}% boite pour le strut¤\idx*\setbox\idx*\hbox¤
		\edef\stack@strut{\vrule width\z@ height\the\ht0 depth\the\dp0 }% définit le strut¤\idx*\vrule\idx*\z@¤
		\stackbox@i#1\\\quark\\% ajoute "\\\quark\\" à la fin et appelle \stackbox@i¤§*\quark¤
		\unkern% annule la dernière compensation verticale
		\par
	\endgroup
}
\def\stackbox@i#1\\{% #1=ligne courante
	\def\temp@{#1}% stocke la ligne courante
	\unless\ifx\quark\temp@% si ce n'est pas la fin¤\tidx*{unless}§*\quark¤
		\hfill % ressort infini de centrage (passe en mode horizontal)¤\idx*\hfill\idx*{mode!horizontal}¤
		\doforeach\current@item\in{#1}% pour chaque élément dans la ligne courante...¤§*\doforeach¤
			{\frbox{% ...encadrer¤§*\frbox¤
				\hbox to\stackwd{% une \hbox de largeur \stackwd contenant¤\idx*\hbox¤
					\hss%         1) ressort de centrage¤\idx*\hss¤
					\stack@strut% 2) strut de dimension verticale
					\current@item%3) l'élement courant
					\hss}%        4)ressort de centrage
				}% fin de la \fbox
			\kern-\frboxrule% revenir en arrière pour superposer les réglures verticales¤\idx*\kern¤
			}% fin de \doforeach
		\unkern% annuler la dernière compensation horizontale¤\idx*\unkern¤
		\hfill% ressort infini de centrage¤\idx*\hfill¤
		\null% fait prendre en compte le dernier ressort¤\idx*\null¤
		\par% termine le paragraphe
		\nobreak% interdit une coupure de page¤\idx*\nobreak¤
		\nointerlineskip% sinon, ne pas ajouter le ressort d'interligne¤\idx*\nointerlineskip¤
		\kern-\frboxrule% superposer les réglures horizontales¤\idx*\kern§*\frboxrule¤
		\expandafter\stackbox@i% et recommencer
	\fi
}
\frboxrule=0.5pt ¤§*\frboxrule¤
\frboxsep=3pt ¤§*\frboxsep¤
\stackbox{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}|

\begin{exercice}
Modifier la macro §\stackbox en §\lineboxed[|(] de telle sorte que pour chaque ligne, les boites aient une largeur telle qu'elles occupent la totalité de la ligne.
\solution
Pour que la largeur des boites d'une ligne soit telle que toutes ces boites remplissent la ligne, nous devons d'abord savoir combien il y a de boites dans chaque ligne. Pour cela, il faut compter combien de virgules il y a dans l'argument \verb|#1| et ajouter 1 ou, méthode plus simple, rajouter une virgule à \verb|#1| et effectuer le comptage. La macro §\cnttimestocs se chargera de ce travail et assignera le nombre de boites $n$ dans une macro.

La largeur disponible pour tous les contenus cumulés de toutes les boites de la ligne s'obtient en retirant de \idx\hsize l'épaisseur §\frboxrule des réglures verticales et les espaces §\frboxsep entre ces réglures et les contenus des boites. S'il y a $n$ boites, il y a $n+1$ réglures verticales et $2n$ espaces §\frboxsep. La largeur interne d'une boite, stockée dans la macro \verb|\dim@box| sera donc

\[
\frac{\hbox{\ttfamily\char`\\hsize}-(n+1)\hbox{\ttfamily\char`\\frboxrule}-2n\hbox{\ttfamily\char`\\frboxsep}}{n}
\]

\showcode|\catcode`\@11
\def\lineboxed#1{%¤§*\lineboxed¤
	\par% termine le paragraphe en cours
	\begingroup% dans un groupe semi-simple
		\parindent=0pt% pas d'indentation¤\idx*\parindent¤
		\parskip=0pt% annuler le \parskip¤\idx*\parskip¤
		\setbox0\hbox{Àgjp}% boite pour le strut¤\idx*\setbox\idx*\hbox¤
		\edef\stack@strut{\vrule width\z@ height\the\ht0 depth\the\dp0 }% définit le strut¤\idx*\vrule\idx*\z@¤
		\lineboxed@i#1\\\quark\\% ajoute "\\\quark\\" à la fin et appelle la macro récursive¤§*\quark¤
		\unkern% annule la dernière compensation verticale
		\par
	\endgroup
}
\def\lineboxed@i#1\\{% #1=ligne courante
	\def\temp@{#1}% stocke la ligne courante
	\unless\ifx\quark\temp@% si ce n'est pas la fin¤\tidx*{unless}§*\quark¤
		\cnttimestocs{#1,}{,}\nb@args% reçoit le nombre d'arguments dans la ligne courante¤§*\cnttimestocs¤
		\edef\dim@box{\the\dimexpr(\hsize-\frboxrule*(\nb@args+1)-
		              \frboxsep*2*\nb@args)/\nb@args}%¤\idx*\the\idx*\dimexpr§*\frboxrule§*\frboxsep¤
		\hbox{%¤\idx*\hbox¤
			\doforeach\current@item\in{#1}% pour chaque élément dans la ligne courante...¤§*\doforeach¤
				{\frbox{% ...encadrer¤§*\frbox¤
					\hbox to\dim@box{% une \hbox de largeur \dim@box contenant
						\hss%         1) ressort de centrage¤\idx*\hss¤
						\stack@strut% 2) strut de dimension verticale
						\current@item%3) l'élement courant
						\hss}%        4)ressort de centrage
					}% fin de la \fbox
				\kern-\frboxrule% revenir en arrière pour superposer les réglures verticales¤\idx*\kern§*\frboxrule¤
				}% fin de \doforeach
			\unkern% annuler la dernière compensation horizontale¤\idx*\unkern¤
		}%
		\par% termine le paragraphe
		\nobreak% interdit une coupure de page¤\idx*\nobreak¤
		\nointerlineskip% sinon, ne pas ajouter le ressort d'interligne¤\idx*\nointerlineskip¤
		\kern-\frboxrule% superposer les réglures horizontales¤\idx*\kern§*\frboxrule¤
		\expandafter\lineboxed@i% et recommencer
	\fi
}
\catcode`\@12
\lineboxed{a,bc,,d\\e,foobar,g\\123,456,$\alpha$,$x+y$,}\medbreak¤\idx*\medbreak¤

\frboxrule=1.5pt ¤§*\frboxrule¤
\frboxsep=3pt ¤§*\frboxrule¤
\lineboxed{,,,,,,,\\,,\\,,,,,,}|§*\lineboxed[|)]\end{exercice}\idx*[|)]{boite!empilement}

\subsection{Dessiner des quadrillages}\idx*[|(]{quadrillages}
Comment parler de réglure sans parler de quadrillage ? Car s'il est bien un domaine où elles sont adaptées, c'est bien celui-là.

Mettons à profit ce que nous savons pour écrire une macro §\grid[|(], capable de dessiner des quadrillages tels que celui-ci :

\begin{centrage}
\xunit=1.5cm \yunit=1cm \mainrule=1pt \subrule=0.2pt
\leavevmode\grid{5}{4}{2}{10}
\end{centrage}

Avant d'entrer dans le vif du sujet, quel est le nombre de paramètres qu'il est nécessaire de spécifier ? L'observation de ce quadrillage permet de se faire une idée. Il faut définir la largeur et hauteur d'un carreau-unité que nous stockerons dans deux registres de dimension (\verb|\xunit| et \verb|\yunit|) ainsi que l'épaisseur des lignes principales et secondaires stockées dans deux autres registres de dimension (\verb|\mainrule| et \verb|\subrule|). Puis, il faut passer à la macro §\grid le nombre de carreaux-unité que l'on veut horizontalement et verticalement ainsi que le nombre de subdivisions horizontales et verticales dans chaque carreau. Il semble donc naturel de construire une macro utilisant 4 registres de dimension et admettant 4 arguments.

Le quadrillage ci-dessus a été tracé en exécutant

\centrecode-\grid{5}{4}{2}{10}-

\noindent pour demander qu'il comporte 5 carreaux-unité horizontalement, chacun divisé en 4 et 2 carreaux-unité verticalement, chacun divisé en 10. De plus, les registres de dimension ont été initialisés avec

\centrecode-\xunit=1.5cm \yunit=1cm \mainrule=1pt \subrule=0.2pt-

\subsubsection{Réglures horizontales}
Construisons la macro §\grid pas à pas et décidons que cette macro mettra des éléments dans une \idx\vbox.Nous allons dans un premier temps empiler des éléments dans une liste verticale pour tracer les réglures horizontales. Il est bien entendu que l'épaisseur des réglures ne doit pas perturber les espacements verticaux, c'est pourquoi elles doivent être mises dans une sous-boite de hauteur nulle. Nous allons donc définir l'analogue de §\clap mais pour les \idx\vbox. La macro suivante, §\vlap enferme son argument dans une boite verticale et rend la hauteur du tout égale à \verb|0pt| :

\centrecode-\def\vlap#1{\vbox to0pt{\vss#1\vss}}-\idx*\vss

Chaque réglure horizontale doit avoir comme largeur \verb|\xunit*#1|, que nous stockerons dans une macro pour l'utiliser ensuite. Pour que les espacements verticaux soient rigoureusement exacts, le ressort inter-ligne doit être neutralisé et pour cela, \idx\offinterlineskip sera appelé au début de la \idx\vbox. Voici un premier essai où ne sont construites que les réglures horizontales principales. On prend les unités égales à \numprint[cm]{0.5} par souci de gain de place.

\showcode/\xunit=0.5cm \yunit=0.5cm \mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}¤§*\vlap\idx*\vss¤
\catcode`@11
\def\grid#1#2#3#4{%¤§*\grid¤
	\vbox{% empiler les éléments verticalement¤\idx*\vbox¤
		\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
		\edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale ds réglures¤\idx*\the\idx*\dimexpr¤
		\for\ii = 1 to #3 \do1% pour chaque carreau vertical (\ii=variable muette)¤§*\for¤
			{\vlap{\hrule width\total@wd height\mainrule}% tracer la réglure horizontale¤\idx*\hrule§*\vlap¤
			\kern\yunit% insérer l'espace vertical¤\idx*\kern¤
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernière réglure horizontale¤§*\vlap¤
	}%
}
\catcode`@12
\setbox0\hbox{\grid{4}{}{3}{}}% range la quadrillage dans le registre no 0¤\idx*\setbox\idx*\hbox¤
Essai \copy0{} qui a pour
largeur=\convertunit{\wd0}{cm} cm et pour hauteur=\convertunit{\ht0}{cm} cm¤§*\convertunit\idx*\ht\idx*\wd¤/

Pour s'assurer que les dimensions du quadrillage sont parfaitement correctes, le quadrillage a été placé dans une \idx\hbox stockée dans le registre de boite \no0\idx*{boite!\no0}. Ainsi, nous pouvons mesurer sa largeur et sa hauteur (converties en \verb|cm| avec la macro §\convertunit vue précédemment) : les dimensions obtenues sont bien \numprint[cm]2 de largeur et \numprint[cm]{1.5} en hauteur qui correspondent à 4\verb|\xunit| et à 3\verb|\yunit|.
\grandsaut

Venons-en aux lignes horizontales de subdivisions. Elles seront placées immédiatement \emph{sous} la position courante de la réglure principale en cours, moyennant un ressort \idx\vss inséré en fin de \idx\vbox. Le code suivant illustre cette structure :

\showcode/Début\vbox to0pt{\hbox{sous}\hbox{la ligne de base}\vss}suite¤\idx*\vss¤/
\grandsaut

Dans le cas présent, nous placerons sous la position de la réglure principale en cours le matériel suivant, répété \verb|#4|${}-{}1$ fois   :

\begin{itemize}
	\item l'espace verticale de dimension \verb|\yunit/#4|;
	\item la réglure secondaire, enfermée dans une §\vlap, de façon à ce que son épaisseur n'entre pas en ligne de compte.
\end{itemize}

\noindent Remarquons qu'il n'y a pas lieu de tester si \verb|#4|${}>1$, car la boucle §\for suivante 

\centrecode-\for\jj = 2 to #4 \do 1 {<code à exécuter>}-

\noindent ne s'exécutera que si le test est vrai.

\showcode|\xunit=0.5cm \yunit=0.5cm \mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}¤§*\vlap\idx*\vss¤
\catcode`@11
\def\grid#1#2#3#4{%¤§*\grid¤
	\vbox{% empiler les éléments verticalement¤\idx*\vbox¤
		\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
		\edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale de la boite¤\idx*\the\idx*\dimexpr¤
		\edef\sub@unit{\the\dimexpr\yunit/#4\relax}% hauteur verticale de la subdivision
		\for\ii = 1 to #3 \do% pour chaque unité verticale en partant du haut, tracer :¤§*\for¤
			{\vlap{\hrule width\total@wd height\mainrule}% la réglure horizontale principale¤§*\vlap¤
			% et dessous, les réglures horizontales secondaires :
			\vbox to\z@{% dans une \vbox de hauteur nulle,¤\idx*\vbox\idx*\z@¤
				\for\jj = 2 to #4 \do 1% insérer #4-1 fois sous la position courante :¤§*\for¤
					{\kern\sub@unit % l'espace verticale¤\idx*\kern¤
					\vlap{\hrule width\total@wd height\subrule}% et la réglure secondaire¤§*\vlap\idx*\vrule¤
					}%
				\vss% ressort qui se comprime pour satisfaire la hauteur nulle¤\idx*\vss¤
			}%
			\kern\yunit% insérer l'espace vertical entre réglures principales¤\idx*\kern¤
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernière réglure principale du bas¤§*\vlap¤
	}%
}
\catcode`@12
\setbox0=\hbox{\grid{4}{}{3}{5}}¤\idx*\setbox¤
Essai \copy0{} qui a pour
largeur=\convertunit{\wd0}{cm} cm et pour hauteur=\convertunit{\ht0}{cm} cm¤\idx*\wd\idx*\ht§*\convertunit¤|

\subsubsection{Réglures verticales}
Pour les réglures verticales, nous allons procéder exactement de la même façon qu'avec les réglures horizontales. Nous allons les tracer avant les réglures horizontales et le tout sera enfermé dans une \idx\vbox chapeau contenant la totalité du quadrillage.

Afin que ces réglures verticales ne prennent aucun encombrement vertical, nous les enfermerons dans une \idx\vbox de hauteur nulle et ferons en sorte que le contenu de cette boite se place au-dessous de la plus haute position de la \idx\vbox chapeau en utilisant à nouveau cette structure :

\centrecode-\vbox to0pt{<réglures verticales>\vss}-\idx*\vss

La totalité des réglures verticales sera mise dans une \idx\rlap, c'est-à-dire en débordement à droite de la position courante :

\centrecode-\vbox to0pt{\rlap{<réglures verticales>}\vss}-\idx*\vss

Il est maintenant clair que, puisque la \idx\rlap a une largeur nulle, cette \idx\vbox aura toutes ses dimensions nulles. Cela signifie que toutes les réglures verticales seront dessinées sans que la position courante ne change.

\showcode|\mainrule=0.8pt \subrule=0.2pt
\def\vlap#1{\vbox to0pt{\vss#1\vss}}¤§*\vlap\idx*\vss¤
\catcode`@11
\def\grid#1#2#3#4{%¤§*\grid¤
	\vbox{% empiler les éléments verticalement¤\idx*\vbox¤
		\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
		% #################### Tracé des réglures verticales ####################
		\vbox to\z@{% dans une \vbox de hauteur nulle¤\idx*\vbox\idx*\z@¤
			\edef\total@ht{\the\dimexpr\yunit*#3\relax}% hauteur totale¤\idx*\the\idx*\dimexpr¤
			\edef\sub@unit{\the\dimexpr\xunit/#2\relax}% espace entre 2 subdivisions
			\rlap{% mettre à droite de la position sans bouger¤\idx*\rlap¤
				\for\ii = 1 to #1 \do 1% pour chaque unité horizontale¤§*\for¤
					{\clap{\vrule width\dimexpr\mainrule height\total@ht}% réglure principale¤\idx*\vrule§*\clap¤
					\rlap{% mettre à droite de la position sans bouger¤\idx*\rlap¤
						\for\jj = 2 to #2 \do 1% insérer #2-1 fois
							{\kern\sub@unit % l'espace horizontal¤\idx*\kern¤
							\clap{\vrule width\subrule height\total@ht}% et la réglure verticale¤§*\clap\idx*\vrule¤
							}%
					}%
					\kern\xunit % insérer l'espace entre réglures horizontales
					}%
				\clap{\vrule width\mainrule height\total@ht}% dernière réglure principale¤\idx*\vrule§*\clap¤
			}%
			\vss% compense la hauteur=0pt de la \vbox¤\idx*\vss¤
		}%
		% #################### Tracé des réglures horizontales ####################
		\edef\total@wd{\the\dimexpr\xunit*#1\relax}% largeur totale de la boite¤\idx*\the\idx*\dimexpr¤
		\edef\sub@unit{\the\dimexpr\yunit/#4\relax}% espace entre 2 subdivisions
		\for\ii = 1 to #3 \do 1% pour chaque carreau vertical en partant du haut :¤§*\for¤
			{\vlap{\hrule width\total@wd height\mainrule}% réglure horizontale principale¤§*\vlap¤
			% et dessous, les réglures secondaires :
			\vbox to\z@{% dans une \vbox de hauteur nulle,¤\idx*\vbox\idx*\z@¤
				\for\jj = 2 to #4 \do 1% insérer #4-1 fois sous la position courante :¤§*\for¤
					{\kern\sub@unit % l'espace vertical¤\idx*\kern¤
					\vlap{\hrule width\total@wd height\subrule}% et la réglure secondaire¤§*\vlap\idx*\vrule¤
					}%
				\vss% ressort qui se comprime pour satisfaire la hauteur nulle¤\idx*\vss¤
			}%
			\kern\yunit% insérer l'espace vertical entre réglures principales¤\idx*\kern¤
			}%
		\vlap{\hrule width\total@wd height\mainrule}% dernière réglure horizontale¤§*\vlap¤
	}%
}
\catcode`@12
Grille 1 : \xunit=1cm \yunit=1cm \grid{5}{10}{2}{10}\smallskip¤\idx*\smallskip¤

Grille 2 : \xunit=0.5cm \yunit=0.5cm \grid{7}{1}{3}{1}\smallskip¤\idx*\smallskip¤

Grille 3 : \xunit=1.5cm \yunit=0.5cm \grid{4}{3}{3}{2}|§*\grid[|)]\idx*[|)]{réglure}\idx*[|)]{quadrillages}

\section{Répétition de motifs}\label{repetition.motifs}
\subsection{\texttt{\char`\\leaders} et ses complices}\idx*[|(]{\leaders}
Venons-en maintenant à une primitive intéressante qui a la capacité de répéter une boite autant de fois que nécessaire pour remplir un espace donné, que ce soit en mode horizontal\idx*{mode!horizontal} ou vertical\idx*{mode!vertical}. Cette primitive est \idx\leaders et la syntaxe pour le mode horizontal\idx*{mode!horizontal} est la suivante :

\centrecode-\leaders<boite ou réglure>\hskip<ressort>-

\noindent La syntaxe est la même pour le mode vertical\idx*{mode!vertical} sauf que \idx\vskip est utilisé au lieu de \idx\hskip. En réalité, \idx\leaders est juste une assignation pour le \verb|<ressort>| qui spécifie tout simplement avec quel motif il doit être rempli. Car contrairement aux \idx\kern, un ressort a vocation à être rempli avec quelque chose ! Si \idx\leaders est absent comme cela a été le cas jusqu'à présent, ce motif est vide ce qui conduit à des ressorts qui laissent des espaces blancs.

Intéressons-nous au mode horizontal\idx*{mode!horizontal}, celui en grande majorité pour lequel est utilisée \idx\leaders. Supposons que la boite de \numprint[cm]{1.5} de long suivante

\centrecode-\hbox to1.5cm{\hss A\hss}-

\noindent doive remplir un espace de \numprint[cm]{10}. La primitive \idx\leaders va coller ces boites les unes aux autres de façon à remplir le plus grand espace possible. Ce collage se fera bord à bord en partant de la gauche et laissera, si la longueur à remplir n'est pas un multiple de la longueur du motif, une espace laissée vide à la fin. Dans le code ci-dessous, nous spécifions «\verb|\hbox to10cm|» pour imposer que la dimension horizontale à remplir soit de \numprint[cm]{10}. Les \idx\vrule placées de part et d'autre de cette \idx\hbox permettent de visualiser le début et la fin de cette boite :

\showcode/\vrule\hbox to10cm{\leaders\hbox to1.5cm{\hss A\hss}\hfill}\vrule¤\idx*\vrule\idx*\leaders\idx*\hbox\idx*\hfill¤/

Comme on peut facilement s'en assurer par calcul mental, seules 6 copies de la boites ont été collées les unes aux autres pour remplir un espace de \numprint[cm]9, laissant une espace vide de \numprint[cm]1 à la fin.

Deux variantes de cette primitive existent et permettent de répartir l'éventuelle espace non remplie :
\begin{itemize}
	\item avec \idx\cleaders, elle est également répartie avant la première et après la dernière boite répétée ;
	\item avec \idx\xleaders, elle est également répartie avant la première, après la dernière et entre chaque boite répétée.
\end{itemize}

Le plus visuellement compréhensible est de définir cette boite «{\frboxsep=-\frboxrule \frbox{\hbox to1.5cm{\hss A\hss}}}», de \numprint[cm]{1.5} de long et encadrée au plus proche par ce code :

\centrecode/\frboxsep=-\frboxrule \frbox{\hbox to1.5cm{\hss A\hss}}/

\noindent et regarder les différences de comportement entre les différentes variantes. Pour bien visualiser l'espace de \numprint[cm]{10} à remplir, le caractère actif «\cidx\~» a été programmé pour imprimer une réglure horizontale de \verb|1em| de longueur juste avant et juste après cette espace :

\showcode/\frboxsep=-\frboxrule \def~{\leavevmode\raise.75ex\hbox{\vrule height.2pt width1em}}¤§*\frboxsep\cidx*\~\idx*\raise\idx*\hbox\idx*\leavevmode\idx*\vrule¤
~\hbox to10cm{\leaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~¤\idx*\hfill\idx*\hss\idx*\leaders§*\frbox¤

~\hbox to10cm{\cleaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~¤\idx*\cleaders¤

~\hbox to10cm{\xleaders\hbox{\frbox{\hbox to1.5cm{\hss A\hss}}}\hfill}~¤\idx*\xleaders§*\frbox¤/

Au lieu d'un encadrement contenant un texte, on peut aussi mettre une réglure ou même plusieurs dans une boite pour faire des dessins rudimentaires :

\showcode+a) \leavevmode\hbox to10cm{\leaders\hrule\hfill}\smallskip¤\idx*\leavevmode\idx*\smallskip¤

b) \hbox to10cm{\leaders\hbox{\vrule height0.2pt width2.5mm \kern1.5mm}\hfill}¤\idx*\leaders\idx*\leavevmode\idx*\hfill¤

c) \vrule width0.2pt height1ex depth0pt % première réglure verticale
     \hbox to10cm{% puis répétition de "_|"
     \leaders\hbox{\vrule width2em height0.2pt \vrule width0.2pt height1ex}\hfill}¤\idx*\vrule¤

d) \hbox to10cm{\leaders\hbox{%¤\idx*\leaders\idx*\leavevmode¤
		\vrule height.2pt width.5em% 1/2 palier bas¤\idx*\vrule¤
		\vrule height5pt width0.2pt% montée au palier haut
		\vrule height5pt depth-4.8pt width1em% palier haut
		\vrule height5pt width0.2pt% descente au palier bas
		\vrule height.2pt width.5em% 1/2 palier bas¤\idx*\vrule¤
		}\hfill}+

La macro \idx\hrulefill, qui remplit l'espace disponible avec une réglure horizontale, est programmée de la façon suivante dans plain-\TeX{} :

\centrecode-\def\hrulefill{\leaders\hrule\hfill}-

\noindent C'est d'ailleurs un cas où la primitive \idx\hrule peut être appelée en mode horizontal\idx*{mode!horizontal} pour produire une réglure horizontale alors que son mode de fonctionnement est le mode vertical\idx*{mode!vertical}.\idx*[|)]{\leaders}

\subsection{Retour sur le quadrillage}
On entrevoit que la primitive \idx\leaders, de par sa propriété qui est d'effectuer une répétition, peut nous aider à tracer un quadrillage sans faire explicitement appel à une boucle ! Pour y arriver, nous allons tout d'abord nous employer à construire un carreau-unité avec les subdivisions adéquates que \idx\leaders répètera horizontalement et verticalement pour créer le quadrillage.

Commençons verticalement. S'il faut $n$ subdivisions dans une espace verticale de \verb|\yunit|, il faut empiler verticalement dans une boite de hauteur \verb|\yunit| :

\begin{enumerate}
	\item une réglure horizontale d'épaisseur \verb|\mainrule| dont la dimension verticale sera forcée à 0pt;
	\item placer autant de fois qu'il est possible ce matériel vertical suivant (dont la dimension est \verb|\yunit|/$n$) :
	\begin{enumerate}
		\item une espace verticale de dimension \verb|\yunit|/$n$;
		\item une réglure horizontale d'épaisseur \verb|\subrule| dont la dimension verticale sera forcée à 0pt;
	\end{enumerate}
	\item une espace verticale de dimension \verb|\yunit|/$n$;
	\item une réglure horizontale d'épaisseur \verb|\mainrule| dont la dimension verticale sera forcée à 0pt.
\end{enumerate}

Comme les composants du point \no2 prennent à chaque fois \verb|\yunit|/$n$ d'espace vertical et que les deux derniers composants prennent aussi cette espace, la répétition de l'élément 2 aura donc lieu $n-1$ fois.

\showcode|\mainrule=0.8pt \subrule=0.2pt
\def\carreau#1#2{% #1=nb subdiv H  #2=nb subdiv V
	\vbox to\yunit{% dans un \vbox de hauteur \yunit¤\idx*\vbox¤
		\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
		\vlap{\hrule height\mainrule width\xunit}% réglure principale du haut¤§*\vlap¤
		\leaders% répéter (ici ce sera donc #2-1 fois)¤\idx*\leaders¤
			\vbox to\dimexpr\yunit/#2\relax% une \vbox de hauteur \yunit/#2¤\idx*\vbox\idx*\dimexpr¤
				{\vss% ressort qui va s'étirer à \yunit/#2¤\idx*\vss¤
				\vlap{\hrule height\subrule width\xunit}% réglure de subdiv de dim 0pt
				}\vfill¤\idx*\vfill¤
		\kern\dimexpr\yunit/#2\relax% dernière espace verticale¤\idx*\kern¤
		\vlap{\hrule height\mainrule width\xunit}% réglure principale du bas¤\idx*\hrule§*\vlap¤
	}%
}
\yunit=1cm
\leavevmode \carreau{}{4} puis \carreau{}{10}¤\idx*\leavevmode¤|

Pour les réglures horizontales, nous allons procéder de même après voir mis tout le code précédent dans une \idx\rlap de telle sorte que son encombrement horizontal soit nul.

\showcode|\mainrule=0.8pt \subrule=0.2pt
\def\carreau#1#2{% #1=nb subdiv H  #2=nb subdiv V
	% ######## réglures horizontales ########
	\rlap{% mettre à droite de la position sans bouger¤\idx*\rlap¤
		\vbox to\yunit{% dans un \vbox de hauteur \yunit
			\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
			\vlap{\hrule height\mainrule width\xunit}% réglure principale du haut¤§*\vlap¤
			\leaders% répéter (ici ce sera #2-1 fois)¤\idx*\leaders¤
				\vbox to\dimexpr\yunit/#2\relax% une \vbox de hauteur \yunit/#2¤\idx*\vbox\idx*\dimexpr¤
					{\vss% ressort qui va s'étirer à \yunit/#2¤\idx*\vss¤
					\vlap{\hrule height\subrule width\xunit}% réglure de subdiv de dim 0pt
					}\vfill% ressort de \leaders¤\idx*\vfill¤
			\kern\dimexpr\yunit/#2\relax% derniere espace verticale¤\idx*\kern¤
			\vlap{\hrule height\mainrule width\xunit}% réglure principale du bas¤\idx*\hrule§*\vlap¤
		}%
	}%
	% ######## réglures verticales ########
	\hbox to\xunit{% dans une \hbox de longueur \xunit¤\idx*\hbox¤
		\clap{\vrule height\yunit width\mainrule}% réglure principale de gauche¤§*\clap\idx*\vrule¤
		\leaders% répéter (ici ce sera #1-1 fois)¤\idx*\leaders¤
			\hbox to\dimexpr\xunit/#1\relax¤\idx*\dimexpr\idx*\hbox¤
				{\hss% ressort qui va s'étirer à \xunit/#1¤\idx*\hss¤
				\clap{\vrule height\yunit width\subrule}% réglure H de dimension 0
				}\hfill% ressort de \leaders¤\idx*\hfill¤
			\kern\dimexpr\xunit/#1\relax% dernière espace H¤\idx*\kern¤
			\clap{\vrule height\yunit width\mainrule}% réglure principale de droite¤\idx*\vrule§*\clap¤
	}%
}
\yunit=1cm \xunit=2cm
\leavevmode \carreau{3}{4} puis \carreau{8}{10}¤\idx*\leavevmode¤|

Il suffit maintenant de mettre le tout dans une \idx\hbox. Cette boite a pour exactes dimensions \verb|\xunit| et \verb|\yunit| et il ne reste plus qu'à confier à \idx\leaders le soin de la répéter autant de fois horizontalement et verticalement que l'on veut de carreaux dans ces deux directions :

\begingroup
\def\carreau#1#2{% #1=nb subdiv H  #2=nb subdiv V
	% #### réglures horizontales
	\rlap{% mettre à droite de la position sans bouger¤\idx*\rlap¤
		\vbox to\yunit{% dans un \vbox de hauteur \yunit¤\idx*\vbox¤
			\offinterlineskip% pas de ressort d'interligne¤\idx*\offinterlineskip¤
			\vlap{\hrule height\mainrule width\xunit}% réglure principale¤§*\vlap\idx*\hrule¤
			\leaders% répéter (ici ce sera donc #2-1 fois)¤\idx*\leaders¤
				\vbox to\dimexpr\yunit/#2\relax% une \vbox de hauteur \yunit/#2¤\idx*\dimexpr¤
					{\vss% ressort qui va s'étirer à \yunit/#2¤\idx*\vss¤
					\vlap{\hrule height\subrule width\xunit}% réglure de subdiv de dim 0pt
					}\vfill% ressort de \leaders¤\idx*\vfill¤
			\kern\dimexpr\yunit/#2\relax% derniere espace verticale¤\idx*\kern¤
			\vlap{\hrule height\mainrule width\xunit}% réglure principale¤§*\vlap¤
		}%
	}%
	% #### réglures verticales
	\hbox to\xunit{% dans une \hbox de longueur \xunit¤\idx*\vbox¤
		\clap{\vrule height\yunit width\mainrule}% réglure principale¤§*\clap\idx*\vrule¤
		\leaders% réopéter (ici ce sera donc #1-1 fois)¤\idx*\leaders¤
			\hbox to\dimexpr\xunit/#1\relax¤\idx*\hbox¤
				{\hss% ressort qui va s'étirer à \xunit/#1¤\idx*\hss¤
				\clap{\vrule height\yunit width\subrule}% réglure H de dimension 0¤§*\clap¤
				}\hfill% ressort de \leaders¤\idx*\hfill¤
			\kern\dimexpr\xunit/#1\relax% dernière espace H¤\idx*\kern¤
			\clap{\vrule height\yunit width\mainrule}% réglure principale¤\idx*\vrule§*\clap¤
	}%
}
\showcode|\mainrule=0.8pt \subrule=0.2pt
\def\grid#1#2#3#4{%¤§*\grid¤
	\vbox to#3\yunit{% dans une boite verticale de hauteur #3*\yunit¤\idx*\vbox¤
		\leaders% répéter verticalement¤\idx*\leaders¤
			\hbox to#1\xunit{% une boite de longueur #1*\xunit
				\leaders% dans laquelle se répète horizontalement¤\idx*\leaders¤
					\hbox{\carreau{#2}{#4}}% le carreau de largeur \xunit
				\hfill}%¤\idx*\hfill¤
		\vfill¤\idx*\vfill¤
	}%
}
Grille 1 : \xunit=1cm \yunit=1cm \grid{5}{10}{2}{10}\smallskip¤\idx*\smallskip¤

Grille 2 : \xunit=0.5cm \yunit=0.5cm \grid{7}{1}{3}{1}\smallskip¤\idx*\smallskip¤

Grille 3 : \xunit=1.5cm \yunit=0.5cm \grid{4}{3}{3}{2}|
\endgroup

Bien que le résultat soit strictement identique, la façon de tracer le quadrillage avec \idx\leaders comme ci-dessus est très différente de celle employée précédemment avec la boucle §\for. En effet, la méthode avec \idx\leaders est beaucoup plus «laborieuse» puisqu'il s'agit d'une bête répétition d'un élément. Le résultat est trompeur pour l'\oe il, car la répétition horizontale et verticale de cet élément donne l'illusion que les réglures horizontales ou verticales sont tracées en un coup alors qu'il n'en est rien. De plus, toutes les réglures principales communes à deux carreaux-unité adjacents sont même superposées et sont donc tracées deux fois. Personne ne tracerait un quadrillage à la main de cette façon sur une feuille de papier ! À l'inverse, la méthode avec §\for bâtissait le quadrillage de façon plus globale puisque les réglures avaient la dimension maximale et étaient effectivement tracées en un coup, comme on le ferait spontanément à la règle et au crayon.

\chapter{Fichiers : lecture et écriture}\idx*[|(]{fichier}
\section{Lire un fichier}\idx*[|(]{fichier!lecture}
\subsection{La primitive \texttt{\char`\\ input}}\idx*[|(]\input
\TeX{} peut « lire un fichier », c'est-à-dire qu'il peut lire le contenu du fichier, exactement comme il le fait lorsqu'il lit le code source. Pour cela, on utilise la syntaxe\footnote{Il est peut-être utile de signaler que \LaTeX{}, aussi incroyable que cela puisse paraitre, franchit un interdit en redéfinissant la primitive \texttt{\string\input} pour en faire une macro (non développable). Fort heureusement, la primitive est sauvegardée par \texttt{\string\let} dans la séquence de contrôle \texttt{\string\@@input}.} :

\centrecode-\input <nom d'un fichier>-

\noindent Lorsque \TeX{} s'attend à lire le nom d'un fichier, le développement maximal se met en place. Le nom du fichier s'étend jusqu'au premier espace rencontré (et cet espace sera absorbé) ou jusqu'à la première primitive non développable : mettre un espace ou un \idx\relax après la fin d'un nom de fichier est donc une bonne habitude à prendre.

La primitive \idx\jobname se développe en le nom du fichier « maitre » en cours de compilation. Le fichier « maitre » est le fichier de plus haut niveau, celui qui n'a été appelé par aucun \idx\input.  Le nom créé par \idx\jobname se compose de caractères de catcode 12\idx*{catcode!12 (autre)} et ne comporte pas l'extension du fichier, c'est-à-dire le «\verb|.|» et les caractères qui le suivent.

Le fichier lu par \idx\input peut lui aussi contenir la primitive \idx\input, et ainsi de suite récursivement dans des limites raisonnables. Une fois que la fin du fichier est atteinte ou que la primitive \verb|\endinput| est rencontrée, \TeX{} cesse la lecture du fichier et la reprend dans fichier parent où il s'était interrompu.

\begin{regle}
Lorsque \TeX{} lit le code source, on peut faire lire à \TeX{} le contenu d'un fichier. La lecture se fera comme se fait celle du code source et tout se passe donc comme si l'intégralité du contenu du fichier était insérée dans le code source à l'endroit où est rencontré :

\centrecode-\input <nom de fichier>-

Si le \verb|<nom de fichier>| ne spécifie pas d'extension, \TeX{} rajoute «\verb|.tex|».

La lecture du fichier s'arrête lorsque la fin du fichier est atteinte ou lorsque la primitive \verb|\endinput| est atteinte.
\end{regle}

\subsection{\texttt{\char`\\ input} et ses secrets}\label{input.secrets}
Examinons maintenant les autres aspects bien plus \TeX niques de la primitive \idx\input. Cette section, assez ardue, peut être sautée lors d'une première lecture.

Tout d'abord, la primitive \idx\input est développable lorsqu'on la 1-développe, tout se passe comme si \TeX{} détournait sa tête de lecture pour aller lire la totalité du contenu du fichier. Il faut signaler que la totalité du fichier est lue selon le régime de catcode en vigueur au moment du 1-développement. De la même façon qu'il le fait lorsqu'il lit du code source, \TeX{} insère le caractère de code \idx\endlinechar à la fin de chaque ligne du fichier, y compris la dernière.

Plusieurs choses assez \TeX niques se passent à la fin d'un fichier :

\begin{enumerate}
	\item avant la fin du fichier, \TeX{} insère le contenu de \idx\everyeof. Cette primitive a un comportement identique à celui d'un registre de tokens et elle est vide par défaut;
	\item juste après le code inséré par \idx\everyeof, \TeX{} exécute une routine interne.
\end{enumerate}

Cette routine interne est en réalité un test auquel procède \TeX{} : il vérifie que l'endroit où il se trouve est compatible avec le statut \idx\outer\footnote{On peut le constater dans le code source «\texttt{tex.web}» du programme \texttt{tex} à la section \no362, le test «\texttt{check\_outer\_validity}» est effectué.}. Avant de poursuivre, il faut définir ce qu'est ce statut : il concerne normalement les macros qui peuvent être définies comme étant «\idx\outer».

\label{outer}\begin{regle}
Lorsque la primitive \idx\outer précède la définition d'une macro, cette dernière ne pourra pas se situer dans les endroits où \TeX{} lit du code « à grande vitesse »\idx*{lecture à grande vitesse}, à savoir :
\begin{itemize}
	\item le texte de remplacement ou le \idx{texte de paramètre} lors de la définition d'une macro ;
	\item le code situé dans les branches d'un test;
	\item le préambule d'un alignement initié par \idx\halign ou \idx\valign.
\end{itemize}
\end{regle}

Si une telle macro se trouve dans ces endroits interdits, un message d'erreur sera émis et la compilation stoppée :

\errcode/\outer\def\foo{Bonjour}
\def\bar{\foo}/{! Forbidden control sequence found while scanning definition of \string\bar.}

Une action peu connue de \idx\noexpand\verb|<token>|, lorsque \idx\noexpand est développé, est de désactiver pour le \verb|<token>| le test qui vérifie si ce \verb|<token>| est \idx\outer\footnote{Cela est expliqué à la section \no369 de \texttt{tex.web} par \textsc{Knuth} lui-même : «Comme des macros {\string\outer} peuvent se présenter ici, on doit aussi réinitialiser [à "\texttt{normal}"] le \texttt{scanner\_statut} temporairement.»}. On peut donc l'utiliser pour enfreindre la règle précédente et mettre une macro \idx\outer dans le texte de remplacement d'une autre macro :

\showcode/\outer\def\foo{Bonjour}¤\idx*\outer¤
\expandafter\def\expandafter\bar\expandafter{\noexpand\foo}¤\idx*\noexpand¤
\meaning\bar¤\idx*\meaning¤

\edef\baz{\noexpand\foo}¤\idx*\noexpand¤
\meaning\baz/

Revenons au test à la fin du fichier : comme il vérifie que l'endroit où il se trouve est compatible avec \idx\outer, il communique à la fin du fichier le statut \idx\outer. Pour désactiver le test, nous allons appliquer la même méthode qu'avec une macro \idx\outer, c'est-à-dire le faire précéder de la primitive \idx\noexpand.

\begin{regle}
La fin d'un fichier a le statut \idx\outer.

Pour permettre que la fin d'un fichier se situe dans un endroit normalement interdit à ce statut, il faut placer la primitive \idx\noexpand juste avant la fin du fichier, soit en l'écrivant explicitement, soit via \idx\everyeof avec l'assignation

\centrecode-\everyeof{\noexpand}-\idx*\everyeof

\noindent et faire en sorte de développer ce \idx\noexpand.
\end{regle}

Développer le \idx\noexpand rend très contraignante et quasi impossible la définition d'une macro dont le texte de remplacement serait le contenu d'un fichier. En effet, pour forcer ce développement \emph{avant} que la définition de la macro ne se fasse, il faudrait la définir avec \idx[|etc]\edef\forbidindex\edef{} selon ce schéma :

\centrecode-\begingroup
\everyeof{\noexpand}¤\idx*\noexpand¤
\global\edef\<macro>{\input<nom de fichier> }
\endgroup-\idx*\global\idx*\input

Cette définition est très peu satisfaisante, car la primitive \idx\edef implique que le contenu du fichier est développé au maximum ce qui, sauf cas très particulier, n'est pas ce qui est recherché. De plus, elle rend la définition globale puisqu'un groupe semi-simple a été ouvert pour limiter la portée de la modification de \idx\everyeof.

\label{input.dans.macro}Heureusement, nous pouvons bien mieux faire. L'idée est d'insérer un délimiteur (ici \verb|\eof@nil|) en fin de fichier via \idx\everyeof. Ce délimiteur sera capturé par une macro auxiliaire à argument délimité qui sera dès lors capable de savoir où se trouve la fin du fichier et affecter à une macro ce qui se trouve dans ce fichier avant ce délimiteur. Toute cette man\oe uvre suppose que le fichier ne contient pas \verb|\eof@nil|.

Supposons par exemple que le fichier «\texttt{test.txt}» contient :

\centrecode-Programmer en \TeX{} est   facile

et utile-

Voici comment programmer une macro §*\filedef[|(]

\centrecode-\filedef\<macro>{<nom du fichier>}-
\immediate\openout\wtest=test.txt
\exactwrite\wtest|Programmer en \TeX{} est   facile

et utile|%
\immediate\closeout\wtest

\noindent qui définit une \verb|\<macro>| dont le texte de remplacement est le contenu du fichier :

\showcode/\catcode`\@11
\long\def\filedef#1#2{%¤§*\filedef\idx*\long¤
	\begingroup
		\let\input\@@input% <- utilisateurs de latex uniquement¤\idx*\input\idx*\@@input\idx*[|etc]\let\forbidindex\let¤
		\everyeof{\eof@nil\noexpand}% insère "\eof@nil\noexpand" à la fin du fichier¤\idx*\everyeof\idx*\noexpand¤
		\expandafter\filedef@i\expandafter#1% développe \input #2¤\defline\ccc¤
			\expandafter\relax\input #2¤\defline\aaa¤
}
\long\def\filedef@i#1#2\eof@nil{%¤\idx*\long¤
	\endgroup
	\expandafter\def\expandafter#1\expandafter{\gobone#2}% mange le \relax¤\defline\bbb¤
}
\catcode`\@12
\filedef\foo{test.txt}
\meaning\foo/

La ligne «\verb|\let\input\@@input|» redonne à \idx\input son statut de primitive et annule la redéfinition effectuée par \LaTeX\footnote{Ce livre a été compilé en utilisant le format \LaTeX.}. Il est bien évident que les utilisateurs d'autres formats ne doivent pas écrire cette ligne.

Ensuite, à la ligne \no\aaa, un \idx\relax a été inséré avant le développement de \idx\input. Ceci nous assure que l'argument délimité \verb|#2| de \verb|\filedef@i| ne serait pas dépouillé de ses accolades si jamais le contenu du fichier était constitué d'un texte entre accolades. Ce \idx\relax est mangé à la ligne \no\bbb{} par le \verb|\gobone| avant que la définition ne soit faite.

L'important est de comprendre qu'une fois le \idx\input 1-développé par le pont d'\idx\expandafter et en tenant compte du contenu de \idx\everyeof, les lignes \nos\ccc{} et \number\numexpr\ccc+1\relax{} deviennent :

\centrecode-\filedef@i#1\relax<contenu du fichier lu par \input>\eof@nil\noexpand<EOF>-

\noindent La macro \verb|\filedef@i|, qui ne lit que ce qui se situe jusqu'au \verb|\eof@nil|, ne verra jamais la fin du fichier \verb|<EOF>|. Le but recherché est atteint : le \verb|<EOF>| est précédé d'un \idx\noexpand, et ce \idx\noexpand, en étant exécuté après que \verb|\filedef@i| ait fait son travail, rendra \verb|<EOF>| compatible avec le statut \idx\outer.\idx*[|)]\input§*\filedef[|)]

\section{Lire dans un fichier}
« Lire un fichier » n'a pas la même signification que « lire \emph{dans} un fichier » qui sous-entend que l'on peut lire, contrôler ce qu'on lit et donc reprendre la main. Pour fonctionner selon ce mode, \TeX{} dispose de 16 canaux d'entrée, numérotés de 0 à 15, chacun correspondant à un flux de lecture. Comme pour les boites, les compteurs, les dimensions et les registres de tokens, plain-\TeX{} fournit la macro \idx\newread\verb|\<macro>| qui assigne\footnote{Cette macro fonctionne comme son homologue \texttt{\string\newbox}. Comme il n'existe pas de primitive \texttt{\string\readdef}, la macro est définie par la primitive \texttt{\string\chardef}.} à la \verb|\<macro>| un entier correspondant à un canal de lecture disponible.

\begin{regle}
\relax\TeX{} dispose de 15 canaux de lecture portant les numéros de 0 à 15.

On demande l'allocation d'un canal de lecture par

\centrecode-\newread\<macro>-

et ce faisant, la \verb|\<macro>| devient équivalente à un \verb|<nombre>|, qui est un numéro de canal libre. Un \verb|<canal>| est donc un \verb|<nombre>| explicitement écrit ou une macro définie avec \idx\newread.
\medbreak

Avant de lire dans un fichier, on doit d'abord lier un \verb|<canal>| à un fichier avec\idx*\openin :

\centrecode-\openin<canal>= <nom du fichier>-

\noindent Si aucune extension n'est précisée au \verb|<nom du fichier>|, \TeX{} rajoute «\verb|.tex|». Le signe \verb|=| et l'espace qui le suit sont optionnels. Lorsque \TeX{} lit le \verb|<nom du fichier>|, il entre dans une phase de développement maximal et si ce nom est suivi d'un espace, cet espace est absorbé.

Tout canal ouvert doit être fermé et donc, après avoir fait les opérations de lecture, il convient d'exécuter \idx\closein\verb|<canal>| pour désolidariser le \verb|<canal>| du fichier qui lui avait été attaché avec \idx\openin.
\end{regle}

Le test \tidx{ifeof}\verb|<canal>| teste si la lecture du fichier lié au \verb|<canal>| est arrivée à la fin du fichier. Employé juste après avoir lié un flux à un fichier via \idx\openin, le test \verb|\ifeof<canal>| sera vrai uniquement si le fichier spécifié n'existe pas. Voici donc comment bâtir une macro §\iffileexists :

\showcode/¤\string\newread\string\rtest\idx*\newread¤% canal de lecture employé dans tout ce chapitre
\def\iffileexists#1#2{% #1=canal de lecture  #2=nom du fichier¤§*\iffileexists¤
	\openin#1=#2¤\idx*\openin¤
	\ifeof#1% le fichier n'existe pas¤\tidx*{ifeof}¤
		\closein#1¤\idx*\closein¤
		\expandafter\secondoftwo% renvoyer faux¤§*\secondoftwo[|etc]\forbidindex\secondoftwo¤
	\else
		\closein#1
		\expandafter\firstoftwo% sinon renvoyer vrai¤§*\firstoftwo[|etc]\forbidindex\firstoftwo¤
	\fi
}
a) \iffileexists\rtest{test.txt}{vrai}{faux}\qquad
b) \iffileexists\rtest{foobar.txt}{vrai}{faux}¤§*\iffileexists¤/

Dans tout cet exemple, nous avons demandé l'allocation d'un \verb|<canal>| avec « \idx\newread\verb|\rtest| » et désormais, nous utiliserons le canal de lecture \no\verb|\rtest| dans tous les exemples.
\grandsaut

Un fichier peut-être lu par plusieurs canaux simultanément. Cela signifie que si le besoin s'en fait sentir, on peut positionner des têtes de lecture dans un fichier à plusieurs endroits, chacune pouvant lire le fichier indépendamment des autres.

\begin{regle}
Lorsqu'un \verb|<canal>| de lecture est ouvert et lié à un fichier, \TeX{} peut lire des \emph{lignes} dans ce fichier les unes après les autres, et assigner la ligne lue à une macro. On utilise la syntaxe\idx*\read

\centrecode-\read\<canal> to \<macro>-

\noindent où le mot-clé «to» est obligatoire et éventuellement suivi d'espaces optionnels.

Ceci a pour effet de placer dans le texte de remplacement de la \verb|\<macro>| tout ce qu'il y a dans la ligne en cours :

\begin{itemize}
	\item les accolades doivent être équilibrées dans la ligne en cours. Si elles ne le sont pas, \TeX{} lit autant de lignes que nécessaire pour qu'elles le soient. Si la fin du fichier est atteinte sans que l'équilibrage des accolades ne soit réalisé, une erreur de compilation surviendra;
	\item une fois l'équilibrage des accolades atteint, la primitive \idx\read lit tout ce qui s'étend jusqu'à la «marque de \idx{fin de ligne}» (voir page~\pageref{marque.fin.ligne});
	\item les tokens dans le texte de remplacement de la \verb|\<macro>| tiennent compte du régime de catcode en vigueur lorsque \idx\read est exécutée; \idx\read effectue donc une « tokénisation», c'est-à-dire la transformation d'\idx{octet}s bruts en tokens;
	\item le caractère de code \idx\endlinechar est inséré à la fin du texte de remplacement de la\verb|\<macro>|;
	\item l'assignation est globale si \idx\read est précédé de \idx\global.
\end{itemize}

La primitive de \idx\eTeX{}\idx\readline, dont la syntaxe est

\centrecode-\readline\<canal> to \<macro>-

\noindent agit comme \idx\read sauf qu'elle insère dans le texte de remplacement de la \verb|\<macro>| tous les tokens lus dans la ligne (y compris le caractère de code \idx\endlinechar). L'espace aura le catcode 10\idx*{catcode!10 (espace)} et tous les autres caractères le catcode 12\idx*{catcode!12 (autre)}.
\end{regle}

Pour fixer les idées, si le canal \no\verb|\rtest| est lié à un fichier et que la ligne suivante à lire dans ce fichier est :

\centrecode-Programmer en \TeX{} est facile-

\noindent Si l'on écrit «\verb-\read\rtest to \foo-», tout se passe comme si on avait fait l'assignation d'une macro sans argument :

\centrecode-\def\foo{Programmer en \TeX{} est facile }-

\noindent Il est important de noter que l'espace en fin de texte provient du caractère de code \idx\endlinechar : celui-ci étant par défaut «\verbidx*[ (retour charriot)]{^^M}\verb|^^M|» de catcode \number\catcode`\^^M {}\idx*{catcode!5 (retour charriot)}, il est lu comme un espace comme le stipule la règle page~\pageref{regle.catcode5}. Pour mettre ce comportement en évidence dans l'exemple ci-dessous, le fichier \verb|filetest.txt| contiet :
\immediate\openout\wtest= filetest.txt
\exactwrite\wtest|Programmer en \TeX{} est   facile

et utile|%
\immediate\closeout\wtest

\centrecode-Programmer en \TeX{} est   facile

et utile-

Notons qu'il y a 3 espaces entre les mots « est » et « facile » et regardons ce que donne le code suivant :

\showcode|\openin\rtest =filetest.txt¤\idx*\openin¤
\read\rtest to \foo% lit la première ligne¤\idx*\read¤
1) Signification : \meaning\foo.\par% signification de ce qui a été lu¤\idx*\meaning¤
1) Exécution : \foo\par
\read\rtest to \foo% lit la deuxième ligne
2) Signification : \meaning\foo.\par
2) Exécution : \foo\par
\read\rtest to \foo% lit la dernière ligne¤\idx*\read¤
3) Signification : \meaning\foo.\par¤\idx*\meaning¤
3) Exécution : \foo
\closein\rtest¤\idx*\closein¤|

Les points après chaque \idx\meaning\verb|\foo| sont ici destinés à mettre en évidence l'espace en fin de texte de remplacement.

Voici le même exemple, cette fois-ci avec la primitive \idx\readline :

\showcode|\openin\rtest =filetest.txt¤\idx*\openin¤
\readline\rtest to \foo% lit la première ligne¤\idx*\readline¤
1) Signification : \meaning\foo.\par% signification de ce qui a été lu¤\idx*\meaning¤
1) Exécution : \foo\par
\readline\rtest to \foo% lit la deuxième ligne
2) Signification : \meaning\foo.\par
2) Exécution : \foo\par
\readline\rtest to \foo% lit la dernière ligne¤\idx*\readline¤
3) Signification : \meaning\foo.\par¤\idx*\meaning¤
3) Exécution : \foo
\closein\rtest¤\idx*\closein¤|

Une première question se pose naturellement : d'où viennent les virgules que l'on observe à la fin du texte de remplacement de \verb|\foo| ? Elles sont la preuve que le caractère de code \idx\endlinechar, placé en fin de ligne, a été détokénizé par \idx\readline pour devenir un inoffensif caractère de catcode 12\idx*{catcode!12 (autre)}. On voit une virgule car \idx\endlinechar a pour valeur \number\endlinechar{} et que le caractère ayant ce code dans la \idx{fonte} utilisée est la virgule :

\showcode/Valeur de \string\endlinechar = \number\endlinechar\par¤\idx*\string\idx*\number\idx*\endlinechar¤
Caractère correspondant : << \char\endlinechar{} >>¤\idx*\char¤/

Le second point qui peut surprendre est qu'au premier cas, le texte de remplacement de \verb|\foo| contient \emph{tous les espaces} (ils sont 3) entre les mots «est» et «facile», alors qu'un seul était lu par \idx\read. La subtile différence entre \idx\read et \idx\readline est que cette dernière ignore les catcodes en cours et insère dans le texte de remplacement de la macro \emph{tous} les caractères lus dans la ligne; elle insère donc \emph{tous} les espaces, en leur donnant un catcode de 10.

\begin{exercice}
Proposer une méthode pour que la macro \idx\read ne lise que ce qui se trouve dans la ligne courante, \emph{sans} y ajouter le caractère de code \idx\endlinechar.

Appliquer cette méthode pour écrire une macro §\xread[|(] qui agit de la même façon que \idx\read avec la même syntaxe :

\centrecode|\xread<canal> to \<macro>|

mais qui place dans le texte de remplacement de la \verb|\<macro>| le contenu de la ligne sans le caractère de code \idx\endlinechar.
\solution
Il suffit d'opérer localement et définir le \idx\endlinechar à $-1$ et utiliser un \idx\global pour que la 
\verb|\<macro>| survive à la fermeture du groupe :

\showcode|\openin\rtest =filetest.txt¤\idx*\openin¤
Ligne 1 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la première ligne¤\idx*\endlinechar\idx*\global\idx*\read¤
\meaning\foo.\par% donne ce qui a été lu¤\idx*\meaning¤
Ligne 2 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la deuxième ligne
\meaning\foo.\par
Ligne 3 : {\endlinechar=-1 \global\read\rtest to \foo}% lit la dernière ligne¤\idx*\endlinechar\idx*\global\idx*\read¤
\meaning\foo.¤\idx*\meaning¤
\closein\rtest¤\idx*\closein¤|

Contrairement à l'exemple précédent, comme le caractère de code \idx\endlinechar n'est pas inséré à la fin des lignes, la seconde ligne est bien lue comme étant vide.

Pour la macro \verb|\xread|, nous n'allons pas utiliser de \idx\global car il est toujours plus sûr de se passer, lorsque c'est possible, d'assignations globales qui provoquent des effets de bord difficiles à maitriser. Nous allons tout d'abord sauvegarder  dans la macro \verb|\restoreendlinechar| le code qui permet de restaurer \idx\endlinechar. Cette macro aura comme texte de remplacement

\centrecode-\endlinechar=<valeur actuelle de \endlinechar>-

Toute la difficulté vient ensuite des espaces optionnels qui se trouvent après le mot-clé «\verb|to|». En effet, si nous déclarons la macro §\xread ainsi

\centrecode-\def\xread#1to#2{<code à définir>}-

\noindent rien ne permet d'affirmer que l'argument \verb|#2| sera la \verb|\<macro>| : si des espaces optionnels sont écrits après «\verb|to|», alors \verb|#2| sera un espace. Il va donc falloir tester l'argument \verb|#2| et ne le prendre en compte que lorsqu'il sera une séquence de contrôle, ce qui suppose la mise en place d'une macro récursive. Pour mener à bien le test, nous mettrons en \oe uvre la macro §\ifcs programmée à la page~\pageref{ifcs.la.vraie}.

\showcode/\def\xread#1to#2{%
	\ifcs{#2}% si #2 est une séquence de contrôle
		{\edef\restoreendlinechar{\endlinechar=\the\endlinechar}%
		\endlinechar=-1 % supprime le caractère mis en fin de ligne
		\read#1to#2% lit la ligne et l'assigne à la macro #2
		\restoreendlinechar\relax% restaure le \endlinechar
		}% si #2 n'est pas une séquence de contrôle,
		{\xread#1to}% ignorer #2, et recommencer 
}

\openin\rtest =filetest.txt¤\idx*\openin¤
Ligne 1 : \xread\rtest to \foo% lit la première ligne
\meaning\foo.\par% donne ce qui a été lu¤\idx*\meaning¤
Ligne 2 : \xread\rtest to \foo% lit la deuxième ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la dernière ligne
\meaning\foo.¤\idx*\meaning¤
\closein\rtest¤\idx*\closein¤/

Une première remarque consiste à dire que la syntaxe de §\xread n'est \emph{pas exactement identique} à celle de \idx\read. En effet, la macro récursive §\xread ignore les arguments \verb|#2| tant qu'ils ne sont pas une séquence de contrôle. L'appel farfelu suivant est donc tout à fait valide :

\centrecode-\xread\rtest toW a aZcd 1 2345\foo-

Mais surtout, il existe une méthode bien plus élégante pour programmer §\xread, non récursive, ayant exactement la même syntaxe que \idx\read, mais qui fait intervenir la primitive \idx\afterassignment que nous verrons plus tard (voir page~\pageref{afterassignment}). Le code est donné à titre indicatif :

\showcode|\def\xread{% doit être suivie de "<nombre> to \<macro>"
	\edef\restoreendlinechar{\endlinechar=\the\endlinechar}%¤\idx*\endlinechar\idx*\the¤
	\endlinechar=-1 % neutralise \endlinechar
	\afterassignment\restoreendlinechar% après l'assignation, restaurer \endlinechar¤\idx*\afterassignment¤
	\read% attend <nombre> to \<macro> pour effectuer l'assignation¤\idx*\read¤
}
\catcode`\@12

\openin\rtest =filetest.txt¤\idx*\openin¤
Ligne 1 : \xread\rtest to \foo% lit la première ligne
\meaning\foo.\par% donne ce qui a été lu¤\idx*\meaning¤
Ligne 2 : \xread\rtest to \foo% lit la deuxième ligne
\meaning\foo.\par
Ligne 3 : \xread\rtest to \foo% lit la dernière ligne
\meaning\foo.¤\idx*\meaning¤
\closein\rtest¤\idx*\closein¤|§*\xread[|)]
\end{exercice}

\subsection{Faire une recherche dans un fichier}
Envisageons maintenant un cas pratique et imaginons qu'une liste de fournitures soit contenue dans un fichier «\verb|founitures.txt|» dont le contenu est le suivant :

\immediate\openout\wtest= fournitures.txt
\immediate\write\wtest{Ref,Item,Prix,Fournisseur^^J%
1201a,article 1,25.90,\noexpand\TeX{} marchand ^^J%
4562u,article 2,120,fournisseur 1^^J%
1721d,article 3,57.10,fournisseur 2}%
\immediate\closeout\wtest
\centrecode|Ref,Item,Prix,Fournisseur
1201a,article 1,25.90,\TeX{} marchand
4562u,article 2,120,fournisseur 1
1721d,article 3,57.10,fournisseur 2
<etc>|

On remarque que la première ligne du fichier n'est pas à proprement parler une ligne de données, elle indique le nom des champs qui composent les lignes suivantes.

Supposons que ce fichier soit dans le même répertoire\footnote{Ou qu'un lien symbolique vers ce fichier soit présent dans le répertoire de compilation.} que le fichier maitre et que nous souhaitions chercher dans ce fichier une ligne par sa référence, c'est-à-dire par ce qui est contenu dans le premier champ. Le but est de mettre au point une macro §\searchitem appelée de cette façon

\centrecode-\searchitem<canal>{fournitures.txt}{1721d}\foo-§*\searchitem

\noindent de telle sorte que la ligne où se trouve le premier champ «\verb|1721d|» soit trouvée. La macro purement développable \verb|\foo|\verb|{<champ>}| sera créée où son argument précisera de quel \verb|<champ>| on souhaite obtenir la valeur. Par exemple,

\begin{centrage}\small
	\begin{tabular}{r@{\quad affiche \quad}l}
		\verb|\foo{ref}|&1721d\\
		\verb|\foo{item}|&article 3\\
		\verb|\foo{prix}|&57.10\\
		\verb|\foo{fournisseur}|&fournisseur 2
	\end{tabular}
\end{centrage}

La macro \verb|\foo| est ici prise pour l'exemple, mais naturellement, le choix du nom de cette macro est à la convenance de l'utilisateur.

Fixons-nous trois contraintes supplémentaires :

\begin{itemize}
	\item si le fichier n'existe pas ou si la référence cherchée n'existe pas, la macro \verb|\foo| définie doit être \idx\let-égale à \verb|\gobone|. De cette façon, elle absorbera son argument et ne produira aucun affichage;
	\item si un champ n'existe pas, rien ne doit être affiché. Par exemple, \verb|\foo{truc}| ne doit produire aucun affichage;
	\item lors de la recherche, toute ligne vide doit être ignorée.
\end{itemize}

La première chose à faire va être d'initialiser la macro \verb|\foo| (argument \verb|#4|) sera initialisée à \verb|\gobone|. Ensuite, la première ligne du fichier sera lue, ses champs seront parcourus avec §\doforeach afin de stocker leur nom écrit en lettres minuscules dans une macro \verb|\fieldname<i>| ou \verb|<i>| est le numéro du champ.

Par la suite, nous pourrons commencer à lire les lignes de données : chaque ligne sera envoyée à une macro auxiliaire \verb|\test@field| chargée d'examiner leurs champs. Le premier champ de la ligne en cours sera comparé à celui qui est recherché et si le test est positif, il incombera à la macro \verb|\test@filed| de procéder aux assignations nécessaires des macros

\begin{itemize}
	\item \verb|\foo.<nom du champ 1>|%{\ttfamily\textbackslash\boxtoken{foo.\codeelement{nom du champ 1}}}
	\item \verb|\foo.<nom du champ 2>|{\ttfamily\textbackslash\boxtoken{foo.\codeelement{nom du champ 2}}}
	\item etc
\end{itemize}

\noindent chacune \verb|\let|-égale à \verb|\fieldname<i>|.

Enfin, la macro purement développable \verb|\foo|, prenant comme argument un \verb|<champ>|, sera créée. Elle testera avec \tidx{ifcsname} si la macro \verb|\foo.<champ>| existe, auquel cas elle formera cette macro via \idx\csname.

\showcode|\def\macroname{% se développe en le nom de la macro qui suit sans ¤§*\macroname¤
               % le caractère d'échappement
	\ifnum\escapechar>-1 % si le caractère d'échappement est positif¤\idx*\escapechar¤
		\ifnum\escapechar<256 % et inférieur à 256, développer les 2 "\fi"
			\expandafter\expandafter\expandafter\expandafter% et le "\string", puis
			\expandafter\expandafter\expandafter\gobone% manger le "\" avec \gobone
		\fi
	\fi
	\string% doit être suivi d'une macro¤\idx*\string¤
}
\catcode`\@11
\newcount\field@cnt
\def\searchitem#1#2#3#4{% #1= canal  #2=nom fichier #3=référence  #4=macro à définir¤§*\searchitem¤
	\let#4\gobone% pour l'instant, #4=\gobone
	\openin#1=#2\relax¤\idx*\openin¤
	\unless\ifeof#1% si le fichier existe¤\tidx*{unless}\tidx*{ifeof}¤
		\lowercase{\def\sought@firstfield{#3}}% stocke le 1er champ à chercher¤\idx*\lowercase¤
		\edef\macro@name{\macroname#4}% nom de la macro sans "\"¤§*\macroname¤
		\xread#1 to \current@line% lire la première ligne¤§*\xread¤
		\field@cnt=0 % initialiser le compteur de champs
		% ################ sauvegarde du nom des champs ################
		\expsecond{\doforeach\current@field\in}\current@line% pour chaque champ¤§*\expsecond¤
			{\advance\field@cnt1 % incrémenter le compteur de champs¤\idx*\advance¤
			\lowercase\expandafter{% e texte de remplacement de \current@field en minuscule¤\idx*\lowercase¤
				\expandafter\def\expandafter\current@field\expandafter{\current@field}%
			}%
			% sauvegarder chaque champ de la 1re ligne (qui sont les intitulés) dans une macro
			\letname{fieldname\number\field@cnt}=\current@field¤§*\letname¤
			}%
		\edef\field@num{\number\field@cnt}% nombre de champs
		% ################ lecture des lignes de données ################
		\loop% tant que...¤\idx*\loop¤
			\unless\ifeof#1\relax% ...la fin du fichier n'est pas atteinte¤\tidx*{unless}\tidx*{ifeof}¤
				\xread#1 to \current@line% lire une ligne¤§*\xread¤
				\unless\ifx\current@line\empty% si elle n'est pas vide¤\idx*\empty¤
					% examniner les champs qu'elle contient (aller à \test@field)
					\expsecond{\expandafter\test@field\current@line\@nil}\macro@name%¤\defline\aaa §*\expsecond¤
				\fi
		\repeat¤\idx*\repeat¤
	\fi
	\closein#1\relax¤\idx*\closein¤
}

\def\test@field#1,#2\@nil#3{% #1=champ no 1 #2=autres champs #3=nom de la macro sans "\"
	\def\current@firstfield{#1}% stocke le premier champ de la ligne en cours
	\ifx\current@firstfield\sought@firstfield% s'il est égal à celui cherché
		\defname{#3.\csname fieldname1\endcsname}{#1}% définir la macros \<#3."champ 1">¤§*\defname¤
		\field@cnt=1 % initialiser le compteur de champ
		\doforeach\current@field\in{#2}% puis, pour i>2, définir les macros \<#3."champ i">¤§*\doforeach¤
			{\advance\field@cnt1 % incrémenter le compteur de champ
			\letname{#3.\csname fieldname\number\field@cnt\endcsname}=\current@field¤§*\letname¤
			}%
		\defname{#3}##1{% et définir la macro \<#3>¤§*\defname¤
			\ifcsname#3.##1\endcsname% si la macro \<#3."argument"> existe déjà¤\tidx*{ifcsname}¤
				\csname#3.##1\expandafter\endcsname% l'exécuter après avoir mangé le \fi
			\fi
		}%
	\fi
}
\catcode`\@12

\searchitem\rtest{fournitures.txt}{4562u}\monarticle¤§*\searchitem¤
réf = \monarticle{ref},
dénomination = \monarticle{item},
prix = \monarticle{prix},
fournisseur = \monarticle{fournisseur},
champ non existant = \monarticle{foobar}.

\searchitem\rtest{fournitures.txt}{truc}\essai% référence "truc" n'existe pas¤§*\searchitem¤
réf = \essai{ref},
dénomination = \essai{item},
prix = \essai{prix},
fournisseur = \essai{fournisseur}.|

La macro §\macroname, donnée tout au début, doit être suivie d'une \verb|\<macro>| et se développe en le nom de cette \verb|\<macro>| sans l'éventuel caractère d'échappement.

\begin{exercice}
Programmer une amélioration de la macro §\searchitem pour que la recherche puisse se faire sur n'importe quel champ. Les champs seront spécifiés par leur numéro et non plus par leur nom. La syntaxe sera :

\centrecode-\searchitem<canal>{<nom fichier>}{<numéro champ>=<valeur>}\<macro>-

La modification de la syntaxe concerne le 3\ieme{} argument et l'introduction du \verb|<numéro champ>| que l'on souhaite chercher. Si ce \verb|<numéro champ>| et le signe \verb|=| sont absent, le \verb|<numéro champ>| sera pris égal à 1.

On supposera que le fichier «\verb|basecourse.txt|» recueille les données des participants à une course à pied et contient :
\immediate\openout\wtest= basecourse.txt
\exactwrite\wtest|Nom,Prénom,Classement,Naissance,Licencié,Temps
Demay,Pierre,237,27/8/1986,oui,2h37
Leblanc,Nicolas,187,4/9/1978,non,2h05
Valet,Bruno,78,25/11/1989,oui,1h47
Hachel,André,283,2/3/1972,non,2h42
Jalabert,Jean,165,19/1/1982,Oui,2h01|%
\immediate\closeout\wtest

\centrecode-Nom,Prénom,Classement,Naissance,Licencié,Temps
Demay,Pierre,237,27/8/1986,oui,2h37
Leblanc,Nicolas,187,4/9/1978,non,2h05
Valet,Bruno,78,25/11/1989,oui,1h47
Hachel,André,283,2/3/1972,non,2h42
Jalabert,Jean,165,19/1/1982,Oui,2h01-

Si l'on écrit

\centrecode-\searchitem\rtest{basecourse.txt}{3=283}\coureur-

alors, §\searchitem doit chercher la ligne où le 3\ieme{} champ vaut 283. Par la suite, la macro \verb|\coureur| doit admettre un argument \emph{numérique} \verb|<i>| et \verb|\coureur{<i>}| doit renvoyer la valeur du champ \no\verb|<i>|. Par exemple, \verb|\coureur{2}| doit renvoyer «André».
\solution
Les modifications à apporter ne sont pas très nombreuses.

Tout d'abord, il faut lire la première ligne et l'ignorer : elle n'est d'aucune utilité. Ensuite, il faut traiter correctement l'argument \verb|#3| selon qu'il contient le signe \verb|=| ou pas. À l'issue de ce traitement, on a stocké le numéro du champ et sa valeur dans 2 macros pour les utiliser plus tard.

Dans le code précédent, la boucle \idx\loop était parcourue jusqu'à ce que \tidx{ifeof} soit vrai. Une petite amélioration consiste à permettre une sortie prématurée si la ligne est trouvée. Pour cela, un booléen créé avec \idx\newif sera initialisé à vrai et mis à faux s'il faut sortir de la boucle \idx\loop :

\begin{itemize}
	\item soit lorsque le test \tidx{ifeof} est vrai;
	\item soit parce que la ligne a été trouvée.
\end{itemize}

\showcode/\def\macroname{% se développe en le nom de la macro qui suit sans ¤§*\macroname¤
               % le caractère d'échappement
	\ifnum\escapechar>-1 % si le caractère d'échappement est positif¤\idx*\escapechar¤
		\ifnum\escapechar<256 % et inférieur à 256, développer les 2 "\fi"
			\expandafter\expandafter\expandafter\expandafter% et le "\string", puis
			\expandafter\expandafter\expandafter\gobone% manger le "\" avec \gobone
		\fi
	\fi
	\string% doit être suivi d'une macro¤\idx*\string¤
}
\catcode`\@11
\newcount\field@cnt
\newif\ifsearch@repeat¤\idx*\newif¤
\def\assign@arg#1=#2\@nil{%
	\def\sought@fieldnumber{#1}% no du champ à chercher
	\def\sought@fielvalue{#2}% et sa valeur
}
\def\searchitem#1#2#3#4{% #1= canal  #2=nom fichier #3=champ cherché  #4=macro à définir¤§*\searchitem¤
	\let#4\gobone% pour l'instant, #4=\gobone
	\openin#1=#2\relax%¤\idx*\openin¤
	\unless\ifeof#1% si le fichier existe¤\tidx*{unless}\tidx*{ifeof}¤
		\edef\macro@name{\macroname#4}% nom de la macro sans "\"¤§*\macroname¤
		\xread#1 to \current@line% lire et ignorer la première ligne¤§*\xread¤
		\ifin{#3}{=}% si #3 contient =¤§*\ifin¤
			{\assign@arg#3\@nil}% trouver le no de champ et sa valeur
			{\def\sought@fieldnumber{1}% sinon, no du champ = 1
			\def\sought@fielvalue{#3}% et sa valeur = #3
			}%
		% ################ lecture des lignes de données ################
		\search@repeattrue% poursuite de la boucle loop : vraie
		\loop% tant que...¤\idx*\loop¤
			\ifeof#1\relax% ...la fin du fichier n'est pas atteinte¤\tidx*{unless}\tidx*{ifeof}¤
				\search@repeatfalse% sortir de la boucle loop
			\else
				\xread#1 to \current@line% lire une ligne¤§*\xread¤
				\unless\ifx\current@line\empty% si elle n'est pas vide¤\idx*\empty¤
					% examniner les champs qu'elle contient (aller à \test@field)
					\expsecond{\expandafter\test@field\current@line\@nil}\macro@name%¤\defline\aaa §*\expsecond¤
				\fi
			\fi
			\ifsearch@repeat% ne poursuivre que si le booléen en vrai
		\repeat¤\idx*\repeat¤
	\fi
	\closein#1\relax¤\idx*\closein¤
}

\def\test@field#1\@nil#2{% #1=champs #2=nom de la macro sans "\"
	\field@cnt=0 % initialiser le compteur de champ
	\doforeach\current@field\in{#1}% parcourir les champs de la ligne en cours¤§*\doforeach¤
		{\advance\field@cnt1 % incrémenter le compteur de champ
		\ifnum\field@cnt=\sought@fieldnumber\relax% si c'est le bon numéro de champ
			\ifx\current@field\sought@fielvalue% et si le champ correspond à celui cherché
				\search@repeatfalse% sortir de la boucle loop
				\doforeachexit% sortir de la boucle \doforeach en cours¤§*\doforeachexit¤
			\fi
		\fi
		}%
	\unless\ifsearch@repeat% si la ligne a été trouvée
		\field@cnt=0 % initialiser le compteur de champ
		\doforeach\current@field\in{#1}% parcourir à nouveau les champs de la ligne¤§*\doforeach¤
				{\advance\field@cnt1 % incrémenter le compteur de champ
				\letname{#2.\number\field@cnt}=\current@field% faire l'assignation¤§*\letname¤
				}%
		\defname{#2}##1{% et définir la macro \<#2>¤§*\defname¤
			\ifcsname#2.##1\endcsname% si la macro \<#2."argument"> existe déjà¤\tidx*{ifcsname}¤
				\csname#2.##1\expandafter\endcsname% l'exécuter après avoir mangé le \fi
			\fi
		}%
	\fi
}
\catcode`\@12
a) \searchitem\rtest{basecourse.txt}{3=283}\foo
   "\foo1", "\foo2", "\foo3", "\foo4", "\foo5", "\foo6", "\foo7"

b) \searchitem\rtest{basecourse.txt}{Valet}\bar
   "\bar1", "\bar2", "\bar3", "\bar4", "\bar5", "\bar6", "\bar{abcd}"/
\end{exercice}

\subsection{Afficher le contenu exact d'un fichier}
Nous allons maintenant programmer une macro §\showfilecontent[|(] de syntaxe

\centrecode-\showfilecontent<canal>{<nom du fichier>}-

\noindent qui affiche le contenu du fichier passé en argument, en police à chasse fixe. Le but est d'imiter pour les fichiers la primitive \idx\meaning qui donne le texte de remplacement d'une macro.

Il va falloir agir sur les codes de catégorie avec les macros \idx\do et \idx\dospecials de plain-\TeX{} pour rendre tous les tokens inoffensifs, sauf l'espace qui sera rendu actif avec \idx\obeyspaces.

Le fichier «\verb|readtext.txt|» utilisé dans l'exemple contient 3 lignes :

\centrecode-Programmer en \TeX{} est   facile

et utile-

\immediate\openout\wtest=readtest.txt
\exactwrite\wtest|Programmer en \TeX{} est   facile

et utile|%
\immediate\closeout\wtest

\showcode|\def\showfilecontent#1#2{% #1=canal de lecture #2=nom de fichier¤§*\showfilecontent¤
	\begingroup
		\tt% sélectionner la fonte à chasse fixe¤\idx*\tt¤
		\openin#1=#2\relax¤\idx*\openin¤
		\ifeof#1% si la fin du fichier est déjà atteinte, il n'existe pas et¤\tidx*{ifeof}¤
			Le fichier n'existe pas% afficher le message
		\else% le fichier existe
			\def\do##1{\catcode`##1=12 }%¤\idx*\do¤
			\dospecials% neutraliser tous les tokens spéciaux¤\idx*\dospecials¤
			\obeyspaces% rendre l'espace actif¤\idx*\obeyspaces\defline\bbb¤
			\loop¤\idx*\loop¤
				\xread#1 to \currline% lire une ligne¤§*\xread¤
				\unless\ifeof#1% si la fin du fichier n'est pas atteinte¤\tidx*{unless}\tidx*{ifeof}¤
				\leavevmode\par% aller à la ligne¤\idx*\leavevmode\defline\aaa¤
				\currline% afficher la ligne lue
			\repeat% recommencer¤\idx*\repeat¤
		\fi
		\closein#1\relax¤\idx*\closein¤
	\endgroup
}

Contenu du fichier : "\showfilecontent\rtest{readtest.txt}", affiché tel quel|

Il est intéressant de noter qu'un \idx\obeyspaces est écrit à la ligne \no\bbb{} car

\centrecode-\letactive\ =\space-§*\letactive\idx*\space{}

\noindent ne fonctionnerait pas puisque que §\letactive, tout comme §\defactive, \emph{nécessite} que le caractère «\verb|~|» soit actif. Or, ce n'est plus le cas ici puisque \idx\dospecials l'a rendu de catcode 12.

En revanche, placer \verb|\letactive\ =\space|§*\letactive\idx*\space{} avant le \idx\dospecials aurait fonctionné.

\begin{exercice}
Expliquer pourquoi le guillemet initial ne se situe pas juste avant le mot «\verb|Début|» et proposer une solution pour que cela soit le cas.
\solution
Chaque ligne affichée, contenue dans la macro \verb|\currline|, est précédée de \idx\leavevmode\idx\par (ligne \no\aaa), y compris pour la première ligne lue. De par la structure de la macro §\showfilecontent, un \idx\par est donc toujours inséré entre le guillemet initial et le premier caractère du fichier.

Une solution originale est de garder «\verb|\leavevmode\par|» sauf que l'on va mettre une macro «magique» §\magicpar en lieu et place de \idx\par. Cette macro aux vertus spéciales doit n'avoir aucun effet pour l'affichage la première fois et exécuter un \idx\par les autres fois. Pour répondre à ces contraintes, §\magicpar doit se modifier elle-même en \idx\par la première fois qu'elle sera exécutée. Voici comment la définir :

\centrecode-\def\magicpar{\let\magicpar=\par}-

Avec une telle définition, §\magicpar ne va rien afficher la première fois qu'elle sera exécutée, mais va silencieusement se redéfinir pour devenir égale à \idx\par. Nous avons bien créé une macro locale au groupe semi-simple, qui est neutre pour l'affichage la première fois et équivalente à \idx\par ensuite.

\showcode|\def\showfilecontent#1#2{% #1=canal de lecture #2=nom de fichier¤§*\showfilecontent¤
	\begingroup
		\tt% sélectionner la fonte à chasse fixe¤\idx*\tt¤
		\openin#1=#2\relax¤\idx*\openin¤
		\ifeof#1% si la fin du fichier est déjà atteinte, il n'existe pas et
			Le fichier n'existe pas% afficher le message
		\else% le fichier existe
			\def\do##1{\catcode`##1=12 }%¤\idx*\do¤
			\dospecials% neutraliser tous les tokens spéciaux¤\idx*\dospecials¤
			\obeyspaces% rendre l'espace actif¤\idx*\obeyspaces¤
			\def\magicpar{\let\magicpar=\par}%¤§*\magicpar¤
			\loop¤\idx*\loop¤
				\xread#1 to \currline% lire une ligne¤§*\xread¤
				\unless\ifeof#1% si la fin du fichier n'est pas atteinte¤\tidx*{unless}\tidx*{ifeof}¤
				\leavevmode\magicpar% former le paragraphe (sauf à la 1er itération)¤\idx*\leavevmode¤
				\currline% afficher la ligne
			\repeat% recommencer¤\idx*\repeat¤
		\fi
		\closein#1\relax¤\idx*\closein¤
	\endgroup
}

Contenu du fichier : "\showfilecontent\rtest{readtest.txt}", affiché tel quel|
\end{exercice}§*\showfilecontent[|)]\idx*[|)]{fichier!lecture}

\section{Écrire dans un fichier}\idx*[|(]{fichier!écriture}
\subsection{La primitive \texttt{\textbackslash write}}\idx*[|(]\write
Il est facile de deviner par symétrie que si \TeX{} dispose de 16 canaux pour lire un fichier, il en dispose aussi de 16 pour écrire dans un fichier. Et le pendant de la macro \idx\newread est évidemment \idx\newwrite, qui en partage la syntaxe et qui alloue globalement un canal d'écriture libre.

\begin{regle}
\relax\TeX{} dispose de 15 canaux d'écriture portant les numéros de 0 à 15.

On demande l'allocation d'un canal d'écriture par\idx*\newwrite

\centrecode-\newwrite\<macro>-

et ce faisant, la \verb|\<macro>| devient équivalente à un \verb|<nombre>|, qui est un numéro de canal libre. Un \verb|<canal>| est donc un \verb|<nombre>| explicitement écrit ou une macro définie avec \idx\newwrite.
\medbreak

Avant d'écrire dans un fichier, on doit d'abord lier un \verb|<canal>| à un fichier avec\idx*\openout :

\centrecode-\openout<canal>= <nom du fichier>-

\noindent et lorsque les opérations d'écriture sont terminées, on désolidarise le \verb|<canal>| du fichier par \idx*\closeout

\centrecode-\closeout<canal>= <nom du fichier>-

\noindent Une ligne vide est insérée en fin de fichier.

Pour écrire une ligne dans le fichier, on écrit :

\centrecode-\write<canal>{<texte>}-

\noindent où le \verb|<texte>| est un code dans lequel les accolades sont équilibrées. L'écriture dans le fichier n'a pas lieu lorsque la commande \idx\write est rencontrée, mais lorsque la page courante est composée. Le \verb|<texte>| est stocké dans la mémoire de \TeX{} et est développé au maximum lorsque \TeX{} écrit dans le fichier. Si l'utilisateur souhaite bloquer le développement, il lui appartient de le bloquer à l'aide des méthodes vues à la page~\pageref{bloquer.developpement.maximum}.
\grandsaut

Les opérations liées à l'écriture dans un fichier (\idx\openout, \idx\write et \idx\closeout) ont la particularité d'avoir lieu lorsque la page est composée, c'est-à-dire plus tard dans le temps que lorsque les instructions sont rencontrées. Ce décalage temporel est bien utile lorsqu'on souhaite écrire un \idx{numéro de page} puisque l'on s'assure que le bon numéro de page sera écrit, mais il est indésirable pour écrire des données non sensibles au positionnement dans le document. Pour s'affranchir de cette désynchronisation temporelle, il faut faire précéder \idx\openout, \idx\write et \idx\closeout de la primitive « \idx\immediate » qui force les opérations d'écriture à être faites immédiatement lorsqu'elles sont rencontrées.
\end{regle}

Dans tout le reste du chapitre, nous utiliserons le canal d'écriture \verb|\wtest| que nous allons allouer avec \idx\newwrite\verb|\wtest|.

Voici deux tentatives successives d'écriture dans un même fichier :

\showcode|¤\string\newwrite\string\wtest¤% sera le canal d'écriture dans tout ce chapitre¤\idx*\newwrite¤
\immediate\openout\wtest=writetest.txt % lie \wtest au fichier¤\idx*\immediate\idx*\openout¤
\immediate\write\wtest{Programmer en \noexpand\TeX{} est   facile.}% écrit une ligne¤\idx*\write\idx*\noexpand¤
\immediate\write\wtest{Et utile...}% puis une autre
\immediate\closeout\wtest% défait la liaison¤\idx*\closeout¤
a) Contenu du fichier :\par
"\showfilecontent\rtest{writetest.txt}"% affiche le contenu du fichier¤§*\showfilecontent¤
\medbreak¤\idx*\medbreak¤
% 2e tentative :¤\defline\aaa¤
b) Contenu du fichier :\par
\immediate\openout\wtest=writetest.txt % lie \wtest au fichier
\immediate\write\wtest{Essai d'écriture}% écrit une ligne¤\idx*\write¤
\immediate\closeout\wtest% défait la liaison¤\idx*\immediate¤
"\showfilecontent\rtest{writetest.txt}"% affiche le contenu du fichier¤§*\showfilecontent¤|

Remarquons à partir de la ligne \no\aaa, que si on lie un canal à un fichier déjà existant et que l'on écrit à nouveau dans ce fichier, le contenu précédent est effacé, c'est-à-dire que l'écriture recommence au début du fichier.

Remarquons également que l'argument de \idx\write est lu par \TeX{} avant d'être détokénizé et écrit dans le fichier. La perte d'informations lorsque \TeX{} lit du code source a donc lieu. Ici en particulier, les espaces consécutifs dans «\verb*|est   facile|» ont été lus comme un seul espace et écrits comme tel dans le fichier.

Enfin, il faut noter que \idx\write, lorsqu'il détokénize le \verb|<texte>|, rajoute un espace après les séquences de contrôle.

\subsection{Programmer des variantes de \texttt{\textbackslash write}}
\subsubsection{La macro \texttt{\char`\\noexpwrite}}§*\noexpwrite
Si la primitive \idx\write développe au maximum ce qu'elle va écrire, il est logique de construire un équivalent qui lui, ne procèdera à aucun développement. Parmi des méthodes à notre disposition pour bloquer le développement, la plus pratique est de recourir à \idx\unexpanded :

\showcode/\def\noexpwrite#1#2{% #1=numéro de canal  #2=texte à écrire¤§*\noexpwrite¤
	\write#1{\unexpanded{#2}}%¤\idx*\write\idx*\unexpanded¤
}
\immediate\openout\wtest=writetest.txt ¤\idx*\openout¤
\immediate\noexpwrite\wtest{Programmer en \TeX{} est   facile.}%¤\idx*\immediate¤
\immediate\noexpwrite\wtest{Et utile...}%¤§*\noexpwrite¤
\immediate\closeout\wtest¤\idx*\closeout¤
Contenu du fichier :\par
\showfilecontent\rtest{writetest.txt}% affiche le contenu du fichier¤§*\showfilecontent¤/

Ici encore, comme l'argument \verb|#2| a été lu par la macro §\noexpwrite, les mêmes pertes d'information que précédemment ont eu lieu. Le seul moyen d'écrire dans le fichier ce qu'il y a \emph{exactement} dans le code source est de procéder comme avec la macro §\litterate (voir page~\pageref{litterate}).

\subsubsection{La macro \texttt{\char`\\exactwrite}}\label{exactwrite}§*\exactwrite[|(]
Nous allons créer l'équivalent de la macro §\litterate pour l'écriture dans un fichier, c'est-à-dire une macro qui écrit dans un fichier \emph{tous} les caractères qu'on lui donne à lire. Appelons cette macro §\exactwrite et par commodité, sa syntaxe va ressembler à celle de §\litterate. La primitive \idx\immediate sera appelée et donc l'écriture sera synchrone. On suppose qu'un \verb|<canal>| a déjà été lié au fichier dans lequel on veut écrire. La syntaxe sera :

\centrecode-\exactwrite{<canal><car><texte><car>-

\noindent Ici, \verb|<car>| sera un caractère choisi par l'utilisateur qui servira de délimiteur au \verb|<texte>| que l'on veut écrire dans le fichier, avec la limitation classique que \verb|<car>| doit être choisi de telle sorte qu'il ne figure pas dans le \verb|<texte>|.

On va procéder comme avec §\litterate en rendant inoffensifs des tokens en mettant leurs catcodes à 12, sauf qu'ici, cela va concerner \emph{tous} les octets, de 0 à 255. C'est certes un remède de cheval, mais de cette façon, tous les caractères peuvent être écrits sur un fichier et ce quels que soient l'\idx{encodage} du fichier source et le régime de catcode en cours.

La méthode va être la suivante :

\begin{algo}
	\item lire le \verb|<canal>|;
	\item ouvrir un groupe, mettre le catcode de tous les octets à 12;
	\item lire le \verb|<car>| (qui sera de catcode 12 à cause du point précédent) ;
	\item isoler le \verb|<texte>| qui se trouve jusqu'au prochain \verb|<car>|;
	\item si ce \verb|<texte>| contient le retour charriot «\verb|^^M|\verbidx*[ (retour charriot)]{^^M}» (de catcode 12) :
	\begin{algo}
		\item écrire dans le fichier le texte se trouvant avant \verb|^^M|;
		\item retourner en 5) avec en prenant \verb|<texte>| égal à ce qu'il y a près \verb|^^M|;
	\end{algo}
	\item sinon écrire le \verb|<texte>| dans le fichier et fermer le groupe.
\end{algo}

Pour forcer les catcodes de tous les octets à 12, une simple boucle §\for suffit :

\centrecode-\for\xx=0 to 255 \do{\catcode\xx=12 }-

\noindent Ensuite, comme à partir du point \no3, tout ce qui est lu est constitué de caractères de catcode 12, il va falloir définir un retour charriot de catcode 12\idx*{catcode!12 (autre)} qui nous servira de délimiteur d'argument. On peut s'y prendre ainsi :

\centrecode-{\catcode`\^^M=12 \gdef\EOL@char{^^M}}-\idx*\gdef

Dans les grandes lignes, la tâches vont se répartir de la façon suivante. Les points \nos1 et 2 sont dévolus à la macro chapeau §\exactwrite. Une macro auxiliaire \verb|\exactwrite@i| va lire le \verb|<car>|, forcément de catcode 12, qui sera son unique argument. Une fois qu'elle s'est emparé de ce \verb|<car>|, elle peut définir une sous-macro \verb|\exactwrite@ii| dont l'argument délimité par ce \verb|<car>| sera le \verb|<texte>| qu'elle transmettra à la macro récursive \verb|\exactwrite@iii| qui se chargera des points \no5 à 6.

\showcode/\catcode`\@11
\def\exactwrite#1{% #1=numéro de canal¤§*\showfilecontent¤
	\begingroup
		\def\canal@write{#1}% sauvegarde le numéro de canal
		\for\xx=0 to 255\do{\catcode\xx=12 }% donne à tous les octets le catcode 12¤§*\for\idx*{catcode!12\space(autre)}¤
		\exactwrite@i% aller lire le <car>
}

\def\exactwrite@i#1{% #1 est le <car> de catcode 12
	\def\exactwrite@ii##1#1{% ##1 est le <texte> à envoyer vers le fichier
		\exactwrite@iii##1\@nil% envoyer <texte> à \exactwrite@iii
	}%
	\exactwrite@ii% va lire tout ce qui se trouve jusqu'au prochain <car>
}

{\catcode`\^^M 12 \gdef\EOL@char{^^M}}% définit le caractère <EOL> de catcode 12¤\verbidx*[ (retour charriot)]{^^M}\idx*\gdef¤

\def\exactwrite@iii#1\@nil{% #1 = <texte> à écrire dans le fichier
	\expsecond{\ifin{#1}}\EOL@char% si #1 contient "retour charriot"¤§*\expsecond§*\ifin¤
		{\write@line#1\@nil% écrire la première ligne de #1
		}
		{\immediate\write\canal@write{#1}% sinon : dernière ligne atteinte, l'écrire¤\idx*\immediate\idx*\write¤
		\endgroup% puis sortir du groupe
		}%
}

% les \expandafter provoquent le 1-développement de \EOL@char :
\expandafter\def\expandafter\write@line\expandafter#\expandafter1\EOL@char#2\@nil{%
	\immediate\write\canal@write{#1}% écrit la ligne (ce qui se trouve avant ^^M)¤\idx*\immediate\idx*\write¤
	\exactwrite@iii#2\@nil% recommencer avec ce qui se trouve après "^^M"
}
\catcode`\@12

\immediate\openout\wtest=writetest.txt % lie le canal \wtest au fichier¤\idx*\immediate\idx*\openout¤
\exactwrite\wtest|Programmer en \TeX{} est   facile !

Et très utile.|
\immediate\closeout\wtest% et fermer le fichier

Le contenu du fichier "writetest.txt" est :\par
"\showfilecontent\rtest{writetest.txt}"¤§*\showfilecontent¤/\idx*[|)]\write

Plus précisément, voici comment un éditeur de fichiers\footnote{Programme dont la principale fonctionnalité est de lire les octets d'un fichier un par un, de les afficher ainsi que les caractères ASCII correspondants s'ils sont affichables.} voit le fichier généré :

\begin{centrage}
	\ttfamily\footnotesize
	\setbox0\hbox{0}
	\edef~{\hbox to\the\wd0{\hss\noexpand\small\noexpand\textbullet\hss}}
	\catcode`\:12 \catcode`\!12
	\obeyspaces
	\catcode`\/0
	\catcode`\{12 \catcode`\}12
	\catcode`\[1 \catcode`\]2
	\catcode`\\12
	/tabular[r|l|l]%
		0000&50 72 6F 67  72 61 6D 6D  65 72 20 65  6E 20 5C 54&Programmer en \T/\%
		0010&65 58 7B 7D  20 65 73 74  20 20 20 66  61 63 69 6C&eX{} est   facil/\%
		0020&65 20 21 0A  0A 45 74 20  74 72 E8 73  20 75 74 69&e !~~Et très uti/\%
		0030&6C 65 2E 0A                                       &le.~%
	/endtabular%
/end[centrage]%

L'affichage se divise en trois parties, à gauche l'«offset» (en hexadécimal), c'est-à-dire le numéro d'ordre du premier \idx{octet} de la ligne (le premier octet du fichier portant le numéro 0), au centre les octets contenus dans le fichier en notation hexadécimale et à droite les caractères correspondant aux octets (dans un codage sur un octet, le plus souvent \latin). Les caractères non affichables sont représentés par « {\small\textbullet} ». Constatons en premier lieu que le caractère «è» est codé sur \emph{un seul} \idx{octet} (qui est \Hex{E8}) puisque l'\idx{encodage} utilisé dans le code source de ce livre est \latin\footnote{Si l'encodage avait été \utf, le caractère «è» aurait été codé sur deux octets : \Hex{C3} \Hex{A8}}. Remarquons aussi que les seuls caractères non affichables portent le code de caractère \Hex{0A} qui est 13 en décimal; ce sont donc les retours charriot. Il est normal d'avoir un retour charriot en fin de fichier, car comme nous l'avons vu, \TeX{} insère une ligne vide en fin de fichier.§*\exactwrite[|)]

\subsection{Utilisation pratique}
Mettons à profit ce que nous savons pour écrire une macro §\exo[|(], utile pour rédiger des exercices et afficher leur barème. Supposons que «\verb|\exo{3.5pt}|» soit exécutée. Elle devra afficher le texte suivant :

\medbreak
\noindent\vrule height1ex width1ex depth0pt\kern1ex\textbf{Exercice 3}\leaders\hbox to5pt{\hss.\hss}\hfill3.5pt/15
\medbreak

\noindent où «15» est le total des points de toutes les macros §\exo du document.

Remarquons que la macro \verb|\exo| a été appelée 2 fois auparavant puisque cet appel génère le texte de l'exercice \no3.

La principale difficulté est que le total n'est pas connu lorsque la macro \verb|\exo| est exécutée puisque d'éventuels autres appels de cette macro qui sont à venir dans le code. C'est donc un cas où il va falloir se servir d'un fichier auxiliaire pour transmettre ce total entre deux compilations avec la contrepartie que lors d'une compilation :
\begin{itemize}
	\item le fichier n'existe pas, ce qui signifierait qu'il s'agit de la première compilation du document ou que le fichier auxiliaire a été effacé. Dans ce cas, il faudra afficher un total qui représente cette situation particulière, par exemple «\#\#»;
	\item le total est faux parce que depuis la dernière compilation, l'auteur du document a modifié le barème d'un ou plusieurs exercices ou a changé le nombre d'exercices.
\end{itemize}

\noindent Dans ces cas, il faudra lancer \emph{deux} compilations successives pour obtenir le total correct.
\grandsaut

Avant tout, appelons \verb|\total@points| la macro dont le texte de remplacement sera soit «\verb|##|», soit le total des points. Il reste à prendre une décision; comment pouvons-nous stocker dans un fichier le total des points au fur et à mesure que le document est compilé ? Nous pouvons procéder en 3 temps :

\begin{enumerate}
	\item au début du document, appeler une macro \verb|\initexo| qui va tester si le fichier auxiliaire existe.
	\begin{itemize}
		\item dans l'affirmative, elle va exécuter le code qu'il contient avec \idx\input. Ce code définira la macro \verb|\total@points| avec le barème de la précédente compilation;
		\item sinon, elle va placer dans le texte de remplacement de \verb|\total@points| le code «\verb|\char`\#\char`\#|» qui affiche «\char`\#\char`\#».
	\end{itemize}

	\item elle va ouvrir ce fichier en écriture y insérer les caractères «\verb|\exocalctotal|». Puis à chaque fois que la macro \verb|\exo{<barème>}| est rencontrée, ajouter les caractères «\verb|+<barème>|» au fichier;
	\item à la fin du document, la macro \verb|\stopexo| écrira «\verb|\relax\endtotal|» dans le fichier et le fermera.
\end{enumerate}

Admettons par exemple que «\verb|\exo{5pt}|», «\verb|\exo{3.5pt}|» et «\verb|\exo{3pt}|» sont rencontrées dans le document. Alors, à la fin de la compilation (et au début de la suivante), le fichier auxiliaire contiendra :

\centrecode-\exocalctotal+5pt+3.5pt+3pt\relax\endtotal-

Il nous reste à dire un mot sur la macro \verb|\exocalctotal|. Elle sera définie pour que son argument soit délimité par \verb|\endtotal| et son texte de remplacement placera dans la macro \verb|\total@points| la somme de tous les points. Pour ce faire, \idx\dimexpr et §\dimtodec seront employées, avec les éventuels inconvénients concernant les erreurs d'arrondis qui peuvent survenir (voir page~\pageref{arrondis.sur.dimensions}) :

\centrecode-\def\exocalctotal#1\endtotal{\edef\total@points{\dimtodec\dimexpr#1}}-

Le fichier contenant les points sera nommé comme le fichier maitre (nom qui est le développement de \idx\jobname), mais avec l'extension «\verb|.pts|»

\catcode`\W12
\showcode W\catcode`\@11
\newcount\exo@number% compteur pour le numéro d'exercice¤\idx*\newcount¤

\def\exocalctotal#1\endtotal{\edef\total@points{\dimtodec\dimexpr#1}}¤§*\dimtodec¤

\def\initexo#1{%
	\def\exo@canal{#1}% sauvegarde le canal d'écriture
	\exo@number=0 % initialiser le compteur d'exo
	\iffileexists\exo@canal{\jobname.pts}% si le fichier .pts existe¤§*\iffileexists\idx*\jobname¤
		{\input \jobname.pts }% le lire et exécuter son contenu¤\idx*\input\idx*\jobname¤
		{\def\total@points{\char`\#\char`\#}}% sinon, définir un total alternatif¤\idx*\char¤
	\immediate\openout\exo@canal=\jobname.pts % ouvrir le fichier .pts¤\idx*\immediate\idx*\jobname\idx*\openout¤
	\immediate\write\exo@canal{\noexpand\exocalctotal}% et commencer à y écrire dedans¤\idx*\noexpand\idx*\write¤
}

\def\exo#1{% définti la macro qui affiche l'exercice
	\bigbreak% sauter une grande espace verticale
	\immediate\write\exo@canal{+#1}% écrire "+#1" dans le fichier .pts¤\idx*\immediate\idx*\write¤
	\advance\exo@number by 1 % incrémenter le numéro de l'exercice¤\idx*\advance¤
	\noindent\vrule height1ex width1ex depth0pt % trace le carré¤\idx*\noindent\idx*\vrule¤
	\kern1ex% insérer une espace horizontale¤\idx*\kern¤
	{\bf Exercice \number\exo@number}% afficher "Exercice <nombre>"¤\idx*\bf\idx*\number¤
	\leaders\hbox to.5em{\hss.\hss}\hfill% afficher les pointillés¤\idx*\leaders\idx*\hbox\idx*\hss¤
	#1/\total@points%  puis #1/<total>
	\smallbreak% composer la ligne précédente et sauter une espace verticale¤\idx*\smallbreak¤
}

\def\stopexo{%
	\immediate\write\exo@canal{\relax\noexpand\endtotal}%¤\idx*\immediate\idx*\write\idx*\noexpand¤
	\immediate\closeout\exo@canal¤\idx*\closeout¤
}
\catcode`\@12
\initexo\wtest

\hfill{\bf Interrogation écrite. Sujet : \TeX{}}\hfill\null¤\idx*\hfill\idx*\null¤
\par
\leavevmode\hfill\vrule height.4pt width 2cm depth0pt\hfill\null¤\idx*\leavevmode\idx*\vrule¤
\exo{3pt}
Élaborer un test \litterate/\ifonebyte{<texte>}{<vrai>}{<faux>}/ qui teste, pour une¤§*\litterate¤
compilation avec un moteur 8 bits, si le \litterate/<texte>/ est codé sur un seul
octet. Ce test pourrait être utilisé pour déterminer si l'encodage d'un document
est à plusieurs octets (comme l'est UTF8) en prenant comme \litterate/<texte>/
les caractères <<~é~>>, <<~à~>>, etc.

\exo{5,5pt}
Si \verb-#1- est un nombre entier, quel est le test fait par ce code ?
\smallbreak¤\idx*\smallbreak¤
\hfill
\litterate/\if\string l\expandafter\firstto@nil\romannumeral#1\relax\@nil/
\hfill\null¤\idx*[|etc]\string\forbidindex\string\idx*\romannumeral\idx*\hfill\idx*\null§*\firstto@nil§*\litterate¤

\exo{4,5pt}
On a vu que pour provoquer un $n$-développement, les \litterate/\expandafter/se plaçaient
en nombre égal à $2^n-1$ devant chaque token précédant celui que l'on veut développer.
Or, ce nombre est {\it impair\/}. Trouver un exemple ou un cas particulier où il faut¤\idx*\it\idx*\/¤
placer un nombre {\it pair\/} d'\litterate/\expandafter/ devant un token (on pourra ¤\idx*\it\idx*\/¤
envisager le cas de 2 \litterate/\expandafter/).¤§*\litterate¤
\stopexo W
\catcode`\W11

La macro §\dimtodec est ici utilisée puisque le nombre de points n'est pas forcément entier. D'ailleurs, le côté pratique des « points » est que l'argument de \verb|\exo| est considéré comme un barème par l'utilisateur, mais il est vu comme une vraie dimension par \idx\dimexpr !

La man\oe uvre effectuée avec \verb|\exo| est finalement très courante. Écrire dans un fichier lors d'une compilation pour lire des éléments dans ce fichier à la compilation suivante est utilisé dans beaucoup de contextes\footnote{Le format \LaTeX{} écrit des informations de localisation de sectionnement et de références croisées dans le fichier «\texttt{.aux}» via le canal \texttt{\string\@auxout}.}. Pour afficher une table des matières en début de document, il faudrait, à l'aide d'une macro spéciale de sectionnement, d'abord stocker dans un fichier les titres assortis de leurs numéros de page, sachant que le \idx{numéro de page} courant est contenu dans le compteur \idx\count\verb|0| pour plain-\TeX{} et \LaTeX{}\catcode`\@11 \footnote{Le nom qui lui est donné diffère selon le format : plain-\TeX{} demande «\idx\countdef{}\idx\pageno{}\texttt{=0} » tandis que \LaTeX{} préfère «\idx\countdef{}\idx\c@page{}\texttt{=0} ».}\catcode`\@12. Dès lors, à la compilation suivante et sous réserve qu'aucune modification du fichier source n'ait été effectuée entre temps, les instructions écrites dans le fichier reflètent les bons numéros de page.

La construction d'un index repose sur le même stratagème.§*\exo[|)]
\grandsaut

Pour les lecteurs consciencieux, voici les réponses aux exercices donnés dans cet exemple :

\begingroup
\small
\parindent0pt
\solution[exercice 1]
La solution apparait immédiatement en utilisant la macro §\ifempty et \verb|\gobone|, qui va enlever un \idx{octet} à \verb|#1| et que nous prenons soin de développer avant de tester :

\centrecode|\def\ifonebyte#1{\expandafter\ifempty\expandafter{\gobone#1}}|

\solution[exercice 2]
Le test est positif si la lettre «\verb|l|» est la lettre de gauche du nombre écrit en chiffres romains. Ce cas ne se présente que si l'entier est compris entre 50 et 89 (qui s'écrivent «\texttt{\romannumeral50} » et «\texttt{\romannumeral89} »). Ce test est donc positif pour les entiers allant de 50 à 89 compris et négatif pour tous les autres.

\solution[exercice 3]
Le code \verb|\expandafter\expandafter<token>| procède au 1-développement de \verb|<token>| puis au 1-développement du deuxième token du code qui résulte de ce développement.

Voici un cas où 2 \idx\expandafter se justifient :

\showcode/\def\identite{Foo Bar}% Prénom Nom
\def\beforespace#1 #2\nil{#1}
\def\afterspace#1 #2\nil{#2}
\def\prenom{\beforespace\identite\nil}
\def\nom{\afterspace\identite\nil}
Mon prénom : \expandafter\expandafter\prenom¤\defline\aaa¤

Mon nom : \expandafter\expandafter\nom/

À la ligne \no\aaa, l'\idx\expandafter de gauche effectue ce développement :
\medbreak
\hfill\verb|\prenom|\quad$\longrightarrow$\quad\verb|\beforespace\identite\nil|\hfill\null
\medbreak
\noindent et celui de droite 1-développe \verb|\itentite| en «\verb|Foo Bar|» de telle sorte que le code finalement obtenu est :

\centrecode-\beforespace Foo Bar\nil-
\endgroup\idx*[|)]{fichier!écriture}

\section{\texttt{\textbackslash newlinechar} et \texttt{\textbackslash endlinechar}}
L'entier \idx\newlinechar représente le code du caractère qui ordonne à \TeX{} de commencer une nouvelle ligne lors d'une opération avec \idx\write. Dès lors, il devient possible d'écrire en une opération plusieurs lignes dans un fichier. Plain-\TeX{} assigne $-1$ à cet entier ce qui signifie qu'aucun caractère ne revêt cette propriété. \LaTeX, en revanche, y range l'entier \number`\^^J{} qui est le code de caractère de \verb|LF| (le caractère \verbidx*[ (fin de ligne)]{^^J}\verb|^^J|).

\showcode|\newlinechar`\^^J ¤\idx*\newlinechar\verbidx*[ (fin de ligne)]{^^J}¤
\immediate\openout\wtest=test1.txt ¤\idx*\immediate\idx*\openout¤
\immediate\write\wtest{Une première ligne^^JEt une seconde.}¤\idx*\write¤
\immediate\closeout\wtest ¤\idx*\closeout¤
\showfilecontent\rtest{test1.txt}¤§*\showfilecontent¤|

\Qu ant à l'entier \idx\endlinechar, il s'applique également lors des opérations de lecture, c'est-à-dire que le caractère dont le code est \idx\endlinechar sera inséré à la fin de chaque ligne lue, qu'elle se trouve dans le fichier à lire ou dans le code source. Si ce caractère est modifié localement afin d'obtenir des effets spéciaux lors de la lecture d'un fichier, il faut penser à commenter les fins de ligne de la partie du code source concernée pour que ces effets ne s'y appliquent pas aussi.

\showcode|\newlinechar`\^^J ¤\idx*\newlinechar\verbidx*[ (fin de ligne)]{^^J}¤
\immediate\openout\wtest=test2.txt ¤\idx*\immediate\idx*\openout¤
\immediate\write\wtest{Une première ligne^^JEt une seconde.}¤\idx*\write¤
\immediate\write\wtest{Et la dernière.}¤\idx*\write¤
\immediate\closeout\wtest ¤\idx*\closeout¤

{\endlinechar`\X % insère "X" à chaque fin de ligne¤\idx*\endlinechar¤
\openin\rtest=test2.txt % les fins de lignes sont commentées¤\idx*\openin¤
\loop%                    pour éviter que \endlinechar ¤\idx*\loop¤
	\read\rtest to \foo%    ne soit inséré à chaque fin de¤\idx*\read¤
	\unless\ifeof\rtest%    ligne du code source¤\tidx*{unless}\tidx*{ifeof}¤
	\meaning\foo\par%       affiche le texte de remplacement de \foo¤\idx*\meaning¤
\repeat%¤\idx*\repeat¤
\closein\rtest}%|

\begin{exercice}
Utiliser \idx\newlinechar pour simplifier la macro §\exactwrite vue à la page~\pageref{exactwrite}.
\solution
Rappelons-nous que le \verb|<texte>|, susceptible de contenir des retours à la ligne, était lu de telle sorte que tous les octets aient un catcode de 12. Au lieu d'écrire une macro récursive qui lit une seule ligne à chaque itération pour l'écrire dans le fichier, il est bien plus élégant et rapide d'assigner à \idx\newlinechar l'entier \verb|`\^^M|\verbidx*[ (retour charriot)]{^^M}. Une fois ceci fait, il ne reste plus qu'à écrire en une seule fois le \verb|<texte>| dans le fichier :

\showcode/\catcode`\@11
\def\exactwrite#1{% #1=numéro de canal¤§*\exactwrite¤
	\begingroup
		\for\xx=0 to 255\do{\catcode\xx=12 }% donne à tous les octets le catcode 12¤§*\for\idx*{catcode!12\space(autre)}¤
		\newlinechar=`\^^M % caractère de fin de ligne = retour charriot¤\idx\newlinechar\idx*{caractère de fin de ligne}¤
		\exactwrite@i{#1}% donne le <canal> d'écriture comme premier argument
}

\def\exactwrite@i#1#2{% #2 est le caractère délimiteur de catcode 12
	\def\exactwrite@ii##1#2{% ##1 est le <texte> à envoyer vers le fichier
		\immediate\write#1{##1}% écrire le <texte> dans le fichier
		\endgroup% puis, sortir du groupe
	}%
	\exactwrite@ii% traiter tout ce qui se trouve jusqu'au prochain #2
}
\catcode`\@12

\immediate\openout\wtest=writetest.txt % lie le canal \wtest au fichier¤\idx*\openout¤
\exactwrite\wtest|Programmer en \TeX{} est   facile !¤§*\exactwrite¤

Et très utile.|
\immediate\closeout\wtest% et fermer le fichier

Le contenu du fichier "writetest.txt" est :\par
"\showfilecontent\rtest{writetest.txt}"¤§*\showfilecontent¤/
\end{exercice}

\section{Autres canaux d'entrée-sortie}
En plus des 16 canaux de lectures ou d'écriture, \TeX{} dispose de canaux spéciaux. En ce qui concerne la lecture, si le \verb|<canal>| qui suit \idx\read n'est pas compris entre 0 et 15 ou si aucun fichier n'a pu être ouvert (notamment parce que le fichier n'existe pas) ou encore si la fin du fichier a été atteinte (et donc le test \tidx{ifeof} est devenu vrai) alors, la lecture de la ligne courante se fait à partir du terminal : \TeX{} attend que l'utilisateur tape un texte au clavier et finisse par la touche « entrée » (\bioLegacyKeyGlyph{E_n_t_e_r})\footnote{Ce moyen de collecter interactivement des informations n'est possible que lorsque l'exécutable pfd\TeX{} est appelé \emph{sans} l'option «\texttt{-interaction=nonstopmode}» qui l'interdit !}. Un message d'invite est affiché sur le terminal sauf lorsque le \verb|<canal>| est strictement négatif. Si on écrit

\centrecode|\read16 to \foo|

\noindent alors, l'invite est «\verb|\foo=|»

\grandsaut
Du côté de l'écriture, la primitive \idx\message\verb|{<texte>}| a pour action d'écrire le \verb|<texte>| sur le terminal et dans le \idx[!log]{fichier} \verb|log| après avoir développé au maximum ce \verb|<texte>|. Il convient de s'assurer que ce \verb|<texte>| est purement développable et dans le cas contraire, bloquer le développement de certaines de ces parties avec \idx\noexpand ou \idx\unexpanded.

Si on utilise \idx\write\verb|<canal>|, si le \verb|<canal>| n'est pas compris entre 0 et 15 ou si le flux spécifié par le \verb|<canal>| n'a pas été lié à un fichier par \idx\openout, l'écriture est dirigée vers le \idx[!log]{fichier} \verb|log| et vers le terminal, et uniquement vers le \idx[!log]{fichier} \verb|log| si le \verb|<canal>| est strictement négatif.

Il est donc assez facile de converser avec l'utilisateur :

\errcode|\newlinechar`\^^J ¤\idx*\newlinechar\verbidx*[ (fin de ligne)]{^^J}¤
\message{^^JQuel est votre nom ? }¤\idx*\message¤
\xread-1 to \username¤§*\xread¤
\message{Bonjour \username.^^J%
Depuis combien d'années pratiquez-vous TeX ? }
\read-1 to \yeartex ¤\idx*\read¤
\message{%¤\idx*\message¤
	\ifnum\yeartex<5 Cher \username, vous êtes encore un débutant !
	\else\ifnum\yeartex<10 Bravo \username, vous êtes un TeXpert !
	\else\ifnum\yeartex<15 Félicitations \username, vous êtes un TeXgourou.
	\else Passez à autre chose, par exemple à Metafont et Metapost !
	\fi\fi\fi^^J}|{Quel est votre nom ? Christian\par
Bonjour Christian.\par
Depuis combien d'années pratiquez-vous TeX ? 8\par
Bravo Christian, vous êtes un TeXpert !}
\grandsaut

Voici pour finir comment \TeX{} pourrait, par dialogue avec l'utilisateur et en procédant par dichotomie, trouver un nombre entre 1 et 100 choisi au hasard par l'utilisateur :

\errcode|\catcode`\@11
\def\answer@plus{+}\def\answer@minus{-}\def\answer@equal{=}%
\def\nb@found#1{% macro appelée lorsque le nombre (argument #1) est trouvé
	\message{^^JVotre nombre est #1.^^JMerci d'avoir joué avec moi.^^J}%¤\idx*\message¤
}

\def\nbguess#1#2{%
	\message{Choisissez un nombre entre #1 et #2.^^J¤\idx*\message¤
	Tapez entrée lorsque c'est fait.}%
	\read-1 to \tex@guess% attend que l'on tape sur "entrée"¤\idx*\read¤
	\nbguess@i{#1}{#2}%
}

\def\nbguess@i#1#2{%
	\ifnum#1<#2  \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		% si #1<#2 (donc le nombre n'est pas trouvé),
		% mettre dans \tex@guess la troncature de la moyenne de #1 et #2
		{\edef\tex@guess{\number\truncdiv{\numexpr#1+#2\relax}2}%¤§*\truncdiv¤
		\message{Je propose \tex@guess.^^J% afficher sur le terminal¤\idx*\message¤
		Votre nombre est-il plus grand (+), plus petit (-) ou égal (=) : }%
		\read -1 to \user@answer% lire la réponse de l'utilisateur¤\idx*\read¤
		\edef\user@answer{%
			\expandafter\firstto@nil\user@answer\relax\@nil% ne garder que le 1er caractère¤§*\firstto@nil¤
		}%
		\ifxcase\user@answer% envisager les cas "+", "-" et "="¤§*\ifxcase¤
			\answer@plus{\exparg\nbguess@i{\number\numexpr\tex@guess+1\relax}{#2}}%¤§*\exparg¤
			\answer@minus{\expsecond{\nbguess@i{#1}}{\number\numexpr\tex@guess-1\relax}}%¤§*\expsecond¤
			\answer@equal{\nb@found\tex@guess}%
		\elseif% si la réponse ne commence pas par "+", "-" ou "="¤§*\elseif¤
			\message{Je n'ai pas compris votre réponse}% afficher message erreur¤\idx*\message¤
			\nbguess@i{#1}{#2}% et recommencer avec les mêmes nombres
		\endif¤§*\endif¤
		}
		% si #1>=#2, le nombre est trouvé
		{\nb@found{#1}}%
}
\catcode`\@12

\nbguess{1}{100}|{Choisissez un nombre entre 1 et 100.\par
Tapez entrée lorsque c'est fait.\par
\leavevmode\par
Je propose 50.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : -\par
\leavevmode\par
Je propose 25.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : +\par
\leavevmode\par
Je propose 37.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : -\par
\leavevmode\par
Je propose 31.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : -\par
\leavevmode\par
Je propose 28.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : +\par
\leavevmode\par
Je propose 29.\par
Votre nombre est plus grand (+), plus petit (-) ou égal (=) : +\par
\leavevmode\par
Votre nombre est 30.\par
Merci d'avoir joué avec moi.}\idx*[|)]{fichier}

\chapter{Autres algorithmes}
Dans ce chapitre qui sera dépourvu d'exercice, nous allons nous attacher à écrire quelques algorithmes --~des classiques de la programmation~-- en \TeX{}.

\section{Macros de calcul}
\subsection{La suite de Syracuse}
Pour générer une suite de \idx[ (suite de)|(]{Syracuse}, le procédé consiste à choisir un nombre entier strictement positif. S'il est pair, on le divise par 2 ; s'il est impair, on le multiplie par 3 et on ajoute 1. En répétant l'opération, on génère une suite d'entiers appelée « suite de Syracuse ». Si à partir d'un certain rang, l'entier 1 est atteint, la suite de valeurs 1; 4; 2 se répète infiniment et ces trois valeurs constituent ce que l'on appelle le « cycle trivial ». La conjecture de Syracuse, non démontrée, affirme que, quel que soit l'entier choisi au départ, on arrive au bout d'un nombre fini d'itérations à la valeur 1 et donc au cycle trivial.

Nous allons programmer une macro §\syracuse\verb|{<nombre>}|, purement développable qui va afficher toutes les valeurs générées selon le procédé décrit ci-dessus, et s'arrêter lorsque la valeur 1 est atteinte.

Nous aurons recours au test

\centrecode-\ifodd<nombre><code vrai>\else<code faux>\fi-\tidx*{ifodd}

qui est vrai si le \verb|<nombre>| est impair.

\showcode|\def\syracuse#1{%¤§*\syracuse¤
	#1% affiche le nombre
	\ifnum#1>1 % si le nombre est >1
		, % afficher une virgule+espace
		\ifodd#1 % s'il est pair¤\tidx*{ifodd}¤
			\exparg\syracuse% appeler la macro \syracuse¤§*\syracuse¤
			{\number\numexpr3*#1+1% avec 3*n+1¤\idx*\number\idx*\numexpr¤
			\expandafter\expandafter\expandafter}% après avoir rendu la macro terminale¤\idx*{récursivité!terminale}¤
		\else % s'il est pair
			\expandafter\syracuse\expandafter% appeler la macro \syracuse¤§*\syracuse¤
			{\number\numexpr#1/2% avec n/2
			\expandafter\expandafter\expandafter}% après avoir rendu la macro terminale
		\fi
	\else% si le nombre est 1
		.% afficher un point
	\fi
}
a) \syracuse{20}\par
b) \syracuse{14}\par
c) \syracuse{99}\par
d) \edef\foo{\syracuse{15}}\meaning\foo¤§*\syracuse¤|

Les \idx\expandafter qui se trouvent à la fin de l'argument de §\syracuse lors de l'appel récursif sont développés par \idx\numexpr et rendent la récursivité terminale\idx*{récursivité!terminale}. Il est cependant possible d'écrire un code comportant moins d'\idx\expandafter en mettant le test \tidx{ifodd} à l'intérieur du nombre évalué par \idx\numexpr :

\showcode|\def\syracuse#1{%¤§*\syracuse¤
	#1% afficher le nombre
	\ifnum#1>1 % si le nombre est >1
		, % afficher une virgule+espace
		\exparg\syracuse{% appeler la macro \syracuse¤§*\syracuse¤
			\number\numexpr% avec le nombre :¤\idx*\number\idx*\numexpr¤
				\ifodd#1 3*#1+1% 3n+1 si #1 est impair¤\tidx*{ifodd}¤
				\else #1/2%      n/2 sinon
				\fi%
			\expandafter}% avant de rendre la récursivité terminale¤\idx*{récursivité!terminale}¤
	\else
	.% si #1=1, afficher un point
	\fi
}
a) \syracuse{20}\par
b) \syracuse{14}\par
c) \syracuse{99}\par
d) \edef\foo{\syracuse{15}}\meaning\foo¤§*\syracuse¤|\idx*[ (suite de)|)]{Syracuse}

\subsection{Calculer une factorielle}\idx*[|(]{factorielle (calcul)}
La factorielle d'un nombre entier positif $n$, notée $n!$, est égale au produit des $n$ premiers entiers strictement positifs. Par convention $0!=1$.

L'algorithme récursif classique est le suivant où l'on considère que l'argument de la macro §\factorielle[|(] est positif ou nul :
\begin{algo}
	\item si \verb|#1|${}={}0$, \verb|\factorielle{0}|${}={}1$;
	\item sinon, \verb|\factorielle{#1}|${}={}$\verb|#1|${}\times{}$\verb|\factorielle{#1-1}|.
\end{algo}
L'algorithme est d'une simplicité biblique et sa traduction en \TeX{} est immédiate :

\showcode/\def\factorielle#1{%¤§*\factorielle¤
	\ifnum#1=0 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{1}% "1" si #1=0}
		{#1*\exparg\factorielle{\number\numexpr#1-1}}% ¤\idx*\number\idx*\numexpr¤
}
a) \factorielle{0}\qquad
b) \factorielle{3}\qquad
c) \edef\foo{\factorielle{8}}\meaning\foo/

La première chose qui saute aux yeux est que l'expression est bien générée, mais qu'elle n'est pas évaluée par un \idx\numexpr.

Pour y remédier, l'idée va être de partir d'une macro chapeau qui se chargera de lancer \idx\number{}\idx\numexpr afin de provoquer, par développement maximal, la génération de l'enchainement des multiplications obtenu précédemment et son calcul. Cette macro chapeau ajoutera également le \idx\relax final pour stopper le calcul effectué par \idx\numexpr.

\showcode/\catcode`\@11
\def\factorielle#1{%¤§*\factorielle¤
	\number\numexpr\factorielle@i{#1}\relax% appelle \factorielle@i¤\idx*\number\idx*\numexpr¤
	% en lançant le développement maximal
}
\def\factorielle@i#1{%
	\ifnum#1=0 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{1}% "1" si #1=
		{#1*\exparg\factorielle@i{\number\numexpr#1-1}}% ¤\idx*\number\idx*\numexpr¤
}
\catcode`\@12
a) \factorielle{0}\qquad
b) \factorielle{3}\qquad
c) \edef\foo{\factorielle{8}}\meaning\foo/§*\factorielle[|)]\idx*[|)]{factorielle (calcul)}

\subsection{Calculer un PGCD}\idx*[|(]{PGCD}
Le célèbre algorithme d'\textsc{Euclide}\idx*{algorithme d'Euclide} permet de calculer le plus grand diviseur commun à deux entiers, voici comment procéder :
\begin{algo}
	\item soit $a$ le plus grand nombre et $b$ le plus petit
	\item effectuer la division euclidienne $a\div b$ et appeler $r$ le reste;
	\item si $r=0$, le PGCD est le diviseur précédent $b$;
	\item sinon, retourner en 2 en prenant $a\longleftarrow b$ et $b\longleftarrow r$
\end{algo}

Cet algorithme est des plus faciles à traduire en \TeX{}. La macro chapeau §\PGCD[|(], purement développable, se chargera du point \no1, une macro auxiliaire du point \no2 et une autre macro auxiliaire des deux derniers points. La récursivité se jouera sur les deux macros auxiliaires :

\showcode|\catcode`\@11
\def\PGCD#1#2{%¤§*\PGCD¤
	\ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\PGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
		{\PGCD@i{#1}{#2}}%
}

\def\PGCD@i#1#2{% #1=a   #2=b avec a>b
	\exptwoargs\PGCD@ii% appeler la macro récursive avec¤§*\exptwoargs¤
			{\number\numexpr#1-#2*\truncdiv{#1}{#2}}% le reste de a/b¤§*\truncdiv¤
			{#2}% et le divisieur b
}

\def\PGCD@ii#1#2{% #1=reste r   #2=diviseur b
	\ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤\idx*\z@¤
		{#2}% si le reste est nul, renvoyer b
		{\PGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
a) \PGCD{120}{75}\qquad
b) \PGCD{64}{180}\qquad
c) \PGCD{145}{64}\qquad
d) \edef\foo{\PGCD{1612}{299}}\meaning\foo|

Il peut être utile d'écrire les divisions successives qui permettent d'arriver au résultat. Par exemple, si l'on écrit \verb|\calcPGCD{39}{15}|, on aurait les étapes suivantes :

\begingroup\parskip=0pt
$39=15\times2+9$\par
$15=9\times1+6$\par
$9=6\times1+3$\par
$6=3\times2+0$\par\endgroup

La macro §\calcPGCD se chargera d'afficher les étapes ci-dessus. Comme il s'agit d'une macro qui produit un résultat typographique, il n'y a pas besoin de la rendre purement développable. Peu de choses changent; un \verb|\edef| stocke le quotient pour éviter de le calculer deux fois et pour chaque ligne de calcul, les nombres sont affichés lorsqu'ils sont disponibles. Le mode math commence donc dans la première macro auxiliaire et se termine dans la seconde, une fois que le reste a été calculé.

\showcode|\catcode`\@11
\def\calcPGCD#1#2{%¤§*\calcPGCD¤
	\ifhmode\par\fi% si en mode horizontal, former le paragraphe¤\tidx*{ifhmode}¤
	\ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\calcPGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
		{\calcPGCD@i{#1}{#2}}%
}

\def\calcPGCD@i#1#2{% #1=a   #2=b avec a>b
	\edef\calcPGCD@quotient{\number\truncdiv{#1}{#2}}% stocke le quotient
	$#1=\calcPGCD@quotient\times#2% en mode maths, afficher "a=q*b" (à suivre)
	\exptwoargs\calcPGCD@ii% appeler la macro récursive avec¤§*\exptwoargs¤
			{\number\numexpr#1-#2*\calcPGCD@quotient}% le reste de a/b¤§*\truncdiv¤
			{#2}% et le divisieur b
}

\def\calcPGCD@ii#1#2{% #1=reste r   #2=diviseur b
	+#1$\par% (suite du mode math) afficher "+r", fermer le mode math et \par
	\ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi%¤\idx*\z@¤
		{}% si le reste est nul, ne rien faire
		{\calcPGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
\calcPGCD{39}{15}\medbreak¤\idx*\medbreak¤
\calcPGCD{1612}{299}|

Pour améliorer la lisibilité de ces lignes de calcul, un raffinement typographique supplémentaire pourrait être d'aligner sur une même verticale les signes «$=$», «$\times$» et «$+$». Comme ces signes sont toujours les mêmes, le meilleur moyen d'y parvenir va être de bâtir un alignement avec \idx[|(]\halign où ces signes feront partie prenante du préambule de façon à ne pas être écrits à chaque ligne.

Examinons donc tout d'abord le préambule. Il y aura 4 colonnes, chacune étant réservée à un nombre comme dans

\[39=15\times2+9\]

Décidons que la première colonne est composée au fer à droite (le nombre sera au plus près du signe «$=$»), elle sera déclarée \idx*\hfil\verb|$\hfil#$| dans le préambule.

Pour la seconde colonne, nous allons placer le signe «$=$» avant le contenu de la colonne. Il est important de comprendre qu'en mode mathématique\idx*{mode!mathématique}, le signe «$=$» doit être précédé de quelque chose pour qu'une espace mathématique soit insérée avant lui\footnote{Tous les composants d'une formule mathématique sont appelés \emph{atomes}.

Pour de plus amples informations sur le type d'atomes mathématiques composant une formule (le signe $=$ étant de type «\textit{Rel}») et les espaces qu'ils génèrent, voir le \TeX book pages 184-185, 200 ainsi que l'annexe~G.} :

\showcode/\frboxsep=0pt % encadrer au plus proche¤§*\frbox¤
\leavevmode\frbox{$=$} n'est pas identique à \frbox{${}={}$}¤\idx*\leavevmode§*\frbox¤/

En effet, dans le premier cas, ce qui se trouve à gauche de l'atome de relation «$=$» est vide, il n'y a donc aucun espace mathématique qui est ajouté. En revanche, dans la seconde boite, ce qui se trouve à gauche de «$=$» est «\verb|}|» qui est un atome « \textit{Close} » et, en vertu des règles exposées dans le \TeX book, l'espace mathématique inséré à gauche de «$=$» devient le même qu'avec un atome « \textit{Ord} » comme l'est un chiffre ou une lettre.

La conséquence de tout cela est que la deuxième colonne aura comme préambule

\centrecode-${}=\hfil#$-

\noindent où le \idx\hfil nous assure que le nombre, représenté par \verb|#|, sera composé au fer à droite (il sera donc au plus près du signe «$\times$» qui suit).

Puisque les atomes «$\times$» et «$+$» étant de type \textit{Rel}, le même raisonnement doit être suivi pour la 3\ieme{} et 4\ieme{} colonnes qui auront comme préambules

\centrecode-${}\times#\hfil$-\idx*\times

\noindent et

\centrecode-${}+#\hfil$-

Un deuxième problème est qu'une cellule d'un alignement est équivalente à un groupe. Par conséquent, pour pouvoir se transmettre dans l'alignement, l'assignation du quotient doit être globale. Enfin, le \tidx{ifnum} et le \verb|\fi| doivent se trouver dans la même cellule.

\showcode|\catcode`\@11
\def\calcPGCD#1#2{%¤§*\calcPGCD¤
	\vtop{% mettre l'alignement dans une \vtop
		\halign{% les "#" doivent être doublés puisqu'à l'intérieur d'une macro¤\idx*\halign¤
		$\hfil##$&${}=\hfil##$&${}\times##\hfil$&${}+##\hfil$% préambule¤\idx*\hfil\idx*\times¤
		\cr% fin du préambule et début de la première cellule¤\idx*\cr¤
		\ifnum#1<#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{\calcPGCD@i{#2}{#1}}% si #1<#2, mettre #2 (le  grand) dans le premier argument
			{\calcPGCD@i{#1}{#2}}%
		\crcr% fin de l'alignement¤\idx*\crcr¤
		}%
	}%
}

\def\calcPGCD@i#1#2{% #1=a   #2=b avec a>b
	\xdef\calcPGCD@quotient{\number\truncdiv{#1}{#2}}% stocke le quotient¤\idx*\xdef¤
	#1 & \calcPGCD@quotient & #2 &% afficher "a=q*b" (à suivre)
	\exptwoargs\calcPGCD@ii% appeler la macro récursive avec¤§*\exptwoargs¤
			{\number\numexpr#1-#2*\calcPGCD@quotient}% le reste de a/b¤§*\truncdiv¤
			{#2}% et le divisieur b
}

\def\calcPGCD@ii#1#2{% #1=reste r   #2=diviseur b
	#1% (suite de l'alignement) afficher "+r"
	\cr% et terminer la ligne en cours¤\idx*\cr¤
	\ifnum#1=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi%¤\idx*\z@¤
		{}% si le reste est nul, ne rien faire
		{\calcPGCD@i{#2}{#1}}% sinon, recommencer avec b et r
}
\catcode`\@12
a) \calcPGCD{39}{15}\medbreak¤\idx*\medbreak¤
b) \calcPGCD{1612}{299}|\idx*[|)]\halign§*\PGCD[|)]\idx*[|)]{PGCD}

\subsection{Convertir un nombre en base 2}\idx*[|(]{base (conversion)}
Pour convertir un entier positif $n$ quelconque écrit en base 10 en base $b$, voici l'algorithme à utiliser :

\begin{algo}
	\item effectuer la division de $n$ par $b$. Appeler $q$ est le quotient et $r$ le reste;
	\item si $q\neq 0$, retourner en 1 avec $n\longleftarrow q$;
	\item sinon, le nombre cherché est constitué des restes, lus du \emph{dernier au premier}.
\end{algo}

Voici les divisions euclidiennes qu'il faut poser pour convertir 43 en base 2 :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\makeatletter
\newbox\nb@box
\newcount\nb@a
\newcount\nb@b
\newcount\iter@
\newcommand\division[2][2]{\def\dividende@{#2}\def\base@{#1}\iter@\@ne\division@{#2}{#1}}
\newcommand\division@[2]{%
	\setbox\nb@box\hbox{\kern0.5em#1\kern0.5em}%
	\nb@a#1 \nb@b#1 \divide\nb@b#2
	 \vtop{%
		\begingroup
			\multiply\nb@b#2 \advance\nb@a-\nb@b
			\hbox to\wd\nb@box{\hfil#1\hfil}%
			\vskip3pt\hrule height0pt width\wd\nb@box\vskip3.4pt
			\hbox to\wd\nb@box{\hfil\textbf{\number\nb@a}\kern0.5em}%
			\expandafter\xdef\csname reste@\number\iter@\endcsname{\number\nb@a}%
		\endgroup}%
	\setbox\nb@box\hbox{8}\vrule height\ht\nb@box depth3.5ex
	\setbox\nb@box\hbox{\kern0.5em\ifnum#2>\nb@b #2\else\number\nb@b\fi\kern0.5em}%
	\vtop{%
		\hbox to\wd\nb@box{\kern0.5em#2\hfil}%
		\vskip3pt\hrule height0.4pt width\wd\nb@box\vskip3pt
		\hbox{%
			\csname @\ifnum\nb@b>\z@ first\else second\fi oftwo\endcsname
				{\advance\iter@\@ne\gdef\maxiter{\number\iter@}%\idx*\gdef
				\expandafter\division@\expandafter{\number\nb@b}{#2}}%
				{\kern0.5em\number\nb@b\xdef\maxiter{\number\iter@}}}%
		}%
}
\newcommand\afficheresultat[1]{%
	\csname reste@#1\endcsname
	\ifnum#1>\@ne
		\expandafter\afficheresultat
	\else
		\expandafter\@gobble
	\fi{\number\numexpr#1-1}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\par\hfill\division{43}\hfill\null
\medbreak

Et donc, en lisant les restes dans l'ordre inverse, le nombre \dividende@{} s'écrit \afficheresultat\maxiter{} en base 2.
\makeatother

Appelons §\baseconv[|(]\verb|{<n>}| la macro qui va convertir en base 2 le nombre \verb|<n>| écrit en base 10. Donnons-nous une difficulté supplémentaire de taille : le code devra être purement développable. Ainsi, écrire \verb|\edef\foo{\baseconv{43}}| met dans le texte de remplacement de \verb|\foo| les caractères \texttt{\afficheresultat\maxiter}.
\grandsaut

Dans un premier temps, nous allons écrire la macro \verb|\baseconv| de façon à ce qu'elle écrive les restes dans l'ordre où ils sont trouvés. Afin que la macro soit purement développable, la macro §\truncdiv sera mise à contribution.

\showcode|\catcode`\@11
\def\baseconv#1{%¤§*\baseconv¤
	\unless\ifnum#1=\z@ % si #1 est différent de 0¤\tidx*{unless}\idx*\z@¤
		\number\numexpr#1-2*\truncdiv{#1}2\relax% écrire le reste¤\idx*\number\idx*\numexpr §*\truncdiv\defline\aaa¤
		\exparg\baseconv{\number\truncdiv{#1}2\expandafter}% recommencer avec #1/2¤§*\truncdiv¤
	\fi% après que le \fi ait été lu
}
\catcode`\@12
a) \baseconv{43}\qquad
b) \baseconv{32}\qquad
c) \edef\foo{\baseconv{159}}\meaning\foo¤\idx*\meaning§*\baseconv¤|

Cela fonctionne, les restes sont bien écrits au fur et à mesure de leur calcul à la ligne \no\aaa. Certes, la macro pourrait être optimisée puisque §\truncdiv\verb|{#1}2| est calculé deux fois, mais laissons cela pour l'instant. La question qui se pose est «comment s'y prendre pour inverser l'ordre des restes ?»

L'idée est de copier la méthode des « réservoirs» mise en \oe uvre dans la macro §\reverse programmée à la page~\pageref{reverse}. Pour ce faire, la macro §\baseconv ne va devenir qu'une macro chapeau qui va transmettre à la vraie macro récursive \verb|\baseconv@i| deux arguments non délimités : le premier, vide au début, contiendra la liste des restes écrits dans l'ordre désiré. Le second sera le nombre \verb|<n>|. Le fonctionnement de cette macro sera des plus simples.

Si \verb|<n>| est nul, l'affichage de l'argument \verb|#1| sera fait. Sinon, la macro \verb|\baseconv@i|

\begin{itemize}
	\item ajoutera \emph{avant} les autres restes le chiffre

	\centrecode/\number\numexpr#2-2*\truncdiv{#2}2\relax/

	\noindent Notons que la primitive \idx\number ne s'applique ici qu'à \idx\numexpr\verb|...|\idx\relax qui a le statut de registre d'entier. Il n'y a donc aucun risque pour \idx\number de lire un entier supérieur à $2^{31}-1$ si les autres restes qui sont à la suite sont en grand nombre ;
	\item remplacera l'argument \verb|#2| par \verb|\number\truncdiv{#2}2|;
	\item une fois ceci fait, elle s'appellera elle-même.
\end{itemize}

\showcode|\catcode`\@11
\def\baseconv#1{%¤§*\baseconv¤
	\baseconv@i{}{#1}%
}

\def\baseconv@i#1#2{% #1=restes   #2=n
	\ifnum#2=\z@\expandafter\firstoftwo\else\expandafter\secondoftwo\fi% si n=0
		{#1}% si <n>=0, afficher tous les restes
		{% sinon, recommencer en
		\exptwoargs\baseconv@i% ajoutant le reste courant avant #1¤§*\exptwoargs¤
			{\number\numexpr#2-2*\truncdiv{#2}2\relax #1}
			{\number\truncdiv{#2}2}% et en prenant n:=n/2¤§*\truncdiv¤
		}%
}

\catcode`\@12
a) \baseconv{43}\qquad
b) \baseconv{32}\qquad
c) \edef\foo{\baseconv{159}}\meaning\foo|

\subsection{Aller vers des bases plus élevées}
Pourquoi ne pas aller plus loin et convertir un nombre en une base arbitraire ? La limitation réside dans le fait que les symboles utilisés pour les chiffres ne sont pas extensibles à l'infini. Nous avons les 10 chiffres et les 26 lettres (que nous prendrons majuscules) ce qui nous fait 36 signes différents, que nous appellerons « \verb|<chiffre>| ». Nous allons donc d'emblée nous limiter à une conversion vers une base inférieure ou égale à 36.

Le premier travail est de construire une macro §\basedigit, purement développable, de syntaxe

\centrecode|\basedigit{<nombre>}|

\noindent qui se développe en un \verb|<chiffre>| selon le \verb|<nombre>| inférieur à 36 passé en argument. La méthode bête et méchante du \tidx{ifcase} et des 36 \tidx{or} va être privilégiée ici.

Pour que le \verb|<chiffre>| puisse être facilement accessible, l'ensemble

\centrecode-\romannumeral\basedigit{<nombre>}-

\noindent doit donner le \verb|<chiffre>| par 1-développement du \idx\romannumeral. Cela implique de 1-développer les \tidx{or} restants et le \verb|\fi| avant que \idx\romannumeral ait fini son travail :

\showcode/\catcode`\@11
\def\z@@{\expandafter\z@\expandafter}¤\idx*\z@¤
\def\basedigit#1{%¤\tidx*{ifcase}§*\basedigit¤
	\ifcase#1
		\z@@ 0%
		\or\z@@ 1\or\z@@ 2\or\z@@ 3\or\z@@ 4\or\z@@ 5\or\z@@ 6\or\z@@ 7%¤\tidx*{or}¤
		\or\z@@ 8\or\z@@ 9\or\z@@ A\or\z@@ B\or\z@@ C\or\z@@ D\or\z@@ E%
		\or\z@@ F\or\z@@ G\or\z@@ H\or\z@@ I\or\z@@ J\or\z@@ K\or\z@@ L%
		\or\z@@ M\or\z@@ N\or\z@@ O\or\z@@ P\or\z@@ Q\or\z@@ R\or\z@@ S%
		\or\z@@ T\or\z@@ U\or\z@@ V\or\z@@ W\or\z@@ X\or\z@@ Y\or\z@@ Z%¤\tidx*{or}¤
	\fi
}
\long\def\>#1<{\detokenize{#1}}¤\idx*\long\idx*\detokenize¤
a) \expandafter\>\romannumeral\basedigit{23}<\quad¤\idx*\romannumeral¤
b) \expandafter\>\romannumeral\basedigit{6}<¤\idx*\romannumeral§*\basedigit¤
\catcode`@12/

Le test \tidx{ifcase}\verb|<n>|, développé par \idx\romannumeral, avale tout jusqu'au \verb|<n>|\ieme{} \tidx{or}. Par exemple, si l'argument \verb|<n>| est 3, \idx\romannumeral va développer le test et trouver ceci :

\centrecode-\z@@ C\or \z@@ D......\fi-

\noindent La macro \verb|\z@@| sera 1-développée et \idx\romannumeral va voir

\centrecode-\expandafter\z@\expandafter C\or \z@@ D......\fi-

\noindent \idx\romannumeral poursuit le développement puisque n'ayant toujours pas trouvé de nombre. Le pont d'\idx\expandafter va 1-développer «\verb|\or \z@@ D...\fi|», faisant disparaitre le tout. Il va rester

\centrecode-\z@ C-\idx*\z@

\noindent Ensuite, le \idx\z@ va stopper la lecture du nombre par \idx\romannumeral, laissant «\verb|C|».
\grandsaut

Pour que la macro §\baseconv reste purement développable, il va falloir lui transmettre à chaque itération tous les arguments dont elle a besoin et en particulier la base, qui sera un argument figé et lu à chaque fois.

De plus, pour éviter que § \truncdiv\verb|{<n>}{<b>}| soit calculé deux fois, ce quotient, une fois calculé, sera transmis comme argument supplémentaire à une autre sous macro.

Voici le code complet :

\showcode|\catcode`\@11
\def\baseconv#1#2{% #1=base  #2=nombre à convertir¤§*\baseconv¤
	\ifnum#1<37 % base maxi = 36 (10 signes chiffres + 26 signes lettres)
		\antefi¤§*\antefi¤
		\baseconv@i{}{#2}{#1}%
	\fi
}
\def\baseconv@i#1#2#3{% #1=restes  #2=n  #3=base
	\ifnum#2=\z@ \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{#1}% si n=0, afficher tous les restes
		{% si non, transmettre en dernier argument
		\expsecond{\baseconv@ii{#1}{#2}{#3}}%¤§*\expsecond¤
			{\number\truncdiv{#2}{#3}}% le quotient¤§*\truncdiv¤
		}%
}
\def\baseconv@ii#1#2#3#4{% #1=restes  #2=n  #3=base  #4=q
	\exparg\baseconv@i% recommencer, en ajoutant le <chiffre> avant les restes
		{\romannumeral\basedigit{\number\numexpr#2-#4*#3\relax}#1}%¤\idx*\romannumeral§*\basedigit¤
		{#4}% et en remplaçant n par q
		{#3}%
}
\def\z@@{\expandafter\z@\expandafter}%¤\idx*\z@¤
\def\basedigit#1{%¤\tidx*{ifcase}§*\basedigit¤
	\ifcase#1
		\z@@ 0%
		\or\z@@ 1\or\z@@ 2\or\z@@ 3\or\z@@ 4\or\z@@ 5\or\z@@ 6\or\z@@ 7%¤\tidx*{or}¤
		\or\z@@ 8\or\z@@ 9\or\z@@ A\or\z@@ B\or\z@@ C\or\z@@ D\or\z@@ E%
		\or\z@@ F\or\z@@ G\or\z@@ H\or\z@@ I\or\z@@ J\or\z@@ K\or\z@@ L%
		\or\z@@ M\or\z@@ N\or\z@@ O\or\z@@ P\or\z@@ Q\or\z@@ R\or\z@@ S%
		\or\z@@ T\or\z@@ U\or\z@@ V\or\z@@ W\or\z@@ X\or\z@@ Y\or\z@@ Z%¤\tidx*{or}¤
	\fi
}
\catcode`\@12
a) "\baseconv{20}{21587}"\qquad
b) "\baseconv{16}{32}"\qquad
c) \edef\foo{\baseconv{16}{159}}%
   "\meaning\foo"\qquad¤\idx*\meaning¤
d) "\baseconv{2}{43}"¤§*\baseconv¤|§*\baseconv[|)]\idx*[|)]{base (conversion)}

\section{Macros manipulant les listes}\idx*[|(]{liste d'éléments}
Donnons-nous la définition suivante : une « liste » est une collection ordonnée d'« éléments » séparés les uns des autres par un « séparateur » que nous prendrons égal à la virgule. Un « élément » est un ensemble de tokens où les accolades éventuelles qui le composent sont équilibrées et qui ne contient pas le séparateur, sauf si celui-ci est entre accolades.

Le but est d'exécuter les actions suivantes sur une liste donnée : trouver un élément par son numéro, trouver le numéro d'un élément, supprimer un élément, le déplacer, insérer un élément à une position, et « exécuter » la liste, c'est-à-dire que chaque élément deviendra l'argument d'une macro et le code obtenu sera lu par \TeX{}.

Une liste est stockée par \verb|\def| dans le texte de remplacement d'une macro. Une telle macro recevra le nom de \verb|\<macrolist>|.

\subsection{Trouver un élément d'une liste}§*\finditem[|(]
Trouver le \verb|<n>|\ieme{} élément se fera à l'aide de la macro §\finditem selon cette syntaxe:

\centrecode-\finditem\<macrolist>{<n>}-

\noindent Le \verb|<n>|\ieme{} élément de la liste sera renvoyé. La macro sera purement développable, sous réserve que l'élément renvoyé le soit.

Du côté de la mise en \oe uvre, nous utiliserons la méthode classique : la macro §\finditem sera une macro chapeau. Afin qu'elle soit purement développable, la macro récursive \verb|\finditem@i| doit recevoir à chaque itération \emph{tous} les paramètres dont elle a besoin sous forme d'arguments, c'est-à-dire

\begin{enumerate}
	\item la position courante, initialisée à 1 par la macro chapeau et incrémentée à chaque itération;
	\item la position de l'élément à trouver;
	\item l'élément courant qui précède le reste de la liste, que la macro chapeau aura pris soin de terminer par une virgule et un quark.
\end{enumerate}

Le travail de la macro consistera en deux tests imbriqués. Le premier qui regardera si la liste est arrivée à sa fin (en comparant l'élément courant au quark) et l'autre si la position courante correspond à la position cherchée.

\showcode|\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\finditem#1{% #1 = \<macrolist>, la position est lue plus tard par \finditem@i¤§*\finditem¤
	\exparg\finditem@i{#1}% 1-développe la \<macrolist>¤§*\exparg¤
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherchée
	\finditem@ii{1}{#2}#1,\quark@list,% appelle la macro récursive
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherchée  #3=élément courant
	\ifx\quark@list#3\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{}% si la fin de liste est atteinte, ne rien renvoyer
		{% sinon
		\ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{% si la position est la bonne
			\finditem@iii{#3}% renvoyer #3 et manger les éléments restants
			}
			{% si la position n'est pas la bonne, recommencer en incrémentant #1
			\exparg\finditem@ii{\number\numexpr#1+1}{#2}%¤§*\exparg¤
			}%
		}%
}
\def\finditem@iii#1#2\quark@list,{% renvoyer #1 et manger le reste de la liste
	#1%¤\defline\aaa¤
}
\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,kl}
a) \edef\foo{\finditem\liste5}\meaning\foo\qquad
b) \edef\bar{\finditem\liste3}\meaning\bar|

L'élément «\verb|{ef}|» est dépouillé de ses accolades lorsqu'il est lu par la macro récursive \verb|\finditem@ii|. Pour nous prémunir de cette erreur, nous devons insérer un token (nous prendrons \idx\relax) avant chaque élément, et supprimer ce \idx\relax à chaque fois que figure l'élément \verb|#3| dans la macro \verb|\finditem@ii|, ainsi qu'à la ligne \no\aaa{} où il est l'argument \verb|#1| de la macro.

De plus, nous allons aussi définir une macro §\finditemtocs, qui assignera l'élément trouvé à une macro selon la syntaxe

\centrecode-\finditemtocs\<macrolist>{<n>}\<macro>-

Comme cette variante n'a pas à être purement développable, il lui suffira de définir \verb|\finditemtocs@ii| pour exécuter une l'assignation. Tout le reste sera identique à §\finditem.

\showcode/\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\finditem#1{% #1 = \<macro>, la position est lue plus tard par \finditem@i
	\exparg\finditem@i{#1}% 1-développe la \<macro>¤§*\exparg¤
}
\def\finditem@i#1#2{% #1 = liste   #2=position cherchée¤§*\finditem¤
	\ifnum#2>\z@% ne faire quelque chose que si la position est >0
		\antefi¤§*\antefi¤
		\finditem@ii{1}{#2}\relax#1,\quark@list,% appelle la macro récursive
	\fi
}
\def\finditem@ii#1#2#3,{% #1=position courante  #2=position cherché  #3=élément courant
	\expandafter\ifx\expandafter\quark@list\gobone#3%
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{}% si la fin de liste est atteinte, ne rien renvoyer
		{% sinon
		\ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{% si la position est la bonne
			\finditem@iii{#3}% renvoyer #3 et manger les éléments restants
			}
			{% si la position n'est pas la bonne, recommencer en incrémentant #1
			\exparg\finditem@ii{\number\numexpr#1+1}{#2}\relax¤§*\exparg¤
			}%
		}%
}
\def\finditem@iii#1#2\quark@list,{% renvoyer #1 et manger le reste de la liste
	\gobone#1%¤\defline\aaa¤
}
\def\finditemtocs#1#2#3{% #1 = \<macro>  #2=position  #3=macro à définir¤§*\finditemtocs¤
	\def\finditemtocs@iii##1##2\quark@list,{% renvoyer #1 et manger le reste de la liste
		\expandafter\def\expandafter#3\expandafter{\gobone##1}%¤\defline\aaa¤
	}%
	\let#3=\empty¤\idx*\empty¤
	\exparg\finditemtocs@i{#1}{#2}% 1-développe la \<macro>¤§*\exparg¤
}
\def\finditemtocs@i#1#2{% #1 = liste   #2=position cherchée
	\ifnum#2>\z@% ne faire quelque chose que si la position est >0¤\idx*\z@¤
		\antefi\finditemtocs@ii{1}{#2}\relax#1,\quark@list,% appelle la macro récursive¤§*\antefi¤
	\fi
}
\def\finditemtocs@ii#1#2#3,{%
% #1=position courante  #2=position cherché  #3=\relax + élément courant
	\expandafter\ifx\expandafter\quark@list\gobone#3%
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{}% si fin de liste ne rien faire. Sinon, si position bonne
		{\ifnum#1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{\finditemtocs@iii{#3}% renvoyer #3 et manger les éléments restants
			}% si la position n'est pas la bonne, recommencer en incrémentant #1
			{\exparg\finditemtocs@ii{\number\numexpr#1+1}{#2}\relax%¤§*\exparg¤
			}%
		}%
}
\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,kl}
a) "\finditem\liste5"\qquad
b) \edef\bar{\finditem\liste3}\meaning\bar\qquad
c) \finditemtocs\liste{3}\foo\meaning\foo¤§*\finditemtocs¤/§*\finditem[|)]

\subsection{Trouver la position d'un élément}
Il faut annoncer la couleur d'entrée : la macro §\positem, chargée de trouver la position d'un élément et de syntaxe

\centrecode-\positem\<macrolist>{<élément>}-

\noindent ne sera pas purement développable. En effet, il faudra comparer l'élément courant à l'élément cherché et pour ce faire, un test \verb|\ifx| comparera deux macros contenant ces éléments. Définir ces macros rend donc la macro non développable.

Si l'élément cherché n'est pas dans la liste, la position renvoyée sera égale 0.
\grandsaut

À nouveau, une variante §\positemtocs sera programmée. Toutefois, nous allons essayer de ne pas procéder comme avec §\finditem et ne pas réécrire presque complètement le code de la macro §\positem en modifiant deux ou trois choses, ce qui est lourd et assez maladroit. Il est possible de faire mieux. Pour cela, il faut définir ce que l'on appelle en programmation un «\emph{\idx[ (méthode de programmation)]{hook}}». Un hook est un appel à une macro que l'on met à certains endroits du code afin d'exécuter l'action faite par la macro. Pour modifier cette action, il suffit de reprogrammer le hook et non pas réécrire des portions entières du code initial.

Dans le cas présent, le hook sera nommé «\verb|\positem@endprocess|». Pour la macro §\positem, se hook sera défini pour donner la position, préalablement calculée et stockée dans la macro \verb|\pos@item|. Le hook sera donc défini par 

\centrecode-\def\positem@endprocess{\pos@item}-

Pour la macro §\positemtocs, ce \idx[ (méthode de programmation)]{hook} sera programmé pour rendre la macro à définir \verb|\let|-égale à \verb|\pos@item|.

\showcode/\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\positem#1{% #1 = \<macrolist>, la position est lue plus tard par \positem@i¤§*\positem¤
	\def\positem@endprocess{\pos@item}% hook : afficher la position¤\idx*[ (méthode de programmation)]{hook}¤
	\exparg\positem@i{#1}% 1-développe la \<macrolist>¤§*\exparg¤
}
\def\positem@i#1#2{% #1 = liste   #2=élément cherché
	\def\sought@item{#2}% définir l'élément cherché
	\positem@ii{1}\relax#1,\quark@list,% appelle la macro récursive
}
\def\positem@ii#1#2,{% #1=position courante  #2=\relax + élément courant
	\expandafter\def\expandafter\current@item\expandafter{\gobone#2}%
	\ifx\current@item\quark@list\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\def\pos@item{0}% si la fin de liste est atteinte, renvoyer 0
		\positem@endprocess% et aller au hook
		}% sinon
		{\ifx\current@item\sought@item\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{\def\pos@item{#1}% si la position est la bonne, définir la position
			\positem@goblist% et manger les éléments restants
			}% si la position n'est pas la bonne, recommencer en incrémentant #1
			{\exparg\positem@ii{\number\numexpr#1+1}\relax¤§*\exparg¤
			}%
		}%
}
\def\positem@goblist#1\quark@list,{\positem@endprocess}% manger la liste et aller au hook

\def\positemtocs#1#2#3{% #1=\<macrolist>  #2=élément à chercher  #3=macro à définir¤§*\positemtocs¤
	\def\positem@endprocess{\let#3=\pos@item}% hook : mettre le résultat dans #3¤\idx*[ (méthode de programmation)]{hook}¤
	\exparg\positem@i{#1}{#2}% 1-développe la \<macrolist>¤§*\exparg¤
}

\catcode`\@12
\def\liste{a,bcd,{ef},g,hij,,kl}
a) \positem\liste{g}\qquad
b) \positem\liste{ef}\qquad
c) \positem\liste{{ef}}\qquad
d) \positem\liste{}\medbreak¤§*\positem¤

\def\liste{a,bcd,{ef},g,hij,,kl}
a) \positemtocs\liste{g}\foo\meaning\foo\qquad
b) \positemtocs\liste{ef}\foo\meaning\foo\qquad
c) \positemtocs\liste{{ef}}\foo\meaning\foo\qquad
d) \positemtocs\liste{}\foo\meaning\foo\qquad¤§*\positemtocs¤/

\subsection{Insérer un élément dans une liste}§*\insitem[|(]
Passons maintenant à la macro §\insitem qui insère un élément dans une liste à une position spécifiée, position qui sera la position de l'élément dans la liste modifiée après l'insertion

\centrecode-\insitem\<macrolist>{<position>}{<élément>}-

Si la \verb|<position>| est inférieure ou égale à 1, l'élément devra être inséré à la première position. Si la \verb|<position>| est strictement supérieure à la longueur de la liste, l'élément viendra en dernière position. Remarquons que rendre la macro §\insitem purement développable serait un non-sens puisqu'elle n'a pas vocation à renvoyer quelque chose, mais modifie la \verb|\<macrolist>| qui contient la liste d'éléments.

Nous allons procéder un peu comme avec §\finditem, mais nous stockerons  dans une macro temporaire \verb|\item@list| les éléments mangés en y ajoutant l'élément à insérer lorsque la position voulue est atteinte. Par ailleurs, la macro récursive sera écrite comme une sous-macro de §\insitem afin de pouvoir facilement accéder à ses arguments.

\showcode/\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\insitem#1#2#3{% #1 = macro   #2=position cherchée   #3=élément à insérer
	\let\item@list=\empty
	\ifnum#2<1 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		% si position < 1
		{\addtomacro\item@list{#3,}% ajouter l'élement à insérer en premier
		\eaddtomacro\item@list#1% puis la liste entière
		}
		% si la position  > 1
		{% définir la macro récursive
		\def\insitem@i##1##2,{% ##1 = position courante  ##2=\relax + élément courant
			\expandafter\ifx\expandafter\quark@list\gobone##2%
			\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
				{\addtomacro\item@list{#3}}% si fin de liste, ajouter l'élément en dernier
				{% sinon, si la position cherchée est atteinte
				\ifnum##1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
					{\addtomacro\item@list{#3,}% ajouter l'élement
					\add@remainlist##2,% et ##2 (en supprimant le \relax) et le reste
					}% si la position n'est pas atteinte
					{\eaddtomacro\item@list{\gobone##2,}% ajouter l'élément
					\exparg\insitem@i{\number\numexpr##1+1}\relax% et recommencer
					}%
				}%
			}%
		% appel de la macro récursive
		\expandafter\insitem@i\expandafter1\expandafter\relax#1,\quark@list,%
		}%
	\let#1=\item@list% rendre #1 égal au résultat
}

\def\add@remainlist#1,\quark@list,{%
	\eaddtomacro\item@list{\gobone#1}% ajouter #1 ainsi que les autres
}
\catcode`\@12
\def\liste{a,bra,{cA},da,brA}\insitem\liste3{XX}\meaning\liste\par
\def\liste{a,bra,{cA},da,brA}\insitem\liste0{XX}\meaning\liste\par
\def\liste{a,bra,{cA},da,brA}\insitem\liste9{XX}\meaning\liste¤§*\insitem¤/§*\insitem[|)]

\subsection{Supprimer un élément}
Pour supprimer un élément de la liste donné par son numéro avec §\delitem, nous allons agir comme ci-dessus avec la différence suivante : si la position est strictement inférieure à 1 ou strictement supérieure au numéro du dernier élément, ne rien faire.

Supprimer un élément va être un peu plus difficile qu'en insérer un. La difficulté vient du fait que lorsqu'on lit un élément, on lit aussi la virgule qui le suit puisqu'elle agit comme délimiteur de la macro récursive. Si l'élément à supprimer est le dernier de la liste, il restera donc à lire le quark et la virgule qui sont insérés à l'appel de la macro récursive. On ne peut donc pas définir la macro \verb|\add@remainlist| avec un délimiteur «\verb|,\quark@list,|» mais avec ce délimiteur-là : «\verb|\quark@list,|». Nous la nommerons \verb|\add@reaminingitems|.

\showcode/\catcode`\@11
\def\quark@list{\quark@list}% quark de fin de liste
\def\delitem#1#2{% #1 = macro   #2=position cherchée¤§*\delitem¤
	\ifnum#2>0 % ne faire quelque chose que si la position est >0
		\def\delitem@i##1##2,{% ##1 = position courante  ##2=\relax + élément courant
			\expandafter\ifx\expandafter\quark@list\gobone##2%
			\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
				{}% si fin de liste, ne rien faire¤\defline\ccc¤
				{% sinon, si la position cherchée est atteinte
				\ifnum##1=#2 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
					{\add@reaminingitems% et ##2 (en supprimant le \relax) et le reste
					}% si la position n'est pas la bonne
					{\eaddtomacro\item@list{\gobone##2,}% ajouter l'élément¤§*\eaddtomacro\defline\bbb¤
					\exparg\delitem@i{\number\numexpr##1+1}\relax% et recommencer¤§*\exparg¤
					}%
				}%
			}%
		\let\item@list=\empty% initialiser la macro tempporaire
		% appel de la macro récursive
		\expandafter\delitem@i\expandafter1\expandafter\relax#1,\quark@list,%¤\defline\aaa¤
		\let#1=\item@list% rendre #1 égal au résultat
	\fi
}

\def\add@reaminingitems#1\quark@list,{%
	\eaddtomacro\item@list{#1}% ajouter tout jusqu'au quark
}
\catcode`\@12
\for\xx=0 to 8 \do{%¤§*\for¤
\def\liste{a,bcd,{ef},g,hij,kl}
position \xx{} : \expandafter\delitem\expandafter\liste\xx\meaning\liste.\par
}/

Nous le constatons, mais il fallait s'y attendre : une virgule parasite se trouve à la fin de chaque liste traitée par la macro. Si l'élément à supprimer n'est pas le dernier, cette virgule provient de la ligne \no\aaa{} où elle est insérée avant le quark et non mangée par la macro \verb|\add@reaminingitems|. En revanche, si l'élément à supprimer est le dernier, cette virgule provient de la ligne \no\bbb{} où elle a été insérée à l'itération précédente.

Dans tous les cas, il nous faut trouver un moyen de supprimer cette virgule. Le moyen le plus rapide est de définir une macro 

\centrecode|\def\remove@lastcomma#1,\@nil{\def\item@list{#1}}|

Il faut s'assurer que cette macro reçoit le texte de remplacement de \verb|\item@list| (qui se finit par une virgule dont on veut  se débarrasser) suivi d'un \verb|\@nil|. Il faut donc insérer la ligne suivante juste après la ligne \no\aaa{} de la macro §\delitem :

\centrecode-\expandafter\remove@lastcomma\item@list\@nil-

\subsection{Déplacer un élément}
Pour déplacer un item d'une position $x$ à une position $y$, il faut déjà isoler cet item avec §\finditemtocs, le supprimer avec §\delitem et enfin l'insérer avec §\insitem à la position $y$.

\showcode/\catcode`\@11
\def\moveitem#1#2#3{% #1 = liste, #2=position départ, #3=position arrivée¤§*\moveitem¤
	\ifnum#2>0 % ne faire quemque chose que si #2>0
		\finditemtocs#1{#2}\temp@item% sauvegarder l'élément¤§*\finditemtocs¤
		\delitem#1{#2}% supprimer l'élément¤§*\delitem¤
		\expsecond{\insitem#1{#3}}\temp@item% insérer l'élément¤§*\expsecond§*\insitem¤
	\fi
}
\catcode`\@12
% déplace "b" en 5e position
a) \def\liste{a,b,c,d,e,f} \moveitem\liste25 "\liste"\par
% déplace "d" en 1e position
b) \def\liste{a,b,c,d,e,f} \moveitem\liste41 "\liste"\par
% déplace "c" en 9e position
c) \def\liste{a,b,c,d,e,f} \moveitem\liste39 \liste"\par
% position départ=0 -> sans effet
d) \def\liste{a,b,c,d,e,f} \moveitem\liste02 "\liste"¤§*\moveitem¤/

\subsection{Exécuter une liste}
La dernière chose qu'il nous reste à faire est d'exécuter une liste et pour ce faire, programmer une macro §\runlist. Pour cela, chacun des éléments de la liste sera placé dans l'argument d'une \verb|\<macro>|. Donnons-nous cette syntaxe :

\centrecode-\runlist{\<macrolist>}\with\<macro>-§*\runlist

\noindent Tous les éléments de la \verb|<liste>| seront placés tour à tour dans l'argument d'une \verb|\<macro>| acceptant un seul argument, et tout se passera comme si nous avions écrit

\centrecode-\<macro>{<élément 1>}\<macro>{<élément 2>}...\<macro>{<élément n>}-

\noindent et que ce code soit exécuté par \TeX.

La méthode consiste à manger chaque élément, l'écrire comme argument de la \verb|\<macro>| et s'arrêter lorsque la fin de la liste est atteinte. Il va donc falloir stoker dans une macro auxiliaire nommée \verb|\collect@run| les \verb|\<macro>{<élément i>}| au fur et à mesure que les éléments seront rencontrés et exécuter cette macro à la toute fin du processus. Pour être tout à fait propre en programmation, nous allons effectuer la collecte dans un groupe semi-simple de telle sorte que la macro \verb|\collect@run| soit locale à ce groupe et n'existe plus ensuite, étant entendu que \verb|\collect@run| doit être exécutée \emph{hors} du groupe semi-simple.

\showcode/\catcode`\@11
\def\runlist#1\with#2{% #1=liste #2=macro¤§*\runlist¤
	\def\runlist@i##1,{%
		\ifx\quark@list##1\relax\else% si la fin n'est pas atteinte
			\addtomacro\collect@run{#2{##1}}% ajouter "\<macro>{<élément>}""¤§*\addtomacro¤
			\expandafter\runlist@i% et recommencer en lisant l'élément suivant
		\fi
	}%
	\begingroup% fait la collecte dans un groupe
		\let\collect@run=\empty% initialiser la macro¤\defline\bbb¤
		\expandafter\runlist@i#1,\quark@list,% appeler \runlist@i
	\expandafter\endgroup% ferme le groupe et détruit \collect@run¤\defline\aaa¤
	\collect@run% après l'avoir développé !
}
\catcode`\@12
\newcount\foocnt
\foocnt=0 % compteur utilisé pour numéroter les éléments dans la macro \foo¤\idx*\newcount¤¤\idx*\long¤
\def\foo#1{% la macro qui va exécuter chaque élément de la liste. #1 = l'élément
	\advance\foocnt1 % incrémente le compteur¤\idx*\advance¤
	L'argument \number\foocnt\ est : {\bf #1}\par%¤\idx*\number¤
}
\def\liste{a,bra,ca,da,BRA}%
\runlist\liste\with\foo%¤§*\runlist¤/

Remarquons l'astuce à la ligne \no\aaa{} qui consiste à « sauter » le \idx\endgroup à l'aide d'un un \idx\expandafter pour 1-développer la macro \verb|\collect@run| avant que le \idx\endgroup ne la détruise ! C'est une astuce assez commune que de sauter une fin de groupe avec un ou plusieurs \idx\expandafter pour gagner le territoire se trouvant à l'extérieur du groupe tout en restant imprégné de ses propriétés. Cette méthode permet donc à peu de frais\footnote{Tout au plus quelques \texttt{\string\expandafter} avant le \texttt{\string\endgroup} éventuellement relayés à l'extérieur du groupe par d'autres \texttt{\string\expandafter} ou tout autre procédé permettant de propager le développement jusqu'au lieu où l'on veut exporter les propriétés du groupe.} d'exporter au dehors de son territoire les propriétés d'un groupe avant sa fermeture.

Ici, nous aurions pu procéder autrement et initialiser \verb|\collet@run| de cette façon à la ligne \no\bbb{}

\centrecode-\def\collect@run{\endgroup}-

\noindent et écrire en lieu et place des lignes \nos\aaa-\number\numexpr\aaa+1\relax{} un simple \verb|\collect@run| qui, en se développant, aurait fait apparaitre le \idx\endgroup au début de son texte de remplacement qui aurait provoqué sa destruction.

\subsection{Enlever les espaces extrêmes}
Il nous reste un dernier pas à accomplir, celui de se jouer des espaces laissés avant ou après les éléments d'une liste. En effet, il serait commode de saisir

\centrecodespc-\def\liste{ a, b c , def,   g h, ij }-

\noindent et de disposer d'une macro §\sanitizelist\verb|\liste| qui rendrait la liste égale à

\centrecodespc-a,b c,def,g h,ij-

Cette macro §\sanitizelist supposerait qu'il existe une macro capable de retirer \emph{tous} les espaces qui se trouvent au début ou à la fin d'un argument, sans évidemment toucher aux espaces «intérieurs».

\subsubsection{Supprimer les espaces du début}
La mise au point d'une macro §\removefirstspaces qui retire tous les espaces qui se trouvent au \emph{début} de son argument demande tout d'abord de programmer un test §\ifspacefirst\verb|{<texte>}{<vrai>}{<faux>}| qui est vrai si son premier argument commence par un espace. Pour éviter d'envisager le cas d'un \verb|<texte>| vide, la lettre «\verb|W|» sera ajoutée à la fin de cet argument.

\showcode/\catcode`\@11
\def\ifspacefirst#1{%¤§*\ifspacefirst¤
	\expandafter\ifspacefirst@i\detokenize{#1W} \@nil% "W" se prémunit d'un argument vide
}
\def\ifspacefirst@i#1 #2\@nil{\ifempty{#1}}% renvoyer vrai s'il n'y a rien avant " "¤§*\ifempty¤
\catcode`\@12
a) \ifspacefirst{a bc d}{vrai}{faux}\qquad
b) \ifspacefirst{ a bc d}{vrai}{faux}\qquad
c) \ifspacefirst{ }{vrai}{faux}\qquad
d) \ifspacefirst{}{vrai}{faux}\qquad
e) \ifspacefirst{{ } }{vrai}{faux}\qquad
f) \ifspacefirst{ {x} }{vrai}{faux}¤§*\ifspacefirst¤/

Le côté pratique de \idx\detokenize est qu'il permet des accolades dans le \verb|<texte>| malgré le fait que ce \verb|<texte>| soit l'argument d'une macro à argument délimité.

La méthode mise en \oe uvre sera simple : pour supprimer tous les espaces au début d'un argument, il faut tester s'il commence par un espace et dans l'affirmative, manger cet espace avec une macro §\gobspace puis recommencer avec ce qui a été obtenu. La macro §\gobspace attendra donc un espace juste après elle et sera donc délimitée par un espace. Pour la définir, il n'est pas possible d'écrire

\centrecodespc|\def\gobspace {}|

\noindent car dans le code source, un espace qui suit une séquence de contrôle est ignoré (voir règle page~\pageref{regle.espace}). Pour contourner cette règle, nous allons mettre en place un pont d'\idx\expandafter pour 1-développer \idx\space en \verb*| | avant que \idx\def n'entre en action :

\showcode/\catcode`\@11
\expandafter\def\expandafter\gobspace\space{}¤§*\gobspace\idx*\space¤

\def\removefirstspaces#1{%¤§*\removefirstspaces¤
	\ifspacefirst{#1}% si #1 commence par un espace¤§*\ifspacefirst¤
		{\exparg\removefirstspaces{\gobspace#1}}% recommencer sans le 1er espace¤§*\gobspace¤
		{#1}% sinon, renvoyer l'argument¤\defline\aaa¤
}
\catcode`\@12
a) "\removefirstspaces{12 {\bf3}4 567}"\qquad
b) "\removefirstspaces{ 12 {\bf3}4 567}"\qquad
c) \edef\foo{\space\space\space 12 34 567}¤\idx*\space¤
   "\exparg\removefirstspaces\foo"¤§*\expsecond§*\removefirstspaces¤/

Le dernier cas permet de vérifier que la récursivité fonctionne lorsque le texte de remplacement de \verb|\foo| commence par \emph{trois} espaces, chacun issu du développement de \idx\space.

Essayons d'aller un peu plus loin et faisons en sorte que cette macro se développe en un nombre connu de fois. Nous allons recourir à un \idx\romannumeral, placé au tout début du texte de remplacement de  §\removefirstspaces afin de lancer le développement maximal. Il faudra le stopper en écrivant \verb|{\z@#1}| à la ligne \no\aaa. On s'offre donc une macro qui effectue son travail en deux développements : le premier pour extraire son texte de remplacement et le deuxième qui lance celui de \idx\romannumeral.

\showcode/\catcode`\@11
\def\removefirstspaces{%¤§*\removefirstspaces¤
	\romannumeral% lance le développement maximal¤\idx*\romannumeral¤
	\removefirstspaces@i% et passe la main à la macro récursive
}

\def\removefirstspaces@i#1{%
	\ifspacefirst{#1}% si #1 commence par un espace¤§*\ifspacefirst¤
		{\exparg\removefirstspaces@i{\gobspace#1}}% recommencer sans le 1er espace¤§*\gobspace§*\exparg¤
		{\z@#1}% sinon, renvoyer l'argument où \z@ stoppe l'action de \romannumeral¤\idx*\z@¤
}
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}¤\idx*\long\idx*\detokenize¤

a) \expandafter\expandafter\expandafter\>\removefirstspaces{12 {\bf3}4 567}<\qquad¤\idx*\bf§*\removefirstspaces¤
b) \expandafter\expandafter\expandafter\>\removefirstspaces{ 12 {\bf3}4 567}<\qquad
c) "\removefirstspaces{ 12 {\bf3}4 }"¤§*\removefirstspaces¤/

\subsubsection{Supprimer les espaces de fin}
Programmons maintenant la macro §\removelastspaces\verb|{<texte>}| qui supprime les espaces qui se trouvent à la fin de son argument. Bien que l'algorithme soit un peu plus compliqué, nous allons \emph{aussi} utiliser des arguments délimités.

Pour décrire la méthode, prenons «\verb|W|» comme délimiteur en supposant pour l'instant que cette lettre ne figure pas dans l'argument. L'idée se décompose en plusieurs étapes :

\begin{enumerate}
	\item ajouter «\verb*|W W|» à la fin de l'argument;
	\item du résultat obtenu, prendre ce qui se trouve avant le premier «\verb*| W|»;
	\item ajouter «\verb|W|» à la fin du résultat obtenu;
	\item du résultat précédent, prendre ce qui se trouve avant le premier «\verb|W|».
\end{enumerate}

Énuméré comme cela, il est quasi impossible de se représenter les différentes étapes et comprendre comment évolue l'argument. Aussi, nous allons prendre deux exemples pour décrire les deux cas de figure pouvant se présenter, «\verb*|a|» qui ne finit pas par un espace et «\verb*|b |» qui se trouve dans le cas opposé :

\begin{centrage}
\small
\begin{tabular}{clcc}
	\no d'étape & decription & \verb*|a| & \verb*|b |\\\hline
	1& ajout de «\verb*|W W|» & \verb*|aW W|&\verb*|b W W|\\
	2& ce qui est avant «\verb*| W|» & \verb*|aW|&\verb*|b|\\
	3& ajout de «\verb*|W|» & \verb*|aWW|&\verb*|bW|\\
	4& ce qui est avant «\verb*|W|» & \verb*|a|&\verb*|b|\\\hline
\end{tabular}
\end{centrage}

Le cheminement est désormais plus clair et il est plus facile de se persuader que la méthode fonctionne quels que soient «\verb|a|» et «\verb|b|».

La méthode présente cependant un petit défaut; elle indique ce qui se trouve \emph{avant} les délimiteurs, mais ne dit pas un mot de ce qu'elle laisse \emph{après}. Nous allons donc aussi récolter les reliquats qui sont laissés après les délimiteurs.

Imaginons qu'au lieu de \verb*|W W|, nous ajoutions en fin d'argument «\verb*|W W\@nil|» lors de la première étape et que l'on fasse fonctionner les étapes déjà décrites. Le fait nouveau sera qu'à la fin, on récolte les reliquats se trouvant avant le \verb|\@nil|. \Qu'y trouverait-on ? Tout ce qui a été laissé après les délimiteurs des lignes \no2 et 4. Le tableau est repris sauf qu'ici, les lignes grises montrent ce qui est laissé après ces délimiteurs :

\begin{centrage}
\small
\begin{tabular}{clcc}
	\no d'étape & description
 & \verb*|a| & \verb*|b |\\\hline
	1& ajout de «\verb*|W W|» & \verb*|aW W|&\verb*|b W W|\\
	2& ce qui est avant «\verb*| W|» & \verb*|aW|&\verb*|b|\\
	\rowcolor{gray!40} & ce qui est après «\verb*| W|» & \verb|<vide>|&\verb*| W|\\
	3& ajout de «\verb*|W|» & \verb*|aWW|&\verb*|bW|\\
	4& ce qui est avant «\verb*|W|» & \verb*|a|&\verb*|b|\\
	\rowcolor{gray!40} & ce qui est après «\verb*|W|» & \verb*|W|&\verb|<vide>|\\\hline
\end{tabular}
\end{centrage}

Avant le \verb|\@nil| se trouve la concaténation des reliquats partiels, c'est-à-dire :

\begin{itemize}
	\item «\verb|W|» dans le cas «\verb|a|»;
	\item «\verb*| W|» dans le cas «\verb*|b |».
\end{itemize}

Il est intéressant de remarquer que si le reliquat \emph{commence} par un espace, cela signifie que l'argument se finissait par un espace. Dans le cas présent, puisque nous souhaitons supprimer \emph{tous} les espaces à la fin de l'argument, il va donc falloir mettre en place une récursivité et recommencer dans le cas où le reliquat commence par un espace.

Réglons enfin le délimiteur «\verb|W|» qui nous a servi pour exposer la méthode, mais qui ne peut être utilisé dans les vraies conditions, car trop probable dans un vrai argument. Remplaçons-le par un caractère bien plus improbable mais pas trop «exotique», par exemple le caractère de code 0 (qui s'écrit \verb|^^00|) et de catcode 12\footnote{Rien n'empêcherait de lui assigner un catcode de 3 pour le rendre plus exotique.}\idx*{catcode!12 (autre)}.

\showcode/\catcode`\@11
\edef\catcodezero@saved{\number\catcode0 }% stocke le catcode de ^^00
\catcode0=12 % le modifie à 12
\def\removelastspaces#1{%
	\romannumeral% lance le développement maximal
	\removelastspaces@i\relax#1^^00 ^^00\@nil% mettre un \relax au début¤\defline\aaa¤
	                                         % et passer la main à \removelastspaces@i
}
\def\removelastspaces@i#1 ^^00{% prendre ce qui est avant " W"
	\removelastspaces@ii#1^^00% ajouter "W"
}
\def\removelastspaces@ii#1^^00#2\@nil{% #1=ce qui est avant "W"  #2=reliquat
	\ifspacefirst{#2}% si le reliquat commence par un espace
		{\removelastspaces@i#1^^00 ^^00\@nil}% recommencer sans passer par \removelastspaces
		{\expandafter\z@\gobone#1}% sinon supprimer le \relax ajouté au début
		                          % et stopper l'action de \romannumeral avec \z@
}
\catcode0=\catcodezero@saved\relax% restaure le catcode de ^^00
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}¤\idx*\long\idx*\detokenize¤

a) \expandafter\expandafter\expandafter\>\removelastspaces{ 12 {\bf3}4 }<\qquad
b) \expandafter\expandafter\expandafter\>\removelastspaces{12 {\bf3}4}<\qquad
c) "\removelastspaces{ 12 {\bf3}4 }"¤§*\removelastspaces¤/

La première remarque concerne le \idx\relax mis avant \verb|#1| tout au début afin d'éviter que \verb|#1| ne soit dépouillé de ses accolades s'il s'agit d'un texte entre accolades. Ce \idx\relax est retiré juste avant que \idx\z@ ne stoppe l'action de \idx\romannumeral.

L'autre remarque, essentielle, est que l'appel récursif de la ligne \no\aaa{} n'appelle pas la macro chapeau §\removelastspaces. Cela évite de lancer à chaque itération un nouveau \idx\romannumeral qui ne serait pas stoppé par la suite et provoquerait des erreurs de compilation.

\subsubsection{Supprimer les espaces extrêmes}
Tout est en place pour construire une macro §\removetrailspaces, chargée de supprimer les espaces en trop se trouvant au début et à la fin de son argument. Il suffit d'assembler correctement les macros vues précédemment. Cet assemblage mérite une explication\ldots{} Si \verb|#1| est l'argument de cette macro, on voudrait pouvoir écrire

\centrecode-\removelastspaces{\removefirstspaces{<sp>#1<sp>}}-§*\removefirstspaces§*\removelastspaces

\noindent où \verb|<sp>|  représente d'éventuels espaces extrêmes de \verb|#1|. Mais n'oublions pas que \TeX{} prend les arguments tels quels, sans les remplacer par ce qu'ils sont après développement.

Pour que §\removefirstspaces\verb|{<sp>#1<sp>}| soit développé, nous allons d'abord lancer le développement maximal avec \idx\romannumeral en tout début de texte de remplacement de §\removetrailspaces. Comme précédemment, cet artifice nous assurera que cette macro donne son résultat en deux développements.

Dans le code ci-dessus, convenons que «\textbullet» représente un \idx\expandafter. Le pont d'\idx\expandafter, lui-même développé par \idx\romannumeral, va 2-développer «§\removefirstspaces\verb|{<sp>#1<sp>}|» :

\begin{centrage}
	\small
	\idx\romannumeral\textbullet\textbullet\textbullet§\removelastspaces\textbullet\textbullet\textbullet\verb|{|§\removefirstspaces\verb|{<sp>#1<sp>}}|
\end{centrage}

\noindent Après que les \idx\expandafter aient joué leur rôle, la macro §\removefirstspaces a effectué son travail et on obtient :

\centrecode-\removelastspaces{#1<sp>}-§*\removelastspaces

\noindent Enfin, comme \idx\romannumeral n'a toujours pas trouve de nombre, le développement se poursuit, la macro §\removelastspaces se 2-développe et nous obtenons :

\centrecode-#1-

Mais à ce stade, \idx\romannumeral est toujours en action et nous n'avons pas pensé à la stopper. Si \verb|#1| commence par un nombre au sens de \TeX{}, ce nombre sera capturé par \idx\romannumeral pour former les chiffres romains et sinon, \TeX{} se plaindra d'une erreur de compilation du type «\texttt{Missing number}».

Pour régler ce problème, il faut revenir en arrière et réfléchir où mettre \idx\z@ pour qu'à la dernière étape ci-dessus, le \verb|#1| soit précédé de \idx\z@. Le bon endroit est juste avant §\removefirstspaces, mais surtout pas avant \verb|#1|, car ce \idx\z@ cacherait les éventuels espaces au début de \verb|#1|. Remarquons au passage que ce token supplémentaire «\idx\z@» implique la prolongation du pont d'\idx\expandafter. Voici les étapes du développement jusqu'au résultat final:

\begin{centrage}
	\small
	\idx\romannumeral\textbullet\textbullet\textbullet§\removelastspaces\textbullet\textbullet\textbullet\verb|{|\textbullet\textbullet\textbullet\verb|\z@|§\removefirstspaces\verb|{<sp>#1<sp>}}|\smallbreak
	§\removelastspaces\verb|{\z@#1<sp>}|\smallbreak
	\verb|\z@#1|\smallbreak
	\verb|#1|
\end{centrage}

Cette méthode donne le code suivant :

\showcode/\catcode`\@11
\def\removetrailspaces#1{%¤§*\removetrailspaces¤
	\romannumeral% lance le développement maximal¤\idx*\romannumeral¤
		\expandafter\expandafter\expandafter% le pont d'\expandafter
	\removelastspaces¤§*\removelastspaces¤
		\expandafter\expandafter\expandafter% fait agir \removefirstspaces en premier
	{%
		\expandafter\expandafter\expandafter
	\z@% stoppe le développement initié par \romannumeral¤\idx*\z@¤
	\removefirstspaces{#1}%¤§*\removefirstspaces¤
	}%
}
\catcode`\@12
\long\def\>#1<{"\detokenize{#1}"}

a) \expandafter\expandafter\expandafter\>\removetrailspaces{ 12 {\bf3}4 }<\qquad¤\idx*\bf¤
b) \expandafter\expandafter\expandafter\>\removetrailspaces{12 {\bf3}4}<\par
c) \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
   \foo\expandafter\expandafter\expandafter{\removetrailspaces{ 12 {\bf3}4 }}%
   signification : \meaning\foo.\par¤\idx*\meaning¤
c) exécution : "\foo"\par
d) "\removetrailspaces{ 12 {\bf3}4 }"¤§*\removetrailspaces¤/

\subsubsection{La macro \texttt{\char`\\sanitizelist}}
Le plus dur est fait ! Nous allons maintenant pouvoir finir en douceur en écrivant la macro §\sanitizelist qui supprime tous les espaces extrêmes des éléments d'une liste. Le confort dont nous profitons ici est que §\removetrailspaces ne demande que deux développements pour donner son résultat.

Au fur et à mesure de la lecture de la liste, nous allons collecter dans la macro \verb|\item@list| les éléments purgés de leurs espaces indésirables. Ici encore, nous placerons un \verb|\relax| avant chaque élément (argument \verb|#1|), sous réserve de le supprimer ensuite avec \verb|\gobone|. L'ajout de l'élément en cours \verb|#1| au collecteur \verb|\item@list| se fera donc par :

\centrecode-\addtomacro\item@list{\removetrailspaces{\gobone#1},}-

\noindent sauf qu'il faut développer les arguments avant que les macros ne s'en emparent. Ici, \verb|\gobone| doit être 1-développé en premier puis §\removetrailspaces doit être 2-développé. Cela va être le festival des \verb|\expandafter|, ou plutôt l'invasion ! Un \verb|\expandafter| est représenté par $\bullet$ ci-dessous.

\begin{centrage}
\small
$\bullet\bullet\bullet\bullet\bullet\bullet\bullet$%
\verb|\addtomacro|%
$\bullet\bullet\bullet\bullet\bullet\bullet\bullet$%
\verb|\item@list|\par
$\bullet\bullet\bullet\bullet\bullet\bullet\bullet$%
\verb|{|$\bullet$\verb|\removetrailspaces|$\bullet$\verb|{\gobone#1},}|
\end{centrage}

\showcode/\catcode`\@11
\def\sanitizelist#1{% #1 = liste¤§*\sanitizelist¤
	\let\item@list\empty% initialise le réceptacle de la liste assainie¤\idx*\empty¤
	\def\sanitizelist@endprocess{% définit le hook de fin¤\idx*[ (méthode de programmation)]{hook}¤
		\expandafter\remove@lastcomma\item@list\@nil% supprimer dernière virgule
		\let#1=\item@list% et assigner le résultat à #1
	}%
	\expandafter\sanitizelist@i\expandafter\relax#1,\quark@list,% aller à la macro récursive
}

\def\sanitizelist@i#1,{% #1="\relax" + élément courant
	\expandafter\ifx\expandafter\quark@list\gobone#1%
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\sanitizelist@endprocess% si fin de liste, hook de fin¤\idx*[ (méthode de programmation)]{hook}¤
		}% si la fin de la liste n'est pas atteinte :
		{\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
			\addtomacro% 1-développer \gobone pour retirer \relax
		\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
			\item@list% puis 2-développer \removetrailspaces
		\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter\expandafter
			{\expandafter\removetrailspaces\expandafter{\gobone#1},}% "#1"¤§*\removetrailspaces¤
		\sanitizelist@i\relax% et continuer avec l'élément suivant
		}%
}

\catcode`\@12
\frboxsep=0pt % encadrer au plus proche¤§*\frboxsep¤
\def\foo#1{\frbox{\tt\strut#1} }% boite avec un strut et en fonte "tt" puis espace¤\idx*\strut§*\frbox¤
\def\liste{ Programmer, en \TeX{} ,est   ,{\bf facile}, et utile }
a) \runlist\liste\with\foo% encadrer les items¤§*\runlist¤

b) \sanitizelist\liste% supprimer les espaces inutiles des items¤§*\sanitizelist¤
   \runlist\liste\with\foo/\idx*[|)]{liste d'éléments}

Il est toujours possible d'éviter ces fastidieux ponts d'\verb|\expandafter|. Nous aurions pu mettre à contribution nos macros §\expsecond et §\eaddtomacro pour alléger le code. Ces \verb|\expandafter| ont été laissés en l'état pour montrer que la gestion du développement est parfois assez pénible.

\begin{centrage}
$\star$\par\nobreak
$\star$\quad$\star$
\end{centrage}

Après avoir compris dans cette partie comment construire des macros récursives et donc, comment s'y prendre pour bâtir des boucles, nous allons poursuivre notre chemin.

Il s'agit désormais de lire non pas des arguments comme le font les macros, mais descendre à un niveau inférieur, celui des tokens. Pour prendre une analogie chimique, les arguments seraient les molécules tandis que les tokens seraient les atomes; l'un étant fait avec l'autre. Il nous faut apprendre à programmer des macros qui lisent des tokens, un peu comme le fait \TeX{} lorsqu'il lit du code, mais en gardant la main après chaque token de façon à être capable de \emph{contrôler} chaque token lu et d'agir en conséquence.
%|                                                                            |
%|                                Fin partie 3                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Partie 4                                  |
%|                                                                            |
\defpartcomment{\lettrine[lines=3,nindent=0pt,slope=2pt]{\libertineInitialGlyph{M}}{\kern -2pt aintenant} que les arguments des macros n'ont plus de secrets, il faut apprendre à intervenir à un niveau plus bas, celui des tokens. En effet, pour certains besoins spécifiques, la lecture d'arguments par des macros est trop grossière et ne permet pas de les résoudre de façon satisfaisante.}

\part{Au niveau des tokens}
\chapter{Mise en évidence du problème}
Supposons que nous souhaitions effectuer un traitement sur chaque caractère d'une phrase. Pour rendre les choses visuelles, choisissons d'encadrer chaque caractère. L'idée est de lire chaque caractère de la phrase par une macro à argument puis d'encadrer ce caractère à l'aide de la macro §\frbox vue dans la partie précédente. La récursivité sera classique, une macro chapeau §\boxsentence se chargera de transmettre la phrase suivie d'un quark à une macro récursive. La macro récursive \verb|\boxsentence@i| lira donc un argument, le stockera dans une macro brouillon pour le comparer au \idx{quark} et tant que l'égalité n'aura pas lieu, bouclera sur elle-même pour lire les arguments les uns après les autres.

\showcode/\catcode`\@11
\def\boxsentence#1{%¤§*\boxsentence¤
	\leavevmode% se mettre en mode horizontal¤\idx*\leavevmode\idx*{mode!horizontal}¤
	\boxsentence@i#1\quark% transmet "#1+\quark" à boxsentence@i¤§*\quark¤
}
\def\boxsentence@i#1{% #1= argument lu
	\def\current@arg{#1}% stocke l'argument dans une macro temporaire
	\unless\ifx\quark\current@arg% si la fin n'est  pas atteinte¤\tidx*{unless}§*\quark¤
		\frbox{#1}% encadrer cet argument¤§*\frbox¤
		\expandafter\boxsentence@i% lire l'argument suivant
	\fi
}
\catcode`@12
\frboxsep=1pt \frboxrule=0.2pt ¤§*\frboxsep§*\frboxrule¤
\boxsentence{Programmer en \TeX\ est facile}¤§*\boxsentence¤/

Les espaces sont ignorés puisque la règle dit que lorsque les espaces ne sont pas enveloppés entre accolades, ils sont ignorés lorsque lus par une macro en tant qu'arguments. Si l'on avait voulu encadrer les espaces de cette phrase, il aurait fallu les écrire entre accolades ou bien utiliser la primitive \idx\ ou utiliser la macro \idx\space. Ce sont des artifices que l'on n'utilise jamais dans une phrase tapée naturellement, sauf éventuellement après une séquence de contrôle, comme ici après \verb|\TeX|.
\grandsaut

Voici un autre exemple. On pourrait aussi vouloir écrire une macro et pouvoir l'appeler avec une \emph{variante}. Le moyen le plus communément utilisé pour signifier que l'on souhaite la variante est d'écrire une étoile juste après le nom de la macro. À charge pour la macro de tester si l'étoile est présente ou pas et d'adopter deux comportements différents selon le cas. En l'état actuel de nos connaissances, nous sommes obligés de lire l'argument qui suit afin de le tester pour déterminer si cet argument est une étoile.

Appelons §\expo une macro sans argument qui, appelée seule, produit l'exposant «${}^{\dag}$» et, appelée étoilée (\verb|\expo*|), affiche l'exposant «${}^{\ddag}$»\idx*{macro étoilée}. Le signe «$\dag$» s'obtient avec la macro \idx\dag tandis que «$\ddag$» s'obtient avec \idx\ddag, ces macros devant opérer en mode mathématique\idx*{mode!mathématique}.

Nous allons donc définir §\expo comme une macro admettant un argument :

\begin{itemize}
	\item si c'est une étoile, afficher «\verb|$^\dag$|»;
	\item si ce n'est pas une étoile, afficher «\verb|$^\ddag$|» et \emph{réécrire l'argument lu}.
\end{itemize}

\showcode|\catcode`\@11
\edef\star@macro{\string *}% stocke une étoile de catcode 12
\def\expo#1{%¤§*\expo¤
	\def\temp@arg{#1}% stocke l'argument lu
	\ifx\star@macro\temp@arg\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{% si l'argument est une étoile de catcode 12¤\idx*{catcode!12\space(autre)}¤
		$^\dag$% affiche une dague
		}% sinon
		{$^\ddag$% affiche une double dague
		{#1}% puis ré-écrit l'argument {#1}¤\defline\aaa¤
		}%
}
A\expo B\expo*C¤§*\expo¤|

Bien que cela \emph{semble} fonctionner, on va tout droit à la catastrophe si on écrit :

\centrecode/A\expo \def\foo{BAR}/

\noindent En effet, à la ligne \no\aaa, en réécrivant l'argument \verb|#1|, \emph{on le met entre accolades}. Et donc ici, §\expo prendrait \verb|\def| comme argument. Ce \verb|\def| se retrouverait \emph{seul} entre accolades ce qui, lors de son exécution, déclencherait une erreur du type «\texttt{Missing control sequence.}». Rappelons-nous que \verb|\def| \emph{doit} être suivie d'une séquence de contrôle ou d'un caractère actif. On pourrait penser s'en sortir en réécrivant \verb|#1| à la ligne \no\aaa{}, c'est-à-dire sans entre accolades. Mais avec cette modification, si on écrit

\centrecode-A\expo {<code dans le groupe>}-

\noindent alors, le \verb|<code dans le groupe>| ne sera justement plus dans un groupe puisque dépouillé des accolades par la macro §\expo lorsqu'elle le réécrit. Avec les conséquences que l'on sait : toutes les assignations que l'utilisateur pensait confinées dans le groupe seraient désormais de portée globale !

Toute la difficulté vient du fait qu'une macro qui lit un argument ne \emph{peut pas savoir} si cet argument est enveloppé dans des accolades ou pas, notamment lorsque l'argument est un token unique. Ainsi, que l'on écrive «\verb|\foo A|» ou «\verb|\foo{A}|», la macro \verb|\foo| lit dans les deux cas l'argument «\verb|A|» et ne peut pas déterminer s'il était entre accolades ou pas.
\grandsaut

Pour résumer, la lecture d'arguments est défectueuse sur deux points essentiels :
\begin{itemize}
	\item les espaces ne sont pas vus comme des arguments et sont ignorés (sauf si l'utilisateur les a délibérément mis entre accolades);
	\item il est impossible pour une macro de faire la différence entre l'argument «\verb|{x}|» et l'argument «\verb|x|» où \verb|x| est un token quelconque (de catcode civilisé tout de même) autre qu'un espace.
\end{itemize}
\medbreak

Ces deux défauts rendent bien trop imprécise la lecture d'un texte quelconque \emph{argument par argument} en vue d'effectuer une action pour chaque argument lu. Heureusement, on peut lire du code \emph{token par token}. Voyons comment\ldots

\chapter{Lire du code token par token}
Un petit rappel s'impose concernant la primitive \idx\let vue à partir de la page~\pageref{let}. Nous savons qu'elle agit au niveau des tokens. Sa syntaxe est la suivante :

\centrecode-\let\<macro>= <token>-

\noindent Et à la suite de cette assignation, la \verb|\<macro>| (qui peut être un caractère actif) devient un alias pour le \verb|<token>|. Rappelons également que le test \verb|\ifx| se fait modulo la \idx\let-égalité.

\section{Reprendre la main après un \ttfamily \textbackslash let}
Comment construire une macro §\readtok qui lit le \verb|<token>| qui la suit et qui l'assigne avec \verb|\let| à \verb|\nxttok| ?

La chose n'a rien de compliqué, il suffit de commencer l'assignation avec \idx\let à l'intérieur du texte de remplacement de la macro pour que le \verb|<token>| soit lu à l'extérieur. Il est important d'écrire la syntaxe \emph{complète} de \idx\let dans le texte de remplacement, c'est-à-dire faire suivre \verb|\let\nxttok| de «\verb*|= |». Si par exemple, le \verb|<token>| est «\verb|=|», cette man\oe uvre nous assure que ce signe \verb|=| n'est pas compris comme faisant partie prenante de la syntaxe de \idx\let et soit perdu pour l'assignation. Voici comment on pourrait programmer la macro §\readtok :

\centrecodespc|\def\readtok{\let\nxttok= }|§*\readtok

En procédant de cette façon, même si la macro est suivie d'un signe égal comme dans «\verb|\readtok=|», ce signe égal sera bien assigné à \verb|\nxttok|. Le problème est cependant évident : la macro lit bien un \verb|<token>| et l'assigne à \verb|\nxttok|, mais \emph{c'est tout} ! Après cette action, la macro s'achève. Pour reprendre la main après l'assignation afin d'appeler une autre macro \verb|\cmptok| chargée d'analyser le \verb|<token>| lu, nous sommes bloqués. En effet, si nous voulons appeler une macro \verb|\cmptok| après l'assignation, il serait absurde d'écrire

\centrecodespc-\def\readtok{\let\nxttok= \cmptok}-§*\readtok

\noindent car cela reviendrait à rendre \verb|\nxttok| égal à \verb|\cmptok| et pour le coup, la macro §\readtok ne lirait rien du tout. On peut tourner le problème dans tous les sens, «\verb*|\let\nxttok= |» \emph{doit} se trouver à la toute fin du texte de remplacement de la macro.

\subsection{La primitive \texttt{\char`\\afterassignment}}\label{afterassignment}
Ce cas de figure a été prévu et la primitive \idx\afterassignment permet de s'en sortir.

\begin{regle}
La primitive \idx\afterassignment dont la syntaxe est

\centrecode-\afterassignment<token>-

stocke le \verb|<token>| dans un endroit spécial de la mémoire de \TeX{} pour le placer sur la \idx{pile d'entrée} immédiatement après la prochaine assignation. Cette assignation peut résulter de l'utilisation de primitives déjà vues \verb|\def|, \verb|\gdef|, \verb|\edef|, \verb|\xdef|, \idx\let, \idx\chardef, \idx\mathchardef, ou bien d'une assignation à un registre (de boite, d'entier, de ressort, de dimension, de token), voire après une opération sur un registre d'entier ou de dimension par \idx\advance, \idx\multiply ou \idx\divide.

Si plusieurs \verb|\afterassignment<token>| sont rencontrés avant une assignation, seul le dernier \verb|<token>| est pris en compte.

Lorsque \verb|\afterassignment<token>| est appelé avant \idx\setbox (c'est-à-dire avant l'assignation à un registre de boite), le \verb|<token>| est placé en tout début de boite.
\end{regle}

Tout ceci nous conduit donc à programmer la macro §\readtok ainsi :

\centrecodespc-\def\readtok{\afterassignment\cmptok\let\nxttok= }-§*\readtok

Dès lors, on peut programmer une macro §\boxsentence qui va encadrer chaque token d'une phrase. Il suffira pour la macro \verb|\cmptok|, appelée après chaque assignation, d'encadrer le token lu (dont l'alias est \verb|\nxttok|) et de stopper la récursivité si elle lit un token spécial (nous prendrons ici §\quark) que nous mettrons à la fin de l'argument de §\boxsentence.

\showcode/\def\boxsentence#1{%¤§*\boxsentence¤
	\readtok#1\quark% met le token d'arrêt \quark à la fin de #1¤§*\quark§*\readtok¤
}
\def\readtok{\afterassignment\cmptok\let\nxttok= }¤\idx*\afterassignment§*\readtok¤
\def\cmptok{%
	\unless\ifx\nxttok\quark% si la fin n'est pas atteinte¤\tidx*{unless} §*\quark¤
		\frbox{\nxttok}%  encadrer le token lu¤§*\frbox¤
		\expandafter\readtok% puis aller lire le suivant¤§*\readtok¤
	\fi
}
\frboxsep=1pt \frboxrule=0.2pt ¤§*\frboxsep §*\frboxrule¤
\leavevmode\boxsentence{Programmer en \TeX\ est facile}¤\idx*\leavevmode§*\boxsentence¤/

Nous avons déjà levé un défaut qui existait avec la lecture d'arguments : les espaces ne sont pas ignorés lorsque lus après \idx\let\verb|\<macro>|\verb*|= |.

\subsection{Application : retour sur la permutation circulaire des voyelles}
Reprenons l'exercice de la deuxième partie où l'on effectuait une permutation circulaire sur les voyelles (voir page~\pageref{permutation.voyelles}). Appelons §\permutstart la macro qui marque le début de la zone où cette permutation sera faite et §\permutend la macro qui marque la fin de cette zone.

Pour mener à bien cette permutation, il nous suffit de reprendre l'exemple précédent et tester dans \verb|\cmptok| si le token lu est successivement chacune des voyelles et dans chaque cas, afficher la voyelle suivante. La macro §\permutend sera un \idx{quark} :

\showcode/\def\permutstart{\afterassignment\cmptok\let\nxttok= }¤\idx*\afterassignment§*\permutstart¤
\def\permutend{\permutend}%¤§*\permutend¤
\def\cmptok{%
	\unless\ifx\permutend\nxttok% tant que la fin n'est pas atteinte :¤\tidx*{unless}§*\permutend¤
		\ifxcase\nxttok¤§*\ifxcase¤
		ae% si le token lu est "a", afficher un "e"
		ei io ou uy ya% etc pour les autres lettres
		\elseif¤§*\elseif¤
			\nxttok% si ce n'est aucune voyelle, afficher le token¤\defline\aaa¤
		\endif¤§*\endif¤
		\expandafter\permutstart% aller lire le token suivant
	\fi
}
\permutstart Un "a" puis "e puis "i" ensuite, un "o", un "u" et "y".\permutend¤§*\permutend§*\permutstart¤/

Cela semble fonctionner comme nous l'attendons, mais ce n'est qu'une impression. L'algorithme présente un défaut majeur : à la ligne \no\aaa, il met le token lu tel quel dans le flux de lecture de \TeX. Tout se passe bien tant qu'il ne s'agit que de tokens \emph{indépendants} et n'ayant aucun besoin les uns des autres. Si l'on avait écrit «\verb|\'e|», le token «\idx\'» aurait été lu puis exécuté à la ligne \no\aaa. Comme ce token est une macro qui va lire l'argument suivant pour lui mettre un accent dessus, elle aurait donc capturé le premier \verb|\fi| de la ligne \no\number\numexpr\aaa+1{} avec deux conséquences aussi graves l'une que l'autre :

\begin{itemize}
	\item ce \verb|\fi| capturé par \idx\' n'aurait pas été disponible pour le \verb|\ifx| apparié et donc, l'équilibrage entre les \verb|\ifx| et les \verb|\fi| aurait été rompu en faveur des \verb|\ifx| qui auraient été excédentaires;
	\item l'argument de \idx\' ayant été \verb|\fi| au lieu d'une simple lettre comme elle l'attend. Il est quasi certain que cet argument aurait provoqué une erreur de compilation puisque l'argument \verb|\fi| est un argument «explosif» dès lors qu'il se retrouve dans un test (ce qui est le cas pour la macro \idx\' avec le \idx[!\LaTeX]{format} \LaTeX.).
\end{itemize}

Comme on l'a déjà vu à l'exercice qui mettait les premières lettres de chaque mot en majuscule (lire page~\pageref{exo.majuscules}), il faudrait accumuler dans une variable les tokens au fur et à mesure de leur lecture. Il suffirait ensuite d'appeler cette variable en toute fin du processus. Hélas, une fois que \verb|\nxttok| a été rendu \idx\let-égal au token lu, on ne peut pas\footnote{On pourrait éventuellement penser à \texttt{\string\meaning} mais les cas de figure à envisager sont tellement nombreux que cette man\oe uvre est irréaliste.} savoir \emph{a posteriori} à quel token il a été rendu \idx\let-égal. Certes, on peut le tester, le faire lire par \TeX{}  pour l'afficher, mais on ne peut pas savoir ce à quoi il est égal ! L'affectation avec \idx\let est à sens unique\ldots{} C'est toute la différence entre une \emph{macro} dont le texte de remplacement est facilement accessible (il suffit de la développer) et entre une séquence de contrôle assignée avec \idx\let qui cache soigneusement ce à quoi elle est \idx\let-égale. Impossible donc de faire comme avec une macro, de « développer » la séquence de contrôle \verb|\nxttok| pour l'ajouter à une variable qui collecterait les tokens lus. Il faudra attendre le chapitre suivant pour apprendre comment, avec l'aide d'une autre primitive, procéder différemment.

\subsection{Lecture d'accolades explicites}
Essayons maintenant de corser la difficulté et de parcourir avec \idx\let du code qui contient des accolades explicites (c'est-à-dire des tokens de catcode 1\idx*{catcode!1 (accolade)} et 2). Faisons l'expérience avec le code vu au-dessus, où chaque token est enfermé dans une boite encadrée par la macro §\frbox programmée dans la partie précédente :

\errcode/\def\boxsentence#1{\readtok#1\boxsentence}¤§*\boxsentence§*\readtok¤
\def\readtok{\afterassignment\cmptok\let\nxttok= }
\def\cmptok{%
	%\show\nxttok% à décommenter pour débogage
	\unless\ifx\nxttok\boxsentence
		\frbox{\nxttok}%¤§*\frbox¤
		\expandafter\readtok
	\fi¤§*\readtok¤
}
\frboxsep=1pt \frboxrule=0.2pt ¤§*\frboxsep §*\frboxrule¤
\leavevmode\boxsentence{Pro{gra}mmer en \TeX\ est facile}¤\idx*\leavevmode§*\boxsentence¤/{! You can't use `\string\hrule' here except with leaders.}

Le message d'erreur n'est pas vraiment explicite, mais il est manifeste que quelque chose a mal tourné. Pour avoir un début d'explication, on peut chercher à déboguer ce code. Un simple «\idx\show\verb|\nxttok|» placé tout au début de la macro \verb|\cmptok| écrira dans le \idx[!log]{fichier} \verb|log| ce qu'est \verb|\nxttok| à chaque itération. Voici ce que l'on obtient :% TODO : voir si un saut de page a lieu ici

\centrecode*|> \nxttok=the letter P.
> \nxttok=the letter r.
> \nxttok=the letter o.
> \nxttok=begin-group character {.
> \nxttok=the letter g.
> \nxttok=the letter r.
> \nxttok=the letter a.
> \nxttok=end-group character }.
! You can't use `\hrule' here except with leaders.
To put a horizontal rule in an hbox or an alignment,
you should use \leaders or \hrulefill (see The TeXbook).

! Missing number, treated as zero.
<to be read again>|

Les messages d'erreurs (qui commencent par «\verb|!|») continuent sur plusieurs lignes, seuls les deux premiers ont été retranscrits ici.

Il est donc intéressant de voir que \verb|\nxttok|, accolade ouvrante devenue \emph{implicite} (comme l'est \idx\bgroup) par le truchement de \idx\let, ne provoque pas d'erreur lorsqu'elle seule dans §\frbox. Ainsi donc, §\frbox\verb|{\bgroup}| est valide\ldots{} Mais ce n'est qu'apparent, car l'équilibrage des accolades a été rompu et \TeX{} finirait tôt ou tard par se plaindre d'un «\texttt{Missing \} inserted}». Avant qu'il puisse en arriver là, l'erreur survient lorsque \idx\let enferme dans §\frbox l'accolade fermante explicite devenue implicite. Avant d'aller plus loin, il faut se souvenir que les boites de \TeX{} ont comme propriété que leurs accolades peuvent \emph{aussi} être implicites. À ce titre, les primitives de boites acceptent indifféremment accolades explicites et implicites qui sont donc interchangeables. Pour expliquer l'erreur constatée, voici la définition de §\frbox où son argument \verb|#1| a été remplacé par un \idx\egroup à la ligne \no10 :

{\indencodenumtrue
\small
\indentcode-\def\frbox#1{%¤§*\frbox¤
	\hbox{%
		\vrule width\frboxrule¤\idx*\vrule§*\frboxrule¤
		\vtop{%¤\idx*\vtop¤
			\vbox{%¤\idx*\vbox¤
				\hrule height\frboxrule¤\idx*\hrule¤
				\kern\frboxsep¤\idx*\kern§*\frboxsep¤
				\hbox{%¤\idx*\hbox¤
					\kern\frboxsep
					\egroup% est l'argument #1 de la macro¤\idx*\egroup¤
					\kern\frboxsep
					}%
			}%
			\kern\frboxsep¤\idx*\kern§*\frboxsep¤
			\hrule height\frboxrule¤\idx*\hrule¤
		}%
		\vrule width\frboxrule¤\idx*\vrule§*\frboxrule¤
	}%
}-
}

Le \idx\egroup de la ligne \no10 ferme prématurément la \idx\hbox la plus intérieure (ligne \no8), rejetant hors de celle-ci le \verb|\kern\frboxsep| de la ligne \no11. L'accolade explicite suivante (ligne \no12) ferme la \idx\vbox tandis que l'accolade explicite de la ligne \no13 ferme la \idx\vtop. Par conséquent, \verb|\kern\frboxsep| et \idx\hrule (lignes \no14-15) se trouvent rejetés hors de la \idx\vtop et prennent place dans la \idx\hbox chapeau de la ligne \no2, en mode horizontal interne\idx*{mode!horizontal interne} donc. C'est là que la première erreur survient car \idx\hrule ne peut être employé en mode horizontal\idx*{mode!horizontal}, sauf justement à l'utiliser avec \idx\leaders comme le suggère le message d'erreur.

\grandsaut
Pour en revenir à la lecture d'un code avec \idx\let, on voit donc que les accolades explicites posent un vrai problème puisqu'elles sont derechef transformées par \idx\let en leur « alias » \idx\bgroup ou \idx\egroup qui ne leur est pas équivalent. Là encore, patientons jusqu'au chapitre suivant où une nouvelle primitive nous permettra d'agir \emph{avant} que le token ne soit lu.

\subsection{Retour sur la macro \texttt{\char`\\litterate}}\idx*[|(]{verbatim}
Forts de nos connaissances, nous sommes en mesure d'écrire une variante §\Litterate de la macro §\litterate programmée à la page~\pageref{litterate}. Son action était de désactiver tous les tokens spéciaux de façon à écrire exactement le texte situé entre deux tokens identiques (par exemple «\verb-|-») servant de délimiteurs.

Le défi va être de fabriquer un équivalent de la macro §\litterate mais sans modifier les catcodes. Pour y parvenir et pour rendre tous les tokens lus inoffensifs, il faudra faire en sorte que chaque token du texte lu soit précédé d'un \idx\string.

La première chose à faire est de stocker le délimiteur qui suit §\Litterate. Pour être surs que son catcode est 12,  nous allons le faire précéder d'un \idx\string que nous développerons : la séquence de contrôle \verb|\lim@tok| recevra ce token. Par la suite, lorsque l'on parcourra le texte, si le token lu après avoir été traité par \idx\string est égal à \verb|\lim@tok|, cela signifiera que le deuxième token délimiteur est atteint et qu'il faut cesser la lecture.

\showcode/\catcode`\@11
\def\Litterate{%¤§*\Litterate¤
	\begingroup% ouvrir un groupe
		\tt% et adopter une fonte à chasse fixe¤\idx*\tt¤
		\afterassignment\Litterate@i% après l'assignation, aller à \Litterate@i¤\idx*\afterassignment¤
		\expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token délimiteur¤\idx*\string¤
}
\def\Litterate@i{%
		\afterassignment\Litterate@ii%après avoir lu le prochain token, aller à \Litterate@ii¤\idx*\afterassignment¤
		\expandafter\let\expandafter\nxttok\expandafter=\string% lit le token suivant¤\defline\aaa\idx*\string¤
}
\def\Litterate@ii{%
	\ifx\nxttok\lim@tok% si le token suivant="token délimiteur"
		\endgroup% fermer le groupe et finir
	\else
		\nxttok% sinon, afficher ce token¤\defline\bbb¤
		\expandafter\Litterate@i% et lire le token suivant
	\fi
}
\catcode`\@12
\Litterate|Programmer     en \TeX {} est << facile >> !|¤§*\Litterate¤/

Cela ne fonctionne pas du tout comme on l'attendait :

\begin{itemize}
	\item les espaces sont ignorés ;
	\item la séquence de contrôle \idx\TeX est exécutée.
\end{itemize}

En fait, les deux dysfonctionnements proviennent d'un même mal. L'erreur se trouve à la ligne \no\aaa{} de la macro \verb|\Litterate@i| qui lit le prochain token en développant au préalable \idx\string. Si cette macro s'apprête à lire un espace, alors cet espace est précédé d'un \idx\string et donc, après développement, cet espace reste inchangé. Il va être considéré par \TeX{} comme l'espace facultatif qui vient après le signe «\verb|=|» dans la syntaxe de \idx\let ! Il sera donc ignoré et \verb|\nxttok| sera rendu \idx\let-égal au token suivant, mais sans que ce token ne soit soumis à \idx\string puisque celui-ci a déjà été utilisé par l'espace. Voilà pourquoi la macro \idx\TeX, qui se trouve juste après un espace, n'est pas passée par \idx\string : \verb|\nxttok| est donc devenu un alias pour \idx\TeX et à la ligne \no\bbb, \verb|\nxttok| est exécuté et provoque l'affichage du logo de \TeX.

Pour corriger cette erreur de programmation, dans la macro \verb|\Litterate@i|, il \emph{faut} écrire l'espace après le signe «\verb|=|» et sauter cet espace avec un \idx\expandafter de plus. Mais on ne peut pas écrire :

\centrecodespc|\expandafter\let\expandafter\nxttok\expandafter=\expandafter \string|

\noindent car l'espace serait ignoré puisque précédé par une séquence de contrôle. Au lieu de cet espace \emph{explicite}, il va falloir écrire la macro \idx\space (dont le texte de remplacement est un espace) que nous allons 1-développer après avoir 1-développé \idx\string. Cela conduit à un pont d'\idx\expandafter.

\showcode/\catcode`\@11
\def\Litterate{%¤§*\Litterate¤
	\begingroup% ouvrir un groupe
		\tt% et adopter une fonte à chasse fixe¤\idx*\tt¤
		\afterassignment\Litterate@i% après l'assignation, aller à \Litterate@i¤\idx*\afterassignment¤
		\expandafter\let\expandafter\lim@tok\expandafter=\string% \lim@tok = token délimiteur¤\idx*\string¤
}
\def\Litterate@i{%
	\afterassignment\Litterate@ii% après avoir lu un token, aller à \Litterate@ii
		\expandafter\expandafter\expandafter% 1-développer \string
	\let
		\expandafter\expandafter\expandafter% puis 1-développer \space en " "
	\nxttok
		\expandafter\expandafter\expandafter
	=\expandafter\space\string% et lire le token obtenu¤\idx*\space\idx*\string¤
}
\def\Litterate@ii{%
	\ifx\nxttok\lim@tok% si le token suivant="token délimiteur"
		\endgroup% fermer le groupe et finir
	\else
		\nxttok% sinon, afficher ce token¤\defline\bbb¤
		\expandafter\Litterate@i% et lire le token suivant
	\fi
}
\catcode`\@12
\Litterate|Programmer     en \TeX {} est << facile >> : $~$^_#|¤§*\Litterate¤/

Dernière observation : le résultat n'est pas \emph{exactement} ce qui est entre les délimiteurs. Deux règles de lecture du code s'appliquent toujours :
\begin{itemize}
	\item plusieurs espaces consécutifs sont lus comme un seul;
	\item un espace qui suit une séquence de contrôle est ignoré. Ici, l'espace qui suit la macro \idx\TeX est ignoré.
\end{itemize}

Ces deux règles concernent les espaces, c'est-à-dire les tokens de catcode 10\idx*{catcode!10 (espace)}. Pour les contourner, nous allons devoir légèrement enfreindre la contrainte que nous nous étions donnée : changer le catcode de l'espace à 12 pour que les règles ne s'appliquent plus. Il suffit donc d'écrire

\centrecodespc|\catcode`\ =12 |

\noindent juste après le \idx\begingroup pour que les espaces soient tous affichés.

La conclusion est que §\Litterate fonctionne bien, mais de par l'assignation et le test qu'elle effectue pour chaque token, elle est \emph{beaucoup plus lente} que son homologue §\litterate. Cette dernière ne s'encombrait pas de tant précautions. Une fois les catcodes changés et les \idx{ligature}s désactivées, elle laissait \TeX{} librement lire le texte jusqu'à ce qu'il rencontre le délimiteur de fin qui, rendu actif et \idx\let-égal à \idx\endgroup, redonnait aux tokens spéciaux leur catcode normal et mettait fin au comportement initié par §\litterate\idx*[|)]{verbatim}.

\begin{exercice}
Créer une macro §\letterspace de syntaxe

\centrecode-\letterspace{<dimension de ressort>}{<texte>}-

où le \verb|<texte>| est constitué de tokens de catcode 10, 11 ou 12. L'action de cette macro est d'afficher entre chaque caractère du \verb|<texte>| un ressort dont la dimension est spécifiée dans le premier argument.

\solution
Puisque l'on sait lire un argument token par token, on va largement s'inspirer de ce qui a été fait avec la macro §\Litterate.

\showcode/\catcode`@11
\newskip\ltr@spc¤\idx*\newskip¤
\def\letterspace#1#2{%¤§*\letterspace¤
	\ltr@spc=#1\relax % assigne le ressort
	\letterspace@i#2\letterspace@i% appelle la macro \letterspace@i
}
\def\letterspace@i{%
	\afterassignment\letterspace@ii¤\idx*\afterassignment¤
	\let\nxttok=
}
\def\letterspace@ii{%
	\ifx\nxttok\letterspace@i% si la fin est atteinte
		\unskip% supprimer le dernier ressort qui est de trop¤\idx*\unskip¤
	\else
		\nxttok% afficher le token
		\hskip\ltr@spc\relax% insère le ressort¤\idx*\hskip¤
		\expandafter\letterspace@i% va lire le token suivant
	\fi
}
\catcode`@12
Voici "\letterspace{0.3em}{des lettres espacées}"
et voici "\letterspace{-0.075em}{de la compression}".¤§*\letterspace¤/

Mais attention, si cela fonctionne ici, c'est parce que l'\idx{encodage} du code source de ce livre est \latin et donc, le caractère «\verb|é|» est vu comme un seul token. Si l'\idx{encodage} avait été \utf et le moteur 8 bits, le caractère «\verb|é|», codé sur 2 \idx{octet}s, aurait été vu comme \emph{deux} tokens. Ceux-ci sont inséparables pour former la lettre \verb|é| (le premier est actif et prend le second comme argument). Comme l'algorithme les aurait séparés, on aurait certainement eu une erreur de compilation. Le même problème serait apparu si l'on avait écrit «\idx\'\verb|e|».
\end{exercice}

\begin{exercice}
Inventer un procédé qui permet à une macro §\ifinteger de tester si son argument est un nombre entier. La syntaxe sera :
\centrecode-\ifinterger{<caractères>}{<vrai>}{<faux>}-

\solution
L'idée directrice est de définir un compteur, de faire précéder l'argument de cette macro d'un «\verb|0|» et d'assigner \verb|0#1| au compteur : 

\centrecode-<compteur>=0#1\relax-

Le «\verb|0|» nous assure qu'au moins un caractère servira à former un \verb|<nombre>|. Après cette assignation, il faut aller voir ce qu'il reste jusqu'au \verb|\relax| et qui ne sert pas à la formation du \verb|<nombre>|. S'il ne reste rien, alors la totalité de l'argument était constituée de caractères pouvant entrer dans la composition d'un \verb|<nombre>| et peut donc être assimilée à un entier.

On va rencontrer un petit grain de sable lorsque \verb|#1| commence par le caractère «\verb|-|» car

\centrecode|0-<caractères>|

\noindent sera compris comme le nombre \verb|0| suivi d'autres tokens ne pouvant entrer dans la composition d'un nombre à cause du «\verb|-|». Il faut donc prévoir de tester si \verb|#1| commence par «\verb|-|» à l'aide de la macro §\ifstart vue à la page~\pageref{ifstart} de la troisième partie. Si le test est positif, on se contentera de manger ce signe «\verb|-|» et recommencer avec ce qui reste dans \verb|#1|. Pour éviter qu'un argument vide donne un test §\ifinteger positif, il est préférable de tester si \verb|#1| est vide auquel cas il faut lire l'argument \verb|<faux>|.

\showcode|\catcode`@11
\newcount\test@cnt¤\idx*\newcount¤
\def\ifinteger#1{%¤§*\ifinteger¤
	\ifstart{#1}{-}% si "-" est au début de #1¤§*\ifstart¤
		{\exparg\ifinteger{\gobone#1}% l'enlever et recommencer¤§*\ifinteger§*\exparg¤
		}
		{\ifempty{#1}% sinon, si #1 est vide¤§*\ifempty¤
			\secondoftwo% lire l'argument <faux>
			{\afterassignment\after@number% sinon, après l'assignation, aller à \after@number¤\idx*\afterassignment¤
			\test@cnt=0#1\relax% faire l'assignation
			                   %(\relax termine le nombre et n'est pas mangé)
			}%
		}%
}
\def\after@number#1\relax{% #1 est ce qui reste après l'assignation
	\ifempty{#1}% teste si #1 est vide et lit l'argument <vrai> ou <faux> qui suit¤§*\ifempty¤
}

\catcode`@12
1) \ifinteger{5644}{oui}{non}\qquad
2) \ifinteger{-987}{oui}{non}\qquad
3) \ifinteger{6a87}{oui}{non}\qquad
4) \ifinteger{abcd}{oui}{non}\qquad
5) \ifinteger{-a}{oui}{non}\qquad
6) \ifinteger{-}{oui}{non}\qquad
7) \ifinteger{3.14}{oui}{non}¤§*\ifinteger¤|

Ajoutons que la macro §\ifinteger n'est pas développable, car elle contient trois choses qui ne le sont pas :
\begin{enumerate}
	\item la macro §\ifstart;
	\item l'assignation à un compteur;
	\item la primitive \idx\afterassignment.
\end{enumerate}
\end{exercice}

\subsection{En résumé...}
Prenons le temps de faire le point sur la lecture token par token. Du côté des avantages :

\begin{itemize}
	\item les espaces sont bien lus ;
	\item il est possible de faire un test sur chaque token après qu'il ait été lu.
\end{itemize}

Et du côté des défauts: 

\begin{itemize}
	\item lorsqu'un token a été lu et assigné à une séquence de contrôle par \idx\let, on ne peut plus savoir quel était le token lu. Par conséquent, il est impossible d'ajouter ce token à une variable cumulative que l'on pourrait développer à la fin, hors de toute récursivité. Si l'on veut afficher le token lu, on doit mettre la séquence de contrôle qui lui est \idx\let-égale dans le flux de lecture pendant la boucle récursive ce qui, on l'a vu, peut entrainer des problèmes lorsque des tokens sont des macros nécessitant un ou plusieurs arguments ;
	\item les tokens de catcode 1\idx*{catcode!1 (accolade)} et 2 («\verb|{|» et «\verb|}|») sont dénaturés par une assignation via \idx\let et deviennent \idx\bgroup et \idx\egroup.
\end{itemize}

La conclusion est sans appel : la lecture token par token souffre de défauts qui la rendent bien peu commode. La suite va certainement adoucir cette conclusion\ldots{}

\section{Lire un token sans avancer la tête de lecture}
Le titre ci-dessus a de quoi surprendre puisqu'on a considéré jusqu'à présent que toute lecture entrainait l'inévitable avancée de la tête de lecture de \TeX{} ! Il y a eu là un petit mensonge par omission puisqu'il y a une seule exception à cette règle.

\begin{regle}
La primitive \idx\futurelet a la syntaxe suivante :

\centrecode-\futurelet\<macro><token1><token2>-

L'effet est le suivant :

\begin{enumerate}
	\item \TeX{} effectue l'action «\verb*|\let\<macro>= <token2>|» (en figeant le catcode de \verb|<token2>|);
	\item puis la tête de lecture avance jusqu'à \verb|<token 1><token2>| qui restent intacts, comme s'ils n'avaient pas été lus.
\end{enumerate}

Il y a comme un air de ressemblance avec \idx\expandafter sauf qu'il n'est pas question de développement, mais d'assignation via \idx\let : il y a bien le «saut» de \verb|<token1>| pour faire une assignation sans que la tête de lecture ne bouge. Tout se passe comme si \TeX{} allait lire le \verb|<token2>| pour le \emph{copier} juste après \verb|\<macro>| pour effectuer une assignation avec un \idx\let. Et donc, le code

\centrecode-\futurelet\<macro><token1><token2>-\idx*\futurelet

\noindent est équivalent à

\centrecode-\let\<macro>= <token2><token1><token2>-
\end{regle}

Assurément, \idx\futurelet est une primitive formidable car elle va régler tous nos problèmes. En effet, si le texte de remplacement d'une \verb|\<macro>| se termine par

\centrecode-\futurelet\nxttok\testtok-\idx*\futurelet

\noindent alors, le token se trouvant juste après cette \verb|\<macro>| sera lu et stocké dans \verb|\nxttok|, mais la tête de lecture n'aura pas bougé et ce token qui se trouve hors de la macro restera intact\footnote{En particulier, les accolades explicites restent explicites et ne sont pas transformées en leurs alias \texttt{\string\bgroup} ou \texttt{\string\egroup}.}. Il suffira que la macro \verb|\testtok| teste ce token pour décider l'action à faire. Cette primitive permet donc de prévoir (d'un token) le futur, c'est sans doute pourquoi elle s'appelle \idx\futurelet et non pas \verb|\letafter|.
\grandsaut

Voici comment programmer une macro §\teststar dont le comportement va changer selon qu'elle est immédiatement suivie d'une étoile ou non : la version \emph{normale} composera l'argument en italique et la version \emph{étoilée}\idx*{macro étoilée} en gras. Clairement, un \idx\futurelet sera utilisé pour savoir si le token qui suit immédiatement §\teststar est une étoile; la macro qui sera chargée de tester ce token est \verb|\teststar@i| :

\showcode|\catcode`\@11
\def\teststar{%¤§*\teststar¤
	\futurelet\nxttok\teststar@i% % pioche le token suivant puis aller à \teststar@i¤\idx*\futurelet¤
}
\def\teststar@i{%
	\ifx *\nxttok\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{% si le token suivant est une étoile
		\afterassignment\teststar@bf% après avoir lu "*", aller à \teststar@bf¤\idx*\afterassignment¤
		\let\nxttok= % lire l'étoile
		}% si le token n'est pas une étoile
		{\teststar@it% aller à \teststar@it
		}%
}
\def\teststar@bf#1{{\bf#1}}% lit l'argument et le compose en gras dans un groupe¤\idx*\bf¤
\def\teststar@it#1{{\it#1\/}}% lit l'argument et le compose en italique¤\idx*\it\idx*[ (correction d'italique)]\/¤
\catcode`\@12
Un essai \teststar{réussi} et un essai \teststar*{étoilé} réussi aussi.¤§*\teststar¤|

Il serait plus intéressant de programmer une macro à caractère généraliste «§\ifnexttok» dont la syntaxe serait :

\centrecode-\ifnexttok<token>{<code vrai>}{<code faux>}-

\noindent que l'on placerait à la fin du texte de remplacement d'une macro et qui irait tester le prochain token extérieur à la macro non égal à un espace. Le \verb|<code vrai>| serait exécuté s'il est égal à \verb|<token>| et \verb|<code faux>| sinon.

Pour savoir si le token lu est un espace, nous le comparerons à §\sptoken défini à la page~\pageref{sptoken}. Profitons-en pour découvrir une autre façon (parmi beaucoup d'autres) de définir §\sptoken avec une macro §\deftok :

\showcode|\catcode`@11
\def\deftok#1#2{\let#1= #2\empty}% définit le token #1 (\empty au cas où #2 est vide)¤§*\deftok¤
\deftok\sptoken{ }¤§*\sptoken¤
\def\ifnexttok#1#2#3{% lit les 3 arguments : #1=token #2=code vrai #3=code faux¤§*\ifnexttok¤
	\deftok\test@tok{#1}% stocke le token cherch餧*\deftok¤
	\def\true@code{#2}\def\false@code{#3}% et les codes à exécuter
	\ifnexttok@i% aller à la macro récursive
}
\def\ifnexttok@i{%
	\futurelet\nxttok\ifnexttok@ii% piocher le token d'après et aller à \ifnexttok@ii¤\idx*\futurelet¤
}
\def\ifnexttok@ii{%
	\ifx\nxttok\sptoken% si le prochain token est un espace¤§*\sptoken¤
		\def\donext{%
			\afterassignment\ifnexttok@i% recommencer après¤\idx*\afterassignment¤
			\let\nxttok= % après avoir absorbé cet espace
		}%
	\else
		\ifx\nxttok\test@tok% si le prochain token est celui cherché
			\let\donext\true@code% exécuter le code vrai
		\else
			\let\donext\false@code% sinon code faux
		\fi
	\fi
	\donext% faire l'action décidée ci-dessus
}
\catcode`@12
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }a.\par
\ifnexttok *{je vais lire une étoile : }{je ne vais pas lire une étoile : } *.\par
\ifnexttok *{je vais lire une étoile : }{je ne vais pas lire une étoile : }a.¤§*\ifnexttok¤|

Cela fonctionne bien comme on l'attend notamment à l'avant-dernière ligne où l'étoile est séparée de l'accolade fermante par un espace. Le test est pourtant positif ce qui montre que les espaces sont bien ignorés.

\begin{exercice}
Comment pourrait-on modifier la macro §\ifnexttok pour lui donner une option afin de choisir d'ignorer les espaces ou pas ?
\solution
Le plus simple est de définir un booléen \verb|\iftestspace| que l'on mettrait à faux par défaut et à vrai si l'on se trouve dans des conditions où l'on veut prendre en compte les espaces.

\showcode|\catcode`@11
\newif\iftestspace \testspacefalse¤\idx*\newif¤
\def\deftok#1#2{\let#1= #2}\deftok\sptoken{ }¤§*\deftok §*\sptoken¤
\def\ifnexttok#1#2#3{% #1=token #2=code vrai #3=code faux¤§*\ifnexttok¤
	\let\test@tok= #1% stocke le token à tester
	\def\true@code{#2}\def\false@code{#3}% et les codes à exécuter
	\iftestspace \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@ii}%¤\idx*\futurelet¤
	\else        \def\ifnexttok@i{\futurelet\nxttok\ifnexttok@iii}%¤\idx*\futurelet¤
	\fi% après avoir défini la macro récursive selon le booléen,
	\ifnexttok@i% l'exécuter
}
\def\ifnexttok@ii{% macro "normale" qui ne teste pas les espaces
	\ifx\nxttok\test@tok \expandafter\true@code% exécuter le code vrai
	\else                \expandafter\false@code% sinon code faux
	\fi
}
\def\ifnexttok@iii{% macro qui ignore les espaces
	\ifx\nxttok\sptoken% si le prochain token est un espace¤§*\sptoken¤
		\def\donext{%
			\afterassignment\ifnexttok@i% lire le token d'après¤\idx*\afterassignment¤
			\let\nxttok= % après avoir absorbé l'espace
		}%
	\else
		\let\donext\ifnexttok@ii% sinon, faire le test "normal"
	\fi
	\donext% faire l'action décidée ci-dessus
}
\catcode`@12
\testspacefalse
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : } W.\medbreak
\testspacetrue
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : }W.\par
\ifnexttok W{je vais lire un W : }{je ne vais pas lire un W : } W.¤§*\ifnexttok¤|
\end{exercice}

Élaborons à présent une macro §\ifstarred qui permettrait de tester, lorsque placée à la fin du texte de remplacement d'une macro, si cette dernière est étoilée ou pas et agir en conséquence\idx*{macro étoilée}. La syntaxe serait :

\centrecode-\ifstarred{<code vrai>}{<code faux>}-

Gardons en mémoire qu'en cas de test positif avec §\ifnexttok, l'étoile n'est pas mangée. Il faut donc trouver un moyen de manger cette étoile et le plus simple est d'utiliser \verb|\firstoftwo| où le premier argument sera \verb|<code vrai>| et le second l'étoile, non encore lue.

\centrecode/\def\ifstarred#1#2{% #1=code vrai  #2=code faux¤§*\ifstarred¤
	\ifnexttok *% si le prochain token est une étoile¤§*\ifnexttok¤
		{\firstoftwo{#1}}% le 2e argument de \firstoftwo est "*"
		{#2}% sinon, exécuter le code faux
}/

Comme l'argument \verb|{#2}| figure une seule fois dans la macro en dernière position, nous pouvons nous permettre de ne pas l'écrire dans le texte de remplacement de §\ifstarred. Au risque d'être bien moins compréhensible, le code peut donc se simplifier en :

\centrecode-\def\ifstarred#1{\ifnexttok*{\firstoftwo{#1}}}-

\showcode|\def\ifstarred#1{\ifnexttok*{\firstoftwo{#1}}}¤§*\ifstarred§*\ifnexttok¤
\catcode`\@11
\def\teststar{\ifstarred{\teststar@bf}{\teststar@it}}¤§*\ifstarred§*\teststar¤
\def\teststar@bf#1{{\bf#1}}¤\idx*\bf¤
\def\teststar@it#1{{\it#1\/}}¤\idx*\it\idx*[ (correction d'italique)]\/¤
\catcode`\@12

Un essai \teststar{réussi} et un essai \teststar*{étoilé} réussi aussi.¤§*\teststar¤|

\section{Parser du code}\label{parser.code}\idx*[|(]{parser du code}
\subsection{La macro \texttt{\char`\\parse}}§*\parse[|(]
L'utilisation conjointe de \idx\futurelet et de la lecture d'arguments est la méthode qu'il nous faut pour parcourir et analyser du code (l'anglicisme \emph{parser du code} est souvent employé). Inventons une syntaxe simple :§*\parse

\centrecode-\parse<code à parser>\parsestop-§*\parsestop

\noindent Le bond en avant que permet \idx\futurelet est de savoir, avant de l'avoir absorbé, si le token qui suit dans le code est un token « à problème » comme le sont l'espace et l'accolade ouvrante. Le principe va être de parcourir le code et selon ce que l'on rencontre, ajouter des tokens au fur et à mesure dans un collecteur (qui sera un registre de tokens \verb|\code@toks|).

Nous allons nous fixer comme objectif que si le \verb|<code à parser>| contient un texte entre accolades, celui-ci sera ajouté tel quel au collecteur. En revanche, pour les autres tokens y compris l'espace, un test sera fait et selon le token rencontré, on pourra choisir ce que l'on ajoute au collecteur. Cela implique qu'un test sera effectué à chaque itération sur le prochain token non encore absorbé.

Voici l'algorithme qui va parser le code :

\begin{algo}
	\item initialiser \verb|\code@toks| à vide;
	\item lire le prochain token \verb|\nxttok| avec \idx\futurelet.
	\item si \verb|\nxttok| est §\parsestop, manger §\parsestop et afficher le collecteur \verb|\code@toks|;
	\item si \verb|\nxttok| est différent de §\parsestop
	\begin{algo}
		\item si \verb|\nxttok| est un espace, manger l'espace et aller en 5 en transmettant «\verb*| |» ;
		\item si \verb|\nxttok| est une accolade ouvrante (qui est vue comme un \idx\bgroup par \idx\futurelet), lire l'argument formé par le texte entre accolades et l'ajouter à \verb|\code@toks| puis retourner en 2;
		\item dans les autres cas, aller en 5 pour lire ce prochain token;
	\end{algo}
	\item tester le token transmis en argument et, selon l'issue du test, ajouter ce que l'on souhaite à \verb|\code@toks| puis, retourner en 2.
\end{algo}

Du point de vue des macros à écrire, le point \no1 est effectué par la macro chapeau §\parse, le point \no2 sera l'affaire d'une macro auxiliaire \verb|\parse@i| et les points \nos3 et 4 seront effectués par la macro \verb|\parse@ii|. Le point \no5 sera une macro \emph{publique} «§\testtoken» à un argument, écrite par l'utilisateur pour y effectuer les tests qu'il souhaite sur l'argument et selon l'issue de ceux-ci, ajouter ce qu'il souhaite au collecteur de tokens.

\label{parse}\showcode|\catcode`\@11
\def\parsestop{\parsestop}% définit la macro-quark se trouvant en fin de code¤§*\parsestop¤
\newtoks\code@toks% registre contenant le code lu¤\idx*\newtoks¤
\def\parseadd{\addtotoks\code@toks}¤§*\addtotoks¤
\def\parse{%¤§*\parse¤
	\code@toks={}% initialise \code@toks à vide
	\parse@i% et passe la main à \parse@i
}
\def\parse@i{\futurelet\nxttok\parse@ii}% lit le prochain token et va à \parse@ii¤\idx*\futurelet¤
\def\parse@ii{%
	\ifxcase\nxttok¤§*\ifxcase¤
		\parsestop\parsestop@i% si la fin va être atteinte, aller à \parsestop@i¤§*\parsestop¤
		\sptoken\read@space% si un espace va être lu, aller à \read@space¤§*\sptoken¤
		\bgroup\read@bracearg% si une accolade ouvrante  aller à \read@bracearg¤\idx*\bgroup¤
	\elseif¤§*\elseif¤
		\testtoken% dans les autres cas, aller à \testtoken¤§*\testtoken¤
	\endif¤§*\endif¤
}

\def\parsestop@i\parsestop{% la fin est atteinte : manger \parsestop
	\the\code@toks% afficher le registre de tokens¤\idx*\the¤
}
\expandafter\def\expandafter\read@space\space{% manger un espace dans le code¤\idx*\space¤
	\testtoken{ }% et aller à \testtoken¤§*\testtoken¤
}
\def\read@bracearg#1{% l'argument entre accolades est lu
	\parseadd{{#1}}% puis ajouté (entre accolades) tel quel à \code@toks
	\parse@i% ensuite, lire le prochain token
}
\catcode`@12

{\bf Exemple 1 :}
\catcode`@11
\def\testtoken#1{% macro qui teste le token¤§*\testtoken¤
	\ifxcase{#1}¤§*\ifxcase¤
		a{\parseadd{e}}% remplacer a par e
		e{\parseadd{i}}% e par i
		i{\parseadd{o}}% i par o
		o{\parseadd{u}}% o par u
		u{\parseadd{y}}% u par y
		y{\parseadd{a}}% y par a
	\elseif¤§*\elseif¤
		\parseadd{#1}% sinon, ajouter le token tel quel
	\endif¤§*\endif¤
	\parse@i% aller lire le token suivant
}%
\catcode`@12
\parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, corses ou grecques} assez inattendues.¤\defline\aaa\idx*\bf¤
\parsestop\medbreak¤\idx*\medbreak§*\parsestop¤

{\bf Exemple 2 :}¤\idx*\bf¤
\leavevmode \frboxsep=1pt ¤\idx*\leavevmode§*\frboxsep¤
\catcode`@11
\def\testtoken#1{%¤§*\testtoken¤
	\ifxcase{#1}% si #1 est un espace¤§*\ifxcase¤
		{ }{\parseadd{\hskip 0.75em }}% ajouter un espace
		\ {\parseadd{\hskip 0.75em }}
	\elseif¤§*\elseif¤
		\parseadd{\frbox{#1}}% sinon, l'encadrer¤§*\frbox¤
	\endif¤§*\endif¤
	\parse@i}%
\catcode`@12 
\parse Programmer en \TeX\ est facile\parsestop\medbreak¤\idx*\medbreak§*\parsestop¤

{\bf Exemple 3 :}
\catcode`@11
\def\testtoken#1{%¤§*\testtoken¤
	\ifx a#1\parseadd{X}\else\parseadd{#1}\fi% remplace les "a" par des "X"
	\parse@i
}
\catcode`@12
\parse a\bgroup\bf braca\egroup dabra\parsestop¤§*\parse\idx*\bgroup\idx*\egroup§*\parsestop¤|

On le voit, le code entre accolades (ligne \no\aaa) n'a pas été modifié, c'est ce que l'on s'était fixé dans le cahier des charges.

\begin{exercice}
Une zone d'ombre subsiste quant à la séquence de contrôle \idx\bgroup. En effet, une accolade ouvrante explicite sera vue par \idx\futurelet comme \idx\bgroup. Par conséquent, la macro §\parse \emph{ne sait pas distinguer} une accolade ouvrante de la séquence de contrôle \idx\bgroup.

\begin{enumerate}
	\item Décrire ce que contient le registre de tokens \verb|\code@toks| lors de l'exemple \no3.
	\item \Qu elle difficulté se présente si on souhaite parser «\verb|\hbox\bgroup XY\egroup|» ?
	\item Comment peut-on résoudre cette difficulté ?
\end{enumerate}
\solution
Lorsque le token qui doit être lu est \idx\bgroup, la façon dont est programmée \verb|\parse@ii| lui fait croire à tort que ce qui suit est une accolade ouvrante. La macro \verb|\read@bracearg| lit donc l'argument (qui est ici \idx\bgroup) et le met entre accolades. Le registre de tokens contient donc

\centrecode-X{\bgroup}\bf brXcX\egroup dXbrX-
\grandsaut

Pour la question \no2, la réponse est donnée à la question précédente. En effet, si l'on parse

\centrecode|\hbox\bgroup XY\egroup|

le registre de tokens va contenir

\centrecode|\hbox{\bgroup}XY\egroup|

La \idx\hbox va donc contenir un simple \idx\bgroup au lieu du \verb|XY|.
\grandsaut

Répondre à la question \no3 est difficile. Pour résoudre le problème, nous allons tout d'abord construire une macro §\ifbracefirst de syntaxe

\centrecode-\ifbracefirst{<argument>}{<code vrai>}{<code faux>}-§*\ifbracefirst

\noindent qui exécute \verb|<code vrai>| si son \verb|<argument>| commence par une accolade ouvrante (ou tout autre token de catcode 1) et \verb|<code faux>| sinon.

Le simple fait que §\ifbracefirst admette un argument et non un token implique de renoncer à la lecture \emph{au fur et à mesure} du \verb|<texte>| entre §\parse et §\parsestop. Nous sommes contraints de lire la \emph{totalité} de ce qui reste avant §\parsestop et de transmettre cet \verb|<argument>| à §\ifbracefirst.

Pour mener à bien sa mission, cette macro va détokéniser son \verb|<argument>|, n'en garder que le premier token et, avec \idx\catcode, regarder s'il s'agit d'un token ayant un catcode égal à 1. Comme \idx\catcode attend de lire un nombre, un développement maximal est lancé et un pont d'\idx\expandafter détokénise d'abord l'argument \verb|#1| puis en isole le premier token :

\showcode/\catcode`\@11
\def\ifbracefirst#1{%¤§*\ifbracefirst¤
	\ifnum\catcode\expandafter\expandafter\expandafter
		`\expandafter\firstto@nil\detokenize{#1W}\@nil=1 % tester si son catcode est 1¤§*\firstto@nil¤
		\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
}
\catcode`\@12

a) \ifbracefirst{123 456}{vrai}{faux}\qquad
b) \ifbracefirst{\bgroup12\egroup3 456}{vrai}{faux}\qquad
c) \ifbracefirst{{12}3 456}{vrai}{faux}\qquad
d) \ifbracefirst{1{2}3 456}{vrai}{faux}\qquad
\begingroup
\catcode`[=1 \catcode`]=2 % les crochets deviennent des accolades
e) \ifbracefirst[[]123 456][vrai][faux]¤§*\ifbracefirst¤
\endgroup/

Le «\verb|W|», écrit dans l'argument de \idx\detokenize, nous met à l'abri d'une erreur de compilation en cas d'\verb|<argument>| vide. Par ailleurs, comme il est assez improbable que «\verb|W|» ait un catcode 1 lorsque la macro est appelée, un \verb|<argument>| vide donnera un test négatif.

Malgré cela, ce code comporte une erreur de programmation : si l'\verb|<argument>| commence par un espace, cet espace sera ignoré par §\firstto@nil et donc, le test «§\ifbracefirst\verb*|{ {}}|» sera positif. Pour se prémunir de ce bug, il suffit au préalable d'effectuer le test §\ifspacefirst et s'il est positif, agir en conséquence.

\showcode/\catcode`\@11
\def\ifbracefirst#1{% teste si #1 commence par un token de catcode 1¤§*\ifbracefirst¤
	\ifspacefirst{#1}% si #1 commence par un espace¤§*\ifspacefirst¤
		{\secondoftwo}% renvoyer faux
		{\ifnum\catcode\expandafter\expandafter\expandafter
			`\expandafter\firstto@nil\detokenize{#1W}\@nil=1 % tester si son catcode est 1¤§*\firstto@nil¤
			\expandafter\firstoftwo
		\else
			\expandafter\secondoftwo
		\fi
		}%
}

\catcode`\@12
a) \ifbracefirst{}{vrai}{faux}\qquad b) \ifbracefirst{ }{vrai}{faux}\qquad
c) \ifbracefirst{ {}}{vrai}{faux}¤§*\ifbracefirst¤/

Revenons maintenant à la macro \verb|\read@bracearg|. Voici son fonctionnement : tout d'abord, elle rajoute un token (ici \verb|\relax|) avant ce qui reste à parser. Cette précaution évite que ce qui reste ne soit dépouillé des accolades s'il s'agit d'un unique texte entre accolades. Ensuite, elle passe la main à \verb|\read@bracearg@i| dont l'argument, délimité par §\parsestop, est tout ce qui reste à parser. Après avoir ôté le \verb|\relax|, cet argument est testé avec §\ifbracefirst. \label{parsestop.obligatoire}Remarquons que faire de §\parsestop un délimiteur d'argument le rend \emph{obligatoire} dans la syntaxe de §\parse et introduit une contrainte assez forte. Par exemple, il ne sera pas possible de définir une autre séquence de contrôle \idx\let-égale à §\parsestop et utiliser cette macro en lieu et place de §\parsestop.

La macro §\testtoken est réduite à sa plus simple expression : elle ne fait que rajouter le token lu au collecteur de tokens \verb|\code@toks| sans le modifier.

Pour s'assurer que le code est parsé correctement, au lieu d'écrire \verb|\the\code@toks| à la fin du processus, on a écrit «\idx\detokenize\verb-\expandafter{\the\code@toks}-» de façon à afficher le contenu du registre de tokens. On aurait également pu écrire «\idx\showthe\verb|\code@toks|» pour écrire le contenu de ce registre dans le \idx[!log]{fichier} \verb|log|.

Le code ci-dessous ne montre que la macro \verb|\read@bracearg| puisqu'elle seule a été modifiée.

\showcode/\catcode`\@11
\def\parsestop@i\parsestop{% la fin va être atteinte
	\detokenize\expandafter{\the\code@toks}% afficher le contenu du registre¤\idx*[|etc]\the\forbidindex\the¤
}
\def\read@bracearg{%
	\read@bracearg@i\relax% ajoute un \relax avant de passer la main à \read@bracearg@i
}
\def\read@bracearg@i#1\parsestop{% #1 = tout jusqu'à \parsestop¤§*\parsestop¤
	\exparg\ifbracefirst{\gobone#1}% retire le \relax et teste si #1 commence par "{"¤§*\exparg§*\ifbracefirst¤
		{\expandafter\read@bracearg@ii\gobone#1\parsestop}% si oui, aller à \readbrace@ii¤§*\parsestop¤
		{\expandafter\testtoken\gobone#1\parsestop}% sinon, aller à \testtoken¤§*\parsestop§*\testtoken¤
}
\def\read@bracearg@ii#1{% lit l'argument entre accolades
	\parseadd{{#1}}% ajoute cet argument entre accolades
	\parse@i% aller lire le token suivant
}

\def\testtoken#1{%¤§*\testtoken¤
	\parseadd{#1}% ajouter le token tel quel
	\parse@i% aller lire le token suivant
}
\catcode`\@12
\parse a\hbox\bgroup\bf braca\egroup {da}{}b{ra}\parsestop¤\idx*\hbox\idx*\bgroup\idx*\bf\idx*\egroup§*\parsestop¤/%

Comme nous obtenons exactement ce qui est parsé, nous avons l'assurance que la macro \verb|\read@brace| fait désormais correctement son travail.
\end{exercice}

\subsection{Parser aussi l'intérieur des groupes}
Le fait que la macro §\parse n'aille pas voir à l'intérieur des accolades est certes une règle que l'on s'était fixée, mais on pourrait trouver utile d'ajouter une option pour que cette macro pénètre aussi dans les groupes entre accolades. En guise d'option, une étoile sera mise juste après la macro. Pour que l'option soit stockée quelque part, nous créerons un nouveau booléen \verb|\ifparse@groups| que l'on mettra à vrai dans la version étoilée\idx*{macro étoilée} et à faux sinon. Ensuite, on sent bien que le n\oe ud du problème se trouve dans la macro \verb|\read@bracearg|, seul endroit où le parseur s'attend à lire un argument entre accolades.

La macro \verb|\read@bracearg| doit donc être réécrite. Elle testera le booléen et s'il est faux, il faudra qu'elle agisse comme précédemment. S'il est vrai, \verb|\read@bracearg| doit aller parser l'argument \verb|#1| qu'elle a lu. Pour ce faire, elle exécutera ce code \emph{dans un groupe semi-simple} :

\centrecode-\parse*#1\parsestop-§*\parsestop

Une fois que le quark §\parsestop est atteint, il ne faut pas afficher \verb|\code@toks| comme le faisait \verb|\parsestop@i|. La macro \verb|\parsestop@i| doit donc être redéfinie localement afin de lui faire exécuter la chose suivante : ajouter le contenu de \verb|\code@toks| collecté dans le groupe (sans oublier de l'envelopper d'accolades) au contenu de \verb|\code@toks| tel qu'il était à l'extérieur du groupe. Le \verb|\endgroup| fait donc partie prenant de \verb|\parsestop@i|. Afin que cet ajout soit correctement mené à bien, un pont d'\idx\expandafter sera mis en place pour retarder la sortie du groupe et développer au préalable «\verb|\the\code@toks|» qui est l'argument de \verb|\parseadd| :

\centrecode|\expandafter\endgroup% ne fermer le groupe qu'après avoir
\expandafter\parseadd% 1-développé à l'extérieur du groupe
\expandafter{\expandafter{\the\code@toks}}% "\the\code@toks"|

Une fois cette action effectuée, il appartient à \verb|\parsestop@i| de poursuivre le parsing en appelant la macro \verb|\parse@i| qui lira le token suivant.

Voici le code complet :

\label{parse.a}\showcode|\catcode`\@11
\def\parsestop{\parsestop}% définit le quark se trouvant en fin de code¤§*\parsestop¤
\newtoks\code@toks% alloue le registre contenant le code lu¤\idx*\newtoks¤
\def\parseadd#1{\code@toks\expandafter{\the\code@toks#1}}
\newif\ifparse@group¤\idx*\newif¤
\def\parse{%
	\code@toks{}% initialise le collecteur de tokens
	\ifstarred% teste si la macro est étoilée¤§*\ifstarred¤
		{\parse@grouptrue\parse@i}% mettre le booléen à vrai
		{\parse@groupfalse\parse@i}% sinon à faux
}
\def\parse@i{\futurelet\nxttok\parse@ii}% lit le prochain token
                                        % et va à \parse@ii¤\idx*\futurelet¤
\def\parse@ii{%
	\ifxcase\nxttok¤§*\ifxcase¤
		\parsestop\parsestop@i% si la fin va être atteinte, aller à \parsestop@i¤§*\parsestop¤
		\sptoken\read@space% si un espace va être lu, aller à \read@space¤§*\sptoken¤
		\bgroup\read@bracearg% si une accolade ouvrante  aller à \read@bracearg¤\idx*\bgroup¤
	\elseif¤§*\elseif¤
		\testtoken% dans les autres cas, aller à \testtoken¤§*\testtoken¤
	\endif¤§*\endif¤
}
\def\parsestop@i\parsestop{% la fin est atteinte
	\the\code@toks% afficher le registre de tokens
}
\expandafter\def\expandafter\read@space\space{% \read@space mange un espace dans le code¤\idx*\space¤
	\testtoken{ }% et va à \testtoken¤§*\testtoken¤
}
\def\read@bracearg{%
	\read@bracearg@i\relax% ajoute un \relax avant de passer la main à \read@bracearg@i
}
\def\read@bracearg@i#1\parsestop{% l'argument tout jusqu'à \parsestop¤§*\parsestop¤
	\expsecond\ifbracefirst{\gobone#1}% retire le \relax et teste si #1 commence par "{"¤§*\ifbracefirst§*\expsecond¤
		{\expandafter\read@bracearg@ii\gobone#1\parsestop}% lire l'argument entre accolades
		{\expandafter\testtoken\gobone#1\parsestop}% sinon, tester le token¤§*\parsestop§*\testtoken¤
}
\def\read@bracearg@ii#1{% l'argument entre accolades est lu
	\ifparse@group\expandafter\firstoftwo\else\expandafter\secondoftwo\fi% si macro étoilée
		{\begingroup% ouvre un groupe pour parser l'intérieur de l'accolade
			\def\parsestop@i\parsestop{% redéfinir localement \parsestop@i pour
				\expandafter\endgroup% ne fermer le groupe qu'après avoir
				\expandafter\parseadd% 1-développé à l'extérieur du groupe
				\expandafter{\expandafter{\the\code@toks}}%¤\idx\the¤
				\parse@i% puis va lire le token suivant
			}%
			\parse*#1\parsestop% <- le \parsestop@i fermera le groupe semi-simple¤§*\parsestop¤
		}
		{\parseadd{{#1}}% macro non étoilée, on ajoute #1 tel quel entre accolades
		\parse@i% puis va lire le token suivant
		}%
}
\def\testtoken#1{% macro qui teste le token¤§*\testtoken¤
	\ifxcase{#1}¤§*\ifxcase¤
		a{\parseadd{e}}
		e{\parseadd{i}}
		i{\parseadd{o}}
		o{\parseadd{u}}
		u{\parseadd{y}}
		y{\parseadd{a}}
	\elseif¤§*\elseif¤
		\parseadd{#1}%
	\endif¤§*\endif¤
	\parse@i% aller lire le token suivant
}
\catcode`@12
\frboxsep=1pt
a) \parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.¤§*\frbox¤
\parsestop\medbreak¤\idx*\medbreak§*\parsestop¤

b) \parse*
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.¤\idx*\bf§*\frbox¤
\parsestop¤§*\parsestop¤|

\begin{exercice}
Expliquer d'où vient l'espace indésirable devant «Ci» que l'on constate lorsqu'on appelle la \idx{macro étoilée} et proposer un remède pour le supprimer.
\solution

La présence de l'étoile fait que le retour à la ligne qui la suit est interprété comme un espace et n'est pas ignoré puisque dans ce cas, l'espace ne suit pas une séquence de contrôle.

Il va donc falloir tester si un espace suit l'étoile et dans l'affirmative, manger cet espace avant de commencer le processus. Un simple «§\ifnexttok\verb*|{ }|» tester si un espace suit l'étoile et dans l'affirmative, cet espace sera mangé en mettant à la fin du texte de remplacement de la macro :

\centrecodespc-\afterassignment\parse@i\let\nxttok= -

Cette macro devient donc :

\showcode/\catcode`\@11
\def\parse{%
	\code@toks{}% initialise le collecteur de tokens
	\ifstarred¤§*\ifstarred¤
		{\parse@grouptrue
		\ifnexttok{ }% si un espace suit l'étoile¤§*\ifnexttok¤
			{\afterassignment\parse@i% aller à \parse@i¤\idx*\afterassignment¤
			\let\nxttok= }% après l'avoir mangé
			{\parse@i}% sinon, aller à \parse@i
		}
		{\parse@groupfalse
		\parse@i
		}%
}
\def\testtoken#1{% macro qui teste le token¤§*\testtoken¤
	\ifxcase{#1}¤§*\ifxcase¤
		a{\parseadd{e}}e{\parseadd{i}}i{\parseadd{o}}o{\parseadd{u}}
		u{\parseadd{y}}y{\parseadd{a}}
	\elseif¤§*\elseif¤
		\parseadd{#1}%
	\endif¤§*\endif¤
	\parse@i% aller lire le token suivant
}
\catcode`@12
\frboxsep=1pt
a) \parse
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.
\parsestop\medbreak¤\idx*\medbreak§*\parsestop¤
b) \parse*
Ce texte devenu \`a peine reconnaissable montre que le r\'esultat contient des sonorit\'es
{\bf catalanes, \frbox{corses} ou grecques} assez inattendues.¤\idx*\bf§*\frbox¤
\parsestop¤§*\parsestop¤/
\end{exercice}\idx*[|)]{parser du code}§*\parse[|)]

\section{Rechercher, remplacer un ensemble de tokens}
Nous avions déjà écrit la macro §\ifin à la page~\pageref{ifin} qui permettait de savoir si un texte contenait un ensemble de tokens. Nous utilisions des arguments délimités et la limitation qui en découlait était que le motif cherché ne pouvait pas contenir d'accolades. Heureusement, nous allons pouvoir contourner cette difficulté en parcourant le code token par token.

Pour parvenir à nos fins, il nous suffit de programmer une macro capable de tester si un \verb|<texet>| commence par un \verb|<motif>|.

\subsection{Un ensemble de tokens commence-t-il par un motif?}
La fabrication de la macro §\ifstartwith, dont le but est de tester si un \verb|<texte>| commence par un \verb|<motif>| va donc devenir le seul enjeu pour l'instant. En voici la syntaxe :

\centrecode-\ifstartwith{<texte>}{<motif>}{<vrai>}{<faux>}-

Avant d'en arriver à cette macro, la difficulté se concentre dans l'écriture d'une macro auxiliaire qui ampute le premier argument du texte du remplacement d'une \verb|<macro 1>| et le place dans le texte de remplacement de \verb|<macro 2>|. Le mot «argument» doit ici être compris dans un sens \emph{élargi} puisqu'il peut être un texte entre accolades, un unique token ou \emph{un espace}.

Cette macro sera baptisée \verb|\grab@first| et admettra deux arguments qui seront des séquences de contrôle

\centrecode-\grab@first\<macro1>\<macro2>-

\noindent Le principe va consister à tester si le texte de remplacement de \verb|\<macro1>| commence par une accolade et sinon, utiliser \idx\futurelet pour déterminer s'il commence par un espace ou par autre chose. Selon les trois cas envisagés, on s'orientera vers une macro qui lira convenablement le premier argument de \verb|<macro1>| et le déplacera dans \verb|\<macro2>| tout en assignant ce qu'il reste à \verb|\<macro1>|.

\showcode/\catcode`\@11 
\def\grab@first#1#2{%
	\ifx#1\empty\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\let#2\empty% si #1 est vide, ne rien faire et assigner <vide> à #2
		}% si #1 n'est pas vide
		{\def\arg@b{#2}% stocke la macro #2 dans \arg@b
		\exparg\ifbracefirst#1% si le 1er token de #1 est "{"¤\defline\aaa §*\ifbracefirst§*\exparg¤
			{\expandafter\grab@arg#1\@nil#1% aller lire l'argument avec \grab@arg
			}
			{% sinon, développer #1 avant de le regarder avec \futurelet :
			\expandafter\futurelet\expandafter\nxttok\expandafter\test@nxttok#1\@nil#1%¤\defline\bbb\idx*\futurelet¤
			% puis aller à \test@nxttok
			}%
		}%
}
\def\test@nxttok{% si le premier token de l'arg #1 de \grab@first est
	\ifx\nxttok\sptoken% un espace¤§*\sptoken¤
		\expandafter\grab@spc% aller le lire avec \grab@spc
	\else
		\expandafter\grab@tok% sinon, lire le token avec \grab@tok
	\fi
}
\def\grab@arg#1{% assigne l'argument de \grab@first (mis entre accolades)
	\expandafter\def\arg@b{{#1}}% à #2
	\assign@tonil\relax% puis, assigne le reste à #1 de \grab@first
}
\expandafter\def\expandafter\grab@spc\space{%¤\idx*\space¤
	\expandafter\def\arg@b{ }% assigne un espace à #2 de \grab@first
	\assign@tonil\relax% puis, assigne le reste à #1 de \grab@first
}
\def\grab@tok#1{%% assigne le premier token de l'arg #1 de \grab@first
	\expandafter\def\arg@b{#1}% à la macro #2 de \grab@first
	\assign@tonil\relax% puis, assigne le reste à #1 de \grab@first
}
% assigne tout ce qui reste à lire (moins le "\relax") à la macro
% #1 de \grab@first
\def\assign@tonil#1\@nil#2{\expsecond{\def#2}{\gobone#1}}¤§*\expsecond¤
\tt
a) \def\foo{1 {2 3} 4}\grab@first\foo\bar
   "\meaning\bar"\qquad"\meaning\foo"

b) \def\foo{ 1 {2 3} 4}\grab@first\foo\bar
   "\meaning\bar"\qquad"\meaning\foo""

c) \def\foo{{1 2} 3 4}\grab@first\foo\bar
   "\meaning\bar"\qquad"\meaning\foo"/

Revenons sur la macro \verb|\grab@first| et ses macros auxiliaires\ldots{} On constate dans son texte de remplacement que, en plus du cas trivial où \verb|#1| est vide, l'aiguillage se fait en deux temps selon ce par quoi commence le texte de remplacement de la macro \verb|#1|. Le premier test fait concerne l'accolade ouvrante (ligne \no\aaa). Afin d'envisager tous les cas, supposons que le test est vrai : le texte de remplacement de \verb|#1| est de la forme «\verb|{<code a>}<code b>|». L'appel suivant est alors effectué :

\centrecode-\expandafter\grab@arg#1\@nil#1-

\noindent L'\idx\expandafter fait apparaitre ce texte de remplacement puis \verb|\grab@arg| en capture l'argument \verb|<code a>| pour le mettre dans le texte de remplacement de la macro \verb|#2|, après l'avoir rhabillé d'accolades. Une fois ceci fait, il reste à lire le code suivant :

\centrecode-<code b>\@nil#1-

Rappelons-nous de ce code restant et passons maintenant à l'autre éventualité, celle où le texte de remplacement de \verb|#1| ne commence pas par une accolade. Le texte de remplacement de \verb|#1| est de la forme «\verb|<token a><code b>|». Dans ce cas, on passe la main à cette ligne :

\centrecode-\expandafter\futurelet\expandafter\nxttok\expandafter\test@nxttok#1\@nil#1-\idx*\futurelet

\noindent Tout d'abord, un pont d'\idx\expandafter développe la macro \verb|#1| pour faire apparaitre son texte de remplacement ce qui donne

\centrecode-\futurelet\nxttok\test@nxttok<token a><code b>\@nil#1-\idx*\futurelet

Ensuite, le \idx\futurelet va rendre \verb|\nxttok| \idx\let-égal à \verb|<token a>|. La macro \verb|\test@nxttok| est appelée par le \idx\futurelet pour tester ce qu'est \verb|<token a>| et selon qu'il est un espace ou pas, appelle \verb|\grab@spc| ou \verb|\grab@tok|. Ces deux macros capturent le \verb|<token a>| pour le mettre dans le texte de remplacement de \verb|#2| et le code qui reste à lire après cette opération est ici encore :

\centrecode-<code b>\@nil#1-

\Qu e le texte de remplacement de \verb|#1| commence par un argument entre accolades, un espace ou un token, il reste dans tous les cas la même chose à lire

\centrecode|<code b>\@nil#1|

\noindent Le code «\verb|\assign@tonil\relax|» est exécuté à la toute fin de chacune des trois macros \verb|\grab@arg|, \verb|\grab@spc| et \verb|\grab@tok| devant ce code restant de telle sorte que l'on a formé l'appel

\centrecode-\assign@tonil\relax<code b>\@nil#1-

\noindent La macro \verb|\assign@tonil| mange ce \verb|\relax| avec \verb|\assign@tonil| puis assigne à la \verb|\<macro1>| (qui est l'argument \verb|#1|) le \verb|<code b>| et ceci termine le processus. Ouf, nous avons fait le plus dur !
\grandsaut

Ayant construit \verb|\grab@first|, il suffit ensuite pour §\ifstartwith d'extraire le premier argument élargi de \verb|<texte>| et de \verb|<motif>|, de les comparer et renvoyer \verb|<faux>| s'il ne sont pas égaux et dans le cas contraire, recommencer jusqu'à ce que le \verb|<motif>| soit vide. À ce moment-là, comme aucune comparaison n'a été fausse, il faut renvoyer \verb|<vrai>|. Le cas où le \verb|<texte>| devient vide \emph{avant} le \verb|<motif>| doit être envisagé, car cela signifie que le \verb|<texte>| est plus court que le \verb|<motif>| et dans cette éventualité, il faut renvoyer \verb|<faux>|.

\showcode|\catcode`\@11 
\def\ifstartwith#1#2{% #1=<texte>  #2=<motif>¤§*\ifstartwith¤
	\ifempty{#2}¤§*\ifempty¤
		\firstoftwo% si <motif> est vide, renvoyer vrai
		{\ifempty{#1}% si <code> est vide et <motif> non vide¤§*\ifempty¤
			\secondoftwo% renvoyer faux
			{\def\startwith@code{#1}\def\startwith@pattern{#2}%
			\ifstartwith@i% dans les autres cas, aller à \ifstartwith@i
			}%
		}%
}
\def\ifstartwith@i{%
	\grab@first\startwith@code\first@code% extrait le premier "argument" de <texte>
	\grab@first\startwith@pattern\first@pattern% et celui de <motif>
	\ifx\first@code\first@pattern\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{% si les deux arguments élargis sont égaux
		\exparg\ifempty\startwith@pattern¤§*\exparg§*\ifempty¤
			\firstoftwo% et que <motif> ne contient plus rien => vrai
			{\exparg\ifempty\startwith@code¤§*\exparg§*\ifempty¤
				\secondoftwo% si <texte> ne contient plus rien => faux
				\ifstartwith@i% sinon poursuivre les tests
			}%
		}
		\secondoftwo% si les deux argument élargis sont différents, renvoyer faux
}
\catcode`\@12

1) \ifstartwith{a b c}{a b}{oui}{non}\quad 2) \ifstartwith{a b}{a b c}{oui}{non}\quad
3) \ifstartwith{ 123 }{ }{oui}{non}\quad   4) \ifstartwith{ 123 }{1}{oui}{non}\quad
5) \ifstartwith{1{2} 3}{12}{oui}{non}\quad 6) \ifstartwith{1{2} 3}{1{2} }{oui}{non}\quad
7) \ifstartwith{{} {}}{ }{oui}{non}\quad   8) \ifstartwith{{} {}}{{} }{oui}{non}\quad
9) \ifstartwith{ {12} a}{ }{oui}{non}\quad10) \ifstartwith{ {12} a}{ {1}}{oui}{non}¤§*\ifstartwith¤|

\subsection{Un code contient-il un motif ?}
Puisque nous avons à notre disposition la macro §\ifstartwith qui sera la brique essentielle pour la suite, poursuivons avec la macro §\ifcontain dont la syntaxe est

\centrecode-\ifcontain{<texte>}{<motif>}{<vrai>}{<faux>}-

\noindent et qui renverra \verb|<vrai>| si le \verb|<texte>| contient le \verb|<motif>| et \verb|<faux>| sinon.

L'algorithme le plus naïf, que nous allons utiliser, consiste à tester si \verb|<motif>| est au début du \verb|<texte>|. Dans l'affirmative, il faut renvoyer \verb|<vrai>| et dans le cas contraire, manger le premier «argument élargi» de \verb|<texte>| et recommencer jusqu'à ce que \verb|<texte>| soit vide auquel cas, on renvoie \verb|<faux>|.

\showcode|\catcode`\@11
\def\ifcontain#1#2{% #1 contient-il #2?¤§*\ifcontain¤
	\def\main@arg{#1}\def\pattern@arg{#2}% stocke le <code> et le <motif>
	\ifempty{#2}¤§*\ifempty¤
		\firstoftwo% si #2 est vide => vrai
		{\ifempty{#1}
			\secondoftwo% si #1 est vide et pas #2 => faux
			\ifcontain@i% sinon, aller faire les tests
		}%
}
\def\ifcontain@i{%
	\exptwoargs\ifstartwith\main@arg\pattern@arg¤§*\exptwoargs§*\ifstartwith¤
		\firstoftwo% si motif est au début de code => vrai
		{\exparg\ifempty\main@arg¤§*\exparg§*\ifempty¤
			\secondoftwo% sinon, si code est vide => faux
			{\grab@first\main@arg\aux@arg% autrement, manger le 1er "argument" de code
			\ifcontain@i% et recommencer
			}%
		}%
}
\catcode`\@12
1) \ifcontain{abc def}{c }{oui}{non}\quad  2) \ifcontain{abc def}{cd}{oui}{non}\quad
3) \ifcontain{12 34 5}{1 }{oui}{non}\quad  4) \ifcontain{12 34 5}{ }{oui}{non}\quad
5) \ifcontain{a{b c}d}{b c}{oui}{non}\quad 6) \ifcontain{a{b c}d}{{b c}}{oui}{non}\quad
7) \ifcontain{{} {}}{ }{oui}{non}\quad     8) \ifcontain{{} {}}{{}}{oui}{non}¤§*\ifcontain¤|

On le voit au cas \no5, la macro §\ifcontain n'inspecte pas l'intérieur des groupes et donc, elle considère que le motif «\verb*|b c|» n'est pas contenu dans «\verb*|a{b c}d|». On pourrait souhaiter que la macro §\ifcontain aille aussi voir à l'intérieur des groupes lorsqu'elle est étoilée\idx*{macro étoilée}. Pour ajouter cette fonctionnalité, il va falloir modifier la macro \verb|\ifcontain@i| pour qu'elle teste si \verb|\main@arg| commence par une accolade ouvrante et dans ce cas, agir différemment.

Voici l'algorithme que l'on pourrait suivre :

\begin{algo}
	\item si \verb|<motif>| est vide, renvoyer \verb|<vrai>|, sinon, si \verb|<texte>| est vide, renvoyer \verb|<faux>|. Si aucun n'est vide, aller au point \no2;
	\item initialiser le booléen \verb|\ifin@group| à faux;
	\item si \verb|<texte>| commence par «\verb|{|»
	\begin{algo}
		\item enlever le premier argument de \verb|<texte>| et le mettre dans une macro temporaire \verb|\aux@arg|;
		\item ouvrir un groupe semi-simple;
		\item initialiser le booléen \verb|\ifin@group| à \verb|vrai|;
		\item dans ce groupe, prendre \verb|<texte>| égal à \verb|\aux@arg|;
		\item aller au point 3.
	\end{algo}
	\item sinon
	\begin{algo}
	\item si \verb|<motif>| est au début de \verb|<texte>| sortir de tous les groupes et renvoyer \verb|<vrai>|\label{sortir.tous.les.groupes};
	\item sinon
		\begin{algo}
			\item si \verb|<texte>| est vide
			\begin{algo}
				\item si \verb|\ifin@group| est \verb|vrai| sortir du groupe semi-simple et aller en 3;
				\item sinon renvoyer \verb|<faux>|;
			\end{algo}
			\item sinon retirer le premier argument élargi de \verb|<texte>| et aller en 3.
		\end{algo}
	\end{algo}
\end{algo}

Distribuons les tâches. Les points 1 et 2 seront traités par une macro chapeau comme auparavant. Les points 3 et 4 seront écrits dans une macro récursive \verb|\ifcontain@star| alors que la macro récursive \verb|\ifcontain@nostar|, vue précédemment sous le nom de \verb|\ifcontain@i| sera employée dans le cas ou §\ifcontain n'est pas étoilé\idx*{macro étoilée}.

Pour le point \ref{sortir.tous.les.groupes}, nous devons également écrire une macro \verb|\return@true| qui ferme tous les groupes et qui renvoie \verb|<vrai>|. Le booléen \verb|\ifin@group| rend la tâche facile puisqu'il est localement \verb|vrai| dans tous les groupes et faux à l'extérieur. Une simple macro récursive qui ferme successivement les groupes jusqu'à ce que le booléen soit faux est suffisante :

\centrecode-\def\return@true{%
	\ifin@group% si on est dans un groupe
		\endgroup% le fermer
		\expandafter\return@true% et recommencer
	\else
		\expandafter\firstoftwo% sinon, renvoyer vrai
	\fi
}-

Voici le code complet qui en résulte :

\showcode|\catcode`@11
\newif\ifin@group¤\idx*\newif¤
\def\ifcontain{%¤§*\ifcontain¤
	\ifstarred¤§*\ifstarred¤
		{\in@groupfalse\ifcontain@i\ifcontain@star}%
		{\ifcontain@i\ifcontain@nostar}}

\def\ifcontain@i#1#2#3{% #1 = macro à appeler selon étoile ou pas. #2 = code. #3 = motif
	\def\main@arg{#2}\def\pattern@arg{#3}%
	\ifempty{#3}¤§*\ifempty¤
		\firstoftwo
		{\ifempty{#2}¤§*\ifempty¤
			\secondoftwo
			#1% aller à \ifcontain@star ou \ifcontain@nostar
		}%
}
\def\ifcontain@nostar{%
	\exptwoargs\ifstartwith\main@arg\pattern@arg¤§*\exptwoargs§*\ifstartwith¤
		\firstoftwo% si motif est au début de code => vrai
		{\exparg\ifempty\main@arg¤§*\ifempty§*\exparg¤
			\secondoftwo% sinon, si code est vide => faux
			{\grab@first\main@arg\aux@arg% autrement, manger le 1er "argument" de code
			\ifcontain@nostar% et recommencer
			}%
		}%
}
\def\ifcontain@star{%
	\expandafter\ifbracefirst\expandafter{\main@arg}% si code commence par "{"¤§*\ifbracefirst¤
		{\grab@first\main@arg\aux@arg% enlever {<argument>} de main@arg
		\begingroup% ouvrir un groupe
			\in@grouptrue% mettre le booléen à vrai
			\expandafter\def\expandafter\main@arg\aux@arg% assigner "argument" à \main@arg
			\ifcontain@star% et recommencer avec ce nouveau \main@arg
		}% si code ne commence pas par "{"
		{\exptwoargs\ifstartwith\main@arg\pattern@arg% si motif est au début de code¤§*\exptwoargs§*\ifstartwith¤
			\return@true% renvoyer vrai
			{\expandafter\ifempty\expandafter{\main@arg}% si code est vide¤§*\ifempty¤
				{\ifin@group% et que l'on est dans un groupe
					\endgroup \expandafter\ifcontain@star% en sortir et recommencer
				\else% si on n'est pas dans un groupe, le code a été parcouru
					\expandafter\secondoftwo% sans trouver <motif> => renvoyer faux
				\fi
				}% si code n'est pas vide
				{\grab@first\main@arg\startwith@code% manger le 1er "argument" de code
				\ifcontain@star% et recommencer
				}%
			}%
		}%
}
\def\return@true{%
	\ifin@group% tant qu'on est dans un groupe
		\endgroup \expandafter\return@true% en sortir et recommencer
	\else
		\expandafter\firstoftwo% sinon, renvoyer vrai
	\fi
}
\catcode`@12
1) \ifcontain{ab {c d}ef}{c}{oui}{non}\quad 2) \ifcontain*{ab {c d}ef}{c}{oui}{non}¤§*\ifcontain¤|

\subsection{Remplacer un motif par un autre}\label{substitute}§*\substitute[|(]
Il nous reste une dernière étape, celle de remplacer dans \verb|<texte>| un \verb|<motif a>| par un \verb|<motif b>|. La syntaxe naturelle pour une telle macro est :

\centrecode-\substitute{<texte>}{<motif a>}{<motif b>}-

La recette est connue; il nous suffit de reprendre une méthode similaire à celle de la macro §\ifcontain (en version étoilée\idx*{macro étoilée} ou pas) et si le \verb|<texte>| restant à lire commence par le \verb|<motif>|, on ajoutera à un registre de tokens tenant lieu de collecteur le \verb|<motif b>|. Dans le cas contraire, il faudra ajouter à ce même registre le premier argument élargi du \verb|<texte>|.

Comme il n'est pas question de fermer tous les groupes d'un coup, nous allons nous passer du booléen \verb|\ifin@group| en définissant une macro de fin de processus \verb|\substitute@end| qui sera appelée lorsque \verb|<texte>| sera vide. Ce \verb|<texte>| est vide dans deux situations; soit la totalité du texte initial a été parsée, soit nous sommes dans un groupe et le \verb|<texte>| local est parsé. En dehors de tout groupe ou pour la macro non étoilée\idx*{macro étoilée}, la macro \verb|\substitute@end| se contentera d'afficher le contenu du registre de tokens \verb|\subst@toks| :

\centrecode-\def\substitute@end{\the\subst@toks}-

En revanche, lorsque la macro est étoilée\idx*{macro étoilée} et que l'on inspecte un groupe, cette macro sera modifiée de la même façon qu'était modifiée la macro \verb|\parsestop@i| : \verb|\substitute@end| devra ajouter au collecteur \verb|\subst@toks| hors du groupe ce qu'il était dans le groupe, après l'avoir enveloppé d'accolades.

\showcode|\catcode`@11
\newtoks\subst@toks% registre de tokens pour stocker le <texte> modifié
\def\substitute{%¤§*\substitute¤
	\def\substitute@end{\the\subst@toks}% macro exécutée à la fin
	\ifstarred¤§*\ifstarred¤
		{\let\recurse@macro\substitute@star  \substitute@i}%
		{\let\recurse@macro\substitute@nostar\substitute@i}%
}
\def\substitute@i#1#2#3#4{% #1=macro à appeler selon étoile ou pas.
                          % #2=<texte> #3=<motif>  #4=<motif de substi>
	\def\code@arg{#2}\def\pattern@arg{#3}\def\subst@arg{#4}%
	\subst@toks={}% initialiser le collecteur à vide
	#1% aller à \substitute@star ou \substitute@nostar
}
\def\substitute@nostar{%
	\exptwoargs\ifstartwith\code@arg\pattern@arg% si le <texte> commence par <motif>¤\defline\aaa§*\exptwoargs§*\ifstartwith¤
		{\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>¤§*\eaddtotoks¤
		\grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
		\substitute@nostar% et recommencer
		}
		{\expandafter\ifempty\expandafter{\code@arg}%¤§*\ifempty¤
			{\substitute@end% sinon, si <texte> est vide => afficher le registre de tokens
			}
			{\grab@first\code@arg\aux@arg% autrement, manger le 1er "argument" de <texte>
			\eaddtotoks\subst@toks\aux@arg% et l'ajouter au registre de tokens¤§*\eaddtotoks¤
			\substitute@nostar% et recommencer
			}%
		}%¤\defline\bbb¤
}
\def\substitute@star{%
	\expandafter\ifbracefirst\expandafter{\code@arg}% si <texte> commence par "{"¤§*\ifbracefirst¤
		{\grab@first\code@arg\aux@arg% enlever {<argument>} de \code@arg
		\begingroup% ouvrir un groupe
			\def\substitute@end{% modifier localement la macro exécutée à la fin
				\expandafter\endgroup\expandafter% avant de fermer le groupe
				\addtotoks\expandafter\subst@toks\expandafter% ajouter au registre hors du groupe¤§*\addtotoks¤
					{\expandafter{\the\subst@toks}}% ce qui est collecté localement, mis entre {}
			\substitute@star% puis recommencer
			}%
			\subst@toks{}% initialiser à vide
			\expandafter\def\expandafter\code@arg\aux@arg% % assigner "argument" au <texte>
			\substitute@star% et recommencer avec ce nouveau \code@arg
		}% si code ne commence pas par "{"
		{\exptwoargs\ifstartwith\code@arg\pattern@arg% si <motif> est au début de <texte>¤\defline\ccc§*\exptwoargs§*\ifstartwith¤
			{\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>¤§*\eaddtotoks¤
			\grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
			\substitute@star% et recommencer
			}
			{\expandafter\ifempty\expandafter{\code@arg}% si <texte> est vide¤§*\ifempty¤
				{\substitute@end% aller à la macro de fin
				}% si <texte> n'est pas vide
				{\grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
				\eaddtotoks\subst@toks\aux@code% et l'ajouter au registre¤§*\eaddtotoks¤
				\substitute@star% et recommencer
				}%
			}%¤\defline\ddd¤
		}%
}
\catcode`@12
1) \substitute{ab{\bf racada}bra}{a}{W}\qquad
2) \substitute*{ab{\bf racada}bra}{a}{W}\qquad
3) \substitute{12\frbox{\bf 34}56}{\bf}{\it}\qquad
4) \substitute*{12\frbox{\bf 34}56}{\bf}{\it}¤§*\frbox¤|

\begin{exercice}
Dans le code proposé, les lignes \nos\aaa-\bbb{} sont identiques aux lignes \nos\ccc-\ddd{}, exception faite des macros \verb|\substitute@star| et \verb|\substitute@nostar|. Proposer une amélioration afin de ne pas écrire deux fois cette portion de code.

Définir une macro §\substitutetocs de syntaxe

\centrecode-\substitutetocs{<texte>}{<motif a>}{<motif b>}\<macro>-

\noindent qui assigne à \verb|\<macro>| le résultat de la substitution.

\solution
On peut définir une macro auxiliaire \verb|\recurse@macro| qui, selon que la version est étoilée\idx*{macro étoilée} ou non, sera \idx\let-égale à \verb|\substitute@star| ou  \verb|\substitute@nostar|. Il suffit dès lors de remplacer les occurrences de \verb|\substitute@star| et celles de \verb|\substitute@nostar| par \verb|\recurse@macro| et remplacer les lignes \no\ccc-\ddd{} par \verb|\substitute@nostar|.
\grandsaut

Pour créer §\substitutetocs, nous allons nous mettre à profit la macro \verb|\substitute@end| qui est en réalité un \idx[ (méthode de programmation)]{hook}. Il sera redéfini pour que la \verb|\<macro>| (argument \verb|#4|) reçoive le contenu du registre de tokens \verb|\subst@toks|. Un \verb|\edef| peut être utilisé ici, car lorsque \idx\the\verb|<registre de tokens>| est placé dans un \verb|\edef|, le contenu de ce registre \emph{non développé} apparait dans le texte de remplacement de la macro ainsi définie (voir page~\pageref{bloquer.developpement.maximum}).

Une fois le hook correctement défini, le déroulement de la macro \verb|\subtitute| se poursuit.

\showcode|\catcode`@11
\newtoks\subst@toks% registre de tokens pour stocker le <texte> modifié¤\idx\newtoks¤
\def\substitute{%¤§*\substitute¤
	\def\substitute@end{\the\subst@toks}% macro exécutée à la fin
	\ifstarred¤§*\ifstarred¤
		{\let\recurse@macro\substitute@star  \substitute@i}%
		{\let\recurse@macro\substitute@nostar\substitute@i}%
}
\def\substitute@i#1#2#3{% #1=<texte> #2=<motif> #3=<motif de substi>
	\def\code@arg{#1}\def\pattern@arg{#2}\def\subst@arg{#3}%
	\subst@toks={}% initialiser à vide
	\recurse@macro% aller à \substitute@star ou \substitute@nostar
}
\def\substitute@nostar{%
	\exptwoargs\ifstartwith\code@arg\pattern@arg% si le <texte> commence par <motif>¤§*\exptwoargs §*\ifstartwith¤
		{\eaddtotoks\subst@toks\subst@arg% ajouter <motif subst>¤§\eaddtotoks¤
		\grab@first\code@arg\aux@code% manger le 1er "argument" de <texte>
		\recurse@macro% et recommencer
		}
		{\expandafter\ifempty\expandafter{\code@arg}%¤§*\ifempty¤
			\substitute@end% sinon, si <texte> est vide => afficher le registre de tokens
			{\grab@first\code@arg\aux@arg% autrement, manger le 1er "argument" de <texte>
			\eaddtotoks\subst@toks\aux@arg% et l'ajouter au registre de tokens¤§*\eaddtotoks¤
			\recurse@macro% et recommencer
			}%
		}%
}
\def\substitute@star{%
	\expandafter\ifbracefirst\expandafter{\code@arg}% si <texte> commence par "{"¤§*\ifbracefirst¤
		{\grab@first\code@arg\aux@arg% enlever {<argument>} de \code@arg
		\begingroup% ouvrir un groupe
			\def\substitute@end{% modifier localement la macro exécutée à la fin
				\expandafter\endgroup\expandafter% avant de fermer le groupe
				\addtotoks\expandafter\subst@toks\expandafter% ajouter au registre hors du groupe¤§*\addtotoks¤
					{\expandafter{\the\subst@toks}}% ce qui est collecté localement, mis entre {}¤\idx*\the¤
				\recurse@macro% puis recommencer
			}%
			\subst@toks{}% initialiser à vide
			\expandafter\def\expandafter\code@arg\aux@arg% % assigner "argument" au <texte>
			\recurse@macro% et recommencer avec ce nouveau \code@arg
		}% si <texte> ne commence pas par "{" :
		\substitute@nostar% exécuter macro non étoilée pour une seule itération
}
\def\substitutetocs{%¤§*\substitutetocs¤
	\ifstarred¤§*\ifstarred¤
		{\let\recurse@macro\substitute@star  \substitutetocs@i}%
		{\let\recurse@macro\substitute@nostar\substitutetocs@i}%
}
\def\substitutetocs@i#1#2#3#4{% #1=<texte> #2=<motif> #3=<motif de substi> #4=\<macro>
	\def\substitute@end{\edef#4{\the\subst@toks}}% macro exécutée à la fin
	\substitute@i{#1}{#2}{#3}% continuer comme avec \substitute
}
\catcode`@12
\frboxsep=1pt
1) \substitute{ab{\bf racada}bra}{a}{W}\qquad
2) \substitute*{ab{\bf racada}bra}{a}{W}\qquad
3) \substitute{12\frbox{\bf 34}56}{\bf}{\it}\qquad
4) \substitute*{12\frbox{\bf 34}56}{\bf}{\it}¤§*\substitute\idx*\bf\idx*\it§*\frbox¤
\medbreak

1) \substitutetocs{ab{\bf racada}bra}{a}{W}\foo       \meaning\foo\par
2) \substitutetocs*{ab{\bf racada}bra}{a}{W}\foo      \meaning\foo\par
3) \substitutetocs{12\frbox{\bf 34}56}{\bf}{\it}\foo  \meaning\foo\par
4) \substitutetocs*{12\frbox{\bf 34}56}{\bf}{\it}\foo \meaning\foo¤§*\substitutetocs\idx*\bf\idx*\it§*\frbox¤|
\end{exercice}§*\substitute[|)]

\chapter{Des macros sur mesure}
\section{Macros à arguments optionnels}§*\vecteur[|(]
L'utilisation de §\ifnexttok va nous permettre de bâtir des macros acceptant des arguments \emph{optionnels}. Les arguments optionnels de ces macros ont vocation à se trouver entre des délimiteurs que l'on peut choisir comme on le souhaite (parenthèses, crochets\footnote{C'est la choix fait par \LaTeX{} et Con\TeX t.} ou autre), tout en rendant ces arguments et leurs délimiteurs \emph{facultatifs}. En cas d'absence d'argument optionnel, un argument \emph{par défaut}, fixé lors de la définition de la macro sera utilisé. Pour nous placer dans la continuité de ce qui se fait, nous prendrons les crochets pour délimiter les arguments optionnels.

La méthode consiste, pour une macro chapeau, à tester avec §\ifnexttok si le prochain token est un délimiteur ouvrant. Si tel est le cas, il faut appeler une macro auxiliaire à argument délimité qui va lire l'argument optionnel entre délimiteurs. Dans le cas contraire, il faut transmettre à la macro à arguments délimités un argument optionnel entre délimiteurs que l'on choisit par défaut.

Imaginons une macro \verb|\vecteur{<lettre>}| qui admet un argument obligatoire et qui se comporte de la façon suivante :

\begin{center}
 \begin{tabular}{c@{ donne }c}
 	\verb|\vecteur{n}|&$(x_1,\ldots,x_n)$\\
 	\verb|\vecteur{k}|&$(x_1,\ldots,x_k)$\\
 	\verb|\vecteur{i}|&$(x_1,\ldots,x_i)$
 \end{tabular}
\end{center}

L'argument obligatoire \verb|<lettre>| est l'indice du dernier terme. On pourrait vouloir spécifier un argument \emph{optionnel} entre crochets qui viendrait juste après la macro et qui serait l'indice du premier terme. La valeur par défaut de cet argument serait 1. Voici comment procéder :

\showcode/\catcode`@11
\def\vecteur{%
	\ifnexttok[% si la macro est suivie d'un crochet¤§*\ifnexttok¤
		\vecteur@i% aller à la macro à arguments délimités
		{\vecteur@i[1]}% sinon, ajouter l'argument optionnel par défaut entre crochets
}
\def\vecteur@i[#1]#2{% #1=arg optionnel  #2=arg obligatoire
	$(x_{#1},\ldots,x_{#2})$¤\idx*\ldots¤
}
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[0]{k}\qquad 3) \vecteur[i]j \qquad4) \vecteur[]n/

Bien que fonctionnant bien, on peut imaginer ce qu'il va se passer si cette macro est appelée alors que l'on est \emph{déjà} en mode mathématique\idx*{mode!mathématique} : le premier \verb|$| rencontré dans la macro va faire quitter ce mode et provoquer des erreurs de compilation avec le token «\verb|_|» qui n'opère qu'en mode mathématique. Il faut donc programmer une macro §\forcemath qui compose son argument en mode mathématique\idx*{mode!mathématique}, quel que soit le mode en cours. Pour cela, on va utiliser le test \tidx{ifmmode} qui est un test de \TeX{} :

\centrecode-\ifmmode<code vrai>\else<code faux>\fi-

Ce test est vrai si le mode mathématique\idx*{mode!mathématique} est en vigueur. C'est lorsqu'il est faux que la macro §\forcemath doit composer son argument entre délimiteurs mathématiques «\verb|$|».

Une autre amélioration serait de programmer un deuxième argument optionnel pour spécifier la lettre des coordonnées du vecteur, en choisissant $x$ par défaut. Bien qu'il nous soit possible de le mettre entre crochets, nous allons, par souci de changement, mettre cet argument optionnel entre parenthèses :

\showcode/\catcode`@11
\def\forcemath#1{% compose #1 en mode math, quel que soit le mode en cours¤§*\forcemath\idx*{mode!mathématique}¤
	\ifmmode\expandafter\firstoftwo\else\expandafter\secondoftwo\fi¤\tidx*{ifmmode}¤
		{#1}{$#1$}%
}
\def\vecteur{%
	\ifnexttok[% si la macro est suivie d'un crochet¤§*\ifnexttok¤
		\vecteur@i% aller à la macro à arguments délimités
		{\vecteur@i[1]}% sinon, ajouter l'argument optionnel par défaut entre crochets
}
\def\vecteur@i[#1]{%
	\ifnexttok(% si une parenthèse vient ensuite¤§*\ifnexttok¤
		{\vecteur@ii[#1]}% aller à la macro à argument délimités
		{\vecteur@ii[#1](x)}% sinon, rajouter "x" comme argument optionnel
}
\def\vecteur@ii[#1](#2)#3{% #1 et #2=arg optionnel  #3=arg obligatoire
	\forcemath{({#2}_{#1},\ldots,{#2}_{#3})}%¤§*\forcemath¤
}
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[0]{k}\qquad
3) \vecteur[i](y)j \qquad4) \vecteur[](\alpha)n/

\begin{exercice}
La macro \verb|\vecteur| ci-dessus admet deux arguments optionnels, mais ceux-ci doivent se trouver dans le bon ordre : celui entre crochets d'abord puis celui entre parenthèses et enfin l'argument obligatoire. On peut écrire \verb|\vecteur[i](y){j}|, mais pas \verb|\vecteur(y)[i]{j}|.

Comment faudrait-il modifier la macro pour que les arguments optionnels puissent être tapés dans n'importe quel ordre ?
\solution
Le plus simple est d'aiguiller l'algorithme vers deux «branches» selon que la macro \verb|\vecteur| est suivie d'un crochet ou d'une parenthèse. Ces deux branches seront contenues dans les macros \verb|\vecteur@bracket| et \verb|\vecteur@paren|.

\showcode/\catcode`@11
\def\vecteur{%
	\ifnexttok[% si la macro est suivie d'un crochet¤§*\ifnexttok¤
		\vecteur@bracket% lire cet argument entre crochet
		{\ifnexttok(% sinon, si elle est suivie d'une parenthèse¤§*\ifnexttok¤
			\vecteur@paren % lire cet argument entre parenthèses
			{\vecteur@i[1](x)}% sinon, transmettre les arguments par défaut
		}%
}
\def\vecteur@bracket[#1]{%
	\ifnexttok(% s'il y a une parenthèse après¤§*\ifnexttok¤
		{\vecteur@i[#1]}% lire la parenthèse
		{\vecteur@i[#1](x)}% sinon, donne "x" comme argument par défaut
}
\def\vecteur@paren(#1){%
	\ifnexttok[% si le caractère suivant est un crochet¤§*\ifnexttok¤
		{\vecteur@ii(#1)}% lire l'argument entre crochets
		{\vecteur@ii(#1)[1]}% sinon, donner "1" comme argument par défaut
}
\def\vecteur@i[#1](#2)#3{\forcemath{({#2}_{#1},\ldots,{#2}_{#3})}}¤§*\forcemath¤
\def\vecteur@ii(#1)[#2]{\vecteur@i[#2](#1)}% met les arg optionnels dans l'ordre
\catcode`@12
1) \vecteur{n}\qquad 2) \vecteur[i](y){j}\qquad 3) \vecteur(y)[i]{j}\qquad
4) \vecteur[0]{k}\qquad 5) \vecteur(\alpha){n}/
\end{exercice}§*\vecteur[|)]

\section{Définir une macro à plusieurs arguments optionnels}
La tentation est grande de créer une macro qui étendrait les possibilités de la primitive \verb|\def| et qui permettrait de définir des macros avec un ou plusieurs arguments optionnels\footnote{Comme le fait la macro \texttt{\string\newcommand} de \LaTeX,  même si elle ne permet de définir qu'un seul argument optionnel.}. Afin de rester simple, nous allons devoir faire quelques sacrifices : les macros ainsi définies ne pourront pas être à arguments délimités et les arguments optionnels seront entre crochets. Bien entendu, le nombre total d'arguments sera inférieur ou égal à 9.

Voici la syntaxe que nous pouvons nous fixer pour la macro §\newmacro[|(] :

\centrecode-\newmacro\<macro><paramètres>{<code>}-

\noindent Les \verb|<paramètres>| sont composés soit de chiffres, soit de textes entre crochets. Les chiffres désignent le nombre d'arguments obligatoires requis à cette position et les crochets un argument optionnel dont la valeur par défaut est le code qui se trouve entre les crochets. Par exemple, si on écrit :

\centrecode-\newmacro\foo1[xxx]2[y]1{<code>}-

\noindent alors, les paramètres «\verb|1[xxx]2[y]1|» spécifient que la macro \verb|\foo| admet 6 arguments qui seront dans l'ordre :
\begin{itemize}
	\item un argument obligatoire;
	\item un argument optionnel dont la valeur par défaut est «\verb|xxx|»;
	\item deux argument obligatoires;
	\item un argument optionnel dont la valeur par défaut est «\verb|y|»;
	\item un argument obligatoire.
\end{itemize}

Le \verb|<code>| de la macro pourra contenir les arguments sous la forme habituelle \verb|#1|, \verb|#2|, etc.

\subsection{Cas particulier}
Écrire d'emblée la macro \verb|\newmacro| est un défi vraiment difficile. Essayons plutôt de construire à la main la macro \verb|\foo| pour bien en comprendre le fonctionnement et ensuite, nous écrirons une macro généraliste \verb|\newmacro| qui bâtira automatiquement des macros admettant plusieurs arguments optionnels.

Il est bien évident que notre macro \verb|\foo| ne va pas tenir en une seule macro. En réalité, à chaque fois que nous devons lui faire lire un argument optionnel, il va falloir s'assurer que le token suivant est un crochet ou pas. Par conséquent, à ces occasions, la macro \verb|\foo| va passer la main à d'autres macros auxiliaires \verb|\foo@i|, \verb|\foo@ii|, etc.

Voici le code qui permet de construire la macro \verb|\foo| :

\showcode/\catcode`\@11
\def\foo#1{% #1 -> lit le premier argument obligatoire
	\ifnexttok[% si le token suivant est un crochet¤§*\ifnexttok¤
		{\foo@i{#1}}% aller à \foo@i qui va lire cet argument¤\defline\aaa¤
		{\foo@i{#1}[xxx]}% sinon, transmettre [xxx] à foo@i¤\defline\bbb¤
}

\def\foo@i#1[#2]#3#4{% lit l'arg obligatoire + arg optionnel + 2 arg obligatoires
	\ifnexttok[¤§*\ifnexttok¤
		{\foo@ii{#1}[#2]{#3}{#4}}%¤\defline\ccc¤
		{\foo@ii{#1}[#2]{#3}{#4}[y]}%¤\defline\ddd¤
}

\def\foo@ii#1[#2]#3#4[#5]#6{% lit tous les arguments
	1="#1" 2="#2" 3="#3" 4="#4" 5="#5" 6="#6"%
}

\catcode`\@12
1) \foo{arg1}{arg2}{arg3}{arg4}\par
2) \foo{arg1}[OPT\_A]{arg2}{arg3}{arg4}\par
3) \foo{arg1}{arg2}{arg3}[OPT\_B]{arg4}\par
4) \foo{arg1}[OPT\_A]{arg2}{arg3}[OPT\_B]{arg4}\medbreak¤\idx*\medbreak¤/

On voit donc qu'à chaque fois que l'on attend un argument optionnel, il s'agit de tester la présence d'un crochet. Pour lire l'argument optionnel entre crochet, une nouvelle macro auxiliaire \verb|\foo@<n>| à argument délimité doit être créée. On remarque aussi que lorsque cette macro auxiliaire est appelée (lignes \nos\aaa-\bbb{} et lignes \nos\ccc-\ddd), la \emph{totalité} des arguments lus jusqu'à présent lui est transmise. À charge pour cette macro de les lire, de lire aussi l'argument optionnel pour lequel elle est créée, ainsi que d'éventuels arguments obligatoires à suivre.

Il est également très important de remarquer que si une macro créée par le truchement de §\newmacro admet un ou plusieurs arguments optionnels, non seulement elle ne peut pas être purement développable à cause de l'emploi de \idx\futurelet, mais on ne peut pas faire apparaitre son texte de remplacement avec des \verb|\expandafter|. C'est la contrepartie qu'il faut concéder pour profiter de la souplesse des arguments optionnels.

\subsection{Cas général}
Pour construire la macro \verb|\newmacro|, nous allons d'abord nous mettre au clair avec les noms des macros auxiliaires. Dans le cas particulier précédent, la macro \verb|\foo| avait deux macros auxiliaires \verb|\foo@i| et \verb|\foo@ii|. Ces macros, si elles sont automatiquement créées par §\newmacro, posent un problème si l'utilisateur veut en disposer pour créer de lui même d'autres macros auxiliaires. Nous allons donc prendre le parti que si la macro à définir est \verb|\<macro>|, alors les macros auxiliaires seront de la forme \verb|\<macro>@[<chiffre romains>]|. Pour ce faire, une macro purement développable \verb|\macro@name{<nombre>}| se chargera de donner sous forme de tokens de catcode 12, le nom de la macro (sans caractère d'échappement) sous la forme \verb|<macro>@[<chiffre romains>]|.

Venons-en à la méthode proprement dite. Elle va consister à définir la \idx{macro fille} \verb|\macro@name| puis à parser les \verb|<paramètres>| jusqu'à rencontrer une accolade ouvrante. Comme on l'a vu avec la macro \verb|\foo| précédemment, chaque macro auxiliaire doit relire la totalité des arguments rencontrés jusqu'à présent en y ajoutant d'autres arguments. Le \idx{texte de paramètre} de ces macros va donc s'allonger au fur et à mesure que les \verb|<paramètres>| seront parsés. Rappelons-nous qu'avec la macro \verb|\foo|, ce texte de paramètre était «\verb|#1|» pour la macro principale puis «\verb|#1[#2]#3#4|» pour \verb|\foo@i| et enfin «\verb|#1[#2]#3#4[#5]#6|» pour la troisième macro \verb|\foo@ii|. Dans le cas général, nous allons stocker ce texte de paramètre dans le registre de tokens \verb|\param@text|. 

Lorsque les \verb|<paramètres>| sont parsés, trois cas sont possibles selon le prochain token vu par \idx\futurelet :

\begin{enumerate}
	\item si c'est une accolade ouvrante (ou plus exactement un \idx\bgroup comme le voit \idx\futurelet), alors, c'est que le \idx{texte de paramètre} a été entièrement lu;
	\item si c'est un crochet, il faut créer une sous-macro supplémentaire et ajouter à \verb|\param@text| «\hbox{\verb|[#<x>]|}» où \hbox{\verb|<x>|} est le numéro du prochain paramètre;
	\item dans les autres cas, il s'agit donc d'un chiffre (un unique token de 1 à 9) et il faut ajouter à \verb|\param@text| «\hbox{\verb|#<x>|}», «\hbox{\verb|#<x+1>|}», etc., autant de fois que le spécifie le chiffre lu.
\end{enumerate}

La dernière difficulté est d'appeler les macros auxiliaires tout en leur transmettant les arguments déjà lus sous la forme «\hbox{\verb|{#<x>}|}» si c'est un argument obligatoire et sous la forme «\hbox{\verb|[#<x>]|}» si c'est un argument optionnel. Comme les arguments obligatoires doivent être transmis entre accolades, le registre de tokens \verb|\param@text| ne peut pas être utilisé. Il faut donc utiliser un autre registre de tokens \verb|\arg@text|, mis à jour en même temps que \verb|\param@text| et qui enveloppera d'accolades les arguments obligatoires.

Voici donc le code, plutôt difficile, de la macro \verb|\newmacro| :

\showcode7\catcode`\@11
\newcount\macro@cnt% numéro à mettre dans le nom des sous macros¤\idx*\newcount¤
\newcount\arg@cnt% compte le nombre d'arguments
\newtoks\param@text% texte de paramètre des macros sous forme "#x" et/ou "[#x]"¤\idx*\newtoks¤
\newtoks\arg@text% arguments sous forme "{#x}" et/ou "[#x]"

\def\newmacro#1{%
	% \macro@name construit le <nom> de la macro et éventuellement "@[<chiffre romain>]"
	\def\macro@name##1{\expandafter\gobone\string#1\ifnum##1>0 @[\romannumeral##1]\fi}%¤\idx*\romannumeral\idx*\string¤
	\macro@cnt=0 \arg@cnt=0 % initialise les compteurs
	\param@text{}\arg@text{}% vide les registres de texte de paramètre et d'argument
	\newmacro@i% va voir le prochain token
}

\def\newmacro@i{\futurelet\nxttok\newmacro@ii}% met le prochain token dans \nxttok...¤\idx*\futurelet¤
% ...puis va à la macro :
\def\newmacro@ii{%
	\ifxcase\nxttok¤§*\ifxcase¤
		[\newmacro@optarg% si le prochain token est un crochet aller à \newmacro@optarg
		\bgroup% si c'est un accolade ouvrante¤\idx*\bgroup¤
			% le texte de paramètre est fini et il faut définir la macro
			{\defname{\macro@name\macro@cnt\expandafter}%¤§*\defname¤
			\the\param@text}% <- le {<code>} est juste après, il n'est pas encore lu¤\idx*\the¤
	\elseif% sinon, c'est donc un chiffre¤§*\elseif¤
			\newmacro@arg% aller à \newmacro@arg
	\endif¤§*\endif¤
}

\def\newmacro@optarg[#1]{% lit la valeur par défaut de l'argument optionnel
	% Définit la macro \<nom>@[<nbre>] qui lit tous les arguments (optionnels ou pas)
	% jusqu'alors définis à l'aide de \param@text. Puis, cette macro testera si le prochain
	% token est un crochet
	\expandafter\edef\csname\macro@name\macro@cnt\expandafter\endcsname\the\param@text{%
		\noexpand\ifnexttok[%¤\idx*\noexpand§*\ifnexttok\idx*\noexpand¤
			% si oui : la macro \<nom>@<nbr+1> le lira
			{\expandafter\noexpand\csname\macro@name{\numexpr\macro@cnt+1}\expandafter\endcsname
			\the\arg@text}%
			% si non : transmettre à \<nom>@<nbr+1> l'argument optionnel par défaut lu
			{\expandafter\noexpand\csname\macro@name{\numexpr\macro@cnt+1}\expandafter\endcsname
			\the\arg@text[\unexpanded{#1}]}%¤\idx*\unexpanded¤
	}%
	\advance\arg@cnt 1 % incrémenter le numéro d'argument¤\idx*\advance¤
	% pour ajouter "[#<x>]" à \param@text et à \arg@text
	\eaddtotoks\param@text{\expandafter[\expandafter##\number\arg@cnt]}%¤§*\eaddtotoks¤
	\eaddtotoks\arg@text  {\expandafter[\expandafter##\number\arg@cnt]}%¤§*\eaddtotoks¤
	\advance\macro@cnt 1 % incrémenter le numéro de nom de macro¤\idx*\advance¤
	\newmacro@i% va voir le token suivant
}

\def\newmacro@arg#1{% #1=nombre d'arguments obligatoires à ajouter
	% boucle qui ajoute "#<x>#<x+1>etc" dans \param@text
	% et "{#<x>}{#<x+1>}etc" dans \arg@text
	\ifnum#1>\z@ % tant qu'on n'a pas ajouté le nombre de #x nécessaire¤\idx*\z@¤
		\advance\arg@cnt 1 % incrémenter le numéro d'argument¤\idx*\advance¤
		% pour ajouter #x à \param@text et {#x} à \arg@text
		\eaddtotoks\param@text{\expandafter##\number\arg@cnt}%
		\eaddtotoks\arg@text  {\expandafter{\expandafter##\number\arg@cnt}}%¤§*\eaddtotoks¤
		\expandafter\newmacro@arg\expandafter{\number\numexpr#1-1\expandafter}% boucler
	\else% si les arguments sont tous ajoutés
		\expandafter\newmacro@i% lire le token suivant
	\fi
}
\catcode`\@12
\newmacro\foo 1[xxx]2[y]1{1="#1" 2="#2" 3="#3" 4="#4" 5="#5" 6="#6"}
a) \foo{arg1}{arg2}{arg3}{arg4}\par
b) \foo{arg1}[OPT\_A]{arg2}{arg3}{arg4}\par
c) \foo{arg1}{arg2}{arg3}[OPT\_B]{arg4}\par
d) \foo{arg1}[OPT\_A]{arg2}{arg3}[OPT\_B]{arg4}\medbreak¤\idx*\medbreak¤

\meaning\foo\par
\expandafter\meaning\csname foo@[i]\endcsname\par
\expandafter\meaning\csname foo@[ii]\endcsname¤\idx*\meaning¤7

Il est peut être utile de donner quelques explications sur le code :

\begin{itemize}
	\item au chapitre des variables, le compteur \verb|\macro@cnt| sert à \verb|\macro@name| pour nommer les macros auxiliaires via \idx\romannumeral. Ces numéros entre crochets viennent après «\verb|@|» et sont «\texttt i», «\texttt{ii}», etc. 
	
	Ensuite, le compteur \verb|\arg@cnt| sert à compter les arguments. Il est utilisé dans la macro \verb|\newmacro@arg| pour insérer dans les registres à tokens \verb|\param@text| et \verb|arg@text|, soit \verb|[#<i>]|, soit \verb|#<i>|, soit \verb|{#<i>}|;
	\item la macro \verb|\newmacro| n'est qu'une macro chapeau qui se charge des initialisations;
	\item ensuite, \verb|\newmacro@i| va voir le prochain token avec un \idx\futurelet;
	\item ce token est testé par la macro \verb|\newmacro@ii| qui décide ce qu'il faut faire selon les cas envisagés plus haut :
	\begin{itemize}
		\item si ce token est un crochet, \verb|\newmacro@optarg| se charge de construire une macro auxiliaire supplémentaire avec un \verb|\edef| en prenant soin de ne pas développer toutes les séquences de contrôle qui ne doivent pas l'être. La primitive \idx\unexpanded est employée pour l'argument entre crochets  puisqu'il est susceptible de contenir un nombre inconnu de tokens;
		\item si ce token est un chiffre, \verb|\newmacro@arg| lit ce chiffre et met en place une récursivité pour ajouter \verb|{#<x>}| et \verb|#<x>| autant de fois qu'il le faut aux registres de tokens \verb|\arg@text| et \verb|\param@text|;
		\item enfin, si ce token est une accolade ouvrante, la dernière macro avec le texte de paramètre complet est définie avec le \verb|<code>| qui suit les \verb|<paramètres>|.
	\end{itemize}
\end{itemize}

Afin que les choses soient le plus claires possible et même si c'est fastidieux, essayons de faire mentalement fonctionner \verb|\newmacro| pour l'exemple

\centrecode|\newmacro\foo 1[xxx]2[y]1|

\noindent Par souci de clarté, les crochets autour du chiffre romain figurant dans les noms des macros auxiliaires seront omis :

\begin{enumerate}
	\item le chiffre 1 est détecté. Il est lu par \verb|\newmacro@arg| qui ajoute «\verb|{#1}|» et «\verb|#1|» à \verb|\arg@text| et \verb|\param@text| qui, étant initialisés à vide par \verb|\newmacro| contiennent donc «\verb|{#1}|» et «\verb|#1|»;
	\item un crochet est détecté et l'argument «\verb|[xxx]|» est lu par \verb|\newmacro@optarg| :
	\begin{itemize}
		\item elle définit la macro \verb|\foo| de cette façon :
\centrecode-\def\foo#1{%
	\ifnexttok[%¤§*\ifnexttok¤
		{\foo@i{#1}}
		{\foo@i{#1}[xxx]}%
}-
		\item les registres \verb|\arg@text| et \verb|\param@text| sont mis à jour et contiennent «\verb|{#1}[#2]|» et «\verb|#1[#2]|»
	\end{itemize}
	\item le chiffre 2 est détecté. Il est lu par \verb|\newmacro@arg| qui ajoute 2 arguments «\verb|{#3}{#4}|» et «\verb|#3#4|» à \verb|\arg@text| et \verb|\param@text| qui contiennent désormais «\verb|{#1}[#2]{#3}{#4}|» et «\verb|#1[#2]#3#4|»;
	\item un crochet est détecté et l'argument «\verb|[y]|» est lu par \verb|\newmacro@optarg| :
		\begin{itemize}
		\item elle définit la macro \verb|\foo@i| de cette façon :
\centrecode-\def\foo@i#1[#2]#3#4{%
	\ifnexttok[%¤§*\ifnexttok¤
		{\foo@ii{#1}[#2]{#3}{#4}}
		{\foo@ii{#1}[#2]{#3}{#4}[y]}%
}-
		\item les registres \verb|\arg@text| et \verb|\param@text| sont mis à jour et contiennent «\verb|{#1}[#2]{#3}{#4}[#5]|» et «\verb|#1[#2]#3#4#5|»
	\end{itemize}
	\item le chiffre 1 est détecté. Il est lu par \verb|\newmacro@arg| qui ajoute «\verb|{#6}|» et «\verb|#6|» à \verb|\arg@text| et \verb|\param@text|;
	\item une accolade ouvrante est lue par \idx\futurelet ce qui signe la fin du processus. Le code
	
	\centrecode-\defname{\macro@name\macro@cnt\expandafter}\the\param@text}-
	
	se développe en 
	
	\centrecode-\def\foo@ii#1[#2]#3#4#5#6-
	
	Ceci est suivi du \verb|<code>| entre accolades «\verb-{|#1|#2|#3|#4|#5|#6|}-» toujours non lu ce qui signifie que la macro \verb|\foo@ii| aura ce \verb|<code>| comme texte de remplacement.
\end{enumerate}

Cet algorithme ne définit donc une macro \emph{que} lorsqu'un crochet est détecté dans les \verb|<paramètres>| ou lorsque l'accolade ouvrante marquant la fin des \verb|<paramètres>| est atteinte.

\begin{exercice}
Créer une macro §\framebox\label{framebox} dont la syntaxe est

\centrecode-\framebox[<lettres>]{<texte}-

\noindent et qui agit comme §\frbox mais ne trace les réglures que selon les lettres qui figurent dans l'argument optionnel. La lettre «U» (comme «\emph{up}») demandera à ce que la réglure supérieure soit tracée. De la même façon «D», «L» et «R» spécifieront respectivement que les réglures inférieures, gauche et droite soient tracées. Par défaut, l'argument optionnel vaut «ULRD».
\solution
Il faut reprendre la code de §\frbox et tester avec §\ifin s'il y a lieu de tracer une réglure et l'espace qui la sépare du \verb|<texte>|. Afin que les \verb|<lettres>| de l'argument optionnel puisse être minuscules ou majuscules, la primitive \idx\uppercase sera chargée de mettre en majuscule

\centrecode-\ifin{#1}<lettre>-

Comme cette primitive est sans effet sur les séquences de contrôle, seuls l'argument optionnel \verb|#1| et la \verb|<lettre>| seront mis en majuscule.

\showcode/\newmacro\framebox[ULRD]1{% #1 = ULRD (Up, Down, Right, Left)¤§*\framebox¤
% ne pas changer le mode H ou V en cours
	\hbox{% enferme dans une \hbox¤\idx*\hbox¤
		\uppercase{\ifin{#1}L}{\vrule width\frboxrule}{}% réglure gauche¤\idx*\uppercase\idx*\vrule§*\frboxrule§*\ifin¤
		\vtop{%¤\idx*\vtop¤
			\vbox{% 1er élément de la \vtop¤\idx*\vbox¤
				\uppercase{\ifin{#1}U}{% si la réglure sup doit être tracée¤\idx*\uppercase §*\ifin¤
					\hrule height\frboxrule% réglure supérieure¤\idx*\hrule¤
					\kern\frboxsep% espace haut¤\idx*\kern¤
					}
					{}%
				\hbox{%¤\idx*\hbox¤
					\uppercase{\ifin{#1}L}{\kern\frboxsep}{}% espace gauche
					#2% contenu
					\uppercase{\ifin{#1}R}{\kern\frboxsep}{}% espace droite¤\idx*\uppercase¤
					}%
			}% puis autres éléments de la \vtop, sous la ligne de base
			\uppercase{\ifin{#1}D}{%¤\idx*\uppercase §*\ifin¤
				\kern\frboxsep% espace bas¤§*\frboxsep¤
				\hrule height\frboxrule% réglure inférieure¤\idx*\hrule§*\frboxrule¤
				}%
				{}%
		}%
		\uppercase{\ifin{#1}R}{\vrule width\frboxrule}{}% réglure droite¤\idx*\uppercase\idx*\vrule§*\ifin¤
	}%
}
\frboxsep=1pt ¤§*\frboxsep¤
Boite \framebox{entière}, \framebox[ud]{Up down}, \framebox[LR]{Left Right},
\framebox[LU]{Left Up} et \framebox[rd]{Right Down}.¤§*\framebox¤/
\end{exercice}§*\newmacro[|)]

\section{Développer les arguments d'une macro}\label{eargs}
Pour rendre l'emploi des macros encore plus agréable et souple, nous devons maintenant chercher, lorsqu'elles sont exécutées, à développer comme on le souhaite leurs arguments. Nous nous limiterons aux \emph{vrais} arguments et laisserons de côté les arguments optionnels.

Certes, nous avons déjà à notre disposition de §\exparg (et §\expsecond qui lui est \idx\let-égale) ainsi que §\exptwoargs, mais ces macros ne peut 1-développer qu'un seul ou deux arguments. Imaginons qu'une \verb|\<macro>| admette 5 arguments et qu'un appel à cette macro nécessite de lui passer le premier tel quel, de 1-développer le premier token du 2\ieme{} argument, de 2-développer celui du 3\ieme, de 3-développer celui du 4\ieme{} et de développer au maximum le dernier argument. Nos macros §\exparg et §\expsecond seraient bien faibles pour y parvenir. Bâtissons une macro §\eargs[|(], admettant un argument obligatoire entre crochets contenant, pour chaque argument, le nombre de développements souhaités. Si un développement maximal est voulu, un «\verb|+|» sera spécifié. Pour notre macro \verb|\<macro>|, voici la syntaxe que l'appel à cette macro prendrait :

\centrecode-\eargs[0123+]\<macro>{<arg1>}{<arg2>}{<arg3>}{<arg4>}{<arg5>}-

Du côté de la \TeX nique, §\eargs lira son argument entre crochet et la \verb|\<macro>|. Les autres argument seront lus un par un par une macro récursive. Cette macro se chargera de développer correctement l'argument courant et d'ajouter le résultat à un registre de tokens \verb|\eargs@toks| qui jouera le rôle d'un accumulateur. Ce registre étant initialisé avec \verb|\<macro>| par §\eargs, il contiendra à la fin cette \verb|\<macro>| et les arguments correctement développés.

Voici l'algorithme que nous mettrons en \oe uvre :

\begingroup
\numalgofalse
\def\algoleftskip{.08\hsize}
\def\algorightskip{.08\hsize}
\algorithm[\#]{Macro \texttt{\string\eargs}}/
macro ~eargs~[#1]#2% #1= liste des n-développements  #2=macro à exécuter
	eargs@toks:=#2% mettre la macro dans le collecteur de tokens
	~eargs@i~#1nil% appeler eargs@i avec la liste de n-développements
~fin~\medskip
macro ~eargs@i~#1nil% #1=liste des n-développements
	~si~ #1 est vide
		exécuter eargs@toks
	~sinon~
		~eargs@ii~#1nil% appeler eargs@ii avec la liste de n-développements
	~finsi~
~fin~\medskip
macro ~eargs@ii~#1#2nil#3
%#1=n-développement actuel %#2=n-développements restants #3=argument courant
	~si~ #1="+"% si un développement maximal est demandé
		macro@temp:=développement maximal de #3
	~sinon~
		macro@temp:=#3% mettre l'argument dans une macro
		~pour~ i=1 to #1 ~faire~% 1-développer #1 fois macro_temp
			macro@temp:=1-développement du contenu de macro@temp
		~finpour~
	~finsi~
	eargs@toks:=eargs@toks+\{macro@temp\}% ajouter le résultat au registre
	~eargs@i~#2nil% recommencer avec la liste des n-développements restants
~fin~
/
\endgroup

Pour nous assurer que \verb|\eargs| fonctionne bien, la macro \verb|\foo| se contente ici d'afficher les arguments qu'elle reçoit tels quels avec \idx\detokenize.

\showcode/\catcode`\@11
\newtoks\eargs@toks¤\idx*\newtoks¤
\newtoks\eargs@temptoks
\def\eargs[#1]#2{% #1=liste des développements  #2=macro
	\eargs@toks{#2}% mettre la macro dans le collecteur de tokens
	\expandafter\eargs@i\detokenize{#1}\@nil% appeler \eargs@i avec
	                                        % la liste des developpements¤\idx*\detokenize¤
}

\def\eargs@i#1\@nil{% #1=liste des n-développements restant
	\ifempty{#1}% s'il n' y plus de n-développements¤§*\ifempty¤
		{\the\eargs@toks}% exécuter la macro et ses arguments développés¤\idx*\the¤
		{\eargs@ii#1\@nil}% sinon appeller la macro qui lit un argument
}

% #1=n-développement actuel  #2=liste des n-développements restants   #3=argument lu
\def\eargs@ii#1#2\@nil#3{%
	\if+#1% si #1="+", un \edef est demandé pour cet argument¤\tidx*{if}¤
		\edef\eargs@tempmacro{{#3}}% le stocker dans une macro temporaire
	\else% sinon
		\eargs@temptoks={#3}% stocker l'argument dans un registre temporaire
		\for\eargs@loop = 1 to #1\do 1 % faire #1 fois :¤§*\for¤
			{\eargs@temptoks=% 1-développer le 1er token du registre temporaire
				\expandafter\expandafter\expandafter{\the\eargs@temptoks}%
			}% puis le stocker dans la macro temporaire
		\edef\eargs@tempmacro{{\the\eargs@temptoks}}%¤\defline\aaa\idx*\the¤
	\fi
	\eaddtotoks\eargs@toks\eargs@tempmacro% ajouter le contenu de la macro au collecteur¤§*\eaddtotoks¤
	\eargs@i#2\@nil% appeler \eargs@i avec les n-développements restants
}
\catcode`\@12
\def\foo#1#2#3#4#5{\detokenize{1="#1" 2="#2" 3="#3" 4="#4" 5="#5"}}
\def\aaa{\bbb}\def\bbb{\ccc}\def\ccc{Bonjour}

\eargs[0123+]\foo{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}{\aaa\bbb}./

La ligne \no\aaa{} rhabille d'accolades l'argument dument développé et, comme cela a été expliqué à la page~\pageref{bloquer.developpement.maximum}, le \idx\edef ne \emph{développe pas} le contenu du registre.§*\eargs[|)]
%|                                                                            |
%|                                Fin partie 4                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                  Partie 5                                  |
%|                                                                            |
\defpartcomment{\lettrine[lines=3,nindent=0pt]{\libertineInitialGlyph{L}}{e moment} est venu de mettre en application toutes les connaissances et les méthodes de programmation vues dans les parties précédentes. Un effort a été fait pour rendre certains de ces exemples aussi proches que possibles de ceux que l'on pourrait rencontrer dans une vie d'utilisateur de \TeX{}, même si leur complexité peut pour certains sembler rebutante, mais il en est ainsi, plus on s'approche de \emph{vrais} exemples, plus le niveau tend à s'élever.}

\part{Aller plus loin}

\chapter{Du nouveau dans les arguments des macros}

\section{Détecter des marqueurs dans l'argument d'une macro}
\subsection{Créer un effet entre deux marqueurs}
\Qu i n'a jamais souhaité mettre des «marqueurs» dans l'argument\idx*{argument!marqueur} d'une macro spécialement conçue, de telle sorte qu'entre deux de ces marqueurs, un effet spécial soit obtenu ? Si l'on appelle §\detectmark cette macro, on pourrait par exemple écrire

\centrecode-\detectmark{+}{Un +argument+ où les +marqueurs+ sont détectés}-§*\detectmark

\noindent pour que ce qui est entre deux «\verb|+|» subisse un traitement que l'on peut choisir. On obtiendrait par exemple

\begin{centrage}\small
Un {\bf argument} où les {\bf marqueurs} sont détectés

{\normalsize ou}\hfill\null

Un \frboxsep=1pt \frbox{\strut argument} où les \frbox{\strut marqueurs} sont détectés
\end{centrage}

Le but est bien sûr de créer un raccourci pour passer de \verb|+<code>+| à \verb|{\bf<code>}| ou à \verb|\frbox{<code>}| ou à tout autre effet.
\grandsaut

Pour programmer la macro §\detectmark, l'idée est d'agir dans un groupe, de rendre actif son premier argument qui est le caractère «marqueur», et de programmer ce caractère pour obtenir l'effet souhaité. Nous utiliserons ici l'astuce du \idx\lccode et \idx\lowercase, sous réserve que \cidx\~ soit actif au moment de la définition. Ceci fait, il suffira de faire lire le deuxième argument et ensuite, fermer le groupe.

Pour davantage de souplesse, la programmation de l'effet sera confiée à une macro externe §\markeffect qui recevra dans son argument ce qui se trouve entre les deux marqueurs.

\showcode/\catcode`\@11
\def\detectmark#1{% #1 est le marqueur¤§*\detectmark¤
	\begingroup
		\catcode`#1=13 % rendra #1 actif après la macro
		\begingroup% pour les besoins du \lccode
			\lccode`\~=`#1 % transforme "~" en " #1 actif"¤\idx*\lccode¤
			\lowercase{\endgroup\def~##1~}{\markeffect{##1}}%¤\idx*\lowercase\cidx*\~§*\markeffect¤
		\detectmark@i
}
\def\detectmark@i#1{%
		#1% exécute le code
	\endgroup% ferme le groupe, le marqueur perd son catcode actif
}
\catcode`\@12
a) \def\markeffect#1{{\bf #1}}% met en gras¤§*\markeffect¤
\detectmark+{Un +argument+ où les +marqueurs+ sont détectés}¤§*\detectmark¤
\medskip¤\idx*\medskip¤

b) \def\markeffect#1{% met dans une boite¤§*\markeffect¤
	\begingroup
		\frboxsep=1pt % modifie l'espacement entre texte et encadrement¤§*\frboxsep¤
		\frbox{\strut#1}% encadre¤\idx*\strut§*\frbox¤
	\endgroup
}
\detectmark|{Un |argument| où les |marqueurs| sont détectés}¤§*\detectmark¤
\medskip¤\idx*\medskip¤

c) \def\markeffect#1{$\vcenter{\hbox{#1}\hbox{#1}}$}% superpose 2 fois¤§*\markeffect\idx*\vcenter\idx*[|etc]\hbox\forbidindex\hbox¤
\detectmark`{Un `argument` où les `marqueurs` sont détectés}¤§*\detectmark¤/

La macro §\detectmark est certes bien pratique, mais elle doit cependant être utilisée avec précaution. Tout d'abord parce qu'en l'état, elle ne fonctionnera pas dans l'argument d'une macro :

\showcode/\catcode`\@11
\def\detectmark#1{%¤§*\detectmark¤
	\begingroup
		\catcode`#1=13 % rendra #1 actif après la macro
		\begingroup% pour les besoins du \lccode
			\lccode`\~=`#1 % transforme "~" en " #1 actif"¤\idx*\lccode¤
			\lowercase{\endgroup\def~##1~}{\markeffect{##1}}%¤\idx*\lowercase\cidx*\~§*\markeffect¤%
		\detectmark@i
}
\def\detectmark@i#1{%
		#1% lit le code
	\endgroup% ferme le groupe, le marqueur perd son catcode actif
}
\catcode`\@12
\def\markeffect#1{{\bf #1}}% met en gras¤\idx*\bf§*\markeffect¤
\frbox{\detectmark+{Un +argument+ où les +marqueurs+ sont détectés}}¤§*\detectmark§*\frbox¤/

La raison est toujours la même, mais il faut la rappeler une fois de plus : la macro §\frbox \emph{lit} son argument (pour le traiter par la suite) et dès lors, les catcodes de tous les tokens qui le composent sont figés\idx*{argument!catcode figé}. Par conséquent, la macro interne §\detectmark, qui agit \emph{après} cette congélation des catcodes, ne peut plus modifier celui de \verb|+| pour le rendre actif.

Mais il existe une autre limitation : nous aurions aussi pu rêver que la macro §\markeffect agisse comme §\litterate de la page~\pageref{litterate} c'est-à-dire qu'elle affiche le code tel qu'il est écrit. Là aussi, l'échec est assuré, et toujours  pour la même raison. En effet, le marqueur dans la macro §\detectmark, après être rendu actif, a été programmé \emph{lire} ce qui se trouve jusqu'au prochain marqueur. Ce marqueur transmet tout ce qu'il a lu à la macro §\markeffect qui, à son tour, le \emph{lit} avant de le traiter. Ce qui est entre deux marqueurs est donc lu \emph{deux fois} avant d'être traité. La conséquence est la même que s'il y avait eu une seule lecture : les catcodes des tokens se trouvant entre deux marqueurs sont figés et il n'est plus possible de les neutraliser avec \idx\dospecials.

\subsection{Autoriser du verbatim dans l'argument d'une macro}\idx*[|(]{verbatim}
Est-il possible de trouver une méthode permettant de faire lire une portion de texte en «\idx{verbatim}» dans l'argument d'une macro ? C'est-à-dire que les tokens faisant partie de cette portion seraient lus par la macro comme étant tous de catcode 12. La réponse est oui, mais le procédé va être assez \TeX nique et de toute façon, la solution aura des limitations.

Décidons pour cela de créer une macro §\alter dont la syntaxe serait la suivante :

\centrecode-\alter<délimiteur>\<macro>{<argument>}-§*\alter

\noindent La \verb|\<macro>| serait altérée en ce sens que si des \verb|<délimiteurs>| sont présents par paires dans son \verb|<argument>|, alors tout ce qui est entre deux délimiteurs consécutifs serait compris comme étant en mode « \idx{verbatim} ». Par exemple, écrire 

\centrecode-\alter{|}\frbox{texte normal |$\ver {# batim$| texte normal}-§*\alter

\noindent produirait à l'affichage

\begin{centrage}
\leavevmode\small\frbox{texte normal {\ttfamily\string$\string\ver\ \{\#\  batim\string$} texte normal}
\end{centrage}
\grandsaut

Pour parvenir à nos fins, le principe général est de collecter dans un registre de tokens \verb|\alter@toks| tous les tokens de l'\verb|<argument>| en prenant soin de modifier à 12 le catcode de tous les tokens qui sont entre deux occurrences du \verb|<délimiteur>|. Une fois ceci fait, il ne reste plus qu'à donner à la \verb|\<macro>| le contenu du registre de tokens.

La macro §\alter va effectuer les actions suivantes : elle va lire deux arguments qui sont le délimiteur et la \verb|\<macro>| à altérer et va les stocker pour les utiliser ultérieurement. C'est ensuite qu'elle va effectuer une action que nous n'avons jusqu'ici jamais faite : elle va manger l'accolade ouvrante de l'\verb|<argument>| avec un \idx\let\verb*|\next= | précédé d'un \idx\afterassignment qui spécifiera où aller après avoir mangé cette accolade. Dès lors, le problème qui surgit est que l'accolade qui ferme l'\verb|<argument>| se retrouve orpheline et il faudra bien prendre en compte et gérer cette rupture d'équilibre à un moment. Mais poursuivons notre chemin : puisque §\alter est entré à l'intérieur de l'\verb|<argument>|, elle va le parcourir token par token (comme le faisait la macro §\parse) et décider l'action à faire en fonction du prochain token à lire (obtenu avec \idx\futurelet). Voici les cas à envisager :

\begin{itemize}
	\item accolade fermante;
	\item accolade ouvrante;
	\item espace;
	\item un \verb|<délimiteur>|;
	\item un autre token.
\end{itemize}

Précisons que la macro §\ifbracefirst ne doit pas être utilisée pour tester si une accolade ouvrante est à lire, car cette macro lit la totalité de son argument pour savoir si celui-ci commence par une accolade. Cette lecture provoque des pertes d'informations (lire page~\pageref{perte.information.lecture}) et le gel des catcodes de tous les tokens, ce qui l'exact contraire de ce qui est recherché ici.

Comme l'\verb|<argument>| est parcouru avec \idx\futurelet, les limitations de la commande §\alter apparaissent donc : il faut que l'\verb|<argument>| ne contienne ni \idx\bgroup ni \idx\egroup, car cela provoquerait des faux positifs par le test \verb|\ifx| avec les accolades ouvrantes et fermantes.

La macro §\alter va être construite sur le modèle de la macro §\parse de la page~\pageref{parse} et, comme elle doit aussi effectuer son travail à l'intérieur de groupes entre accolades, elle va emprunter la méthode de la \idx{macro étoilée} \verb|\parse*| de la page~\pageref{parse.a}. Une macro de fin de processus va être programmée et localement modifiée lorsqu'un groupe entre accolades est rencontré.

Ceci donne l'algorithme suivant :

\begin{algo}
	\item définir la macro de fin \verb|\alter@stop|
	\begin {algo}
		\item lire l'accolade fermante orpheline «\verb|}|»;
		\item passer à l'argument de \verb|\<macro>| le contenu de \verb|\alter@toks|
	\end {algo}
	\item lire les deux arguments \verb|<délimiteur>| et \verb|\<macro>|
	\item manger l'accolade ouvrante qui suit
	\item initialiser \verb|\alter@toks| à vide
	\item lire avec \idx\futurelet le prochain token \verb|\alter@nxttok|
	\item tester \verb|\alter@nxttok|
	\begin {algo}
		\item si c'est une accolade fermante, la fin de l'argument est donc atteinte, aller à la macro de fin \verb|\alter@stop|
		\item si c'est un espace : absorber cet espace et ajouter un espace à \verb|\alter@toks|
		\item si c'est une accolade ouvrante
		\begin{algo}
			\item ouvrir un groupe
			\item modifier localement la macro de fin \verb|\alter@stop| pour qu'elle rajoute à \verb|\alter@toks| le contenu local de \verb|\alter@toks| enveloppé d'accolades puis qu'elle ferme le groupe et aille au point \no5
			\item aller au point \no3
		\end{algo}
		\item si c'est \verb|<délimiteur>| : ouvrir un groupe semi-simple, changer les catcodes de tous les octets pour 12, ajouter tous les tokens jusqu'à la prochaine occurrence de ce délimiteur après avoir fermé le groupe (toutes ces opérations sont faites par une macro à arguments délimités)
		\item dans les autres cas, le token à lire ne demande aucune action particulière : le manger et l'ajouter à \verb|\alter@toks|
	\end{algo}
	\item dans tous les cas ci-dessous sauf le c, aller au point \no5
\end{algo}

Les cas \no b, c et e ont déjà été vus avec la macro §\parse. Ici, il n'y a donc que deux cas supplémentaires à traiter, les cas \no a et d.

\label{alter}\showcode/\catcode`\@11
\newtoks\alter@toks% collecteur de tokens

\def\alter#1#2{% #1= délimiteur  #2 = macro à altérer¤§*\alter¤
	\let\alter@macro#2% sauvegarde la macro
	\edef\alter@restorecatcode{% restaurera le catcode de #1
		\catcode`\noexpand#1=\the\catcode`#1 }%¤\idx*\noexpand\idx*\the¤
	\edef\alter@tmp{\let\noexpand\alter@markertoks= \string#1}%¤\idx*\string¤
	\alter@tmp% et sauvegarder le délimiteur après avoir mis son catcode à 12
	\edef\alter@tmp{\def\noexpand\alter@readlitterate@i\string#1####1\string#1}%¤\idx*\string\idx*\noexpand¤
	% développe les \string#1 pour que les arguments délimités aient
	% des délimiteurs de catcode 12¤\idx*{catcode!12\space(autre)}¤
	\alter@tmp{% <- comme si on écrivait "\def\alter@readlitterate@i#1##1#1"
		\endgroup% après avoir lu ##1 (tokens rendus inoffensifs), fermer le groupe
		\addtotoks\alter@toks{{\tt##1}}% ajouter ces tokens¤§*\addtotoks¤
		\alter@i% et aller lire le prochain token
	}%
	\alter@toks{}% initialise le collecteur de tokens
	\afterassignment\alter@i% aller lire le premier token après avoir¤\idx*\afterassignment¤
	\let\alter@tmptok= % mangé l'accolade ouvrante de l'<argument> qui suit
}

\def\alter@i{% lit le prochain token et va à \alter@ii
	\futurelet\alter@nxttok\alter@ii}%¤\idx*\futurelet¤

\def\alter@ii{% teste le token qui doit être lu
	\ifxcase\alter@nxttok% si le token à lire est¤§*\ifxcase¤
		\egroup           \alter@stop% "}" : aller à \alterstop@i¤\idx*\egroup¤
		\sptoken          \alter@readspc% " " : aller à \alter@readspc¤§*\sptoken¤
		\bgroup           \alter@readarg% "{" : aller à \alter@readarg¤\idx*\bgroup¤
		\alter@markertoks \alter@readlitterate% "<delimiteur>" : aller à \alter@readlitterate
	\elseif¤§*\elseif¤
		\alter@readtok% dans les autres cas, aller à \alter@readtok
	\endif¤§*\endif¤
}

\def\alter@readlitterate{% le prochain token est le délimiteur
	\begingroup% ouvrir un groupe
	\for\alter@tmp=0to255\do{\catcode\alter@tmp=12 }%¤§*\for¤
	% mettre tous les catcodes à 12
	\defactive{ }{\ }% sauf l'espace rendu actif¤§*\defactive¤
	\doforeach\alter@tmp\in{<,>,-,`,{,},'}% pour chaque motif de ligature¤§*\doforeach\idx{ligature}¤
			{\unless\if\alter@tmp\alter@markertoks% s'il est différent du délimiteur¤\tidx*{unless}¤
				% le rendre actif pour éviter la ligature
				\expandafter\alter@defligchar\alter@tmp
			\fi
			}%
	\alter@readlitterate@i% puis aller à \alter@readlitterate@i...
	% ...qui a été définie dans \alter
}

\def\alter@defligchar#1{% définit le caractère pour ne pas provoquer de ligature¤\idx*{ligature}¤
	\defactive#1{\string#1{}}%¤§*\defactive\idx*\string¤
}

\expandafter\def\expandafter\alter@readspc\space{% mange un espace dans le code¤\idx*\space¤
	\addtotoks\alter@toks{ }% ajoute l'espace¤§*\addtotoks¤
	\alter@i% puis lire le token suivant
}

\def\alter@readarg{% le token qui suit est "{"
	\begingroup% ouvrir un groupe
	\def\alter@stop@ii{% et modifier localement la macro appelée à la toute fin,
	% après que l'accolade fermante ait été mangée (par \alterstop@i)
		\expandafter\endgroup% retarder la fermeture de groupe ouvert ci-dessus
		\expandafter\addtotoks\expandafter\alter@toks\expandafter¤§*\addtotoks¤
			{\expandafter{\the\alter@toks}}%¤\idx*\the¤
		% pour ajouter hors du groupe ce qui a été collecté à l'intérieur,
		% le tout mis entre accolades
		\alter@i% puis, lire le token suivant
	}%
	\alter@toks{}% au début du groupe, initialiser le collecteur
	\afterassignment\alter@i% aller lire le prochain token après¤\idx*\afterassignment¤
	\let\alter@tmptok= % avoir mangé l'accolade ouvrante
}

\def\alter@readtok#1{% le prochain token ne demande pas une action spéciale
	\addtotoks\alter@toks{#1}% l'ajouter au collecteur¤§*\addtotoks¤
	\alter@i% et aller lire le token suivant
}

\def\alter@stop{% le token à lire est "}"
	\afterassignment\alter@stop@ii% aller à \alter@stop@ii après¤\idx*\afterassignment¤
	\let\alter@tmptok= % avoir mangé l'accolade fermante
}

\def\alter@stop@ii{% donner à la \<macro> tout ce qui a été récolté
	\expandafter\alter@macro\expandafter{\the\alter@toks}%¤\idx*\the¤
	\alter@restorecatcode% puis restaure le catcode du délimiteur
}
\catcode`@12

\frboxsep=1pt ¤§*\frboxsep¤
\alter|\frbox{Texte normal - |#& }| - texte normal - |_^ ##| - texte normal}¤§*\frbox¤
\alter=\frbox{La macro =\alter= autorise du verbatim dans
des commandes imbriquées \frbox{comme ici =\alter=}.}¤§*\alter¤/

Nous avons considéré que la \verb|\<macro>| à altérer n'avait qu'un seul argument. Or, il serait commode de pouvoir altérer les macros à plusieurs arguments de façon à mettre du \idx{verbatim} dans n'importe lequel de leurs arguments. C'est ici que la macro §\identity (voir page~\pageref{identity}) peut résoudre ce problème. Il suffira de placer la macro à altérer ainsi que ses arguments dans l'argument de §\identity :

\showcode/\def\hello#1#2{Bonjour #1 et  #2 !}
\hello{foo}{bar}\par
\alter|\identity{\hello{macro |{{{\foo|}{macro |\bar}|}}¤§*\alter §*\identity¤/\idx*[|)]{verbatim}

\section{Modifier les catcodes des arguments déjà lus}
La règle de la page~\pageref{catcode.inalterable} était pourtant claire : dès que \TeX{} lit un token, il lui affecte de façon inaltérable un code de catégorie\idx*{argument!catcode figé}. Il était même précisé que ce mécanisme est incontournable. Le titre de cette section pose donc des interrogations quant au moyen utilisé.

\subsection{Technique de «écriture-lecture»}
Ce moyen consiste à enregistrer des tokens dans un fichier auxiliaire puis lire ce fichier. En effet, lorsqu'on enregistre du code dans un fichier, celui-ci, après éventuel développement, est « détokénisé », c'est-à-dire que n'en subsistent que les caractères (au sens d'octet) qui le formaient. Les catcodes, caractéristiques de \TeX, sont perdus à l'enregistrement. Par la suite, lors de la lecture d'un fichier, les octets qui le composent sont lus par \TeX{} et transformés en tokens selon le régime de catcode en cours à ce moment.

Cette astuce redonne à n'importe quel ensemble de tokens une sorte de virginité puisqu'on peut les relire à n'importe quel moment --~y compris dans le texte de remplacement d'une macro~-- pour qu'ils se colorent des catcodes en vigueur.

On peut l'observer en utilisant la macro §\frbox en mettant dans son argument macro §\retokenize qui enregistre les tokens de son argument (déjà lus par la macro §\frbox) dans un fichier puis les relit :

\showcode/\def\retokenize#1{%¤§*\retokenize¤
	\immediate\openout\wtest=retokenize.tex % ouvre le fichier¤\idx*\immediate\idx*\openout¤
	\immediate\write\wtest{\unexpanded{#1}}%  y écrit l'argument¤\idx*\unexpanded¤
	\immediate\closeout\wtest% ferme le fichier¤\idx*\immediate\idx*\closeout¤
	\input retokenize.tex % lit le fichier selon les catcodes en vigueur¤\idx*\input¤
	\unskip% mange l'espace précédemment ajouté qui provient de la fin du fichier¤\idx*\unskip¤
}
\frboxsep=1pt
1) \frbox{Programmer en \catcode`\~=12 \TeX{} est~facile et~utile.}\par¤§*\frbox¤
2) \frbox{Programmer en \retokenize{\catcode`\~=12 \TeX{} est~facile} et~utile.}\par
3) \frbox{Programmer en \catcode`\~=12 \retokenize{\TeX{} est~facile} et~utile.}¤§*\frbox§*\retokenize¤/

Le cas \no1 montre bien que «\cidx\~» ne change pas de catcode dans l'argument de la macro §\frbox puisqu'il ne prend jamais le catcode 12\idx*{catcode!12 (autre)} pour donner l'affichage «\cidx\~». Il ne le prend pas non plus à l'extérieur du texte de remplacement de cette macro, car §\frbox enveloppe son argument dans des boites qui jouent le rôle de groupe.


Au contraire, les cas \nos2 et 3 mettent en évidence que la relecture du fichier «\texttt{retokenize.tex}» se fait avec les catcodes en cours. Le fichier est lu avec \cidx\~ de catcode 12\idx*{catcode!12 (autre)} pour le cas \no2 tandis que pour le cas \no3, le changement de catcode est inclus dans le fichier ce qui ne change rien au résultat final.

Il faut bien avoir conscience que la relecture du fichier se fait \emph{après} que l'argument de §\frbox ait été lu. Cette lecture d'argument s'accompagne d'irrémédiables pertes d'information (par exemple des espaces consécutifs lus comme un seul espace). De plus, la lecture d'un fichier provoque une altération qui lui est propre : si ce n'est pas déjà le cas, un espace est inséré après toute séquence de contrôle lue dans le fichier. Cet espace ajouté n'a aucune incidence si le code est \emph{exécuté} car les espaces sont ignorés lorsqu'ils suivent une séquence de contrôle. Le seul cas où cet espace peut devenir gênant est lorsqu'on compose du « \idx{verbatim} » en provenance d'un fichier. L'exemple montre avec §\litterate la double altération que subit le code : la première rend plusieurs espaces consécutifs égaux à un seul espace et l'autre insère un espace après la macro \idx\TeX. Les deux arguments des cas \no1 et 2, bien que et  présentant plusieurs différences, sont rendus de la même façon :

\showcode/\frboxsep=1pt ¤§*\frboxsep¤
1) \frbox{Programmer \retokenize{\litterate|en \TeX {} est |}facile et utile.}\par¤§*\frbox§*\litterate§*\retokenize¤
2) \frbox{Programmer \retokenize{\litterate|en    \TeX{} est |}facile et utile.}¤§*\frbox§*\litterate§*\retokenize¤/

\subsection{La primitive \texttt{\char`\\scantokens}}\idx*[|(]{\scantokens}
Le moteur \eTeX{}\idx*{moteur!etex} dispose de la primitive \verb|\scantokens{<texte>}| qui agit comme la macro §\retokenize avec quelques petites différences :

\begin{itemize}
	\item l'écriture a lieu dans un fichier \emph{virtuel}, c'est-à-dire qu'aucun fichier n'est créé sur le disque dur et en réalité, tout se passe dans la mémoire de \eTeX{};
	\item la primitive \verb|\scantokens| est développable et son 1-développement est l'ensemble des tokens qui sont dans son argument, remis au gout du régime de catcode en cours;
	\item comme toutes les primitives devant être suivies d'une accolade, \verb|\scantokens| procède à un développement maximal jusqu'à rencontrer l'accolade ouvrante.
\end{itemize}

\showcode/\frboxsep=1pt ¤§*\frboxsep¤
1) \frbox{Programmer en \catcode`\~=12 \TeX{} est~facile et~utile.}\par¤§*\frbox¤
2) \frbox{Programmer en \scantokens{\catcode`\~=12 \TeX{} est~facile} et~utile.}\par¤\idx*\scantokens¤
3) \frbox{Programmer en \catcode`\~=12 \scantokens{\TeX{} est~facile} et~utile.}\par
4) \frbox{Programmer \scantokens{\litterate|en \TeX {} est facile|} et utile.}\par¤§*\litterate¤
5) \frbox{Programmer \scantokens{\litterate|en    \TeX{} est facile|} et utile.}¤§*\frbox\idx*\scantokens§*\litterate¤/

\begin{exercice}
Expliquer d'où vient l'espace en trop entre les mots «facile» et «et» des cas \no2-5 de l'exemple précédent ainsi que l'espace parasite entre lettres «a» et «b» ci-dessous :

\showcode/\scantokens{a}b/
\solution
Il provient du \idx{caractère de fin de ligne}\idx*{fin de ligne} qui est inséré à la fin de chaque ligne. Ici, le fichier virtuel est constitué d'une seule ligne contenant «a» et le caractère de code \idx\endlinechar est inséré à la fin de cette ligne. Par défaut, ce caractère est «\verbidx*[ (retour charriot)]{^^M}\verb|^^M|», de catcode 5\idx*{catcode!5 (retour charriot)}, qui est lu comme un espace. On peut donc définir localement \idx\endlinechar comme entier négatif pour le neutraliser :

\showcode/\begingroup\endlinechar=-1 \scantokens{a}b\endgroup¤\idx*\scantokens\idx*\endlinechar¤/
\end{exercice}

\subsection{\texttt{\char`\\scantokens} : erreurs en vue}
Le fonctionnement est clair, mais une erreur surprenante est émise lorsque l'on tente de développer \verb|\scantokens| dans le texte de remplacement d'une macro :

\errcode/\edef\foo{\scantokens{Bonjour le monde}}% produit une erreur/{! File ended while scanning definition of \string\foo.}

\noindent Si l'on réitère l'expérience en ne la développant qu'une seule fois, la même erreur survient :

\errcode/\expandafter\def\expandafter\foo\expandafter
	{\scantokens{Bonjour le monde}}% produit une erreur/{! File ended while scanning definition of \string\foo.}

Il arriverait une erreur similaire si l'on écrivait :

\centrecode-\toks0=\expandafter{\scantokens{Bonjour le monde}}-\idx*\toks
\noindent et on obtiendrait «\texttt{! File ended while scanning text of \string\toks.}»

Comme \verb|\scantokens| agit un peu comme \idx\input, il en partage aussi les secrets (voir page~\pageref{input.secrets}). Le lecteur qui avait sauté la lecture de cette section ou qui n'en a plus qu'un vague souvenir est invité à s'y replonger. L'essentiel à retenir est que la fin d'un fichier --~virtuel ou pas~-- est «\idx\outer». Ici, \TeX{} se plaint, car cette fin de fichier se trouve à des endroits qui lui sont interdits par son statut d'\idx\outer.

Le remède pour la fin d'un fichier virtuel \idx\outer est le même que pour la fin d'un fichier réel présent dans le texte de remplacement d'une macro : il suffit de placer un \idx\noexpand juste avant la fin de ce fichier et de s'assurer qu'il sera développé \emph{avant} que la définition de la macro ne se fasse. Ceci implique donc qu'il \emph{faut} utiliser la macro \verb|\edef| :

\begingroup\edef\foo{Bonjour le monde}
\showcode/¤\litterate|\edef\foo{\scantokens{Bonjour le monde\noexpand}}|§*\litterate\idx*\noexpand¤
Voici la macro \string\foo\ : \foo.¤\idx*\string¤/
\endgroup

Utiliser \verb|\edef| comporte l'inconvénient de développer la totalité de l'argument alors que finalement, seul le \idx\noexpand final aurait besoin d'être développé. Comme nous l'avions fait avec \idx\input, il est possible de construire une macro §\scandef ayant la syntaxe suivante

\centrecode-\scandef\<macro>{<texte>}-

\noindent et qui met le 1-développement de \verb|\scantokens{<texte>}| dans le texte de remplacement de \verb|\<macro>|. Nous allons utiliser le même artifice qu'avec \idx\input (voir page~\pageref{input.dans.macro}) et nous servir de \idx\everyeof pour placer un \verb|\@nil| à la fin du fichier virtuel. Ce \verb|\@nil| sera utilisé par une macro auxiliaire comme délimiteur d'argument:

\showcode/\catcode`\@11
\def\scandef#1#2{% #1=\<macro>   #2=<texte>¤§*\scandef¤
	\begingroup
		\endlinechar=-1 % pas de caractère de fin de ligne¤\idx*\endlinechar\idx*{caractère de fin de ligne}¤
		\everyeof{\@nil#1\noexpand}% ajoute "\@nil\<macro>\noexpand" avant la fin du fichier¤\idx*\everyeof\idx*\noexpand¤
		\expandafter\scandef@i\expandafter\relax\scantokens{#2}%¤\idx*\scantokens¤
}
\def\scandef@i#1\@nil#2{% "\@nil#2" ont été ajouté par \everyeof
	\endgroup% ferme le groupe
	\expandafter\def\expandafter#2\expandafter{\gobone#1}% et définit la \<macro>
}
\catcode`@12
\def\foo{%
	Dans tout l'argument de \string\foo, <<~>> est actif¤\idx*\string¤
	sauf
	\catcode`\~12
	\scandef\bar{dans celui de \string\bar : <<~>>}%¤\idx*\string§*\scandef¤
	\catcode`~13
	\bar
}
\foo/

\noindent Toute l'astuce réside dans «\idx\everyeof\verb|{\@nil#1\noexpand}|» qui demande que soit ajouté avant la fin du fichier un \verb|\@nil| et la \verb|\<macro>| (qui est \verb|#1|), le tout suivi de \idx\noexpand. Par conséquent, la ligne

\centrecode-\expandafter\scandef@i\scantokens{<texte>}-

\noindent se développe en

\centrecode-\scandef@i<texte relu par \scantokens>\@nil\<macro>\noexpand<EOF>-

\noindent et la macro à argument délimité \verb|\scandef@i| n'a plus qu'à saisir les arguments délimités pour, une fois sorti du groupe, définir la \verb|\<macro>| sans jamais avoir à lire la fin du fichier \verb|<EOF>| qui de toute façon, est neutralisée par \idx\noexpand.
\grandsaut

La chronologie qui se met en place lorsque \verb|\scantokens|\linebreak[1]\verb|{<code>}| est exécuté est la suivante :

\begin{itemize}
	\item insertion du caractère de code \idx\endlinechar après tous les retours à la ligne, y compris après la dernière;
	\item transformation du code qui en résulte en tokens;
	\item insertion du code contenu dans \idx\everyeof à la fin de ce qui va être lu par \verb|\scantokens|.
\end{itemize}

On peut constater que le point \no1 est bien celui qui est exécuté en premier avec ce code assez amusant où la lettre «\verb|d|» de \idx\noexpand est ajoutée par \idx\endlinechar :

\begingroup
\edef\foo{Bonjour le monde}
\showcode/{%
\endlinechar=`\d% insère la lettre "d" à chaque fin de ligne¤\idx*\endlinechar¤
¤\litterate|\edef\foo{\scantokens{Bonjour le monde\noexpan}}|¤% le \noexpan(d) est incomplet
Voici la macro \string\foo\ : \foo.% fins de ligne...¤\idx*\string¤
}% ...commentées pour éviter le "d"/
\endgroup

\begin{exercice}
Utiliser \verb|\scantokens| pour programmer une macro §\cprotect (le «\verb|c|» signifiant «catcode»), dont la syntaxe est

\centrecode-\cprotect\<macro>{<argument>}-

\noindent et qui appelle la \verb|\<macro>| de cette façon :

\centrecode-\<macro>{\scantokens{<argument>\noexpand}}-

Comme l'\verb|<argument>| est relu par \idx\scantokens, l'intérêt de cette macro est qu'elle permet d'utiliser §\litterate dans l'\verb|<argument>|. De façon plus générale, §\cprotect permet de changer des catcodes dans l'\verb|<argument>| de la \verb|\<macro>|.
\solution
La primitive \verb|\scantokens| va évidemment considérablement simplifier la méthode, mais va aussi changer les limites de la macro comme nous le verrons, de telle sorte que §\cprotect ne peut pas être qualifié d'équivalent de la macro §\alter vue précédemment.

Tout d'abord, nous allons lire l'\verb|<argument>| après avoir rendu les catcodes de tous les octets égaux à 12, sauf celui de l'accolade ouvrante et de l'accolade fermante qui gardent leurs catcodes de 1 et 2 afin justement de pouvoir délimiter l'argument et de rendre possible sa lecture. La suite est simple : l'argument ainsi lu sera retokénisé par \verb|\scantokens| et donné comme argument à la \verb|\<macro>|.

\showcode/\catcode`\@11
\def\cprotect#1{% #1 est la \<macro>¤§*\cprotect¤
	\def\cprotect@i##1{% ##1 est l'<argument>
		\endgroup% ferme le groupe précédemment ouvert
		#1{\scantokens{##1\noexpand}}%¤\idx*\scantokens\idx*\noexpand¤
	}%
	\begingroup% rend tous les octets de catcode12
		\for\cprotect@temp=0to255\do{\catcode\cprotect@temp=12 }%¤§*\for¤
		\catcode`\{=1 \catcode`\}=2 % sauf "{" et "}"
		\cprotect@i% puis, lit l'argument
}
\catcode`@12
\frboxsep=1.5pt ¤§*\frboxsep¤
1) \cprotect\frbox{foo \litterate-&#  #^   ^_%- bar}\par¤§*\litterate§*\frbox¤
2) \cprotect\frbox{\catcode`\~=12 a~b~c~d}\par
3) \cprotect\frbox{foo \litterate-\bar- \cprotect\frbox{\litterate-&#   #-} fin}¤§*\cprotect§*\frbox§*\litterate¤/

La macro §\cprotect, malgré sa grande simplicité, présente trois limitations principales :

\begin{enumerate}
	\item l'\verb|<argument>| ne doit pas contenir d'accolade ouvrante ou fermante non équilibrée, et donc le texte traité par §\litterate doit également obéir à cette contrainte. Y contrevenir tromperait \TeX{} sur la portée de l'\verb|<argument>| car lors de la lecture de cet \verb|<argument>|, les accolades ont leurs catcodes normaux.
	\item §\cprotect ne peut agir que sur une macro admettant un seul argument puisque \verb|\cprotect@i| a été définie comme lisant et traitant un unique argument. Il n'est pas possible de contourner cette limitation comme on le faisait avec §\identity pour la macro §\alter. En revanche, il aurait été possible de programmer la macro §\cprotect différemment afin de mettre entre les accolades la liste des arguments de la \verb|\<macro>| :

\centrecode-\cprotect\<macro>{{argument 1}{argument 2}...}-§*\cprotect

	\item on a considéré que l'\verb|<argument>| était entre accolades, sans envisager le cas d'autres caractères de catcode 1\idx*{catcode!1 (accolade)} ou 2. Pour bien faire, on n'aurait dû changer le catcode d'un caractère que s'il est différent de 1 ou 2. La boucle §\for aurait donc dû être programmée ainsi :
	
\centrecode-\for\cprotect@temp=0to255\do{%
	\unless\ifnum\catcode\cprotect@temp=1
		\unless\ifnum\catcode\cprotect@temp=2
			\catcode\cprotect@temp=12
		\fi
	\fi}-
\end{enumerate}

Selon les besoins et les limitations dont on veut s'affranchir, il convient donc de s'orienter vers §\cprotect ou §\alter.
\end{exercice}

\begin{exercice}
Comment modifier le code de §\cprotect pour permettre à la \verb|\<macro>| d'avoir plusieurs arguments et offrir la syntaxe qui est donnée au point \no2 de la solution précédente?
\solution
Appelons §\Cprotect cette macro. La stratégie consiste à parcourir la liste des arguments, et les stocker sous la forme

\centrecode-{\scantokens{<argument>\noexpand}}-

\noindent dans un registre de tokens qui accumulera ces arguments de telle sorte qu'à la fin du processus, ce registre contienne

\centrecode-\<macro>{\scantokens{#1\noexpand}}{\scantokens{#2\noexpand}}etc...-

\noexpand Une fois tout ceci fait, le contenu du registre sera exécuté avec \idx\the.

La principale difficulté est de parcourir tous les arguments et gérer d'une façon ou d'une autre la fin de la liste. Ici, le \idx{quark} §\quark est mis comme dernier argument. Une macro récursive lira un argument à la fois et avant d'agir, fera un test pour déterminer si tous les arguments ont été traités (cas où l'argument lu est \verb|\ifx|-égal à §\quark). Il faut également tenir compte du fait que chaque argument est dépouillé de ses éventuelles accolades lorsqu'il est lu par une macro.

Le registre de token \no0 tiendra lieu d'accumulateur.

\showcode/\catcode`@11
\def\Cprotect#1{% #1 est la \<macro>¤§*\Cprotect¤
	\def\Cprotect@i##1{% ##1 est la liste des arguments
		\endgroup% ferme le groupe précédemment ouvert
		\toks0={#1}% met la \<macro> dans le registre de tokens¤\idx*\toks¤
		\Cprotect@ii##1\quark% \quark est mis à la fin des arguments¤§*\quark¤
		\the\toks0 % exécute le registre¤\idx*\the\idx*\toks¤
	}%
	\begingroup% rend tous les octets de catcode12
		\for\temp@arg= 0 to 255 \do{% changer à 12 tous les catcodes¤§*\for¤
			\unless\ifnum\catcode\temp@arg=1 % sauf si catcode=1¤\tidx*{unless}¤
				\unless\ifnum\catcode\temp@arg=2 % ou 2
					\catcode\temp@arg=12
				\fi
			\fi}%
		\Cprotect@i% puis, lit l'argument
}
\def\Cprotect@ii#1{% #1 est l'argument courant (dépouillé de ses accolades)
	\def\temp@arg{#1}% stocke l'argument pour le tester ci dessous :
	\unless\ifx\quark\temp@arg% si la fin n'est pas atteinte¤\tidx*{unless} §*\quark¤
		% ajouter "{\scantokens{#1\noexpand}}" au registre
		\addtotoks{\toks0}{{\scantokens{#1\noexpand}}}%¤§*\addtotoks\idx*\toks\idx*\noexpand¤
		\expandafter\Cprotect@ii% et recommencer
	\fi
}
\catcode`@12

\def\test#1#2{Bonjour #1 et #2}
\Cprotect\test{{argument 1 : \litterate-\foo-}{argument 2 : \litterate-\bar-}}¤§*\Cprotect §*\litterate¤/
\end{exercice}\idx*[|)]{\scantokens}

\chapter{Aller plus loin avec des réglures}
Les réglures, qui ne sont par définition que de simples rectangles noirs peuvent, moyennant un peu d'imagination, être utilisées pour donner lieu à des effets plutôt originaux\ldots

\section{Créer une police Impact}\idx*[|(]{police Impact}
\subsection{Analyse du problème}
Le but ici est de créer de toutes pièces une « police » de type \impact[1pt] Impact\impactend{} comme il était courant d'en rencontrer du temps où les imprimantes à aiguilles (ou matricielles) étaient encore largement majoritaires. Leur fonctionnement est d'une grande simplicité : la tête d'écriture est constituée d'une ligne de fins picots --~les aiguilles~--, tous jointifs, alignés verticalement et actionnables indépendamment les uns des autres. Au fur et à mesure que la tête d'écriture se déplace par rapport à la page, les aiguilles sont brièvement actionnées, chacune imprimant un pixel lorsqu'elle exerce une pression sur le ruban encreur qui se trouve entre elle et la page. Voici l'effet que l'on obtient en rendant visibles les espaces entre les aiguilles :

\begin{centrage}
\impact[1.5pt][.5pt]La police Impact\impactend
\end{centrage}

La tête de lecture a deux caractéristiques qui lui sont données lors de sa fabrication : sa hauteur et le nombre d'aiguilles. Plus les aiguilles sont en grand nombre par unité de longueur, plus la résolution est importante et meilleure est la qualité d'impression.

Précisons tout de suite que nous allons \emph{dessiner} des caractères de toutes pièces, mais que \emph{stricto sensu}, nous n'allons pas créer une « \idx{police} » de caractères. En effet, toutes les fonctionnalités avancées des \emph{vraies} \idx{police}s ne seront pas présentes ici :

\begin{itemize}
	\item \idx{crénage}\footnote{C'est la possibilité de modifier (souvent réduire) l'espacement entre deux caractères en fonction de leur forme de telle sorte que l'ensemble soit plus esthétique. Ainsi «\hbox{AVATAR}» avec crénage est bien plus esthétique que «\hbox{A{}V{}A{}T{}A{}R}» sans crénage. Le mot avec crénage a une longueur de \setbox0\hbox{AVATAR}\the\wd0 {} alors que le mot sans crénage mesure \setbox0\hbox{A{}V{}A{}T{}A{}R}\the\wd0.} entre caractères;
	\item \idx{ligature}s;
	\item \idx*{coupure de mot}coupures des mots, même si les coupures n'ont rien à voir avec les polices, mais sont faites par \TeX{} en fonction de la position de certains groupes de lettres rencontrés dans le mot;
	\item différentes formes (italique, petites majuscules, etc.), graisse.
\end{itemize}

\noindent Il s'agit donc d'un abus de langage, certes volontaire, mais pas réellement malhonnête puisqu'on pourra dessiner les caractères que l'on veut et écrire de vraies phrases avec les dessins créés.

\subsection{Empilement de pixels}
Avec \TeX, ce qui va nous tenir lieu de point élémentaire et que nous dénommerons «\emph{pixel}, est une simple réglure carrée. Contrairement aux imprimantes, nous n'imposerons aucune limite sur le nombre de pixels qui composent un caractère, pas plus en hauteur, profondeur qu'en largeur, la seule limite étant finalement la patience de l'utilisateur à créer un caractère fait d'un grand nombre de pixels. Pour dessiner un pixel et correctement le positionner par rapport aux autres, il nous faut définir deux dimensions, §\pixelsize qui est le côté du carré et §\pixelsep qui est l'espacement entre deux pixels adjacents, aussi bien horizontalement ou verticalement.

Autant commencer par le plus facile et définir la macro §\pixel qui imprime un pixel carré en mode horizontal\idx*{mode!horizontal}, de telle sorte que le bord inférieur du carré coïncide avec la \idx{ligne de base} :

\centrecode-\def\pixel{\vrule height\pixelsize width\pixelsize depth0pt }-\idx*\vrule§*\pixelsep§*\pixelsize

Pour corser un peu plus l'exemple qui va suivre, on peut essayer d'empiler verticalement deux lignes de pixels au-dessus de la \idx{ligne de base}. Puisqu'on est au-dessus de cette \idx{ligne de base}, on va naturellement le faire dans une \idx\vbox et enfermer dans une \idx\hbox chaque ligne de pixels après l'avoir convenablement séparée de la précédente. Pour respecter l'espacement vertical entre les deux lignes de pixels, il suffira d'annuler le ressort d'interligne avec \idx\offinterlineskip puis de régler ce ressort d'interligne à §\pixelsep :

\showcode/\newdimen\pixelsize \newdimen\pixelsep¤\idx*\newdimen§*\pixelsep§*\pixelsize¤
\def\pixel{\vrule height\pixelsize width\pixelsize depth0pt }¤§*\pixel¤
\def\vblankpixel{\vrule height\pixelsize width0pt depth0pt }
\def\blankpixel{\vblankpixel \vrule height0pt width\pixelsize depth0pt }¤\idx*\vrule¤
\def\gap{\kern\pixelsep}
\pixelsize=3pt \pixelsep=1pt ¤§*\pixelsize§*\pixelsep¤
Essai :
\vbox{% aligne verticalement¤\idx*\vbox¤
	\offinterlineskip% annule le ressort d'interligne¤\idx*\offinterlineskip¤
	\lineskip=\pixelsep\relax% pour le mettre à \pixelsep¤\idx*\lineskip§*\pixelsep¤
	\hbox{\pixel\gap\blankpixel\gap\blankpixel\gap\blankpixel\gap\pixel}% 1re ligne¤\idx*\hbox¤
	\hbox{\pixel\gap\pixel     \gap\blankpixel\gap\pixel     \gap\pixel}% 2e ligne¤§*\pixel¤
}/

Les deux autres macros \verb|\blankpixel| et \verb|\vblankpixel| nous seront utiles par la suite et laissent un pixel blanc pour la première et un strut de la hauteur d'un pixel pour la seconde. La macro \verb|\gap| insère une espace insécable de la valeur de §\pixelsep et a vocation à être insérée  horizontalement entre deux pixels consécutifs, quelle que soit leurs couleurs.

Le code est clair et on comprend vite le principe. On voit ici que les pixels dessinés pourraient former le haut de la lettre

\begin{centrage}
\impact[3pt][1pt]M\impactend
\end{centrage}

\noindent Et l'on pourrait facilement écrire les lignes supplémentaires nécessaires pour afficher cette lettre en entier.

Remarquons que l'ordre d'affichage des pixels n'est pas celui des imprimantes à aiguilles : le caractère n'est pas imprimé par une succession de lignes de pixels verticales. Bien sûr, on pourrait procéder ainsi, mais les boites de \TeX{} nous facilitent la tâche si l'on s'y prend autrement. On va plutôt imprimer de haut en bas toutes les lignes de pixels (elles-mêmes imprimées de gauche à droite) nécessaires à la formation d'un caractère.

\subsection{Prise en compte de la ligne de base}
Il faut maintenant s'intéresser au respect de la \idx{ligne de base} si nous voulons imprimer un caractère comme \impact[1pt][0.4pt]g\impactend : il faut que le bas des pixels formant la partie inférieure de la boucle de la lettre «\impact[1pt][0.4pt]g\impactend» coïncide exactement avec la \idx{ligne de base} :

\begin{centrage}
	\quitvmode\rlap{\vrule width4cm height0.15pt depth0.15pt }%
	\kern2cm \clap{\impact[3pt][1pt]g\impactend}\kern 2cm
\end{centrage}

Pour cela, la même méthode que celle de §\frbox (voir page~\pageref{frbox.ligne.de.base}) va être déployée : une \idx\vbox sera insérée au sommet d'une \idx\vtop, ce qui revient à utiliser ce schéma :

\centrecode|\vtop{%¤\idx*\vtop¤
	\offinterlineskip \lineskip=\pixelsep ¤\idx*\offinterlineskip\idx*\lineskip§*\pixelsep¤
	\vbox{<lignes de pixels au-dessus de la ligne de base>}%¤\idx*\vbox¤
	<lignes de pixels au-dessous de la ligne de base>%
	}|

Voici un exemple où nous appliquons ce schéma pour construire la lettre «\impact[1pt][0.4pt]g\impactend» :

\showcode/\pixelsize=3pt \pixelsep=1pt ¤§*\pixelsize §*\pixelsep¤
Essai :
\vtop{%¤\idx*\vtop¤
  \offinterlineskip \lineskip=\pixelsep\relax¤\idx*\lineskip\idx*\offinterlineskip§*\pixelsep¤
  \vbox{%¤\idx*\vbox¤
    \hbox{\blankpixel\gap\pixel     \gap\pixel     \gap\pixel}%         ***¤\idx*\hbox §*\pixel¤
    \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
    \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
    \hbox{\pixel     \gap\blankpixel\gap\blankpixel\gap\pixel}%        *  *
    \hbox{\blankpixel\gap\pixel     \gap\pixel     \gap\pixel}%         ***
  }%                                                      ----ligne de base
  \hbox  {\blankpixel\gap\blankpixel\gap\blankpixel\gap\pixel}%           *
  \hbox  {\blankpixel\gap\pixel     \gap\pixel               }%         **¤§*\pixel¤
}/

La constatation qui s'impose est que définir un caractère avec cette méthode est extrêmement fastidieux et il n'est pas acceptable de l'utiliser pour définir toutes les lettres de l'alphabet.

\subsection{Créer une macro dont la syntaxe est facile}
\subsubsection{La macro \ttfamily\char`\\makecar}
Syntaxiquement, l'idéal serait d'inventer un moyen pour écrire les lignes de pixels « visuellement » les unes à la suite des autres. Il faudrait donc bâtir une macro §\makecar qui ressemblerait à ceci

\centrecode/\makecar\<macro>{%¤§*\makecar¤
 ***
*  *
*  *
*  *
 ***_
   *
 **,}/

\noindent et qui stockerait dans \verb|\<macro>| le code exposé dans l'exemple ci-dessus qui permet de tracer la lettre «\impact[1pt][0.4pt]g\impactend». Le caractère «\verb|_|» signifie, s'il est présent, que la ligne de pixels en cours s'achève et que les lignes suivantes doivent se trouver sous la \idx{ligne de base}.

Pour s'offrir cette syntaxe, la première chose à faire est de forcer \TeX{} à faire prendre en compte les espaces lorsqu'ils sont consécutifs ou placés en début de ligne. Ceci nous contraindra à changer localement le code de catégorie de l'espace à 12 pour qu'il échappe à la règle qui lui est fixée lorsque ce catcode est 10. Le retour charriot sera rendu actif et se développera en une virgule pour pouvoir utiliser par la suite la macro §\doforeach.

Enfin, il faut déterminer si «\verb|_|» est présent ou pas et si c'est le cas, scinder l'argument \verb|#2| en deux parties, chacune représentant les lignes de pixels au-dessus et au-dessous de la ligne de base.

\subsubsection{La macro \ttfamily\char`\\makecar@i}
Une macro privée \verb|\makecar@i| traitera une de ces parties en transformant «\verb|*|» en §\pixel, «\verb*| |» en §\blankpixel et en ajoutant \idx\kern§\pixelsep après chacune de ces macros, tout en insérant à la toute fin \idx\unkern pour annuler le dernier espace interpixel.

Par le truchement de §\doforeach, cette macro \verb|\makecar@i| appellera une autre macro auxiliaire \verb|\makecar@ii| qui sera chargée de transformer chaque ligne de pixels (une suite de \verb|*| et \verb*| |) en une série de §\pixel, §\blankpixel et §\gap. Elle enfermera le tout dans une \idx\hbox et ajoutera le code ainsi obtenu à une macro \verb|\pixabove| qui jouera le rôle de collecteur et qui sera affichée dans la \idx\vtop chapeau à la toute fin. L'écriture du code de cette macro privée ne présente pas de difficulté mais fait entrer en jeu quelques astuces.

\showcode/\catcode`\@11
\begingroup% dans ce groupe :¤\defline\aaa¤
\catcode`\ =12\relax% l'espace devient un "caractère autre"
\catcode`\^^M=13\relax% le retour à la ligne est actif¤\verbidx*[ (retour chariot)]{^^M}¤
\edef^^M{\string,}% et se développe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% définit un espace de catcode 12¤\idx*\global\idx*{catcode!12\space(autre)}§*\otherspc§*\deftok¤
\xdef\letter@code{% macro contenant le dessin de la lettre "e"¤\idx*\gdef¤
 **
*  *
***
*
 ***}%
\endgroup¤\defline\bbb¤

\def\makecar@i#1{% #1 = dessin de la lettre avec les caractères "," "*" et " "
	\doforeach\current@line\in{#1}% pour chaque ligne dans #1 :¤§*\doforeach¤
		{\ifx\empty\current@line% si la ligne est vide¤\idx*\empty¤
			\addtomacro\pixabove{\hbox{\vblankpixel}}% ajouter une fausse ligne¤§*\addtomacro¤
		\else% sinon
			\let\pix@line\empty% initialiser le code de la ligne à vide¤\idx*\empty¤
			\expandafter\makecar@ii\current@line\quark% et la construire¤§*\quark¤
		\fi
		}%
}

\def\makecar@ii#1{% #1=caractère de dessin de la ligne en cours
	\ifxcase#1% si le caractère est¤§*\ifxcase¤
		*        {\addtomacro\pix@line\pixel}%¤§*\addtomacro§*\pixel¤
		\otherspc{\addtomacro\pix@line\blankpixel}%¤§*\addtomacro§*\otherspc§*\blankpixel¤
	\endif
	\ifx#1\quark% si la fin est atteinte ¤§*\quark¤
		\addtomacro\pix@line\unkern% annuler le dernier espace interpixel¤\idx*\unkern¤
		\eaddtomacro\pixabove{% et encapsuler \pix@line dans une \hbox¤§*\eaddtomacro¤
		\expandafter\hbox\expandafter{\pix@line}}%¤\idx*\hbox¤
	\else% si la fin n'est pas atteinte, ajouter l'espace interpixel
		\addtomacro\pix@line\gap¤§*\addtomacro§*\gap¤
		\expandafter\makecar@ii% recommencer avec le caractère suivant
	\fi
}
\pixelsize=3pt \pixelsep=1pt ¤§*\pixelsize §*\pixelsep¤
\let\pixabove\empty% initialisation de la macro finale à vide
\exparg\makecar@i\letter@code% appelle la macro qui construit \pixabove¤\defline\ccc¤
La lettre
\vtop{% enferme le tout dans une \vtop :¤\idx*\vtop¤
	\offinterlineskip\lineskip=\pixelsep% ajuste l'espace interligne¤\idx*\offinterlineskip\idx*\lineskip§*\pixelsep¤
	\vbox{\pixabove}% affiche le caractère créé¤\idx*\vbox¤
}./

La partie la plus intéressante se situe dans le groupe semi-simple au début (lignes \nos\aaa{} à \bbb) où le code de catégorie de l'espace est changé à 12 et le celui du retour charriot est changé à 13 pour qu'il devienne actif. Cette altération de \verb|^^M| suppose que toutes les fins de ligne où l'on ne souhaite pas voir ce \verb|^^M| actif soient commentées, même celles que l'on ne commente habituellement pas (après une séquence de contrôle par exemple). Ces modifications locales faites, on peut donc tranquillement définir globalement la macro \verb|\letter@code| qui contient le code qui dessine la lettre «\verb|e|». On profite de ce groupe pour définir avec §\deftok la séquence de contrôle §\otherspc qui sera \verb|\let|-égale à un espace de catcode 12\idx*{catcode!12 (autre)} et qui servira dans un test \verb|\ifx| plus tard.

\subsubsection{Retour sur la macro \ttfamily\char`\\makecar}
On voit maintenant comment procéder lorsqu'il y a le marqueur «\verb|_|» qui indique que des pixels se trouvent au-dessous de la \idx{ligne de base}. Il faut séparer le code définissant le caractère en deux parties et agir de la même façon avec \verb|\makecar@i| sur chacune. Le code résultant de la première est voué à se retrouver dans la \idx\vbox tandis que celui résultant de la seconde est simplement ajouté dans la \idx\vtop chapeau.

Si une \verb|\<macro de dessin>| contient les éléments qui dessinent un caractère  à l'aide de «\verb|*|», «\verb*| |» et «\verb|^^M|» de catcode 12 et éventuellement «\verb|_|»), la macro §\makecar, de syntaxe

\centrecode-\makecar\<macro>\<macro de dessin>-§*\makecar

\noindent se chargera de stocker dans la \verb|\<macro>| le code résultant de l'analyse du texte de remplacement de \verb|\<macro de dessin>|. Le texte de remplacement de \verb|\<macro>| sera constitué de §\pixel, §\blankpixel et §\gap enfermés dans des \idx\hbox, elles-mêmes incluses dans une \idx\vtop.

\showcode/\catcode`\@11
\begingroup% dans ce groupe :¤\defline\aaa¤
\catcode`\ =12\relax% l'espace devient un "caractère autre"
\catcode`\^^M=13\relax% le retour à la ligne est actif¤\verbidx*[ (retour charriot)]{^^M}¤
\edef^^M{\string,}% et se développe en une virgule (de catcode 12)
\global\deftok\otherspc{ }% définit un espace de catcode 12¤\idx*\global\idx*{catcode!12\space(autre)}§*\otherspc§*\deftok¤
\xdef\letter@code{% macro contenant le dessin de la lettre "g"¤\idx*\gdef¤
 ***
*  *
*  *
*  *
 ***_
   *
 **}%
\endgroup¤\defline\bbb¤

\def\makecar#1#2{% #1=nom recevant le code final  #2=macro contenant le dessin¤§*\makecar¤
	\let\pixabove\empty \let\pixbelow\empty \let\pix@line\empty% initialise à vide¤\idx*\empty¤
	\exparg\ifin{#2}_% si le code contient _¤§*\ifin¤
		{\expandafter\makecar@iii#2\@nil}% aller à \makecar@iii
		{\exparg\makecar@i{#2}}% sinon, à \makecar@i
	\edef#1{% définit la macro #1 comme
		\vtop{% une \vtop contenant :¤\idx*\vtop¤
			\unexpanded{\offinterlineskip\lineskip\pixelsep}% réglage d'espace inter ligne¤\idx*\unexpanded\idx*\offinterlineskip\idx*\lineskip §*\pixelsep¤
			\vbox{\unexpanded\expandafter{\pixabove}}% \vbox des pixels au-dessus
			                                         % de la ligne de base¤\idx*\vbox\idx*\unexpanded¤
			\unless\ifx\pixbelow\empty% s'il y a des pixels au-dessous de la baseline¤\tidx*{unless}¤
				\unexpanded\expandafter{\pixbelow}% les ajouter dans la \vtop¤\idx*\unexpanded¤
			\fi
			}%
		}%
}

\def\makecar@iii#1_,#2\@nil{%
	\makecar@i{#2}% construit la partie au-dessous de la baseline
	\let\pixbelow\pixabove% et affecte le code à \pixbelow
	\let\pixabove\empty \let\pix@line\empty% ré-initialise¤\idx*\empty¤
	\makecar@i{#1}% construit la partie au-dessus de la baseline
}

\makecar\lettreg\letter@code¤§*\makecar¤
\catcode`\@12
\pixelsize=3pt \pixelsep=1pt ¤§*\pixelsize §*\pixelsep¤

Essai : \lettreg/

On voit clairement ce que fait la macro \verb|\makecar@iii|; elle construit séparément les lignes de pixels se trouvant au-dessous puis au-dessus de la \idx{ligne de base} et stocke les codes obtenus dans les séquences de contrôle \verb|\pixbelow| et \verb|\pixabove|. La macro §\makecar peut ensuite définir \verb|#1| en incluant \verb|\pixbelow| si elle n'est pas vide (cas où \verb|_| n'est pas présent). Cette définition se fait avec un \verb|\edef| en prenant soin de protéger avec \verb|\unexpanded| les endroits qui ne doivent pas être développés.

\subsubsection{Définir toutes les lettres}
L'étape suivante va être de finaliser le tout. Il faut d'abord trouver un moyen simple de définir toutes les lettres de l'alphabet. La macro \verb|\impact@alphabet|, contenant le code de toutes les lettres, pourrait être définie ainsi :

\centrecode|\def\impact@alphabet{¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
a/¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
<dessin de la lettre a>,¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
b/¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
<dessin de la lettre b>,¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
etc¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
Z/¤\bioLegacyKeyGlyph{E_n_t_e_r}¤
<dessin de la lettre Z>}|

Pour que les choses soient parfaitement claires, les retours charriots ne faisant pas partie du dessin des lettres sont explicitement écrits «\bioLegacyKeyGlyph{E_n_t_e_r}». Il est important de noter que dans le texte de remplacement de \verb|\impact@alphabet|, tous les \verb|^^M| sont actifs, \emph{mais non développés} en une virgule. Imaginons maintenant que l'on parcoure ce texte de remplacement avec une boucle de type §\doforeach :

\centrecode-\doforeach\letter@name/\letter@code\in
    {<texte de remplacement de \code@lettre>}-

\noindent À chaque itération, \verb|\letter@name| va contenir

\centrecode-¤\bioLegacyKeyGlyph{E_n_t_e_r}¤<lettre>-

\noindent et \verb|\letter@code|

\centrecode-¤\bioLegacyKeyGlyph{E_n_t_e_r}¤<dessin de la lettre>-

\noindent où les \bioLegacyKeyGlyph{E_n_t_e_r} sont ceux qui ne font pas partie du dessin de la lettre. Si l'on développe au maximum \verb|\letter@name| et \verb|\letter@code|, tous les retours charriots vont céder leur place à une virgule, et les textes de remplacement de \verb|\letter@name| et \verb|\letter@code| seront :

\begin{centrage}
	\verb|,<lettre>|\qquad et\qquad\verb|,<dessin de la lettre>|
\end{centrage}

Il faudra donc tester si ces textes de remplacement commencent par une virgule et dans l'affirmative, la supprimer.

\showcode|\catcode`\@11
\begingroup
\expandafter\gdef\csname impact@" "\endcsname{% définit la lettre "espace"
	\hskip 4\pixelsize plus.5\pixelsize minus.5\pixelsize\relax}%
\catcode`\^^M=13\relax% le retour à la ligne est actif¤\verbidx*[ (retour charriot)]{^^M}¤
\edef^^M{\string,}% et se développe en une virgule (de catcode 12)
\catcode`\ =12\relax% l'espace devient un "caractère autre"
\gdef\impact@alphabet{
a/
***
   *
 ***
*  *
****,
b/
*
*
***
*  *
*  *
*  *
***,
% beaucoup de caractères omis
9/
 ***
*   *
*   *
 ****
    *
    *
 ***,
0/
 ***
*   *
*   *
* * *
*   *
*   *
 ***,
error/
* * *
 * *
* * *
 * *
* * *
 * *
* * *}% <- commenter la fin de ligne
\endgroup%
% On parcourt le texte de remplacement de \impact@alphabet
\edef\saved@crcatcode{\catcode13=\the\catcode13\relax}%
\catcode`\^^M=13\relax% le retour à la ligne est actif¤\verbidx*[ (retour charriot)]{^^M}¤
\edef^^M{\string,}% et se développe en une virgule (de catcode 12)
\expsecond{\doforeach\letter@name/\letter@code\in}\impact@alphabet%¤§*\expsecond §*\doforeach¤
	{\edef\letter@name{\letter@name}% développe la lettre (^^M devient ",")
	\edef\letter@code{\letter@code}% développe le code (^^M devient ",")
	\exparg\ifstart\letter@name,% si la lettre commence par ","
		{\edef\letter@name{\expandafter\gobone\letter@name}}% la retirer
		{}%
	\exparg\ifstart\letter@code,% si le code commence par ","
		{\edef\letter@code{\expandafter\gobone\letter@code}}% la retirer
		{}%
	\expandafter\makecar\csname impact@"\letter@name"\endcsname\letter@code%¤§*\makecar\defline\aaa¤
	}%
\saved@crcatcode% redonne le catcode de ^^M
% % définit l'espace
\pixelsize=3pt \pixelsep=1pt ¤§*\pixelsize §*\pixelsep¤
% puis, on affiche ce qui a été défini :
a = \csname impact@"a"\endcsname\qquad b = \csname impact@"b"\endcsname\qquad
9 = \csname impact@"9"\endcsname \qquad 0 = \csname impact@"0"\endcsname\qquad
error = \csname impact@"error"\endcsname|

La méthode fonctionne correctement pour les caractères définis : bien évidemment, pour éviter un très long listing, seuls quelques uns sont définis ici.

Dans le code itéré de la boucle §\doforeach, remarquons à la ligne \no\aaa{} que \verb|\makecar| est invoqué et la macro contenant le code qui dessine le caractère «\verb|<car>|» est \verb|\impact@"<car>"|. Notons également que l'espace est défini comme un ressort horizontal de dimension fixe égale à 4 fois celle de §\pixelsize mais contenant aussi des composantes étirables égales à la moitié de §\pixelsize. Celles-ci peuvent entrer en jeu pour justifier le texte à composer à la largeur disponible en comblant la différence entre la largeur des caractères affichés sur la ligne et la largeur de composition.

Un caractère «\verb|error|» a également été dessiné au cas où l'on rencontrerait une lettre non définie.

\subsubsection{La macro \ttfamily\char`\\impact}
Tout cela va permettre de définir deux macros §\impact et \verb|\impactend| qui vont composer en police \impact Impact\impactend{} le \verb|<texte>| se trouvant entre elles selon cette syntaxe :

\centrecode/\impact[1.2pt][0.2pt]Programmer en {TEX} est
facile et tr{e`}s utile !\impactend/

Tout d'abord, pour composer ce livre, un caractère de la police impact dont le nom est «TEX» a été défini et le fait qu'il soit écrit entre accolades assure que l'ensemble est bien lu comme un argument et compris comme le nom d'un caractère. Le même principe s'applique aux caractères accentués «\verb|e`|», «\verb|e'|» et d'autres. Ensuite, la macro §\impact a deux arguments optionnels, le premier étant la dimension qui sera assignée à §\pixelsize et le second celle qui sera assignée à §\pixelsep. La macro §\newmacro que nous avons vue à la partie précédente sera utilisée afin que ces arguments optionnels soient facilement accessibles.

En reprenant la procédure mise en \oe uvre pour la macro §\parse, nous allons parcourir ce qui se trouve après la macro §\impact et, à l'aide de \idx\futurelet, nous déciderons quelle action entreprendre selon le type de token à venir :
\begin{enumerate}
	\item le \idx{quark} \verb|\impactend|;
	\item un espace;
	\item un argument commençant par une accolade.
\end{enumerate}

Le premier cas stoppera la lecture du texte. Pour les deux derniers cas, on insèrera après chaque caractère une espace qui est en réalité le ressort \verb|\letter@skip| défini par

\centrecode-\letter@skip=\pixelsep plus.1\pixelsize minus.1\pixelsize-§*\pixelsep

\noindent Les composantes de compression et d'étirement de l'espace interlettre, cumulées avec celles du caractère intermot «\verb*|\letter@" "|», assurent que les avertissements\idx*{message d'avertissement} de type \verb|Overful|/\linebreak[1]\verb|Underful hbox| qui caractérisent les lignes trop longues ou trop courtes seront le plus rare possible.

La façon de coder ce genre de macro a été vue à la partie précédente et il suffit de reproduire le schéma déjà étudié :

\showcode|\catcode`\@11
\newskip\letter@skip% ressort mis entre chaque lettre¤\idx*\newskip¤
\def\impactend{\impactend}% définit le quark de fin

\newmacro\impact[0.2ex][0pt]{% définit la macro à arguments optionnels¤§*\impact§*\newmacro¤
	\leavevmode% passer en mode horizontal¤\idx*\leavevmode¤
	\begingroup% dans un groupe semi-simple :
		\pixelsize=#1\relax \pixelsep=#2\relax% définir ces deux dimensions¤§*\pixelsize §*\pixelsep¤
		\letter@skip=#1 plus.1\pixelsize minus.1\pixelsize\relax% définir espace inter-lettre
		\baselineskip=% définir la distance entre les lignes de base¤\idx*\baselineskip¤
			\dimexpr12\pixelsize+7\pixelsep\relax% à 12\pixelsize+7\pixelsep
		\lineskiplimit=0pt % si lignes trop serrées¤\idx*\lineskiplimit¤
		\lineskip=2\pixelsize\relax% les espacer de 2\pixelsize¤\idx*\lineskip¤
		\impact@i% puis aller voir le prochain token
}

% va voir le prochain token puis va le tester à \impact@ii
\def\impact@i{\futurelet\nxtletter\impact@ii}¤\idx*\futurelet¤

\def\impact@ii{%
		\ifx\nxtletter\impactend% si le token est \let égal à \impactend
			\let\donext\impact@endprocess% aller à al macro de fin
		\else
			\ifx\nxtletter\sptoken% si c'est un espace¤§*\sptoken¤
				\let\donext\impact@spc% aller à \impact@spc
			\else
				\let\donext\impact@arg% sinon, aller à \impact@arg
			\fi
		\fi
		\donext% faire l'action décidée ci-dessus
}

% mange un espace (argument délimité) et affiche "\letter@<spc>"
\expandafter\def\expandafter\impact@spc\space{%¤\idx*\space¤
		\csname impact@" "\endcsname
		\impact@i% puis va voir le prochain token
}
% 
% lit l'argument suivant
\def\impact@arg#1{%
		\csname impact@% affiche
			\ifcsname impact@"#1"\endcsname¤\tidx{ifcsname}¤
				"#1"% le caractère \impact@"#1" s'il est défini
			\else
				"error"% sinon \impact@"error"
			\fi
		\endcsname
		\hskip\letter@skip% insérer le ressort inter-lettre¤\idx*\hskip¤
		\impact@i% puis, aller voir le prochain token
}
\def\impact@endprocess\impactend{% macro exécuté lorsqque le quark \impactend va être lu
		\unskip% annuler le dernier ressort¤\idx*\unskip¤
		\par% composer le paragraphe pour prendre en compte
		    % \baselineskip, \lineskip et \lineskiplimit
	\endgroup% et fermer le groupe
}
\catcode`\!=12 % rend le point d'exclamation "gentil"
\impact Programmer en {TEX} est facile et tr{e`}s utile !\impactend\par
\impact[2pt][0.5pt]Programmer en {TEX} est facile et tr{e`}s utile !\impactend¤§*\impact¤|

La valeur de \idx\baselineskip s'explique par le fait que tels qu'ils sont dessinés, les caractères alphanumériques de la police impact ont au maximum 9 pixels de \emph{hauteur totale}, où la hauteur totale est la somme de la hauteur et de la profondeur. L'encombrement vertical maximal d'un caractère est donc

\[9\times\verb|\pixelsize|+7\times\verb|\pixelsep|\]

Pour augmenter un peu l'espacement entre les lignes, on rajoute à cette dimension $3\times\verb|\pixelsize|$, ce qui donne la valeur de \idx\baselineskip choisie pour composer le paragraphe composé en police impact.

\idx*[|)]{police Impact}

\section{Tracer des graphiques}
Pourquoi vouloir tracer un graphique avec \TeX{} alors que des extensions très puissantes\footnote{Les deux plus connues sont PStricks et Ti\textit kz.} aux capacités quasi illimitées existent pour cela ? Il s'agit ici non pas de les concurrencer, mais de relever le défi et exploiter les maigres possibilités qu'offre \TeX{}, c'est-à-dire les réglures. Le but est de comprendre comment les placer précisément dans une zone. Voici par exemple ce qu'il est possible de faire :

\begin{centrage}
	\xunit=1cm \yunit=0.75cm
	\def\fonction#1{\dimtodec\dimexpr\decmul{#1}{\decmul{#1}{#1}}pt-%
		\decmul{#1}{#1}pt-#1pt*3+2pt\relax}%
	\graphzone{-2}[0.5]{2.5}[5]{-5}{5}[2]{%
		\let\plotstuff\cross% définit ce qu'il faut afficher comme point
		\FOR\xx=-2 to 2.5 \do 0.1{%
			\plot(\xx,\fonction{\xx})% afficher les points de coordonnées (x ; f(x))
		}%
		\putat{5pt}{\dimexpr\graphboxht-10pt\relax}% afficher
			{$\scriptstyle f(x)=x^3-x^2-3x+2$}% la fonction tracée
		\showaxis% et les axes
	}%
\end{centrage}

Le nombre de réglures est assez important et nous allons découper le problème en problèmes élémentaires avant de rassembler le tout à la fin.

La méthode qui va être notre fil directeur est de tracer \emph{toutes} les réglures et \emph{tous} les caractères après avoir rendu leurs dimensions nulles. Ainsi, pendant tout le tracé, le \idx{point de référence} reste le point inférieur gauche qui a pour coordonnées dans cet exemple \hbox{ $(-2{,}5\;\string;\;-5)$}. C'est seulement à la fin que l'on forcera une boite à prendre celle du graphique afin que la boite englobante\idx*{boite!englobante} du tout coïncide avec le rectangle représentant la zone graphique.

\subsection{Dessiner des axes gradués}\idx*[|(]{axe gradué}
Le premier problème est de tracer les axes gradués situés en bas et à gauche de la zone. \Qu els paramètres faut-il spécifier pour tracer un axe horizontal tel que celui-ci ?

\begin{centrage}
\leavevmode\xaxis[2cm]{-2}[2]{8}[4]
\end{centrage}

Une simple observation permet de répondre. Il faut :

\begin{enumerate}
	\item l'abscisse de départ et celle d'arrivée «\verb|xmin|» et «\verb|xmax|» (ici $-2$ et $8$);
	\item l'incrément «\verb|inc|» entre 2 graduations principales (ici $2$);
	\item le nombre de subdivisions «\verb|nb_subdiv|» (ici $4$);
	\item la distance «\verb|dist|» entre deux graduations principales (ici \numprint[cm]2);
	\item enfin, les dimensions des réglures proprement dites :\label{graphzone.non.arg}
	\begin{itemize}
		\item les dimensions verticales des traits représentant une division principale et une subdivision ;
		\item les épaisseurs des traits représentant une division principale et une subdivision ;
		\item l'épaisseur du trait horizontal représentant l'axe.
	\end{itemize}
\end{enumerate}

Nous allons décider que la macro §\xaxis va tracer un axe horizontal et que tous les arguments (sauf ceux du point \no\ref{graphzone.non.arg}) seront passés à la macro. Celle-ci aura 5 arguments (2 obligatoires et 3 optionnels) disposés selon cette syntaxe :

\centrecode-\xaxis[dist]{xmin}[inc]{xmax}[nb_subdiv]-§*\xaxis

Les 5 autres dimensions graphiques du point \no\ref{graphzone.non.arg} seront contenues dans des registres de dimension :

\begin{itemize}
	\item \verb|\maingraddim| et \verb|\subgraddim| pour les hauteurs des traits ;
	\item \verb|\maingradwd| et \verb|\subgradwd| pour leurs épaisseurs;
	\item \verb|\axiswd| pour l'épaisseur de l'axe.
\end{itemize}

Maintenant que la syntaxe est définie, passons au mécanisme de tracé proprement dit. Voyons d'abord comment tracer une graduation principale avec une abscisse située au-dessous. Pour le trait, nous utiliserons un \idx\rlap pour que sa dimension soit nulle. Pour le nombre affiché au-dessous, il sera l'argument de la macro et sera également affiché avec la macro §\clap, et abaissé de \verb|1.5ex| à l'aide de la primitive \idx\lower :

\showcode/\newdimen\maingraddim \maingraddim=4pt % hauteur des graduations principales¤\idx*\newdimen¤
\newdimen\maingradwd \maingradwd=0.5pt % épaisseur des graduations principales
\def\maingradx#1{%
	\lower1.5ex\clap{$\scriptscriptstyle#1$}% afficher l'argument au dessous¤\idx*\lower\idx*\scriptscriptstyle§*\clap¤
	\clap{\vrule height\maingraddim width\maingradwd depth0pt }% et la réglure¤\idx*\rlap\idx*\vrule¤
}
Début\maingradx{1}suite\maingradx{2}conclusion\maingradx{3}fin./

La longueur horizontale de l'axe sera

\[\text{\small\tt dist}\times\frac{\text{\small\tt xmax}-\text{\small\tt xmin}}{\text{\small\tt inc}}\]

Voici donc une ébauche de la macro §\xaxis :

\showcode|\maingraddim=4pt \maingradwd=0.5pt
\newdimen\axiswd \axiswd=0.5pt ¤\idx*\newdimen¤
\newmacro\xaxis[1cm]1[1]1[4]{%% #1= dist  #2=xmin  #3=inc  #4=xmax  #5=subdiv¤§*\xaxis§*\newmacro¤
	\hbox{% mettre le tout dans une \hbox¤\idx*\hbox¤
		\rlap{% en débordement à droite :
			\FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale¤§*\FOR¤
				\maingradx{\xx}% tracer la graduation et écrire l'abscisse
				\kern#1\relax% puis se déplacer vers la droite¤\idx*\kern¤
			}%
		}%
		\vrule% tracer l'axe des abscisses¤\idx*\vrule\defline\aaa¤
			height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
			width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax¤§*\decdiv§*\dimtodec¤
			depth 0pt\relax % et de profondeur nulle¤\defline\bbb¤
	}%
}
a) \xaxis{-2}{5}suite

b) \frboxsep=0pt\frbox{\xaxis[1.25cm]{-1}[0.25]{1}}suite¤§*\axis§*\frboxsep§*\frbox§*\xaxis¤|

Dans le deuxième cas, on constate en l'encadrant avec §\frbox que l'encombrement de l'axe est bon. C'est ce qui était recherché puisque la seule chose tracée ayant une dimension horizontale non nulle est l'axe lui-même, c'est-à-dire la \idx\vrule des lignes \nos\aaa-\bbb{}.

Il nous reste à insérer dans chaque boucle les graduations secondaires qui sont au nombre de \hbox{$\verb|#|5-1$}. Elles seront affichées en débordement à droite après chaque graduation principale, sauf pour la dernière. Préalablement à la boucle, elles seront stockées dans une \idx\hbox via le registre de boite \no0. Dans cette \idx\hbox, il doit y avoir $\verb|#5|-1$ fois ceci :

\begin{itemize}
	\item une espace de dimension \hbox{$\verb|#|1\div\verb|#|5$};
	\item une réglure de dimension nulle correspondant à la marque de subdivision.
\end{itemize}

Nous avons le choix pour remplir cette \idx\hbox avec ces $\verb|#5|-1$ répétitions. Soit nous faisons appel à \idx\leaders, soit à une boucle §\for. C'est cette deuxième alternative qui sera choisie ici :

\showcode|\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\newdimen\subgraddim \subgraddim=2.5pt ¤\idx*\newdimen¤
\newdimen\subgradwd \subgradwd=0.2pt
% trace un trait de subdivision
\def\subgradx{\clap{\vrule height\subgraddim width\subgradwd depth0pt }}¤\idx*\rlap\idx*\vrule¤

\newmacro\xaxis[1cm]1[1]1[4]{% #1= dist  #2=xmin  #3=inc  #4=xmax  #5=subdiv¤§*\xaxis§*\newmacro¤
	\hbox{% tout mettre dans une \hbox¤\idx*\hbox¤
		\setbox0=\hbox{% stocke dans une \hbox les grad secondaires entre 2 unités¤\idx*\setbox¤
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions¤\idx*\the¤
			\for\xx=1 to #5-1 \do{% insérer #5-1 fois¤§*\for¤
				\kern\dimsubgrad% une espace secondaire¤\idx*\kern¤
				\subgradx% une graduation secondaire
				}%
		}%
		\rlap{% en débordement à droite :
			\FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale¤§*\FOR¤
				\maingradx{\xx}% imprimer l'abscisse
				\ifdim\xx pt<#4pt % et en débordement à droite,
					\rlap{\copy0 }% les réglures secondaires, sauf pour la dernière¤\idx*\rlap\idx*\copy¤
				\fi
				\kern#1\relax% se déplacer vers la droite¤\idx*\kern¤
			}%
		}%
		\vrule% tracer l'axe des abscisses¤\idx*\vrule\defline\aaa¤
			height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
			width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax¤§*\decdiv§*\dimtodec¤
			depth 0pt\relax % et de profondeur nulle¤\defline\bbb¤
	}%
}
a) \xaxis{-2}{5}[2]

)b \xaxis[1.25cm]{-1}[0.25]{1}[5]¤\idx*\leavevmode§*\xaxis¤|

Retenons que la largeur de la \idx\hbox chapeau est la largeur de la zone graphique. Notons également que l'on \emph{ne peut pas} écrire

\centrecode|\setbox0\xaxis{-2}{5}[2]|§*\axis

\noindent car, contrairement aux apparences, la macro §\xaxis ne se développe pas en une \idx\hbox. Cela est dû à la façon dont §\newmacro construit les macros qui ont des arguments optionnels : des sous-macros sont créées et l'emploi de \idx\futurelet annule toute possibilité de développement maximal.

Passons maintenant aux axes verticaux. La méthode va être la même, sauf que toutes les primitives typées en mode horizontal\idx*{mode!horizontal} passeront cette fois en mode vertical\idx*{mode!vertical} : nous mettrons le tout dans une \idx\vbox et puisqu'elle sera remplie du haut vers le bas, il faudra commencer avec l'ordonnée de fin et construire une boucle §\FOR avec un incrément négatif.

La méthode utilisée avec §\yaxis pour l'affichage des ordonnées ne sera pas identiques à celles des abscisses : les dimensions des nombres représentant les ordonnées seront rendues nulles grâce à une \idx\llap. En effet, la dimension horizontale d'un nombre est variable alors que sa dimension verticale est constante. Réserver suffisamment d'espace à gauche de l'axe pour y placer les ordonnées aurait nécessité de calculer la plus grande dimension horizontale des ordonnées ce qui implique une boucle préalable. Il s'avère donc plus facile et plus économique d'ignorer cette dimension horizontale, quitte à rejeter hors de la boite englobante toutes les ordonnées.

\showcode|\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\def\maingrady#1{% affiche...
	\vlap{\llap{$\scriptscriptstyle#1$\kern2pt }}% l'ordonnée...¤§*\vlap \idx*\llap\idx*\scriptscriptstyle¤
	\vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la réglure¤\idx*\vbox\idx*\vss\idx*\hrule¤
}

% affiche une subdiv
\def\subgrady{\vlap{\hrule height\subgradwd width\subgraddim depth0pt }}¤§*\vlap\idx*\hrule¤
\newmacro\yaxis[1cm]1[1]1[4]{%
% #1= dist  #2=ymin  #3=inc  #4=ymax  #5=subdiv¤§*\yaxis§*\newmacro¤
	\vbox{%¤\idx*\vbox¤
		\offinterlineskip% désactiver le ressort d'interligne¤\idx*\offinterlineskip¤
		\setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 unités¤\idx*\setbox¤
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions¤\idx*\the¤
			\for\xx=1 to #5-1 \do{% insérer #5-1 fois¤§*\for¤
				\kern\dimsubgrad% une espace secondaire¤\idx*\kern¤
				\subgrady% une graduation secondaire
				}%
		}%
		\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% distance entre 2 subdivisions¤\idx*\the\idx*\dimexpr¤
		\vbox to 0pt{% en débordement vers le bas
			\FOR\xx = #4to#2\do-#3{%¤§*\FOR¤
				\maingrady{\xx}% imprimer l'abscisse
				\ifdim\xx pt>#2pt % et en débordement à droite,
					\vbox to 0pt{\copy0 \vss}% les réglures secondaires, sauf pour la dernière¤\idx*\copy\idx*\vss¤
				\fi
				\kern#1\relax% se déplacer vers la droite¤\idx*\kern¤
			}%
			\vss% assure le débordement vers le bas¤\idx*\vss¤
		}%
		\clap{\vrule% tracer l'axe des ordonnées
			width\axiswd% d'épaisseur \axiwd, et de hauteur (#4-#2)/#3*#1
			height\decdiv{\dimtodec\dimexpr(#4pt-#2pt)\relax}{#3}\dimexpr#1\relax¤§*\decdiv§*\dimtodec¤
			depth 0pt\relax % profondeur nulle
		}%
	}%
}

Essai : \yaxis{-2}{5}[2]\qquad \frboxsep=0pt \frbox{\yaxis[0.75cm]{-1}[0.5]{3}[5]}¤§*\frboxsep§*\frbox§*\yaxis¤|\idx*[|)]{axe gradué}

\subsection{Créer une zone pour le graphique}
Tout est maintenant prêt pour tracer notre zone graphique. Deux registres de dimension supplémentaires vont être créés, \verb|\xunit| et \verb|\yunit|, chacun spécifiant la distance entre deux graduations principales sur chacun des axes. La syntaxe de la macro va être proche des syntaxes de §\xaxis ou §\yaxis:

\centrecode-\graphzone{xmin}[xinc]{xmax}[nbsubdivx]{ymin}[yinc]{ymax}[nbsubdivy]{<code>}-§*\graphzone

\noindent où le \verb|<code>| contient les instructions graphiques que nous verrons plus tard et qui permettent de dessiner dans la zone.

\showcode|\newdimen\xunit \xunit=1cm ¤\idx*\newdimen¤
\newdimen\yunit \yunit=0.75cm
\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\catcode`@11
\newmacro\graphzone1[1]1[4]1[1]1[4]{%¤§*\graphzone§*\newmacro¤
	\leavevmode% quitter le mode vertical¤\idx*\leavevmode\idx*{mode!vertical}¤
	\begingroup% travailler dans un groupe semi-simple
		\def\graphxmin{#1}\def\graphxmax{#3}% sauvegarder
		\def\graphymin{#5}\def\graphymax{#7}% les
		\def\xincrement{#2}\def\yincrement{#6}% arguments
		\setbox0\hbox{\yaxis[\yunit]{#5}[#6]{#7}[#8]}% axe "y" dans boite 0¤\idx*\setbox§*\yaxis¤
		\setbox1\hbox{\xaxis[\xunit]{#1}[#2]{#3}[#4]}% axe "x" dans boite 1¤\idx*\setbox§*\xaxis¤
		\edef\graphboxht{\the\ht0 }% \graphboxh est la hauteur de la zone¤\idx*\the\idx*\ht¤
		\edef\graphboxwd{\the\wd1 }% \graphboxw est la largeur de la zone¤\idx*\wd¤
		\rlap{% annuler la dimension horizontale, et...¤\idx*\rlap¤
			\box1 % ...afficher l'axe (Ox) puis¤\idx*\box¤
			% le trait vertical à l'extrême droite de la zone
			\clap{\vrule height\dimexpr\graphboxht+\axiswd\relax width\axiswd depth0pt }%¤\idx*\vrule\idx*\dimexpr¤
			}%
		\rlap{\box0 }% afficher l'axe (Oy) en annulant sa dimension horizontale¤\idx*\rlap\idx*\box¤
		\raise\graphboxht% puis monter tout en haut de la zone¤\idx*\raise¤
			% pour tracer le trait horizontal en annulant sa longueur
			\rlap{\kern-0.5\axiswd% et en rattrapant le centrage de l'axe des ordonnées
				\vrule height\axiswd width\dimexpr\graphboxwd+\axiswd}%¤\idx*\rlap\idx*\vrule¤
		\begingroup% pour lire l'argument "<code>" :
			\catcode`\^^M=9\relax % ignorer les retours à la ligne¤\verbidx*[ (retour charriot)]{^^M}¤
			\graphzone@i% appeler \graphzone@i
}
\def\graphzone@i#1{% lire le <code>...
		\endgroup% et fermer le groupe précédemment ouvert
		\setbox0\hbox{#1}% mettre les instructions graphique dans la boite 0¤\idx*\setbox¤
		\wd0=\dimexpr\graphboxwd+\axiswd\relax% forcer sa dim horizontale¤\idx*\wd\idx*\dimexpr¤
		\ht0=\dimexpr\graphboxht+\axiswd\relax% et verticale¤\idx*\ht¤
		% pour correspondre aux dimension de la zone graphique
		\box0 % l'afficher¤\idx*\box\defline\aaa¤
	\endgroup% sortir du groupe initial
}
\catcode`@12
essai\graphzone{-1}[0.5]{1.5}[5]{-20}[10]{10}[2]{\relax}fin¤§*\graphzone¤|

Le code ne présente pas beaucoup de difficulté. Signalons tout de même les quelques points suivants:
\begin{itemize}
	\item les réglures correspondant au trait vertical à droite et au trait horizontal en haut sont tracées à coup de \idx\vrule. Celle de droite est tracée à la suite de \idx\box\verb|1| qui est l'axe horizontal et celle du haut en est correctement placée en s'aidant de \idx\raise qui élève la boite \idx\rlap de la hauteur de la zone graphique ;
	\item on a modifié le code de catégorie du retour à la ligne dans l'argument final \verb|<code>| de §\graphzone afin que les instructions graphiques puissent être entrées le plus « naturellement » possible, notamment sans avoir besoin de commenter les fins de ligne ;
	\item le \idx{point de référence} demeure en bas à gauche de la zone graphique jusqu'au \idx\box\verb|0| de la macro \verb|\graphzone@i| (ligne \no\aaa{}) puisque jusque là, on n'a affiché que des \idx\rlap. C'est justement en forçant les dimensions de cette boite \no0 aux dimensions de la zone graphique qu'en l'affichant, on obtient le bon encombrement final.
\end{itemize}

\subsection{Remplir la zone graphique}
Il nous reste à écrire des instructions graphiques pour remplir la zone\ldots{} Tout d'abord, il va falloir construire une macro §\putat qui place n'importe quel contenu relativement au \idx{point de référence} courant :

\centrecode-\putat{dimx}{dimy}{<contenu>}-§*\putat 

Il est bien entendu que cette macro va placer le point de référence du \verb|<contenu>| à des coordonnées relatives par rapport au point de référence courant, mais \emph{sans changer ce \idx{point de référence} courant}. Autrement dit, la boite englobante\idx*{boite!englobante} de cette macro a toutes ses dimensions nulles et donc, son exécution n'a aucune influence sur le point de référence courant.

En jouant sur les boites et imbriquant des boites horizontales et verticales en débordement, on peut facilement effectuer cette action :

\showcode|\def\putat#1#2#3{%¤§*\putat¤
	\leavevmode\rlap{\kern#1\vbox to0pt{\vss\hbox{#3}\kern#2}}%¤\idx*\leavevmode\idx*\rlap\idx*\kern\idx*\vbox\idx*\hss¤
}
Essai\putat{0.5cm}{0.3cm}{A}\putat{-0.2cm}{-0.1cm}{B}\putat{0pt}{0.2cm}{C}suite¤§*\putat¤|

Cette macro §\putat va nous permettre de placer n'importe quel matériel dans la zone graphique, mais l'idéal serait que le matériel placé le soit avec les coordonnées affichées sur les bords de la zone graphique (que nous appelons $X$ et $Y$) et non pas les coordonnées par rapport au coin inférieur gauche ($x$ et $y$) qui est le \idx{point de référence}. Il est bien entendu facile de passer d'un système de coordonnées à l'autre avec une simple formule de changement de repère :

\[\begin{cases}
	X=(x-x_{\text{min}})\div x_{\text{inc}}\\[5pt]
	Y=(y-y_{\text{min}})\div y_{\text{inc}}
\end{cases}\]

Pour éviter que les divisions ne soient faites à chaque placement d'un objet, nous diviserons une bonne fois pour toutes les dimensions \verb|\xunit| et \verb|\yunit| par les incréments $x_{\text{inc}}$ et $y_{\text{inc}}$ à l'intérieur de la zone graphique.

Pour placer les axes, il faut d'abord tester si le nombre 0 est contenu dans l'intervalle représenté sur l'axe horizontal dans la zone graphique et faire de même pour l'axe vertical. Le plus simple est de modifier la macro §\ifinside, programmée à la page~\pageref{ifinside}, mais qui avait le défaut de n'agir que sur les entiers :

\showcode|\def\ifinside#1[#2,#3]{%¤§*\ifinside¤
	\ifnum\sgn{\dimexpr#1pt-#2pt\relax}\sgn{\dimexpr#1pt-#3pt}1=1 ¤§*\sgn¤
		\expandafter\secondoftwo
	\else
		\expandafter\firstoftwo
	\fi
}
1) \ifinside3.5[0.5,4]{vrai}{faux}\qquad
2) \ifinside-0.2[-0.4,-0.3]{vrai}{faux}\qquad
3) \ifinside-0.999[-1,-0.5]{vrai}{faux}¤§*\ifinside¤|

Puis, il faut définir la fonction dont on veut afficher la courbe représentative, sachant que les seules opérations dont nous disposons sont les quatre opérations arithmétiques sur des décimaux. On ne peut donc représenter que des fonctions rationnelles\footnote{Il est bien évident qu'avec une extension spécialisée dans le calcul comme l'est «\texttt{fp}», toutes les fonctions, y compris transcendantes, sont très facilement accessibles.}.

Supposons que l'on veuille représenter la fonction $f(x)=x^3-x^2-3x+2$. Nous allons devoir faire le petit effort de traduire cet enchainement d'opérations en instructions compréhensibles par \eTeX{} muni des macros rendant possibles la multiplication et la division par un décimal que sont §\decmul et §\decdiv, vues à partir de la page~\pageref{decmul} :

\showcode|\def\fonction#1{\dimtodec\dimexpr¤§*\dimtodec¤
	\decmul{#1}{\decmul{#1}{#1}}pt% x^3¤§*\decmul¤
	-\decmul{#1}{#1}pt% -x^2¤§*\decmul¤
	-#1pt*3% -3x
	+2pt\relax}% +2
1) \fonction{-4}\qquad% doit afficher -66
2) \fonction{-1.7}\qquad %  doit afficher -0.703
3) \fonction{1}\qquad%  doit afficher -1
4) \fonction{1.35}%  doit afficher -1.412125|

On voit ici que l'on a ajouté les dimensions en \idx*{unité!pt}\idx*{pt (unité)}\verb|pt| pour permettre à \idx\dimexpr d'effectuer le calcul avant que §\dimtodec n'enlève cette unité pour que cette macro, purement développable, renvoie un nombre décimal sans unité. Bien sûr, certaines erreurs d'arrondis rendent les résultats légèrement faux ce qui n'a aucune importance ici puisqu'ils seront des coordonnées de points dans un repère où l'erreur commise est insignifiante en regard de ce qui est visible à l'\oe il nu.

Il faut ensuite définir la forme du point qui sera affiché. Pourquoi pas une croix ? Il faut bien sûr qu'elle soit de dimensions nulles :

\showcode|\newmacro\cross[2pt][0.2pt]{%¤§*\cross§*\newmacro¤
	% #1=dimensions de traits depuis le centre de la croix
	% #2=épaisseur des traits
	\leavevmode¤\idx*\leavevmode¤
	\vlap{%¤§*\vlap¤
		\clap{%¤§*\clap¤
			\vrule height#2 depth0pt width#1 % 1/2 trait horizontal gauche
			\vrule height#1 depth#1 width#2  % trait vertical
			\vrule height#2 depth0pt width#1 % 1/2 trait horizontal droit
		}%¤\idx*\vrule¤
	}%
}
Une croix : \cross{}puis une autre\cross[8pt][0.8pt]¤§*\cross¤|

Voici maintenant le code reprenant toutes les macros vues précédemment où deux courbes représentatives sont construites :

\showcode|\maingraddim=4pt \maingradwd=0.5pt \axiswd=0.5pt
\subgraddim=2.5pt \subgradwd=0.2pt
\xunit=1.25cm \yunit=0.75cm

\def\maingradx#1{%
	\lower1.5ex\clap{$\scriptscriptstyle#1$}% afficher l'argument au dessous¤\idx*\lower\idx*\scriptscriptstyle§*\clap¤
	\clap{\vrule height\maingraddim width\maingradwd depth0pt }% et la réglure¤\idx*\rlap\idx*\vrule¤
}

\def\subgradx{\clap{\vrule height\subgraddim width\subgradwd depth0pt }}¤\idx*\rlap\idx*\vrule¤

\newmacro\xaxis[1cm]1[1]1[4]{%¤§*\xaxis§*\newmacro¤
	\hbox{% tout mettre dans une \hbox¤\idx*\hbox¤
		\setbox0=\hbox{% stocke dans une \hbox les grad secondaires entre 2 unités¤\idx*\setbox¤
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions¤\idx*\the¤
			\for\xx=1 to #5-1 \do{% insérer #5-1 fois¤§*\for¤
				\kern\dimsubgrad% une espace secondaire¤\idx*\kern¤
				\subgradx% une graduation secondaire
				}%
		}%
		\rlap{% en débordement à droite :
			\FOR\xx = #2 to #4 \do #3{% pour chaque graduation principale¤§*\FOR¤
				\maingradx{\xx}% imprimer l'abscisse
				\ifdim\xx pt<#4pt % et en débordement à droite,
					\rlap{\copy0 }% les réglures secondaires, sauf pour la dernière¤\idx*\rlap\idx*\copy¤
				\fi
				\kern#1\relax% se déplacer vers la droite¤\idx*\kern¤
			}%
		}%
		\vrule% tracer l'axe des abscisses¤\idx*\vrule\defline\aaa¤
			height\axiswd% d'epaisseur \axiswd, de longueur #1*(#4-#2)/#3
			width\dimexpr#1*\decdiv{\dimtodec\dimexpr#4pt-#2pt\relax}{#3}\relax¤§*\decdiv§*\dimtodec¤
			depth 0pt\relax % et de profondeur nulle¤\defline\bbb¤
	}%
}

\def\maingrady#1{% affiche...
	\vlap{\llap{$\scriptscriptstyle#1$\kern2pt }}% l'ordonnée...¤§*\vlap \idx*\llap\idx*\scriptscriptstyle¤
	\vbox to0pt{\vss\hrule height\maingradwd width\maingraddim depth0pt }% et la réglure¤\idx*\vbox\idx*\vss\idx*\hrule¤
}

% affiche une subdiv
\def\subgrady{\vlap{\hrule height\subgradwd width\subgraddim depth0pt }}¤§*\vlap\idx*\hrule¤
% #1= dim entre 2 grad principales #2=abscisse départ #3=incrément
% #4=abscisse arrivée #5=nb intervalles secondaires
\newmacro\yaxis[1cm]1[1]1[4]{%¤§*\yaxis§*\newmacro¤
	\vbox{%¤\idx*\vbox¤
		\offinterlineskip% désactiver le ressort d'interligne¤\idx*\offinterlineskip¤
		\setbox0=\vbox{% stocke dans une \hbox les grad secondaires entre 2 unités¤\idx*\setbox¤
			\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% dimension entre 2 subdivisions¤\idx*\the¤
			\for\xx=1 to #5-1 \do{% insérer #5-1 fois¤§*\for¤
				\kern\dimsubgrad% une espace secondaire¤\idx*\kern¤
				\subgrady% une graduation secondaire
				}%
		}%
		\edef\dimsubgrad{\the\dimexpr#1/#5\relax}% distance entre 2 subdivisions¤\idx*\the\idx*\dimexpr¤
		\vbox to 0pt{% en débordement vers le bas
			\FOR\xx = #4to#2\do-#3{%¤§*\FOR¤
				\maingrady{\xx}% imprimer l'abscisse
				\ifdim\xx pt>#2pt % et en débordement à droite,
					\vbox to 0pt{\copy0 \vss}% les réglures secondaires, sauf pour la dernière¤\idx*\copy\idx*\vss¤
				\fi
				\kern#1\relax% se déplacer vers la droite¤\idx*\kern¤
			}%
			\vss% assure le débordement vers le bas¤\idx*\vss¤
		}%
		\clap{\vrule% tracer l'axe des ordonnées
			width\axiswd% d'épaisseur \axiwd, et de hauteur (#4-#2)/#3*#1
			height\decdiv{\dimtodec\dimexpr(#4pt-#2pt)\relax}{#3}\dimexpr#1\relax¤§*\decdiv§*\dimtodec¤
			depth 0pt\relax % profondeur nulle
		}%
	}%
}

\catcode`@11
\newmacro\graphzone1[1]1[4]1[1]1[4]{%¤§*\graphzone§*\newmacro¤
	\leavevmode% quitter le mode vertical¤\idx*\leavevmode\idx*{mode!vertical}¤
	\begingroup% travailler dans un groupe semi-simple
		\def\graphxmin{#1}\def\graphxmax{#3}% sauvegarder
		\def\graphymin{#5}\def\graphymax{#7}% les
		\def\xincrement{#2}\def\yincrement{#6}% arguments
		\setbox0\hbox{\yaxis[\yunit]{#5}[#6]{#7}[#8]}% axe "y" dans boite 0¤\idx*\setbox§*\yaxis¤
		\setbox1\hbox{\xaxis[\xunit]{#1}[#2]{#3}[#4]}% axe "x" dans boite 1¤\idx*\setbox§*\xaxis¤
		\edef\graphboxht{\the\ht0 }% \graphboxh est la hauteur de la zone¤\idx*\the\idx*\ht¤
		\edef\graphboxwd{\the\wd1 }% \graphboxw est la largeur de la zone¤\idx*\wd¤
		\rlap{% annuler la dimension horizontale, et...¤\idx*\rlap¤
			\box1 % ...afficher l'axe (Ox) puis¤\idx*\box¤
			% le trait vertical à l'extrême droite de la zone
			\clap{\vrule height\dimexpr\graphboxht+\axiswd\relax width\axiswd depth0pt }%¤\idx*\vrule\idx*\dimexpr¤
			}%
		\rlap{\box0 }% afficher l'axe (Oy) en annulant sa dimension horizontale¤\idx*\rlap\idx*\box¤
		\raise\graphboxht% puis monter tout en haut de la zone¤\idx*\raise¤
			% pour tracer le trait horizontal en annulant sa longueur
			\rlap{\kern-0.5\axiswd% et en rattrapant le centrage de l'axe des ordonnées
				\vrule height\axiswd width\dimexpr\graphboxwd+\axiswd}%¤\idx*\rlap\idx*\vrule¤
		\begingroup% pour lire l'argument "<code>" :
			\catcode`\^^M=9\relax % ignorer les retours à la ligne¤\verbidx*[ (retour charriot)]{^^M}¤
			\graphzone@i% appeler \graphzone@i
}
\def\graphzone@i#1{% lire le <code>...
		\endgroup% et fermer le groupe précédemment ouvert
		\xunit=\decdiv1\xincrement\xunit% divise les unités par l'incrément
		\yunit=\decdiv1\yincrement\yunit
		\setbox0\hbox{#1}% mettre les instructions graphique dans la boite 0¤\idx*\setbox¤
		\wd0=\dimexpr\graphboxwd+\axiswd\relax% forcer sa dim horizontale¤\idx*\wd\idx*\dimexpr¤
		\ht0=\dimexpr\graphboxht+\axiswd\relax% et verticale¤\idx*\ht¤
		% pour correspondre aux dimension de la zone graphique
		\box0 % l'afficher¤\idx*\box\defline\aaa¤
	\endgroup% sortir du groupe initial
}

\def\putat#1#2#3{%¤§*\putat¤
	\leavevmode\rlap{\kern#1\vbox to0pt{\vss\hbox{#3}\kern#2}}%¤\idx*\leavevmode\idx*\rlap\idx*\kern\idx*\vbox\idx*\hss¤
}

\newmacro\cross[2pt][0.2pt]{%¤§*\cross§*\newmacro¤
	\leavevmode¤\idx*\leavevmode¤
	\vlap{%¤§*\vlap¤
		\clap{%¤§*\clap¤
			\vrule height#2 depth0pt width#1 % 1/2 terait horizontal gauche
			\vrule height#1 depth#1 width#2  % trait vertical
			\vrule height#2 depth0pt width#1 % 1/2 trait horizontal droit
		}%¤\idx*\vrule¤
	}%
}

\def\plot(#1,#2){% place "\plotstuff" aux coordonnées #1,#2¤§*\plot¤
	\edef\x@plot{#1}\edef\y@plot{#2}% développer au cas où
	\ifinside\x@plot[\graphxmin,\graphxmax]% si #1 est dans les limites¤§*\ifinside¤
		{\ifinside\y@plot[\graphymin,\graphymax]% et si #2 l'est aussi¤§*\ifinside¤
			{\putat% placer aux coordonnées¤§*\putat¤
				{\dimexpr\x@plot\xunit-\graphxmin\xunit\relax}% X=(x-xmin)/xinc¤\idx*\dimexpr¤
				{\dimexpr\y@plot\yunit-\graphymin\yunit\relax}% Y=(y-ymin)/yinc¤\idx*\dimexpr¤
				\plotstuff% le contenu de \plotstuff
			}%
			\relax
		}
		\relax
}

\def\showxaxis{% affiche l'axe (Ox)
	\ifinside0[\graphymin,\graphymax]%¤§*\ifinside¤
		{\putat\z@{-\graphymin\yunit}{\vlap{\vrule width\graphboxwd height\axiswd}}}%¤\idx*\vrule §*\putat\idx*\z@¤
		\relax
}

\def\showyaxis{% affiche l'axe (Oy)
	\ifinside0[\graphxmin,\graphxmax]%¤§*\ifinside¤
		{\putat{-\graphxmin\xunit}\z@{\clap{\vrule width\axiswd height\graphboxht}}}%¤\idx*\vrule §*\putat\idx*\z@¤
		\relax
}

\def\showaxis{\showxaxis\showyaxis}% affiche les deux axes
\catcode`@12

%%%%%%%%%%%%%%% 1er exemple :
\xunit=1cm \yunit=0.5cm 
\def\fonction#1{\dimtodec\dimexpr\decmul{#1}{\decmul{#1}{#1}}pt-%
	\decmul{#1}{#1}pt-#1pt*3+2pt\relax}¤§*\dimtodec §*\decmul\idx*\dimexpr¤
Exemple 1 :\qquad
\graphzone{-2}[0.5]{2.5}[5]{-5}{5}[2]{%¤§*\graphzone¤
	\let\plotstuff\cross% définit ce qu'il faut afficher comme point¤§*\cross¤
	\FOR\xx=-2 to 2.5 \do 0.1{%¤§*\FOR¤
		\plot(\xx,\fonction{\xx})% afficher les points de coordonnées (x ; f(x))¤§*\plot¤
	}%
	\putat{5pt}{\dimexpr\graphboxht-10pt\relax}% afficher¤§*\putat¤
		{$f(x)=x^3-x^2-3x+2$}% la fonction tracée
	\showaxis% et les axes
}\par\medskip¤\idx*\medskip¤
%%%%%%%%%%%%% 2e exemple
\xunit=0.7cm \yunit=\xunit
\def\foncx#1{\dimtodec\dimexpr\decmul{#1}{\decmul{#1}{#1}}pt-%
	\decmul{4}{\decmul{#1}{#1}}pt-#1pt+4pt}¤§*\dimtodec §*\decmul\idx*\dimexpr¤
\def\foncy#1{\dimtodec\dimexpr\decmul{#1}{#1}pt-#1pt*2-6pt}¤§*\dimtodec §*\decmul\idx*\dimexpr¤
Exemple 2 :\qquad
\graphzone{-12}[2]{12}[2]{-8}[2]{8}[2]{%¤§*\graphzone¤
	\def\plotstuff{\cross[1.25pt]}¤§*\cross¤
	\FOR\tt = -5 to 5 \do 0.1 {%¤§*\FOR¤
		\plot(\foncx\tt,\foncy\tt)%¤§*\plot¤
	}%
	\putat{5pt}{\dimexpr\graphboxht-20pt\relax}% afficher la fonction paramétrique tracée¤§*\putat¤
		{$\left\{\vcenter{\hbox{$x(t)=t^3-4t^2-t-4$}\hbox{$y(t)=t^2-2t-6$}}\right.$}%¤\idx*\vcenter¤
	\showaxis
}|

\subsection{Construire l'ensemble de Mandelbrot}\idx*{Mandelbrot}
L'\idx{ensemble de Mandelbrot}\footnote{Du nom de son inventeur, Benoît \textsc{Mandelbrot} (1924--2010), mathématicien franco-arménien.}, noté $\mathcal M$, est une figure fractale définie comme l'ensemble des points $c$ du plan complexe pour lesquels la suite définie par récurrence par

\[\left\{
\begin{tabular}{@{}r@{}l}
$z_0$&${}=0$\\[2ex]
$z_{n+1}$&${}=z_n^2+c$
\end{tabular}
\right.\]

\noindent est bornée en module. En posant $c=a+\mathrm ib$, on passe aux coordonnées cartésiennes et l'on obtient

\[\left\{
\begin{tabular}{@{}r@{}l}
$x_0$&${}=0$\\[2ex]
$x_{n+1}$&${}=x_n^2-y_n^2+a$
\end{tabular}\right.\kern5em
\left\{\begin{tabular}{@{}r@{}l}
$y_0$&${}=0$\\[2ex]
$y_{n+1}$&${}=2x_n y_n+b$
\end{tabular}
\right.\]

Cet ensemble a été beaucoup étudié et on a démontré les choses suivantes qui vont nous servir pour le construire :

\begin{itemize}
	\item $\mathcal M$ est symétrique par rapport à l'axe des abscisses et donc, on peut se limiter au calcul des points dont la partie imaginaire est positive et tracer leurs symétriques par rapport à $(Ox)$;
	\item si à un certain indice $i$, on a $|z_i|>2$, alors la suite diverge et donc, le point d'affixe $c$ n'appartient pas à $\mathcal M$. Il est dès lors inutile de poursuivre les calculs aux indices supérieurs à $i$.
\end{itemize}

Pour dessiner l'ensemble, nous nous limiterons à la portion de plan complexe comprise entre $-2$ et $1$ pour la partie réelle et entre $-1$ et $1$ pour la partie imaginaire. L'essentiel est d'écrire une macro §\mandeltest qui admet deux arguments décimaux qui sont les coordonnées du point à tester. Cette macro mettra en place une boucle qui calculera les termes de la suite en fonction des deux arguments qui représentent $Re(c)$ et $Im(c)$. Bien évidemment, si la suite ne diverge pas, il n'est pas possible de calculer un nombre illimité de termes de la série. Nous nous limiterons à un entier, contenu dans la macro \verb|\maxiter|.

L'algorithme de §\mandeltest est très simple : les itérations doivent se poursuivre tant que le nombre d'itérations est inférieur à \verb|\maxiter| et que le module du terme $z_i$ actuellement calculé est inférieur à 2. Une fois le test terminé et l'issue connue, le test §\mandeltest définira la macro \verb|\mandelresult|  : elle contiendra 1 si le test est positif et 0 sinon.

Pour chaque terme $z_i$, les macros \verb|\zx| et \verb|\zy| contiennent $Re(z_i)$ et $Im(z_i)$. Par souci d'optimisation et pour ne pas les calculer deux fois, nous stockerons les carrés de \verb|\zx| et \verb|\zy| dans \verb|\zxx| et \verb|\zyy|.

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}\label{algo3}
\algorithm[\#]{Tester si un point appartient à M}/
macro ~mandeltest~ #1#2 % #1 et #2 = coordonnées du point à tester
	mandelresult:=1 % on considère a priori que le point apprtient à M
	zx:=0 \qquad  zy:=0 % partie réelle et imaginaire de $z_0$
	zxx:=0\qquad zyy:=0 % les carrés de zx et zy
	~pour~ i=1 to maxiter
		zy:=2*zx*zy + #2 % $y_{n+1}=2x_n y_n + Im(c)$
		zx:=zxx-zyy + #1 % $x_{n+1}=x_n^2-y_n^2+Re(c)$
		zxx:=zx*zx\qquad zyy:=zy*zy % calcul des carrés
		~si~ $\mathrm{zxx}+\mathrm{zyy}>4$ % si $|z_n|^2>4$ (càd si le module est > à 2)
			mandelresult:=0 % le point n'est pas dans M
			i:=maxiter % sortir de la boucle prématurément
		~finsi~
	~finpour~
~finmacro~/
\endgroup

Dans le domaine $[-2\;\string;\;1]\times[-1\;\string;\;1]$ nous allons choisir la \emph{résolution} du dessin, c'est-à-dire combien de pixels doivent être contenus dans une unité, aussi bien horizontalement que verticalement. Ce nombre sera le premier argument de la macro §\mandel chargée de tracer $\mathcal M$. Le second argument sera le nombre maximal d'itérations.

Pour parcourir tous les points du rectangle, nous allons utiliser deux boucles §\FOR imbriquées, l'une pilotant les abscisses \verb|\xxx| et l'autre les ordonnées \verb|\yyy|. L'incrément sera égal à $\frac{1}{\string#1}$. Dans le c\oe ur de la boucle, c'est-à-dire pour chaque point de coordonnées (\verb|\xxx|\;\string;\;\verb|\yyy|), le test §\mandeltest sera effectué et si la macro \verb|\mandelresult| vaut 1, le pixel et son symétrique par rapport à l'axe $(Ox)$ seront affichés.

Un pixel sera une réglure carrée ayant pour côté l'incrément multiplié par la longueur \verb|\xunit|.

\errcode|\def\mandeltest#1#2{%¤§\mandeltest¤
	\def\zx{0}\def\zy{0}% zn=0 + i*0
	\def\zxx{0}\def\zyy{0}% carrés de \zx et \zy
	\def\mandelresult{1}% le point appartient à M a priori
	\for\ii=1to\maxiter\do1{%¤§*\for¤
		\advance\count255 by1¤\idx*\advance¤
		\edef\zy{\dimtodec\dimexpr\decmul{\decmul2\zx}\zy pt+#2pt\relax}%¤§*\dimtodec\idx*\dimexpr §*\decmul¤
		\edef\zx{\dimtodec\dimexpr\zxx pt-\zyy pt+#1pt\relax}%%¤§*\dimtodec\idx*\dimexpr¤
		\edef\zxx{\decmul\zx\zx}%¤§*\decmul¤
		\edef\zyy{\decmul\zy\zy}%¤§*\decmul¤
		\ifdim\dimexpr\zxx pt+\zyy pt\relax>4pt¤\tidx*{ifdim}¤
			\def\mandelresult{0}%
 			\exitfor\ii¤§*\exitfor¤
		\fi
	}%
}
\def\mandel#1#2{% #1=points par unité #2=nombre maximal d'itérations¤§\mandel¤
	\graphzone{-2}[1]{1}[2]{-1}[1]{1}[2]{%¤§*\graphzone¤
		\def\maxiter{#2}%
		\edef\plotstuff{\the\dimexpr\xunit/#1\relax}% taille d'un pixel¤\idx*\the\idx*\dimexpr¤
		\edef\plotstuff{\vrule height\plotstuff width\plotstuff}%¤\idx*\vrule¤
		\edef\increment{\decdiv{1}{#1}}% incrément¤§*\decdiv¤
		\count255=0 % compteur des itérations¤\idx*\count¤
		\FOR\xxx = -2 to 1 \do \increment{% pour chaque¤§*\FOR¤
			\FOR\yyy = 0 to 1 \do \increment{% pixel du domaine¤§*\FOR¤
				\mandeltest\xxx\yyy% tester s'il est dans M¤§*\mandeltest¤
				\ifnum\mandelresult=1 % si oui,
					\plot(\xxx,\yyy)\plot(\xxx,-\yyy)% afficher les 2 points¤§*\plot¤
				\fi
			}%
		}%
	\edef\plotstuff{$\scriptstyle\number\count255 $}% affiche la valeur du compteur¤\idx*\scriptstyle\idx*\number\idx*\count¤
	\plot(-1.99,0.92)% aux coordonnées (-1.99 ; 0.92)¤§*\plot¤
	}%
}
\xunit=3cm \yunit=3cm \mandel{400}{500}¤§\mandel¤|{\includegraphics{mandelbrot.pdf}}

Afin d'obtenir un tracé précis et assez fidèle à ce qu'est $\mathcal M$, nous avons demandé un grand nombre de pixels par unité (400) et un nombre élevé d'itérations (500). Nous avons donc $3\times400$ pixels horizontalement et 400 pixels verticalement à tester c'est-à-dire \numprint{480000} tests à faire. Chacun exécute une boucle supplémentaire pouvant aller jusqu'à 500 itérations. Même si tous les tests ne procèdent pas à ces 500 itérations, il s'agit là sans nul doute du plus grand nombre d'itérations qu'il m'ait été donné de programmer en \TeX{} : il y en a très exactement \numprint{63430877} ! Compte tenu de la grandeur des arguments de §\mandel conduisant à cet incroyable nombre d'itérations, la compilation de ce seul code demande de longues minutes. En outre, le nombre de pixels (c'est-à-dire de réglures) à placer sur la page est extrêmement important ce qui requiert une augmentation de la mémoire de \TeX{}. Pour ce faire, les paramètres suivants ont été modifiés :

\centrecode/main_memory = 10000000
extra_mem_bot = 20000000/

Ce dernier code, en raison du temps de compilation qu'il requiert, déroge à la règle qui veut que chaque code génère l'affichage qui se trouve dans la partie basse du cadre. Ce code a donc été compilé à part avec une version modifiée de \texttt{tex} et le fichier pdf obtenu a été incorporé sous le code.

\chapter{Aller plus loin dans la mise en forme}
\section{Formater un nombre}\idx*[|(]{formatter un nombre}
\Qu elle différence y a t-il entre «\hbox{9876543,21012}» et «\numprint{9876543,21012}» ? Mathématiquement aucune, mais typographiquement, la différence est énorme : elle se situe au niveau de ces petites espaces insécables qui séparent les groupes de chiffres en les groupant trois par trois et qui font que, du premier coup d'\oe il, on sait que 9 est le chiffre des unités de millions. Il en va ainsi de la typographie française qui, par souci de lisibilité, fixe comme règle d'insérer une espace fine insécable entre chaque groupe de trois chiffres.

Le but que nous nous fixons e de pouvoir formater n'importe quel nombre, on ne va s'imposer aucune limite sur le nombre de chiffres, pas plus dans la partie entière que dans la partie décimale. Par conséquent, nous ne pourrons à aucun moment utiliser la primitive \idx\number puisque l'entier qui la suit doit être inférieur à $2^{31}-1$.

\subsection{Partie décimale}
La partie facile est de traiter la partie décimale puisqu'elle doit être parcourue de gauche à droite --~le sens de lecture de \TeX~-- afin d'insérer une espace fine (créée par la macro \verb|\numsep|) chaque fois que l'on a parcouru 3 chiffres. Pour cela, nous allons reprendre la macro §\reverse vue à la page~\pageref{reverse} en la modifiant légèrement. Cette macro offre la particularité intéressante de fournir du matériel purement développable ne produisant aucune sortie vers l'affichage jusqu'à ce que l'argument soit inversé en totalité, moment il est dirigé vers l'affichage.

Sur ce modèle, nous allons bâtir une macro récursive \verb|\formatdecpart@i| qui admet trois arguments délimités. Le premier est l'entier qui représente le nombre de chiffres parcourus et qu'il faudra tester par rapport à 3. Les deux autres sont les « réservoirs » déjà vus avec la macro §\reverse qui stockent les tokens et qui, en se passant de séquence de contrôle définies par \verb|\def|, rendent la macro purement développable.

\showcode|\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le séparateur mis tous les 3 chiffres¤\idx*\protected¤

\def\formatdecpart#1{% #1=série de chiffres¤§*\formatdecpart¤
	\ifempty{#1}% si la partie décimale est vide¤§*\ifempty¤
		{}% ne rien afficher
		{{,}\formatdecpart@i 1.#1..}% sinon, afficher la virgule et mettre en forme
}

% #1=compteur de caractères #2= chiffre courant
% #3= chiffres restants     #4 = chiffres déjà traités
\def\formatdecpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre¤§*\ifempty¤
		{#4#2}% le mettre en dernière position et tout afficher, sinon
		{\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			% si 3 chiffres sont atteint, rendre #1 égal à 1 et
			{\formatdecpart@i 1.#3.#4#2\numsep.}% mettre #2\numsep en dernier puis recommencer
			% sinon, mettre #2 en dernière position et recommencer
			% tout en incrémentant #1 de 1
			{\expandafter\formatdecpart@i \number\numexpr#1+1.#3.#4#2.}%¤\idx*\numexpr¤
		}%
}
a) \formatdecpart{1234567}\qquad
b) \formatdecpart{987125}\qquad
c) \formatdecpart{56}\qquad
d) \edef\foo{\formatdecpart{2014}}\meaning\foo¤§*\formatdecpart¤|

La virgule, qui joue le rôle de séparateur décimal est insérée entre accolades pour que cette virgule ne soit pas prise comme un séparateur de liste si la macro est exécutée en mode mathématique\idx*{mode!mathématique} car dans ce cas, elle serait suivie d'une espace.

\subsection{Partie entière}
La partie entière est plus difficile. La première étape sera de légèrement modifier la macro §\formatdecpart en la macro §\formatintpart pour que cette dernière affiche le nombre qu'elle a traité, mais à l'envers. Pour cela, il suffit de changer l'ordre des arguments \verb|#2| et \verb|#4| dans le texte de remplacement de \verb|\formatdecpart@i| :

\showcode|\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le séparateur mis tous les 3 chiffres¤\idx*\protected¤
\def\formatintpart#1{% #1=série de chiffres¤§*\formatintpart¤
	\formatintpart@i 1.#1..% appelle la macro récursive
}

% #1=compteur de caractères #2= chiffre courant
% #3= chiffres restants     #4 = chiffres déjà traités
\def\formatintpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre¤§*\ifempty¤
		{#2#4}% le mettre en première position et tout afficher, sinon
		{\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo
		\fi% si 3 chiffres sont atteint, rendre #1 égal à 1 et
			{\formatintpart@i 1.#3.\numsep#2#4.}% mettre "\numsep#2" en premier et recommencer
			% sinon, mettre #2 en première position et recommencer
			% tout en incrémentant #1 de 1
			{\expandafter\formatintpart@i \number\numexpr#1+1.#3.#2#4.}%¤\idx*\numexpr¤
		}%
}
\catcode`\@12
a) \formatintpart{1234567}\qquad b) \formatintpart{987125}\qquad
c) \formatintpart{56}\qquad
d) \edef\foo{\formatintpart{2014}}\meaning\foo¤§*\formatintpart¤|

Comme deux inversions s'annulent, le résultat serait celui que l'on attend si au lieu du nombre passé comme argument à §\formatintpart, on passait le nombre inversé. On va donc utiliser la macro §\reverse et faire l'appel à la macro récursive de cette façon :

\centrecode-\expandafter\formatintpart@i\expandafter1\expandafter.\reverse{#1}..-

\noindent Le seul ennui est que §\reverse ne donne pas son résultat en un seul développement ! Mais, du fait de sa structure, l'affichage est fait à la toute fin, après des instructions purement développables ne donnant aucun affichage. La primitive \idx\romannumeral va nous servir pour tout développer en un coup jusqu'à l'affichage final. Pour stopper \idx\romannumeral \emph{avant} qu'elle ne voit les chiffres et ne s'en empare pour former un nombre romain, nous mettrons \idx\z@ dans l'argument de §\reverse telle sorte qu'il stoppe l'expansion et l'action de \idx\romannumeral. Comme  §\reverse inverse l'ordre, il faut écrire \idx\z@ en dernier pour qu'il soit en premier à la fin du traitement :

\showcode|\catcode`\@11
\def\formatintpart#1{% #1=série de chiffres¤§*\formatintpart¤
	\expandafter\formatintpart@i\expandafter1\expandafter.\romannumeral\reverse{#1\z@}..%¤\idx*\romannumeral\idx*\z@¤
}

\catcode`\@12
a) \formatintpart{1234567}\qquad b) \formatintpart{987125}\qquad
c) \formatintpart{56}\qquad
d) \edef\foo{\formatintpart{2014}}\meaning\foo¤§*\formatintpart¤|

Mettre le tout en cohérence pour former une macro §\formatnum est maintenant aisé :

\showcode|\catcode`\@11
\def\ifnodecpart#1{\if@nodecpart#1.\@nil}% teste si #1 est un entier¤§*\ifnodecpart¤
\def\if@nodecpart#1.#2\@nil{\ifempty{#2}}¤§*\ifempty¤

\def\formatnum#1{%¤§*\formatnum¤
	\ifnodecpart{#1}% s'il n'y a pas de partie décimale¤§*\ifnodecpart¤
		{\formatintpart{#1}}% formatter la partie entière
		{\formatnum@i#1\@nil}% sinon, formatter les deux parties
}

\def\formatnum@i#1.#2\@nil{%
	\formatintpart{#1}% formatte la partie entière¤§*\formatintpart¤
	\formatdecpart{#2}% et la partie décimale¤§*\formatdecpart¤
}

\catcode`\@12
a) \formatnum{3.1415926}\qquad
b) \formatnum{1987654.12301}\qquad
c) \edef\foo{\formatnum{0987654.12300}}$\foo$¤§*\formatnum¤|

Un défaut de notre macro saute aux yeux avec le dernier cas; elle ne supprime pas les zéros inutiles. Et comme il est impossible d'utiliser \idx\number qui l'aurait fait, il va donc falloir écrire deux macros, purement développables, qui suppriment les zéros inutiles d'un nombre entier lorsqu'ils sont au début pour l'une et à la fin pour l'autre.

\subsection{Supprimer les 0 inutiles de gauche}
Voici la macro §\removefirstzeros, purement développable, qui supprime les 0 au début de son argument :

\showcode|\catcode`\@11
\def\removefirstzeros#1{%¤§*\removefirstzeros¤
	\removefirstzeros@i#1\quark% ajoute "\quark" en dernier¤§*\quark¤
}
\def\removefirstzeros@i#1{% #1=chiffre courant
	\ifx\quark#1% fin atteinte donc nombre = 0
		\expandafter0% laisser un zéro
	\else
		\ifx0#1% si le chiffre lu est un 0
			\expandafter\expandafter\expandafter\removefirstzeros@i% recommencer
		\else% sinon remettre le chiffre #1 et tout afficher jusqu'à \removefirstzeros@i
			\expandafter\expandafter\expandafter\removefirstzeros@ii
			\expandafter\expandafter\expandafter#1%
		\fi
	\fi
}
\def\removefirstzeros@ii#1\quark{#1}¤§*\quark¤
\catcode`\@12
a) \removefirstzeros{000325478}\qquad
b) \removefirstzeros{00000}\qquad
c) \edef\foo{\removefirstzeros{001000}}\meaning\foo\qquad
d) \long\def\>#1<{\detokenize{#1}}
   \expandafter\>\romannumeral\removefirstzeros{0123}<¤§*\removefirstzeros¤|

La macro fonctionne bien sauf qu'au dernier cas, la forcer à donner le résultat en un développement avec \idx\romannumeral est un échec puisque justement, les caractères que laisse la macro sont des chiffres qui sont derechef convertis en un nombre romain. L'idéal serait de trouver une astuce pour rendre cette macro développable avec \idx\romannumeral sans rien changer à la macro. La réponse, non encore vue jusqu'à présent tient dans le dernier point de la règle de la page~\pageref{definition.entier}.

Rappelons-nous que cette règle stipule que si \TeX{} s'attend à lire un nombre, les caractères

\centrecode|-`\@|

\noindent sont lus comme la représentation interne de l'entier \number-`\@{} car le code de caractère de \verb|@| est 64\footnote{On aurait tout aussi bien pu écrire «\texttt{-`\string\a}» qui représente \number-`\a\relax{} ou encore tout nombre négatif ou nul de la forme «\texttt{-`\char`\\\codeelement{car}}».}. Mais le point intéressant de cette règle est que \TeX{} \emph{continue} le développement maximal après ces caractères jusqu'à trouver un espace (qu'il absorbe) ou tout autre token (qu'il laisse tel quel). On comprend tout le bénéfice que l'on peut tirer de cette règle ici. En effet, §\removefirstzeros ne dirige aucun token vers l'affichage tant qu'il n'a pas trouvé autre chose que 0. Par conséquent, si 

\centrecode/\romannumeral-`\@/

\noindent est placé devant §\removefirstzeros, le développement maximal sera en route jusqu'à ce que quelque chose soit affiché, c'est-à-dire après avoir mangé les 0 inutiles. De plus, \idx\romannumeral évaluant le nombre négatif \verb|-`\@|, aucun chiffre romain ne sera dirigé vers l'affichage.

\begin{regle}
Lorsqu'il est 1-développé, le code suivant

\centrecode|\romannumeral-`\<caractère>|

\noindent effectue l'action « tout développer au maximum jusqu'à trouver un token (absorbé si c'est un espace et laissé tel quel sinon) qui stoppera le développement ».
\end{regle}

\showcode|\long\def\>#1<{\detokenize{#1}}
\expandafter\>\romannumeral-`\@\removefirstzeros{000123}<¤\idx*\romannumeral§*\removefirstzeros¤|

\subsection{Supprimer les 0 inutiles de droite}
Maintenant, il nous faut écrire la partie plus difficile, celle d'enlever les zéros inutiles finaux. Pour cela, inutile de tout réinventer, nous avons déjà tout ce qu'il nous faut : il suffit d'inverser l'argument, d'enlever tous les zéros de gauche puis d'inverser encore le résultat obtenu pour arriver à nos fins. Rien n'empêche d'utiliser plusieurs \idx\romannumeral imbriqués qui se passent la main afin de provoquer le développement maximal dans le bon ordre.

On souhaiterait écrire

\centrecode-\reverse{\removefirstzeros{\reverse{<nombre>}}}-§*\reverse

\noindent mais ça serait oublier que \TeX{} n'évalue pas ses arguments avant que la macro ne les lise. Il nous incombe donc de forcer le développement dans le bon ordre, c'est-à-dire développer §\reverse\verb|{<nombre>}| en premier, puis §\removefirstzeros pour que le §\reverse chapeau agisse sur le nombre purgé de ses 0 de gauche. De plus, §\removefirstzeros doit être ré-écrit, car cette macro laissait un 0 si le nombre était nul, et ce comportement n'est pas souhaitable ici. La macro \verb|\removelastzeros@i| rétablit le comportement souhaité.

Toute la \TeX nicité réside dans la macro chapeau §\removelastzeros où, par le truchement de \idx\romannumeral, les arguments sont développés dans le bon ordre.

\showcode|\catcode`\@11
\def\removelastzeros#1{%¤§*\removelastzeros¤
	\exparg\reverse% inverser après¤§*\reverse¤
		{\romannumeral-`\.% tout développer¤\idx*\romannumeral¤
			\expandafter\removelastzeros@i% enlever les 0 de gauche après
			\romannumeral\reverse{#1\z@}\quark% avoir inversé #1¤§*\reverse\idx*\z@\idx*\romannumeral¤
		}%
}
\def\removelastzeros@i#1{% enlève tous les 0 de gauche
	\unless\ifx\quark#1% si la fin n'est pas atteinte¤\tidx*{unless}§*\quark¤
		\ifx0#1% si le chiffre lu est un 0
			\expandafter\expandafter\expandafter\removelastzeros@i% recommencer
		\else% sinon remettre le chiffre et tout afficher jusqu'à \removefirstzeros@i
			\expandafter\expandafter\expandafter\removelastzeros@ii
			\expandafter\expandafter\expandafter#1%
		\fi
	\fi
}
\def\removelastzeros@ii#1\quark{#1}¤§*\quark¤
\catcode`\@12
a) \removelastzeros{0003254780}\qquad
b) \removelastzeros{00000}\qquad
c) \edef\foo{\removelastzeros{001000}}\foo\qquad
\long\def\>#1<{\detokenize{#1}}
d) \expandafter\>\romannumeral-`\.\removelastzeros{012300}<¤§*\removelastzeros\idx*\romannumeral¤|

\subsection{Gérer le signe du nombre}
Nous voyons bientôt le bout du tunnel, il nous reste à parler du signe du nombre. Pour rester cohérent avec \TeX{}, nous allons admettre qu'un nombre peut commencer par autant de signes \verb|+| et \verb|-|, mais que le signe mathématique du nombre affiché sera négatif si les signes «\verb|-|» sont en nombre impair. Pour cela, la macro §\formatnum va devoir transmettre son argument à une macro \verb|\formmatnum@i|, à arguments délimités de type « réservoirs communicants». Ici, le délimiteur sera «\verb|!|» puisque le «\verb|.|» est susceptible d'être contenu dans le nombre. La macro chapeau effectuera cet appel initial à la macro récursive :

\centrecode-\def\formatnum#1{\formatnum@i 1!#1!}-

Le premier argument délimité, qui tient lieu de réservoir \no1, vaut 1 lors de l'appel initial. Ce réservoir accumulera en première position tous les signes rencontrés au début du réservoir \no2 qui situé entre les deux points d'exclamation, dont la valeur initiale est le \verb|<nombre>| à formater. La macro \verb|\formatnum@i| va donc avoir un texte de paramètre défini ainsi

\centrecode-\def\formatnum@i#1!#2#3!{...}-

\noindent de façon à ce que \verb|#2| soit le premier caractère du nombre à examiner et \verb|#3| soit les caractères non encore traités. Il suffit de tester si ce caractère \verb|#2| est \verb|+| ou \verb|-| et dans ce cas, le mettre en première position dans le réservoir \no1 et recommencer avec les arguments qui seront devenus «\verb|#2#1|» et \verb|#3|». Si ce n'est pas le cas, cela veut dire que l'on a épuisé les signes situés au début du nombre. Il est alors temps de tester si le nombre dans le réservoir \no1, constitué de tous les signes rencontrés suivis de 1, est lu par \TeX{} comme égal à $-1$ et dans ce cas, afficher un «\verb|-|» puis passer la main à la mise en forme du nombre proprement dite.

On remarquera que si le nombre n'est constitué que de signes \verb|+| ou \verb|-|, $+1$ ou $-1$ sera lu dans le premier réservoir selon la parité du nombre de signes \verb|-|. Enfin, dernier raffinement, une macro se chargera de remplacer dans l'argument de §\formatnum le séparateur décimaux «virgule» en «point» avant de traiter le nombre. Ainsi, la virgule ou le point peuvent indifféremment être utilisés comme séparateur décimal.

Voici le code complet :

\showcode|\catcode`\@11
\protected\def\numsep{\kern0.2em }% \numsep est le séparateur mis tous les 3 chiffres¤\idx*\protected¤

\def\formatdecpart#1{% #1=série de chiffres¤§*\formatdecpart¤
	\ifempty{#1}% si la partie décimale est vide¤§*\ifempty¤
		{}% ne rien afficher
		{{,}\formatdecpart@i 1.#1..}% sinon, afficher la virgule et mettre en forme
}

% #1=compteur de caractères #2= chiffre courant
% #3= chiffres restants     #4 = chiffres déjà traités
\def\formatdecpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre¤§*\ifempty¤
		{#4#2}% le mettre en dernière position et tout afficher, sinon
		{\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			% si 3 chiffres sont atteint, rendre #1 égal à 1 et
			{\formatdecpart@i 1.#3.#4#2\numsep.}% mettre #2\numsep en dernier puis recommencer
			% sinon, mettre #2 en dernière position et recommencer
			% tout en incrémentant #1 de 1
			{\expandafter\formatdecpart@i \number\numexpr#1+1.#3.#4#2.}%¤\idx*\numexpr¤
		}%
}

\def\formatintpart#1{% #1=série de chiffres¤§*\formatintpart¤
	\expandafter\formatintpart@i\expandafter1\expandafter.%
	\romannumeral\reverse{#1\z@}..% appelle la macro récursive¤\idx*\romannumeral\idx*\z@¤
}

% #1=compteur de caractères #2= chiffre à déplacer
% #3= chiffres restants     #4 = chiffres déjà traités
\def\formatintpart@i#1.#2#3.#4.{%
	\ifempty{#3}% si #2 est le dernier chiffre à traiter¤§*\ifempty¤
		{#2#4}% le mettre en première position et tout afficher, sinon
		{\ifnum#1=3 \expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			% si 3 chiffres sont atteint, rendre #1 égal à 1 et
			{\formatintpart@i 1.#3.\numsep#2#4.}% mettre \numsep#2 en premier puis recommencer
			% sinon, mettre #2 en dernière position et recommencer
			% tout en incrémentant #1 de 1
			{\expandafter\formatintpart@i\number\numexpr#1+1.#3.#2#4.}%
		}%
}
\def\removefirstzeros#1{%¤§*\removefirstzeros¤
	\removefirstzeros@i#1\quark% ajoute "\quark" en dernier¤§*\quark¤
}
\def\removefirstzeros@i#1{% #1=chiffre courant
	\ifx\quark#1% fin atteinte donc nombre = 0
		\expandafter0% laisser un zéro
	\else
		\ifx0#1% si le chiffre lu est un 0
			\expandafter\expandafter\expandafter\removefirstzeros@i% recommencer
		\else% sinon remettre le chiffre #1 et tout afficher jusqu'à \removefirstzeros@i
			\expandafter\expandafter\expandafter\removefirstzeros@ii
			\expandafter\expandafter\expandafter#1%
		\fi
	\fi
}
\def\removefirstzeros@ii#1\quark{#1}¤§*\quark¤

\def\removelastzeros#1{%¤§*\removelastzeros¤
	\exparg\reverse% inverser après¤§*\reverse¤
		{\romannumeral-`\.% tout développer¤\idx*\romannumeral¤
			\expandafter\removelastzeros@i% enlever les 0 de gauche après
			\romannumeral\reverse{#1\z@}\quark% avoir inversé #1¤§*\reverse\idx*\z@\idx*\romannumeral¤
		}%
}
\def\removelastzeros@i#1{% enlève tous les 0 de gauche
	\unless\ifx\quark#1% si la fin n'est pas atteinte¤\tidx*{unless}§*\quark¤
		\ifx0#1% si le chiffre lu est un 0
			\expandafter\expandafter\expandafter\removelastzeros@i% recommencer
		\else% sinon remettre le chiffre et tout afficher jusqu'à \removefirstzeros@i
			\expandafter\expandafter\expandafter\removelastzeros@ii
			\expandafter\expandafter\expandafter#1%
		\fi
	\fi
}
\def\removelastzeros@ii#1\quark{#1}¤§*\quark¤

% renvoie vrai s'il n'y a pas de partie décimale
\def\if@nodecpart#1.#2\@nil{\ifempty{#2}}¤§*\ifempty¤

\def\formatnum#1{\formatnum@i1!#1!}¤§*\formatnum¤

% #1 = <série de signes> suivie de "1"
% #2 = caractère courant
% #3 = caractères non traités
\def\formatnum@i#1!#2#3!{%
	\ifx+#2\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\ifempty{#3}% si #2=+ et #3 est vide¤§*\ifempty¤
			{\number#1 }% afficher "+1" ou "-1" (il n'y avait que des signes)¤\idx*\number¤
			{\formatnum@i#2#1!#3!}% sinon, mettre le signe #2 devant #1
		}
		{\ifx-#2\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{\ifempty{#3}% si #2=- et #3 est vide¤§*\ifempty¤
				{\number#1 }% afficher "+1" ou "-1" (il n'y avait que des signes)¤\idx*\number¤
				{\formatnum@i#2#1!#3!}% sinon, mettre le signe #2 devant #1
			}% #2 est le dernier caractère qui n'est pas un signe + ou -
			{\ifnum#1<0 -\fi% si "<signes>1" est <0 afficher un "-"¤\defline\aaa¤
			\formatnum@ii{#2#3}% formatter le nombre formé avec "#2#3""
			}%
		}%
}

\def\formatnum@ii#1{%
	\if@comma{#1}% si #1 comporte une virgule
		{\formatnum@iii#1\@nil}% la remplacer par un "." et recommencer
		{\if@nodecpart#1.\@nil% puis si les chiffres restants sont un entier
			{\formatintpart{#1}}% formatter l'entier
			{\formatnum@iv#1\@nil}% sinon, formatter le nombre
		}%
}

\def\formatnum@iii#1,#2\@nil{\formatnum@ii{#1.#2}}

\def\formatnum@iv#1.#2\@nil{% formatte le nombre décimal #1.#2
	\exparg\formatintpart{\romannumeral-`\.\removefirstzeros{#1}}%¤\idx*\romannumeral§*\removefirstzeros§*\exparg¤
	\exparg\formatdecpart{\romannumeral-`\.\removelastzeros{#2}}%¤§*\formatdecpart§*\removelastzeros§*\exparg¤
}

\def\if@comma#1{\if@comma@i#1,\@nil}% teste la présence d'un virgule dans #1
\def\if@comma@i#1,#2\@nil{\ifempty{#2}\secondoftwo\firstoftwo}¤§*\ifempty¤
\catcode`\@12

a) \formatnum{3,141592653589793238462643383279502884197169399375105820974944592}\par
b) \formatnum{---+69874}\qquad
c) \formatnum{0032100,98000}\qquad
d) \formatnum{+++010.01100}\qquad
e) \formatnum{-+--+}\qquad
f) \formatnum{---00.0000}\qquad
g) \formatnum{+99,0000}\qquad
h) \formatnum{.123456}\par
i) \edef\foo{\formatnum{-+-+-010500,090900}}\meaning\foo¤§*\formatnum¤|\idx*[|)]{formatter un nombre}

\section{Permettre à une boite encadrée de franchir des pages}
\subsection{Couper une boite verticale}\idx*[|(]{couper une boite verticale}
Cela avait été clairement annoncé à la page~\pageref{boite.insecable} : toute boite construite avec les primitives \idx\hbox, \idx\vbox ou \idx\vtop est \emph{insécable}. C'est effectivement le cas à un petit mensonge près\ldots{} Si une boite \emph{verticale} est stockée dans un registre de boite, il est possible de couper la boite ainsi stockée en deux boites verticales. La primitive qui permet cette opération est \idx\vsplit\footnote{En revanche, les boites horizontales \texttt{\string\hbox} sont \emph{vraiment} insécables, il n'existe hélas pas de primitive \texttt{\string\hsplit}.}.

\begin{regle}
Si \verb|<x>| est un registre de boite auquel on a assigné une boite verticale (construite avec \idx\vbox ou \idx\vtop) et si \verb|<y>| est un numéro de registre de boite, alors

\centrecode-\setbox <y>=\vsplit <x> to <dimension>-\idx*\vsplit

\noindent va commander à \TeX{} de parcourir la boite contenue dans le registre \no\verb|<x>| et opérer la meilleure coupure possible pour générer une boite de hauteur \verb|<dimension>|. Le registre \no\verb|<y>| contiendra cette nouvelle boite tandis que le registre \verb|<x>| contiendra la boite initiale amputée d'autant. Si la \verb|<dimension>| est suffisamment grande pour que la coupure englobe la totalité de la boite initiale \verb|<x>|, le registre \verb|<x>| devient vide, c'est-à-dire positif au test \tidx{ifvoid}.

Le mécanisme de coupure de boite verticale est similaire à celui des coupures de pages. En particulier, les objets « volatils » sont supprimés à la coupure (\idx{pénalité}s et espaces verticaux de type \idx[|etc]\kern\forbidindex\kern{} ou \idx\vskip).

Enfin, un ressort appelé \idx\splittopskip est inséré au sommet de la boite restante \verb|<x>|.
\end{regle}

Le code ci-dessous illustre cette règle, où la boite initiale contient 4 lignes, chacune enfermée dans une \idx\hbox :

\showcode/\setbox0=\vbox{%¤\idx*[|etc]\setbox\forbidindex\setbox¤
	\hbox{Première ligne}¤\idx*\hbox¤
	\hbox{Deuxième ligne}
	\hbox{Avant-dernière ligne}
	\hbox{Dernière ligne}
}

\frboxsep=0pt % aucun espace entre le contenu et l'encadrement¤§*\frboxsep¤
Boite initiale de hauteur \the\ht0 {} : \frbox{\copy0 }¤§*\frbox¤
\splittopskip0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\setbox1=\vsplit0 to 22pt % couper la boite à 22pt de hauteur¤\idx*\setbox\idx*\vsplit¤

Boite 1 de hauteur \the\ht1 {} : \frbox{\box1 }

Boite 0 de hauteur \the\ht0 {} : \frbox{\box0 }¤\idx*\box\idx*\the\idx*\ht §*\frbox¤/

Il faut noter qu'un message d'avertissement\idx*{message d'avertissement} est émis lorsque la coupure est faite : «\texttt{Underfull \string\vbox{} (badness 10000) detected}». Ce message indique que la boite \no1 est insuffisamment remplie\idx*{boite insuffisamment remplie}, ce que l'on peut constater visuellement. L'explication tient au fait que seules deux lignes ont pu être logées verticalement dans 22 points. Mais ces deux lignes ne remplissent pas la totalité de ces 22 points qui sont imposés. Pour éviter de garder une boite insuffisamment pleine, on peut utiliser

\centrecode-\setbox1=\vbox{\unvbox1 }-\idx*\unvbox

\noindent afin que la boite \no1 soit « extraite » de la \idx\vbox de hauteur imposée et, ayant repris sa dimension naturelle, soit à nouveau enfermée dans une \idx\vbox.

Pour empêcher \TeX{} d'émettre un message d'avertissement\idx*{message d'avertissement} lors de la coupe de la boite \no0, il faut agir sur l'entier \idx\vbadness qui représente le seuil de médiocrité au-delà duquel un message d'avertissement\idx*{message d'avertissement} n'est plus émis concernant une boite verticale (\idx\hbadness est le pendant pour les boites horizontales). Nous allons donc sauvegarder cet entier puis lui assigner l'entier \numprint{10000} qui représente la médiocrité maximale, et après avoir coupé la boite avec \idx\vsplit, restaurer \idx\vbadness à la valeur initiale.

\showcode/\setbox0=\vbox{%¤\idx*\setbox¤
	\hbox{Première ligne}
	\hbox{Deuxième ligne}
	\hbox{Avant-dernière ligne}
	\hbox{Dernière ligne}
}

\edef\restorevbadness{\vbadness=\the\vbadness\relax}% restaurera le \vbadness¤\idx*\the\idx*\vbadness¤
\vbadness=10000 % plus d'avertissement pour boite verticale¤\idx*{message d'avertissement}\idx*\vbadness¤
\frboxsep=0pt % aucun espace entre le contenu et l'encadrement¤§*\frboxsep¤
Boite initiale de hauteur \the\ht0 {} : \frbox{\copy0 }¤\idx*\the\idx*\copy §*\frbox¤
\splittopskip0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\setbox1=\vsplit0 to 22pt % couper la boite à 22pt de hauteur¤\idx*\setbox\idx*\vsplit¤
\setbox1=\vbox{\unvbox1 }% la boite 1 prend la hauteur naturelle¤\idx*\unvbox\idx*\vbox¤
\restorevbadness\relax% restaure le \vbadness

Boite 1 de hauteur \the\ht1 {} : \frbox{\box1 }

Boite 0 de hauteur \the\ht0 {} : \frbox{\box0 }¤\idx*\box\idx*\the\idx*\ht §*\frbox¤/

On constate bien que la boite \no1 a repris la hauteur naturelle et devient donc la boite contenant le plus de lignes possible dans \verb|22pt| de hauteur.

Il est en revanche assez inexplicable que la somme des deux hauteurs ne soit pas égale à la hauteur de la boite initiale. Il manque

\[34.024\text{\ttfamily pt}-2\times15.024\text{\ttfamily pt}\approx 4\text{\ttfamily pt}\]

Cette hauteur manquante est celle qui sépare la frontière inférieure de la boite \no1 de la frontière supérieure de la boite \no0. Ce \idx{ressort d'interligne} a disparu à la coupure, comme le font tous les ressorts aux coupures de page ou de ligne.\idx*[|)]{couper une boite verticale}

\subsection{Couper à la bonne hauteur}
Avant de bâtir un algorithme permettant de composer un texte dans un cadre qui franchit des pages, il reste tout de même une question essentielle : comment connaitre la hauteur qui reste à composer dans la page en cours ? Deux nouvelles primitives de \TeX{} vont nous permettre de répondre à cette question :

\begin{itemize}
	\item \idx\pagetotal est la dimension accumulée verticalement jusqu'à la fin du précédent paragraphe entièrement composé;
	\item \idx\pagegoal est la dimension verticale du texte à composer dans la page en cours.
\end{itemize}

La dimension \idx\pagetotal n'est pas actualisée en permanence, mais seulement après chaque paragraphe composé. Par ailleurs, au tout début de la construction d'une page, lorsqu'elle est vide, \idx\pagetotal vaut \numprint[pt]0 alors que \idx\pagegoal vaut \numprint[pt]{16383,99999}\footnote{Lire le \TeX book page~133 et plus généralement le chapitre 15 en entier.}, soit \idx\maxdimen. Par conséquent, notre futur algorithme devra tenir compte de cette spécificité au début des pages. Afin que \idx\pagegoal prenne une valeur reflétant la hauteur de la page, il faudra donc, avant de mesurer quoi que ce soit, faire en sorte que la nouvelle page ne soit pas vide . Insérer le matériel vertical «\idx\hbox\verb-{}-\idx\nointerlineskip» teindra lieu de remplissage de haut de page, tout en ne prenant aucune place verticalement. Ainsi, après cette opération, \idx\pagegoal sera égal à la hauteur de la zone de texte en haut d'une page. Nous sommes maintenant assurés que, quelles que soient les circonstances, la différence entre \idx\pagegoal et \idx\pagetotal sera la hauteur de l'espace vertical disponible restant dans la page en cours.

Ces deux primitives étaient ce qui nous manquait pour construire l'algorithme permettent de couper $n$ fois une boite verticale pour la loger sur $n+1$ pages.

Nous allons d'abord décider que le contenu à afficher dans un cadre sera compris entre les macros §\breakpar et\verb|\endbreakpar|. La première macro sera chargée d'assigner à un registre de boite verticale tout ce qui se trouvera jusqu'à \verb|\endbreakpar|. Pour cela, cette macro utilisera \idx\bgroup au lieu de «\verb|{|» pour délimiter le début de la boite alors que \verb|\endbreakpar| utilisera \idx\egroup pour marquer la fin de la boite verticale. La macro §\breakpar aura également pris soin, en début de boite, de diminuer la dimension horizontale \idx\hsize de cette boite. En effet, la largeur du texte à encadrer doit tenir compte de l'épaisseur de la réglure d'encadrement §\frboxrule et de l'espace entre le texte et cette réglure §\frboxsep, chacune de ces dimensions devant être comptée deux fois, une fois pour la réglure de gauche et une fois pour celle de droite.

En ce qui concerne le cadre proprement dit, il faut bien garder à l'esprit que selon les cas, les encadrements pourront être de 4 types différents :
\begin{enumerate}
	\item cadre plein (\kern1pt {\frboxsep=0pt \framebox{\phantom M}}\kern1pt ) dans le cas où l'espace restant dans la page en cours permet de loger le cadre dans sa totalité;
\end{enumerate}

\noindent Si le cadre ne peut loger sur la page en cours, 3 autres types sont possibles :
\begin{enumerate}[start=2]
	\item cadre de début (\kern1pt {\frboxsep=0pt \framebox[ULR]{\phantom M}}\kern1pt );
	\item cadre intermédiaire (\kern1pt {\frboxsep=0pt \framebox[LR]{\phantom M}}\kern1pt ) dans le cas où le texte à encadrer est tellement long qu'il faut une ou plusieurs pages intermédiaires entre le début du cadre et la fin;
	\item cadre de fin (\kern1pt {\frboxsep=0pt \framebox[DLR]{\phantom M}}\kern1pt ).
\end{enumerate}

% rappeler où a été créée la macro \framebox
Pour tracer ces cadres, la macro §\framebox vue à la page~\pageref{framebox} va nous être d'un grand secours, il suffira de spécifier le bon argument optionnel pour avoir le cadre du type souhaité.

Dans les grandes lignes, l'algorithme va fonctionner de cette manière :

\begin{algo}
	\item capturer et composer dans une \idx\vbox de largeur appropriée tout ce qui se trouve entre §\breakpar et \verb|\endbreakpar|, stocker cette boite dans le registre \verb|\remainbox| et aller au point \no2;
	\item macro §\splitbox
	\begin{algo}
		\item si \verb|\remainbox| est vide : fin du processus
		\item sinon, aller au point \no3.
	\end{algo}
	\item macro \verb|\splitbox@i|
	\begin{algo}
		\item si \verb|\remainbox|, une fois encadré, loge sur l'espace restant dans la page, l'encadrer avec le cadre \no1 ou \no4, et fin du processus;
		\item sinon couper \verb|\remainbox| à une hauteur correspondant à celle de l'espace restant sur la page; encadrer le registre de boite obtenu (\verb|\partialbox|) avec le cadre \no2 ou \no3, composer la page en cours et aller au point \no2 avec la boite restante \verb|\remainbox|.
	\end{algo}
\end{algo}

Pour mener à bien cet algorithme, nous avons à écrire 5 macros différentes : §\breakpar, \verb|\endbreakpar|, §\splitbox, \verb|\splitbox@i| ainsi qu'une macro qui affiche la boite à encadrer \verb|\printpartialbox|. Nous devrons correctement gérer l'argument optionnel de §\framebox (où les lettres «UDRL» spécifient les réglures à afficher) pour choisir selon les cas, le bon encadrement. Pour ce faire, nous stockerons dans la macro \verb|\rule@arg| les lettres devant être passées à cet argument optionnel.
\grandsaut

Avant d'entrer dans le vif du sujet, il est nécessaire d'examiner ce qui se passe en haut d'une page : afin que dans la mesure du possible, les lignes de base des premières lignes de chaque page se situent toutes à la même position verticale, le ressort \idx\topskip est inséré en haut de chaque page. Sa valeur est diminuée de la hauteur de la première ligne et si le résultat est négatif, le ressort \verb|0pt| est inséré. Plain-\TeX{} prend \idx\topskip égal à \verb|10pt| ce qui assure que toutes les premières lignes dont la hauteur est inférieure ou égale à \verb|10pt| commenceront à la même position verticale dans les pages.

Pour notre problème, si une boite doit être coupée, il ne faut pas qu'un ressort en haut de page soit inséré avant le cadre restant (\kern1pt {\frboxsep=0pt \framebox[LR]{\phantom M}} ou {\frboxsep=0pt \framebox[DLR]{\phantom M}}\kern1pt ) : le haut des réglures du cadre doit exactement coïncider avec le bord supérieur de la zone de texte. Par conséquent, \idx\topskip sera pris égal à \verb|0pt|. Avant de procéder à cette assignation, la valeur de \idx\topskip sera copiée dans \idx\splittopskip qui joue le même rôle que \idx\topskip dans les boites résiduelles après une coupure par \idx\vsplit. Ce faisant, à chaque début de page, on s'assure que la première ligne dans le cadre se situe à la même position verticale que les premières lignes des pages « normales ».
\grandsaut

Venons-en au c\oe ur du problème : à quelle hauteur allons-nous demander la coupure de la boite \verb|\remainbox| ? Au premier abord, on pourrait être tenté de répondre \idx*\pagegoal\idx*\pagetotal{}\verb|\pagegoal-\pagetotal| mais ce serait ignorer l'encombrement vertical de \verb|\frboxsep+\frboxrule|, requis par les éventuelles réglures (supérieures ou inférieures) d'épaisseur §\frboxrule et les espaces §\frboxsep qui les suivent ou les précèdent. Il va de soi que selon les cas, ces réglures sont présentes soit toutes les deux (cas du cadre {\frboxsep=0pt \framebox{\phantom M}}\kern1pt ), soit seulement une des deux (cadre {\frboxsep=0pt \framebox[ULR]{\phantom M}} ou {\frboxsep=0pt \framebox[DLR]{\phantom M}}\kern1pt ), soit aucune (cadre \kern1pt {\frboxsep=0pt \framebox[LR]{\phantom M}}\kern 1pt ). Nous devons être rigoureux pour ne pas demander trop ou trop peu de hauteur de coupure.

Pour nous faciliter la tâche, nous allons stocker dans la macro \verb|\coeff@rule| le nombre de réglures horizontales qui restent à afficher. Dans la macro chapeau, il sera initialisé à 2 puisque les deux réglures sont encore à afficher. Ce coefficient sera ensuite pris égal à 1 dès que la première coupure sera faite puisque la réglure supérieure ne sera plus à afficher.

Du côté du calcul, il faut décider si une coupure de \verb|\remainbox| doit avoir lieu ou pas. La réponse est positive si sa dimension verticale totale (hauteur + profondeur) est supérieure à l'espace disponible sur la page en cours auquel on a soustrait l'espace requis pour les réglures horizontales restantes. Mathématiquement, une coupure doit être faite si $\verb|\ht\remainbox|+\verb|\dp\remainbox|$ est strictement supérieur à $\verb|\pagegoal|-\verb|\pagetotal|-(\verb|\frboxsep|+\verb|\frboxrule|)\times\verb|\coeff@rule|$. Nous appellerons $D_v$ cette dernière quantité et la stockerons dans un registre de dimension appelé \verb|\cut@ht|.

Si la coupure doit être faite, à quelle hauteur doit être coupée \verb|\remainbox| ? Comme une coupure est faite, la réglure horizontale de fin de cadre ne se trouvera pas sur la page recevant la boite coupée. Par conséquent, la hauteur de coupure est $D_v$ augmentée de $\verb|\frboxsep|+\verb|\frboxrule|$.

Voici comment va opérer la macro \verb|\splitbox@i| :

\begin{itemize}
	\item le registre de dimension \verb|\cut@ht| reçoit la hauteur $D_v$;
	\item si une coupure doit être faite, la dimension $\verb|\frboxsep|+\verb|\frboxrule|$ est ajoutée à \verb|\cut@ht|;
	\item \verb|\remainbox| est coupée à la hauteur \verb|\cut@ht| et la boite obtenue est stockée dans le registre \verb|\partialbox|;
	\item on rend \verb|\coeff@rule| égal à 1 puisque la réglure supérieure ne peut plus être présente;
	\item si \verb|\splitbox@i| détecte que la coupure n'est pas nécessaire, \verb|\remainbox| sera copiée dans \verb|\partialbox| et \verb|\cut@ht| reçoit la hauteur verticale totale de \verb|\partialbox|;
\end{itemize}

Nous sommes bientôt au bout du tunnel, mais il y a un dernier raffinement auquel nous devons penser. Comment s'assurer que les réglures verticales des encadrements «{\frboxsep=0pt \framebox[ULR]{\phantom M}}» et «{\frboxsep=0pt \framebox[LR]{\phantom M}}» iront jusqu'en bas de la page ? En effet, si nous encadrons avec 

\centrecode-\expandafter\framebox\expandafter[\rule@arg]{\vbox{\unvbox\partialbox}}-\idx*\unvbox§*\framebox

\noindent le «\verb|\vbox{\unvbox\partialbox}|» va redonner à \verb|\partialbox| sa hauteur naturelle (plus petite que \verb|\cut@ht|) et l'encadrement n'atteindra pas exactement le bas de la page. Pour nous prémunir de cette petite perte de hauteur, nous devons imposer un cadre de hauteur \verb|\cut@ht|, car ce registre contient la hauteur totale verticale du texte à encadrer. On écrira donc dans l'argument de §\framebox

\centrecode-\vbox to\cut@ht{\unvbox\partialbox\vss}-\idx*\unvbox\idx*\vss

Le ressort \idx\vss se charge de rattraper la différence entre \verb|\cut@ht| et la hauteur naturelle de \verb|\partialbox|.
\grandsaut

Le code ci-dessous est un de ceux qui dérogent à ce qui est la règle dans ce livre. Le résultat du code n'est pas présenté celui qui découle de la compilation de ce code, car pour des raisons de place, les pages obtenues ont été réduites et présentées les unes à côté des autres.

\errcode/\catcode`@11
\newbox\remainbox¤\idx*\newbox¤
\newbox\partialbox¤\idx*\newbox¤
\newdimen\cut@ht¤\idx*\newdimen¤

\def\breakpar{%¤§*\breakpar¤
	\par\nointerlineskip% termine le paragraphe précédent¤\idx*\nointerlineskip¤
	\vskip\frboxsep\relax% et saute une petite espace verticale¤\idx*\vskip§*\frboxsep¤
	\begingroup
		\splittopskip\topskip% \topskip en haut des boites coupées¤\idx*\splittopskip\idx*\topskip¤
		\topskip=0pt % neutraliser le \topskip¤\idx*\topskip¤
		% nbre de réglures horizontales contribuant à l'encadrement restant (2 au début)
		\def\coeff@rule{2}%
		\setbox\remainbox=\vbox\bgroup% compose la boite après avoir...¤\idx*\setbox\idx*\vbox\idx*\bgroup¤
			\advance\hsize by -2\dimexpr\frboxrule+\frboxsep\relax% ajusté sa largeur¤\idx*\advance§*\frboxrule¤
}

\def\endbreakpar{%
		\egroup% fin de la composition de la boite¤\idx*\egroup¤
		\def\rule@arg{ULR}% prendre l\cut@htes réglures d'encadrement haute, gauche et droite
		\splitbox% puis, aller à l'algorithme de coupure¤§*\splitbox¤
	\endgroup% une fois fini, sortir du groupe semi-simple
}

\def\splitbox{%¤§*\splitbox¤
	\ifvoid\remainbox% si la boite est vide, c'est la fin du processus¤\tidx*{ifvoid}¤
		\par\nointerlineskip% termine le paragraphe précédent¤\idx*\nointerlineskip¤
		\vskip\frboxsep\relax% et saute un petit espace vertical¤\idx*\vskip§*\frboxsep¤
	\else% sinon
		\expandafter\splitbox@i% aller à \splitbox@i
	\fi
}

\def\splitbox@i{%
	\hbox{}% composer un noeud en mode vertical¤\idx*\hbox\idx*{mode!vertical}¤
	\nointerlineskip% pas de ressort d'interligne¤\idx*\nointerlineskip¤
	% calculer la dimension verticale disponible dans la page pour le texte de la boite
	\cut@ht=\dimexpr\pagegoal-\pagetotal-(\frboxsep+\frboxrule)*\coeff@rule\relax¤\idx*\dimexpr\idx*\pagegoal\idx*\pagetotal§*\frboxsep§*\frboxrule¤
	% si dimension totale du texte > dimension disponible pour le texte
	\ifdim\dimexpr\ht\remainbox+\dp\remainbox>\cut@ht% si une coupure doit être faite¤\tidx*{ifdim}¤
			\advance\cut@ht\dimexpr%   augmenter Dv de l'espace verticale libérée
				+\frboxsep+\frboxrule% par la réglure inférieure qui n'est pas sur cette page
				\relax
		\edef\old@vbadness{\the\vbadness}% sauvegarder \badness¤\idx*\the\idx*\vbadness¤
		\vbadness=10000 % désactive les avertissement lors de la coupure¤\idx*\vbadness\idx*{message d'avertissement}¤
		\def\coeff@rule{1}% ne prendre en compte que réglure D + espace D
		\setbox\partialbox=\vsplit\remainbox to\cut@ht% coupe à la hauteur calculée¤\idx*\setbox\idx*\vsplit¤
		% \partialbox retrouve sa hauteur naturelle
		\setbox\partialbox=\vbox{\unvbox\partialbox}%¤\idx*\setbox\idx*\vbox\idx*\unvbox¤
		\vbadness=\old@vbadness\relax% restaure \vbadness¤\idx*\vbadness¤
		\printpartialbox% imprime la boite partielle
		\vfill\eject% et compose la page en cours¤\idx*\vfill\idx*\eject¤
	\else% si une coupure n'est pas nécessaire :
		\setbox\remainbox\vbox{\unvbox\remainbox}% reprendre la hauteur naturelle¤\idx*\setbox\idx*\vbox\idx*\unvbox¤
		\setbox\partialbox=\box\remainbox% \partialbox devient \remainbox
		                                 % et cette dernière devient vide¤\idx*\box¤
		\cut@ht=\dimexpr\ht\partialbox+\dp\partialbox\relax% hauteur à encadrer¤\idx*\the\idx*\ht¤
		\edef\rule@arg{\rule@arg D}% ajouter "D" aux réglures à tracer
		\printpartialbox% afficher la boite restante
	\fi
	\splitbox¤§*\splitbox¤
}

\def\printpartialbox{% imprime \partialbox
	\expandafter\framebox\expandafter[\rule@arg]{%
		\vbox to\cut@ht{\unvbox\partialbox\vss}}%¤§*\framebox\idx*\vbox\idx*\unvbox\idx*\vss¤
	\def\rule@arg{LR}% ne mettre que les réglures d et g
}

\def\dummytext#1{%
	\for\xx=1to#1\do% composer #1 fois la phrase suivante :¤§*\for¤
		{Ceci est un texte sans aucun int\'er\^et dont le seul but est de meubler
		la page artificiellement.
		}%
}

\catcode`@12
\dummytext{5}
\frboxsep=5pt ¤§*\frboxsep¤

\breakpar
	\dummytext{70}
\endbreakpar¤§*\breakpar¤

\dummytext{5}/{\frboxrule=1pt \frboxsep=0pt \leavevmode
\hfill\frbox{\includegraphics[scale=0.15]{pg0001.pdf}}\hfill
\frbox{\includegraphics[scale=0.15]{pg0002.pdf}}\hfill
\frbox{\includegraphics[scale=0.15]{pg0003.pdf}}\hfill\null
}

\subsection{Couper un paragraphe en lignes}
Maintenant que le mécanisme de coupure à l'aide de \idx\vsplit est un peu maitrisé, nous allons le mettre à profit pour couper une boite verticale en lignes, chacune d'entre elles étant contenue dans une boite. L'énorme intérêt est qu'il devient alors possible d'effectuer une action pour chaque \emph{ligne} d'un ou plusieurs paragraphes. On pourra par exemple les numéroter ou afficher quelque chose dans la marge de gauche ou de droite. Il deviendra même possible d'agir sur la boite elle-même, pour l'encadrer par exemple.

À quelle hauteur faudra-t-il couper la boite contenant le tout pour n'obtenir qu'une seule ligne ? La question mérite d'être posée car nous n'avons aucune indication sur la hauteur d'une ligne. La méthode consiste à demander une coupure à une hauteur nulle. Cela va évidemment provoquer une «\texttt{overful vbox}» puisque rien ne peut tenir dans 0pt de hauteur. Il va donc falloir, le temps de la coupure, désactiver le mécanisme qui guette si une boite est trop remplie. \TeX{} dispose de la primitive \idx\vfuzz qui contient une dimension, seuil au-delà duquel est émis un avertissement\idx*{message d'avertissement} lorsqu'une boite verticale déborde (\idx\hfuzz est l'équivalent pour les boites horizontales)\idx*{débordement de boite}. Il suffira donc de dire que \verb|\vfuzz=\maxdimen| pour s'assurer qu'aucun avertissement\idx*{message d'avertissement} n'est émis lors du débordement d'une boite verticale, quelle que soit la valeur de ce débordement.

\showcode/\setbox0=\vbox{%¤\idx*\setbox¤
	\hsize=5cm ¤\idx*\hsize¤
	Ceci est un texte sans aucun intérêt dont le seul but est de meubler
	la page de façon artificielle.
}

Boite 0 : \copy0 % affiche la boite totale¤\idx*\copy¤
\medbreak¤\idx*\medbreak¤

\edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% appelée après la coupure¤\idx*\the\idx*\vfuzz¤
\vfuzz=\maxdimen% annule les avertissements pour débordement¤\idx*\maxdimen\idx*{message d'avertissement}\idx*\vfuzz¤
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\setbox1=\vsplit0 to 0pt % couper la boite à 0pt de hauteur¤\idx*\setbox\idx*\vsplit¤
\restorevfuzz% restaurer \vfuzz
\setbox1=\vbox{\unvbox1}% redonner à la boite sa hauteur d'origine¤\idx*\unvbox\idx*\vbox¤

Boites 1+0 : \vbox{%
	\offinterlineskip% annule le ressort d'interligne¤\idx*\offinterlineskip¤
	\box1 % affiche la première ligne¤\idx*\box¤
	\box0 %affiche les lignes restantes
}/

Comme on l'a déjà constaté, les ressorts disparaissent lors des coupures et donc ici, nous avons perdu le ressort d'interligne entre la 1\iere{} et la 2\ieme{} ligne. Si l'on veut afficher les lignes une par une, telles qu'elles auraient été affichées lors d'une composition normale, on doit absolument récupérer les ressorts mangés lors des coupures pour les insérer entre chaque ligne. Si l'on appelle \verb|\htbefore| la hauteur de la boite \no0 avant la coupure, alors, la longueur verticale du matériel mangé à la coupure est

\centrecode|\htbefore-(\ht0+\dp0+\ht1+\dp1)|

On peut le vérifier :

\label{recup.espace.vertical}\showcode/\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}% hauteur totale de la boite #1¤§*\vdim\idx*\dimexpr\idx*\ht\idx*\dp¤
\setbox0=\vbox{%¤\idx*\vbox\idx*\setbox¤
	\hsize=5cm Ceci est un texte sans aucun intérêt dont le seul but est¤\idx*\hsize¤
	de meubler la page de façon artificielle.
}
\edef\htbefore{\the\vdim0}% hauteur de la boite 0¤\idx*\the §*\vdim¤

Boite 0 : \copy0 % affiche la boite totale¤\idx*\copy¤
\medbreak¤\idx*\medbreak¤

\edef\restoreparam{%
	\vfuzz=\the\vfuzz\relax% sauvegarde le \vfuzz¤\idx*\the\idx*\vfuzz¤
	\splittopskip=\the\splittopskip% et \splittopskip¤\idx*\splittopskip¤
}%
\vfuzz=\maxdimen% annule les avertissements pour débordement¤\idx*\vfuzz\idx*\maxdimen\idx*{message d'avertissement}¤
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\setbox1=\vsplit0 to 0pt % couper la boite à 0pt de hauteur¤\idx*\setbox\idx*\vsplit¤
\restoreparam
\setbox1=\vbox{\unvbox1}% redonner à la boite sa hauteur d'origine¤\idx*\vbox\idx*\unvbox¤

\edef\intersplitspace{\the\dimexpr\htbefore-(\vdim0+\vdim1)\relax}%¤\idx*\the\idx*\dimexpr§*\vdim¤
Boites 1+0 : \vbox{%¤\idx*\vbox¤
	\offinterlineskip% annule le ressort d'interligne¤\idx*\offinterlineskip¤
	\box1 % affiche la première ligne¤\idx*\box¤
	\vskip\intersplitspace\relax% ajoute le ressort perdu à la coupure¤\idx*\vskip¤
	\box0 % affiche les lignes restantes¤\idx*\box¤
}/

Ici encore, \eTeX{} offre des primitives précieuses qui vont rendre la tâche précédente plus simple\footnote{Lire le manuel de \eTeX, chapitre «3.11 Discarded Items».}. La primitive \idx\savingvdiscards a vocation à contenir un entier qui, s'il est positif, autorise la sauvegarde des éléments ignorés lors d'une coupure verticale (les \idx\kern, les ressorts verticaux et les \idx{pénalité}s), qu'elle soit une coupure de page ou une coupure de boite verticale par \idx\vsplit. On peut ensuite insérer ces éléments dans une liste verticale avec \idx\pagediscards pour les éléments ignorés lors d'une coupure de page et avec \idx\splitdiscards pour ceux ignorés lors d'une coupure par \idx\vsplit. Ces deux listes d'éléments sauvegardés sont vidées après la routine de sortie ou au début de l'opération \idx\vsplit. Elles sont également vidées après avoir été utilisées.

Les macros \verb|\totalht| et \verb|\intersplitspace| du code précédent deviennent dès lors inutiles :

\showcode/\setbox0=\vbox{%¤\idx*\vbox\idx*\setbox¤
	\hsize=5cm Ceci est un texte sans aucun intérêt dont le seul but est¤\idx*\hsize¤
	de meubler la page de façon artificielle.
}

Boite 0 : \copy0 % affiche la boite totale¤\idx*\copy¤
\medbreak¤\idx*\medbreak¤

\edef\restoreparam{%
	\vfuzz=\the\vfuzz\relax% sauvegarde le \vfuzz¤\idx*\the\idx*\vfuzz¤
	\splittopskip=\the\splittopskip\relax% , le \splittopskip¤\idx*\splittopskip¤
	\savingvdiscards=\the\savingvdiscards\relax% et le \savingvdiscards
	}%
\vfuzz=\maxdimen% annule les avertissements pour débordement¤\idx*\vfuzz\idx*\maxdimen\idx*{message d'avertissement}¤
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\savingvdiscards=1 % autorise la sauvagarde des éléments supprimés¤\idx*\savingvdiscards¤
\setbox1=\vsplit0 to 0pt % couper la boite à 0pt de hauteur¤\idx*\setbox\idx*\vsplit¤
\setbox1=\vbox{\unvbox1}% redonner à la boite sa hauteur d'origine¤\idx*\setbox\idx*\unvbox\idx*\vbox¤
\restoreparam

Boites 1+0 : \vbox{%
	\offinterlineskip% annule le ressort d'interligne¤\idx*\offinterlineskip¤
	\box1 % affiche la première ligne¤\idx*\box¤
	\splitdiscards% affiche les éléments ignorés¤\idx*\splitdiscards¤
	\box0 % affiche les lignes restantes¤\idx*\box¤
}/

Maintenant que la méthode pour couper \emph{une} ligne a été exposée, il est facile de construire une macro récursive qui coupera successivement les lignes jusqu'à ce qu'il n'y ait plus rien à couper. Ceci sera fait par la macro §\numlines :

\centrecode-\numlines<texte à couper en lignes>\endnumlines-

Nous voulons manipuler chaque ligne ainsi coupée, c'est-à-dire avoir la possibilité d'écrire quelque chose à droite et à gauche de chaque ligne, tout en ayant également le contrôle sur la ligne elle-même. Nous allons donc écrire trois macros :

\begin{enumerate}
	\item les macros §\leftline et §\rightline, de syntaxe
	
	\centrecode-\leftline[<dimension>]{<matériel>}
\rightline[<dimension>]{<matériel>}-
	
	\noindent qui stockent dans des macros privées le \verb|<matériel>| à écrire à gauche et à droite de chaque ligne. Ce \verb|<matériel>| sera composé dans une \idx\hbox de longueur \verb|<dimension>| et dont le ressort \idx\hss sera correctement positionné pour le contenu s'étende à gauche ou à droite en débordement;
	\item une macro §\formatline dont l'argument \verb|#1| sera la boite contenant la ligne en cours. Par défaut, \verb|\formatline| sera rendue \verb|\let|-égale à §\identity pour afficher chaque ligne telle quelle. Il sera possible de personnaliser l'affichage en écrivant, par exemple, \verb|\let\formatline=\frbox| pour encadrer chaque ligne.
\end{enumerate}

Chaque ligne sera enfermée dans une \idx\hbox afin que le mode vertical principal perdure. Après cette \idx\hbox, \idx\splitdiscards sera insérée. Ainsi, une ligne sera composée de la façon suivante :

\centrecode-\hbox{%
	\hbox to<dimension gauche>{\hss<matériel gauche>}%
	\formatline{<ligne courante>}%
	\hbox to <dimension droite>{<matériel droit>\hss}%
}%
\splitdiscards-

Insérer \idx\splitdiscards dans la liste verticale principale nous empêche de savoir quelle est la dimension verticale totale de la ligne composée. Certes, nous aurions pu placer le tout dans une \idx\vbox et stocker cette boite un registre pour accéder à sa dimension verticale. Mais agir ainsi et enfermer \idx\splitdiscards aurait empêché le matériel contenu dans \idx\splitdiscards de disparaitre aux coupures de page.

Pourtant, accéder à la dimension verticale totale de la ligne composée peut s'avérer nécessaire pour correctement dimensionner les matériels affichés à droite et à gauche de la ligne courante pour obtenir certains effets. Nous allons donc agir comme au code de la page~\pageref{recup.espace.vertical} et calculer \verb|\htbefore| pour obtenir la hauteur de \idx\splitdiscards dans \verb|\intersplitspace|.

Comme le suggère son nom, la macro §\numlines a pour vocation première à numéroter les lignes du \verb|<texte>| qui s'étend jusqu'à \verb|\endnumlines|. Pour ce faire, un compteur \verb|\linecnt| est créé et incrémenté à chaque ligne. Il appartient à l'utilisateur d'afficher, s'il le souhaite, la valeur de ce compteur à l'aide de §\leftline ou §\rightline.

\showcode|\catcode`@11
\newbox\remainbox% boite contenant le texte total¤\idx*\newbox¤
\newbox\currentline% boite contenant le ligne en cours¤\idx*\newbox¤
\newcount\linecnt% compteur pour numéroter les lignes¤\idx*\newcount¤

\def\vdim#1{\dimexpr\ht#1+\dp#1\relax}% hauteur totale de la boite #1¤§*\vdim\idx*\dimexpr\idx*\ht\idx*\dp¤

\newmacro\leftline[0pt]{% définit ce qui se trouve à gauche de chaque ligne¤§*\newmacro§*\leftline¤
	\def\wd@left{#1}%
	\def\stuff@left
}

\newmacro\rightline[0pt]{% définit ce qui se trouve à droite de chaque ligne¤§*\newmacro§*\rightline¤
	\def\wd@right{#1}%
	\def\stuff@right
}

\let\formatline=\identity% par défaut, afficher chaque ligne telle quelle¤§*\identity¤

% Par défaut :
\leftline[11pt]{$\scriptscriptstyle\number\linecnt$\kern3pt }% numérotation à gauche¤\idx*\scriptscriptstyle§*\leftline¤
\rightline{}% rien à droite¤§*\rightline¤

\def\numlines{%¤§*\numlines¤
	\par\smallskip¤\idx*\smallskip¤
	\begingroup% dans un groupe semi-simple
		\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
		\linecnt=0 % initialiser le compteur de lignes
		\savingvdiscards=1 % autorise la sauvagarde des éléments supprimés¤\idx*\savingvdiscards¤
		\setbox\remainbox=\vbox\bgroup% compose la boite...¤\idx*\setbox\idx*\vbox\idx*\bgroup¤
			\advance\hsize by% diminuer la \hsize¤\idx*\advance\idx*\hsize¤
			-\dimexpr\wd@left+\wd@right\relax% de la largeur des contenus¤\idx*\dimexpr¤
}

\def\endnumlines{%
	\egroup¤\idx*\egroup¤
	\offinterlineskip¤\idx*\offinterlineskip¤
	\split@line
}

\def\split@line{%
	\ifvoid\remainbox% si la boite est vide¤\tidx*{ifvoid}¤
		\par% fin du processus
		\endgroup% fermer le groupe ouvert au début
	\else% sinon
		\advance\linecnt 1 % incrémente le compteur de lignes¤\idx*\advance¤
		\edef\htbefore{\the\vdim\remainbox}%¤\idx*\the §*\vdim¤
		\edef\restorevfuzz{\vfuzz=\the\vfuzz\relax}% sauvegarde le \vfuzz¤\idx*\vfuzz¤
		\vfuzz=\maxdimen% annule les avertissements pour débordement¤\idx*\maxdimen\idx*{message d'avertissement}\idx*\vfuzz¤
		\setbox\currentline=\vsplit\remainbox to 0pt % couper la boite à 0pt de hauteur¤\idx*\setbox\idx*\vsplit¤
		\restorevfuzz
		\setbox\currentline=\vbox{\unvbox\currentline}% redonner à la boite sa hauteur¤\idx*\setbox\idx*\unvbox¤
		\edef\intersplitspace{% calcul de l'espace vertical perdu à la coupure
			\the\dimexpr\htbefore-(\vdim\remainbox+\vdim\currentline)\relax¤\idx*\the\idx*\dimexpr §*\vdim¤
		}%
		\hbox{% en mode vertical et dans une hbox, afficher :¤\idx*{mode!vertical}¤
			\hbox to\wd@left{\hss\stuff@left}%   1) ce qui est à gauche¤\idx*\hss\idx*\hbox¤
			\formatline{\box\currentline}%       2) la ligne courante¤\idx*\box¤
			\hbox to\wd@right{\stuff@right\hss}% 3) ce qui est à droite¤\idx*\hss¤
		}%
		\splitdiscards% affiche ce qui a été ignoré à la coupure¤\idx*\splitdiscards¤
		\expandafter\split@line% recommencer
	\fi
}

\def\dummytext#1{%
	\for\xx=1to#1\do% composer #1 fois la phrase suivante :¤§*\for¤
		{Ceci est un texte sans aucun intérêt dont le seul but est de meubler
		la page de façon artificielle. }%
}

\catcode`@12
\parindent=2em ¤\idx*\parindent¤

ESSAI 1 :
¤§*\numlines¤\numlines
	\dummytext{2}\par% 2 phrases
	$$1+1=2$$\par% des maths
	\dummytext{1}\par% une phrase
	\hrulefill\par% un leaders¤\idx*\hrulefill¤
	\dummytext{2}% 2 phrases
	\hrule height2pt depth 2pt %une \hrule¤\idx*\hrule¤
	\vskip10pt % saute 10pt verticalement¤\idx*\vskip¤
	\dummytext{1}% une phrase
\endnumlines\medbreak¤\idx*\medbreak¤

ESSAI 2 :
\leftline{}\rightline{}% rien à gauche et rien à droite¤§*\leftline¤
\frboxsep=-\frboxrule% encadrer vers "l'intérieur"¤§*\frboxsep§*\frboxrule¤
\let\formatline\frbox% lignes encadrées¤§*\frbox¤
¤§*\numlines¤\numlines
	\dummytext{4}
\endnumlines\medbreak¤\idx*\medbreak¤

ESSAI 3 :
\let\formatline\identity¤§*\identity¤
\leftline[7pt]{%¤§*\leftline¤
	\for\xx= 1 to 2 \do{% insérer 2 fois¤\idx*\llap §*\for¤
		\setbox0=\hbox{% % mettre dans une \hbox une \vrule de "bonnes dimensions"¤\idx*\setbox\idx*\hbox¤
			\vrule height\ht\currentline depth\dimexpr\dp\currentline+\intersplitspace
			       width0.5pt }%¤\idx*\vrule\idx*\dimexpr\idx*\dp¤
		\dp0=\dp\currentline% réajuster la profondeur (c-à-d enlever \intersplitspace)¤\idx*\dp¤
		\box0 % afficher le boite¤\idx*\box¤
		\kern2pt % et insérer un espace horizontal de 2pt après chaque réglure verticale¤\idx*\kern¤
		}%
	\kern2pt % ajouter 2pt de plus entre les lignes et le texte¤\idx*\kern¤
}

\rightline[10pt]{\kern5pt $\scriptscriptstyle\number\linecnt$}% numéroter à droite¤\idx*\scriptscriptstyle§*\rightline¤

¤§*\numlines¤\numlines
	\dummytext{2}

	$$a^2+b^2=c^2$$

	\dummytext{2}
\endnumlines|
À l'essai \no3,  une petite cuisine interne est faite pour tracer deux traits verticaux à gauche du texte. Elle consiste à afficher deux fois un trait vertical de bonnes dimensions. Pour ce faire, le registre de boite \no0 reçoit une \idx\hbox contenant une réglure dont la hauteur coïncide exactement avec celle de la ligne en cours et dont la profondeur couvre aussi l'espace additionnel \verb|\intersplitspace| qui sépare deux lignes adjacentes. Cette \idx\hbox est ensuite redimensionnée pour qu'elle ait la dimension verticale de la ligne à afficher. En procédant ainsi, les réglures seront jointives d'une ligne à l'autre.

Pour arriver au même résultat, nous aurions pu inclure une \idx\hrule de même dimensions que la \idx\vrule de l'essai \no3 dans une \idx\vtop dont la dimension verticale est imposée et égale à la hauteur totale de la ligne à afficher. Le débordement vers le bas, d'une valeur de \verb|\intersplitspace| serait rattrapé par un \idx\vss. Voici donc un code équivalent qui ne mobilise pas de registre de boite :

\centrecode-\leftline[7pt]{%¤§*\leftline¤
	\for\xx= 1 to 2 \do{% insérer 2 fois¤§*\for¤
		\vtop to\dimexpr\ht\currentline+\dp\currentline{%¤\idx*\vtop\idx*\ht\idx*\dp¤
			\hrule height\ht\currentline
			       depth\dimexpr\dp\currentline+\intersplitspace¤\idx*\dp¤
			       width0.5pt
			\vss% rattrape la profondeur de trop \intersplitspace¤\idx*\vss¤
			}%
		\kern2pt % et insérer un espace horizontal
		         % de 2pt après chaque réglure verticale¤\idx*\kern¤
	}%
	\kern2pt % ajouter 2pt de plus entre les lignes et le texte¤\idx*\kern¤
}-

\section{Étirer horizontalement du texte}\idx*[|(]{étirer du texte}
Il tout d'abord faut être précis sur les termes. Étirer du texte va signifier ici que des espaces seront insérées entre chaque lettre de façon à ce que le texte ainsi modifié prenne davantage de place que s'il était composé normalement.

Il faut également savoir qu'étirer du texte est un effet typographiquement discutable qui donne parfois des résultats malheureux. Il est donc recommandé de ne pas en abuser et de limiter sa portée à des portions de texte \emph{courtes}, par exemple pour mettre en évidence des titres, cas où son emploi est justifié.

\subsection{Espace inter-lettre}
La méthode qui semble être la plus naturelle est d'insérer un ressort prédéfini que nous appellerons « inter-lettre » après chaque caractère dont le catcode est 11 ou 12 et en remplaçant l'espace par un ressort « inter-mot » dont la dimension fixe sera plus importante que celles des ressorts inter-lettres. La macro §\spreadtxt\verb|{<texte>}| s'acquittera de cette tâche.

La macro §\parse écrite à la page~\pageref{parse} permet de lire le texte token par token et d'agir en conséquence via la macro §\testtoken. Nous nous contenterons donc de modifier localement §\testtoken pour lui faire insérer les espaces voulues. La macro §\spreadtxt se chargera de lire son argument, d'ouvrir un groupe semi-simple, de correctement définir §\testtoken et appellera §\parse :

\showcode/% définition des ressorts "inter-lettre" et "inter-mot"
\newskip\interletterskip \interletterskip=0.25em plus0.05em minus0.05em ¤\idx*\newskip¤
\newskip\interwordskip   \interwordskip=3\interletterskip\catcode`\@11 ¤\idx*\newskip¤
\catcode`@11
\def\spreadtxt@testtoken#1{% macro qui teste le token¤§*\testtoken¤
	\ifcat\noexpand#1\sptoken% si le token est un espace¤\defline\aaa\tidx*{ifcat}\idx*\noexpand§*\sptoken¤
		\parseadd{%
			\unskip% retirer le précédent ressort¤\idx*\unskip¤
			\hskip\interwordskip}% et ajouter le ressort inter-mot¤\idx*\hskip¤
	\else
		\ifcat\noexpand#1a% si le token est une lettre¤\defline\bbb\tidx*{ifcat}¤
			\parseadd{#1\hskip\interletterskip}% ajouter le ressort inter-lettre¤\idx*\hskip¤
		\else
			\ifcat\noexpand#1.% si le token est "autre", comme le "."¤\defline\ccc\tidx*{ifcat}\idx*\noexpand¤
				\parseadd{#1\hskip\interletterskip}% ajouter le ressort inter-lettre¤\idx*\hskip¤
			\else% sinon
				\parseadd{#1}% ajouter le token lu¤\defline\ddd¤
			\fi
		\fi
	\fi
	\parse@i
}
\def\spreadtxt{%
	\ifstarred% si étoilée
		{\spreadtxt@i{\parse*}}% appeler \parse*¤§*\parse¤
		{\spreadtxt@i{\parse}}% sinon, appeler \parse¤§*\parse¤
}
\def\spreadtxt@i#1#2{% #1= appel "\parse*" ou "\parse"   #2 = texte à espacer
	\begingroup% dans un groupe
		\let\testtoken=\spreadtxt@testtoken% modifier \testtoken
		#1#2\parsestop% et appeler \parse
	\endgroup
}
\catcode`@12

\spreadtxt{Comme on le voit sur cet exemple, une espace est insérée après
{\it chaque} caractère de catcode 10, 11 ou 12.}¤\idx*\it\idx*{catcode!10\space(espace)}¤
\medbreak¤\idx*\medbreak¤

\spreadtxt*{Comme on le voit sur cet exemple, une espace est insérée après
{\it chaque} caractère de catcode 10, 11 ou 12.}¤\idx*\it¤/

Il y a un petit dysfonctionnement tout de même : les caractères accentués ne sont pas suivis d'une espace. Ceci s'explique par le fait que ce livre a été composé avec \LaTeX{} et l'extension \texttt{inputenc} chargée avec l'option \latin. La combinaison des deux rend les caractères accentués actifs et donc les tests des lignes \nos\aaa, \bbb{} et \ccc{} sont faux. Le token est donc simplement rajouté au registre de tokens à la ligne \no\ddd{} sans le ressort inter-lettre. Il y a plusieurs façons de se sortir de ce mauvais pas. On pourrait imaginer un test supplémentaire où l'on traiterait un caractère actif comme un caractère normal et insèrerait le ressort inter-lettre après lui. Mais cette méthode échouerait avec \utf et un moteur 8 bits\idx*{moteur!8 bits}, car si l'on rencontre un caractère codé sur plusieurs octets, le premier octet (actif) sera séparé des autres octets participant à la construction du caractère final.

On touche du doigt une difficulté majeure, celle de lire un texte caractère par caractère, où le mot « caractère » est pris au sens d'entité typographique. La difficulté dépend de la combinaison entre l'\idx{encodage} du code source et le type de moteur utilisé :

\begin{description}
	\item[cas favorables] Les associations entre un moteur et un \idx{encodage} sur un nombre d'octets correspondant à ce que lit le moteur ne présentent aucune difficulté puisque les caractères typographiques sont les entités lues par le moteur.
	\begin{itemize}[topsep=0pt]
		\item \idx*{moteur!8 bits}moteur 8 bits (comme \verb|tex|, \verb|etex| et \verb|pdftex|) avec un \idx{encodage} 8 bits (comme \latin) : les caractères lus sont des \idx{octet}s;
		\item \idx*{moteur!utf8}moteur \utf (comme \verb|xetex| et \verb|luatex|) avec un encodage \utf : les caractères lus sont des caractères \utf;
	\end{itemize}
	\item[cas défavorables] Les combinaisons entre un moteur 8 bits\idx*{moteur!8 bits} et un encodage multi octets comme \utf va faire surgir de grandes difficultés pour lire le code source caractère \utf par caractère \utf.
\end{description}

\subsection{Liste de motifs insécables}
Comment s'en sortir sans laisser de côté le cas le plus défavorable qui est encore très utilisé\footnote{L'association de pdf\TeX{} (ou pdf\LaTeX) avec un encodage \utf est en effet très répandu. Cette combinaison ouvre la possibilité d'écrire dans le code source beaucoup plus de caractères que ceux accessibles avec un \idx{encodage} 8 bits et fonctionne très bien sauf lorsqu'on souhaite élaborer des \emph{programmes} devant lire le code source caractère par caractère.} ? L'idée est de créer une liste de motifs indivisibles qui seraient laissés tels quels : il faudrait donc tester à chaque itération si les prochains caractères à lire ne commencent pas par un des motifs. Dans l'affirmative, il faudrait laisser ce motif et insérer le ressort inter-lettre après ce motif. Si le test s'avérait négatif, il faudrait agir comme précédemment.

Le problème est que pour déterminer si ce qui reste à lire commence par un motif, il faut lire la totalité du texte à espacer au préalable. La méthode change donc radicalement. Il ne s'agit plus de laisser §\parse faire le travail. Nous allons créer une nouvelle macro §\spacetxt qui reprendra en grande partie l'algorithme vu pour la macro §\substitute (voir page~\pageref{substitute}). Le principe consiste à stocker la totalité du texte initial dans la macro \verb|\spacetxt@code| et le texte espacé dans le registre de tokens \verb|\spacetxt@toks|. Au fur et à mesure des itérations, \verb|\spacetxt@code| sera peu à peu amputée des caractères lus et \verb|\spacetxt@toks| collectera le code produisant le texte espacé.

La liste des motifs indivisibles sera stockée dans la macro \verb|\indivilist|, chacun étant séparé du suivant par une virgule. Pour tenir compte de ces motifs, il faudra à chaque itération et avant toute chose, tester si le texte de remplacement de \verb|\spacetxt@code| commence par un des motifs déclarés dans \verb|\indivilist|. Cette série de tests sera faite à l'aide d'une boucle de type §\doforeach. Il est clair que tous ces tests supplémentaires vont être exécutés à chaque itération et cela consommera du temps; ce n'est donc pas une panacée du point de vue de l'efficacité du programme. Heureusement, comme le texte à espacer est censé être assez court et le nombre de motifs ne doit normalement pas excéder une dizaine d'éléments, la perte de temps n'est pas très importante. Nous utiliserons la macro §\doforeachexit pour sortir prématurément de la série de tests si l'un est positif et le booléen \verb|\if@indivifound| sera pris égal à \verb|vrai| pour indiquer qu'un motif a été trouvé. Dans ce cas, nous retirerons ce motif à \verb|\spacetxt@code| pour l'ajouter à \verb|\spacetxt@toks| en le faisant suivre de l'espace inter-lettre.

La fin du processus se produit lorsqu'il n'y a plus de texte à espacer, c'est-à-dire lorsque \verb|\spacetxt@code| est vide.

Pour espacer du texte entre accolades, la \idx{macro étoilée} §\spacetxt\verb|*| devra être appelée. Les mêmes astuces de programmation que pour la macro §\substitute ont été employées.\label{spacetxt}

\showcode/\newskip\interletterskip¤\idx*\newskip¤
\newskip\interwordskip ¤\idx*\newskip¤
\catcode`\@11
\newtoks\spacetxt@toks%  le registre qui contient le texte final¤\idx*\newtoks¤

\def\spacetxt{%¤§*\spacetxt¤
	\let\spacetxt@endprocess\spacetxt@endnormal
	% définit la macro appelée en fin de processus -> a priori : fin normale
	\ifstarred% si la macro est étoilée¤§*\ifstarred¤
		{\let\spacetxt@recurse\spacetxt@star% définir la macro récursive
		\spacetxt@i% et aller à \spacetxt@i
		}% sinon
		{\let\spacetxt@recurse\spacetxt@nostar% définir la macro récursive
		\spacetxt@i% et aller à \spacetxt@i
		}%
}

\newmacro\spacetxt@i[0.3em plus0.07em minus.07em][3\interletterskip]1{%¤§*\newmacro¤
% arg optionnel #1 et #2 = ressorts inter-lettre et inter--mot
% #3 = texte à espacer
	\interletterskip=#1\relax
	\interwordskip=#2\relax
	\def\spacetxt@code{#3}% met le texte à espacer dans \spacetxt@code
	\spacetxt@toks{}% initialiser le registre contenant le texte final
	\spacetxt@recurse% aller à la macro récursive précédemment définie
}

\newif\if@indivifound% booléen qui sera vrai si un motif spécial est rencontré¤\idx*\newif¤

\def\rightofsc#1#2{%
	\exparg\ifin{#1}{#2}% si #1 contient le #2
		{\def\right@of##1#2##2\@nil{\def#1{##2}}%
		\expandafter\right@of#1\@nil% appelle la macro auxiliaire
		}%
		{\let#1=\empty}% sinon, #1 est vide
}

\def\spacetxt@nostar{%
	\exparg\ifempty{\spacetxt@code}% si texte restant est vide¤§*\exparg §*\ifempty¤
		\spacetxt@endprocess% aller à la fin du processus
		{\@indivifoundfalse% sinon, a priori, les motifs non réguliers ne sont pas trouvés
		% pour chaque \indivi@tmp dans \indivilist
		\expsecond{\doforeach\indivi@tmp\in}{\indivilist}% pour chaque motif indivisible¤§*\expsecond §*\doforeach¤
			{% si le code commence par le motif courant
			\exptwoargs\ifstartwith\spacetxt@code\indivi@tmp¤§*\exptwoargs §*\ifstartwith¤
				{% l'ajouter dans le registre ainsi que l'espace inter-lettre
				\eaddtotoks\spacetxt@toks{\indivi@tmp\hskip\interletterskip}%¤§*\eaddtotoks\idx*\hskip¤
				% et enlever le motif du texte restant à lire
				\expsecond{\rightofsc\spacetxt@code}{\indivi@tmp}%¤§*\expsecond §*\rightofsc¤
				\@indivifoundtrue% marquer qu'un motif a été trouvé
				\doforeachexit% et sortir prématurément de la boucle¤§*\doforeachexit¤
				}%
				\relax% si le code ne commence pas le motif courant -> ne rien faire
			}%
		\unless\if@indivifound% si aucun motif n'a été trouvé¤\tidx*{unless}¤			
			\grab@first\spacetxt@code\spacetxt@temp% retirer le 1er caractère du texte
			\ifx\spacetxt@temp\space% si le 1er caractère est un espace¤\idx*\space¤
				\addtotoks\spacetxt@toks{%¤§\addtotoks¤
					\unskip% annuler le précédent ressort¤\idx*\unskip¤
					\hskip\interwordskip}% ajouter l'espace inter-mot au registre de token¤\idx*\hskip¤
			\else% si le 1er caractère n'est pas un espace
				% ajouter ce caractère et l'espace inter-lettre au registre de token
				\eaddtotoks\spacetxt@toks{\spacetxt@temp\hskip\interletterskip}%¤§*\eaddtotoks¤
			\fi
		\fi
		\spacetxt@recurse% enfin, continuer le processus
		}%
}

\def\spacetxt@star{%
	\exparg\ifempty{\spacetxt@code}% si texte restant est vide¤§*\exparg §*\ifempty¤
		\spacetxt@endprocess% aller à la fin du processus
		{% sinon, si texte commence par "{"
		\exparg\ifbracefirst{\spacetxt@code}%¤§*\exparg §*\ifbracefirst¤
			{\grab@first\spacetxt@code\spacetxt@temp
			% mettre {<argument} dans \spacetxt@temp
			\begingroup% ouvrir un groupe
			% mettre le contenu de l'argument dans \spacetxt@code
			\expandafter\def\expandafter\spacetxt@code\spacetxt@temp
			\let\spacetxt@endprocess\spacetxt@endingroup% changer le processus de fin
			\spacetxt@toks{}% initialiser
			\spacetxt@recurse% exécuter le processus avec ce nouveau texte
			}% si le code ne commence pas par "{", aller à \spacetxt@nostar mais comme
			\spacetxt@nostar% \spacetxt@recurse vaut \spacetxt@star, n'y faire qu'1 boucle
		}%
}

\def\spacetxt@endnormal{% fin de processus normal
	\the\spacetxt@toks% afficher le registre à token¤\idx*\the¤
	\unskip% et supprimer le dernier ressort¤\idx*\unskip¤
}

\def\spacetxt@endingroup{% fin du processus dans un groupe :
	\expandafter\endgroup\expandafter% avant de fermer le groupe
	\addtotoks\expandafter\spacetxt@toks\expandafter% ajouter au registre hors du groupe¤§*\addtotoks¤
		{\expandafter{\the\spacetxt@toks}}% ce qui est collecté localement mis entre {}¤\idx*\the¤
	\spacetxt@recurse% puis aller à la macro récursive
}

\catcode`\@12
\def\indivilist{é,è}% liste des motifs spéciaux
\spacetxt*{Comme on le voit sur cet exemple, une espace est insérée après
{\it chaque} caractère.}¤§*\spacetxt\idx*\it¤
\medbreak¤\idx*\medbreak¤

\def\indivilist{é,es,au,<<,>>}
\spacetxt[4pt plus.7pt minus.7pt][12pt plus2pt minus2pt]{Ici, les motifs <<es>> et <<au>>
restent indivisibles et la ligature des guillemets devient possible en déclarant "<<" et
">>" comme motifs.}¤§*\spacetxt\idx*\it¤/

Nous avons utilisé les arguments optionnels de la macro \verb|\spacetxt@i| pour définir à l'intérieur de celle-ci les ressorts inter-lettre et inter-mot. Cette méthode est préférable à celle de §\spreadtxt où l'on avait défini ces registres de ressort en dehors de toute macro. En effet, si l'on définit ces ressorts avec des unités qui varient selon le contexte (comme l'\idx*{unité!ex}\verb|ex| ou l'\idx*{unité!em}\verb|em|), les dimensions des ressorts ainsi définis ne dépendront que de la valeur de ces unités \emph{lors de l'assignation}.

Il est important de comprendre que l'\idx*{assignation!registre de ressort}assignation d'une dimension à un registre de ressort (ou de dimension) \emph{évalue} cette dimension pour la stocker dans le registre. La différence est fondamentale entre

\centrecode-<ressort>=0.3em-

\noindent et

\centrecode-\def\<macro>{0.3em}-

\noindent suivi plus tard de

\centrecode-<ressort>=\<macro>-

En effet, lorsqu'on écrit «\verb|<ressort>=0.3em|», la dimension \verb|3em| est évaluée et le résultat est stocké dans le registre qui dès lors, contient une dimension qui dépend de la valeur de l'\verb|em| lors de l'assignation.

Au contraire, écrire «\verb|\def\<macro>{0.3em}|» stocke simplement dans le texte de remplacement de \verb|\<macro>| les caractères «\verb|0.3em|». C'est lors de l'assignation de ressort «\verb|<ressort>=\<macro>|» que l'évaluation de \verb|0.3em| est faite. Ce passage par une macro auxiliaire de stockage permet donc de garder le caractère variable de l'unité \verb|em| et choisir le moment où l'on évalue cette dimension.

\subsection{Une alternative à \texttt{\char`\\litterate}}
La méthode précédente peut être adaptée pour insérer un court passage en fonte à chasse fixe à l'intérieur d'un paragraphe, pour écrire une adresse URL, par exemple. Nous allons écrire une macro §\ttcode, de syntaxe

\centrecode-\ttcode<délimiteur><texte><délimiteur>-

\noindent qui compose le \verb|<texte>| en police à chasse fixe où les tokens de catcode différents de 10, 11 et 12 sont neutralisés avec \idx\dospecials. En invoquant §\spacetxt, nous allons insérer un ressort de faible dimension après chaque token du \verb|<texte>| et donc, contrairement à §\litterate, §\ttcode permet qu'une coupure se produise après chaque token du \verb|<texte>|.

\showcode|\catcode`\@11
\def\ttcode#1{% lit #1, le <délimiteur> de début¤§*\ttcode¤
	\def\ttcode@i##1#1{% ##1 = <texte> entre délimiteurs
		\tt% passe en fonte à chasse fixe¤\idx*\tt¤
		\setbox0=\hbox{ }%¤\idx*\setbox\idx*\hbox¤
		\edef\spc@wd{\the\wd0 }% longueur d'un espace¤\idx*\the\idx*\wd¤
		\spacetxt¤§*\spacetxt¤
			[.1pt plus0pt minus.1pt]% espace inter-lettre
			[\glueexpr\wd0+.3pt plus.1pt minus.1pt\relax]% espace inter-mot¤\idx*\glueexpr\idx*\wd¤
			{##1}% le <texte> est composé par \spacetxt
		\endgroup
	}%
	\begingroup
		\def\indivilist{<<,>>,{,,},--}% (rajouter à, é, è, etc. en codage UTF8)
		\def\do##1{\catcode`##1=12 }%¤\idx*\do¤
		\dospecials% rend inoffensifs tous les tokens spéciaux¤\idx*\dospecials¤
		\letactive\ =\space % rend l'espace actif¤§*\letactive¤
		\ttcode@i% va lire le <texte> et le délimiteur de fin
}
\catcode`\@12

\hfill\vrule\vbox{%¤\idx*\hfill\idx*\vrule\idx*\vbox¤
	\hsize=.75\hsize¤\idx*\hsize¤
	Avec \ttcode/\ttcode/, on peut insérer une adresse internet <<
	\ttcode-http://www.gutenberg.eu.org/Typographie- >> puis repasser en fonte normale
	puis \ttcode+même composer un court passage en fonte à chasse fixe -- même si les
	coupures de mots se font n'importe où -- et aussi afficher tous les caractères
	spéciaux <<{$^ _$#}&+>>, et finir en fonte normale\ldots
}\vrule\hfill\null¤\idx*\hfill\idx*\vrule\idx*\null§*\ttcode¤|\idx*[|)]{étirer du texte}

\section{Composition en fonte à chasse fixe}\idx*[|(]{composition en fonte à chasse fixe}
\subsection{Mise en évidence du problème}
Une \idx{fonte}\footnote{On peut souvent confondre police et fonte, mais une différence sémantique existe. Une \emph{\idx{police}} est un ensemble de glyphes qu'un auteur (bien souvent, c'est le même auteur qui dessine une police entière) a dessiné dans un même esprit en respectant le même style. Une \emph{\idx{fonte}} est un sous-ensemble d'une police ayant des caractéristiques bien déterminées : taille, graisse (léger, normal, demi-gras, gras, etc.), forme (italique, penché, petite capitale, etc.)

Par exemple, le texte de ce livre est écrit avec la \emph{\idx{police}} Libertine, mais \textbf{ceci} et \textit{ceci} sont écrits en deux \emph{\idx{fonte}s} différentes de cette police.} est dite à « chasse fixe » lorsque tous ses caractères ont la même largeur, y compris l'espace qui est non étirable et non comprimable. La composition en fonte de ce type peut poser des problèmes, car à cause de cette particularité géométrique, il devient impossible de respecter \emph{en même temps} les trois contraintes suivantes\label{contraintes.tt} :

\begin{enumerate}
	\item caractères parfaitement les uns au-dessous des autres d'une ligne à l'autre;
	\item composition justifiée, c'est-à-dire que la distance entre le bord gauche du premier caractère et le bord droit du dernier est toujours la même;
	\item coupures des mots respectées ou interdites.
\end{enumerate}
\grandsaut

Il faut savoir que le passage en \idx{fonte} à chasse fixe avec \LaTeX{} à l'aide des macros \idx\texttt ou \idx\ttfamily désactive la coupure des mots (nous verrons comment). Dès lors, il suffit qu'un mot assez long se trouve en \idx{fin de ligne} pour que le dépassement dans la marge soit tellement important que parfois, les caractères se trouvent en dehors de la page physique. Les utilisateurs de \LaTeX{} savent certainement de quoi je parle\ldots

À titre d'exemple, voici un court paragraphe composé en fonte à chasse fixe (avec la macro \idx\ttfamily) comme le verrait un utilisateur de \LaTeX{} (alors que pour un utilisateur de \TeX{} avec la macro \idx\tt, les coupures de mots seraient effectuées) :

\showcode[\hfuzz=\maxdimen]|\def\ttwide{0.7}% coefficient pour la largeur de composition
\def\ttindent{5}% nombre de caractères d'indentation
\hfill\vrule¤\idx*\hfill\idx*\vrule¤
\vbox{%
	\ttfamily% en TeX, on écrirait "\tt"¤\idx*\ttfamily¤
	\setbox0\hbox{0}% \wd0 est donc la largeur d'un caractère¤\idx*\setbox¤
	\parindent=\ttindent\wd0 % réglage de l'indentation¤\idx*\parindent\idx*\wd¤
	\hsize=\ttwide\hsize % compose sur 70% de la largeur¤\idx*\hsize¤
	Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauches
	et droites du texte ont été tracées, on constate que les caractères sont
	exactement les uns au-dessous d'une ligne à l'autre. Des débordements dans
	la marge deviennent alors inévitables, car la largeur de composition (ici
	\the\hsize) n'est pas un multiple de la largeur d'un caractère (\the\wd0 ),¤\idx*\the\idx*\hsize\idx*\wd¤
	le quotient des deux valant environ
	\xdef\ttratio{\decdiv{\dimtodec\hsize}{\dimtodec\wd0 }}\ttratio.¤§*\decdiv§*\dimtodec\idx*\wd\idx*\xdef¤
}%
\vrule\hfill\null¤\idx*\null¤|

Bien sûr, le \idx[!log]{fichier} \verb|log| contient 6 avertissements\idx*{message d'avertissement}, chacun informant l'utilisateur que \TeX{} a dû composer une ligne trop longue\idx*{débordement de boite} :

\centrecode|Overfull \hbox (4.97778pt too wide) in paragraph at lines 9--16
Overfull \hbox (31.85786pt too wide) in paragraph at lines 9--16
Overfull \hbox (20.33783pt too wide) in paragraph at lines 9--16
Overfull \hbox (43.3779pt too wide) in paragraph at lines 9--16
Overfull \hbox (1.13777pt too wide) in paragraph at lines 9--16
Overfull \hbox (8.8178pt too wide) in paragraph at lines 9--16|

Ici en effet, sur chaque ligne, il entre \def\intratio#1.#2\relax{\def\intratio{#1}}\expandafter\intratio\ttratio\relax\intratio{} caractères complets. Après ce \intratio\ieme{} caractère, comme il reste de la place, \TeX{} place le caractère suivant entrant dès lors dans un dépassement dans la marge. Les coupures de mots étant interdites, il continuera à placer des caractères dans la marge jusqu'au prochain espace qui provoquera, mais trop tard, une coupure de ligne.

Livrons-nous à un petit calcul pour comprendre la valeur \verb|8.8178pt| donnée pour le dépassement de la sixième ligne. Cette ligne comporte 62 caractères : les \intratio{} complets plus les 3 dernières lettres du mot «\verb|quotient|». Le dépassement dans la marge vaut

\[
62\times3.84001-229.26292
\]

\noindent c'est-à-dire \verb|8.8177pt|. C'est bien, à une erreur d'arrondi près, la valeur qui est donnée par \TeX{} dans le message d'avertissement\idx*{message d'avertissement} du \idx[!log]{fichier} \verb|log|.

\subsection{\Qu elques notions sur les fontes}
Avant d'envisager toute solution concernant les fontes de caractères, il nous faut entrer un peu plus profondément dans les entrailles de \TeX{} afin d'examiner quelques commandes spécifiques. Nous nous en tiendrons au strict minimum, car la manipulation des fontes en \TeX{} est un monde long et complexe à explorer.

\subsubsection{Les primitives \texttt{\char`\\font} et \texttt{\char`\\fontname}}\idx*[|(]\fontname
\begin{regle}
La primitive \idx\fontname permet d'accéder au nom externe d'un fichier de \idx{fonte} selon la syntaxe

\centrecode-\fontname<fonte>-

\noindent où \verb|<fonte>| est soit une séquence de contrôle définie avec la primitive \idx\font, soit la primitive \idx\font elle-même auquel cas on fait référence à la fonte en cours d'utilisation. Le tout se développe en le nom du fichier externe correspondant à la \idx{fonte} spécifiée.
\end{regle}

Ainsi, ce paragraphe est écrit avec une des fontes de la \idx{police} «Libertine» dont le nom du fichier externe est «\expandafter\texttt\expandafter{\fontname\font}». Lorsqu'on passe en fonte grasse, le nom devient «{\bfseries\expandafter}\expandafter\texttt\expandafter{\fontname\font}» tandis qu'avec la fonte italique, le nom est «{\itshape\expandafter}\expandafter\texttt\expandafter{\fontname\font}».

Lorsqu'une \idx{fonte} est utilisée dans une autre taille que celle pour laquelle elle a été dessinée, le mot-clé «\verb|at|» suivi de la taille d'utilisation est ajouté après le nom obtenu :

\begingroup
\showcode|Fonte normale : \fontname\font\par¤\idx*\fontname\idx*\font¤
{\bf Fonte grasse : \fontname\font\par}¤\idx*\bf¤
{\it Fonte italique : \fontname\font\par}¤\idx*\it¤
{\sc Fonte petites majuscules : \fontname\font}¤\idx*\sc¤|\idx*[|)]\fontname
\endgroup

Le «\verb|at 8.0pt|» exprime que les rendus des codes de ce livre sont composés avec une taille de \verb|8pt| imposée, ce qui revient à dire que les dessins des caractères ainsi que toutes leurs dimensions géométriques ont été redimensionnés pour atteindre cette taille.

\begin{regle}
La primitive \idx\font permet de créer une séquence de contrôle qui, lorsqu'elle sera exécutée, effectuera un changement de fonte. On utilise la syntaxe

\centrecode-\font\<macro>=<nom de fonte> at <dimension>-

\noindent où «\verb|at <dimension>|» est facultatif.
\end{regle}

Voici comment créer des macros (\verb|\gras|, \verb|\ital| et \verb|\itgras|) qui, lorsqu'elles sont appelées, sélectionnent respectivement la \idx{fonte} de taille \verb|8pt|, en gras, italique et gras italique :

\showcode/\font\gras=LinLibertineTB-tlf-t1 at 8pt¤\idx*\font¤
\font\ital= LinLibertineTI-tlf-t1 at 8pt
\font\itgras=LinLibertineTBI-tlf-t1 at 8pt
Du texte normal {\gras puis en gras, \ital en italique,
\itgras en italique gras} et retour à la normale./

\subsubsection{Caractère de coupure de mots}
Chaque \idx{fonte} se voit assigner un caractère de coupure qui sera inséré à la fin d'une ligne lorsqu'un mot est coupé. Par défaut, ce caractère est le tiret «\verb|-|».

\begin{regle}
Le caractère inséré aux coupures de mots est stocké dans un registre interne de type entier appelé \idx*{caractère de coupure}\idx\hyphenchar. Ce registre \emph{doit} être suivi de la \idx{fonte} à laquelle on souhaite se référer :

\centrecode-\hyphenchar<fonte>-

On peut à tout moment choisir un autre caractère de coupure par son code de caractère en modifiant \idx*{caractère de coupure}\idx\hyphenchar :

\centrecode-\hyphenchar<fonte>=<code de caractère>-

Si le \verb|<code de caractère>| contenu dans \idx*{caractère de coupure}\idx\hyphenchar est négatif ou est supérieur à 255, aucun caractère n'est sélectionné et cela désactive les coupures de mots.

L'assignation d'un entier à \idx*{caractère de coupure}\idx\hyphenchar est toujours globale\idx*{assignation!toujours globale}.
\end{regle}

\showcode/Code du caractère de coupure = \number\hyphenchar\font\par¤\idx*\font¤
Caractère de coupure : "\char\hyphenchar\font"/

Voici comment modifier le \idx*{caractère de coupure}\idx\hyphenchar :

\showcode[\hfuzz=\maxdimen]/\def\longtext{Voici une phrase écrite avec des mots insignifiants mais terriblement,
	épouvantablement, horriblement et indéniablement longs.}
% créér une macro restaurant le \hyphenchar
\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%¤\idx*\hyphenchar\idx*\font¤

%comportement normal, caractère de coupure "-"
1) \vrule\vbox{\hsize=5cm \longtext}\vrule\hfill¤\idx*\vrule\idx*\vbox\idx*\hsize\idx*\hfill¤
% modification du caractère de coupure "W"
2) \vrule\vbox{\hsize=5cm \hyphenchar\font=`W \longtext}\vrule¤\idx*\hyphenchar¤
\medbreak¤\idx*\medbreak¤
% interdiction des coupures de mots
3) \vrule\vbox{\hsize=5cm \hyphenchar\font=-1 \longtext}\vrule¤\idx*\hyphenchar\idx*\font\idx*\vrule¤
\restorehyphenchar/

Lorsque la largeur de la composition est faible, interdire les coupures peut conduire \TeX{} à composer des lignes trop ou pas assez remplies. La macro de \LaTeX{} \idx\sloppy relâche certains paramètres de composition de \TeX{} de telle sorte que les débordements dans les marges sont presque toujours évités, au prix d'espaces inter-mots parfois très (trop !) larges. C'est pourquoi elle ne doit être utilisée qu'en ultime recours.

\showcode[\hbadness=10000 ]/\def\longtext{Voici une phrase écrite avec des mots insignifiants mais terriblement,
	épouvantablement, horriblement et indéniablement longs.}

\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%¤\idx*\hyphenchar\idx*\font¤
\vrule\vbox{\hsize=5cm \hyphenchar\font=-1 \sloppy \longtext}\vrule¤\idx\hsize\idx*\hyphenchar\idx*\font\idx*\sloppy¤
\restorehyphenchar/

Les utilisateurs de \LaTeX{}, à qui s'adresse le code ci-dessous, doivent donc savoir que lorsqu'ils passent en \idx{fonte} à chasse fixe (avec la macro \idx\ttfamily ou \idx\texttt), le code du \idx{caractère de coupure} vaut $-1$. Les coupures de mots sont dès lors interdites.

\showcode/a) \texttt{\number\hyphenchar\font}\qquad¤\idx*\texttt\idx*\number\idx*\hyphenchar\idx*\font¤
b) {\ttfamily\number\hyphenchar\font}¤\idx*\ttfamily¤/

\subsubsection{Dimensions de fonte}\label{espace.dimensions.fonte}\idx*[|(]{dimensions de fonte}
\begin{regle}
Pour composer du texte, chaque \idx{fonte} dispose de sept dimensions propres contenues dans des registres de dimension spéciaux accessibles via la primitive \idx\fontdimen. Chacun de ces registres est accessible par

\centrecode-\fontdimen<entier><fonte>-

où \verb|<entier>| est le numéro de la dimension (compris entre 1 et 7) et dont la signification est la suivante :

\begin{enumerate}[label=\protect\no\arabic{*}]
	\item pente par point (dimension utilisée pour placer les accents);
	\item espace inter-mot (dimension naturelle de l'espace);
	\item étirement inter-mot;
	\item compression inter-mot;
	\item \texttt x-height (valeur de \texttt{1ex});
	\item cadrat (valeur de \texttt{1em});
	\item espace supplémentaire (espace ajouté en fin des phrases).
\end{enumerate}
\end{regle}

Les plus intéressants ici sont les \nos2, 3 et 4 qui permettent de régler la façon dont un espace se comporte lors de la composition. Pour les fontes à chasse fixe, les dimensions \nos3 et 4 sont nulles et la dimension \no2 est égale à largeur de tous les autres caractères.

\showcode/\leavevmode¤\idx*\leavevmode¤
\vbox{%¤\idx*\vbox¤
	\hsize=.4\hsize¤\idx\hsize¤
	\Souligne{Police à chasse variable}%¤§*\Souligne¤
	\vskip5pt ¤\idx*\vskip¤
	espace inter-mot = \the\fontdimen2\font\par¤\idx*\the\idx*\fontdimen\idx*\font¤
	étrirement inter-mot = \the\fontdimen3\font\par
	compression inter-mot = \the\fontdimen4\font¤\idx*\the\idx*\fontdimen\idx*\font¤
}\hfill¤\idx*\hfill¤
\vbox{%¤\idx*\vbox¤
	\tt¤\idx*\tt¤
	\hsize=.4\hsize¤\idx*\hsize¤
	\Souligne{Police à chasse fixe}%¤§*\Souligne¤
	\vskip5pt ¤\idx*\vskip¤
	espace inter-mot = \the\fontdimen2\font\par
	étrirement inter-mot = \the\fontdimen3\font\par
	compression inter-mot = \the\fontdimen4\font¤\idx*\the\idx*\fontdimen\idx*\font¤
}/\idx*[|)]{dimensions de fonte}

\subsubsection{Coupures de mots}
Si l'on travaille avec \LaTeX, la première idée est de réactiver les coupures de mots pour composer un texte en fonte à chasse fixe.

\showcode[\hfuzz=\maxdimen]/\def\ttwide{0.7}\def\ttindent{5}%
\hfill\vrule¤\idx*\vrule¤
\vbox{%
	\ttfamily¤\idx*\ttfamily¤
	\hyphenchar\font=`\- % change le caractère de coupure de la fonte en cours¤\idx*\hyphenchar\idx*\font¤
	\setbox0\hbox{0}\parindent=\ttindent\wd0 ¤\idx*\setbox\idx*\hbox\idx*\parindent\idx*\wd¤
	\hsize=\ttwide\hsize % compose sur 70% de la largeur¤\idx*\hsize¤
	Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
	et droite du texte ont été tracées, on constate que les caractères sont
	exactement les uns au-dessous des autres d'une ligne à l'autre. Des débordements
	dans la marge deviennent inévitables même si les coupures des mots sont
	à nouveau rendues possibles.%
}%
\vrule\hfill\null¤\idx*\vrule\idx*\hfill\idx*\null¤/

Peut-on effectuer les coupures, mais ne pas insérer de caractère de coupure ? La réponse est non, mais il est parfois possible, selon la \idx{fonte} utilisée, de trouver un caractère de dimension horizontale nulle et ne se traduisant par aucun dessin. On peut le chercher en construisant une macro \verb|\printallchars| moyennant une boucle §\for :

\showcode/\frboxsep=0.5pt ¤§*\frboxsep¤
\def\printallchars{%
	\leavevmode¤\idx*\leavevmode¤
	\for\xx=0 to255\do{%¤§*\for¤
		\vbox{% empiler verticalement¤\idx*\vbox¤
			\offinterlineskip% en désactivant le ressort d'interligne¤\idx*\offinterlineskip¤
			\setbox0\hbox{\frbox{\char\xx}}%¤\idx*\setbox\idx*\hbox §*\frbox\idx*\char¤
			\copy0 % la boite contenant le caractère encadré¤\idx*\copy¤
			\kern1pt% saute 1pt vertical¤\idx*\kern¤
			\hbox to\wd0{\hss$\scriptscriptstyle\xx$\hss}% le numéro¤\idx*\hbox\idx*\wd\idx*\hss\idx*\scriptscriptstyle¤
		}\hskip0.5em plus1pt minus1pt % saute 0.5em horizontalement¤\idx*\hskip¤
	}%
}
\tt¤\idx*\tt¤
Nom de la fonte = \fontname\font\par¤\idx*\fontname\idx*\font¤
\printallchars/

Par chance, il semblerait que dans la \idx{fonte} à chasse fixe utilisée dans ce livre (qui est « \texttt{LinLibertineMTC} »), le caractère \no23 de cette \idx{fonte} n'ait aucune dimension horizontale. Vérifions-le :

\showcode/\setbox0=\hbox{\tt\char23}¤\idx*\setbox\idx*\hbox\idx*\tt\idx*\char¤
Largeur = \the\wd0 \qquad Hauteur = \the\ht0 \qquad Profondeur = \the\dp0 ¤\idx*\the\idx*\wd\idx*\ht\idx*\dp¤/

Il est utile de signaler que \eTeX{} offre des primitives bien pratiques pour mesurer les dimensions d'un caractère dans une \idx{fonte} donnée : \idx\fontcharht, \idx\fontcharwd, \idx\fontchardp et \idx\fontcharic, suivies d'une spécification de \idx{fonte} et d'un code de caractères donnent des dimensions égales à la hauteur, largeur, profondeur et correction d'italique du caractère concerné. La dimension \verb|0pt| est renvoyée si le caractère n'existe pas. Le code précédent peut donc s'écrire :

\showcode/{\tt\xdef\nfont{\the\font}}¤\idx*\the\idx*\font\idx*\tt\idx*\xdef¤
Largeur = \the\fontcharwd\nfont23 \qquad Hauteur = \the\fontcharht\nfont23 ¤\idx*\fontcharwd\idx*\fontcharht\idx*\fontchardp¤
\qquad Profondeur = \the\fontchardp\nfont23 /

Concernant ce caractère \no23, il importe peu que la hauteur ne soit pas nulle puisque seule la largeur nulle revêt une importance ici. Elle signifie que si l'on choisit ce caractère comme caractère de coupure avec

\centrecode-\hyphenchar\font=23 -

\noindent tout se passera comme si aucun caractère de coupure n'était sélectionné. Cette man\oe uvre suppose bien entendu que la \idx{fonte} s'y prête et dispose d'un tel caractère.
\grandsaut

Nous avons progressé, mais pas résolu le problème que pose la composition sur plusieurs lignes de texte en fonte à chasse fixe : les débordements sont toujours bien là, même s'ils sont moins importants.

\subsection{Justifier et couper}
Nous allons maintenant supprimer la première contrainte vue à la page~\pageref{contraintes.tt} et nos contraintes seront donc : 

\begin{enumerate}[start=2]
	\item composition justifiée, c'est-à-dire que la distance entre le bord gauche du premier caractère et le bord droit du dernier est toujours la même;
	\item coupures des mots respectées ou carrément interdites.
\end{enumerate}

\noindent Respecter ces contraintes revient à « casser » l'alignement vertical des caractères entre les lignes et en tirer parti pour supprimer --~ou au moins réduire au minimum~-- les débordements dans la marge. La méthode consiste à donner à l'espace le caractère étirable qu'il a dans les autres fontes, c'est-à-dire le rendre compressible et extensible dans des limites raisonnables à fixer, bien entendu. Pour cela, il faut rendre non nuls les \idx\fontdimen \nos3 et~4 de la \idx{fonte} à chasse fixe. Ici, nous allons donner une composante extensible égale à 30\% de l'espace inter-mot et une composante compressible égale à 20\% de cet espace. Un « environnement » sera créé pour l'occasion et s'étendra entre la macro §\ttstart et \verb|\ttstop|.

Nous devons prendre nos précautions pour que les modifications des paramètres de la \idx{fonte} ne restent pas globales\idx*{assignation!toujours globale}\footnote{Les assignations \texttt{\char`\\fontdimen} et\texttt{\char`\\hyphenchar} sont toujours globales, lire le \TeX book page~322. }. Pour cela, la macro \verb|\restaurefontsettings| sera chargée de sauvegarder les paramètres de \idx{fonte} avant les modifications. Elle sera appelée par \verb|\ttstop|, juste avant la fermeture du groupe.

\showcode/\newmacro\ttstart[5]{%¤§*\ttstart§*\newmacro¤
	\begingroup
	\tt¤\idx*\tt¤
	\edef\restorefontsettings{% stocke les paramètres de fonte
		\hyphenchar\font=\the\hyphenchar\font\relax% le \hyphenchar¤\idx*\the\idx*\hyphenchar\idx*\font¤
		\fontdimen2\font=\the\fontdimen2\font\relax% et les paramètres d'espacement¤\idx*\fontdimen¤
		\fontdimen3\font=\the\fontdimen3\font\relax
		\fontdimen4\font=\the\fontdimen4\font\relax¤\idx*\the\idx*\fontdimen¤
	}%
	\fontdimen3\font=0.30\fontdimen2\font% composante + = 30% de la dimension naturelle¤\idx*\fontdimen\idx*\font¤
	\fontdimen4\font=0.20\fontdimen2\font% composante - = 20% de la dimension naturelle
	\hyphenchar\font=`\- % on autorise la coupure des mots (au cas où on utilise latex)¤\idx*\hyphenchar¤
	\setbox0\hbox{0}% largeur d'un caractère¤\idx*\setbox\idx*\hbox¤
	\parindent=#1\wd0 % indentation (en nombre de caractères)¤\idx*\parindent\idx*\wd¤
	\ignorespaces¤\idx*\ignorespaces¤
}
\def\ttstop{%
	\restorefontsettings% restaure les paramètres de fonte
	\endgroup% et ferme le groupe
}
\hfill\vrule¤\idx*\hfill\idx*\vrule¤
\def\ttwide{0.70}%
\vbox{%
	\hsize=\ttwide\hsize % compose sur 70% de la largeur¤\idx*\hsize §*\ttstart¤
	\ttstart[5]
	Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
	et droite du texte ont été tracées, on constate que les caractères ne sont pas
	exactement les uns au-dessous des autres entre les lignes du paragraphe.
	Puisque les espaces sont redevenus étirables, les débordements dans la marge
	(même s'ils restent possibles), sont bien plus rares et ce d'autant plus que
	le nombre d'espaces dans une ligne est grand.%
	\ttstop
}%
\vrule\hfill\null¤\idx*\vrule\idx*\hfill\idx*\null¤/

Le but est atteint, aucun débordement dans la marge n'a lieu, mais comme attendu, on perd l'alignement vertical des lettres entre les lignes. Remarquons que les valeurs 30\% et 20\% devront être augmentées si le nombre de caractères par ligne diminue et réduites dans le cas contraire.
\grandsaut

Une autre alternative aux \idx\fontdimen existe pour modifier l'espace inter-mot. Il s'agit du ressort-primitive \idx\spaceskip qui, s'il n'est pas nul, écrase les spécifications contenues dans \idx\fontdimen \nos2, 3 et~4. L'avantage est que sa modification tient compte des groupes et y reste locale, contrairement aux modifications de \idx\fontdimen. Ainsi, les lignes

\centrecode-\fontdimen3\font=0.30\fontdimen2\font
\fontdimen4\font=0.20\fontdimen2\font-\idx*\font
	
\noindent peuvent être remplacées par celles-ci\idx*\font

\centrecode-\spaceskip=\fontdimen2\font ¤\idx*\spaceskip¤
    plus0.3\fontdimen2\font
    minus0.2\fontdimen2\font-

\subsection{Justifier et aligner}
Le but ici est de supprimer la 3\ieme{} contrainte de la page~\pageref{contraintes.tt} ce qui revient à se fixer les contraintes suivantes :

\begin{enumerate}
	\item caractères parfaitement les uns au-dessous des autres d'une ligne à l'autre;
	\item composition justifiée, c'est-à-dire que la distance entre le bord gauche du premier caractère et le bord droit du dernier est toujours la même.
\end{enumerate}

\noindent Ces deux contraintes impliquent que ces compromis doivent être concédés:

\begin{itemize}
	\item une espace inter-lettre de dimension invariable doit être insérée entre tous les caractères d'une même ligne;
	\item les coupures peuvent se faire n'importe où, même entre deux caractères où elles n'auraient pas eu lieu si elles avaient été faites par l'algorithme de coupure\footnote{Cet algorithme est décrit à l'annexe H du \TeX book.} de \TeX.
\end{itemize}

Puisqu'une espace inter-lettre est insérée entre chaque caractère, nous allons prendre le parti de laisser à l'utilisateur la possibilité de choisir cette espace. Pour ce faire, nous allons écrire une macro §\breaktt qui va insérer un \emph{faible} ressort fixe entre chaque lettre (rappelons-nous qu'un ressort est susceptible d'être un point de coupure). La syntaxe de cette macro sera :

\centrecode|\breaktt[<dimension inter-lettre>][<largeur de composition>]{<texte>}|

\noindent Les deux arguments optionnels permettent de spécifier la dimension de l'espace inter-lettre et la largeur de composition. La dimension inter-lettre sera insérée \emph{après} chaque caractère, sauf le dernier de chaque ligne.

Si l'on veut que la largeur du texte soit égale à la largeur de composition passée en argument, la dimension inter-lettre doit être choisie avec soin. Elle dépend mathématiquement de la largeur des caractères et de la largeur de composition. Si l'utilisateur demande une dimension inter-lettre sans précaution, la largeur d'une ligne sera inférieure à la largeur de composition. Voici le schéma représentant la situation d'une ligne :

\begin{centrage}
\begin{tikzpicture}
\def\wdchar{0.75}\def\wdskip{.15}\def\htchar{1}
\def\extrachar{0.95}\def\numchar{10}
\def\printnextchar{%
	\let\currentabs\nextabs
	\pgfmathparse{\currentabs+\wdchar+\wdskip}\let\nextabs\pgfmathresult
	\filldraw[draw=black,fill=gray!66,line width=.5pt](\currentabs,0)rectangle(\currentabs+\wdskip,\htchar);
	\draw[line width=.5pt](\currentabs+\wdskip,0) rectangle(\nextabs,\htchar);
}
\draw[line width=1pt](0,-\htchar/2)--(0,\htchar*1.5);
\node[inner sep=0pt,outer sep=0pt,minimum size=0pt](debut)at(0,\htchar*1.4){};
\draw[line width=.5pt](0,0) rectangle ++(\wdchar,\htchar);
\let\nextabs\wdchar
\for\ii=1 to \numchar\do{\printnextchar}%
\draw[line width=1pt](\nextabs+\wdchar*\extrachar,-\htchar/2)--(\nextabs+\wdchar*\extrachar,\htchar*1.5);
\node[inner sep=0pt,outer sep=0pt,minimum size=0pt](fin)at(\nextabs+\wdchar*\extrachar,\htchar*1.4){};
\draw[stealth-stealth](debut)--(fin) node[midway,above,inner sep=0pt,outer sep=2pt]{\footnotesize Largeur de composition};
\end{tikzpicture}
\end{centrage}

Les boites englobantes des caractères sont représentées par des rectangles vides et les espaces inter-lettres demandées par l'utilisateur par des zones grisées.

Pour éviter que l'utilisateur ne calcule lui-même la valeur du premier argument, il devient évident qu'il doit être automatiquement ajusté de telle sorte que l'espace disponible à droite du dernier caractère soit également réparti dans chaque zone grisée. Par conséquent, la \verb|<dimension inter-lettre>| donnée en argument \no1 ne sera pas \emph{exactement} celle insérée entre chaque caractère, mais devra être légèrement augmentée.
\grandsaut

Cherchons maintenant à formaliser le tout avec les notations suivantes :

\begin{itemize}
	\item $L$ est la largeur de composition (argument optionnel \verb|#2|);
	\item $l$ est la largeur d'un caractère;
	\item $\Delta$ la dimension inter-lettre demandée (argument optionnel \verb|#1|).
\end{itemize}

Compte tenu du fait que le dernier caractère de la ligne n'est pas suivi d'une espace inter-lettre, nous allons dans un premier temps ignorer ce caractère et soustraire $l$ à la largeur de composition $L$ pour obtenir la place disponible pour les paires \verb|<caractère>| $+$ \verb|<dimension inter-lettre>|. Pour calculer le nombre de ces paires (de largeur $l+\Delta$), il faut prendre la partie entière du quotient

\[
\dfrac{L-l}{l+\Delta}
\]

En ajoutant le dernier caractère de la ligne que nous avions ignoré, nous obtenons le nombre maximal de caractères $n$ qu'il est possible de loger sur une ligne. Cela donne (E représente l'opérateur «partie entière») :

\[n=\text{E}\left(\dfrac{L-l}{l+\Delta}\right)+1\]

Il est immédiat que le nombre de dimensions inter-lettre est égal à $n-1$ et donc, pour justifier le texte, il faut répartir également l'espace non occupé par les caractères entre chaque caractère. Par conséquent, il faut insérer après chaque caractère, non pas l'espace inter-lettre $\Delta$, mais

\[\Delta'=\dfrac{L-nl}{n-1}\]

Voici ce que devient le schéma précédent :

\begin{centrage}
\begin{tikzpicture}
\def\wdchar{0.75}\def\wdskip{.15}\def\htchar{1}
\def\extrachar{.95}\def\numchar{10}
\def\printnextchar{%
	\pgfmathparse{\nextabs+\wdchar*\extrachar/10}\let\currentabs\pgfmathresult
	\pgfmathparse{\currentabs+\wdchar+\wdskip}\let\nextabs\pgfmathresult
	\filldraw[draw=black,fill=gray!66,line width=.5pt](\currentabs,0)rectangle(\currentabs+\wdskip,\htchar);
	\draw[line width=.5pt](\currentabs+\wdskip,0) rectangle(\nextabs,\htchar);
}
\draw[line width=1pt](0,-\htchar/2)--(0,\htchar*1.5);
\node[inner sep=0pt,outer sep=0pt,minimum size=0pt](debut)at(0,\htchar*1.4){};
\draw[line width=.5pt](0,0) rectangle ++(\wdchar,\htchar);
\let\nextabs\wdchar
\for\ii=1 to \numchar\do{\printnextchar}%
\draw[line width=1pt](\nextabs,-\htchar/2)--(\nextabs,\htchar*1.5);
\node[inner sep=0pt,outer sep=0pt,minimum size=0pt](fin)at(\nextabs,\htchar*1.4){};
\draw[stealth-stealth](debut)--(fin) node[midway,above,inner sep=0pt,outer sep=2pt]{\footnotesize Largeur de composition};
\end{tikzpicture}
\end{centrage}

\noindent L'espace grisé $\Delta$ doit être augmenté d'une petite quantité pour que la justification se fasse. Comme l'argument optionnel \verb|#1| n'est \emph{pas} exactement l'espace qui sera inséré entre chaque caractère, il doit être compris comme une dimension \emph{minimale} susceptible d'être un peu allongée pour justifier le texte à la dimension spécifiée.
\grandsaut

Entrons dans le vif du sujet et définissons les variables principales dont nous avons besoin :

\begin{itemize}
	\item un compteur \verb|\brktt@cnt| qui va compter, pour chaque ligne, combien de caractères ont déjà été placés;
	\item une macro \verb|\maxchar@num| qui contiendra $n$, le nombre de caractères par ligne;
	\item un registre de dimension inter-lettre \verb|\brktt@interletter| pour recevoir $\Delta'$;
	\item une macro \verb|\tt@remaintext| dont le texte de remplacement contient ce qu'il reste du texte à composer;
	\item une liste de \idx{ligature}s \verb|\liglist| contenant des suites de caractères susceptibles de former un caractère \emph{unique}, soit par \idx{ligature} (par exemple «\verb|<<|», «\verb|--|», etc.) soit parce que ces caractères sont codés sur plusieurs \idx{octet}s en \utf avec un moteur 8 bits\idx*{moteur!8 bits}.
\end{itemize}
\grandsaut

Le processus va se décomposer en deux. Tout d'abord, la macro §\breaktt va ouvrir un groupe semi-simple qui sera fermé à la fin du processus et passera en mode vertical. Elle va également procéder aux initialisations et aux calculs préalables (nombre de caractères par ligne $n$, espace inter-lettre $\Delta'$) ainsi qu'au passage en \idx{fonte} à chasse fixe. Cette macro chapeau appellera la macro récursive \verb|\breaktt@i| qui imprimera, en mode vertical et dans une \idx\hbox une ligne entière. Ensuite, si le texte restant est vide, cela signe la fin du processus. Dans le cas contraire, la \idx\hbox doit être fermée et une nouvelle doit être ouverte pour accueillir la ligne suivante qui sera imprimée par l'appel récursif \verb|\breaktt@i|.

Le mécanisme de fermeture/ouverture de \idx\hbox sera effectué par la macro \verb|\restart@hbox| dont l'argument est le texte restant à composer. Après avoir fermé la \idx\hbox précédente avec \idx\egroup et avoir ouvert une nouvelle \idx\hbox avec \idx\bgroup, cette macro initialise le compteur de caractères \verb|\brktt@cnt| à 0 et, à l'aide de §\removefirstspaces, purge son argument des éventuels espaces qui se trouvent en première position. Le résultat de cette opération est stocké dans \verb|\tt@remaintext| : ceci évite que la prochaine ligne ne commence par une espace.

Le n\oe ud du processus sera une macro auxiliaire \verb|\print@nchar{<n>}| qui est chargée d'afficher \verb|<n>| caractères pris dans \verb|\tt@remaintext|. Une boucle de type §\for sera mise en \oe uvre à cet effet. Au cours de la boucle :

\begin{itemize}
	\item si \verb|\tt@remaintext| est vide, une sortie prématurée de boucle doit être faite et la macro doit rendre la main;
	\item si \verb|\tt@remaintext| commence par un des motifs figurant dans la liste des \idx{ligature}s, le caractère courant à afficher sera pris égal à ce motif et dans le cas contraire au premier caractère de \verb|\tt@remaintext|;
	\item l'espace inter-lettre ne doit pas être inséré après le dernier caractère de la ligne. Autrement dit, il ne faut insérer cette espace que si $\verb|\brktt@cnt|<\verb|\maxchar@num|$;
	\item si $\verb|\brktt@cnt|>\verb|\maxchar@num|$,  une sortie prématurée de boucle doit être faite et la macro doit rendre la main.
\end{itemize}

Le booléen \verb|\ifline@start|, inutile ici, nous servira dans d'autres versions de la macro §\breaktt.

\showcode|\catcode`\@11
\newcount\brktt@cnt¤\idx*\newcount¤
\newdimen\brktt@interletter¤\idx*\newdimen¤
\newif\ifline@start% booléen vrai lorsqu'aucun caractère n'est encore affiché¤\idx*\newif¤
\newif\if@indivifound% booléen qui sera vrai si un motif spécial est rencontré¤\idx*\newif¤

\def\insert@blankchar{%¤§*\ifstarred¤
	\ifstarred\insert@blankchar@ii\insert@blankchar@i
}

\def\insert@blankchar@i#1{% insère une espace de largeur #1 caractères complets
	\ifnum\numexpr#1\relax>0
		\kern\numexpr#1\relax\dimexpr\ttchar@width+\brktt@interletter\relax
	\fi
}

\def\insert@blankchar@ii#1{% insère #1-1 caractères complets + 1 largeur de caractère
	\ifnum\numexpr#1\relax>0
		\insert@blankchar@i{#1-1}\kern\ttchar@width¤\idx*\kern¤
	\fi
}

\def\restart@hbox#1{%
	\egroup% feerme la \hbox précédente
	\hbox\bgroup% ouvre la suivante¤\idx*\hbox\idx*\bgroup §*\expsecond¤
	\expsecond{\def\tt@remaintext}
		{\romannumeral\removefirstspaces@i{#1}}% initialiser le code à composer¤\idx*\romannumeral§*\removefirstspaces¤
	\let\previous@char\space% initialise le caractère précédent¤\idx*\space¤
	\line@starttrue% aucun caractère n'a encore été imprimé
	\brktt@cnt=0\relax% remettre le compteur à 0
}

\newmacro\breaktt[0.3em][\hsize]1{%¤§*\breaktt§*\newmacro¤
% arg optionnel #1 et #2 = ressorts inter-lettre et dimension horizontale texte
% #3 = texte à espacer
	\begingroup% ouvrir un groupe et le fermer à la toute fin
	\par% commencer un nouveau paragraphe -> passage en mode vertical¤\idx*{mode!vertical}¤
	\parindent=0pt% empêche l'indentation¤\idx*\parindent¤
	\tt% passer en fonte à chasse fixe¤\idx*\tt¤
	\setbox0 = \hbox{M}% la boite 0 contient un caractère¤\idx*\setbox\idx*\hbox¤
	\edef\ttchar@width{\the\wd0 }% largeur de chaque caractère en fonte \tt¤\idx*\the\idx*\wd¤
	\edef\text@width{\the\dimexpr#2\relax}% largeur de composition¤\idx*\dimexpr¤
	% les 2 lignes suivantes rendent le compteur égal à E((L-l)/(l+Delta))
	\brktt@cnt=\numexpr\dimexpr#2-\wd0 \relax\relax% largeur diminuée du 1er caractère¤\idx*\numexpr\idx*\wd¤
	\divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax¤\idx*\divide\idx*\wd¤
	% le nombre de caractère par ligne est égal à 1 de plus :
	\edef\maxchar@num{\number\numexpr\brktt@cnt+1\relax}%
	% calcul de la dimension inter-lettre
	\brktt@interletter=\dimexpr(\text@width-\ttchar@width*\maxchar@num)/\brktt@cnt\relax
	% stocke le texte après avoir enlevé les éventuels espaces extremes :
	\expsecond{\expsecond{\def\tt@remaintext}}{\removetrailspaces{#3}}%¤§*\expsecond§*\removetrailspaces¤
	\unless\ifx\tt@remaintext\empty% si le texte à composer n'est pas vide¤\tidx*{unless}\idx*\empty¤
		\hbox\bgroup% démarrer la boite horizontale contenant la première ligne¤\idx*\hbox\idx*\bgroup¤
		\insert@blankchar\ttindent% insérer une espace d'indentation
		\brktt@cnt=\ttindent\relax% tenir compte du nombre de caractères indentés
		\line@starttrue% il s'agit du début d'une ligne
		\expandafter\breaktt@i% aller à la macro récursive
	\fi
}

\def\breaktt@i{%
	\print@nchar\maxchar@num% afficher \maxchar@num caractères¤\defline\aaa¤
	\ifx\tt@remaintext\empty% si texte restant est vide¤\idx*\empty¤
		\egroup% fermer la hbox¤\idx*\egroup¤
		\par% aller à la ligne
		\endgroup% fermer le groupe ouvert au début
	\else
		\unless\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne est remplie¤\tidx*{unless}¤
			\exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en ré-ouvre une¤§*\exparg¤
		\fi
		\expandafter\breaktt@i% enfin, continuer le processus
 	\fi
}

\def\print@nchar#1{% affiche #1 caractères pris dans \tt@remaintext
	\for\xxx= 1 to #1 \do 1{%¤§*\for¤
		\ifx\tt@remaintext\empty% si le code restant à composer est vide¤\idx*\empty¤
			\exitfor\xxx%sortir de la boucle prématurément¤§*\exitfor¤
		\else
			\@indivifoundfalse% sinon, a priori, les motifs de ligature ne sont pas trouvés
			% pour chaque \indivi@tmp dans la liste de ligatures
			\expsecond{\doforeach\indivi@tmp\in}{\liglist}%¤§*\expsecond§*\doforeach¤
				{% si le code commence par la ligature courante¤\idx{ligature}¤
				\exptwoargs\ifstartwith\tt@remaintext\indivi@tmp¤§*\exptwoargs§*\ifstartwith¤
					{\let\previous@char\indivi@tmp% prendre le motif pour caractère courant,
					\expsecond{\rightofsc\tt@remaintext}{\indivi@tmp}% l'enlever du texte restant¤§*\expsecond¤
					\@indivifoundtrue% marquer qu'un motif a été trouvé
					\doforeachexit% et sortir prématurément de la boucle¤§*\doforeachexit¤
					}%
					{}% si le code ne commence pas le motif courant -> ne rien faire
				}%
			\unless\if@indivifound% si aucun motif trouvé,¤\tidx*{unless}¤
				\grab@first\tt@remaintext\previous@char%  lire le premier caractère
			\fi
			\advance\brktt@cnt by 1 % incrémenter le compteur de caractères¤\idx*\advance¤
			\hbox to\ttchar@width{\hss\previous@char\hss}% afficher le caractère lu¤\idx*\hbox\idx*\hss¤
			\line@startfalse% nous ne sommes plus au début d'une ligne
			\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas encore remplie
				\kern\brktt@interletter% insérer le ressort inter-lettre¤\idx*\kern¤
			\else
				\exitfor\xxx% sinon, sortir de la boucle prématurément¤§*\exitfor¤
			\fi
		\fi
	}%
}
\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature¤\idx{ligature}¤
                   % ajouter à, é, etc si codage UTF8 + moteur 8 bits
\def\ttindent{3}% valeur de l'indentation'
\vrule\vbox{\breaktt[4pt][.7\hsize]{%¤\idx*\vrule\idx*\vbox\idx*\hsize§*\breaktt¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous des autres d'une ligne à l'autre. Plus aucun
débordement n'a lieu, car une espace correctement calculée est insérée entre
chaque caractère. Les mots, en revanche, sont toujours coupés <<sauvagement>>.%
}%
}\vrule\smallbreak¤\idx*\vrule¤

\vrule\vbox{\breaktt[1pt][6cm]{%¤\idx*\vrule\idx*\vbox\idx*\hsize§*\breaktt¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous des autres d'une ligne à l'autre. Plus aucun
débordement n'a lieu, car une espace correctement calculée est insérée entre
chaque caractère. Les mots, en revanche, sont toujours coupés <<sauvagement>>.%
}%
}\vrule¤\idx*\vrule¤|

\subsection{Aligner et ne pas couper}
Pour éviter que les mots ne soient coupés n'importe comment, la solution radicale consiste à interdire toute coupure. L'inévitable conséquence est que la contrainte \no2 de la page~\pageref{contraintes.tt} (composition justifiée) sera impossible à satisfaire.

Dans l'algorithme précédent, la macro \verb|\print@nchar| de la ligne \no\aaa{} effectuait la composition aveugle de \verb|\maxchar@num| caractères à chaque ligne. Cette manière de faire est trop grossière et doit être affinée : au fur et à mesure de l'avancement, nous allons calculer la largeur du prochain mot \verb|\next@len| par l'intermédiaire de la macro \verb|\len@tonextcut|. Il faudra ensuite tester si ce mot loge en entier dans ce qu'il reste de la ligne en cours de composition. Dans l'affirmative, nous composerons ce mot avec la macro \verb|\print@nchar| et sinon, il faudra finir la ligne en cours pour en commencer une nouvelle.

Le raffinement supplémentaire va être de tenir compte des tirets «\verb|-|» éventuellement contenus dans les mots et rendre ces tirets comme possibles caractères de \idx{fin de ligne}. Nous allons donc considérer qu'un mot est ce qui se trouve avant le plus proche des caractères «\verb*| |» ou «\verb|-|». Il faudra tenir compte du fait que le tiret \emph{ne disparait pas} en \idx{fin de ligne} contrairement à l'espace. Pour ce faire, une macro \verb|\extra@char| contenant 0 ou 1 nous permettra de savoir par la suite si, en plus du mot courant, il faut loger un caractère de plus (le tiret) sur la ligne ou pas.

Nous allons baptiser §\breakttA cette variante qui compose du texte sans couper les mots. Les macros \verb|\insert@blankchar|, \verb|\restart@hbox| et \verb|\print@nchar| de la précédente variante §\breaktt seront réutilisées telles quelles. Elles ne sont donc pas réécrites dans le code ci-dessous. La macro \verb|\breakttA@i| ne fait plus appel à une boucle §\for, mais contient des appels récursifs jusqu'à ce que \verb|\tt@remaintext| ne contienne plus de texte à composer.

\showcode|\catcode`\@11
\newcount\brktt@cnt¤\idx*\newcount¤
\newdimen\brktt@interletter¤\idx*\newdimen¤
\newif\ifline@start% booléen vrai lorsqu'aucun caractère n'est encore affiché¤\idx*\newif¤
\newif\if@indivifound% booléen qui sera vrai si un motif spécial est rencontré¤\idx*\newif¤

\newmacro\breakttA[0.3em][\hsize]1{%¤§*\breakttA§*\newmacro¤
% arg optionnel #1 et #2 = ressorts inter-lettre et dimension horizontale texte
% #3 = texte à espacer
	\begingroup% ouvrir un groupe et le fermer à la toute fin
	\par% commencer un nouveau paragraphe -> passage en mode vertical¤\idx*{mode!vertical}¤
	\parindent=0pt% empêche l'indentation¤\idx*\parindent¤
	\tt% passer en fonte à chasse fixe¤\idx*\tt¤
	\setbox0 = \hbox{M}% la boite 0 contient un caractère¤\idx*\setbox\idx*\hbox¤
	\edef\ttchar@width{\the\wd0 }% largeur de chaque caractère en fonte \tt¤\idx*\the\idx*\wd¤
	\edef\text@width{\the\dimexpr#2\relax}% largeur de composition¤\idx*\dimexpr¤
	% les 2 lignes suivantes rendent le compteur égal à E((L-l)/(l+Delta))
	\brktt@cnt=\numexpr\dimexpr#2-\wd0 \relax\relax% largeur diminuée du 1er caractère¤\idx*\numexpr¤
	\divide\brktt@cnt by \numexpr\dimexpr\wd0 + #1 \relax\relax¤\idx*\divide\idx*\wd¤
	% le nombre de caractères par ligne est égal à 1 de plus :
	\edef\maxchar@num{\number\numexpr\brktt@cnt+1\relax}%
	% calcul de la dimension inter-lettre
	\brktt@interletter=\dimexpr(\text@width-\ttchar@width*\maxchar@num)/\brktt@cnt\relax¤\idx*\dimexpr¤
	% stocke le texte après avoir enlevé les éventuels espaces extremes :
	\expsecond{\expsecond{\def\tt@remaintext}}{\removetrailspaces{#3}}%¤§*\expsecond§*\removetrailspaces¤
	\unless\ifx\tt@remaintext\empty% si le texte à composer n'est pas vide¤\tidx*{unless}\idx*\empty¤
		\hbox\bgroup% démarrer la boite horizontale contenant la première ligne¤\idx*\hbox\idx*\bgroup¤
		\insert@blankchar\ttindent% insérer une espace d'indentation
		\brktt@cnt=\ttindent\relax% tenir compte du nombre de caractères indentés
		\line@starttrue% il s'agit du début d'une ligne
		\expandafter\breakttA@i% aller à la macro récursive
	\fi
}

\def\breakttA@i{%
	\edef\remaining@chars{% calculer le nombre de caractères restant à placer sur la ligne
		\numexpr\maxchar@num-\brktt@cnt\relax}%¤\idx*\numexpr¤
	\len@tonextword% \next@len contient le nombre de caractères du prochain mot
	% si le mot + l'eventuel "-" qui le suit ne peut pas loger sur la ligne en cours
	\ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax¤\defline\aaa¤
		\ifline@start% et si c'est le début d'une ligne
			% avertir l'utilisateur
			\message{Largeur de composition trop faible pour
				\unexpanded\expandafter{\next@word}^^J}%¤\idx*\message\idx*\unexpanded\verbidx[ (fin de ligne)]{^^J}¤
			% et composer tout de même "à la sauvage" jusqu'à la fin de la ligne
			\exparg\print@nchar{\number\numexpr\maxchar@num-\brktt@cnt}%¤§*\exparg\idx*\numexpr¤
		\else% si la ligne en cours n'est pas au début
			\insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne d'espaces
		\fi
		\exparg\restart@hbox{\tt@remaintext}% commencer une nouvelle ligne¤§*\exparg¤
		\expandafter\breakttA@i% et poursuivre le processus
	% s'il y a assez de place pour accueillir ce qui est avant la prochaine coupure
	\else
		\print@nchar\next@len% afficher le mot¤\defline\bbb¤
		\ifx\tt@remaintext\empty% si texte restant est vide¤\idx*\empty¤
			\insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
			\egroup% fermer la hbox en cours¤\idx*\egroup¤
			\par% aller à la ligne
			\endgroup% fermer le groupe ouvert au début. Fin du processus
		\else% si le texte restant n'est pas vide
			\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas remplie¤\defline\ccc¤
					\print@nchar{1}% afficher le caractère qui suit le mot (" " ou "-")¤\defline\ddd¤
			\else% si la ligne est remplie
				\exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en ré-ouvre une¤§*\exparg¤
			\fi
			\expandafter\expandafter\expandafter\breakttA@i% enfin, continuer le processus
		\fi
	\fi
}

\def\leftofsc#1#2{% dans la macro #1, garde ce qui est à gauche de #2
	\def\leftofsc@i##1#2##2\@nil{\def#1{##1}}%
	\expandafter\leftofsc@i#1#2\@nil
}

\def\len@tonextword{% stocke dans \next@len le nombre de caractères avant
                    % le prochain point de coupure dans \tt@remaintext
	\let\next@word\tt@remaintext% copie \tt@remaintext dans la macro temporaire \next@word
	\leftofsc\next@word{ }% ne prend que ce qui est avant le prochain espace¤§*\leftofsc¤
	\exparg\ifin\next@word{-}% si le mot contient un tiret¤§*\exparg§*\ifin¤
		{\leftofsc\next@word{-}% prendre ce qui est à gauche de ce tiret¤§*\leftofsc¤
		\def\extra@char{1}% il y a un caractère de plus à loger après le mot
		}% sinon, le caractère après le mot est un espace
		{\def\extra@char{0}% qu'il ne faut pas compter
		}%
	\setbox0=\hbox{\next@word}% enfermer le mot dans une boite¤\idx*\setbox\idx*\hbox¤
	% et en calculer le nombre de caractères = dim(boite)/dim(caractère)
	\edef\next@len{\number\numexpr\dimexpr\wd0 \relax/\dimexpr\ttchar@width\relax\relax}%¤\idx*\wd¤
}
\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature (mettre à, é, etc si codage UTF8)¤\idx{ligature}¤
\def\ttindent{3}

\vrule\vbox{\breakttA[3pt][8cm]{%¤§*\breakttA¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous d'une ligne à l'autre. Plus aucun débordement
n'a lieu, car une espace correctement calculée est insérée entre chaque
caractère. Dorénavant, les mots ne sont plus coupés <<~sauvagement~>>.
}}\vrule\medbreak¤\idx*\medbreak\idx*\vrule¤

\leavevmode\vrule\vbox{\breakttA[1pt][5cm]{%¤\idx*\leavevmode§*\breakttA¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous d'une ligne à l'autre. Plus aucun débordement
n'a lieu, car une espace correctement calculée est insérée entre chaque
caractère. Dorénavant, les mots ne sont plus coupés <<~sauvagement~>>.
}}\vrule\qquad\def\ttindent{0}%
\vrule\vbox{\breakttA[0.6pt][2cm]{mot-composé mot-clé passe-droit au-dessus
là-bas remonte-pente vingt-huit Notre-Dame-de-Lourdes Mont-Blanc
Saint-Jean-de-Luz}}\vrule¤§*\breakttA\idx*\vrule¤|

\subsection{Aligner et couper}
Entrons maintenant dans la phase la plus difficile\ldots{} Nous allons essayer de composer du texte en fonte à chasse fixe tout en alignant les caractères les uns au-dessous des autres et en permettant que les coupures de mots se fassent.

Voici dans les grandes lignes la démarche que nous allons suivre lorsque le prochain mot ne loge pas sur l'espace restant de la ligne en cours :

\begin{enumerate}
	\item pour le prochain mot du texte à composer (un « mot » étant ce qui se trouve avant le plus proche espace ou tiret), nous allons trouver toutes les coupures possibles;
	\item nous allons mesurer les longueurs des syllabes ainsi obtenues et cumuler leurs longueurs de façon à construire la liste des nombres croissants exprimant les longueurs (en caractères) jusqu'aux coupures possibles du mot;
	\item enfin, nous parcourons cette liste et effectuerons, si c'est possible, la coupure la plus longue possible tout en ne dépassant pas le nombre de caractères qu'il reste à composer sur la ligne en cours. Ceci fait, il nous restera à enfermer la ligne en cours dans une \idx\hbox et en commencer une nouvelle.
\end{enumerate}

Comme plusieurs difficultés se dressent devant nous, nous allons procéder pas à pas.

\subsubsection{Provoquer toutes les coupures}\label{provoquer.toutes.les.coupures}
Tout d'abord, comment forcer \TeX{} à effectuer toutes les coupures possibles pour un texte donné ? Pour l'obliger à procéder de la sorte, nous allons composer ce texte dans une boite verticale de largeur \emph{nulle}. Bien sûr, des débordements auront lieu, mais nous neutraliserons leur signalement en réglant \idx\hfuzz à \idx\maxdimen.

Avant de commencer à composer du texte en largeur nulle, certains réglages de composition doivent être faits. Intéressons-nous à la façon dont \TeX{} fabrique un paragraphe\idx*{paragraphe!composition} et comment nous pouvons l'influencer. Il faut savoir que \emph{plusieurs} passes peuvent être faites par \TeX{} pour composer un paragraphe\footnote{Pour en savoir plus, lire le \TeX book pages~112--113.}. La première est tentée si l'entier \idx\pretolerance est positif et a lieu sans faire de coupures de mots. Ceci fait, si aucune ligne du paragraphe obtenu n'a de médiocrité\footnote{Lire le \TeX book page 144 notamment pour comprendre comment est calculée la médiocrité d'une ligne.} supérieure à l'entier \idx\pretolerance, le paragraphe ainsi obtenu sera retenu. Dans le cas contraire, une seconde passe, où les coupures de mots sont permises, est effectuée lors de laquelle, si c'est possible, \TeX{} s'efforce de fabriquer des lignes de telle sorte qu'aucune n'ait de médiocrité supérieure à l'entier \idx\tolerance.

Comme nous cherchons à provoquer les coupures de mots, la première passe ne nous intéresse pas et nous règlerons donc \idx\pretolerance à $-1$. Par ailleurs, nous  fixerons \idx\tolerance à $10000$ de telle sorte que toutes les lignes construites à la deuxième passe soient acceptables\footnote{Toute valeur supérieure à $10000$ est comprise comme étant égale à $10000$.} aux yeux de \TeX.

Ensuite, il nous faut modifier localement les réglages de composition en vue du but que nous nous sommes fixé. Comme la boite verticale de longueur nulle que nous obtiendrons a vocation à être coupée en lignes avec \idx\vsplit, nous devons nous assurer qu'aucune \idx{pénalité} additionnelle entre les lignes n'interdit cette coupure. Voici donc les réglages à effectuer :

\begin{itemize}
	\item l'entier \idx\hyphenpenalty, qui caractérise la \idx{pénalité} d'une coupure de mots sera pris égal à $-10000$ et donc les coupures, extrêmement favorisées par cette pénalité négative, seront toujours effectuées. Par ailleurs, \idx\exhyphenpenalty est la pénalité d'une coupure sur un caractère explicite (le tiret). Notre algorithme ne donnera jamais à composer un mot contenant un tiret puisqu'un «mot» s'étend jusqu'au prochain espace ou tiret. Par conséquent, \idx\exhyphenpenalty, rendu égal à 0, ne jouera aucun rôle.
	\item l'entier \idx\clubpenalty est ajouté à la pénalité de coupure de ligne pour la première ligne du paragraphe. Nous prendrons $0$ comme valeur de cet entier. L'entier \idx\widowpenalty agit de même pour la dernière ligne : il sera réglé à~0;
	\item l'entier \idx\interlinepenalty, ajouté à la \idx{pénalité} d'une coupure de ligne, sera pris égal à $0$;
	\item les entiers \idx\lefthyphenmin et \idx\righthyphenmin, qui caractérisent la longueur minimale du fragment laissé au début ou à la fin d'un mot coupé, seront réglés à leurs valeurs par défaut, soit \number\lefthyphenmin{} et \number\righthyphenmin{};
	\item nous réinitialiserons \idx\rightskip et \idx\leftskip à \verb|0pt| au cas où ces dimensions ne seraient pas nulles au moment de la composition. Le ressort \idx\parfillskip sera réinitialisé à «\verb|0pt plus 1fil|» qui est sa valeur par défaut. Nous viderons également \idx\everypar qui contient la liste de tokens exécutée au début de chaque paragraphe;
	\item l'entier \idx\hyphenchar sera sauvegardé puis pris égal à \verb|`\-| et enfin restauré en fin de composition;
	\item l'indentation sera désactivée avec \idx\noindent tout en provoquant le passage en mode horizontal\idx*{mode!horizontal};
	\item un ressort de longueur nulle sera inséré avant le texte à composer, car une coupure ne peut intervenir sur un mot si ce mot commence le paragraphe. Ce ressort tiendra lieu de remplissage factice et autorisera la coupure du premier mot;
	\item la largeur de composition \idx\hsize sera rendue égale à \verb|0pt|.
\end{itemize}

Forts de tous ces réglages, nous allons bâtir la macro §\zerocompose :

\centrecode-\zerocompose[<code>]{<registre de boite>}{<texte>}-

\noindent où \verb|<code>| est un code optionnel qui sera exécuté avant que la composition ne commence, \verb|<registre de boite>| est le numéro du registre de la boite verticale \idx\vbox recevant le résultat de la composition du \verb|<texte>|.

\showcode/\newmacro\zerocompose[]2{%¤§*\zerocompose§*\newmacro¤
% #1=code à exécuter avant la composition
% #2=registre de boite recevant le résultat
% #3= texte à composer en largeur 0pt
	\setbox#2=\vbox{%¤\idx*\setbox\idx*\vbox¤
		#1% code a exécuter (changement de fonte par exemple)
		\hfuzz=\maxdimen% annule les avertissements pour débordement horizontaux¤\idx*\hfuzz\idx*\maxdimen\idx*{message d'avertissement}¤
		\hbadness=10000 % annule les avertissements pour mauvaise boite horizontale¤\idx*\hbadness\idx*{message d'avertissement}¤
		\pretolerance=-1 % désactive la première passe (celle sans coupures)¤\idx*\pretolerance¤
		\tolerance=10000 % passe avec coupures acceptée¤\idx*\tolerance¤
		\hyphenpenalty=-10000 % favorise fortement les copures de mots¤\idx*\hyphenpenalty¤
		\lefthyphenmin=2 \righthyphenmin=3 % longueur mini des fragments de début et fin¤\idx*\lefthyphenmin\idx*\righthyphenmin¤
		\clubpenalty=0 % pas de pénalité supplémentaire après la première ligne¤\idx*\clubpenalty\idx{pénalité}¤
		\interlinepenalty=0 % pas de pénalité inter-ligne¤\idx*\interlinepenalty\idx{pénalité}¤
		\widowpenalty=0 % pas de pénalité supplémentaire avant la dernière ligne¤\idx*\widowpenalty\idx{pénalité}¤
		\exhyphenpenalty=0 % ne pas pénaliser une coupure explicite¤\idx*\exhyphenpenalty¤
		\leftskip=0pt \rightskip=0pt % désactive les éventuels ressorts latéraux¤\idx*\leftskip\idx*\rightskip¤
		\everypar={}% désactive l'éventuel \everypar¤\idx*\everypar¤
		\parfillskip=0pt plus1fil % règle le \parfillskip par défaut¤\idx*\parfillskip¤
		\hsize=0pt % largeur de composition = 0pt¤\idx*\hsize¤
		\edef\restorehyphenchar{\hyphenchar\font=\number\hyphenchar\font}%
		\hyphenchar\font=`\- % impose "-" comme caractère de coupure
		\noindent % pas d'indentation + passage en mode horizontal¤\idx*\noindent\idx*{mode!horizontal}¤
		\hskip0pt \relax% premier noeud horizontal pour permettre la coupure de la suite¤\idx*\hskip¤
		#3\par% compose #3
		\restorehyphenchar% restaure le caractère de coupure
		}%
}
\zerocompose{0}{Programmation}%¤\idx*\hyphenchar\idx*\font¤
\leavevmode\box0 ¤\idx*\leavevmode\idx*\box¤
\hskip 5cm ¤\idx*\hskip¤
\zerocompose{0}{Composer en largeur nulle}%¤§*\zerocompose\idx*\hyphenchar\idx*\font¤
\box0 ¤\idx*\box¤/

Malgré les apparences, les boites \no0 affichées dans l'exemple ci-dessus ont bel et bien une largeur \emph{nulle}. C'est \verb|\hskip 5cm| qui évite qu'elles ne se chevauchent.

Nous allons appliquer cette méthode à des mots seuls et utiliser \idx\vsplit pour vider peu à peu (par le haut) la boite verticale résultante afin d'obtenir à chaque itération une boite horizontale contenant une ligne de la boite initiale. Le problème est que la boite récupérée sera de largeur nulle puisque la \idx\vbox initiale avait cette largeur. Dès lors, il sera impossible de la mesurer pour trouver le nombre de caractères qui la composent !

Nous allons donc faire appel à une primitive, non encore vue jusqu'alors qui va nous permettre de redonner à la boite contenant la première ligne sa largeur naturelle.

\subsubsection{La primitive \texttt{\char`\\lastbox}}\idx*[|(]\lastbox

\begin{regle}
La primitive \verb|\lastbox| a un comportement très particulier :

\begin{itemize}
	\item non seulement elle contient la dernière boite composée dans la liste en cours, mais utiliser \verb|\lastbox| \emph{retire} cette boite de la liste dans laquelle elle était placée;
	\item si le dernier élément n'est pas une boite, \verb|\lastbox| est vide;
	\item si l'on souhaite accéder à la dernière boite composée, \verb|\lastbox| s'utilise seule. Il est incorrect de la faire précéder de \idx\box.
\end{itemize}

L'opération \verb|\lastbox| n'est pas permise dans le mode mathématique\idx*{mode!mathématique} ni dans le mode vertical\idx*{mode!vertical} \emph{principal} : elle ne peut donc pas servir à retirer une boite de la page courante en cours de composition. En revanche, elle peut très bien être utilisée dans le mode vertical interne\idx*{mode!vertical interne}.

La boite \verb|\lastbox| hérite de la nature --~horizontale ou verticale~-- de la dernière boite composée.

Si un registre de boite est vidé par \verb|\lastbox|, le registre ne devient pas vide, mais contient une boite vide (le test \tidx{ifvoid} est donc inadapté pour tester si un registre est vidé par \verb|\lastbox|).
\end{regle}

La façon habituelle de se servir de \verb|\lastbox| est de capturer la dernière boite pour l'assigner à un registre de boite normal que l'utilisateur peut ensuite manier à sa guise. On rencontre donc la syntaxe

\centrecode-\setbox<registre de boite>=\lastbox-

Par exemple, à l'intérieur d'un groupe et avec l'aide de la boite brouillon \no0, \verb|\lastbox| permet d'effacer la dernière boite composée :

\centrecode-{\setbox0 =\lastbox}-

On peut également s'en servir pour capturer la dernière ligne d'un paragraphe composé dans une boite verticale (dans ce cas, \verb|\lastbox| sera une boite horizontale, celle qui contient la dernière ligne) :

\showcode/\def\dummytext{Ceci est un texte sans aucun intérêt dont le seul but est de meubler
		la page de façon artificielle. }
\setbox0=\vtop{% définit la boite 0¤\idx*\setbox\idx*\vtop¤
	\hsize=8cm ¤\idx*\hsize¤
	\dummytext\dummytext
}

a) Boite pleine : \copy0 ¤\idx*\copy¤

b) \setbox0=\vtop{%¤\idx*\setbox\idx*\vtop¤
	\unvbox0 % boite précédemment composée¤\idx*\unvbox¤
	\global\setbox1=\lastbox% et capture la dernière ligne dans la boite 1¤\idx*\global\idx*\setbox¤
	}%
	Dernière ligne = |\hbox{\unhbox1 }|\par% redonne à box1 sa largeur naturelle¤\idx*\unhbox¤
	Boite restante = \box0 /

Cet exemple illustre comment \verb|\lastbox| permet de « couper » une boite verticale par le bas. La similarité devient évidente entre \verb|\lastbox| qui coupe par le bas et \idx\vsplit qui coupe par le haut. En répétant la man\oe uvre plusieurs fois, il deviendrait possible de vider peu à peu une boite verticale en enlevant à chaque itération la ligne du bas :

\showcode/\def\dummytext{Ceci est un texte sans aucun intérêt dont le seul but est de meubler
		la page de façon artificielle. }
\setbox0=\vtop{% définit la boite 0¤\idx*\setbox\idx*\vtop¤
	\hsize=8cm ¤\idx*\hsize¤
	\dummytext\dummytext
}

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}¤\idx*\setbox\idx*\vtop\idx*\global\idx*\unvbox¤
\setbox1=\hbox{\unhbox1 }¤\idx*\unhbox¤
1) |\box1|¤\idx*\box¤

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}
\setbox1=\hbox{\unhbox1 }¤\idx*\unhbox¤
2) |\box1|

\setbox0=\vtop{\unvbox0 \global\setbox1=\lastbox}¤\idx*\setbox\idx*\vtop\idx*\global\idx*\unvbox¤
\setbox1=\hbox{\unhbox1 }¤\idx*\unhbox¤
3) |\box1|¤\idx*\box¤/

Pourquoi \verb|\lastbox| échoue à capturer la dernière ligne dans les deux derniers cas ? C'est que \verb|\lastbox| est plus contraignante que \idx\vsplit et la réponse demande de connaitre un peu la façon dont est construit un paragraphe\idx*{paragraphe!composition} par \TeX{} : le ressort d'interligne, qui est inséré entre chaque boite horizontale contenant une ligne, est assorti d'une \idx{pénalité} qui le précède.

Pour s'en persuader, il est possible de faire remonter des entrailles de \TeX{} vers le \idx[!log]{fichier} \verb|log| les composants élémentaires des boites qu'il construit. Pour ce faire, plusieurs réglages sont à faire :

\begin{itemize}
	\item pour que les informations ne soient écrites que dans le \idx[!log]{fichier} \verb|log| (et non pas également sur le terminal), il faut que la primitive \idx\tracingonline soit strictement positive;
	\item l'entier \idx\showboxdepth spécifie le nombre de niveaux d'imbrication de boites qui doivent être montrés;
	\item l'entier \idx\showboxbreadth spécifie le nombre d'éléments montrés dans chaque niveau;
	\item la primitive \idx\showbox\label{showbox}, suivie d'un registre de boite donne l'ordre à \TeX{} d'examiner la boite contenue dans le registre et de délivrer les informations selon les réglages spécifiés.
\end{itemize}

\errcode|\setbox0=\vbox{\hsize=2.5cm Programmer en TeX est facile}%¤\idx*\setbox\idx*\vbox\idx*\hsize¤
\showboxbreadth=5 \showboxdepth=3 \tracingonline=1 ¤\idx*\showboxbreadth\idx*\showboxdepth\idx*\tracingonline¤
\showbox0 ¤\idx*\showbox¤|{> \string\box0=\par
\string\vbox(14.77199+0.092)x71.13188\par
.\string\hbox(5.27199+1.888)x71.13188, glue set - 1.0\par
..\string\hbox(0.0+0.0)x0.0\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 P\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 r\par
..\string\kern-0.06401\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 o\par
..etc.\par
.\string\penalty 300\par
.\string\glue(\string\baselineskip) 2.08801\par
.\string\hbox(5.52399+0.092)x71.13188, glue set 53.71591fil\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 f\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 a\par
..\string\discretionary\par
...\string\T1/LinuxLibertineT-TLF/m/n/8 -\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 c\par
..\string\T1/LinuxLibertineT-TLF/m/n/8 i\par
..etc.}

On constate que la \idx{pénalité} (ici de 300) est bien insérée \emph{avant} le ressort d'interligne (\idx\baselineskip). Notons par ailleurs que les «\verb|.\hbox|» représentent les boites horizontales contenant les lignes (le nombre de «\verb|.|» indique le niveau d'imbrication des boites, étant entendu qu'une absence de point indique la boite mère). Il faut également remarquer, juste après le «\verb|r|», que «\verb|\kern-0.06401|» règle le \idx{crénage} (kerning) entre les caractères «r» et «o» dans la fonte « LinuxLibertine-TLF » et montre donc que pour des raisons esthétiques, ces caractères sont légèrement rapprochés.
\grandsaut

Pour en revenir à \verb|\lastbox|, lorsqu'elle a capturé la dernière ligne, elle laisse en bas de la boite restante une pénalité et un ressort vertical. Par conséquent, la \verb|\lastbox| suivante, ne pouvant capturer une boite, sera vide. Pour que la méthode fonctionne, il faut supprimer \emph{dans cet ordre} le ressort avec \idx\unskip puis la \idx{pénalité} avec \idx\unpenalty avant d'extraire la prochaine \verb|\lastbox|. Construire une macro \verb|\reversebox| qui vide une boite verticale par le bas devient une simple routine, à condition de ne pas effectuer le test \tidx{ifvoid}, inadapté à un registre vidé par \verb|\lastbox|, mais les tests §\ifzerodimbox ou §\ifvoidorempty que nous avons programmés (voir page~\pageref{tester.boite.vide} et suivantes) :

\showcode/\newbox\tempbox¤\idx*\newbox¤
\def\reversebox#1{% affiche le contenu de la boite verticale #1
	\setbox#1=\vbox{%
		\unvbox#1% composer la boite #1¤\idx*\unvbox¤
		\unskip\unpenalty% retirer ce qui n'est pas capturable par \lastbox¤\idx*\unskip\idx*\unpenalty¤
		\global\setbox0=\lastbox% la boite 1 devient la dernière ligne¤\idx*\global\idx*\setbox¤
	}%
	|\hbox{\unhbox0 }|\par% afficher la boite 1 dans sa largeur d'origine¤\idx*\hbox\idx*\unhbox¤
	\ifvoidorempty{#1}% si le registre #1 contient une boite vide¤§*\ifvoidorempty¤
		\relax% ne rien faire
		{\reversebox{#1}}% sinon, rencommencer
}
\def\dummytext{Ceci est un texte sans aucun intérêt dont le seul but est de meubler
		la page de façon artificielle. }
\setbox\tempbox=\vbox{% définit la boite 0¤\idx*\setbox\idx*\vbox¤
	\hsize=8cm \dummytext\dummytext¤\idx*\hsize¤
}

\reversebox\tempbox/

Mettons tout ceci en application. La macro §\zerocompose va nous permettre, conjointement avec \verb|\lastbox| et \idx\vsplit, de récupérer une boite horizontale de largeur naturelle contenant la première ligne.

\showcode/% compose "Programmation" en largeur 0 dans la boite 0 :
\zerocompose{0}{Programmation}%¤§*\zerocompose\idx*\font¤
Boite initiale : \copy0 \par% compose la boite résultante¤\idx*\copy¤
\vfuzz=\maxdimen% annule les avertissements pour débordements¤\idx*\vfuzz\idx*\maxdimen\idx*{message d'avertissement}¤
\splittopskip=0pt % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip¤
\setbox1 =\vsplit0 to 0pt % coupe la boite 0 à 0pt¤\idx*\setbox\idx*\vsplit¤
{% dans un groupe (où la boite 0 sert de brouillon)
	\setbox0 =\vbox{% affecter à la boite brouillon¤\idx*\setbox\idx*\vbox¤
		\unvbox1 % la boite 1 composée dans sa largeur naturelle¤\idx*\unvbox¤
		\unskip\unpenalty% annule ce qui n'est pas une boite¤\idx*\unskip\idx*\unpenalty¤
		\global\setbox2 =\lastbox% affecte globalement la dernière (et unique) ligne¤\idx*\global¤
		                         % à la boite 1
	}%
}% ferme le groupe
\setbox2=\hbox{\unhbox2}% rend à la boite 2 sa largeur naturelle¤\idx*\hbox\idx*\unhbox¤
Première ligne = "\box2 "% compose la boite 2¤\idx*\box¤/\idx*[|)]\lastbox

\subsubsection{Mesurer toutes les coupures}
Le but est de construire une macro contenant les longueurs (en caractères) avant les possibles coupures du mot, en tenant compte du caractère de coupure. Par exemple, le mot « programmation » aura 3 coupures possibles auxquelles correspondent les longueurs suivantes :

\begin{centrage}
	\small
	\begin{tabular}{rc}\hline
		Caractères avant la coupure & Longueur\\\hline
		\verb|pro-|&4\\
		\verb|program-|&8\\
		\verb|programma-|&10\\\hline
	\end{tabular}
\end{centrage}

Nous allons donc construire une macro §*\hyphlengths

\centrecode-\hyphlengths{<mot>}{\<macro>}-

\noindent qui assigne à la \verb|\<macro>| la liste de toutes les longueurs avant les coupures possibles. Par exemple, si l'on écrit «\verb|\hyphlengths{programmation}\foo|», la macro \verb|\foo| a comme texte de remplacement «\verb|4,8,10|».

La méthode pour y parvenir fera intervenir

\centrecode-\vsplit<boite> to 0pt-

\noindent pour couper la boite résultante de la macro §\zerocompose et en obtenir la première ligne dans une boite verticale. Ensuite, en composant cette boite dans une boite verticale, en capturant la dernière boite horizontale composée avec \verb|\lastbox| puis en appliquant \idx\unhbox, cette ligne se retrouvera dans une boite horizontale ayant sa largeur naturelle. Dès lors qu'on peut la mesurer, il sera facile de trouver le nombre de caractères sur chaque ligne (4, 5 et 3 pour «\verb|pro-|», «\verb|gram-|» et «\verb|ma-|») : la simple division de la largeur de la boite par la largeur d'un caractère donne le quotient cherché. Il faudra lui soustraire 1 pour écarter le caractère de coupure. En cumulant ces nombres et en ajoutant 1 à chaque cumul pour prendre en compte le caractère de coupure, on arrive bien à la liste «4,8,10».

\showcode|\catcode`@11
\def\hyphlengths#1#2{%#2 = macro contenant les longueurs de coupures du mot #1¤§*\hyphlengths¤
	\begingroup
		\zerocompose¤§*\zerocompose¤
			[\tt% passer en fonte à chasse fixe¤\idx*\tt¤
			\setbox\z@\hbox{M}\xdef\ttwidth{\the\wd\z@}% mesurer la largeur des caractères¤\idx*\setbox\idx*\hbox\idx*\the\idx*\wd\idx*\z@\idx*\xdef¤
			]\z@{#1}% compose en 0pt dans la boite 0¤\idx*\z@¤
		\let#2 = \empty% initialise la macro #2¤\idx*\empty¤
		\def\cumul@length{0}% le cumul des longueurs initialisé à 0
		\vfuzz=\maxdimen% annule les avertissements pour débordement¤\idx*\vfuzz\idx*\maxdimen\idx*{message d'avertissement}¤
		\splittopskip=\z@ % ne rajouter aucun espace au sommet de la boite restante¤\idx*\splittopskip\idx*\z@¤
		\loop¤\idx*\loop¤
			\setbox1=\vsplit\z@ to \z@% couper la boite à 0pt de hauteur¤\idx*\vsplit¤
			{\setbox\z@=\vbox{\unvbox1 \unskip\unpenalty\global\setbox1=\lastbox}}%¤\idx*\vbox\idx*\unvbox\idx*\unskip\idx*\unpenalty\idx*\lastbox\idx*\global¤
			\setbox1=\hbox{\unhbox1 }%¤\idx*\unhbox¤
			\unless\ifvoid\z@% si la boite 0 n'est pas encore vide¤\tidx*{unless}\tidx*{ifvoid}\idx*\z@¤
				\edef\cumul@length{% mettre à jour \cumul@length
					\number\numexpr
						\cumul@length
						+% ajouter le quotient "largeur syllabe/largeur d'1 caractère"¤\idx*\wd¤
						\wd1/\dimexpr\ttwidth\relax
						-1% et soustraire 1 (le caractère "-")
						\relax
				}%
				% ajouter à #2 la virgule et le cumul actuel +1
				\edef#2{% définir la macro #2 :
					#2% reprendre le contenu de #2
					\ifx#2\empty\else,\fi% ajouter "," si #2 non vide
					\number\numexpr\cumul@length+1\relax% et le cumul
					}%
		\repeat% et recommencer¤\idx*\repeat¤
		\expsecond{% avant de fermer le groupe¤§*\expsecond¤
	\endgroup
	\def#2}{#2}% définit #2 hors du groupe
}
\catcode`\@12
a) \hyphlengths{programmation}\foo liste = "\foo"\par
b) \hyphlengths{typographie}\foo liste ="\foo"\par
c) \hyphlengths{j'entendrai}\foo liste ="\foo"\par
d) \hyphlengths{vite}\foo liste ="\foo"¤§*\hyphlengths¤|

\subsubsection{Une solution}
Il est temps de mettre en \oe uvre toute cette théorie. Curieusement, l'algorithme vu précédemment avec §\breakttA n'a pas à subir beaucoup de changements pour autoriser les coupures de mots.

Tout ce qui est nouveau va être contenu dans la macro récursive \verb|\breakttA@i|. En premier lieu, après avoir calculé la longueur du prochain mot (qui s'étend jusqu'à un espace ou un tiret), nous devons tester si ce mot (ainsi que l'éventuel tiret qui le suit) peut loger sur l'espace restant de la ligne en cours. Ce n'est qu'en cas de réponse négative que nous devons entreprendre la coupure du mot. À l'aide de §\hyphlengths et en parcourant la liste de longueurs cumulées qu'elle génère, nous pouvons trouver combien mesure la plus longue coupure possible de ce mot compatible avec la place restante sur la ligne. La macro \verb|\nexthyph@len| sera cette longueur. À l'issue de ce processus, si cet entier est nul, soit aucune coupure n'était nécessaire, soit aucune coupure n'a été trouvée. Dans le cas où il n'est pas nul, il sera copié dans \verb|\next@len|.

Si une coupure doit être faite, le test suivant, qui s'assure que \verb|\next@len| est inférieur au nombre de caractères restant à placer, est toujours vrai. Nous devons alors afficher toutes les lettres de la syllabe retenue (c'est-à-dire \verb|\next@len-1| caractères), puis afficher un tiret, mission qu'exécutera la macro \verb|\print@hyphchar|. Il reste ensuite à remplir la ligne avec des caractères blancs, fermer et ouvrir une nouvelle boite et appeler la macro \verb|\breakttA@i|.

Seules les macros \verb|\breakttA@i| et \verb|\print@hyphchar| ont été écrite dans cet exemple puisque toutes les autres macros déjà vues sont strictement identiques.

\showcode|\catcode`\@11
\newcount\brktt@cnt¤\idx*\newcount¤
\newdimen\brktt@interletter¤\idx*\newdimen¤
\newif\ifline@start% booléen vrai lorsqu'aucun caractère n'est encore affiché¤\idx*\newif¤
\newif\if@indivifound% booléen qui sera vrai si un motif spécial est rencontré¤\idx*\newif¤

\let\breakttB=\breakttA¤§*\breakttB¤

\def\breakttA@i{%
	\edef\remaining@chars{% calculer le nombre de caractères restant à placer sur la ligne
		\numexpr\maxchar@num-\brktt@cnt\relax}%¤\idx*\numexpr¤
	\len@tonextword% calculer dans \next@len le nombre de caractères avant le prochain mot
	\def\next@hyphlen{0}% initialiser la longueur de coupure possible du mot¤\defline\aaa¤
	% si le mot + l'eventuel "-" qui le suit ne rentre pas sur ce qui reste de la ligne
	\ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax
		\hyphlengths\next@word\list@hyphlengths% bâtir la liste des longueurs de coupures¤§*\hyphlengths¤
		\unless\ifx\list@hyphlengths\empty% si une coupure est possible¤\tidx*{unless}¤
			\expsecond{\doforeach\xx\in}{\list@hyphlengths}% les examiner toutes¤§*\expsecond§*\doforeach¤
				{% si la coupure examinée peut loger sur la ligne
				\unless\ifnum\xx>\remaining@chars\relax%
					\let\next@hyphlen\xx% la stocker
				\fi% pour que \next@hyphlen soit maximal
				}%
		\fi
	\fi
	\ifnum\next@hyphlen>0 % si une coupure est nécessaire et a été trouvée
		\let\next@len\next@hyphlen% mettre à jour la longueur du mot à placer
	\fi¤\defline\bbb¤
	% si le mot + l'eventuel "-" qui le suit ne peut pas loger sur la ligne en cours
	\ifnum\numexpr\next@len+\extra@char\relax>\remaining@chars\relax
		\ifline@start% si c'est le début d'une ligne
			% avertir l'utilisateur
			\message{Largeur de composition trop faible pour
				 \unexpanded\expandafter{\next@word}^^J}%¤\idx*\message\verbidx[ (fin de ligne)]{^^J}\idx*\unexpanded¤
			% et composer tout de même jusqu'à la fin de la ligne
			\exparg\print@nchar{\number\numexpr\maxchar@num-\brktt@cnt}%¤§*\exparg¤
		\else% sinon
			\insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
		\fi
		\exparg\restart@hbox{\tt@remaintext}% ré-ouvrir une boite¤§*\exparg¤
		\expandafter\breakttA@i% et poursuivre le processus
	% s'il y a la place pour accueillir ce qui est avant la prochaine coupure
	\else
		\ifnum\next@hyphlen>0 % si une coupure de mot doit être faite¤\defline\ccc¤
			\exparg\print@nchar{\number\numexpr\next@len-1}% afficher les lettres de la syllabe¤§*\exparg¤
			\print@hyphchar% et le caractère de coupure
			\insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
			\exparg\restart@hbox{\tt@remaintext}% ré-ouvrir une boite¤§*\exparg¤
			\expandafter\expandafter\expandafter\breakttA@i% et continuer le processus
		\else% si pas de coupure dans le mot¤\defline\ddd¤
			\print@nchar\next@len% afficher le mot
			\ifx\tt@remaintext\tt@emptytext% si texte restant est vide
				\insert@blankchar*{\maxchar@num-\brktt@cnt}% remplir la ligne
				\egroup% fermer la hbox
				\par% aller à la ligne
				\endgroup% fermer le groupe ouvert au début. Fin du processus
			\else% si le texte restant n'est pas vide
				\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas remplie
						\print@nchar{1}% afficher le caractère qui suit le mot
				\else% si la ligne est remplie
					\exparg\restart@hbox{\tt@remaintext}% ferme la hbox et en ré-ouvre une¤§*\exparg¤
				\fi
				\expandafter\expandafter\expandafter\breakttA@i% enfin, continuer le processus
			\fi
		\fi
	\fi
}

\def\print@hyphchar{%
	\advance\brktt@cnt by 1 % augmenter le compteur de caractères¤\idx*\advance¤
	\hbox to\ttchar@width{\hss-\hss}% afficher "-"¤\idx*\hbox\idx*\hss¤
	\ifnum\brktt@cnt<\maxchar@num\relax% si la ligne n'est pas encore remplie
		\kern\brktt@interletter\relax% insérer le ressort inter-lettre¤\idx*\kern¤
	\fi
}

\catcode`\@12

\def\liglist{<<,>>}% liste des motifs de ligature (mettre à, é, etc si codage UTF8)¤\idx{ligature}¤
\def\ttindent{3}

\vrule\vbox{\breakttB[3pt][8cm]{%¤\idx*\vrule\idx*\vbox§*\breakttB¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous d'une ligne à l'autre. Plus aucun débordement
n'a lieu, car une espace correctement calculée est insérée entre chaque
caractère. Dorénavant, les mots ne sont plus coupés <<sauvagement>>.
}%
}\vrule¤\idx*\vrule¤

\vrule\vbox{\breakttB[1pt][5cm]{%¤§*\breakttB¤
Dans ce paragraphe, composé en fonte à chasse fixe et où les limites gauche
et droite du texte ont été tracées, on constate que les caractères sont
exactement les uns au-dessous d'une ligne à l'autre. Plus aucun débordement
n'a lieu, car une espace correctement calculée est insérée entre chaque
caractère. Dorénavant, les mots ne sont plus coupés <<sauvagement>>.
}%
}\vrule¤\idx*\vrule¤|

La macro \verb|\breakttA@i| est la même que vue précédemment sauf que les lignes \nos\aaa--\bbb{} et \ccc--\ddd{} sont ajoutées pour permettre les coupures de mots.

Concluons ce difficile défi en remarquant qu'en nous aidant de celui de \TeX{}, nous avons \emph{programmé} un algorithme de coupures, mais il n'a pas toutes les fonctionnalités de l'original. En effet, les coupures se feront \emph{toujours} lorsqu'elles sont possibles. Il n'y a par exemple aucun moyen de décourager des coupures, que ce soit sur des lignes adjacentes comme l'augmentation de \idx\doublehyphendemerits le permet ni sur l'avant-dernière ligne d'un paragraphe avec \idx\finalhyphendemerits. Nous avons cependant gagné sur un point : les coupures se feront sur des mots comprenant un trait d'union, aussi bien sur ce trait que sur le mot qui le précède ou le suit, alors que \TeX{} n'autorise une coupure que sur le trait d'union.\idx*[|)]{composition en fonte à chasse fixe}

\section{Afficher des algorithmes}
Bien que la programmation qui entre en jeu ici est \emph{linéaire} (c'est-à-dire sans boucle), il est intéressant de décortiquer la méthode à déployer pour afficher des algorithmes sous forme de \idx{pseudocode} comme cela est parfois fait dans ce livre (voir par exemple ceux des pages \pageref{algo1}, \pageref{algo2} ou \pageref{algo3}).

\subsubsection{La syntaxe et les fonctionnalités}
Commençons par la syntaxe finale. La macro §\algorithm admettra un argument optionnel qui est  la liste des tokens dont le catcode sera rendu égal à 12 pendant le pseudocode. Elle admettra aussi un argument obligatoire qui est le titre de l'algorithme (éventuellement vide). Le \idx{pseudocode} proprement dit est contenu entre deux tokens identiques, à la mode de §\litterate :

\centrecode-\algorithm[<liste de tokens>]{<titre>}<délimiteur><texte><délimiteur>-

Pour que la saisie soit la plus « naturelle » possible, voici les principales fonctionnalités à mettre en \oe uvre:
\begin{enumerate}
	\item chaque caractère de tabulation \verb|^^I|\verbidx[ (tabulation)]{^^I} sera traduit par une espace horizontale. La valeur de cette espace est contenue dans une macro \verb|\algoindent|;
	\item les espaces perdent leur comportement naturel et plusieurs espaces consécutifs seront affichés;
	\item les retours à la ligne \verbidx[ (retour charriot)]{^^M} perdent également leur comportement naturel et sont reprogrammés pour provoquer un retour à la ligne;
	\item le caractère \cidx\~ reste actif, mais est reprogrammé pour que le \verb|<texte>| se trouvant entre deux \cidx\~ soit affiché en caractères gras;
	\item les caractères «\verb|:=|», utilisés pour une assignation, sont traduits à l'affichage par «$\leftarrow$», provoqué par la macro de plain-\TeX \idx\leftarrow;
	\item le caractère «\cidx[ (mise en indice)]\_» garde son comportement normal en mode mathématique\idx*{mode!mathématique} mais est affiché tel quel sinon;
	\item le caractère «\cidx\%» met en italique et en gris tout ce qui reste sur la ligne courante;
	\item les lignes sont numérotées dans la marge de gauche, mais il est possible de désactiver cette fonctionnalité.
\end{enumerate}
\grandsaut

Voici ce que nous devons pouvoir écrire (où «$\longrightarrow$» représente le caractère de tabulation):

\begingroup
\def\showcodeactivechars{\defactive\^^I{\begingroup\color{gray}${}\longrightarrow{}$\endgroup}}
\showcode/Voici un algorithme élémentaire :
\algorithm[\#]{Algorithme {\bf MinMax}}|
macro ~Min_Max~ (#1) % afficher la valeur max et min d'une liste de valeurs #1
	$V_{max}:=-\infty$ % $-\infty$ ou la plus petite valeur possible
	$V_{min}:=+\infty$ % $+\infty$ ou la plus grande valeur possible
	~Pour~ chaque $x$ dans (#1)
		~Si~ $x>V_{max}$
			~alors~ $V_{max}:=x$
		~FinSi~
		~Si~ $x<V_{min}$
			~alors~ $V_{min}:=x$
		~FinSi~
	~FinPour~
	Afficher "$V_{min}$ et $V_{max}$"
~FinMin_Max~|
Suite du texte.../
\endgroup
\grandsaut

Le problème étant posé, seuls les points \nos1 et 8 vont faire intervenir des méthodes nouvelles.

\subsubsection{Rendre actif le caractère de tabulation}
Pour que le caractère de tabulation ait le comportement souhaité, la première idée serait de le rendre actif et de lui faire insérer horizontalement l'espace dont la mesure est contenue dans \verb|\alogoindent| :

\begingroup
\def\showcodeactivechars{\defactive\^^I{\begingroup\color{gray}${}\longrightarrow{}$\endgroup}}
\showcode/\def\algoindent{1cm}%
\begingroup
\parindent=0pt % pas d'indentation¤\idx*\parindent¤
\defactive\^^M{\leavevmode\par}% rend le retour charriot actif¤§*\defactive\verbidx*[ (retour charriot)]{^^M}¤
\defactive\^^I{\hskip\algoindent\relax}% tabulation active¤§*\defactive\verbidx[ (tabulation)]{^^I}\idx*\hskip¤
Pas d'indentation ici\ldots
	Voici une première ligne
		une seconde plus indentée
	retour à l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernière ligne
\endgroup/
\endgroup

Le comportement est celui souhaité sauf lorsque le texte est trop long pour loger sur la ligne entière, comme celui écrit par la boucle §\for. Pour garder une cohérence dans l'alignement vertical, il faut que l'indentation soit rémanente. La méthode la plus immédiate est d'incrémenter le ressort \idx\leftskip de la quantité \verb|\algoindent| à chaque tabulation rencontrée et remettre ce ressort à \verb|0pt| à chaque nouvelle ligne. Dans tout l'algorithme, nous assignerons un ressort infini à \idx\rightskip.

\begingroup
\def\showcodeactivechars{\defactive\^^I{\begingroup\color{gray}${}\longrightarrow{}$\endgroup}}
\showcode/\def\algoindent{1cm}%
\begingroup
\leftskip=0pt \rightskip=0pt plus1fil \relax % initialise les ressorts latéraux¤\idx*\leftskip\idx*\rightskip¤
\parindent=0pt % pas d'indentation¤\idx*\parindent¤
\defactive\^^M{\leavevmode\par\leftskip=0pt }% rend le retour charriot actif¤§*\defactive\verbidx*[ (retour charriot)]{^^M}¤
\defactive\^^I{\advance\leftskip by \algoindent\relax}% tabulation active¤§*\defactive\verbidx[ (tabulation)]{^^I}\idx*\hskip\idx*\advance\idx*\leftskip¤
Pas d'indentation ici\ldots
	Voici une première ligne
		une seconde plus indentée
	retour à l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernière ligne
\endgroup/
\endgroup

\subsubsection{Numérotation des lignes}
Passons maintenant au point \no8 qui consiste à numéroter chaque ligne de l'algorithme. Une « ligne » de l'algorithme est ce qui se trouve entre deux frappes de la touche entrée ce qui revient à considérer ici qu'une ligne est donc un paragraphe pour \TeX. La primitive \idx\everypar, qui se comporte comme un registre de tokens, permet de définir un ensemble de tokens qui seront exécutés (en mode horizontal) lorsqu'un paragraphe débute :

\centrecode-\everypar= {<texte>}-

Nous allons mettre cette primitive à contribution pour numéroter chaque paragraphe. Pour que le numéro soit dans la marge de gauche, nous allons le placer dans une boite en débordement à gauche de type \idx\llap et laisser une espace de \verb|4pt| entre ce numéro et le début de la ligne. Afin que les numéros soient correctement placés, nous devons tenir compte du ressort \idx\leftskip. Il faut donc laisser une espace de \verb|4pt|${}+{}$\idx\leftskip entre le numéro et le début de la ligne.

\begingroup
\def\showcodeactivechars{\defactive\^^I{\begingroup\color{gray}${}\longrightarrow{}$\endgroup}}
\showcode/¤\string\newcount\string\algocnt¤ % compteur de lignes pour l'algorithme¤\idx*\newcount¤
\def\algoindent{1cm}%
\begingroup
\algocnt=1 % initialise le compteur à 1
\leftskip=0pt \rightskip=0pt plus1fil\relax% initialise les ressorts à 0pt¤\idx*\leftskip\idx*\rightskip¤
\parindent=0pt % pas d'indentation¤\idx*\parindent¤
\everypar={\llap{$\scriptstyle\number\algocnt$\kern\dimexpr4pt+\leftskip\relax}}%¤\idx*\llap\idx*\scriptstyle\idx*\kern\idx*\dimexpr\idx*\leftskip\idx*\everypar¤

\defactive\^^M{\leavevmode\par\advance\algocnt by1 \leftskip=0pt }% retour charriot actif¤§*\defactive\verbidx*[ (retour charriot)]{^^M}\idx*\leavevmode\idx*\leftskip\idx*\advance¤
\defactive\^^I{\advance\leftskip by \algoindent\relax}% tabulation active¤§*\defactive\verbidx[ (tabulation)]{^^I}\idx*\leftskip\idx*\advance¤
Pas d'indentation ici\ldots
	Voici une première ligne
		une seconde plus indentée
	retour à l'indentation normale
		\for\xx=1to10\do{un long texte }
	pour terminer, la dernière ligne
\endgroup/
\endgroup

\subsubsection{Ignorer les indésirables en début d'algorithme}
Il nous reste une astuce à prévoir pour que la macro §\algorithm soit la plus agréable à utiliser. Il s'agit de ce qui se trouve au début de l'algorithme, juste après le \verb|<token>| qui délimite le texte de l'algorithme. Pour que les choses soient plus claires, supposons que ce \verb|<token>| est «\verb-|-». Il faudrait que l'affichage soit le même que l'on écrive

\begin{enumerate}
	\item \verb-\algorithm{<titre>}|début de l'algorithme...|-
	\item \verb-\algorithm{<titre>}|-\par
\verb-début de l'algorithme...|-§*\algorithm
\end{enumerate}

Il faut donc que l'on supprime tous les retours charriots (actifs) et tous les espaces (actifs) qui pourraient se trouver au tout début du corps de l'algorithme. Cela suppose une macro non linéaire \verb|\sanitizealgo|, la seule de cette section. En voici l'algorithme :

\begingroup
\numalgofalse
\def\algoleftskip{.1\hsize}
\def\algorightskip{.1\hsize}
\algorithm[]{Manger tous les \texttt{\string^\string^M} et \texttt\textvisiblespace}/
macro ~lire_prochain_token~
	lire le token suivant $x$ à l'aide de \idx\futurelet
	aller à ~tester_prochain_token~
~fin~\medskip
macro ~tester_prochain_token~
	~si~ ($x={}$\verb|espace| actif) ~ou~ ($x={}$\verbidx*[ (retour charriot)]{^^M}\verb|^^M| actif)
		manger $x$
		aller à ~lire_prochain_token~
	~finsi~
~fin~/
\endgroup

Nous appellerons cette macro \emph{en dernier} puis, une fois son travail effectué, nous laisserons \TeX{} composer le texte constituant l'algorithme. On ne pourra reprendre la main que lorsqu'il exécutera le \verb|<délimiteur>| final rendu actif qui fermera le groupe ouvert tout au début, tracera la ligne horizontale de fin d'algorithme et sautera une petite espace verticale à l'aide de \idx\smallbreak.

\subsubsection{Commentaires grisés avec le package \texttt{color}}
Enfin, pour que les commentaires soient en italique et en gris, nous allons rendre le caractère «\cidx\%» actif de façon à ce qu'il sélectionne la \idx{fonte} italique (avec \idx\it) et colore le texte à venir en gris (avec \verb|\color{gray}|). Cette dernière action suppose que la couleur «\verb|gray|» a été définie et que le \idx[!color]{package} «\verb|color|» a préalablement été chargé moyennant :

\begin{itemize}
	\item \idx\usepackage\verb|{color}| pour le \idx[!\LaTeX]{format} \LaTeX{};
	\item \idx\input\verb| color| pour le \idx[!plain-\TeX]{format} plain-\TeX{};
	\item \idx\setupcolor\verb|[state=start]| pour le \idx[!Con\TeX t]{format} Con\TeX t.
\end{itemize}

Pour que la typographie normale (caractères non italiques et couleur noire) soit à nouveau en vigueur à la ligne suivante, nous chargerons le caractère actif \verbidx*[ (retour charriot)]{^^M}\verb|^^M| d'effectuer les actions «\idx\rm» pour un retour en \idx{fonte} droite et «\verb|\color{black}|» pour restaurer la couleur noire.

\subsubsection{Le code complet}
Voici le code complet commenté qui reprend des méthodes déjà vues plusieurs fois (programmation de caractères actifs notamment) :

\begingroup
\defactive\W{\begingroup\color{gray}${}\longrightarrow{}$\endgroup}
\showcode[\defactive\W{\advance\leftskip\algoindent\relax}]/\newif\ifnumalgo¤\idx*\newif¤
\newcount\algocnt¤\idx*\newcount¤
\numalgotrue

\def\algoindent{2em}
\def\algorule{.4pt}% épaisseur des réglures de début et de fin

\def\algohrulefill{% remplit avec une ligne horizontale
	\leavevmode¤\idx*\leavevmode¤
	\leaders\hrule height\algorule\hfill¤\idx*\leaders\idx*\hrule\idx*\hfill¤
	\kern0pt % rajoute un noeud au cas où la commande est en fin de ligne¤\idx*\kern¤
}

\newmacro\algorithm[\\,\#,\{,\}]2{%¤§*\algorithm§*\newmacro¤
	\medbreak¤\idx*\medbreak¤
	\begingroup% ouvre un groupe (sera fermé à la fin de l'algorithme)¤\defline\aaa¤
		\algocnt=1 % initialise le compteur de lignes
		\leftskip=0pt \rightskip=0pt plus1fil\relax% initialise les ressorts latéraux¤\idx*\leftskip\idx*\rightskip¤
		\parindent=0pt % pas d'indentation¤\idx*\parindent¤
		%%%%%%%%%%%% affichage du titre %%%%%%%
		\algohrulefill% remplir avec une ligne horizontale
		\ifempty{#2}% si #2 est vide¤§*\ifempty¤
			{}% ne rien insérer
			{% sinon
			\lower.5ex\hbox{ #2 }% insérer le titre abaissé de 0.5ex¤\idx*\lower\idx*\hbox¤
			\algohrulefill% insérer une ligne horizontale
			}%
		\par% aller à la ligne
		\nointerlineskip% ne pas insérer le ressort d'interligne¤\idx*\nointerlineskip¤
		\kern7pt % et sauter 7pt verticalement¤\idx*\kern¤
		\nobreak% empêcher une coupure de page¤\idx*\nobreak¤
		%%%%%%%%%%%%%% fin du titre %%%%%%%%%%
		%
		%%%%%%%%%%%%%% rend les caractères actifs %%%%%%%%%%%%%%
		\def~##1~{\begingroup\bf##1\endgroup}%¤\idx*\bf¤
		\defactive:{% rend ":" actif¤§*\defactive¤
			\futurelet\nxttok\algoassign% \nxttok = token suivant¤\idx*\futurelet¤
		}%
		\def\algoassign{% suite du code de ":"
			\ifx=\nxttok% si ":" est suivi de "="
				\ifmmode% si mode math¤\tidx*{ifmmode}\idx*{mode!mathématique}¤
					\leftarrow% afficher "\leftarrow"¤\idx*\leftarrow¤
				\else% si mode texte
					${}\leftarrow{}$% passer en mode math pour "\leftarrow"¤\idx*{mode!mathématique}¤
				\fi
				\expandafter\gobone% manger le signe "="
			\else% si ":" n'est pas suivi de "="'
				\string:% afficher ":"¤\idx*\string¤
			\fi
		}%
		\ifnumalgo% si la numérotation est demandée,
			\everypar={% définir le \everypar
				\llap{$\scriptstyle\number\algocnt$\kern\dimexpr4pt+\leftskip\relax}%
			}%¤\idx*\llap\idx*\scriptstyle\idx*\kern\idx*\dimexpr\idx*\leftskip\idx*\everypar¤
		\fi
		\doforeach\currentchar\in{#1}{\catcode\expandafter`\currentchar=12 }%¤§*\doforeach¤
		\def\algocr{% définit ce que fait ^^M
			\color{black}% repasse en couleur noire¤\idx*\color¤
			\rm% fonte droite¤\idx*\rm¤
			\leavevmode\par% termine le paragraphe
			\advance\algocnt by1 % incrémente le compteur de lignes¤\idx*\advance¤
			\leftskip=0pt % initialise le ressort gauche¤\idx*\leftskip¤
		}
		\letactive\^^M=\algocr%¤§*\letactive\verbidx*[ (retour charriot)]{^^M}¤
		\defactive\^^I{\advance\leftskip by \algoindent\relax}%¤§*\defactive\verbidx[ (tabulation)]{^^I}\idx*\advance\idx*\leftskip¤
		\defactive\ {\hskip1.25\fontdimen2\font\relax}% espace = 25% de + que
		                                              % la largeur naturelle¤\idx*\hskip\idx*\fontdimen\idx*\font¤
		\defactive\%{\it\color{gray}\char`\%}% passe en italique et gris puis affiche "%"¤\idx*\it\idx*\char\idx*\color\cidx*\%¤
		\defactive_{\ifmmode_\else\string_\fi}%¤\tidx*{ifmmode}\idx*\string¤
		\defactive#3{% rend le token #3 actif (il sera rencontré à la fin de l'algorithme)¤§*\defactive¤
			\everypar{}% neutralise le \everypar¤\idx*\everypar¤
			\par% aller à la ligne
			\nointerlineskip% ne pas insérer le ressort d'interligne¤\idx*\nointerlineskip¤
			\kern7pt % et sauter 7pt verticalement¤\idx*\kern¤
			\nobreak% empêcher une coupure de page¤\idx*\nobreak¤
			\algohrulefill% tracer la ligne de fin
	\endgroup% ferme le groupe ouvert au début de l'algorithme¤\defline\bbb¤
	\smallbreak% saute un petit espace vertical¤\idx*\smallbreak¤
		}%
	%%%%%%%%%%%%%%%%% fin des caractères actifs %%%%%%%%%%%%%%%%
	\sanitizealgo% va manger les espaces et les ^^M au début de l'algo
}

\def\sanitizealgo{\futurelet\nxttok\checkfirsttok}% récupère le prochain token¤\idx*\futurelet¤

\def\checkfirsttok{% teste le prochaun token
	\def\nextaction{% a priori, on considère que la suite est " " ou "^^M" donc
		\afterassignment\sanitizealgo% aller à \sanitizealgo¤\idx*\afterassignment¤
		\let\nexttok= % après avoir mangé ce "^^M" ou cet espace
	}%
	\unless\ifx\nxttok\algocr% si le prochain token n'est pas un ^^M¤\tidx*{unless}¤
		\unless\ifx\space\nxttok% et si le prochain token n'est pas un espace¤\idx*\space¤
			\let\nextaction\relax% ne rien faire ensuite
		\fi
	\fi
	\nextaction% faire l'action décidée ci-dessus
}

Voici un algorithme élémentaire
\algorithm[\#]{Algorithme {\bf MinMax}}|
macro ~Min_Max~ (#1) % afficher la valeur max et min d'une liste de valeurs #1
W$V_{max}:=-\infty$ % $-\infty$ ou la plus petite valeur possible
W$V_{min}:=+\infty$ % $+\infty$ ou la plus grande valeur possible
W~Pour~ chaque $x$ dans (#1)
WW~Si~ $x>V_{max}$
WWW~alors~ $V_{max}:=x$
WW~FinSi~
WW~Si~ $x<V_{min}$
WWW~alors~ $V_{min}:=x$
WW~FinSi~
W~FinPour~
WAfficher "$V_{min}$ et $V_{max}$"
~FinMin_Max~|
Suite du texte.../% TODO : dans le fichier des codes, remplacer "W" par "TAB"
\endgroup

L'algorithme obtenu peut franchir des sauts de page et donc s'étendre sur plusieurs pages. Ce comportement peut être facilement interdit en englobant la totalité de l'algorithme dans une boite verticale de type \idx\vbox ou \idx\vtop. On peut par exemple remplacer le \idx\begingroup de la ligne \no\aaa{} par \idx\vbox\idx\bgroup qui marquera le début de la boite et en profiter, si on le souhaite pour ajuster la largeur \idx\hsize. Il faudra également remplacer le \idx\endgroup de la ligne \no\bbb{} par \idx\egroup qui fermera la boite.

\chapter*{Conclusion}
\addcontentsline{toc}{part}{Conclusion}

Nous voilà, cher lecteur, arrivés à la fin de notre périple. Nous en savons beaucoup plus qu'au début, mais il reste tant à découvrir, tant à expérimenter\ldots{} Le maitre mot est d'essayer de coder par soi même; c'est un poncif tant c'est répété, mais c'est en programmant qu'on devient programmeur. Pas en lisant un livre sur le sujet.

Si les notions abordées dans ce livre ont balayé le plus large champ possible pour permettre un début d'autonomie, elles ne sont pas exhaustives. Par exemple, nous n'avons jamais parlé de la routine de sortie qui occupe à elle seule un chapitre entier (le \no23) du \TeX book. De la même façon, pas un mot n'a été dit sur les insertions, mécanisme souple et puissant utilisé dans les notes de bas de page ou les notes marginales. Nous avons à peine effleuré les alignements et les tableaux de \TeX{} alors que ce sujet est d'une grande richesse. Il y reste donc des pans entiers à découvrir\ldots
\grandsaut

Bonne chance donc et avant tout, cher lecteur, prenez du plaisir avec \TeX{} !
%|                                                                            |
%|                                Fin partie 5                                |
%|____________________________________________________________________________|

% ____________________________________________________________________________
%|                                                                            |
%|                                   Annexes                                  |
%|                                                                            |
\immediate\closeout\reglewrite
\part{Annexes}
\chapter{Débogage}\idx*[|(]{débogage}
Le débogage est un art difficile qui consiste à trouver pour quelle(s) raison(s) un programme ne fonctionne pas comme on s'y attend. Certes, la relecture du code accompagnée de la simulation mentale de son fonctionnement permet parfois de trouver où se trouve l'erreur. Bien souvent hélas, cet exercice est insuffisant pour débusquer l'endroit où se cache le «\emph{bug}» . Il faut alors s'en remettre à des instructions de débogage.

\section{Délivrer les informations stockées}
Nous allons d'abord examiner les instructions qui font remonter des entrailles de \TeX{} ce qui est contenu dans les différentes structures de données permettant de stocker de l'information (primitives, macros ou registres). Nous avons déjà vu que \idx\meaning\verb|<token>| se développait en tokens de catcode 12\idx*{catcode!12 (autre)} qui, selon ce qu'est le \verb|<token>| :

\begin{itemize}
	\item est le nom de la primitive si ce \verb|<token>| est une primitive ;
	\item est le \idx{texte de paramètre} et le \idx{texte de remplacement} dans le cas d'une macro;
	\item est le \verb|<token>| lui-même accompagné de sa nature si c'est un caractère.
\end{itemize}

\showcode/a) \meaning a\par
b) \meaning {\par
c) \meaning _\par
d) \meaning\def\par % une primitive
e) \meaning\baselineskip\par% une primitive¤\idx*\baselineskip¤
f) \long\def\foo#1#2.#3{#1 puis #2 et #3 !}\meaning\foo¤\idx*\long¤/

La primitive \idx\show a un comportement identique sauf que ces informations sont écrites dans le \idx[!log]{fichier} \verb|log| et sur le terminal. Cela présente l'avantage de ne pas surcharger l'affichage comme peut le faire \idx\meaning, à condition d'aller lire le \idx[!log]{fichier} \verb|log| après la compilation.

Pour connaitre l'argument d'une macro, \idx\show manque de souplesse puisqu'il faut définir une macro auxiliaire dont le texte de remplacement est cet argument et enfin, donner cette macro à \idx\show :

\errcode/\def\foo#1#2{%
	\def\argA{#1}\show\argA% débogage¤\idx*\show¤
	Bonjour #1 et #2}
\foo{{\bf X}}{Y}¤\idx*\bf¤/{\ttfamily> \string\argA=macro:\par
->\string{\string\bf\space X\string}.}

Le moteur \eTeX{}\idx*{moteur!etex} fournit la primitive\idx*\showtokens

\centrecode-\showtokens{<ensemble de tokens>}-

\noindent et écrit sur le terminal et dans le \idx[!log]{fichier} \verb|log| cet \verb|<ensemble de tokens>|. De plus, cette primitive devant être suivie d'une accolade ouvrante, elle obéit à la règle que partagent les primitives possédant cette propriété : elle développe tout jusqu'à trouver cette accolade ouvrante.

\errcode/\def\foo#1#2{%
	\showtokens{#1}% débogage¤\idx*\showtokens¤
	Bonjour #1 et #2}
\foo{{\bf X}}{Y}/{\ttfamily>\string{\string\bf\space X\string}.}
\grandsaut

La primitive \idx\show reste pourtant inopérante pour afficher quel est le contenu d'un registre, qu'il soit primitive (comme \idx\baselineskip) ou défini par l'utilisateur (comme un registre d'entier par exemple).

\errcode/\newtoks\footoks
\footoks={foo bar}
\show\footoks¤\idx*\show¤/{\ttfamily> \string\footoks=\string\toks62.}

Pour extraire les valeurs contenues dans des registres de dimension, de ressort, d'entier ou de tokens, la primitive \idx\showthe doit être utilisée :

\errcode/\showthe\baselineskip% registre-primitive¤\idx*\showthe\idx*\baselineskip¤
\newtoks\footoks \footoks={foo bar} \showthe\footoks¤\idx*\newtoks¤
\newcount\foocount \foocount=987 \showthe\foocount¤\idx*\newcount¤
\newdimen\foodimen \foodimen=3.14pt \showthe\foodimen¤\idx*\newdimen¤
\newskip\fooskip \fooskip=10 pt plus 1pt minus 1fil \showthe\fooskip¤\idx*\newskip¤
\newbox\foobox \foobox\hbox{foo} \showthe\foobox¤\idx*\newbox\idx*\showthe¤/{> 12.0pt.\par
> foo bar.\par
> 987.\par
> 3.14pt.\par
> 10.0pt plus 1.0pt minus 1.0fil.\par
> 101.}

Le dernier registre, celui de boite, échappe à \idx\showthe. Cela est dû au fait que \idx\newbox définit \verb|\foobox| à l'aide de \idx\chardef puisqu'il n'existe pas de primitive \verb|\boxdef|. Nous avons vu que pour demander à \TeX{} de donner la composition d'une boite, il faut passer par la primitive \verb|\showbox| (voir page~\pageref{showbox}).
\grandsaut

Correctement placer les instructions de débogage telles que \idx\show, \idx\showthe et \idx\showtokens afin de se donner le maximum de chances de trouver le dysfonctionnement n'est pas trivial et demande souvent plusieurs essais-erreurs. Bien souvent, l'enquête consiste à suivre l'évolution du \idx{texte de remplacement} d'une macro (avec \idx\show{}), comprendre comment se transmet un argument entre plusieurs macros (avec \idx\showtokens{}) ou «\emph{tracer}» la valeur d'un registre (avec \idx\showthe{}).

\section{Délivrer des informations sur l'exécution}
\TeX{} fournit également des primitives qui permettent de contrôler quelles informations seront affichées dans le \idx[!log]{fichier} \verb|log| lors de l'exécution du code. Une fois la compilation faite, l'examen de ces informations retrace, selon la précision demandée, ce que \TeX{} a fait.

La primitive \idx\tracingmacros se comporte comme un registre d'entier. Lorsqu'elle reçoit un entier strictement positif, \TeX{} donnera dans le \idx[!log]{fichier} \verb|log| des informations sur chaque macro développée : son nom, son texte de paramètre, son texte de remplacement et si elle admet des arguments, la valeur des arguments lus au moment du développement.

\errcode-\def\foo#1,#2\endfoo{Bonjour #1 et #2}
\tracingmacros=1
\foo moi,toi\endfoo
\tracingmacros=0-{\ttfamily\string\foo\space\#1,\#2\string\endfoo{} ->Bonjour \#1 et \#2\par
\#1<-moi\par
\#2<-toi}

Une autre aide au diagnostic est fournie par la primitive \idx\tracingcommands, qui est également de type entier. En assignant un nombre strictement positif à cette primitive, \TeX{} écrira dans le \idx[!log]{fichier} \verb|log| toutes les commandes qu'il exécute. Si l'entier vaut 2 ou plus, les tests et leurs issues seront également montrés.

\errcode-\tracingcommands=2
Foo \hbox{et \ifnum2>1 bar\else toi\fi}\par
Suite
\tracingcommands=0-{\ttfamily\{vertical mode: the letter F\}\par
\{horizontal mode: the letter F\}\par
\{blank space  \}\par
\{\string\hbox\}\par
\{restricted horizontal mode: the letter e\}\par
\{blank space  \}\par
\{\string\ifnum\}\par
\{true\}\par
\{the letter b\}\par
\{\string\else\}\par
\{end-group character \}\}\par
\{horizontal mode: \string\par\}\par
\{vertical mode: the letter S\}\par
\{horizontal mode: the letter S\}\par
\{blank space  \}\par
\{\string\tracingcommands\}\par}

Les espaces parasites générés par des fins de ligne non commentées peuvent facilement être débusqués en cherchant «\texttt{blank space}» dans le \idx[!log]{fichier} \verb|log|.
\grandsaut

Pour déboguer des programmes, la macro \idx\tracingrestores peut également s'avérer utile. Elle est également de type entier et indique dans le \idx[!log]{fichier} \verb|log| ce que \TeX{} garde en mémoire lorsque des assignations sont locales. Ces instructions placées dans la \emph{\idx{pile de sauvegarde}} sont dépilées à la sortie du groupe pour restaurer la variable à son état antérieur. Si une assignation est globale, rien n'est placé dans la pile et la dernière valeur globale assignée sera celle en vigueur à la sortie du groupe

Prenons un exemple inspiré de celui du \TeX book. Afin d'éviter de définir un compteur, utilisons celui qui porte le \no255 et définissons la macro \verb|\i| qui incrémente ce compteur.

\errcode/\def\i{\advance\count255 1 }
\tracingrestores=1
\count255=2 {\i\i\i}¤\defline\aaa¤
\tracingrestores=0/{\ttfamily\{restoring \string\count255=2\}}

L'instruction «\verb|{restoring \count255=2}|» reflète ce qui exécuté à la fin du groupe. L'instruction «\verb|\count255=2|» a été placée sur la \idx{pile de sauvegarde} lorsque le premier \verb|\i| a été exécuté.

Lorsqu'une assignation est globale, la dernière valeur globale assignée devient celle qui sera en vigueur à la sortie du groupe. Dès lors, les précédentes instructions de sauvegarde placées sur la \idx{pile de sauvegarde} deviennent inutiles, mais elles y restent et seront ignorées à la sortie du groupe. Mettons ceci en évidence avec la macro \verb|\gi| qui incrémente globalement le compteur \no255 :

\errcode/\def\i{\advance\count255 1 } \def\gi{\global\i}¤\idx*\global¤
\tracingrestores=1
\count255=2 {\i\i\gi\i\gi\i}
\tracingrestores=0/{\{restoring \string\count255=7\}\par
\{retaining \string\count255=7\}\par
\{retaining \string\count255=7\}}

Les empilements sur la \idx{pile de sauvegarde} ont lieu :

\begin{enumerate}
	\item lorsque le premier \verb|\i| est exécuté;
	\item au troisième \verb|\i|, qui modifie localement une valeur rendue globale par le \verb|\gi| précédent;
	\item au dernier \verb|\i| qui à nouveau, modifie localement une valeur globale.
\end{enumerate}

Au dépilement qui se fait dans l'\emph{ordre inverse} de l'empilement, seule la dernière valeur de sauvegarde 7 est prise en compte. Les deux derniers ordres de sauvegarde sont ignorés et la valeur 7 est retenue. Cela se traduit dans le \idx[!log]{fichier} \verb|log| par lignes contenant le mot «\texttt{retaining}» et non pas «\texttt{restoring}».

Il faut donc être conscient qu'effectuer localement des assignations locales \emph{et} globales peut charger la \idx{pile de sauvegarde} inutilement. Dans les faits, une instruction de sauvegarde est empilée chaque fois qu'une assignation locale suit une assignation globale. La \idx{pile de sauvegarde} n'est évidemment pas infinie et un dépassement de sa capacité se traduit par une erreur à la compilation de type «\texttt{save size capacity exceeded}.»\idx*[|)]{débogage}

\chapter{Programmer l'addition décimale}\label{decadd}§*\decadd[|(]%
Comme nous l'avons vu et expliqué à la page~\pageref{arrondis.sur.dimensions}, l'addition sur les dimensions pose des problèmes d'arrondis conduisant à des résultats faux. Ces erreurs, insignifiantes pour une dimension, sont inacceptables lorsque ces nombres sont considérés comme entités mathématiques. Il est donc utile de programmer une macro purement développable §\decadd\verb|{<décimal 1>}{<décimal 2>}| qui ne présente pas les défauts de l'addition sur les dimensions.

Ayant à notre disposition l'addition des entiers relatifs, programmer une simple addition de deux nombres décimaux relatifs semble trivial. Pourtant\ldots{}

\section{Procédure mathématique}
Appelons $a$ et $b$ les deux nombres à additionner. Si les deux nombres sont entiers, le problème est résolu : il suffit de les additionner avec \idx\numexpr qui ne procède à aucun arrondi.

Si l'un d'entre eux est entier, il faut d'abord le transformer en nombre décimal en ajoutant « \verb|.0| ». Ceci fait, les deux nombres $a$ et $b$ sont de la forme «$x.y$» où $x$ est un entier relatif et $y$ un entier naturel. Ensuite, nous allons transmettre le signe de $x$ à $y$ de telle sorte que l'entier représentant la partie entière et celui représentant la partie décimale aient le même signe. Par exemple, si $a=-3.14$, alors $x_a=-3$ et $y_a=-14$.

L'addition se fait donc entre deux nombres de la forme $x_a.y_a$ et $x_b.y_b$ où $x_a$, $x_b$, $y_a$ et $y_b$ sont des entiers \emph{relatifs}. Nous allons transformer les parties décimales pour qu'elles aient le même nombre de chiffres en rajoutant à l'une d'entre-elles, si c'est nécessaire, des 0 inutiles à sa droite. Une fois ceci effectué, on définit $10^n$ comme la puissance de 10 immédiatement supérieure à $|y_a|$ ou $|y_b|$ que l'on nomme «seuil de retenue».

La méthode consiste ensuite à ajouter indépendamment les parties entières et les parties décimales. Pour que les choses soient plus claires, les parties entières et décimales sont séparées par une ligne verticale :

\begin{centrage}\small
	\begin{tabular}{rr|l}
		&$x_a$&$y_a$\\
	+	&$x_b$&$y_b$\\\hline
		&$x$  &$y$
	\end{tabular}
\end{centrage}

On examine ensuite les nombres relatifs $x$ et $y$ obtenus. Si l'on note $\sigma_x$ le signe de $x$ (ou celui de $y$ si $x$ est nul) et $\sigma_y$ celui de $y$, alors, le cas est favorable se produit lorsque $|y|<10^n$ (pas de retenue) et $\sigma_x=\sigma_y$. Le résultat est alors le nombre décimal 

\[
\begin{cases}
x.|y|&\text{ si } x\neq0\\
\sigma_y0.|y|&\text{ si } x=0
\end{cases}
\]

Deux cas défavorables peuvent se présenter :

\begin{enumerate}
	\item $x$ et $y$ sont de signes contraires. Ces additions en sont des illustrations :
	\begin{centrage}\small
		\begin{tabular}{rr|r}
			&$7$&$20$\\
		+	&$-4$&$-45$\\\hline
			&$3$  &$-25$
		\end{tabular}\hskip0.1\linewidth
		\begin{tabular}{rr|r}
			&$2$&$70$\\
		+	&$-4$&$-15$\\\hline
			&$-2$  &$55$
		\end{tabular}
	\end{centrage}

	Dans ce cas, afin que $x$ et $y$ satisfassent les conditions du cas favorable, les modifications suivantes doivent y être apportées :
	
	\[\begin{cases}
	x\longleftarrow x-\left(\sigma_x1\right)\\
	y\longleftarrow y-\left(\sigma_y10^n\right)
	\end{cases}\]
	
	Les additions précédentes deviennent :
	\begin{centrage}\small
		\begin{tabular}{rr|r}
			&$7$&$20$\\
		+	&$-4$&$-45$\\\hline
			&$3$  &$-25$\\
			&$3-(1)$&$-25-(-100)$\\
		=	&$2$&$75$
		\end{tabular}\hskip0.1\linewidth
		\begin{tabular}{rr|r}
			&$2$&$70$\\
		+	&$-4$&$-15$\\\hline
			&$-2$  &$55$\\
			&$-2-(-1)$&$55-(100)$\\
		=	&$-1$&$-45$
		\end{tabular}
	\end{centrage}

	\item $x$ et $y$ sont de même signe \emph{et} $|y|\geqslant10^n$, comme dans ces additions :
	\begin{centrage}\small
		\begin{tabular}{rr|r}
			&$7$&$20$\\
		+	&$4$&$95$\\\hline
			&$11$  &$115$
		\end{tabular}\hskip0.1\linewidth
		\begin{tabular}{rr|r}
			&$-2$&$-70$\\
		+	&$-4$&$-65$\\\hline
			&$-6$  &$-135$
		\end{tabular}
	\end{centrage}
	Pour que $x$ et $y$ vérifient les conditions du cas favorable, leurs valeurs doivent être modifiées selon la règle suivante :
	
	\[\begin{cases}
	x\longleftarrow x+\left(\sigma_x1\right)\\
	y\longleftarrow y-\left(\sigma_y10^n\right)
	\end{cases}\]
	
	Les deux additions précédentes deviennent alors :
	\begin{centrage}\small
		\begin{tabular}{rr|r}
			&$7$&$20$\\
		+	&$4$&$95$\\\hline
			&$11$  &$115$\\
			&$11+(1)$&$115-(100)$\\
		=	&$12$&$15$
		\end{tabular}\hskip0.1\linewidth
		\begin{tabular}{rr|r}
			&$-2$&$-70$\\
		+	&$-4$&$-65$\\\hline
			&$-6$  &$-135$\\
			&$-6+(-1)$&$-135-(-100)$\\
		=	&$-7$&$-35$\\
		\end{tabular}
	\end{centrage}
\end{enumerate}

\section{Mise en \oe uvre}
\subsection{Rendre les nombres décimaux}
Dans un premier temps, la macro §\decadd doit s'assurer que les parties décimales sont bien présentes et le cas échéant, ajouter «\verb|.0|» comme partie décimale. Une fois ceci fait, elle passera la main à une macro auxiliaire \verb|\decadd@i|, à arguments délimités. La macro §\ifnodecpart, utilisée par §\formatnum, sera chargée de tester si le point est présent ou pas.

\showcode/\catcode`@11
\def\ifnodecpart#1{\ifnodecpart@i#1.\@nil}¤§*\ifnodecpart¤
\def\ifnodecpart@i#1.#2\@nil{\ifempty{#2}}¤§*\ifempty¤
\def\decadd#1#2{% #1 et #2=nombre à additionner¤§*\decadd¤
	\ifnodecpart{#1}% si #1 est un entier¤§*\ifnodecpart¤
		{\ifnodecpart{#2}% et #2 aussi, les additionner avec \numexpr¤§*\ifnodecpart¤
			{\number\numexpr#1+#2\relax}%¤\idx*\numexpr¤
			{\decadd@i#1.0\@nil#2\@nil}% sinon, ajouter ".0" après #1
		}
		{\ifnodecpart{#2}% si #1 a une partie entière mais pas #2¤§*\ifnodecpart¤
			{\decadd@i#1\@nil#2.0\@nil}% ajouter ".0" à #2
			{\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties entières sont présentes
		}%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{% affiche les parties entières et décimales reçues
	$x_a=#1\quad y_a=#2\qquad x_b=#3\quad y_b=#4$
}
\catcode`@12
a) \decadd{5}{9.4}\par
b) \decadd{-3.198}{-6.02}\par
c) \decadd{0.123}{123}¤§*\decadd¤/%
\def\olddecadd#1#2{% #1 et #2=nombre à additionner
	\ifnodecpart{#1}% si #1 est un entier¤§*\ifnodecpart¤
		{\ifnodecpart{#2}% et #2 aussi, les additionner avec \numexpr¤§*\ifnodecpart¤
			{\number\numexpr#1+#2\relax}%
			{\decadd@i#1.0\@nil#2\@nil}% sinon, ajouter ".0" après #1
		}
		{\ifnodecpart{#2}% si #1 a une partie entière mais pas #2¤§*\ifnodecpart¤
			{\decadd@i#1\@nil#2.0\@nil}% ajouter ".0" à #2
			{\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties entières sont présentes
		}%
}

\subsection{Rendre les parties décimales de même longueur}
Venons-en maintenant à la partie la plus complexe. Nous allons programmer la §\addzeros qui va se charger d'ajouter des 0 inutiles à la fin d'un des deux nombres \verb|#2| ou \verb|#4| reçus par \verb|\decadd@i| pour que ces parties décimales aient le même nombre de chiffres. Afin de rester purement développable, cette macro va utiliser le système des « arguments réservoirs ». Son texte de paramètre sera

\centrecode-#1#2/#3.#4#5/#6.#7/-

\noindent où :

\begin{itemize}
	\item \verb|#1| est le premier chiffre de $y_a$ et \verb|#2| les chiffres restants;
	\item \verb|#3| est le réservoir contenant les chiffres de $y_a$ déjà examinés;
	\item \verb|#4|, \verb|#5| et \verb|#6| jouent le même rôle pour $y_b$ que \verb|#1|, \verb|#2| et \verb|#3| pour $y_a$;
	\item \verb|#7| est un réservoir recevant le seuil de retenue : il contient 1 au début et un «\verb|0|» est ajouté à chaque itération.
\end{itemize}

L'idée directrice est que le point d'arrêt se produit lorsque les deux arguments délimités \verb|#2| et \verb|#5| sont vides. Dans le cas contraire, à chaque itération, \verb|#1| passe en fin de \verb|#3|, \verb|#4| passe en fin de \verb|#6| et un 0 est ajouté à \verb|#7|. Si un des arguments \verb|#2| ou \verb|#5| devient vide, il faut alimenter l'argument non délimité \verb|#1| ou \verb|#4| qui le précède avec 0.

Pour se représenter la situation, imaginons que les nombres $y_a=457$ et $y_b=689714$ soient traités par §\addzeros et que l'appel suivant ait été fait :

\centrecode-\addzeros457/.689714/.1-§*\addzeros

\noindent Le chiffre 4 et le chiffre 6 vont être transférés dans les réservoirs et un 0 sera ajouté après le 1. L'appel récursif après la première itération sera donc

\centrecode-\addzeros57/4.89714/6.10-

\noindent Puis le processus identique sera effectué et l'appel suivant sera

\centrecode-\addzeros7/45.9714/68.100-§*\addzeros

Comme il ne reste plus aucun chiffre après le 7 (ce qui signifie que l'argument délimité \verb|#2| est vide), le 7 sera transféré dans le réservoir, mais un 0 sera mis à sa place pour les appels suivants. Ces appels seront donc:

\begin{centrage}\small
	\verb|\addzeros0/457.714/689.1000|\par§*\addzeros
	\verb|\addzeros0/4570.14/6897.10000|\par
	\verb|\addzeros0/45700.4/68971.100000|§*\addzeros
\end{centrage}

Enfin, comme il ne reste plus de chiffre ni après $y_a$ ni après $y_b$, le \idx{point d'arrêt} est atteint : \verb|#2| et \verb|#5| sont vides. La macro transfère une dernière fois un 0 en fin de réservoir \verb|#3|, transfère aussi le 4 en fin de réservoir \verb|#5| et ajoute un dernier 0 au dernier argument pour mettre dans le flux de lecture de \TeX{} les trois arguments suivants :

\centrecode-{457000}{689714}{1000000}-

 Pour comprendre le cheminement des arguments, la macro affiche ici ce qu'elle fait :

\showcode|\def\addzeros#1#2/#3.#4#5/#6.#7/{%¤§*\addzeros¤
	Arguments reçus : #1#2/#3.#4#5/#6.#7/\par% afficher ce que la macro reçoit
	\ifempty{#2}% si #1 est le dernier chiffre de y¤§*\ifempty¤
		{\ifempty{#5}% et si #4 est le dernier chiffre de y2¤§*\ifempty¤
			{Résultat final : \detokenize{{#3#1}{#6#4}{#70}}}% afficher le résultat final
			{\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0
		}
		{\ifempty{#5}% si #4 est le dernier chiffre de y2¤§*\ifempty¤
			{\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
			{\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides
		}%
}
\addzeros457/.689714/.1/¤§*\addzeros¤|

\subsection{Additionner séparément}
Intéressons-nous tout d'abord à la macro qui va donner le signe du nombre décimal. Si $x$ est sa partie entière, la macro §\sgn, vue précédemment ne va pas convenir. Voici quel était son code :

\centrecode|\def\sgn#1{\ifnum#1<0 -\fi}|§*\sgn

Par exemple, si le décimal à examiner vaut $-0.123$, alors, la partie entière $x=-0$ et \verb|\sgn{-0}| ne revoit pas un signe négatif. Pour se prémunir de cette erreur, la macro §\true@sgn que nous allons employer renverra un signe «\verb|-|» lorsque son argument commence par «\verb|-|». Pour ce faire, elle se contente de tester le signe de son argument une fois lui avoir ajouté le chiffre 1 en dernière position :

\centrecode|\def\true@sgn#1{\ifnum#11<\z@-\fi}|\idx*\z@§*\true@sgn

Il faut rester conscient qu'ajouter le chiffre 1 au nombre \verb|#1| et évaluer le tout avec \verb|\ifnum| n'est pas anodin. Le résultat évalué par \verb|\ifnum|, qui est $\verb|#1|\times10\pm1$, doit être dans l'intervalle $I=[-2^{31}+1\;\string;\;2^{31}-1]$. Par conséquent, l'intervalle dans lequel doit se trouver \verb|#1| est plus étroit que $I$. Même si cet écueil n'est pas vraiment gênant, on aurait pu s'en prémunir en testant si \verb|#1| commence par «\verb|-|».

La macro \verb|\decadd@i| va utiliser le fait que \idx\romannumeral\verb|-`\@|, placé avant la macro §\addzeros, lance le développement maximal pour obtenir les trois arguments finaux. Elle appellera donc une nouvelle macro \verb|\decadd@ii|, admettant ces trois arguments auxquels nous rajouterons, en 4\ieme{} et 5\ieme{} arguments, les parties entières. La macro \verb|\decadd@ii|, qui reçoit ces 5 arguments, se contentera d'additionner les parties décimales entre elles (après avoir leur avoir ajouté le signe des parties entières) ainsi que les parties entières entre elles et transmettra le tout à la macro suivante \verb|\decadd@iii| :

\showcode|\catcode`\@11
\def\addzeros#1#2/#3.#4#5/#6.#7/{%¤§*\addzeros¤
	\ifempty{#2}% si #1 est le dernier chiffre de y1¤§*\ifempty¤
		{\ifempty{#5}% et si #4 est le dernier chiffre de y2¤§*\ifempty¤
			{{#3#1}{#6#4}{#70}}% redonner les 3 arguments
			{\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0
		}
		{\ifempty{#5}% si #4 est le dernier chiffre de y2¤§*\ifempty¤
			{\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
			{\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides
		}%
}
\def\decadd#1#2{% #1 et #2=nombre à additionner¤§*\decadd¤
	\ifnodecpart{#1}¤§*\ifnodecpart¤
		{\ifnodecpart{#2}{\number\numexpr#1+#2\relax}{\decadd@i#1.0\@nil#2\@nil}}
		{\ifnodecpart{#2}{\decadd@i#1\@nil#2.0\@nil}{\decadd@i#1\@nil#2\@nil}}%¤§*\ifnodecpart¤
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{%
	\expandafter\decadd@ii
			\romannumeral-`\0\addzeros#2/.#4/.1/% se développe en 3 arguments¤\idx*\romannumeral§*\addzeros¤
			{#1}
			{#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties décimales (mêmes longueurs);
% #3=seuil de retenue; #4 et #5=parties entières
	\exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel¤§*\exptwoargs¤
		% sommer les parties décimales signées
		{\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%¤\defline\aaa§*\true@sgn¤
		% et les parties entières
		{\number\numexpr#4+#5\relax}%
}
\def\decadd@iii#1#2#3{%
	seuil de retenue = #1 \qquad nombre = "#3"."#2"%
}
\catcode`\@12
a) \decadd{6.7}{3.498}\par
b) \decadd{1.67}{-4.9}\par
c) \decadd{3.95}{2.0005}\par
d) \decadd{1.007}{2.008}\par
e) \decadd{-7.123}{3.523}¤§*\decadd¤|

\subsection{Correctement gérer les 0}
Les deux derniers cas montrent que les 0 au début de la partie décimale sont supprimés par le \idx\number de la ligne \no\aaa{} tandis que les 0 inutiles de la fin sont conservés. C'est exactement le comportement inverse de celui qui est souhaité ! Afin de rétablir une partie décimale ayant des 0 là où il faut, nous devons écrire une macro

\centrecode-\format@dec{<partie décimale>}{<seuil de retenue>}-

\noindent qui est purement développable et qui supprime les 0 de droite tout en ajoutant les 0 de gauche.
\grandsaut

Si par exemple, on obtient une partie décimale égale à 710 avec un seuil de retenue de 100000, la partie décimale avait 5 chiffres, c'est-à-dire 00710 qui se doit être transformée en 0071. Pour parvenir à ses fins, la macro \verb|\format@dec| va d'abord ajouter le seuil de retenue à la valeur absolue de la partie décimale :

\[710+100000=100710\]

\noindent Elle va ensuite inverser le résultat avec §\reverse

\[017001\]

\noindent Puis soumettre le nombre obtenu à \idx\number ce qui aura pour effet de supprimer les 0 de début (qui étaient ceux de fin)

\[17001\]

\noindent Ensuite, il faut à nouveau inverser le résultat pour rétablir l'ordre de chiffres

\[10071\]

\noindent Enfin, il reste à manger le "1" en première position avec \verb|\gobone| pour obtenir $0071$. L'ordre des opérations est critique :

\showcode/\catcode`\@11
\def\format@dec#1#2{% #1=partie décimale #2=seuil de retenue
	\expandafter\gobone% le \gobone agira en dernier,
		\romannumeral-`\0% mais avant, tout développer¤\idx*\romannumeral¤
		\expandafter\reverse\expandafter% et retarder le \reverse de fin¤§*\reverse¤
			% pour développer son argument qui 
			{\number% développe tout et évalue avec \number
				\expandafter\reverse\expandafter% l'inversion de¤§*\reverse¤
				{\number\numexpr\abs{#1}+#2\relax}% |#1|+#2¤§*\abs¤
			}%
}
a) \format@dec{710}{100000}\par
b) \format@dec{6}{100}\par
c) \format@dec{-12300}{1000000}
\catcode`\@12/

\subsection{Calculer le résultat}
Reprenons notre chemin dans le texte de remplacement de \verb|\decadd@iii|. Elle doit effectuer les éventuelles modifications sur les parties entières et décimales selon que $x$ et $y$ sont de signes contraires et sinon, effectuer d'autres modifications si $|y|\geqslant10^n$. Ces tests ne présentent pas de difficulté et seront faits avec \tidx{ifnum}. À la toute fin, la macro \verb|\decadd@iv| reçoit 3 arguments de \verb|\decadd@iii|, la partie entière, la partie décimale et le seuil de retenue. Cette macro se chargera d'afficher \verb|#1|, et si \verb|#2| est différent de 0, le point décimal ainsi que la partie décimale formatée avec \verb|\format@dec|. Pour que le 2-développement de §\decadd donne le résultat, le développement maximal sera engagé via \idx\romannumeral début de la macro. Comme rien n'est dirigé vers l'affichage jusqu'à \verb|\decadd@iv|, ce développement sera en vigueur à l'entrée de cette macro. Il faut ensuite le propager pour qu'il atteigne \verb|\format@dec| avant que la partie entière ne soit affichée.

Voici le code complet :

\showcode|\catcode`@11
\def\true@sgn#1{\ifnum#11<\z@-\fi}¤\idx*\z@§*\true@sgn¤
\def\decadd#1#2{% #1 et #2=nombre à additionner¤§*\decadd¤
 	\romannumeral-`\.% tout développer jusqu'à l'affichage du nombre (\decadd@iv)
	\ifnodecpart{#1}% si #1 est un entier¤§\ifnodecpart¤
		{\ifnodecpart{#2}% et #2 aussi, les additionner avec \numexpr¤§*\ifnodecpart¤
			{\numexpr#1+#2\relax}%
			{\decadd@i#1.0\@nil#2\@nil}% sinon, ajouter ".0" après #1
		}
		{\ifnodecpart{#2}% si #1 a une partie entière mais pas #2¤§*\ifnodecpart¤
			{\decadd@i#1\@nil#2.0\@nil}% ajouter ".0" à #2
			{\decadd@i#1\@nil#2\@nil}% sinon, les 2 parties entières sont présentes
		}%
}
\def\decadd@i#1.#2\@nil#3.#4\@nil{%
	\expandafter\decadd@ii
			\romannumeral-`\0\addzeros#2/.#4/.10/% se développe en 3 arguments¤\idx*\romannumeral§*\addzeros¤
			{#1}
			{#3}%
}
\def\decadd@ii#1#2#3#4#5{%
% #1 et #2=parties décimales (mêmes longueurs)
% #3=seuil de retenue; #4 et #5=parties entières
	\exptwoargs{\decadd@iii{#3}}% envoyer le seuil de retenue tel quel¤§*\exptwoargs¤
		% sommer les parties décimales signées
		{\number\numexpr\true@sgn{#4}#1+\true@sgn{#5}#2\relax}%¤\defline\aaa§*\true@sgn¤
		% et les parties entières
		{\number\numexpr#4+#5\relax}%
}
\def\decadd@iii#1#2#3{% #1=seuil de retenue #2=partie décimale #3= partie entière
	\ifnum\true@sgn{#2}\true@sgn{\ifnum#3=\z@#2\else#3\fi}1=-1 % si les signes sont
	                                                           % différents¤\idx*\z@§*\true@sgn¤
	\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
		{\exptwoargs\decadd@iv% transmettre les arguments modifiés :¤§*\exptwoargs¤
			{\number\numexpr#3-\true@sgn{#3}1}% #3:=#3-sgn(#3)1¤\idx*\numexpr¤
			{\number\numexpr#2-\true@sgn{#2}#1}% #2:=#2-sgn(#2)10^n¤§*\true@sgn¤
			{#1}%
		}% si les signes sont égaux
		{\ifnum\abs{#2}<#1 % et si abs(y)<10^n¤§*\abs¤
		\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
			{\decadd@iv{#3}{#2}{#1}% tranmettre les arguments tels quels
			}
			{\exptwoargs\decadd@iv% sinon¤§*\exptwoargs¤
				{\number\numexpr#3+\true@sgn{#3}1}% #3:=#3+sgn(#3)1
				{\number\numexpr#2-\true@sgn{#2}#1}% #2:=#2-sgn(#2)10^n
				{#1}%
			}%
		}%
}
\def\decadd@iv#1#2#3{% affiche le décimal "#1.#2"
	% le développement maximal initié par le \romannumeral de \decadd est actif
	\ifnum#1=\z@\ifnum#2<\z@% si #1=0 et #2<0¤\idx*\z@¤
		\expandafter\expandafter\expandafter% transmettre le développement à \number
		-% puis afficher le signe "-"
	\fi\fi
	\number#1% affiche #1 qui est la somme des parties entières
	% poursuivre le développement initié par \number
	\unless\ifnum#2=\z@% si la partie décimale est différente de 0¤\tidx*{unless}¤
		\antefi% se débarrasser de \fi¤§*\antefi¤
		\expandafter.% afficher le "." décimal après avoir
		\romannumeral-`\0\format@dec{#2}{#3}% correctement géré les 0 de #2¤\idx*\romannumeral¤
	\fi
}
\def\addzeros#1#2/#3.#4#5/#6.#7/{%¤§*\addzeros¤
	\ifempty{#2}% si #1 est le dernier chiffre de y1¤§*\ifempty¤
		{\ifempty{#5}% et si #4 est le dernier chiffre de y2
			{{#3#1}{#6#4}{#7}}% redonner les 3 arguments
			{\addzeros0/#3#1.#5/#6#4.#70/}% sinon alimenter #1 avec un 0¤§*\addzeros¤
		}
		{\ifempty{#5}% si #4 est le dernier chiffre de y2¤§*\ifempty¤
			{\addzeros#2/#3#1.0/#6#4.#70/}% alimenter #4 avec un 0
			{\addzeros#2/#3#1.#5/#6#4.#70/}% #2 et #5 non vides¤§*\addzeros¤
		}%
}
\def\format@dec#1#2{% #1=partie décimale #2=seuil de retenue
	\expandafter\gobone% le \gobone agira en dernier,
		\romannumeral-`\0% mais avant, tout développer¤\idx*\romannumeral¤
		\expandafter\reverse\expandafter% et retarder le \reverse de fin¤§*\reverse¤
			% pour développer son argument qui 
			{\number% développe tout et évalue avec \number
				\expandafter\reverse\expandafter% l'inversion de¤§*\reverse¤
				{\number\numexpr\abs{#1}+#2\relax}% abs(#1)+#2¤§*\abs\idx*\z@¤
			}%
}
\catcode`@12
a) $-3.78+1.6987=\decadd{-3.78}{1.6987}$\par
b) $3.56-3.06=\decadd{3.56}{-3.06}$\par
c) $4.125+13.49=\decadd{4.125}{13.49}$\par
d) $-0.99+1.005=\decadd{-0.99}{1.005}$\par
e) $16.6-19.879=\decadd{16.6}{-19.879}$\par
f) $5.789-0.698=\decadd{5.789}{-0.698}$\par
g) $0.123-0.123=\decadd{0.123}{-0.123}$\par
h) $3.14-16.4912=\decadd{3.14}{-16.4912}$\par
i) $0.1-0.98=\decadd{0.1}{-0.98}$\par
j) $2.43+7.57=\decadd{2.43}{7.57}$\par
h) \edef\foo{\decadd{1.23}{9.78}}\meaning\foo\par
j) \detokenize\expandafter\expandafter\expandafter{\decadd{3.14}{-8.544}}¤§*\decadd¤|§*\decadd[|)]%

\chapter{Primitives spécifiques à un moteur}
Les nouvelles primitives introduites par \eTeX{} font désormais partie du vocabulaire reconnaissable par tous les moteurs (pdf\TeX, \XeTeX{} et lua\TeX).

Cette compatibilité est malheureusement cassée par des primitives \emph{spécifiques} aux moteurs, c'est-à-dire prises en charge par lui seul. On franchit là une ligne de démarcation importante pour la compatibilité puisqu'utiliser ces primitives rend obligatoire la compilation avec un moteur spécifique. Beaucoup de ces primitives spécifiques sont certes \emph{très} pratiques, mais il est utile de se demander si les fonctionnalités additionnelles qu'elles apportent valent une rupture de compatibilité.
\grandsaut

Il n'est évidemment pas question de décrire ici toutes les primitives spécifiques à tous les moteurs. Cela prendrait beaucoup de place (pdf\TeX{} en a plus de 130 !) pour un intérêt limité, car la plupart sont correspondent à un besoin très précis et sont d'une utilisation assez pointue. Les documentations des moteurs en dressent la liste exhaustive, en précisent la syntaxe et décrivent les fonctionnalités offertes. Nous nous contenterons de présenter deux primitives de pdf\TeX{}, moteur utilisé pour compiler le code source de ce livre.

Le lecteur pourra, s'il le souhaite, se plonger dans la documentation de son moteur préféré, explorer les primitives qu'il offre et pourquoi pas, les utiliser pour ses besoins propres. Il faut cependant garder à l'esprit que ces primitives imposant un moteur sont déconseillées si le code source a vocation à être diffusé et compilé par d'autres personnes non avisées de la rupture de compatibilité.

\section{Comparer deux textes avec \texttt{\char`\\ pdfstrcmp}}\idx*[|(]{comparer des textes}
La primitive purement développable \idx*\pdfstrcmp

\centrecode-\pdfstrcmp{<texte 1>}{<texte 2>}-

\noindent permet de comparer les deux textes. Avant qu'elle n'entre en jeu, cette primitive développe au maximum ses deux arguments et les détokenize. \emph{Elle ne tient donc pas compte des catcodes} contrairement au test \verb|\ifx| :

\centrecode-\def\foo{<texte 1>} \def\bar{<texte 2>}
\ifx\foo\bar<code vrai>\else<code faux>\fi-

La primitive \idx\pdfstrcmp se développe en «\verb|0|» si tes textes sont égaux, en «\verb|-1|» si le \verb|<texte 1>| vient avant le \verb|<texte 2>| et en «\verb|1|» s'il vient après. Le classement des  textes se fait en fonction des codes ASCII des caractères, pris successivement de gauche à droite jusqu'à ce qu'une différence apparaisse.

\showcode/a) \pdfstrcmp{foo}{bar}\qquad¤\idx*\pdfstrcmp¤
b) \pdfstrcmp{bar}{foo}\qquad
c) \def\foo{ABC}\pdfstrcmp{\foo}{ABC}\qquad
d) \edef\foo{\string_}\pdfstrcmp{1_2}{1\foo2}\qquad
e) \pdfstrcmp{\string\relax}{\relax}¤\idx*\string\idx*\pdfstrcmp¤/

La dernière comparaison est fausse, car «\idx\detokenize\verb|{\relax}|» se développe en \verb*|\relax | alors que \idx\string n'introduit pas d'espace après les séquences de contrôle. Les textes «\verb*|\relax |» et «\verb|\relax|» ne sont pas égaux.

Cette primitive dispose d'un équivalent pour le moteur \XeTeX{}\idx*{moteur!xetex}, mais elle ne porte pas le même nom : \verb|\strcmp|.\idx*[|)]{comparer des textes}

\section{Mesurer le temps}\idx*[|(]{chronométrer le temps d'exécution}
Voici un deuxième exemple de primitive spécifique à pdf\TeX{}, \idx\pdfelapsedtime qui permet de mesurer le temps de compilation. Cette primitive est de type entier et contient le nombre de secondes \emph{d'échelle} écoulées depuis le début de la compilation : 1 \idx{seconde d'échelle} vaut $\frac1{65536}$ de seconde tout comme un \idx{point d'échelle} vaut $\frac1{65536}$ de point. Convertir les secondes d'échelle en secondes revient à convertir les sp\idx*{sp (unité)} en pt\idx*{pt (unité)}, ce que permet très facilement la macro §\convertunit.

\showcode/\edef\tempcompil{\number\pdfelapsedtime}%¤\idx*\pdfelapsedtime¤
Depuis le début de la compilation, il s'est écoulé \tempcompil{} secondes d'échelle,¤\idx*{seconde d'échelle}¤
soit \convertunit{\tempcompil sp}{pt} secondes.¤§*\convertunit¤/

\Qu elle que soit la durée de compilation, l'entier \idx\pdfelapsedtime ne peut excéder $2^{31}-1$ qui sera sa limite supérieure et qui représente \numprint{32768} secondes.

La primitive \idx\pdfresettimer, qui remet à 0 le compteur interne de secondes d'échelle\idx*{seconde d'échelle}, ouvre des perspectives intéressantes. Couplée à \idx\pdfelapsedtime, elle permet de mesurer avec précision la durée qui s'écoule entre deux moments arbitraires de la compilation. Nous allons ici mettre à profit cette possibilité pour mesurer la vitesse relative entre la boucle \idx\loop...\idx\repeat (celle de \TeX{} puis celle de \LaTeX) et la boucle §\for, dont la programmation a été abordée à partir de la page \no\pageref{for}. Chaque boucle sera parcourue 100000 fois, mais, afin de mesurer la vitesse de la boucle elle-même, aucun code ne sera exécuté à chaque itération :

\showcode/%%%%%%%%%% definition de \loop...\repeat comme plain-TeX %%%%%%%%%%
\def\loop#1\repeat{\def\body{#1}\iterate}¤\idx*\loop\idx*\repeat¤
\def\iterate{\body \let\next\iterate \else\let\next\relax\fi \next}¤\idx*\iterate¤
\let\repeat=\fi¤\idx*\repeat¤
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcount\testcnt¤\idx*\newcount¤
\pdfresettimer% remet le compteur à 0¤\idx*\pdfresettimer¤
	\testcnt=0
	\loop % Test no 1¤\idx*\loop¤
		\ifnum\testcnt<100000 \advance\testcnt 1 ¤\idx*\advance¤
	\repeat¤\idx*\repeat¤
Temps 1 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \TeX)\par¤§*\convertunit\idx*\pdfelapsedtime¤
%%%%%%%%%%%% definition de \loop...\repeat comme LaTeX %%%%%%%%%%%%
\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%
  \iterate \let\iterate\relax}¤\idx*\iterate¤
\let\repeat\fi
\pdfresettimer% remet le compteur à 0¤\idx*\pdfresettimer¤
	\testcnt=0
	\loop % Test no 2¤\idx*\loop¤
		\ifnum\testcnt<100000
		\advance\testcnt 1 ¤\idx*\advance¤
	\repeat¤\idx*\repeat¤
Temps 2 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \LaTeX)\par¤§*\convertunit\idx*\pdfelapsedtime¤
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pdfresettimer% remet le compteur à 0
	\for\ii=1 to 100000\do{}% Test no 3¤§*\for¤
Temps 3 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle for)¤§*\convertunit\idx*\pdfelapsedtime¤/

Notre boucle §\for semble donc environ 3 fois plus lente que la boucle \idx\loop{}\linebreak[2]\verb|...|{}\linebreak[2]\idx\repeat de \LaTeX{} qui est la plus rapide. Il faut dire «\emph{semble}», car l'incrémentation ne se fait pas sur le même type de donnée. La boucle §\for incrémente le \emph{texte de remplacement} d'une macro tandis que dans le code ci-dessus, un \emph{compteur} est incrémenté dans la boucle \idx\loop...\idx\repeat. Pour être strictement équitable et pour être sûr de comparer les codes des deux boucles, la boucle \idx\loop...\idx\repeat doit imiter la boucle §\for et incrémenter le texte de remplacement d'une macro :

\showcode/%%%%%%%%%%%% definition de \loop...\repeat comme LaTeX %%%%%%%%%%%%
\def\loop#1\repeat{\def\iterate{#1\relax\expandafter\iterate\fi}%¤\idx*\loop¤
  \iterate \let\iterate\relax}¤\idx*\iterate¤
\let\repeat\fi¤\idx*\repeat¤
\pdfresettimer% remet le compteur à 0¤\idx*\pdfresettimer¤
	\def\ii{0}%
	\loop % Test no 1¤\idx*\loop¤
		\ifnum\ii<100000
		\edef\ii{\number\numexpr\ii+1\relax}%
	\repeat¤\idx*\repeat¤
Temps 1 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle loop de \LaTeX)\par¤§*\convertunit\idx*\pdfelapsedtime¤
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pdfresettimer% remet le compteur à 0¤\idx*\pdfresettimer¤
	\for\ii=1 to 100000\do{}% Test no 2¤§*\for¤
Temps 2 = \convertunit{\pdfelapsedtime sp}{pt} s (boucle for)¤§*\convertunit\idx*\pdfelapsedtime¤/

La différence de vitesse est maintenant plus ténue, de l'ordre de 30\%, ce qui semble une contrepartie acceptable en regard des fonctionnalités d'imbrication qu'offre §\for par rapport à \idx\loop...\idx\repeat. On en tire par ailleurs l'enseignement qu'incrémenter un compteur est \emph{plus rapide} que de recourir à \idx\numexpr et \idx\edef pour incrémenter un entier contenu dans le texte de remplacement d'une macro. En voici la démonstration :

\showcode/\newcount\testcnt¤\idx*\newcount¤
\pdfresettimer¤\idx*\pdfresettimer¤
\testcnt=0
\for\ii=1 to 100000\do{\advance\testcnt1 }¤§*\for¤
Temps 1 : \convertunit{\pdfelapsedtime sp}{pt} s (incrémentation compteur)¤§*\convertunit\idx*\pdfelapsedtime¤

\pdfresettimer¤\idx*\pdfresettimer¤
\def\foo{0}%
\for\ii=1 to 100000\do{\edef\foo{\number\numexpr\foo+1\relax}}%¤§*\for¤
Temps 2 : \convertunit{\pdfelapsedtime sp}{pt} s (incrémentation du texte de remplacement)¤§*\convertunit\idx*\pdfelapsedtime¤/

On peut ainsi comparer les vitesses entre les variantes d'un algorithme afin de trouver celle qui optimise la vitesse d'exécution.\idx*[|)]{chronométrer le temps d'exécution}

\chapter{Recueil des règles}\label{recapregle}
Les règles se trouvant dans les cadres grisés ont été assez nombreuses (il y en a exactement \number\csname cnt@regle\endcsname). Les voici rassemblées ici.
\makeatletter
\renewcommand\tidx@i[2][]{% #2 est le nom de la primitive SANS le caractère d'échappement
	\print@idx{\texttt{\char92 #2}}%
}
\makeatother
\input regles.txt
%|                                                                            |
%|                                Fin annexes                                 |
%|____________________________________________________________________________|
\chapter*{Bibliographie}
\addcontentsline{toc}{part}{Bibliographie}

\begin{enumerate}[leftmargin=*,itemsep=5pt,topsep=10pt]
	\item \textsc{D.E. Knuth}. Le \TeX book, Vuibert, 2003.\par
	{\footnotesize\verb|http://www.vuibert.fr/ouvrage-9782711748198-le-texbook.html|}
	\item \textsc{D.E. Knuth}. \TeX{} The Program.\par
	{\footnotesize\verb|http://tug.org/texlive/devsrc/Build/source/texk/web2c/tex.web|}
	\item \textsc{V. Eijkhout}. \TeX{} by Topic, Addison-Wesley, 1992.\par
	{\footnotesize\verb|http://www.eijkhout.net/texbytopic/texbytopic.html|}
	\item \textsc{P.W. Abrahams \& K. Hargreaves \& K. Berry}. \TeX{} pour l'impatient.\par
	{\footnotesize\verb|http://ctan.mirrorcatalogs.com/info/impatient/fr/fbook.pdf|}
	\item \textsc{J. Braams \& D. Carlisle \& A. Jeffrey \& L. Lamport \&\endgraf F.Mittelbach \&  C. Rowley \& R. Sch\"opf}. The \LaTeXe{} sources\par
	{\footnotesize\verb|http://www.tug.org/texlive/Contents/live/texmf-dist/doc/latex/base/source2e.pdf|}
	\item \textsc{E. Gregorio}. Appunti di programmazione in \LaTeX{} e \TeX.\par
	{\footnotesize\verb|http://profs.scienze.univr.it/~gregorio/introtex.pdf|}
\end{enumerate}

% ____________________________________________________________________________
%|                                                                            |
%|                                   Index                                    |
%|                                                                            |
\cidx*[|voiraussi{mode mathématique}]\$%
\cidx*[|voiraussi{\texttt{\char92 halign}}]\&%
\idx*[|voiraussi{\texttt{\char92 chardef}}]\&
\cidx*[|voiraussi{\texttt{\char92 catcode} $\rightsquigarrow$ 13}]\\
\idx*[|voir{\texttt{\char`\^\char`\^M}}]{retour charriot}%
\idx*[|voiraussi{\texttt{\char92 loop}}]\body
\idx*[|voiraussi{\texttt{\char92 catcode} $\rightsquigarrow$ 13}]{caractère actif}%
\idx*[|voiraussi{\texttt{\char92 hyphenchar}}]{caractère de coupure}%
\idx*[|voiraussi{\texttt{\char92 catcode} $\rightsquigarrow$ 0, «\texttt{\char92}»}]{caractère d'échappement}%
\idx*[|voiraussi{\texttt{\char92 endlinechar}, \texttt{\char92 newlinechar}}]{caractère de fin de ligne}%
\idx*[|voir{\texttt{\char92 catcode}}]{code de catégorie}
\idx*[|voiraussi{\texttt{\char92 uccode}, \texttt{\char92 uppercase}}]{code majuscule}
\idx*[|voiraussi{\texttt{\char92 lccode}, \texttt{\char92 lowercase}}]{code minuscule}
\idx*[|voiraussi{\texttt{\char92 edef}}]{code purement développable}
\idx*[|voiraussi{\texttt{\char92 /}}]{correction d'italique}
\idx*[|voiraussi{\texttt{\char92 vsplit}}]{couper une boite verticale}
\idx*[|voiraussi{\texttt{\char92 llap}, \texttt{\char92 rlap}, \texttt{\char92 hfuzz},\texttt{\char92 vfuzz}}]{débordement de boite}
\idx*[|voir{\texttt{\char92 moveleft}, \texttt{\char92 moveright}, \texttt{\char92 lower}, \texttt{\char92 raise}}]{déplacement de boite}
\idx*[|voiraussi{\texttt{\char92 edef}, \texttt{\char92 csname}, \texttt{\char92 romannumeral}, \texttt{\char92 write}, nombre $\rightsquigarrow$ définition}]{développement maximal}
\idx*[|voiraussi{\texttt{\char92 fontdimen}}]{dimensions de fonte}
\idx*[|voiraussi{\texttt{\char92 long}, \texttt{\char92 par}}]\endgraf
\idx*[|voir{compteur, nombre}]{entier}
\idx*[|voiraussi{\texttt{\char`\^\char`\^J}}]{fin de ligne}%
\idx*[|voir{macro fille}]{imbrication de macros}
\idx*[|voiraussi{\texttt{\char92 write}, \texttt{\char92 openout}}]{\immediate}%
\idx*[|voir{\texttt{\char92 loop}}]{\iterate}%
\idx*[|voir{\texttt{\char92 loop}, \texttt{\char92 for}$^\star$, \texttt{\char92 doforeach}$^\star$}]{boucle}
\idx*[|voir{«\texttt{\char`@}»}]{macro privée}
\idx*[|voiraussi{boite $\rightsquigarrow$ géométrie}]{point de référence}
\idx*[|voiraussi{sp (unité)}]{point d'échelle}
\index{registre!entier|voir{compteur}}
\idx*[|voir{\texttt{\char92 meaning}, \texttt{\char92 show}}]{signification d'un token}
\idx*[|voir{\texttt{\char`\^\char`\^J}}]{tabulation}%
\idx*[|voiraussi{\texttt{\char92 relax} $\rightsquigarrow$ spécial}]{test incomplet}%
\idx*[|voiraussi{\texttt{\char92 litterate}$^\star$}]{verbatim}%
\idx*[|voiraussi{\texttt{\char92 let}}]{caractère implicite}%
\cidx*[ (notation hexadécimale)|voiraussi{nombre $\rightsquigarrow$ définition}]\"
\cidx*[ (notation octale)|voiraussi{nombre $\rightsquigarrow$ définition}]\'
\makeatletter
\idx*[|voiraussi{\texttt{\char92 input}}]\@@input
\makeatother
\cidx*[ (notation octale)|voiraussi{nombre $\rightsquigarrow$ définition}]\`
\idx*[!implicite|voiraussi{\texttt{\char92 bgroup}, \texttt{\char92 egroup}}]{accolade}
\idx*[|voiraussi{\texttt{\char92 hbadness}, \texttt{\char92 vbadness}}]{boite insuffisamment remplie}


\indexprologue{L'index ci-dessous liste les commandes et les notions abordées dans le livre. Les commandes, qu'elles soient primitives ou macros, sont classées alphabétiquement sans tenir compte du caractère d'échappement «\texttt{\char`\\}». Les commandes précédées d'une étoile sont des primitives.

Certaines séquences de contrôle ont été très fréquemment employées dans les codes exposés dans ce livre. On trouve par exemple \texttt{\char`\\def}, \texttt{\char`\\expandafter}, \texttt{\char`\\catcode}, etc. Afin de ne pas inutilement surcharger l'index, seuls les numéros de pages des premières apparitions ont été retenus. Ils sont suivis par « \ldots » qui symbolise les nombreux autres numéros de page qui ont été omis.

Lorsqu'un renvoi « \textit{voir} » à une macro définie dans ce livre figure dans cet index, cette macro est suivie de «$^\star$». L'index des macros définies dans ce livre se trouve à la page~\pageref{index.macros}.\par
}
\def\indexspace{\vskip 18pt plus 7pt minus 4pt \relax}
\small
\printindex

\normalsize
\indexprologue{\label{index.macros}L'index ci-dessous liste les macros définies dans ce livre. Toutes n'y figurent pas. À de rares exceptions près, seules les macros \emph{publiques}, c'est-à-dire sans «\verb|@|», y figurent.\par
}
\small
\printindex[macros]%

\normalsize
%|                                                                            |
%|                                 Fin index                                  |
%|____________________________________________________________________________|
\immediate\closeout\codewrite
\cleardoublepage\pagestyle{empty}\null\newpage
\null\vfill
\begin{centrage}
	\footnotesize
	Christian \textsc{Tellechea}
	
	---
	
	Dépôt légal: septembre 2014
\end{centrage}%
\null
\vskip1cm\null
\end{document}