Date: 5 November 89 Message No: 020 To: TeX implementors and distributors From: Barbara Beeton Subject: Message from Knuth re TeX 3.0; updates to TANGLE and WEAVE The following two messages have just appeared in TeXhax; though most of you have probably seen them already, I am repeating them here just in case. The new .WEB files are all in place at @labrea.stanford.edu as described by Joe Weening. Since the changes are quite extensive, I believe it would be best, if at all possible, to get new copies of the complete .WEB files. But since I know that will be very difficult for some, I will send copies of the difference files between the last versions and the new ones. The differences for TANGLE and WEAVE are included in this message. The differences for TeX.WEB will follow in six parts. I will try to include a listing of the important new files at labrea in my next (numbered) message. Metafont will take a little longer. I am trying to arrange for the TRIP and TRAP files to be installed in archives that have mail servers to make it possible for those with only mail access to retrieve them by that method, and to make other foolproof arrangements for implementors who can't retrieve reliable copies even in that way. Please stay tuned. -------------------- Date: 27 Oct 89 1211 PDT From: Don Knuth Subject: Calling all Grand Wizards Keywords: TeX, new versions I'm hoping to muster as many as possible of TeX's past masters for an important battle charge, as we lead TeX into the 90s! You may have heard rumors that my resistance to change was temporarily worn down during the recent TUG meeting. Well, it's true: I caved in, and decided to make a TeX version 3.0 that differs substantially from the present version 2.991. The new version is upward compatible, nearly as fast, and only about 10K bytes larger if you don't make full use of the new capabilities. During the past few weeks I have hacked the new version together, and it is now ready for beta-testing. I hope it can be spread rapidly to the hundreds of different machine/operatingsystem configurations that currently run yesterday's version. So I desperately need your help. How about it --- won't it be fun to have one last go at TeX and MF, as they enter their truly final stage? I am now convinced that the new version is the natural, ultimate conclusion to the philosophy I adopted in TeX82 and MF84. Major changes were needed to many of the previous programs. I have prepared and tested the following new versions: TeX version 2.992 (will become 3.0 as soon as two months go by without bug reports) MF version 1.8 (will become 2.0, similarly) TANGLE version 4 WEAVE version 4 POOLtype version 3 TFtoPL version 3 PLtoTF version 3 GFtoDVI version 3 MFtype version 2 The changes fall mostly into three categories: (1) Input files are allowed to contain arbitrary 8-bit characters; previously only 7-bit character sets were supported on input. This means in particular that TANGLE now starts its string pool with string number 256, not 128; all programs that use WEB's string pool feature need to be revised, as they will no longer work with the new TANGLE. (Actually I don't know of any such programs except variants of TeX and MF.) (2) The new TeX supports hyphenation in 256 languages simultaneously. These changes were inspired by Michael Ferguson's Multi-lingual TeX, by my implementation is quite different from his. (3) There is a greatly improved ligature mechanism, allowing (for example) letters to change based on their being at the beginning or end of a word. This upward-compatible extension of TFM format allows ligature/kern programs to be up to 32K words long, and it also has a `skip' command for code-sharing to help keep programs compact. Each of these new features affects many hundreds of lines of code. Altogether 218 of TeX's 1377 modules have been changed; dozens of modules have been completely rewritten. I don't think the change files will be severely affected, but the new situation should still be looked at by experts because expertise is needed to do things right. For example, the 8-bit extension to TANGLE looks fairly innocuous, but on my Sun-UNIX system I had to change one of the accompanying C routines (lineread) because the buffer is now an array of 0..255 instead of an array of 0..127; consequently the Berkeley Pascal compiler now uses two bytes for each buffer element! In TANGLE and WEAVE I can afford that extra memory, but not in TeX or MF; so I've made provisions in the latter for optionally adding/subtracting 128 when reading/writing string pool elements. In your change file you only need to redefine two WEB macros to make that happen; but you also need to change one line of the system-dependent calledit function (which reads directly from TeX/MF's string pool). To run the new TRIP test, you need the new PLtoTF; otherwise you won't have a test font with its new ligature mechanisms. To run the new TRAP test, you need the new TFtoPL in order to test MF's new ability to generate such ligature data. Look for the phrase "change file" in the files tex82.bug and mf84.bug for a few hints. Once you have these new systems working, there will be much more to do in order to make best use of the new 8-bit capabilities. But that can be done in a more relaxed way; the big upgrade in the basic systems needs to be done quickly. With your help, this transition should go very smoothly; we should have trouble only when people who use the new facilities try to do so on old versions of TeX and MF. Therefore: THE SOONER WE STAMP OUT THE OLD VERSIONS, THE BETTER. I've put copies of the new sources on the master TeX archive at Stanford. Joe Weening will soon be sending a message to TeXhax announcing the new location and organization of this archive. I've also sent copies of my personal change files, and updated the files that log all the changes. I hope this material will propagate soon to other TeX archives around the world. A complete list of changes to The TeXbook and The METAFONTbook will appear in the next TUGboat, which has just gone to the printer. A new printing of Volume A is now in the bindery and will be available soon in bookstores; this contains all the version 3.0 changes to TeX. (You will be able to identify it by the words "ninth printing" on the copyright page, on the back of the title page.) Unfortunately the publishers had just made a large printing of the paperback version before I decided to make these changes, so it will be a few months before the paperback version of the TeXbook is updated; at that time it will be recognizable by the words "Seventeenth printing". A-W is keeping two independent numbering schemes for printings of the hardback and paperback versions. The finder's fee for bugs in the new code is $10.24. And if you discover a bug in the "old" paats of TeX while you're installing the new version, you win $163.84. ------------------------------------------------------------------------------ Date: Sat, 28 Oct 89 14:00:50 PDT From: Joe Weening Subject: ***Announcing the new Stanford TeX archive*** Keywords: Stanford TeX archive As you may have heard, the host Score.Stanford.EDU (a DECsystem-2060) has been retired after 10 years of faithful service to Stanford and the TeX community. The files that were in the directories at Score have been moved to the host Labrea.Stanford.EDU, which is a VAX-11/750 running 4.3 BSD Unix, used mainly as a file repository for the Stanford Computer Science Department. Labrea's Internet address is 36.8.0.47. To get TeX files from Labrea, open an FTP connection and log in as the user "anonymous", with any password. Connect to the directory "tex" (or "pub/tex", they are the same), and you will be at the top level of the TeX distribution directory. The files on Labrea are organized somewhat differently from the way they were on Score. This was done to correspond to the directory organization that Don Knuth is now using for his TeX development work on a Unix system. Files that were specific to Score have mostly been removed. On October 27, new versions of many programs and files were installed on Labrea. These include: TeX version 2.992 (beta release of 3.0) MF version 1.8 (beta release of 2.0) TANGLE version 4 WEAVE version 4 POOLtype version 3 TFtoPL version 3 PLtoTF version 3 GFtoDVI version 3 MFtype version 2 Don Knuth will soon send a message to TeXhax that describes these programs in more detail. If you FTP files from Labrea, please: - schedule major FTP sessions outside of normal working hours - take only the files you need Labrea is not a fast machine, and is easily overloaded by too much FTP traffic. Below is a short description of the TeX subdirectories on Labrea. Note that the copy of the Unix TeX distribution is now several months old; it contains TeX version 2.95 and other programs of similar vintage (late 1988/early 1989). Most people already have this version; if you don't, you probably want to wait until TeX 3.0 is incorporated into Unix TeX. amsfonts AMS Cyrillic and math symbols fonts amstex The AMSTeX macros archive Old files kept for posterity bibtex The BibTeX program and related files cm Metafont sources for the Computer Modern fonts errata Error logs for programs and documentation fonts TFM files for standard (and some non-standard) fonts gf GF font files (for Imagen and Lasewriter) imagen Various files to support Imagen printers latex LaTeX macros, font sources, related files lib Input files read by TeX, Metafont and other programs local Additional unsupported files from Don Knuth ln03 Various files to support LN03 printers mf Metafont source code and documentation mfware Metafont utilities tex TeX source code and documentation texware TeX utilities texhax TeXhax archives tugboat Files for things mentioned in TUGboat unix Unix TeX distribution from University of Washington unsupported Unsupported files from various sources web The WEB system It's possible that in the process of moving things, some files were accidentally removed or transferred incorrectly. If you find any problems with the TeX files on Labrea, please send a message to "tex@labrea.stanford.edu". ######################################################################## Differences between Tangle 3.0 and 4.0 ;COMPARISON OF TX:TANGLE-30.WEB.1 AND TX:TANGLE-4-.WEB.1 ;OPTIONS ARE /E /3 **** FILE TX:TANGLE-30.WEB.1, 1-14 (887) % Version 2.9 allows nonnumeric macros before their definition (December, 1988). % Version 3, for Sewell's book, fixed a long-line bug in input_ln (March, 1989). % Here is TeX material that gets inserted after \input webmac **** FILE TX:TANGLE-4-.WEB.1, 1-14 (887) % Version 2.9 allows nonnumeric macros before their def (December, 1988). % Version 3, for Sewell's book, fixed long-line bug in input_ln (March, 1989). % Version 4 was major change to allow 8-bit input (September, 1989). % Here is TeX material that gets inserted after \input webmac *************** **** FILE TX:TANGLE-30.WEB.1, 1-34 (1754) \centerline{(Version 3)} \vfill} **** FILE TX:TANGLE-4-.WEB.1, 1-35 (1815) \centerline{(Version 4)} \vfill} *************** **** FILE TX:TANGLE-30.WEB.1, 2-26 (3016) @d banner=='This is TANGLE, Version 3' @ The program begins with a fairly normal header, made up of pieces that **** FILE TX:TANGLE-4-.WEB.1, 1-64 (3078) @d banner=='This is TANGLE, Version 4' @ The program begins with a fairly normal header, made up of pieces that *************** **** FILE TX:TANGLE-30.WEB.1, 3-9 (10746) to an internal seven-bit code that is essentially standard ASCII, the ``American Standard Code for Information Interchange.'' The conversion is done **** FILE TX:TANGLE-4-.WEB.1, 1-225 (10809) to an internal eight-bit code that is essentially standard ASCII, the ``American Standard Code for Information Interchange.'' The conversion is done *************** **** FILE TX:TANGLE-30.WEB.1, 3-13 (11042) they are output. Such an internal code is relevant to users of \.{WEB} only because it is **** FILE TX:TANGLE-4-.WEB.1, 1-229 (11105) they are output. (The original ASCII code was seven bits only; \.{WEB} now allows eight bits in an attempt to keep up with modern times.) Such an internal code is relevant to users of \.{WEB} only because it is *************** **** FILE TX:TANGLE-30.WEB.1, 3-60 (12987) @!ASCII_code=0..127; {seven-bit numbers, a subrange of the integers} @ The original \PASCAL\ compiler was designed in the late 60s, when six-bit **** FILE TX:TANGLE-4-.WEB.1, 1-277 (13172) @!ASCII_code=0..255; {eight-bit numbers, a subrange of the integers} @ The original \PASCAL\ compiler was designed in the late 60s, when six-bit *************** **** FILE TX:TANGLE-30.WEB.1, 3-81 (14211) @d last_text_char=127 {ordinal number of the largest element of |text_char|} @= **** FILE TX:TANGLE-4-.WEB.1, 1-298 (14396) @d last_text_char=255 {ordinal number of the largest element of |text_char|} @= *************** **** FILE TX:TANGLE-30.WEB.1, 3-230 (18596) @!i:0..last_text_char; @ Here now is the system-dependent part of the character set. **** FILE TX:TANGLE-4-.WEB.1, 1-447 (18781) @!i:0..255; @ Here now is the system-dependent part of the character set. *************** **** FILE TX:TANGLE-30.WEB.1, 3-235 (18831) don't need to make any changes here. But at MIT, for example, the code in this module should be changed to $$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$ \.{WEB}'s character set is essentially identical to MIT's, even with respect to characters less than @'40. **** FILE TX:TANGLE-4-.WEB.1, 1-452 (19005) don't need to make any changes here. But if you have, for example, an extended character set like the one in Appendix~C of {\sl The \TeX book}, the first line of code in this module should be changed to $$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$ \.{WEB}'s character set is essentially identical to \TeX's, even with respect to characters less than @'40. *************** **** FILE TX:TANGLE-30.WEB.1, 3-261 (20107) @ The following system-independent code makes the |xord| array contain a **** FILE TX:TANGLE-4-.WEB.1, 1-478 (20377) for i:=@'200 to @'377 do xchr[i]:=' '; @ The following system-independent code makes the |xord| array contain a *************** **** FILE TX:TANGLE-30.WEB.1, 3-265 (20249) for i:=first_text_char to last_text_char do xord[chr(i)]:=@'40; for i:=1 to @'176 do xord[xchr[i]]:=i; @* Input and output. **** FILE TX:TANGLE-4-.WEB.1, 1-484 (20561) for i:=first_text_char to last_text_char do xord[chr(i)]:=" "; for i:=1 to @'377 do xord[xchr[i]]:=i; xord[' ']:=" "; @* Input and output. *************** **** FILE TX:TANGLE-30.WEB.1, 6-2 (29176) Most of the user's \PASCAL\ code is packed into seven- or eight-bit integers in two large arrays called |byte_mem| and |tok_mem|. **** FILE TX:TANGLE-4-.WEB.1, 1-708 (29507) Most of the user's \PASCAL\ code is packed into eight-bit integers in two large arrays called |byte_mem| and |tok_mem|. *************** **** FILE TX:TANGLE-30.WEB.1, 6-94 (33903) name_ptr:=1; string_ptr:=128; pool_check_sum:=271828; @ Replacement texts are stored in |tok_mem|, using similar conventions. **** FILE TX:TANGLE-4-.WEB.1, 1-800 (34224) name_ptr:=1; string_ptr:=256; pool_check_sum:=271828; @ Replacement texts are stored in |tok_mem|, using similar conventions. *************** **** FILE TX:TANGLE-30.WEB.1, 6-111 (34873) these are the starting positions for the next |ww| replacement texts to be stored in |tok_mem|. **** FILE TX:TANGLE-4-.WEB.1, 1-817 (35194) these are the starting positions for the next |zz| replacement texts to be stored in |tok_mem|. *************** **** FILE TX:TANGLE-30.WEB.1, 7-123 (43797) @^uppercase@> @= **** FILE TX:TANGLE-4-.WEB.1, 1-1021 (44121) @= *************** **** FILE TX:TANGLE-30.WEB.1, 7-138 (44159) @ If a nonnumeric macro has appeared before it was defined, \.{TANGLE} will still work all right; after all, such behavior is typical of the replacement texts for modules, which act very much like macros. However, an undefined numeric macro may not be used on the right-hand side of another numeric macro definition, so \.{TANGLE} finds it simplest to make a blanket rule that numeric macros should be defined before they are used. The following routine gives an error message and also fixes up any damage that may have been caused. @= {now |p<>name_ptr| and |t<>normal|} **** FILE TX:TANGLE-4-.WEB.1, 1-1034 (44466) @ If a nonnumeric macro has appeared before it was defined, \.{TANGLE} will still work all right; after all, such behavior is typical of the replacement texts for modules, which act very much like macros. However, an undefined numeric macro may not be used on the right-hand side of another numeric macro definition, so \.{TANGLE} finds it simplest to make a blanket rule that numeric macros should be defined before they are used. The following routine gives an error message and also fixes up any damage that may have been caused. @= {now |p<>name_ptr| and |t<>normal|} *************** **** FILE TX:TANGLE-30.WEB.1, 7-201 (46559) begin if c>="a" then c:=c-@'40; {convert to uppercase} @^uppercase@> if chopped_id[s]<>c then goto not_found; **** FILE TX:TANGLE-4-.WEB.1, 1-1097 (46866) begin if c>="a" then c:=c-@'40; {merge lowercase with uppercase} if chopped_id[s]<>c then goto not_found; *************** **** FILE TX:TANGLE-30.WEB.1, 14-54 (108852) othercases do_nothing endcases; **** FILE TX:TANGLE-4-.WEB.1, 1-2660 (109161) othercases if c>=128 then goto restart {ignore nonstandard characters} else do_nothing endcases; *************** **** FILE TX:TANGLE-30.WEB.1, 19-14 (129641) if string_ptr>128 then @; stat @;@+tats@;@/ **** FILE TX:TANGLE-4-.WEB.1, 1-3234 (130023) if string_ptr>256 then @; stat @;@+tats@;@/ *************** **** FILE TX:TANGLE-30.WEB.1, 19-30 (130142) begin print_nl(string_ptr-128:1, ' strings written to string pool file.'); write(pool,'*'); **** FILE TX:TANGLE-4-.WEB.1, 1-3250 (130524) begin print_nl(string_ptr-256:1, ' strings written to string pool file.'); write(pool,'*'); *************** ######################################################################## Differences between WEAVE 3.1 and 4.0 ;COMPARISON OF TX:WEAVE-31.WEB.1 AND TX:WEAVE-40.WEB.1 ;OPTIONS ARE /E /3 **** FILE TX:WEAVE-31.WEB.1, 1-25 (1561) % Here is TeX material that gets inserted after \input webmac **** FILE TX:WEAVE-40.WEB.1, 1-24 (1559) % Version 4 was major change to allow 8-bit input (September, 1989). % Here is TeX material that gets inserted after \input webmac *************** **** FILE TX:WEAVE-31.WEB.1, 1-44 (2350) \centerline{(Version 3.1)} \vfill} **** FILE TX:WEAVE-40.WEB.1, 1-45 (2420) \centerline{(Version 4)} \vfill} *************** **** FILE TX:WEAVE-31.WEB.1, 1-71 (3456) @d banner=='This is WEAVE, Version 3.1' @ The program begins with a fairly normal header, made up of pieces that **** FILE TX:WEAVE-40.WEB.1, 1-72 (3524) @d banner=='This is WEAVE, Version 4' @ The program begins with a fairly normal header, made up of pieces that *************** **** FILE TX:WEAVE-31.WEB.1, 1-229 (10839) converted to an internal seven-bit code that is essentially standard ASCII, the ``American Standard Code for Information Interchange.'' The conversion is done immediately when each character is read in. Conversely, characters are converted from ASCII to the user's external representation just before they are output. Such an internal code is relevant to users of \.{WEB} only because it is **** FILE TX:WEAVE-40.WEB.1, 1-230 (10905) converted to an internal eight-bit code that is essentially standard ASCII, the ``American Standard Code for Information Interchange.'' The conversion is done immediately when each character is read in. Conversely, characters are converted from ASCII to the user's external representation just before they are output. (The original ASCII code was seven bits only; \.{WEB} now allows eight bits in an attempt to keep up with modern times.) Such an internal code is relevant to users of \.{WEB} only because it is *************** **** FILE TX:WEAVE-31.WEB.1, 1-280 (13090) @!ASCII_code=0..127; {seven-bit numbers, a subrange of the integers} @ The original \PASCAL\ compiler was designed in the late 60s, when six-bit **** FILE TX:WEAVE-40.WEB.1, 1-283 (13278) @!ASCII_code=0..255; {eight-bit numbers, a subrange of the integers} @ The original \PASCAL\ compiler was designed in the late 60s, when six-bit *************** **** FILE TX:WEAVE-31.WEB.1, 1-301 (14314) @d last_text_char=127 {ordinal number of the largest element of |text_char|} @= **** FILE TX:WEAVE-40.WEB.1, 1-304 (14502) @d last_text_char=255 {ordinal number of the largest element of |text_char|} @= *************** **** FILE TX:WEAVE-31.WEB.1, 1-450 (18699) @!i:0..last_text_char; @ Here now is the system-dependent part of the character set. **** FILE TX:WEAVE-40.WEB.1, 1-453 (18887) @!i:0..255; @ Here now is the system-dependent part of the character set. *************** **** FILE TX:WEAVE-31.WEB.1, 1-455 (18934) don't need to make any changes here. But at MIT, for example, the code in this module should be changed to $$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$ \.{WEB}'s character set is essentially identical to MIT's, even with respect to characters less than @'40. **** FILE TX:WEAVE-40.WEB.1, 1-458 (19111) don't need to make any changes here. But if you have, for example, an extended character set like the one in Appendix~C of {\sl The \TeX book}, the first line of code in this module should be changed to $$\hbox{|for i:=1 to @'37 do xchr[i]:=chr(i);|}$$ \.{WEB}'s character set is essentially identical to \TeX's, even with respect to characters less than @'40. *************** **** FILE TX:WEAVE-31.WEB.1, 1-481 (20209) @ The following system-independent code makes the |xord| array contain a **** FILE TX:WEAVE-40.WEB.1, 1-484 (20482) for i:=@'200 to @'377 do xchr[i]:=' '; @ The following system-independent code makes the |xord| array contain a *************** **** FILE TX:WEAVE-31.WEB.1, 1-485 (20351) for i:=first_text_char to last_text_char do xord[chr(i)]:=@'40; for i:=1 to @'176 do xord[xchr[i]]:=i; @* Input and output. **** FILE TX:WEAVE-40.WEB.1, 1-490 (20666) for i:=first_text_char to last_text_char do xord[chr(i)]:=" "; for i:=1 to @'377 do xord[xchr[i]]:=i; xord[' ']:=" "; @* Input and output. *************** **** FILE TX:WEAVE-31.WEB.1, 1-702 (29203) packed with seven-bit integers. Allocation is sequential, since names are never deleted. **** FILE TX:WEAVE-40.WEB.1, 1-708 (29534) packed with eight-bit integers. Allocation is sequential, since names are never deleted. *************** **** FILE TX:WEAVE-31.WEB.1, 1-1728 (70568) othercases do_nothing endcases; **** FILE TX:WEAVE-40.WEB.1, 1-1734 (70899) othercases if c>=128 then goto restart {ignore nonstandard characters} else do_nothing endcases; *************** **** FILE TX:WEAVE-31.WEB.1, 1-2149 (86167) @= **** FILE TX:WEAVE-40.WEB.1, 1-2155 (86564) @.\\input webmac@> @.webmac@> @= *************** **** FILE TX:WEAVE-31.WEB.1, 1-4029 (159733) begin out2("\")(a+-cancel+"0"); @.\\1@> **** FILE TX:WEAVE-40.WEB.1, 1-4038 (160164) begin out2("\")(a-cancel+"0"); @.\\1@> *************** **** FILE TX:WEAVE-31.WEB.1, 1-4522 (177387) identifiers into 102 different lists based on their first characters. (Uppercase letters are put into the same list as the corresponding lowercase **** FILE TX:WEAVE-40.WEB.1, 1-4531 (177817) identifiers into 230 different lists based on their first characters. (Uppercase letters are put into the same list as the corresponding lowercase *************** **** FILE TX:WEAVE-31.WEB.1, 1-4539 (178139) for c:=0 to 127 do bucket[c]:=0; for h:=0 to hash_size-1 do **** FILE TX:WEAVE-40.WEB.1, 1-4548 (178569) for c:=0 to 255 do bucket[c]:=0; for h:=0 to hash_size-1 do *************** **** FILE TX:WEAVE-31.WEB.1, 1-4576 (179660) |collate[0]=@!collate:array[0..100] of ASCII_code; {collation order} @ @= **** FILE TX:WEAVE-40.WEB.1, 1-4585 (180090) |collate[0]=@!collate:array[0..229] of ASCII_code; {collation order} @ @= *************** **** FILE TX:WEAVE-31.WEB.1, 1-4593 (180227) for c:="z"+1 to 126 do collate[c-63]:=c; collate[64]:="_"; for c:="a" to "z" do collate[c-"a"+65]:=c; for c:="0" to "9" do collate[c-"0"+91]:=c; @ Procedure |unbucket| goes through the buckets and adds nonempty lists **** FILE TX:WEAVE-40.WEB.1, 1-4602 (180657) for c:="z"+1 to 255 do collate[c-63]:=c; collate[193]:="_"; for c:="a" to "z" do collate[c-"a"+194]:=c; for c:="0" to "9" do collate[c-"0"+220]:=c; @ Procedure |unbucket| goes through the buckets and adds nonempty lists *************** **** FILE TX:WEAVE-31.WEB.1, 1-4608 (180859) begin for c:=100 downto 0 do if bucket[collate[c]]>0 then begin if sort_ptr>max_sorts then overflow('sorting'); **** FILE TX:WEAVE-40.WEB.1, 1-4617 (181292) begin for c:=229 downto 0 do if bucket[collate[c]]>0 then begin if sort_ptr>max_sorts then overflow('sorting'); *************** ######################################################################## %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Character code reference %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Upper case letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ % Lower case letters: abcdefghijklmnopqrstuvwxyz % Digits: 0123456789 % Square, curly, angle braces, parentheses: [] {} <> () % Backslash, slash, vertical bar: \ / | % Punctuation: . ? ! , : ; % Underscore, hyphen, equals sign: _ - = % Quotes--right left double: ' ` " %"at", "number" "dollar", "percent", "and": @ # $ % & % "hat", "star", "plus", "tilde": ^ * + ~ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% [ end of message 020 ]