summaryrefslogtreecommitdiff
path: root/web/spiderweb/doc/spiderwebman.tex
blob: c512983ee14d4da03dd7cd7bf8a8793876bc350a (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
% Copyright 1989 by Norman Ramsey, Odyssey Research Associates
% Not to be sold, but may be used freely for any purpose
% For more information, see file COPYRIGHT in the parent directory

\input webkernel % rank bravery; was webmac

% macros for itemized lists
\newcount\level
\level=0

\def\enum#1{\ifcase\the#1 x\or i\or ii\or iii\else iv\fi}
\def\setenum{\edef\theenum{\csname enum\enum\level\endcsname}}


\def\itemize{\begingroup\advance\level by1
    \def\item{\par\noindent
         \raise2pt\llap{$\scriptstyle\bullet$\ }}%
         \par\advance\leftskip by2em\advance\rightskip by2em}
\def\enditemize{\par\endgroup\noindent\ignorespaces}
% end of stuff for itemized lists

\parskip 0pt plus 1pt
\def\RA{\char'31 } % right arrow
\def\hang{\hangindent 4em\ignorespaces}
\font\ninerm=cmr9
\font\ninett=cmtt9
\font\eighttt=cmtt8
\let\mc=\ninerm % medium caps for names like SAIL
\def\PASCAL{\newstuff ``X''\endnewstuff}
\def\PAS{\newstuff X\endnewstuff} % used to mark file extensions
\def\oP{{\sl \overline X}} % used in table of control sequences
\font\quoterm=cmssq8
\font\quoteit=cmssqi8
\def\pb{\.{|...|}}
\def\lpile{\def\cr{\hfill\endline}\matrix} % I only use \lpile by
					   % itself

\def\newstuff{\begingroup\sl}
\def\endnewstuff{\endgroup}

\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
  \noindent{\bf #1.}\quad\ignorespaces}

\def\titlepage{T}
\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
\def\runninghead{SPIDERY {\tentt WEB} USER MANUAL}

% This verbatim mode assumed that no ? appears in the text being copied.
\def\verbatim{\begingroup
  \def\do##1{\catcode`##1=12 } \dospecials
  \parskip 0pt \parindent 0pt
  \catcode`\ =13 \catcode`\^^M=13
  \tt \catcode`\?=0 \verbatimdefs \verbatimgobble}
{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }} %
  \gdef\verbatimgobble#1^^M{}}

\centerline{\titlefont The Spidery {\ttitlefont WEB} System
  of Structured Documentation}

\vskip 15pt plus 3pt minus 3pt
\noindent
\newstuff
This memo describes how to write programs in the \.{WEB} language,
using \.{WEB} systems generated by {Spider}.
This class of \.{WEB} systems will be referred to (collectively) as
``Spidery \.{WEB}.''
Most of the material is taken verbatim from Donald Knuth's original
memo introducing \.{WEB}; new material (like this paragraph) appears
in slant type.
Knuth's original memo is available as Stanford University CS technical
 report number 980 (September 1983).
Unlike Knuth's, this memo is not accompanied by the full \.{WEB}
documentation for Spidery \.{WEAVE} and \.{TANGLE}, the programs that
read \.{WEB} input and produce {\TeX} output and code, respectively.
Nor does it contain the \.{WEB} documentation for {Spider}, the program that
 generates the
language-dependent parts of \.{WEAVE} and \.{TANGLE}.
This memo should be accompanied by ``A {Spider} User's Guide,'' which
explains how to use {Spider} to build a Spidery \.{WEB} system.
\endnewstuff

The philosophy behind \.{WEB} is
that an experienced system programmer, who wants to provide the best
possible documentation of his or her software products, needs two things
simultaneously:  a language like \TeX\ for formatting, and a language
for programming.
\newstuff For convenience, we'll give this programming language a
name; let's call it the \PASCAL\ programming language.
\endnewstuff
Neither type of language can provide the best 
documentation by itself; but when both are appropriately combined, we
obtain a system that is much more useful than either language
separately.


The structure of a software program may be thought of as a ``web'' that is
made up of many interconnected pieces.
To document such a program, we want
to explain each individual part of the web and how it relates to its
neighbors.
The typographic tools provided by \TeX\ give us an opportunity
to explain the local structure of each part by making that structure
visible, and the programming tools provided by \PASCAL\ make it possible
for us to specify the algorithms formally and unambiguously.
By combining
the two, we can develop a style of programming that maximizes our ability
to perceive the structure of a complex piece of software, and at the same
time the documented programs can be mechanically translated into a working
software system that matches the documentation.

Since \.{WEB} is an experimental system developed for internal use within
the \TeX\ project at Stanford, this report is rather terse, and it assumes
that the reader is an experienced programmer who is highly motivated to
read a detailed description of \.{WEB}'s rules.
{\newstuff Spidery \.{WEB} is also an experimental system and
the same warning applies.\endnewstuff}
\newstuff
Before continuing, you may want to read some more introductory
material on {Spider} and \.{WEB}.
Here are some references worth looking at:
\itemize
\rm
\item Donald E. Knuth, ``Literate Programming,'' {\sl Computer
Journal} {\bf 27:2} (1984), 97--111..
The original introduction of \.{WEB}.
\item Jon L. Bentley, ``Programming Pearls,'' {\sl Communications of
the ACM} {\bf 29:5} (May 1986), 364--368 and
{\bf 29:6} (June 1986), 471--483.
Two columns on literate programming with \.{WEB}.
\item Norman Ramsey, ``Building a Language-Independent \.{WEB},'' 
{\sl Communications of the ACM}, September 1989.
An overview of how {Spider} and \.{WEB} work.
\item
Wayne Sewell, ``Weaving a program: Literate programming in \.{WEB},''
Van Nostrand Reinhold, 1989.
\enditemize
In addition to these, there is a periodic column in the {\sl
Communications of the ACM} devoted to literate programming.
\endnewstuff

Even if a
less terse manual were to be written, the reader would have to be warned
in advance that \.{WEB} is not for beginners and it never will be: The
user of \.{WEB} must be familiar with both \TeX\ and \PASCAL.
When one
writes a \.{WEB} description of a software system, it is possible to make
mistakes by breaking the rules of \.{WEB} and/or the rules of \TeX\ and/or
the rules of \PASCAL.
In practice, all three types of errors will occur,
and you will get different error messages from the different language
processors.
In compensation for the sophisticated expertise needed to cope
with such a variety of languages, however, experience has shown that
reliable software can be created quite rapidly by working entirely in
\.{WEB} from the beginning; and the documentation of such programs seems
to be better than the documentation obtained by any other known method.
Thus, \.{WEB} users need to be highly qualified, but they can get some
satisfaction and perhaps even a special feeling of accomplishment when
they have successfully created a software system with this method.

To use \.{WEB}, you prepare a file called \.{COB.WEB} (say), and then you
apply a system program called \.{WEAVE} to this file, obtaining an output
file called \.{COB.TEX}.
When \TeX\ processes \.{COB.TEX}, your output
will be a ``pretty printed'' version of \.{COB.WEB} that takes appropriate
care of typographic details like page layout and the use of indentation,
italics, boldface, etc.; this output will contain extensive cross-index
information that is gathered automatically.
You can also submit the same
file \.{COB.WEB} to another system program called \.{TANGLE}, which will
produce a file \.{COB.\PAS} that contains the \PASCAL\ code of your \.{COB}
program.
The \PASCAL\ compiler will convert \.{COB.\PAS} into
machine-language instructions corresponding to the algorithms that were so
nicely formatted by \.{WEAVE} and \TeX.
Finally, you can (and should)
delete the files \.{COB.TEX} and \.{COB.\PAS}, because \.{COB.WEB} contains
the definitive source code.
Examples of the behavior of \.{WEAVE} and
\.{TANGLE} are 
\newstuff
not
\endnewstuff
appended to this manual.
\newstuff
The names {\tt WEAVE} and \.{TANGLE} may vary, especially since there
may be versions for multiple languages.
My site supports, in addition to the original \.{TANGLE},
\.{CEETANGLE}, \.{AWKTANGLE}, and \.{ADATANGLE}.
\endnewstuff

Besides providing a documentation tool, \.{WEB} enhances the \PASCAL\
language by providing a 
%rudimentary
 macro capability together with the
ability to permute pieces of the program text, so that a large system can
be understood entirely in terms of small modules and their local
interrelationships.
The \.{TANGLE} program is so named because it takes a
given web and moves the modules from their web structure into the order
required by \PASCAL; the advantage of programming in \.{WEB} is that the
algorithms can be expressed in ``untangled'' form, with each module
explained separately.
The \.{WEAVE} program is so named because it takes
a given web and intertwines the \TeX\ and \PASCAL\ portions contained in
each module, then it knits the whole fabric into a structured document.
(Get it? Wow.)  
Perhaps there is some deep connection here with the fact
that the German word for ``weave'' is ``{\it web\/}'', and the
corresponding Latin imperative is ``{\it texe\/}''!

It is impossible to list all of the related work that has influenced the
design of \.{WEB}, but the key contributions should be mentioned
here.\quad (1)~Myrtle Kellington, as executive editor for ACM
publications, developed excellent typographic standards for the
typesetting of Algol programs during the 1960s, based on the original
designs of Peter Naur; the subtlety and quality of this influential work
can be appreciated only by people who have seen what happens when other
printers try to typeset Algol without the advice of ACM's copy
editors.\quad(2)~Bill McKeeman introduced a program intended to automate
some of this task [Algorithm 268, ``Algol~60 reference language editor,''
{\sl CACM \bf8} (1965), 667--668]; and a considerable flowering of such
programs has occurred in recent years [see especially Derek Oppen,
``Prettyprinting,'' {\sl ACM TOPLAS \bf2} (1980), 465--483; G.~A.
Rose and
J.
Welsh, ``Formatted programming languages,'' {\sl SOFTWARE Practice
\char`\&\ Exper.\ \bf11} (1981), 651--669].\quad(3)~The top-down style of
exposition encouraged by \.{WEB} was of course chiefly influenced by Edsger
Dijkstra's essays on structured programming in the late 1960s.
The less
well known work of Pierre-Arnoul de Marneffe [``Holon programming: A
survey,'' Univ.\ de Liege, Service Informatique, Liege, Belgium, 1973; 135
pp.\null] also had a significant influence on the author as \.{WEB} was
being formulated.\quad(4)~Edwin Towster has proposed a similar style of
documentation in which the programmer is supposed to specify the relevant
data structure environment in the name of each submodule [``A convention
for explicit declaration of environments and top-down refinement of
data,'' {\sl IEEE Trans.\ on Software Eng.\ \bf SE--5} (1979), 374--386];
this requirement seems to make the documentation a bit too verbose,
although experience with \.{WEB} has shown that any unusual control
structure or data structure should definitely be incorporated into the
module names on psychological grounds.\quad(5)~Discussions with Luis
Trabb~Pardo in the spring of 1979 were extremely helpful for setting up a
prototype version of \.{WEB} that was called \.{DOC}.\quad (6)~Ignacio
Zabala's extensive experience with \.{DOC}, in which he created a full
implementation of \TeX\ in {Pascal} that was successfully transported to
many different computers, was of immense value while \.{WEB} was taking
its present form.\quad(7)~David~R.
Fuchs made several crucial suggestions
about how to make \.{WEB} more portable; he and Arthur~L.
Samuel
coordinated the initial installations of \.{WEB} on dozens of computer
systems, making changes to the code so that it would be acceptable to
a wide variety of \.{Pascal} compilers.\quad(8)~The name \.{WEB} itself
was chosen in honor of my wife's mother, Wilda Ernestine Bates.

\newstuff
The work on Spidery \.{WEB} would not have been possible without the
help of Silvio Levy, who first ported \.{WEB} to C.
The name {Spider} was chosen because (in nature at least) webs are
built by spiders.
\endnewstuff

The appendices to this report 
\newstuff
do not
\endnewstuff
contain complete \.{WEB} programs for the
\newstuff {Spider}, \endnewstuff
\.{WEAVE}, and \.{TANGLE} processors.
A study of these examples, together
with an attempt to write \.{WEB} programs by yourself, is the best way
to understand why \.{WEB} has come to be like it is.

\section General rules.
A \.{WEB} file is a long string of text that has been divided into
individual lines.
\newstuff
Unlike original {\tt WEB}, Spidery {\tt WEB} respects the programmer's
choice of line breaks.
A newline in code is normally passed along through tangle and will
appear in the resulting program.
This is important in languages like awk where line breaks are
significant.
In documentation, 
\endnewstuff
the exact line boundaries are not terribly crucial, and
a programmer can pretty much chop up the \.{WEB} file in whatever way seems
to look best as the file is being edited; but string constants and control
texts must end on the same line on which they begin, since this convention
helps to keep errors from propagating.
\newstuff
The line length of the input is limited and is rather small.
\endnewstuff
% The end of a line means
% the same thing as a blank space.

Two kinds of material go into \.{WEB} files: \TeX\ text and \PASCAL\ text.
A programmer writing in \.{WEB} should be thinking both of the
documentation and of the \PASCAL\ program that he or she is creating;
i.e., the programmer should be instinctively aware of the different
actions that \.{WEAVE} and \.{TANGLE} will perform on the \.{WEB} file.
\TeX\ text is essentially copied without change by \.{WEAVE}, and it is
entirely deleted by \.{TANGLE}, since the \TeX\ text is ``pure
documentation.'' 
\PASCAL\ text, on the other hand, is formatted by
\.{WEAVE} and it is shuffled around by \.{TANGLE}, according to rules that
will become clear later.
For now the important point to keep in mind is
that there are two kinds of text.
Writing \.{WEB} programs is something
like writing \TeX\ documents, but with an additional ``\PAS\ mode''
that is added to \TeX's horizontal mode, vertical mode, and math mode.

A \.{WEB} file is built up from units called {\sl modules\/} that are more
or less self-contained.
Each module has three parts:

\yskip\item{1)} A \TeX\ part, containing explanatory material about what
is going on in the module.

\item{2)} A definition part, containing macro definitions that serve as
abbreviations for \PASCAL\ constructions that would be less comprehensible
if written out in full each time.

\item{3)} An \PASCAL\ part, containing a piece of the program that
\.{TANGLE} will produce.
This \PASCAL\ code should ideally be about a
dozen lines long, so that it is easily comprehensible as a unit and so
that its structure is readily perceived.

\yskip\noindent The three parts of each module must appear in this order;
i.e., the \TeX\ commentary must come first, then the definitions, and
finally the \PASCAL\ code.
Any of the parts may be empty.

A module begins with the pair of symbols `\.{@\ }' or `\.{@*}', where
`\.{\ }' denotes a blank space.
A module ends
at the beginning of the next module (i.e., at the next
`\.{@\ }' or `\.{@*}'), or at the end of the file, whichever comes first.
The \.{WEB} file may also contain material that is not part of any module
at all, namely the text (if any) that occurs before the first module.
Such text is said to be ``in limbo''; it is ignored by \.{TANGLE}
and copied essentially verbatim by \.{WEAVE}, so its function is to
provide any additional formatting instructions that may be desired in the
\TeX\ output.
Indeed, it is customary to begin a \.{WEB} file with
\TeX\ code in limbo that loads special fonts, defines special macros,
changes the page sizes, and/or produces a title page.

Modules are numbered consecutively, starting with 1; these numbers appear
at the beginning of each module of the \TeX\ documentation, and they appear
as bracketed comments at the beginning of the code generated by that
module in the \PASCAL\ program.

Fortunately, you never mention these numbers yourself when you are writing
in \.{WEB}.
You just say `\.{@\ }' or `\.{@*}' at the beginning of each
new module, and the numbers are supplied automatically by \.{WEAVE} and
\.{TANGLE}.
As far as you are concerned, a module has a
name instead of a number; such a name is specified by writing
`\.{@<}' followed by \TeX\ text followed by `\.{@>}'.
When \.{WEAVE}
outputs a module name, it replaces the `\.{@<}' and `\.{@>}' by
angle brackets and inserts the module number in small type.
Thus, when you
read the output of \.{WEAVE} it is easy to locate any module that is
referred to in another module.

\newstuff
Spidery {\tt WEB} supports a new kind of module called a ``file
module.''
File modules open with \.{@(} instead of \.{@<}, and the module name
 is taken to be the name of a file to which \.{TANGLE} will write the
contents of the module.
When \.{WEAVE}
outputs a file module name, it replaces the `\.{@(}' and `\.{@>}' by
parentheses and sets the entire name in {\tt typewriter} font.
\endnewstuff


For expository purposes, a module name should be a good description of the
contents of that module, i.e., it should stand for the abstraction
represented by the module; then the module can be ``plugged into'' one or
more other modules so that the unimportant details of its inner workings
are suppressed.
A module name therefore ought to be long enough to convey
the necessary meaning.
Unfortunately, however, it is laborious to type
such long names over and over again, and it is also difficult to specify a
long name twice in exactly the same way so that \.{WEAVE} and \.{TANGLE}
will be able to match the names to the modules.
Therefore a module name
can be abbreviated after its first appearance in the \.{WEB} file, by
typing `\.{@<$\alpha$...@>}', where $\alpha$ is any string that is a prefix of
exactly one module name that appears in the file.
For example, `\.{@<Clear
the arrays@>}' can be abbreviated to `\.{@<Clear...@>}' if no other module
name begins with the five letters `\.{Clear}'.
Module names must otherwise
match character for character, except that consecutive blank spaces and/or
tab marks are treated as equivalent to single spaces, and such spaces are
deleted at the beginning and end of the name.
Thus, `\.{@< Clear { }the
arrays @>}' will also match the name in the previous example.

We have said that a module begins with `\.{@\ }' or `\.{@*}', but we
didn't say how it gets divided up into a \TeX\ part, a definition part,
and an \PASCAL\ part.
The definition part begins with the first appearance
of `\.{@d}' or `\.{@f}' in the module, and the \PASCAL\ part begins with
the first appearance of `\.{@u}', `\.{@<}', 
\newstuff or `\.{@(}'.\endnewstuff
The 
%latter
 options `\.{@<}' \newstuff and `\.{@(}'.\endnewstuff
stand for the beginning of a module name, which is the name of the module
itself.
An equals sign (\.=) must follow the `\.{@>}' at the end of this
module name; you are saying, in effect, that the module name stands for
the \PASCAL\ text that follows, so you say `$\langle\,$module
name$\,\rangle=\null$\PASCAL\ text'.
Alternatively, if the \PASCAL\ part
begins with `\.{@u}' instead of a module name, the current module is said
to be {\sl unnamed}.
Note that module names cannot appear in the
definition part of a module, because the first `\.{@<}' \newstuff or
`\.{@(}'.\endnewstuff in a module
signals the beginning of its \PASCAL\ part.
Any number of module names
might appear in the \PASCAL\ part, however, once it has started.

The general idea of \.{TANGLE} is to make an \PASCAL\ program out of these
modules in the following way: First all the \PASCAL\ parts of unnamed
modules are copied down, in order; this constitutes the initial
approximation $T_0$ to the text of the program.
(There should be at least
one unnamed module, otherwise 
\newstuff unless there are file modules \endnewstuff
there will be no program.) Then all module
names that appear in the initial text $T_0$ are replaced by the \PASCAL\
parts of the corresponding modules, and this substitution process
continues until no module names remain.
Then all defined macros are
replaced by their equivalents, according to certain rules that are
explained later.
%The resulting \PASCAL\ code is ``sanitized'' so that it
%will be acceptable to an average garden-variety \PASCAL\ compiler; i.e.,
%lowercase letters are converted to uppercase, long identifiers are
%chopped, and the lines of the output file are constrained to be at most 72
%characters long.
All comments will have been removed from this \PASCAL\
program except for the meta-comments delimited by `\.{@\{}' and
`\.{@\}}', as explained below, and except for the module-number comments
that point to the source location where each piece of the program text
originated in the \.{WEB} file.
\newstuff
Spidery {\tt WEB} does not support the use of the meta-comments 
 `\.{@\{}' and `\.{@\}}'.
Their absence can be partially compensated for by clever use of the
``verbatim'' control sequence `\.{@=...@>}'.
\endnewstuff

Incidentally, module numbers are automatically inserted
as meta-comments into the \PASCAL\ program, in order to help correlate the
outputs of \.{WEAVE} and \.{TANGLE} (see Appendix~C\null).
\newstuff So are {\tt\#line} directives, the exact workings of which
are obscure (but see the ``{Spider} User's Guide'' for more information).
\endnewstuff

If the same name has been given to more than one module, the \PASCAL\ text
for that name is obtained by putting together all of the \PASCAL\ parts in
the corresponding modules.
This feature is useful, for example, in a
module named `Global variables in the outer block', since one can then
declare global variables in whatever modules those variables are
introduced.
When several modules have the same name, \.{WEAVE} assigns the
first module number as the number corresponding to that name, and it
inserts a note at the bottom of that module telling the reader to `See
also sections so-and-so'; this footnote gives the numbers of all the other
modules having the same name as the present one.
The \PASCAL\ text
corresponding to a module is usually formatted by \.{WEAVE} so that the
output has an equivalence sign in place of the equals sign in the \.{WEB}
file; i.e., the output says `$\langle\,$module
name$\,\rangle\equiv\null$\PASCAL\ text'.
However, in the case of the second
and subsequent appearances of a module with the same name, this `$\equiv$'
sign is replaced by `$\mathrel+\equiv$', as an indication that the \PASCAL\
text that follows is being appended to the \PASCAL\ text of another
module.


The general idea of \.{WEAVE} is to make a \.{TEX} file from the \.{WEB}
file in the following way: The first line of the \.{TEX} file will be
`\.{\\input \PAS web}'; this will cause \TeX\ to read in the macros that
define \.{WEB}'s documentation conventions
\newstuff 
for the \PASCAL\ programming language.
\endnewstuff
The next lines of the file
will be copied from whatever \TeX\ text is in limbo before the first
module.
Then comes the output for each module in turn, possibly
interspersed with end-of-page marks.
Finally, \.{WEAVE} will generate a
cross-reference index that lists each module number in which each \PASCAL\
identifier appears, and it will also generate an alphabetized list
of the module names, as well as a table of contents that
shows the page and module numbers for each ``starred'' module.

What is a ``starred'' module, you ask?
A module that begins with `\.{@*}'
instead of `\.{@\ }' is slightly special in that it denotes a new major
group of modules.
The `\.{@*}' should be followed by the title of this
group, followed by a period.
Such modules will always start on a new page
in the \TeX\ output, and the group title will appear as a running headline
on all subsequent pages until the next starred module.
The title will also
appear in the table of contents, and in boldface type at the beginning of
its module.

\newstuff
Spidery {\tt WEB} supports a hack that makes the module structure
appear more hierarchical in the table of contents.
If the title begins with the special character {\tt =}, or one of the
digits {\tt 1}~through~{\tt 4}, it will be formatted specially.
This table shows the effect of the special titles:
\medskip
{
\tabskip=0pt plus 1fil
\noindent\halign to \hsize{\strut\tt#\hfil
\tabskip=2em&#\hfil&\hfil #\hfil&#\hfil\tabskip=0pt plus 1fil\cr
\bf Marker&\bf Level&\bf Page Eject?&\bf Other\cr
\noalign{\smallskip}
@*=&chapter&yes&Bold in toc\cr
@*&section&yes\cr
@*1&subsection&yes\cr
@*2&subsection&no\cr
@*3&subsubsection&yes\cr
@*4&subsubsection&no\cr
}
}
\medskip
\endnewstuff

Caution:  Do not use \TeX\ control sequences in such titles,
unless you know that the \.{webmac} macros will do the right thing with
them.
The reason is that these titles are converted to uppercase when
they appear as running heads, and they are converted to boldface when they
appear at the beginning of their modules, and they are also written out to
a table-of-contents file used for temporary storage while \TeX\ is
working; whatever control sequences you use must be meaningful in all
three of these modes.

\newstuff
Second caution:
do not allow the titles to begin with a non-letter, unless the
non-letter is the control sequence \.{\\relax}.
The reason is that the first character of the titles is checked to see
whether it is the special character {\tt =}, or one of the
digits {\tt 1}~through~{\tt 4}.
A non-letter that is not one of these will only confuse the formatter.
\endnewstuff

The \TeX\ output produced by \.{WEAVE} for each module consists of
the following: First comes the module number (e.g., `\.{\\M123.}'
at the beginning of module 123, except that `\.{\\N}' appears in place of
`\.{\\M}' at the beginning of a starred module).
Then comes the
\TeX\ part of the module, copied almost verbatim except as noted
below.
Then comes the definition part and the \PASCAL\ part, formatted
so that there will be a little extra space between them if both are
nonempty.
The definition and \PASCAL\ parts are obtained by inserting
a bunch of funny looking \TeX\ macros into the \PASCAL\ program; these
macros handle typographic details about fonts and proper math spacing,
as well as line breaks and indentation.

When you are typing \TeX\ text, you will probably want to make frequent
reference to variables and other quantities in your \PASCAL\ code, and you
will want those variables to have the same typographic treatment
when they appear in your text as when they appear in your
program.
Therefore the \.{WEB} language allows you to get the effect of
\PASCAL\ editing within \TeX\ text, if you place `\.|' marks before and
after the \PASCAL\ material.
For example, suppose 
\newstuff
you are writing Pascal code and
\endnewstuff
you want to say something
like this:
$$\hbox{The characters are placed into \\{buffer}, which is a
\&{packed} \&{array} $[1\to\|n]$ \&{of} \\{char}.}$$
The \TeX\ text would look like this in your \.{WEB} file:
$$\.{The characters are placed into |buffer|, which is a |packed
array [1..n] of char|.}$$
And \.{WEAVE} translates this into something you are glad you didn't have
to type:
$$\lpile{\.{The characters are placed into \\\\\{buffer\},}\cr
  \.{which is a \\\&\{packed\}{ }\\\&\{array\}{ }\$
    [1\\to\\|n]\${ }\\\&\{of\}{ }\\\\\{char\}.}\cr}$$
Incidentally, the cross-reference index that \.{WEAVE} would make, in
the presence of a comment like this, would include
the current module number as one of the index entries for \\{buffer}
and \\{char}, even though \\{buffer} and \\{char}
might not appear in the \PASCAL\ part of
this module.
Thus, the index covers references to identifiers in
the explanatory comments as well as in the program itself; you will
soon learn to appreciate this feature.
However, the identifiers
\&{packed} and \&{array} and \|n\ and \&{of\/} would not be indexed,
because \.{WEAVE} does not make index entries for reserved words or
single-letter identifiers.
Such identifiers are felt to be so ubiquitous
that it would be pointless to mention every place where they occur.

Speaking of identifiers, the author of \.{WEB} thinks that
\\{IdentifiersSeveralWordsLong} look terribly ugly when they mix
uppercase and lowercase letters.
He recommends that
\\{identifiers\_several\_words\_long} be written with underline characters
to get a much better effect.
%The actual identifiers sent to the \PASCAL\
%compiler by \.{TANGLE} will have such underlines removed, and \.{TANGLE}
%will check to make sure that two different identifiers do not become
%identical when this happens.
%(In fact, \.{TANGLE} even checks that
%the first seven characters of identifiers are unique, when lowercase
%letters have been converted to uppercase; the number seven in this
%constraint is more strict than \PASCAL's eight, and it can
%be changed if desired.) 
The \.{WEAVE} processor will properly
alphabetize identifiers that have embedded underlines
when it makes the index.
\newstuff
Using Spidery \.{WEB}, you're out of luck if programming language
\PASCAL\ doesn't support underlines in identifiers.
\endnewstuff

Although a module begins with \TeX\ text and ends with \PASCAL\ text, we
have noted that the dividing line isn't sharp, since \PASCAL\ text can be
included in \TeX\ text if it is enclosed in `\pb'.
Conversely, \TeX\ text
also appears frequently within \PASCAL\ text, because everything in
\PASCAL\ comments is treated as \TeX\ text.
Furthermore, a module name consists of \TeX\ text; thus, a \.{WEB} file
typically involves constructions like `\.{if} \.x \.= \.0 \.{then}
\.{@<Empty} \.{the} \.{|buffer|} \.{array@>}' where we go back and forth
between \PASCAL\ and \TeX\ conventions in a natural way.

\section Macros.
\newstuff
In the current implementation of Spidery \.{WEB}, a \.{WEB} programmer
can define two kinds of macros to make the programs shorter and more
readable.

\yskip\hang`\.{@d} \\{identifier} \.{=} \PASCAL\ text' defines a {\sl
simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
when \.{TANGLE} produces its output.

\yskip\hang`\.{@d} \\{identifier} \.{(}\\{formal parameters}\.{)}
\.{=} \PASCAL\ text' defines a 
{\sl parametric\/} macro, where the identifier will be replaced by the
\PASCAL\ 
text and where occurrences of the \\{formal parameters} in that
\PASCAL\ text will be replaced by arguments.
For C programmers, this is similar to the C macro processor, but
the \.{=} sign is used to avoid the need for bizarre lexical
requirements.
Whitespace can appear between a macro name and a list of formal
paramters, and newlines in macros need not be escaped with
backslashes.
A macro definition is terminated by a following \.{@d}, \.{@f},
\.{@u}, \.{@<}, or \.{@(}.
\endnewstuff




%A \.{WEB} programmer can define three kinds of macros to make the programs
%shorter and more readable:
%
%\yskip\hang`\.{@d} \\{identifier} \.= \\{constant}' defines a {\sl numeric\/}
%macro, allowing \.{TANGLE} to do rudimentary arithmetic.
%
%\yskip\hang`\.{@d} \\{identifier} \.{==} \PASCAL\ text' defines a {\sl
%simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
%when \.{TANGLE} produces its output.
%
%\yskip\hang`\.{@d} \\{identifier}\.{(\#) ==} \PASCAL\ text' defines a
%{\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\
%text and where occurrences of \.{\#} in that \PASCAL\ text will be
%replaced by an argument.
%
%\yskip\noindent In all three cases, the identifier must have length greater
%than one; it must not be a single letter.
%Furthermore, the identifier must
%be making its first appearance in the \.{WEB} file; a macro must be defined
%before it is used.
%
%Numeric macros are subject to the following restrictions:\quad
%(1)~The right-hand side of the numeric definition must be made entirely from
%integer constants, numeric macros, preprocessed strings (see below), and
%plus~signs or minus signs.
%No other operations or symbols are allowed,
%not even parentheses, except that \PASCAL-like comments (enclosed in
%braces) can appear.
%Indeed, comments are recommended, since it is usually
%wise to give a brief explanation of the significance of each identifier as
%it is defined.\quad
%(2)~The numeric value must be less than $2^{15}=32768$ in absolute value.
%(For larger values, you can use `\.{==}' in place of~`\.=', thus making use
%of a simple macro instead of a numeric one.
%Note, however, that simple
%macros sometimes have a different effect.
%For example, consider the three
%definitions `\.{@d n1=2 @d n2=2+n1 @d n3==2+n1}'; then `\.{x-n2}' will
%expand into `\.{x-4}', while `\.{x-n3}' will expand into `\.{x-2+2}' which
%is quite different! It is wise to include parentheses in non-numeric
%macros, e.g., `\.{@d n3==(2+n1)}', to avoid such errors.)
%
%When constants are connected by plus signs or minus
%signs in an \PASCAL\ program, \.{TANGLE} does the arithmetic before putting
%the constant into the output file.
%Therefore it is permissible to say, for
%example, `\&{array} $[0\,.\,.\,\\{size}-1]$' if \\{size} has been declared
%as a macro; note that \PASCAL\ doesn't allow this kind of compile-time
%arithmetic if \\{size} is a \&{constant} quantity in the program.
%Another
%use of \.{TANGLE}'s arithmetic is to make \&{case} statement labels such
%as `$\\{flag}+1$' legitimate.
%Of course, it is improper to change \.{2+2}
%into \.4 without looking at the surrounding context; many counterexamples
%exist, such as the phrases `\.{-2+2}', `\.{x/2+2}', and `\.{2+2E5}'.
%The
%program for \.{TANGLE}, in the appendix, gives precise details about this
%conversion, which \.{TANGLE} does only when it is safe.
%
%The right-hand sides of simple and parametric macros
%are required to have balanced parentheses, and the \PASCAL\ texts of
%modules must have balanced parentheses too.
%Therefore when the argument
%to a para\-metric macro appears in parentheses, both parentheses
%will belong to the same \PASCAL\ text.
%
%The appendices to this report contain hundreds of typical examples of the
%usefulness of \.{WEB} macros, so it is not necessary to dwell on the
%subject here.
%However, the reader should know that \.{WEB}'s apparently
%primitive macro capabilities can actually do a lot of rather surprising
%things.
%Here is a construction that sheds further light on what is
%possible: After making the definitions
%$$\catcode`\#=12
%\lpile{\.{@d two\_cases(#)==case j of 1:#(1); 2:#(2); end}\cr
%\.{@d reset\_file(#)==reset(input\_file@\&#)}\cr}$$
%one can write `\.{two\_cases(reset\_file)}' and the resulting \PASCAL\
%output will be
%$$\.{case j of 1:reset(input\_file1); 2:reset(input\_file2); end}$$
%(but in uppercase letters and with \.\_'s removed).
%The `\.{@\&}' operation used here joins together two adjacent tokens
%into a single token, as explained later; otherwise the \PASCAL\ file would
%contain a space between \.{input\_file} and the digit that followed it.
%This trick can be used to provide the effect of an array of files, if you
%are unfortunate enough to have a \PASCAL\ compiler that doesn't allow such
%arrays.
%Incidentally, the cross-reference index made by \.{WEAVE} from
%this example would contain the identifier \\{input\_file} but it would not
%contain \\{input\_file1} or \\{input\_file2}.
%Furthermore, \.{TANGLE}
%would not catch the error that \.{INPUTFILE1} and \.{INPUTFILE2} both
%begin with the same nine letters; one should be more careful when using
%`\.{@\&}'! But such aspects of the construction in this trick are
%peripheral to our main point, which is that a parametric macro name without
%arguments can be used as an argument to another parametric macro.
%
%Although \.{WEB}'s macros are allowed to have at most one parameter, the
%following example shows that this is not as much of a restriction as it
%may seem at first.
%Let \\{amac} and \\{bmac} be any parametric macros, and
%suppose that we want to get the effect of
%$$\catcode`\#=12
%\.{@d cmac(#1,#2) == amac(#1) bmac(#2)}$$
%which \.{WEB} doesn't permit.
%The solution is to make the definitions
%$$\catcode`\#=12
%\lpile{\.{@d cmac(#) == amac(#) dmac}\cr
%\.{@d dmac(#) == bmac(#)}\cr}$$
%and then to say `\.{cmac(x)(y)}'.
%
%There is one restriction in the generality of \.{WEB}'s parametric
%macros, however: the argument to a para\-metric macro must not come from
%the expansion of a macro that has not already been ``started.'' For
%example, here is one of the things \.{WEB} cannot handle:
%$$\catcode`\#=12
%\lpile{\.{@d arg == (p)}\cr
%\.{@d identity(#) == #}\cr
%\.{@p identity arg}\cr}$$
%In this case \.{TANGLE} will complain that the \.{identity} macro is not
%followed by an argument in parentheses.

%The \.{WEB} language has another feature that is somewhat similar to a
%numeric macro.
%A {\sl preprocessed string\/} is a string that is like
%a \PASCAL\ string but delimited by double-quote marks (\.") instead of
%single-quotes.
%Double-quote marks inside of such strings are indicated by
%giving two double-quotes in a row.
%If a preprocessed string is
%of length one (e.g., \.{"A"} or \.{""""}), it will be treated by \.{TANGLE}
%as equivalent to the corresponding ASCII-code integer (e.g., \.{65} or
%\.{34}).
%And if a preprocessed string is not of length one, it will be
%converted into an integer equal to 128 or more.
%A {\sl string pool\/}
%containing all such strings will be written out by the \.{TANGLE}
%processor; this string pool file consists of string 128, then string 129,
%etc., where each string is followed by an end-of-line and prefixed by two
%decimal digits that define its length.
%Thus, for example, the empty string
%\.{""} would be represented in the string pool file by a line containing
%the two characters `\.{00}', while the string \.{"""String"""} would be
%represented by `\.{08"String"}'.
%A given string appears at most once in
%the string pool; the use of such a pool makes it easier to cope with
%\PASCAL's restrictions on string manipulation.
%The string pool ends with
%`\.{*nnnnnnnnn}', where \.{nnnnnnnnn} is a decimal number
%called the {\sl string pool check sum}.
%If any string changes, the check
%sum almost surely changes too; thus, the `\.{@\$}' feature
%described below makes it possible for a program to assure itself that it
%is reading its own string pool.
%
%Here is a simple example that combines numeric macros with preprocessed
%strings of length one:
%$$\lpile{\.{@d upper\_case\_Y = "Y"}\cr
%\.{@d case\_difference = -"y"+upper\_case\_Y}\cr}$$
%The result is to define
%$\\{upper\_case\_Y}=89$, $\\{case\_difference}=-32$.

\newstuff
Spidery \.{WEB} does not support a string pool file.
Pleas for its restoration will be heard.
\endnewstuff

\section Control codes.
We have seen several magic uses of `\.{@}' signs in \.{WEB} files, and it
is time to make a systematic study of
these special features.
A \.{WEB} {\sl control code\/}
is a two-character combination of which the first is `\.@'.
\newstuff
In Spidery \.{WEB} the ``magic at sign'' need not be `\.@'; the person
who built your \.{WEB} (with {Spider}) may have defined it to be
something else.
By convention, people building Spidery {\tt WEB}s
 use `\.@' as the magic at sign, except when it is
deemed unsuitable for some reason, in which case
 cases they use `\.\#'.
\endnewstuff

Here is a complete list of the legal control codes.
The letters $L$, $T$,
$\PAS$, $M$, $C$, and/or $S$ following each code indicate whether or not that
code is allowable in limbo, in \TeX\ text, in \PASCAL\ text, in module
names, in comments, and/or in strings.
A bar over such a letter means
that the control code terminates the present part of the \.{WEB} file; for
example, $\overline L$ means that this control code ends the limbo material
before the first module.

\def\@#1[#2] {\yskip\hangindent 2em\noindent\.{@#1\unskip
  \spacefactor1000{ }}$[#2]$\quad}
\def\oT{\overline T}

\@@ [C,L,M,\PAS,S,T] A double \.@ denotes the single character `\.@'.
This is
the only control code that is legal in limbo, in comments, and in strings.

\@i [L,T]
\newstuff
The \.{@i} control code should always be followed by a file name and a
newline.
It causes the file to be included at the current point in the
\.{WEB} source, just like the C \.{\#include} facility.
\endnewstuff

\@\ [\overline L,\oP,\oT] This denotes the beginning of a new
(unstarred) module.
A tab mark or end-of-line (carriage return)
is equivalent to a space when it follows an \.@ sign.

\@* [\overline L,\oP,\oT] This denotes the beginning of a new starred
module, i.e., a module that begins a new major group.
The title of the new
group should appear after the \.{@*}, followed by a period.
\newstuff
As explained above, the first character of the title should be either
a letter or the control sequence \.{\\relax}, unless special
formatting is desired.
Titles beginning with \.=, \.1, \.2, \.3, or \.4 are formatted
specially.
\endnewstuff
As explained
above, \TeX\ control sequences should be avoided in such titles unless
they are quite simple.
When \.{WEAVE} and \.{TANGLE} read a \.{@*}, they
print an asterisk followed by the current module number, so that the user
can see some indication of progress.
The very first module should be starred.

\@d [\oP,\oT] Macro definitions begin with \.{@d} (or \.{@D}), followed by
the \PASCAL\ text for one of the three kinds of macros, as explained
earlier.

\@f [\oP,\oT] Format definitions begin with \.{@f} (or \.{@F}); they cause
\.{WEAVE} to treat identifiers in a special way when they appear in
\PASCAL\ text.
The general form of a format definition is `\.{@f} \|l %\.{=}
\|r', followed by an optional comment enclosed in braces, where \|l and \|r
are identifiers; \.{WEAVE} will subsequently treat identifier \|l as it
currently treats \|r.
This feature allows a \.{WEB} programmer to invent
new reserved words and/or to unreserve some of \PASCAL's reserved
identifiers.
\newstuff
It is offensive that the syntax is different from the \.{2d} syntax,
but it is that way for historical reasons (to avoid invalidating
existing code. 
\endnewstuff
The definition part of each module consists of any number of
macro definitions (beginning with \.{@d}) and format definitions (beginning
with \.{@f}), intermixed in any order.


\@u [\oP,\oT] \newstuff
The \PASCAL\ part of an unnamed module begins with \.{@u}
(or \.{@U}).
\endnewstuff
This causes \.{TANGLE} to append the following \PASCAL\ code
to the initial program text $T_0$ as explained above.
The \.{WEAVE}
processor does not cause a `\.{@u}' to appear explicitly in the \TeX\
output, so if you are creating a \.{WEB} file based on a \TeX-printed
\.{WEB} documentation you have to remember to insert \.{@u} in the
appropriate places of the unnamed modules.

\@< [\PAS,\oT] A module name begins with \.{@<} followed by \TeX\ text followed
by \.{@>}; the \TeX\ text should not contain any \.{WEB} control sequences
except \.{@@}, unless these control sequences appear in \PASCAL\ text that
is delimited by \pb.
The module name may be abbreviated, after its first
appearance in a \.{WEB} file, by giving any unique prefix followed by \.{...},
where the three dots immediately precede the closing \.{@>}.
Module names may
not appear in \PASCAL\ text that is enclosed in \pb, nor may they appear
in the definition part of a module (since the appearance of a module name
ends the definition part and begins the \PASCAL\ part).


\@( [\PAS,\oT] \newstuff A module beginning
with \.{@(} is treated like one beginning with \.{@<},
except that the module name is treated as the name of a file to which
the module will be written.
If such modules are used in other modules the results are undefined.
\endnewstuff

\@\' [\PAS,T] This denotes an octal constant, to be formed from the
succeeding digits.
For example, if the \.{WEB} file contains `\.{@\'100}',
the \.{TANGLE} processor will treat this an equivalent to `\.{64}';
the constant will be formatted as ``\O{\~100}'' in the \TeX\ output
produced via \.{WEAVE}.
You should use octal notation only for positive
constants; don't try to get, e.g., $-1$ by saying `\.{@\'777777777777}'.

\@" [\PAS,T] A hexadecimal constant; `\.{@"D0D0}' tangles to \.{53456} and
weaves to `\O{\^D0D0}'.

%\@\$ [\PAS] This denotes the string pool check sum.

%\@\{ [\PAS] The beginning of a ``meta comment,'' i.e., a comment
%that is supposed to appear in the \PASCAL\ code, is indicated by
%\.{@\{} in the \.{WEB} file.
%Such delimiters can be used as
%isolated symbols in macros or modules, but they should be properly nested
%in the final \PASCAL\ program.
%The \.{TANGLE} processor will convert
%`\.{@\{}' into `\.\{' in the \PASCAL\ output file, unless
%the output is already part of a meta-comment; in the latter case
%`\.{@\{}' is converted into `\.[', since 
%we don't assume that \PASCAL\ allows
%nested comments.
%Meta-comments
%can be used to put conditional text into an \PASCAL\ program; this helps to
%overcome one of the limitations of \.{WEB}, since the simple macro
%processing routines of \.{TANGLE} do not include the dynamic evaluation of
%boolean expressions.
%\newstuff
%Where is this trick explained, and note that it only works in
%languages whose comments don't end with newline.
%\endnewstuff
%
%\@\} [\PAS] The end of a ``meta comment'' is indicated by `\.{@\}}'; this is
%converted either into `\.\}' or `\.{]}' in the \PASCAL\ output, according
%to the conventions explained for \.{@\{} above.

\@\& [\PAS] The \.{@\&} operation causes whatever is on its left to be
adjacent to whatever is on its right, in the \PASCAL\ output.
No spaces or
line breaks will separate these two items.
However, the thing on the left
should not be a semicolon, since a line break might occur after a semicolon.

\@\^ [\PAS,T] The ``control text'' that follows, up to the next
`\.{@>}', will be entered into the index together with the identifiers of
the \PASCAL\ program; this text will appear in roman type.
For example, to
put the phrase ``system dependencies'' into the index, you can type
`\.{@\^system dependencies@>}' in each module
that you want to index as system dependent.
A control text, like a string,
must end on the same line of the \.{WEB} file as it began.
Furthermore,
no \.{WEB} control sequences are allowed in a control text, not even
\.{@@}.
(If you need an \.{@} sign you can get around this restriction by
typing `\.{\\AT!}'.)

\@.
[\PAS,T] The ``control text'' that follows will be entered into the index
in \.{typewriter} \.{type}; see the rules for `\.{@\^}', which is analogous.

\@: [\PAS,T] The ``control text'' that follows will be entered into the index
in a format controlled by the \TeX\ macro `\.{\\9}', which the user
should define as desired; see the rules for `\.{@\^}', which is analogous.

\@t [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
be put into a \TeX\ \.{\\hbox} and formatted along with the neighboring
\PASCAL\ program.
This text is ignored by \.{TANGLE}, but it can be used
for various purposes within \.{WEAVE}.
For example, you can make comments
that mix \PASCAL\ and classical mathematics, as in `$\\{size}<2^{15}$', by
typing `\.{|size < @t\$2\^\{15\}\$@>|}'.
A control text must end on the
same line of the \.{WEB} file as it began, and it may not contain any
\.{WEB} control codes.

\@= [\PAS] The ``control text'' that follows, up to the next `\.{@>}', will
be passed verbatim to the \PASCAL\ program.

%%% \@\\ [\PAS] Force end-of-line here in the \PASCAL\ program file.

\@! [\PAS,T] The module number in an index entry will be underlined if `\.{@!}'
immediately precedes the identifier or control text being indexed.
This
convention is used to distinguish the modules where an identifier is
defined, or where it is explained in some special way, from the modules
where it is used.
A~reserved word or an identifier of length one will not
be indexed except for underlined entries.
%An `\.{@!}' is implicitly inserted
%by \.{WEAVE} just after the reserved words \&{function}, \&{procedure},
%\&{program}, and \&{var}, and just after \.{@d} and \.{@f}.
%But you should
%insert your own `\.{@!}' before the definitions of types, constants,
%variables, parameters, and components of records and enumerated types that
%are not covered by this implicit convention, if you want to improve the
%quality of the index that you get.
\newstuff
Some Spidery \.{WEAVE}s will insert implicit `\.{@!}' tokens in places
like function definitions or variable declarations.
The person who built your Spidery \.{WEB} should have documented these
places; if not, they can be discovered by examing the {\tt .spider}
file.
The automatic definitions work well for some languages, but
for the best possible index you should insert your own `\.{@!}' token before
the defining instance of every identifier.
\endnewstuff

\@?
[\PAS,T] This cancels an implicit (or explicit) `\.{@!}', so that the next
index entry will not be underlined.
\newstuff This is not implemented in the current version of Spidery \.{WEB}.
\endnewstuff

\@, [\PAS] This control code inserts a thin space in \.{WEAVE}'s output; it is
ignored by \.{TANGLE}.
Sometimes you need this extra space if you are using
macros in an unusual way, e.g., if two identifiers are adjacent.

\@/ [\PAS] This control code causes a line break to occur within an \PASCAL\
program formatted by \.{WEAVE}; it is ignored by \.{TANGLE}.
Line breaks
are chosen automatically by \TeX\ according to a scheme that works 99\%\
of the time, but sometimes you will prefer to force a line break so that
the program is segmented according to logical rather than visual criteria.
\newstuff
The line following such a line break is indented at the same level as
the line broken.
\endnewstuff
Caution: `\.{@/}' should be used only after statements or clauses, not in
the middle of an expression; use \.{@|} in the middle of expressions, in
order to keep \.{WEAVE}'s parser happy.

\@- [\PAS] \newstuff
This control code makes \.{WEAVE} continue the current
statement on the next line; it is ignored by \.{TANGLE}.
If is just like `\.{@/}', except that the following line is indented,
to show that it is a continuation of the line broken.
\endnewstuff

\@| [\PAS] This control code specifies an optional line break in the midst of
an expression.
For example, if you have a long condition between \&{if} and
\&{then}, or a long expression on the right-hand side of an assignment
statement, you can use `\.{@|}' to specify breakpoints more logical than
the ones that \TeX\ might choose on visual grounds.

\@\# [\PAS] This control code forces a line break, like \.{@/} does,
and it also causes a little extra white space to appear between the lines at
this break.
You might use it, for example, between procedure definitions or
between groups of macro definitions that are logically separate but within
the same module.

\@+ [\PAS] This control code cancels a line break that might otherwise be
inserted by \.{WEAVE}, e.g., before the word `\&{else}', if you want to
put a short if-then-else construction on a single line.
It is ignored by
\.{TANGLE}.

\@; [\PAS] Usually this control code is treated like a semicolon, for
formatting purposes, except that it is invisible.
\newstuff
The person who built your \.{WEB} can redefine it, though, so check
his documentation to make sure.
\endnewstuff

You can use it, for example, after
a module name when the \PASCAL\ text represented by that module name ends
with a semicolon.

\yskip\noindent
The last \newstuff seven \endnewstuff
 control codes (namely `\.{@,}', `\.{@/}', `\.{@-}', `\.{@|}',
`\.{@\#}', `\.{@+}', and `\.{@;}') have no effect on the \PASCAL\
program output by \.{TANGLE}; they merely help to improve the readability
of the \TeX-formatted \PASCAL\ that is output by \.{WEAVE}, in unusual
circumstances.
\.{WEAVE}'s built-in formatting method is fairly good, but
it is incapable of handling all possible cases, because it must deal with
fragments of text involving macros and module names; these fragments do
not necessarily obey \PASCAL's syntax.
Although \.{WEB} allows you to
override the automatic formatting, your best strategy is not to worry
about such things until you have seen what \.{WEAVE} produces automatically,
since you will probably need to make only a few corrections when you are
touching up your documentation.

Because of the rules by which every module is broken into three parts,
the control codes `\.{@d}', `\.{@f}', and `\.{@u}' are not allowed to occur
once the \PASCAL\ part of a module has begun.

\section Additional features and caveats.

%1.
%The character pairs `\.{(*}', `\.{*)}', `\.{(.}', and `\.{.)}' are
%converted automatically in \PASCAL\ text as though they were
%`\.{@\{}', `\.{@\}}', `\.[', and `\.]', respectively, except
%%of course in strings.
%Furthermore in certain installations of \.{WEB} that
%{\def\\#1#2{`{\tentex\char'#1#2}'}%
%have an extended character set, the characters \\32, \\34, \\35, \\30,
%\\36, \\04, \\37, \\05, and \\06}
%can be used as abbreviations for
%`\.{<>}', `\.{<=}', `\.{>=}', `\.{:=}', `\.{==}', `\.{and}', `\.{or}',
%`\.{not}', and `\.{in}', respectively.
%However, the latter abbreviations
%are not used in the standard versions of \.{WEAVE.WEB} and \.{TANGLE.WEB}
%that are distributed to people who are installing \.{WEB} on other
%computers, and the programs are designed to produce only standard ASCII
%characters as output if the input consists entirely of ASCII characters.
%
%2.
%If you have an extended character set, all of the characters listed
%in Appendix C of {\sl The \TeX book\/} can be used in strings.
%But you should
%stick to standard ASCII characters if you want to write programs that will
%be useful to the all the poor souls out there who don't have extended
%character sets.

3.
The \TeX\ file output by \.{WEAVE} is broken into lines having at most
80 characters each.
The algorithm that does this line breaking is unaware
of \TeX's convention about comments following `\.\%' signs on a line.
When
\TeX\ text is being copied, the existing line breaks are copied as well,
so there is no problem with `\.\%' signs unless the original \.{WEB} file
contains a line more than eighty characters long or a line with \PASCAL\
text in \pb\ that expands to more than eighty characters long.
Such lines
should not have `\.\%' signs.

4.
\PASCAL\ text is translated by a ``bottom up'' procedure that
identifies each token as a ``part of speech'' and combines parts of speech
into larger and larger phrases as much as possible according to a special
\newstuff prettyprinting \endnewstuff
grammar.
The grammar and the translation process are explained in the
``Spider User's Guide.'' 
It is easy to
learn the translation scheme for simple constructions like single
identifiers and short expressions, just by looking at a few examples of
what \.{WEAVE} does, but the general mechanism is somewhat complex because
it must handle much more than \PASCAL\ itself.
Furthermore the output
contains embedded codes that cause \TeX\ to indent and break lines as
necessary, depending on the fonts used and the desired page width.
For
best results it is wise to adhere to the following restrictions:

\yskip\itemitem{a)}Comments in \PASCAL\ text should appear only after
statements or clauses; i.e., 
\newstuff(if \PASCAL\ were PASCAL) \endnewstuff
after semicolons, after reserved words like
\&{then} and \&{do}, or before reserved words like \&{end} and \&{else}.
Otherwise \.{WEAVE}'s parsing method may well get mixed up.

\itemitem{b)}Don't enclose long \PASCAL\ texts in \pb, since the
indentation and line breaking codes are omitted when the \pb\ text is
translated from \PASCAL\ to \TeX.
Stick to simple expressions or
statements.

\yskip
5.
Comments and module names are not permitted in \pb\ text.
After a `\.|'
signals the change from \TeX\ text to \PASCAL\ text, the next `\.|' that is
not part of a string or control text ends the \PASCAL\ text.

6.
\newstuff
Spidery {\tt WEB} does not handle nested comments.
\endnewstuff
%A comment must have properly nested occurrences of left and right
% braces, otherwise \.{WEAVE} and \.{TANGLE} will not know where the comment
% ends.
%However, the character pairs `\.{\\\{}' and `\.{\\\}}' do not count
%as left and right braces in comments, and the character pair `\.{\\|}'
%does not count as a delimiter that begins \PASCAL\ text.
%(The actual rule
%is that a character after `\.\\' is ignored; hence in `\.{\\\\\{}' the
%left brace {\sl does\/} count.) At present, \.{TANGLE} and \.{WEAVE} treat
%comments in slightly different ways, and it is necessary to satisfy both
%conventions: \.{TANGLE} ignores `\.|' characters entirely, while \.{WEAVE}
%uses them to switch between \TeX\ text and \PASCAL\ text.
%Therefore, a
%comment that includes a brace in a string in \pb---e.g., `\.{\{{ }look at
%this |"\{"| \}}'---will be handled correctly by \.{WEAVE}, but \.{TANGLE}
%will think there is an unmatched left brace.
%In order to satisfy both
%processors, one can write `\.{\{{ }look at this \\leftbrace\\{ }\}}', after
%setting up`\.{\\def\\leftbrace\{|"\{"|\}}'.

7.
Reserved words of \PASCAL\ must appear entirely in lowercase letters
in the \.{WEB} file; otherwise their special nature will not be recognized
by \.{WEAVE}.
\newstuff
This could be changed, but the author of Spidery {\tt WEB} does not
believe in case-insensitivity for programming languages.
\endnewstuff
You could, for example, have a macro named \\{END} and it
would not be confused with \&{end}.

However, you may not want to capitalize macro names just to distinguish them
from other identifiers.
Here is a way to unreserve Pascal's reserved word
`\&{type}' and to substitute another word `\&{mtype}' in the \.{WEB} file.
$$\vbox{\halign{\tt #\hfil\cr
@d type(\char'43) = mem[\char'43].t\cr
@d mtype = t \char'100\char'46{} y \char'100\char'46{} p
  \char'100\char'46{} e\cr
@f mtype = type\cr
@f type = true\cr}}$$
In the output of \.{TANGLE}, the macro \.{mtype} now produces `\.{TYPE}'
and the macro \.{type(x)} now produces `\.{MEM[X].T}'.
In the output of
\.{WEAVE}, these same inputs produce \&{mtype} and \\{type}(\|x),
respectively.

8.
The \.{@f} feature allows you to define one identifier to act like
another, and these format definitions are carried out sequentially, as the
example above indicates.
However, a given identifier has only one printed format
throughout the entire document (and this format will even be used before
the \.{@f} that defines it).
The reason is that \.{WEAVE} operates in two
passes; it processes \.{@f}'s and cross-references on the first pass and
does the output on the second.

9.
You may want some \.{@f} formatting that doesn't correspond to any
existing reserved word.
In that case, \.{WEAVE} could be extended 
\newstuff
by someone who built Spidery {\tt WEB} 
\endnewstuff
to include new ``reserved words'' in its vocabulary.
\newstuff
(The ``\/{Spider} User's Guide'' explains how.)
\endnewstuff

%The identifier `\&{xclause}' has in fact been included already as a
%reserved word, so that it can be used to format the `\&{loop}' macro,
%where `\&{loop}' is defined to be equivalent to `\&{while \\{true} do}'.

10.
Sometimes it is desirable to insert spacing into \PASCAL\ code that is
more general than the thin space provided by `\.{@,}'.
The \.{@t} feature
can be used for this purpose; e.g., `\.{@t\\hskip 1in@>}' will
leave one inch of blank space.
Furthermore, `\.{@t\\4@>}' can be
used to backspace by one unit of indentation, since the control sequence
\.{\\4} is defined in \.{webmac} to be such a backspace.
(This
control sequence is used, for example, at the beginning of lines that
contain labeled statements, so that the label will stick out a little at
the left.)

11.
\.{WEAVE} and \.{TANGLE} are designed to work with two input files,
called \\{web\_file} and \\{change\_file}, where \\{change\_file} contains
data that overrides selected portions of \\{web\_file}.
The resulting merged
text is actually what has been called the \.{WEB} file elsewhere in this
report.

Here's how it works: The change file consists of zero or more ``changes,''
where a change has the form `\.{@x}$\langle$old lines$\rangle$\.{@y}$\langle$%
new lines$\rangle$\.{@z}'.
The special control codes \.{@x}, \.{@y}, \.{@z},
which are allowed only in change files, must appear at the beginning of a line;
the remainder of such a line is ignored.
The $\langle$old lines$\rangle$ represent material that exactly matches
consecutive lines of the \\{web\_file}; the $\langle$new lines$\rangle$
represent zero or more lines that are supposed to replace the old.
Whenever
the first ``old line'' of a change is found to match a line in the
\\{web\_file}, all the other lines in that change must match too.

Between changes, before the first change, and after the last change,
the change file can have any number of lines that do not begin with
`\.{@x}', `\.{@y}', or~`\.{@z}'.
Such lines are bypassed and not used for
matching purposes.

This dual-input feature is useful when working with a master \.{WEB} file
that has been received from elsewhere (e.g., \.{TANGLE.WEB} or
\.{WEAVE.WEB} or \.{TEX.WEB}), when changes are desirable to customize the
program for your local computer system.
You will be able to debug your
system-dependent changes without clobbering the master web file; and once
your changes are working, you will be able to incorporate them readily
into new releases of the master web file that you might receive from time
to time.

\newstuff
There are several multiple-changefile tools in the {\TeX} community;
check back issues of TUGboat for more information.
\endnewstuff

\section Appendices.
% The basic ideas of \.{WEB} can be understood most easily by looking at
% examples of ``real'' programs.
% Appendix~A shows the \.{WEB} input that
% generated modules 55--59 of the \.{WEAVE} program; Appendix~B shows the
% corresponding \TeX\ code output by \.{WEAVE}; and Appendix~C shows excerpts
% from the corresponding \PASCAL\ code output by \.{TANGLE}.
% 
% The complete webs for \.{WEAVE} and \.{TANGLE} appear as the bulk of this
% report, in Appendices D and~E.
% The reader should first compare Appendix~A
% to the corresponding portion of Appendix~D; then the same material should
% be compared to Appendices B and~C.
% Finally, if time permits, the reader may
% enjoy studying the complete programs in Appendices D and~E, since \.{WEAVE}
% and \.{TANGLE} contain several interesting aspects, and since an attempt
% has been made in these appendices to evolve a style of programming that
% makes good use of the \.{WEB} language.
% 
% Finally, Appendix F is the `\.{webkernel}' file that sets \TeX\ up to accept
% the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros
% to vary the output formats; and Appendix~H discusses what needs to be done
% when \.{WEAVE} and \.{TANGLE} are installed in a new operating environment.
% 
% \section Performance statistics.
% The programs in Appendices D and E will optionally keep statistics on
% how much memory they require.
% Here is what they printed out when
% processing themselves:
% 
% \def\pstat#1#2#3
% #4{\yskip\noindent\.{#1} applied to \.{#2} (cpu time #3 sec)\par
% \halign{\quad\tt##\hfil\cr#4}}
% 
% \pstat{TANGLE}{TANGLE}{15}
% {Memory usage statistics:\cr
% 456 names, 215 replacement texts;\cr
% 3396+3361 bytes, 6685+7329+5805 tokens.\cr}
% 
% \pstat{TANGLE}{WEAVE}{30}
% {Memory usage statistics:\cr
% 692 names, 339 replacement texts;\cr
% 4576+4294 bytes, 10184+9875+9150 tokens.\cr}
% 
% \pstat{WEAVE}{TANGLE}{45}
% {Memory usage statistics: 478 names, 2045 cross references, 4159+3729 bytes;\cr
% parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
% sorting required 34 levels.\cr}
% 
% \pstat{WEAVE}{WEAVE}{65}
% {Memory usage statistics: 737 names, 3306 cross references, 4896+4962 bytes;\cr
% parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
% sorting required 73 levels.\cr}
% 
% \yskip\noindent The cpu time for \PASCAL\ to process \.{TANGLE.PAS} was
% approximately 13 seconds, and \.{WEAVE.PAS} took approximately 26 seconds;
% thus the tangling time was slightly more than the compiling time.
% The cpu
% time for \TeX\ to process \.{TANGLE.TEX} was approximately 500 seconds,
% and \.{WEAVE.TEX} took approximately 750 seconds (i.e., about 7
% seconds per printed page, where these pages are substantially larger than
% the pages in a normal book).
% All cpu times quoted are for a DECsystem-10.
% 
% \def\K{{\mc K}}
% The file \.{TANGLE.WEB} is about 125\K\ characters long; \.{TANGLE}
% reduces it to a file \.{TANGLE.PAS} whose size is about 42\K\ characters,
% while \.{WEAVE} expands it to a file \.{TANGLE.TEX} of about 185\K\null.
% The corresponding file sizes for \.{WEAVE.WEB}, \.{WEAVE.PAS}, and
% \.{WEAVE.TEX} are 180\K, 89\K, and 265\K.
% 
% The much larger file \.{TEX.WEB} led to the following numbers:
% 
% \pstat{TANGLE}{TEX}{110}
% {Memory usage statistics:\cr
% 3750 names, 1768 replacement texts;\cr
% 41895+41053 bytes, 42378+45074+41091 tokens.\cr}
% 
% \pstat{WEAVE}{TEX}{270}
% {Memory usage statistics: 3412 names, 19699 cross references,
%   37900+40232 bytes;\cr
% parsing required 685 scraps, 1303 texts, 3784 tokens, 104 levels;\cr
% sorting required 52 levels.\cr}
% 
% \yskip\noindent
% \PASCAL\ did \.{TEX.PAS} in about 75 seconds; \TeX\ did \.{TEX.TEX}
% in about 3600.
% 
% % Here is a quotation that could not really be omitted
% 
% \vfill
% 
% {\baselineskip9pt
% \halign to\hsize{\hfil\quoteit#\tabskip 0pt plus 100pt&
%   \hfil\quoteit#\tabskip 0pt\cr
% O, what a tangled web we weave&
%   O, what a tangled WEB we weave\cr
% When first we practise to deceive!&
%   When \TeX\ we practise to conceive!\cr
% \noalign{\vskip 2pt}
% \quoterm ---SIR WALTER SCOTT, {\quoteit Marmion} 6:17 (1808)&
%   \quoterm ---RICHARD PALAIS (1982)\cr
% }}
% \eject
% 
% \def\runninghead{APPENDIX A --- {\tentt WEB} FILE FORMAT}
% \section Appendix A.
% This excerpt from \.{WEAVE.WEB} produced modules 55--59 in Appendix~D.
% Note that some of the lines are indented to show the program structure.
% The indentation is ignored by \.{WEAVE} and \.{TANGLE}, but users find
% that \.{WEB} files are quite readable if they have some such indentation.
% 
% \vskip 6pt
% \begingroup \def\tt{\eighttt} \baselineskip9pt
% % Note to myself: I had to remove SAIL characters from the file here!
% % Also tabs replaced by double-space.
% The changes were made in WEAVE source.
% \verbatim
% @* Searching for identifiers.
% The hash table described above is updated by the |id_lookup| procedure,
% which finds a given identifier and returns a pointer to its index in
% |byte_start|.
% The identifier is supposed to match character by character
% and it is also supposed to have a given |ilk| code; the same name may be
% present more than once if it is supposed to appear in the index with
% different typesetting conventions.
% If the identifier was not already present, it is inserted into the table.
% 
% Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
% to let |id_lookup| search for an identifier that is present in the |buffer|
% array.
% Two other global variables specify its position in the buffer: the
% first character is |buffer[id_first]|, and the last is |buffer[id_loc-1]|.
% 
% @<Glob...@>=
% @!id_first:0..long_buf_size; {where the current identifier begins in the buffer}
% @!id_loc:0..long_buf_size; {just after the current identifier in the buffer}
% @#
% @!hash:array [0..hash_size] of sixteen_bits; {heads of hash lists}
% 
% @ Initially all the hash lists are empty.
% 
% @<Local variables for init...@>=
% @!h:0..hash_size; {index into hash-head array}
% 
% @ @<Set init...@>=
% for h:=0 to hash_size-1 do hash[h]:=0;
% 
% @ Here now is the main procedure for finding identifiers (and index
% entries).
% The parameter |t| is set to the desired |ilk| code.
% The
% identifier must either have |ilk=t|, or we must have
% |t=normal| and the identifier must be a reserved word.
% 
% @p function id_lookup(@!t:eight_bits):name_pointer; {finds current identifier}
% label found;
% var i:0..long_buf_size; {index into |buffer|}
% @!h:0..hash_size; {hash code}
% @!k:0..max_bytes; {index into |byte_mem|}
% @!w:0..ww-1; {row of |byte_mem|}
% @!l:0..long_buf_size; {length of the given identifier}
% @!p:name_pointer; {where the identifier is being sought}
% begin l:=id_loc-id_first; {compute the length}
% @<Compute the hash code |h|@>;
% @<Compute the name location |p|@>;
% if p=name_ptr then @<Enter a new name into the table at position |p|@>;
% id_lookup:=p;
% end;
% 
% @ A simple hash code is used: If the sequence of
% ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
% $$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
% 
% @<Compute the hash...@>=
% h:=buffer[id_first]; i:=id_first+1;
% while i<id_loc do
%   begin h:=(h+h+buffer[i]) mod hash_size; incr(i);
%   end
% ?endgroup % end of verbatim mode
% \endgroup
% \vfill\eject
% 
% \def\runninghead{APPENDIX B --- TRANSLATION BY {\tentt WEAVE}}
% \section Appendix B.
% This excerpt from \.{WEAVE.TEX} corresponds to Appendix A.
% 
% % I've inserted \vfill's here at the blank lines, to squeeze this on one page!
% \begingroup \def\tt{\eighttt} \baselineskip9pt
% \verbatim
% ?vfill?verbatimgobble
% \N55.
% Searching for identifiers.
% The hash table described above is updated by the \\{id\_lookup} procedure,
% which finds a given identifier and returns a pointer to its index in
% \\{byte\_start}.
% The identifier is supposed to match character by character
% and it is also supposed to have a given \\{ilk} code; the same name may be
% present more than once if it is supposed to appear in the index with
% different typesetting conventions.
% If the identifier was not already present, it is inserted into the table.
% ?vfill?verbatimgobble
% Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
% to let \\{id\_lookup} search for an identifier that is present in the %
% \\{buffer}
% array.
% Two other global variables specify its position in the buffer: the
% first character is $\\{buffer}[\\{id\_first}]$, and the last is $\\{buffer}[%
% \\{id\_loc}-1]$.
% ?vfill?verbatimgobble
% \Y\P$\4\X9:Globals in the outer block\X\mathrel{+}\S$\6
% \4\\{id\_first}: \37$0\to\\{long\_buf\_size}$;\C{where the current identifier
% begins in the buffer}\6
% \4\\{id\_loc}: \37$0\to\\{long\_buf\_size}$;\C{just after the current
% identifier in the buffer}\7
% \4\\{hash}: \37\&{array} $[0\to\\{hash\_size}]$ \1\&{of}\5
% \\{sixteen\_bits};\C{heads of hash lists}\2\par
% \fi
% ?vfill?verbatimgobble
% \M56.
% Initially all the hash lists are empty.
% ?vfill?verbatimgobble
% \Y\P$\4\X16:Local variables for initialization\X\mathrel{+}\S$\6
% \4\|h: \37$0\to\\{hash\_size}$;\C{index into hash-head array}\par
% \fi
% ?vfill?verbatimgobble
% \M57.
% \P$\X10:Set initial values\X\mathrel{+}\S$\6
% \&{for} $\|h\K0\mathrel{\&{to}}\\{hash\_size}-1$ \1\&{do}\5
% $\\{hash}[\|h]\K0$;\2\par
% \fi
% ?vfill?verbatimgobble
% \M58.
% Here now is the main procedure for finding identifiers (and index
% entries).
% The parameter \|t is set to the desired \\{ilk} code.
% The
% identifier must either have $\\{ilk}=\|t$, or we must have
% $\|t=\\{normal}$ and the identifier must be a reserved word.
% ?vfill?verbatimgobble
% \Y\P\4\&{function}\1\  \37$\\{id\_lookup}(\|t:\\{eight\_bits})$: \37\\{name%
% \_pointer};\C{finds current identifier}\6
% \4\&{label} \37\\{found};\6
% \4\&{var} \37\|i: \37$0\to\\{long\_buf\_size}$;\C{index into \\{buffer}}\6
% \|h: \37$0\to\\{hash\_size}$;\C{hash code}\6
% \|k: \37$0\to\\{max\_bytes}$;\C{index into \\{byte\_mem}}\6
% \|w: \37$0\to\\{ww}-1$;\C{row of \\{byte\_mem}}\6
% \|l: \37$0\to\\{long\_buf\_size}$;\C{length of the given identifier}\6
% \|p: \37\\{name\_pointer};\C{where the identifier is being sought}\2\6
% \&{begin} \37$\|l\K\\{id\_loc}-\\{id\_first}$;\C{compute the length}\6
% \X59:Compute the hash code \|h\X;\6
% \X60:Compute the name location \|p\X;\6
% \&{if} $\|p=\\{name\_ptr}$ \1\&{then}\5
% \X62:Enter a new name into the table at position \|p\X;\2\6
% $\\{id\_lookup}\K\|p$;\6
% \&{end};\par
% \fi
% ?vfill?verbatimgobble
% \M59.
% A simple hash code is used: If the sequence of
% ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
% $$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,\\{hash\_size}.$$
% ?vfill?verbatimgobble
% \Y\P$\4\X59:Compute the hash code \|h\X\S$\6
% $\|h\K\\{buffer}[\\{id\_first}]$;\5
% $\|i\K\\{id\_first}+1$;\6
% \&{while} $\|i<\\{id\_loc}$ \1\&{do}\6
% \&{begin} \37$\|h\K(\|h+\|h+\\{buffer}[\|i])\mathbin{\&{mod}}\\{hash\_size}$;\5
% $\\{incr}(\|i)$;\6
% \&{end}\2\par
% \U section~58.\fi
% ?endgroup
% \endgroup
% \eject
% 
% \def\runninghead{APPENDIX C --- TRANSLATION BY {\tentt TANGLE}}
% \section Appendix C.
% The \.{TANGLE} processor converts \.{WEAVE.WEB} into a syntactically
% correct (but not very pretty) \PASCAL\ program \.{WEAVE.PAS}.
% The first three and last two lines of output are shown here, together with the
% lines of code generated by modules 55--62 and the environments of
% those lines.
% There are 1559 lines in all; the notation
% `\.. \\.
% \\.' stands for portions that are not shown.
% 
% Note that, for example, the code corresponding to
% module 55 begins with `\.{\{55:\}}' and ends with `\.{\{:55\}}';
% the code from modules 59--62 has been tangled into the code from module 58.
% 
% \vskip6pt
% \verbatim
% {2:}{4:}{$C-,A+,D-}{[$C+,D+]}{:4}
% PROGRAM WEAVE(WEBFILE,CHANGEFILE,TEXFILE);LABEL 9999;CONST{8:}
% MAXBYTES=45000;MAXNAMES=5000;MAXMODULES=2000;HASHSIZE=353;BUFSIZE=100;
%      .
% . .
% TOKPTR:0..MAXTOKS;{MAXTOKPTR,MAXTXTPTR:0..MAXTOKS;}{:53}{55:}
% IDFIRST:0..LONGBUFSIZE;IDLOC:0..LONGBUFSIZE;
% HASH:ARRAY[0..HASHSIZE]OF SIXTEENBITS;{:55}{63:}CURNAME:NAMEPOINTER;
%      .
% . .
% PROCEDURE INITIALIZE;VAR{16:}I:0..127;{:16}{40:}WI:0..1;{:40}{56:}
% H:0..HASHSIZE;{:56}{247:}C:ASCIICODE;{:247}BEGIN{10:}HISTORY:=0;{:10}
%      .
% . .
% TOKPTR:=1;TEXTPTR:=1;TOKSTART[0]:=1;TOKSTART[1]:=1;{MAXTOKPTR:=1;
% MAXTXTPTR:=1;}{:54}{57:}FOR H:=0 TO HASHSIZE-1 DO HASH[H]:=0;{:57}{94:}
% SCANNINGHEX:=FALSE;{:94}{102:}MODTEXT[0]:=32;{:102}{124:}OUTPTR:=1;
%      .
% . .
% IF R=0 THEN XREF[P]:=XREFPTR ELSE XMEM[R].XLINKFIELD:=XREFPTR;END;{:51}
% {58:}FUNCTION IDLOOKUP(T:EIGHTBITS):NAMEPOINTER;LABEL 31;
% VAR I:0..LONGBUFSIZE;H:0..HASHSIZE;K:0..MAXBYTES;W:0..1;
% L:0..LONGBUFSIZE;P:NAMEPOINTER;BEGIN L:=IDLOC-IDFIRST;{59:}
% H:=BUFFER[IDFIRST];I:=IDFIRST+1;
% WHILE I<IDLOC DO BEGIN H:=(H+H+BUFFER[I])MOD HASHSIZE;I:=I+1;END{:59};
% {60:}P:=HASH[H];
% WHILE P<>0 DO BEGIN IF(BYTESTART[P+2]-BYTESTART[P]=L)AND((ILK[P]=T)OR((T
% =0)AND(ILK[P]>3)))THEN{61:}BEGIN I:=IDFIRST;K:=BYTESTART[P];W:=P MOD 2;
% WHILE(I<IDLOC)AND(BUFFER[I]=BYTEMEM[W,K])DO BEGIN I:=I+1;K:=K+1;END;
% IF I=IDLOC THEN GOTO 31;END{:61};P:=LINK[P];END;P:=NAMEPTR;
% LINK[P]:=HASH[H];HASH[H]:=P;31:{:60};IF P=NAMEPTR THEN{62:}
% BEGIN W:=NAMEPTR MOD 2;
% IF BYTEPTR[W]+L>MAXBYTES THEN BEGIN WRITELN(TERMOUT);
% WRITE(TERMOUT,'! Sorry, ','byte memory',' capacity exceeded');ERROR;
% HISTORY:=3;JUMPOUT;END;
% IF NAMEPTR+2>MAXNAMES THEN BEGIN WRITELN(TERMOUT);
% WRITE(TERMOUT,'! Sorry, ','name',' capacity exceeded');ERROR;HISTORY:=3;
% JUMPOUT;END;I:=IDFIRST;K:=BYTEPTR[W];
% WHILE I<IDLOC DO BEGIN BYTEMEM[W,K]:=BUFFER[I];K:=K+1;I:=I+1;END;
% BYTEPTR[W]:=K;BYTESTART[NAMEPTR+2]:=K;NAMEPTR:=NAMEPTR+1;ILK[P]:=T;
% XREF[P]:=0;END{:62};IDLOOKUP:=P;END;{:58}{66:}
% FUNCTION MODLOOKUP(L:SIXTEENBITS):NAMEPOINTER;LABEL 31;VAR C:0..4;
%      .
% . .
% WRITE(TERMOUT,'(That was a fatal error, my friend.)');END;END{:263};
% END.{:261}
% ?endgroup
% \vfill\eject
% 
% \pageno=199 % take account of the page numbers for App's D and E.
% 
% \def\runninghead{APPENDIX F --- MACROS FOR FORMATTING}
% \section Appendix F: The \.{webmac.tex} file.
% This is the file that extends ``plain \TeX'' format in order to support the
% features needed by the output of \.{WEAVE}.
% 
% \vskip6pt
% \verbatim
% % standard macros for WEB listings (in addition to PLAIN.TEX)
% \xdef\fmtversion{\fmtversion+WEBMAC1.3} % identifies current set of macros
% \parskip 0pt % no stretch between paragraphs
% \parindent 1em % for paragraphs and for the first line of Pascal text
% 
% \font\eightrm=cmr8
% \let\sc=\eightrm \let\mainfont=\tenrm
% \font\titlefont=cmr7 scaled\magstep4 % title on the contents page
% \font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
% \font\tentex=cmtex10 % TeX extended character set (used in strings)
% 
% \def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
% \def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way
% \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
% \def\.#1{\hbox{\tentex % typewriter type for strings
%   \let\\=\BS % backslash in a string
%   \let\'=\RQ % right quote in a string
%   \let\`=\LQ % left quote in a string
%   \let\{=\LB % left brace in a string
%   \let\}=\RB % right brace in a string
%   \let\~=\TL % tilde in a string
%   \let\ =\SP % space in a string
%   \let\_=\UL % underline in a string
%   \let\&=\AM % ampersand in a string
%   #1}}
% \def\#{\hbox{\tt\char`\#}} % parameter sign
% \def\${\hbox{\tt\char`\$}} % dollar sign
% \def\%{\hbox{\tt\char`\%}} % percent sign
% \def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
% % circumflex accents can be obtained from \^^D instead of \^
% \def\AT!{@} % at sign for control text
% 
% \chardef\AM=`\& % ampersand character in a string
% \chardef\BS=`\\ % backslash in a string
% \chardef\LB=`\{ % left brace in a string
% \def\LQ{{\tt\char'22}} % left quote in a string
% \chardef\RB=`\} % right brace in a string
% \def\RQ{{\tt\char'23}} % right quote in a string
% \def\SP{{\tt\char`\ }} % (visible) space in a string
% \chardef\TL=`\~ % tilde in a string
% \chardef\UL=`\_ % underline character in a string
% 
% \newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
% \newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
% 
% \newcount\ind % current indentation in ems
% \def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
% \def\2{\global\advance\ind by-1} % indent one less notch
% \def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
% \def\4{\copy\bak} % backspace one notch
% \def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
% \def\6{\ifmmode\else\par % forced break
%   \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
% \def\7{\Y\6} % forced break and a little extra space
% 
% \let\yskip=\smallskip
% \def\to{\mathrel{.\,.}} % double dot, used only in math mode
% \def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1 #2.\par}}
% \def\lapstar{\rlap{*}}
% \def\startsection{\Q\noindent{\let\*=\lapstar\bf\modstar.\quad}}
% \def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
% \def\A{\note{See also}} % cross-reference for multiply defined section names
% \def\B{\mathopen{\.{@\{}}} % begin controlled comment
% \def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments
%   \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX}
% \def\D{\defin{define}} % macro definition
% \def\E{\cdot10^} % exponent in floating point constant
% \def\F{\defin{format}} % format definition
% \let\G=\ge % greater than or equal sign
% \def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant
% \let\I=\ne % unequal sign
% \def\J{\.{@\&}} % TANGLE's join operation
% \let\K=\gets % left arrow
% \let\L=\le % less than or equal sign
% \outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
%   \vskip12ptminus3pt\startsection\ignorespaces}
% \outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section
%   \def\rhead{\uppercase{\ignorespaces#2}} % define running headline
%   \message{*\modno} % progress report
%   \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file
%   \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces}
% \def\MN#1.{\par % common code for \M, \N
%   {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
%   \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
% \def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
% \def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
%   \sfcode`;=3000
%   \pretolerance 10000
%   \hyphenpenalty 10000 \exhyphenpenalty 10000
%   \global\ind=2 \1\ \unskip}
% \def\Q{\rightskip=0pt % get out of Pascal mode
%   \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
% \let\R=\lnot % logical not
% \let\S=\equiv % equivalence sign
% \def\T{\mathclose{\.{@\}}}} % terminate controlled comment
% \def\U{\note{This code is used in}} % cross-reference for uses of sections
% \let\V=\lor % logical or
% \let\W=\land % logical and
% \def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
%   \XX$\langle\,$#2{\eightrm\kern.5em#1}$\,\rangle$\XX}
% \def\Y{\par\yskip}
% \let\Z=\let % now you can \send the control sequence \Z
% \def\){\hbox{\.{@\$}}} % sign for string pool check sum
% \def\]{\hbox{\.{@\\}}} % sign for forced line break
% \def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
%         \hbox{\strut\kern2pt\.{#1}\kern2pt}}
%       \hrule}\vrule}\kern2pt} % verbatim string
% \let\~=\ignorespaces
% \let\*=*
% 
% \def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
% \newif\ifon \newif\iftitle \newif\ifpagesaved
% \def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
%   \tensy x\mainfont\topmark} % top line on left-hand pages
% \def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
%   \qquad\mainfont\the\pageno} % top line on right-hand pages
% \def\page{\box255 }
% \def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
%   \shipout\vbox{
%     \vbox to\fullpageheight{
%       \iftitle\global\titlefalse
%       \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
%       \vfill#1}} % parameter #1 is the page itself
%   \global\advance\pageno by1}
% 
% \def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
% \def\title{} % an optional title can be set by the user
% \def\topofcontents{\centerline{\titlefont\title}
%   \vfill} % this material will start the table of contents page
% \def\botofcontents{\vfill} % this material will end the table of contents page
% \def\contentspagenumber{0} % default page number for table of contents
% \newdimen\pagewidth \pagewidth=6.5in % the width of each page
% \newdimen\pageheight \pageheight=8.7in % the height of each page
% \newdimen\fullpageheight \fullpageheight=9in % page height including headlines
% \newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
% \def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
%   \fullpageheight=9truein\setpage}
% \def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
% \def\contentsfile{CONTENTS} % file that gets table of contents info
% \def\readcontents{\input CONTENTS}
% 
% \newwrite\cont
% \output{\setbox0=\page % the first page is garbage
%   \openout\cont=\contentsfile
%   \global\output{\normaloutput\page\lheader\rheader}}
% \setpage
% \vbox to \vsize{} % the first \topmark won't be null
% 
% \def\ch{\note{The following sections were changed by the change file:}
%   \let\*=\relax}
% \newbox\sbox % saved box preceding the index
% \newbox\lbox % lefthand column in the index
% \def\inx{\par\vskip6pt plus 1fil % we are beginning the index
%   \write\cont{} % ensure that the contents file isn't empty
%   \closeout\cont % the contents information has been fully gathered
%   \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
%     \global\setbox\sbox=\page \global\pagesavedtrue}
%   \pagesavedfalse \eject % eject the page-so-far and predecessors
%   \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
%   \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
%   \hsize=.5\pagewidth \advance\hsize by -10pt
%     % column width for the index (20pt between cols)
%   \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
%   \def\lr{L} % this tells whether the left or right column is next
%   \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
%     \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
%         \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
%     \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
%   \message{Index:}
%   \parskip 0pt plus .5pt
%   \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
%   \def\[##1]{$\underline{##1}$} % underlined index item
%   \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
%   \hyphenpenalty 10000 \parindent0pt}
% \def\fin{\par\vfill\eject % this is done when we are ending the index
%   \ifpagesaved\null\vfill\eject\fi % output a null index column
%   \if L\lr\else\null\vfill\eject\fi % finish the current page
%   \parfillskip 0pt plus 1fil
%   \def\rhead{NAMES OF THE SECTIONS}
%   \message{Section names:}
%   \output{\normaloutput\page\lheader\rheader}
%   \setpage
%   \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}}
%   \linepenalty=10 % try to conserve lines
%   \def\U{\note{Used in}} % cross-reference for uses of sections
%   \def\:{\par\hangindent 2em}\let\*=*}
% \def\con{\par\vfill\eject % finish the section names
%   \rightskip 0pt \hyphenpenalty 50 \tolerance 200
%   \setpage
%   \output{\normaloutput\page\lheader\rheader}
%   \titletrue % prepare to output the table of contents
%   \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
%   \message{Table of contents:}
%   \topofcontents
%   \line{\hfil Section\hbox to3em{\hss Page}}
%   \def\Z##1##2##3{\line{\ignorespaces##1
%     \leaders\hbox to .5em{.\hfil}\hfil\ ##2\hbox to3em{\hss##3}}}
%   \readcontents\relax % read the contents info
%   \botofcontents \end} % print the contents page(s) and terminate
% ?endgroup
% \vfill\eject
% 
\def\runninghead{APPENDIX G --- NOTES ON FORMATTING}
\section Appendix G: How to use \.{WEB} macros.
The macros in \.{webkernel} make it possible to produce a variety of formats
without editing the output of \.{WEAVE}, and the purpose of this appendix
is to explain some of the possibilities.

\def\point#1.{\yskip\indent#1.\quad\ignorespaces}

\point 1.
Three fonts have been declared in addition to the standard fonts of
\.{PLAIN} format: You can say `\.{\{\\sc stuff\}}' to get {\sc stuff}
in small caps; and you can select the largish fonts \.{\\titlefont}
and \.{\\ttitlefont} in the title of your document, where \.{\\ttitlefont}
is a typewriter style of type.

\point 2.
When you mention an identifier in \TeX\ text, you normally call
it `\.{|identifier|}'.
But you can also say `\.{\\\\\{identifier\}}'.
The
output will look the same in both cases, but the second alternative
doesn't put \\{identifier} into the index, since
it bypasses \.{WEAVE}'s translation from \PASCAL\ mode.

\point 3.
To get typewriter-like type, as when referring to `\.{WEB}', you
can use the `\.{\\.}' macro (e.g., `\.{\\.\{WEB\}}').
In the argument to
this macro you should insert an additional backslash before the symbols
listed as `special string characters' in the index to \.{WEAVE}, i.e.,
before backslashes and dollar signs and the like.
A `\.{\\\ }' here will result in the visible space symbol; to get an
invisible space following a control sequence you can say `\.{\{\ \}}'.

\point 4.
The three control sequences \.{\\pagewidth}, \.{\\pageheight},
and \.{\\fullpageheight} can be redefined in the limbo section at the
beginning of your \.{WEB} file, to change the dimensions of each page.
The standard settings
$$\lpile{\.{\\pagewidth=6.5in}\cr
  \.{\\pageheight=8.7in}\cr
  \.{\\fullpageheight=9in}\cr}$$
were used to prepare the present report; \.{\\fullpageheight} is
\.{\\pageheight} plus room for the additional heading and page numbers at
the top of each page.
If you change any of these quantities, you should
call the macro \.{\\setpage} immediately after making the change.

\point 5.
The \.{\\pageshift} macro defines an amount by which right-hand
pages (i.e., odd-numbered pages) are shifted right with respect to
left-hand (even-numbered) ones.
By adjusting this amount you may be
able to get two-sided output in which the page numbers line up on
opposite sides of each sheet.

\point 6.
The \.{\\title} macro will appear at the top of each page
in small caps.
For example, Appendix~D was produced after saying
`\.{\\def\\title\{WEAVE\}}'.
\newstuff
(Appendix~D was omitted from this document; see Don Knuth's original {\tt WEB}
technical report for all the appendices.)
\endnewstuff

\point 7.
The first page usually is number 1; if you want some other
starting page, just set \.{\\pageno} to the desired number.
For example,
the initial limbo section for Appendix~D included the command
`\.{\\pageno=16}'.

\point 8.
The macro \.{\\iftitle} will suppress the header line if it is
defined by `\.{\\titletrue}'.
The normal value is \.{\\titlefalse}
except for the table of contents; thus, the contents
page is usually unnumbered.
If your program is so long that the table of
contents doesn't fit on a single page, or if you want a number to appear
on the contents page, you should reset \.{\\pageno} when you begin the
table of contents.

Two macros are provided to give flexibility to the table of
contents: \.{\\topofcontents} is invoked just before the contents
info is read, and \.{\\botofcontents} is invoked just after.
For example, Appendix~D 
was produced with the following definitions:
$$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
  \.{ { }\\titlefalse \% include headline on the contents page}\cr
  \.{ { }\\def\\rheader\{\\mainfont Appendix D\\hfil 15\}}\cr
  \.{ { }\\centerline\{\\titlefont The \{\\ttitlefont WEAVE\}{ }processor\}}\cr
  \.{ { }\\vskip 15pt \\centerline\{(Version 2.5)\}{ }\\vfill\}}\cr}$$
Redefining \.{\\rheader}, which is the headline for right-hand pages,
suffices in this case to put the desired information at the top of the page.

\point 9.
Data for the table of contents is written to a file that
is read after the indexes have been \TeX ed; there's one line of data
for every starred module.
For example, when Appendix~D was being generated,
a file
% \.{CONTENTS.TEX} 
containing
$$\lpile{\.{\\Z \{{ }Introduction\}\{1\}\{16\}}\cr
  \.{\\Z \{{ }The character set\}\{11\}\{19\}}\cr}$$
and similar lines was created.
The \.{\\topofcontents} macro could
redefine \.{\\Z} so that the information appears in another format.

\point 10.
Sometimes it is necessary or desirable to divide the output of
\.{WEAVE} into subfiles that can be processed separately.
For example,
the listing of \TeX\ runs to more than 500 pages, and that is enough to
exceed the capacity of many printing devices and/or their software.
When an extremely large job isn't cut into smaller pieces, the entire
process might be spoiled by a single error of some sort, making it
necessary to start everything over.

Here's a safe way to break a woven file into three parts:
Say the pieces are $\alpha$,
$\beta$, and $\gamma$, where each piece begins with a starred module.
All macros should be defined in the opening limbo section of $\alpha$,
and copies of this \TeX\ code should be placed at the
beginning of $\beta$ and of $\gamma$.
In order to process the parts
separately, we need to take care of two things: The starting page
numbers of $\beta$ and $\gamma$ need to be set up properly, and
the table of contents data from all three runs needs to be
accumulated.

The \.{webmac} macros include two control sequences \.{\\contentsfile} and
\.{\\readcontents} that facilitate the necessary processing.
We include
`\.{\\def\\contentsfile\{CONT1\}}' in the limbo section of $\alpha$, and
we include `\.{\\def\\contentsfile\{CONT2\}}' in the limbo section of
$\beta$; this causes \TeX\ to write the contents data for $\alpha$ and $\beta$
into \.{CONT1.TEX} and \.{CONT2.TEX}.
Now in $\gamma$ we say
$$\.{\\def\\readcontents\{\\input CONT1 \\input CONT2 \\input CONTENTS\}};$$
this brings in the data from all three pieces, in the proper order.

\newstuff
Warning: life is a little different in Spidery {\tt WEB}.
{\TeX} hackers should go straight to the source.
\endnewstuff

However, we still need to solve the page-numbering problem.
One way to
do it is to include the following in the limbo material for $\beta$:
$$\lpile{\.{\\message\{Please type the last page number of part 1: \}}\cr
  \.{\\read-1to\\\\ \\pageno=\\\\ \\advance\\pageno by 1}\cr}$$
Then you simply provide the necessary data when \TeX\ requests
it; a similar construction is used at the beginning of $\gamma$.

This method can, of course, be used to divide a woven file into
any number of pieces.

\point 11.
Sometimes it is nice to include things in the index that are
typeset in a special way.
For example, we might want to have an
index entry for `\TeX'.
\.{WEAVE} provides only two standard ways to
typeset an index entry (unless the entry is an identifier or a reserved word):
`\.{@\^}' gives roman type, and `\.{@.}' gives typewriter type.
But if we try to typeset `\TeX' in roman type by saying, e.g.,
`\.{@\^\\TeX@>}', the backslash character gets in the way,
and this entry wouldn't appear in the index with the T's.

The solution is to use the `\.{@:}' feature, declaring a macro that
simply removes a sort key as follows:
$$\.{\\def\\9\#1\{\}}$$
Now you can say, e.g., `\.{@:TeX\}\{\\TeX@>}' in your \.{WEB} file; \.{WEAVE}
puts it into the index alphabetically, based on the sort key, and
produces the macro call `\.{\\9\{TeX\}\{\\TeX\}}' which will ensure that
the sort key isn't printed.

A similar idea can be used to insert hidden material into module
names so that they are alphabetized in whatever way you might wish.
Some people call these tricks ``special refinements''; others call
them ``kludges''.

\point 12.
The control sequence \.{\\modno} is set to the number of the
module being typeset.

\point 13.
If you want to list only the modules that have changed,
together with the index, put the command `\.{\\let\\maybe=\\iffalse}' in
the limbo section before the first module of your \.{WEB} file.
It's
customary to make this the first change in your change file.

\vfill

\eject
% 
% \def\runninghead{APPENDIX H --- GETTING STARTED}
% \section Appendix H: Installing the \.{WEB} system.
% Suppose you want to use the \.{WEB} programs on your computer, and suppose
% that you can't simply borrow them from somebody else who has the same
% kind of machine.
% Here's what to do:
% 
% \yskip
% \def\step(#1){\par\hangindent 2em\noindent\hbox to 2em{\hfil(#1) }\ignorespaces}
% \step(1) Get a tape that contains the files \.{WEAVE.WEB}, \.{TANGLE.WEB},
% \.{TANGLE.PAS}, and \.{WEBMAC.TEX}.
% The tape will probably also contain an
% example change file \.{TANGLE.CH}.
% \step(2) Look at the sections of \.{TANGLE} that are listed under ``system
% dependencies'' in the index of Appendix~E above, and figure out what changes
% (if any) will be needed for your system.
% \step(3) Make a change file \.{TANGLE.CH} that contains the changes of~(2);
% do not change your copy of \.{TANGLE.WEB}, leave it intact.
% (The
% rules for change files are explained at the end of the manual just before
% the appendices; you may want to look at the example change file that
% arrived with your copy of \.{TANGLE.WEB}.
% It's also a good idea to
% define all the ``switches'' like \&{debug} and \&{gubed} to be null in your
% first change files; then you can sure that your compiler will handle
% all of the code.)
% \step(4) Make the changes of (2) in your copy of \.{TANGLE.PAS}.
% (If these
% changes are extensive, you might be better off finding some computer that
% that already has \.{TANGLE} running, and making the new \.{TANGLE.PAS}
% from \.{TANGLE.WEB} and your \.{TANGLE.CH}.)
% \step(5) Use your \PASCAL\ compiler to convert your copy of \.{TANGLE.PAS}
% to a running program \.{TANGLE}.
% \step(6) Check your changes as follows: Run \.{TANGLE} on \.{TANGLE.WEB}
% and your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}'$; make a running
% program $\.{TANGLE}'$ by applying \PASCAL\ to
% $\.{TANGLE.PAS}'$; run $\.{TANGLE}'$ on \.{TANGLE.WEB} and
% your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}''$; and check
% that $\.{TANGLE.PAS}''$ is identical to
% $\.{TANGLE.PAS}'$.
% Once this test has been passed, you have got a
% working \.{TANGLE} program.
% \step(7) Make a change file \.{WEAVE.CH} analogous to (3), but this time
% consider the system-dependent parts of \.{WEAVE} that are listed in
% the index to Appendix~D.
% \step(8) Run \.{TANGLE} on \.{WEAVE.WEB} and your \.{WEAVE.CH}, obtaining
% \.{WEAVE.PAS}.
% \step(9) Use \PASCAL\ on \.{WEAVE.PAS} to make a running \.{WEAVE} program.
% \step(10) Run \.{WEAVE} on \.{TANGLE.WEB} and \.{TANGLE.CH} to produce
% \.{TANGLE.TEX}.
% \step(11) Run \TeX\ on \.{TANGLE.TEX}, obtaining a listing analogous to
% Appendix~E.
% This listing will incorporate your changes.
% \step(12) Run \.{WEAVE} on \.{WEAVE.WEB} and your \.{WEAVE.CH} to produce
% \.{WEAVE.TEX}.
% \step(13) Run \TeX\ on \.{WEAVE.TEX}, obtaining a listing analogous to
% Appendix~D that incorporates your changes.
% 
% \yskip\noindent
% This description assumes that you already have a working \TeX82 system.
% But what if you don't have \TeX82?
% Then you start with a tape that also
% contains \.{TEX.WEB} and \.{plain.tex}, and you refer to a hardcopy
% listing of the \TeX82 program corresponding to \.{TEX.WEB}.
% Between steps
% (10) and (11) you do the following:
% 
% \yskip
% \def\substep(10.#1){\par\hangindent 4em\noindent
%   \hbox to 4em{\hfil(10.#1) }\ignorespaces}
% \substep(10.1) Make a change file \.{TEX.CH} to fix the system dependent
% portions of \.{TEX.WEB}, in a manner analogous to step~(2).
% Since \TeX\ is
% a much more complex program than \.{WEAVE} or \.{TANGLE}, there are more
% system-dependent features to think about, but by now you will be good at
% making such modifications.
% Do not make any changes to \.{TEX.WEB}.
% \substep(10.2) Make an almost-copy of your \.{TEX.CH} called \.{INITEX.CH};
% this one will have the `\&{init}' and `\&{tini}' macros redefined in order
% to make the initialization version of \TeX.
% It also might have smaller
% font memory and dynamic memory areas, since \.{INITEX} doesn't need as
% much memory for such things; by setting the memory smaller in \.{INITEX},
% you guarantee that the production system will have a ``cushion.''
% \substep(10.3) Run \.{TANGLE} on \.{TEX.WEB} and \.{INITEX.CH}, obtaining
% \.{INITEX.PAS} and \.{TEX.POOL}.
% \substep(10.4) Run \PASCAL\ on \.{INITEX.PAS}, obtaining \.{INITEX}.
% \substep(10.5) Run \.{INITEX} on \.{TEX.POOL}, during which run you type
% `\.{plain}' and `\.{\\dump}'.
% This will produce a file \.{plain.fmt}
% containing the data needed to initialize \TeX's memory.
% \substep(10.6) Run \.{TANGLE} on \.{TEX.WEB} and the \.{TEX.CH} of (10.1),
% obtaining \.{TEX.PAS}.
% \substep(10.7) Run \PASCAL\ on \.{TEX.PAS}, obtaining \.{VIRTEX}.
% \substep(10.8) If your operating system supports programs whose core images
% have been saved, run \.{VIRTEX}, type `\.{\&plain}', then save the core image
% and call it \TeX.
% Otherwise, \.{VIRTEX} will be your \TeX, and it will
% read `\.{plain.fmt}' (or some other \.{fmt} file) each time you run.
% 
% \yskip
% This 21-step process may seem long, but it is actually an oversimplification,
% since you also need fonts and a way to print the device-independent files
% that \TeX\ spews out.
% On the other hand, the total number of steps is not
% quite so large when you consider that \.{TANGLE}-followed-by-\PASCAL\ and
% \.{WEAVE}-followed-by-\TeX\ may be regarded as single operations.
% 
% If you have only the present report, not a tape, you will have to prepare
% files \.{WEAVE.WEB} and \.{TANGLE.WEB} by hand, typing them into the
% computer by following Appendices D and E.
% Then you have to simulate the
% behavior of \.{TANGLE} by converting \.{TANGLE.WEB} manually into
% \.{TANGLE.PAS}; with a good text editor this takes about six hours.
% Then
% you have to correct errors that were made in all this hand work; but still
% the whole project is not impossibly difficult, because in fact the entire
% development of \.{WEAVE} and \.{TANGLE} (including the writing of the
% programs and the manual) took less than two months of work.
% 
% \vfill

\end