diff --git a/build/emacs.tcl b/build/emacs.tcl index 960848ca..81ace0c5 100644 --- a/build/emacs.tcl +++ b/build/emacs.tcl @@ -10,6 +10,7 @@ respond "*" ":kill\r" respond "*" ":link sys;ts teco,.teco.;tecpur >\r" respond "*" ":link sys2;ts emacs,emacs;ts >\r" +respond "*" ":link sys2;ts ne,emacs;ts >\r" respond "*" ":emacs\r" respond "EMACS Editor" "\033xrun\033einit\033? Generate\r" expect -timeout 1000 -exact { -> DSK: EMACS; [PURE]} @@ -38,6 +39,7 @@ respond "\n" "\033xgenerate\033emacs;ivory\033emacs1;ivory\r" respond ":EJ" "\033xgenerate\033emacs;pl1\033emacs1;pl1\r" respond ":EJ" "\033xgenerate\033emacs;wordab\033emacs1;wordab\r" respond ":EJ" "\033xgenerate\033emacs;tmacs\033emacs1;tmacs\033tmucs\r" +respond ":EJ" "\033xgenerate\033emacs;babyl\033emacs1;babyl\033babylm\r" respond ":EJ" "\030\003" respond "*" ":kill\r" @@ -89,6 +91,10 @@ respond "*" ":kill\r" respond "*" ":rename emacs;\[rmai\] \021:ej, emacs;\[rmai\] 147\r" +# make TS BABYL +respond "*" ":midas sys3;ts babyl_kmp;babyl\r" +expect ":KILL" + # INFO # For some unknown reason, we can't use a printing terminal when # generating a new TSINFO. Temporarily switch to AAA. diff --git a/doc/info/babyl.53 b/doc/info/babyl.53 new file mode 100755 index 00000000..faa37c48 --- /dev/null +++ b/doc/info/babyl.53 @@ -0,0 +1,1863 @@ +-*-Text-*- +This is the file INFO;BABYL >, which documents the Babyl mail EMACS +subsystem, which allows the user to read and send mail from within +EMACS. + +File: Babyl Node: Top Up: (DIR) Next: Introduction + +Babyl (pronounced like "babble") is an EMACS mail system. You can +read mail, send mail, and process mail (keep some messages, delete +others, edit their text, and categorize messages by attaching labels). +If you have not used an EMACS mail system (e.g. RMail) before, you +should start by reading the Introduction -- type an N. RMail users +who are new to Babyl should type a 1 and then Ns. + +This file defines three special INFO commands that can be used to +quickly go to the description of any character command (use the C +command), extended command (use E), or variable (use V). Examples: + C + ESurvey Menu + VBabyl N After D + +People should feel free to comment on this info file, by mailing to +BUG-BABYL@MIT-MC. Be aware that because of the time and difficulty of +maintaining an accurate info file for such a changing library, this +tries to emphasize automatically produced documentation. + +* Menu: + +* RMailIntro:: Introduction for former RMail users. +* Introduction:: Introduction for new users who haven't used RMail. +* Concepts:: Description of some of the ideas and objects. +* Setup:: How to set up a Babyl file so you can use + Babyl to read your mail, or just try it out. +* Init/VarsFile:: Babyl init or vars files, similar to EMACS ones. +* Commands:: Descriptions of the commands you can give to Babyl. +* OptionVariables:: Variables that are of most general interest, + to control how you read and send mail. +* OtherVariables:: Variables of less general interest, mostly hooks. +* MailingLists:: How to get mail concerning Babyl, where to + send bugs or feature requests. +* Internals:: Some implementation details, for extension writers. + +Node: RMailIntro, Up: Top, Next: Concepts + +Babyl once was merely a hook inside RMail; it grew and grew and +finally set out on its own as a separate mail system library. But a +lot of it still superficially looks like RMail, and so would probably +be usable by RMail users without much difficulty or introduction. +Important differences from RMail are: + + It runs on Twenex (Tops-20) and Tenex. + + It has essentially no jcl, except an optional Babyl filename and +yet has a lot of flexibility, since much more state is kept in Babyl +files than is in RMail files. (E.g. a Babyl file gives the name +of its mail file.) + + It generally "reforms" headers to prettify them, hide "useless" +junk (e.g. message IDs), and correct some kinds of problems (e.g. +missing host names). See: *Note header reformation: Concepts. + + Deletions do not go on a stack -- messages are simply marked +deleted. Thus deleting will not cause messages to be renumbered. + + Messages may be categorized by attached labels (e.g. "deleted", +"unseen", "recent", and arbitrary ones chosen by the user). The +modeline and surveys show these labels. + + There are several varieties of surveys (in addition to the B +command), including surveying by the above labels, or surveying +all messages containing a given string. + + There is a facility for going into a recursive edit level on a +survey and giving Babyl commands from there, in the style of DIRED. + + The "?" command generates its output automatically and so you have +better assurance that it is up to date since documentation is kept +right with the function rather than somewhere else -- modifying one +reminds you to modify the other. + + You can have an init or vars file, similar to ones for EMACS, but +just for Babyl. On ITS these are BABYL INIT and BABYL VARS. On Tenex +or Tops-20 these are BABYL.INIT and BABYL.VARS. For more details, +see: *Note init/vars file: Init/VarsFile. + +Node: Introduction, Up: Top, Next: Concepts + + Babyl is an EMACS subsystem. It uses the user support features of +EMACS, and thus presents the user with an interface similar to much of +the normal view of EMACS. For instance, its commands can be described +with M-X Describe, Help-D, Help-C, or Help-R, or for convenience with +the "?" command in Babyl. Also, when editing a message to send, you +are in the same editing environment you normally use, with additional +tailoring because you are editing a message, and if you want to tailor +Babyl further you can do that in the same way that you tailor EMACS, +setting options or defining or replacing Babyl commands. + + In fact, Babyl has several option variables that control its +operation, and these can be viewed and edited with the standard EMACS +command M-X Edit Options. To see and edit all of them, do: + + M-X Edit OptionsBabyl + +Your EMACS init or EVARS file can set these options if you want to +always have them in effect. + + The simplest use of Babyl deals with two kinds of files: The "mail +file" is the standard file of incoming messages created by the +operating system; this file resides in the user's "home directory" and +has, e.g. for user FOO, a name like FOO;FOO MAIL (on ITS) or +MAIL.TXT.1 (on Twenex) or MESSAGE.TXT.1 (on Tenex). The +second kind of file is the "Babyl file", which has old messages that +you are saving (and which may have been processed in various ways); +it also has the specification for various options controlling Babyl +(such as the name of the mail file). + + When Babyl starts up, it combines the mail file with the Babyl +file, writes the combination back to the Babyl file, and deletes the +mail file. It presents the combination to the user for processing, +initially showing the first message of the new mail. When the user is +done, Babyl will write back the remaining messages to the Babyl file. +(This sequence is protected against the loss of any messages due to +system (or Babyl) crashes.) + + Babyl is designed for use primarily from a display terminal. +It can be used from a printing terminal -- but expect some rough +edges. + + Babyl operates in one of three modes. In the initial ("normal") +mode Babyl shows one message at a time. In this mode, all commands +are a single character, optionally preceded by a number (note: do not +use EMACS meta-digits; merely type the number). The special number +"Z" stands for the number of messages in the file; the special number +"." stands for the current message. So, "D" will delete the current +message (as will ".D"), "3D" will delete the third message, and "ZD" +deletes the last message. + + When you are editing a message/reply to be mailed, Babyl puts you +into a normal EMACS  mode (with a couple of extra key bindings +available). Exiting this recursive editing mode normally (e.g., with +C-M-C or C-M-Z) will mail the message; aborting (e.g., with C-]) will +return you to "normal" mode without mailing. In addition, the Babyl +command "" will allow you to edit the currently selected message in +your mailbox (without mailing). + + In "survey menu" mode (entered with the ' command), Babyl displays +a set of 1-line summaries of messages matching some criteria selected +by the user. In this mode, most Babyl commands work normally, +applying to the message currently selected by the cursor. EMACS are +also available in Survey mode, primarily to allow the positioning of +the cursor and filtering or reordering of the survey lines. (For +instance you can use M-X Keep Lines and M-X Flush Lines to keep only +relevant survey lines.) + + Only a few commands are needed to get started in Babyl. The most +useful commands for starting are: + + ? get help on Babyl commands. + J jump to message (number given in argument: e.g., J goes to + first undeleted message, 1J goes to first message, 5J goes to + message 5, ZJ goes to last message in the file, -J goes to + the last undeleted message). + N go to next message. + P go to previous message. + D delete message, moving to next one. + Q write out modified Babyl file and quit. +  temporarily suspend execution of Babyl. The Babyl file is + not saved; rather, it is left in the buffer, and will be + reselected if Babyl is reentered. + + For more information on Babyl commands, use the INFO command +C to go to the description of specific commands. + +Node: Concepts, Previous: Introduction, Up: Top, Next: Setup + + When you first enter Babyl, you will see one message displayed and +the modeline will contain information about that message. Seeing one +message at a time like this is called "normal message display" mode, +and the commands you give generally either affect the displayed +message or "move" to a different message and cause it to be displayed. + + Messages are made up of a "header" part and a "text" part. Babyl +will process the header ("reform it") to make it prettier and easier +to deal with. For instance it will remove mention of the host you are +on (the "local" host) for better clarity; it will align the header +fields; it will put the fields into a standard order; and it will +make sure that each recipient has a host, and if not figure out what +it should be. (You can control this. Use the INFO command V to see +the description of the variable Babyl Punt Missing Hosts.) The header +reformer will also remove certain fields, e.g. Message-ID, under the +assumption that these are not something the user generally wants to +see. (The 1H command will show you the full original header, though, +if you want to see what it was before header reformation.) For +information on how to tell the header reformer other fields that it +should remove, see: *Note customizing reformation: CustomRef. + + You can attach "labels" to messages, to categorize them. There +are several commands dealing with labels, but the most important are +the Babyl character command L (use the INFO command C to see its +description) and the extended command Edit Labels List (use the INFO +command E to see its description). Labels will be displayed in the +modeline in the normal message display mode. + + Commands (e.g. L) that read a label use a "completing reader", +just like Meta-X (^R Extended Command) does when reading command +names. This means you can type "?" to see a choice of the labels, and +type Altmode to cause completion. You may also define "label +abbrevs"; for instance you might define the label abbrev "an" to +abbreviate the label "arpanet" -- you can type in "an" but the full +label "arpanet" will actually be used. + + A "survey" is a display of 1-line message summaries, for instance: + + No. Lines From->To Subject or Text + 1: 10 ->EAK,JPershing@BBNA {feature, babyl}Possible Babyl idea + 2D 11 EAK-> Possible Babyl idea + 3A 23 EAK->,JPershing@BBNA Another idea + 4+ 18 JPershing@BBNA->EAK Replies + 5- 19 EAK->JPershing@BBNA Replies + + + The message number is followed by a "status character". ":" means +you have seen the message. "D" means you've deleted it (maybe seen +it). "A" means the message has been "answered" (the normal action for +the reply command is to label the message "answered" when it +finishes). "+" means you've seen it and it is "recent", a message +brought into the Babyl file this time. "-" means you have not seen +it. + + The From->To section is the most complicated. (You can alter how +it works by setting the option variable Babyl Survey FROM/TO Control. +See its description using the INFO command C.) Names are shortened to +just username and host. Sometimes the host is abbreviated (e.g. +MIT-AI becomes AI). All occurrences of you and the local host(s) are +removed. Thus in the above example, if that is a survey of your mail, +message 1 is from you to both EAK (at some local host) and JPershing +at BBNA. Message 2 is (a reply probably) from EAK back to you. +Message 3 is from EAK to you and JPershing (note the comma before +"JPershing@BBNA" -- that means there is another recipient; but since +it is you, it isn't shown). Messages 4 and 5 don't mention you (no +comma, even), so you are in the Cc list (you did after all receive the +message). The intent of the normal survey presentation not showing +you, is to highlight the other people in the conversations, since you +already know that you are involved in each message. + + The {feature, babyl} in the survey of message 1 is a list of the +labels attached to the message (two labels: "feature" and "babyl"). + + The rightmost part of the survey is either the Subject field or +the 1st Text line, if there was no Subject field. + + There are several survey-related commands, but the most important +are the Babyl character commands B and ^S. + + An alternative to normal message display mode is "survey menu" +mode, which is based on a survey: you are in a recursive edit level +on a survey. You can use any of the normal EMACS commands to move +around in it. And you can give any of the Babyl commands; they +affect the message whose survey is the line point is on. After each +command, the survey will be updated to reflect that command's effects, +if necessary. (See the character command ' (apostrophe) for how to +get into survey menu, and see the extended command Survey Menu for a +description of what you can do in survey menu.) + + There are several commands for sending mail: M ("mail"), R +("reply" to the current message), F ("forward" the current message to +someone else), C ("continue" editing whatever mail editing was last +aborted by the C-] command), and V (like M but initializes the message +to some arbitrary "template" you can set). + +* Menu: + +* SendingMail:: More details about sending mail. +* CustomRef:: Customizing the header reformer, to have + certain header fields removed. + +Node: SendingMail, Up: Concepts, Next: CustomRef + + Several Babyl commands (C, F, M, R, V) send mail, differing +in the initial message template they offer for editing: Each +command gives you a message to edit in a recursive edit level; +when you exit that level with C-M-C or C-M-Z (^R Exit) the edited +message will be mailed. + + M is the simplest command -- its template is an empty message. + + F creates a template for forwarding the current message (the +one in the Babyl file being viewed): the text is initially a +copy of the current message and the subject is the same as that +in the current message. + + R creates a template for replying to the current message: +the subject is the same, the message is directed back to the +person who sent it (using its FROM or REPLY-TO field), any people +in TO or CC fields are included as CCs (except if you use 1R), +and the text is either empty or (for 3R and 4R) contains an +indented copy of the current message. + + V (or M-X Mail With Template) uses a template that the user +has created before, using M-X Set Mail Template. You should see +the documentation of these commands for more details. + + Each of the above templates commands (M, R, and V) will +automatically include a CC field if you set the Babyl CC To +option variable. It should contain a string which is the +recipient list -- everything but the "Cc:" part. + + The C command does not create a template really -- the +template is whatever was left from the last mail-sending command. +For instance, if you use the R command and edit a reply, but +abort it with C-] (Abort Recursive Edit), you can continue +editing this reply later with C. Or if you want to send two +similar messages, you can send the second one by editing from the +first one, using the C command after the first has been sent with +M. + +* Menu: +* EditingMail:: Details about the mail-sending recursive + edit level. Some hooks for this mode. +* ReplyTemplate:: Details about the template R sets up. +* Babylm:: A library with JUST mail-sending commands. +* WindowUse:: Use of 1- and 2-window mode by C,F,M,R,V. +* MailHooks:: Other mail-sending hooks. + +Node: CustomRef, Previous: SendingMail, Up: Concepts + +Part of the job of the header reformer is to remove certain header +fields from view. (They remain in the original header, so 1H will +show them along with the rest of the unprocessed, original header.) +Message-ID is one field that by default is removed from view. If you +want, you can specify exactly which fields are removed. E.g. in the +examples below, we will show how to have the Via: field removed. + +The variable Babyl Reformation Flushes These Fields contains a string +naming the fields to be removed, each surrounded by square-brackets. +For instance, it by default might be (a two line string in this case +-- and note that spaces or tabs are ignored): + + [Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Redistributed-To] [Redistributed-By] [Redistributed-Date] [Keywords] + +These are the fields that will be removed from view. Since Message-id +is one of them, the message-id field is by default removed. If you +wanted to have the Via field removed too, just add "[Via]" to that +string. If you have an EMACS or BABYL vars file, you could include an +entry like: + +Babyl Reformation Flushes These Fields: " + [Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Redistributed-To] [Redistributed-By] [Redistributed-Date] [Keywords] + [Via] + " + +Or, if you had an EMACS or BABYL init file, you could include: + +@:i*" + [Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Redistributed-To] [Redistributed-By] [Redistributed-Date] [Keywords] + [Via] + " m.vBabyl Reformation Flushes These Fieldsw + +Two final notes: + +First, note that Babyl processes your Babyl init or vars file only +once per EMACS session. If you edit the file in EMACS and then invoke +Babyl from within that EMACS a second time, the changes will not be +noticed. To force Babyl to take notice of them, use the extended +command Process Babyl Init or Vars File, e.g. in Babyl type: + XProcess Babyl Init or Vars File + +Second, any messages which have already been seen most probably have +had their headers reformed too, and viewing them again will not invoke +the header reformer again automatically. If they have visible Via: +(in our example) fields, you will have to tell the reformer manually +to go over the header a second time. To do this, give the H command. + +Node: EditingMail, Next: ReplyTemplate, Up: SendingMail + + In the recursive edit level for sending mail, you will be in +an EMACS buffer named *Mail*, initially in Text mode, and with +C-M-Y by default connected to ^R Babyl Yank, which inserts a copy +of the current message (the one you were looking at before +sending this message). The yanked message will be indented and +use the reformed header if there is one; both of these actions +can be changed by giving numeric arguments -- see the +documentation. Also by default the variable Paragraph +Delimiter is modified so that lines starting with a hyphen (e.g. +the "--Text follows this line--" line) won't be considered part +of a paragraph -- good for using ^R Fill Paragraph. + + You can change the mode or key connections by providing a +Teco program in the variable Babyl Edit Mail Hook. If this +variable is set (non-0), C-M-Y and Paragraph Delimiter won't be +reset. You could use this hook, for instance, to connection ^R +Babyl Yank to another key, or connection other mail-editing +functions that by default are unconnected: ^R Babyl Delete +Recipient, ^R Babyl Add Subject: Field, ^R Babyl Add +To-Recipient, and ^R Babyl Add Cc-Recipient. See their +documentation for details. + + You might note the M-X Edit and Mail Buffer command -- it is +used by the other mail-sending commands but you might some time +find it useful by itself. It enters the recursive edit level on +the current buffer (with its current contents) and, when the +level is exited, mails the edited contents. + +Node: ReplyTemplate, Previous: EditingMail, Next: BabylM, Up: SendingMail + + This section details the reply template the R command sets +up, based on the current message and various option variables the +user can set. + + First the basic reply template (T) is set up, formed as +follows from the fields of the message being replied to (M): + + M's FROM or REPLY-TO becomes T's TO. + M's SUBJECT becomes T's SUBJECT. + Unless this is 1R (reply just to the sender), M's TO and CC +become T's CC. + Any automatic-CC is inserted, specified by the option +variable Babyl CC To. + + Next this basic template is trimmed, to remove duplicate or +unwanted recipients. If variable Babyl Trim Recipient List is 0, +no trimming at all is done. Even if you like the trimming, you +might set it to 0 if the system is very slow, since the new, more +general trimming process is slower than the old special-cased +way. + + Trimming has three phases. Each of these works by +considering only the "mailbox" name part of a recipient +specification. E.g. in each of + + Jennifer Q. Doe + DOE at MC (Jenny Doe) + DOE at MC + +the mailbox is "DOE@MC". Note that " at " always gets +canonicalized to "@". Thus, for instance, each of these +recipients will be recognized as duplicates. In the following we +will talk as if the recipient only had the mailbox part. Also +note that case does not matter. + + First all CC recipients starting with "INFO-", "BBOARD@", or +"*" are removed. + + Next we remove generally unwanted CC recipients using the +Teco search string in the variable Babyl Dont Reply To. If that +variable is 0, however, we skip this phase. If it is the null +string (the default), we will look for your username, so you +won't get CCs. + + Finally duplicate recipients are removed. (If a recipient +occurs in both the TO and CC fields, it will be kept in the TO +rather than in the CC.) + + Some random observations on this trimming process: + + The duplicate removal results in an alphabetically sorted +list of CC recipients. This means it won't look quite so much +like the message being replied to as it used to. + + The default removal of your username does not consider the +host, only the username part. Thus if you are SELF, on host MC, +CCs to SELF@AI will also be removed. This was chosen because +many of our users will have identical usernames on a few +different machine families. On the other hand, someday some +non-you SELF might be removed from the CC field. If you care, +set the Babyl Dont Reply To variable to include the host name. + + The search used to check whether to reply to a mailbox is +over the mailbox surrounded by CRLFs. This means you can delimit +a username by CRLF before and "@" after it, for instance. As an +example, here is a search string for not replying to the mailing +list EVERYONE on any machine, the list A-BUNCH at HOST, and +MYSELF at any machine (and indented, surrounded by "s, and with +^O for Control-O for clarity): + + " + EVERYONE@^O + A-BUNCH@HOST^O + MYSELF@" + + For more information about Teco search strings, see the INFO +node describing them: *Note search strings: (EMACS)TECOsearch. + +Node: BabylM, Previous: ReplyTemplate, Next: WindowUse, Up: SendingMail + + The mail-sending functions of Babyl may be loaded into an +EMACS without the rest of Babyl, by just loading the BABYLM +library. This library is considerably smaller and faster to load +than Babyl. + +Node: WindowUse, Previous: BabylM, Next: MailHooks, Up: SendingMail + + Each of the mail-sending commands may use either one- or +two-window mode; two-window mode allows the user to view the +current Babyl message in one window while editing the message to +send in the other window. + + The R (reply) command will use the two-window mode by +default, except when a copy of the current message is yanked. +Thus 1R and 2R start out with two windows, while 3R and 4R (both +yank) start out with one window. If you use C-M-Y (^R Babyl +Yank) yourself inside R, you'll be back in one-window mode. + + The M, C, and V commands use one window by default, but if +you use 2M, 2C, or 2V they use two-window mode. + +Node: MailHooks, Previous: WindowUse, Up: SendingMail + + Babyl C Hook + Babyl F Hook + Babyl M Hook + Babyl R Hook + Babyl R Done Hook + Babyl F Done Hook + + The hooks probably of most general interest are the +"done-hooks", which execute upon successful completion of R or F. +Babyl provides a small function you can call from Babyl R Done +Hook: the & Babyl R Done Hook function will remove any "reply" +label from the current message, and label it "answered". + + The other hooks execute after their respective commands have +set up their templates -- these hooks could be used for further +template tailoring. There is no Babyl V Hook currently, since +the V command "becomes" the M command and the Babyl M Hook will +be executed. Your M hook can tell an M from a V (and tell the +exact template too) by checking the variable Current Babyl +Template Name -- 0 if M, otherwise the template name. + +Node: Setup, Previous: Concepts, Up: Top, Next: Init/VarsFile + + This section describes how you can start using Babyl and create a +Babyl file. + + You can try out Babyl in two steps: + +1. Without committing yourself to using Babyl, you can try it out, +reading some existing mail (or RMail) file. Since that mail file is +not a Babyl file, Babyl will convert it to one internally, but inhibit +any writing or deletion of files, so you're safe. + + The easiest way, which only works on ITS currently, is to run +the BABYL job, telling it the mail or Rmail filename, e.g. + + :BABYL FOO; FOO MAIL + + On Tenex or Twenex you can try Babyl by loading it and then +running the M-X Babyl command, giving it as a string argument the mail +(or RMail) filename. (This also works on ITS, if ITS users want to +try Babyl out from inside their own EMACS environment.) E.g.: + + M-X Load LibraryBabyl + M-X BabylMAIL.TXT.1 + +2. If you decide you want to use Babyl, the first thing is to +tell EMACS that Babyl is your normal mail reader by setting the +variable Mail Reader Library to the string "BABYL". For example, +if you have an EVARS file, you would add to it the line (but not +indented as it is here): + + Mail Reader Library:BABYL + + This will cause the C-X R (or M-X Read Mail) command to +run Babyl. When Babyl finds that you do not yet have a Babyl +file, it will ask if you want to create one (type Y) and then ask +several questions about Babyl file options (if you aren't sure +about the choice, take the suggested one in square-brackets -- +the question will end in something like "[Y]"). + + After creating the Babyl file, Babyl will read in any new +mail you have and display the first message. You are now all set +up -- unless you formerly used RMail and still have messages in +an RMail file. In that case, you can merge these messages into +the new Babyl file with the 1G command; e.g. type: + + 1Gfoo rmail + +Node: Init/VarsFile, Previous: Setup, Up: Top, Next: Commands + + Babyl init and vars files are similar to EMACS ones, though these +should only be for customizing Babyl. If you only use Babyl from +WITHIN EMACS, you can customize it with your EMACS init or vars file. +You would then need no Babyl init or vars file. But if you want to +use Babyl outside EMACS, i.e. :BABYL on ITS or BABYL.EXE on TNX, then +you should put Babyl customizing in a Babyl init or vars file. + + Babyl checks your home directory for a Babyl init file, which +should be Teco code: BABYL INIT (ITS) or BABYL.INIT (TNX). + + If no init file is found, it looks for a vars file: BABYL VARS +(ITS) or BABYL.VARS (TNX). This file should be in the same format as +an EMACS vars file. + + This processing is only done the first time Babyl is loaded, for +reading or sending mail. If you edit your Babyl init or vars file +after this first entry to Babyl, you can give the M-X Process Babyl +Init or Vars File command manually so that Babyl takes notice of the +changes. + +Node: Commands, Previous: Init/VarsFile, Up: Top, Next: OptionVariables + + Babyl commands (in the "normal" interface -- when viewing one +message, as opposed to Survey Menu) are single characters, either +control-characters or alphanumeric characters. They may be given +numeric arguments, either one argument or two separated by a comma. +Here are some examples of commands you might type to Babyl (control +characters have "^"s): + + b + 3,10b + 5b + ^N + 2^N + + Some commands set up numeric arguments for the next command. For +instance, the Z command turns into the number of the last message in +the Babyl file (deleted or not); the Period command turns into the +number of the current message; and "-", "+", and "/" have their normal +algebraic meanings. Some more examples of commands (assume the +current and last messages in the file have numbers 45 and 60 +respectively): + + This: is the same as this: + + .,zb 45,60b + .-5,.+5b 40,50b + z/2j 30j + + + You can execute any EMACS extended command from Babyl using the X +command. (This is exactly like using EMACS's M-X (^R Extended +Command)) Thus, to edit the list of valid labels type XEdit Labels +List. + + The following command abstract lists all the Babyl commands, +single character and extended commands; it describes the Babyl +commands as of Friday, 27 April 1984: + +Single-character commands in library BABYL (Filename: BABYL): + +A: Move to next message and summarize it. + Given an argument, moves forward that many undeleted messages, and + summarizes the intervening messages as well as the last one. + If the option variable Babyl A Mode Display is non-0, we will update + the mode line. (Default is to update it.) + Users on slow display terminals may want to disable updating, and use + an occasional Z= instead, to see how many messages there are. + +B: Survey all or a range of messages. + Survey argument convention: + No argument means survey all messages in the Babyl file. + One positive argument n means survey the next n messages. + One negative argument -n means survey the previous n messages. + Two arguments m,n mean survey n messages + starting with message number m. + +C: Continue editing the last message sent or aborted. + Describe Edit and Mail Buffer for details about message editing, + and general hooks. + If you give a numeric argument of 2 we will use 2 windows, with the + current message in the top and the message being sent in the + bottom one. + Runs any Teco program in the variable Babyl C Hook after the message + template has been set up. + +D: S Delete this message, maybe select next. + Given numeric argument, n, means delete message n. + The option variable Babyl N After D controls whether Babyl + automatically moves to another undeleted message after deleting + this one. Values are: + 1: Try to do an automatic N -- move forward if can (default). + -1: Try an N (go forward), but if no next message, try a P (go + backward) instead. + 0: No movement. You view the deleted message. + +E: Expunge deleted messages. Handles empty file. + If expunging leaves the file with no messages, a dummy message is + inserted, since many Babyl commands don't work without some + message in the file. + +F: Forward current message. You can edit the message. + The mail will be set up to include the current message and a subject + based on the original one if any. You can then edit any of this + before sending it off. Describe Edit and Mail Buffer for details. + If you give a numeric argument of 2 we will try to use 2 windows, with + the current message in the top and the message being sent in the + bottom one. + If you give a numeric argument of 3 we will REMAIL the message instead + of forwarding it. The variable Babyl Remail Control controls the + action of 1F: 0 (read TO: and send); non0 (read TO: then edit and + send). Babyl Remail Hook should be a TECO macro to run after message + is set up. (Sorry. No 2 window mode yet...someday, 4F will do this.) + The option variable Babyl F Control controls the default action of F: + 0: You are put in a recursive edit level on the outgoing + message, which has an empty To: field (point is there), a + subject based on the original one, and the forwarded + message yanked into the text field. You can thus edit any + field and add comments. On terminals with insert/delete + line capability, we try to optimize redisplay. + 1: The To: and Subject: are read in the echo area, and you + are then put in a recursive edit level on the outgoing + message, with the header above the screen window, i.e. + with only the text field showing. (This may be desirable + for users with slow terminals without insert/delete line + capability, or for users with printing terminals.) Typing + Rubout to the subject prompt makes the message not have + any subject; typing Return makes the default subject be + used. + 2: Reads the To: and Subject: in the echo area, and then + mails the message, without entering a recursive edit + level. + 1F or 2F will force the general default action -- i.e. as if Babyl F + Control were 0. (1F uses one window.) + After the message template is set up, runs any Teco program you + provide in the variable Babyl F Hook. + When successfully exited (not aborted) it will run any Teco program + you provide in the variable Babyl F Done Hook, passing it F's + arguments. + +G: Get any new mail received since Babyl was started. + 1G means get mail from another mail file. You will be asked for its + filename. Any kind of mail file can be read in (it figures out + which kind it is): ITS or TNX mail file, an RMail file, or + another Babyl file. The file will NOT be deleted -- you must do + this manually, if desired. + The Append option (at the top of the Babyl file) determines where the + new messages are put in the Babyl file and in what order: + 0: prepend messages to beginning of Babyl file + 1: append messages to end + 2: prepend and reverse order of new messages + 3: append and reverse + Reversal is only done for the primary mail file, for the owner. + When G is done, it will run any Teco code in the variable Babyl G Done + Hook. Argument is 0 if no new mail, or the number of the last new + message. + +H: Reform or display original header. + If no argument, this forces the original header to be reformed. (You + can thus manually reform selected messages even if you don't have + messages normally reformed automatically -- i.e. if you set the No + Reformation option.) Reparse original header. + If argument, e.g. 1H, makes the original header be the visible header, + i.e. it unreforms. + +I: File out Babyl file, read in another. + After saving the current Babyl file (if necessary), asks for a Babyl + file. Default filename is DSK:homedir;username BABYL on ITS, + DSK:username.BABYL on TNX. You can override this with + the option variable Babyl Default File. + If the Babyl file has an Owner option (either one user name or several + user names separated by commas), then only the specified user(s) + can modify the file. + If file is not a Babyl file, we just read -- no deleting, no writing. + The variable Babyl File Version controls the version written. See its + description for details. + If you try to read in a Babyl file that does not exist, offers to + create one, asking you about the various options. + If a numeric argument is given (e.g. 1I), deleting and writing are + inhibited. This is like forcing this user to definitely NOT be an + owner. + Teco programmers: describe the variable Before Babylizing File Hook. + +J: Jump to message with given number. + nJ goes to message n whether deleted or not. ZJ goes to last message. + J goes to first non-deleted message. + -J goes to last non-deleted message. + +K: Delete message and append to text to be Y(ank)ed. + K kills current message. nK kills message n. + 0K kills current message, but only appends the text of the message. + +L: Attach/remove a label to the current message. + Given negative argument, removes the specified label. + +M: Edit and then send a message. + Describe Edit and Mail Buffer for details about message editing and + general hooks. + If you give a numeric argument of 2 we will try to use 2 windows, the + mail in the bottom window, the current message in the top one. + To continue editing a message aborted earlier, use the C command. + You may set the variable Babyl M Hook to a Teco program to run after + the header is initialized. + +N: Go forward to next undeleted message. + If numeric argument, n, goes forward n undeleted messages. + +O: Write message to a Babyl file. + The message will be labeled recent in the file. Any deleted label it + had will be removed in that file. Other labels remain. + The variable Babyl File Version controls the default version. See its + description. + If the variable Babyl O Confirm New File is non-0, you will be asked + to confirm writing a message to a new file. The default is 0. + Runs Babyl O Message Hook on the message in the file being written + to. (For instance, this might remove some temporary label, e.g. + "file", used to mark messages for filing with the M-X Output + Labeled Messages command.) + Runs Babyl O Done Hook when successfully done. This runs in the + current Babyl file -- not in the file just written to. + +P: Move to previous undeleted message. + +Q: File out Babyl file and exit Babyl. + Deleted messages are expunged from the file before exiting, and the + survey buffer is emptied. + Giving a numeric argument of 1 means do not expunge, just exit. + +R: Reply to message using bottom window, with message in top. + Describe Edit and Mail Buffer for details about message editing, and + the general hooks available. + Numeric argument of 1 means just reply to the FROM field. + Numeric argument of 3 means automatically yank the message. It will + have the reformed header. + Numeric argument of 4 means automatically yank the message but with + the original header. + Recipient names that start with INFO-, BBOARD@, or * will not be + included in a CC. (Thus you won't mistakenly reply to INFO-EMACS + or *ITS or *AI etc.) + Some variables may be set by the user to control header formation if + they are non-0: + Babyl Trim Recipient List: By making this 0 you can turn off any of + this removal (including INFO-, BBOARD@, *, etc.) -- you get just + the basic TOs and CCs based on the FROM, TO, CC, and Babyl CC To + variable. By making this negative, you disable the automatic INFO-, + etc. removal only (duplicates and Babyl Dont Reply To are still + removed). + Babyl CC To: should be a string, automatically inserted as a CC field. + Babyl Fcc To: should be a string, automatically inserted as a Fcc + field on Tenex or Tops-20 systems. + Babyl Reply-To Field: should be a string, automatically inserted in a + Reply-To field. + Babyl Require Subjects: if you don't supply a subject field, you will + be asked for one before mailing. + Babyl Dont Reply To: should be a Teco search string, selecting CC + people to remove. Each recipient mailbox name (the user@host part + only, not any personal name parts) is searched -- if the search is + successful that recipient is removed. This does not affect the + INFO-xxx, BBOARD@, or *machine checks. If this is 0, no removal + searching is done; if it is a null string, any CCs to yourself + are removed, as if the string were "yourname@". + Babyl R Hook: a Teco program run just before entering the recursive + edit level. + Babyl R Done Hook: a Teco program run when R completes successfully. + By default, this hook labels the message "answered". + +S: Write out the Babyl file. + +T: Type some or all of this message. + Numeric argument is optional message number. + +U: Undelete a message. + Giving no numeric argument means undelete current message if deleted, + or go back to one that is deleted and undelete that. + Giving a numeric argument, n, means undelete message number n. + +V: Edit and send mail, with template initialization. + Describe Edit and Mail Buffer for details about message editing and + the general hooks available. + The message is initialized from a template, which may specify any + header or text components. The template is a variable, containing + a copy of what the mail editing buffer should be initialized to. + It can optionally start with a value for point, within brackets, + e.g. it might start: [35]To: + String argument is a template name. The template variable name is + formed from this name -- e.g. for a template named "Foo", the + variable is named Babyl Template Foo. If you are using the Babyl + V command the template name is read with completion. + If you give a numeric argument of 2, we will try to use 2 windows, + current message in top one, message being sent in bottom one. + See the M-X Set Mail Template command for aid in creating templates. + Runs the Teco program in the variable Babyl M Hook if one. This + program can check the variable Current Babyl Template Name, 0 for + normal mailing, if it wants to further process the template. + +W: Access whole file. + +X: Execute an extended EMACS command. + This is just like the EMACS ^R Extended Command command. + +Y: Yank and reset (empty) text saved by K. + nY yanks into message number n. + 0Y or -nY just discards the saved text, in case you mistakenly typed K. + +Z: Return no. of messages in current file. + +': Into recursive edit level on survey. + No arguments means use the last survey. If no last survey, + we call . + M,N arguments means survey messages M through N. + N argument means survey next N messages. + -' is like ^S' but does not print while + surveying. (Except for a "Done" which is unavoidable without + serious work.) + For more details, see documentation for M-X Survey Menu. + +.: Return the message number of current message. + To reposition at top of current message, do .J + +;: Accumulate a line, then execute it with no display. + +=: Type value of numeric argument. + +>: Go to the end of the current message. + +?: Generate a list of Babyl commands, or just describe 1 character. + +\: Refill the current message. + The numeric argument specifies one or two things: the fill column, + and whether to consider indented lines as paragraph starters, as + opposed to lines of a yanked message. + Fill Column: If no argument, or a 0 argument, is given, the variable + Fill Column is used. Otherwise the absolute value of the argument + is used. + Positive argument says to do default filling -- indented lines are not + paragraph starters. + 0 or negative argument says they are paragraph starters. + Thus, for example, plain \ does default, using default Fill Column. + 0\ does paragraph like filling, using default Fill Column. + This will not touch header or mail separator lines, and will respect + indentation. E.g. any yanked messages will be filled separately, + keeping their indentation. + M-x Undo will bring back the old message in case filling caused + problems. + +|: Move to next message with some label. + | or 2| moves forward, -| or -2| moves backward. + No numeric arg, e.g. |, or -1 arg, e.g. -|, means use the last label + again. (If you explicitly give a string argument , though, it + will be used.) The label defaults initially to RemindNow, for + reminders. + With a numeric argument of -2, 1, or 2, will read the label to use. + +: + Move to previous screenfull. + +: Reformat a losing message that contains ^J's, ^H's, etc. + Replace them with their visual counterparts... + ^H deletes character before it, + ^J inserts carriage return + whitespace + ^M becomes CRLF. + This is undoable. (I.e. M-X Undo brings back old message.) + +: + Jump to next unseen message. + +: + No-op, flushes argument, and goes to next line. + +: + Execute a TECO command string. + +: + Print more of this message. + On printing terminal: prints rest of message. + On display terminal: goes to next screenful. + n scrolls up n lines. + 9999 Space (or any semi-infinite numeric argument) goes to the + end of the message. + +, , +, -, *, /, (, and ): + Part of a Babyl numeric argument. + +<: Go to the beginning of the current message. + +: + Delete the last character from accumulating argument. + Period, Z, digits, comma, plus, minus, etc. are characters that + make up arguments. + If you rubout the entire argument, the echo area is cleared. + +^C: (^C on ITS, ^Z on Tops-20) Return to DDT/EXEC temporarily. + +^D: Delete message and move backward. + +^F: Find and select message containing a specific string. + Given no numeric argument the search is forward, starting with the message + after the current one. + Given a positive argument, N, searches forward for the Nth message to + contain the string. + Given a negative argument, -N, the search is backward, starting with the + message before the current one, for the Nth message to contain the + string. + If no match is found, returns to current message. + +^L: Clear screen. Given a numeric argument, keeps same window. + +^N: Move to next message, whether deleted or not. + If argument, n, goes to nth next. + +^O: Append current message to a TNX mail file. + +^P: Move to previous message, whether deleted or not. + If argument, n, moves to nth previous. + +^R: Enter a recursive edit level on current message. + +^S: Survey-prefix. Also ignores ^S^Q for VT52 lossage etc. + ^S^A or ^SA is M-X Survey All Messages + ^S^D or ^SD is M-X Survey Deleted Messages + ^SUD is M-X Survey Undeleted Messages + ^S^L or ^SL is M-X Survey Labeled Messages (reads a label) + ^SUL is M-X Survey Unlabeled Messages (reads a label) + ^S^M or ^SM is M-X Survey Messages Containing String (reads a string) + ^S^F of ^SF is --ditto-- + ^S^R or ^SR is M-X Survey Reminders + ^SS is M-X Survey Seen Messages + ^SUS is M-X Survey Unseen Messages + ^S? shows this description and then reads another character. + To correct for stupid terminals, any number of ^S's followed by a ^Q + are ignored. This is for VT52s, H19s, maybe others. + +^T: Call ^R Display Load Average, for TNX users. + +^W: What is left of this message? Gives line/window count. + +^X: Temporarily exit Babyl. Doesn't file out. + Exits to EMACS or DDT/EXEC, depending on how Babyl was called: + If was 1,M-X Babyl or a BABYL job then will exit back to DDT/EXEC. + Repeating the M-X Babyl command will resume with state unchanged. + +^Z: (^C on ITS, ^Z on Tops-20) Return to DDT/EXEC temporarily. + +^]: Temporarily exit Babyl. Doesn't file out. + Exits to EMACS or DDT/EXEC, depending on how Babyl was called: + If was 1,M-X Babyl or a BABYL job then will exit back to DDT/EXEC. + Repeating the M-X Babyl command will resume with state unchanged. + + + + +Extended commands (invoke with X command): + +Babyl + Mail file editor subsystem. + String argument is Babyl filename. It defaults, and can be + overriden. Describe the I command for details. + If Babyl was temporarily exited before, this command will re-enter it + instead of starting a new session. The # Babyl ^X command is + the one that temporarily exits Babyl. + Babyl init and vars files are similar to EMACS ones, though these + should only be for customizing Babyl. If you only use Babyl from + WITHIN EMACS, you can customize it with your EMACS init or vars + file. You would then need no Babyl init or vars file. But if you + want to use Babyl outside EMACS, i.e. :BABYL on ITS or BABYL.EXE + on TNX, then you should put Babyl customizing in a Babyl init or + vars file. + Babyl checks your home directory for a Babyl init file, which should + be Teco code: BABYL INIT (ITS) or BABYL.INIT (TNX). + If no init file is found, it looks for a vars file: BABYL VARS (ITS) + or BABYL.VARS (TNX). This file should be in the same format as an + EMACS vars file. + This processing is only done the first time Babyl is loaded, for + reading or sending mail. If you edit your Babyl init or vars file + after this first entry to Babyl, you can give the M-X Process + Babyl Init or Vars File command manually so that Babyl takes + notice of the changes. + +Convert Babyl File Version + Numeric argument is desired version to go to. + This command is invoked automatically by Babyl when necessary, so + you probably will never need to use this yourself. + If you give no numeric argument, the conversion will be to the version + that this Babyl assumes. + Buffer should contain a Babyl file. + Point is left at the top. + You may convert up or down in versions. + +Create Babyl File + Create a new Babyl file, with sample message. + Will ask you for the Babyl filename, or you can give it as a string + argument. With a standard default for a user's main Babyl file + that reads the user's mail file. Will ask you about each of the + various Babyl options that a Babyl file may have. + Offers to send a message to BABYL-REQUEST@MIT-MC, requesting that + you be added to INFO-BABYL@MIT-MC. + +Delete Labeled Messages + Delete messages with some label. + String argument is label. + See also UnDelete Labeled Messages. + Numeric argument is number of messages (with the label) to delete, + from the current message forward. + No numeric argument means delete all messages with the label. + +Edit Babyl Options + Lets user change options for current Babyl file. + Will ask you about each of the various Babyl options that a Babyl file + may have. + This command should only be called from within Babyl.ed messages. + First string argument is label1, specifying which messages to + consider. + Second string argument is label2, the label to add or remove from the + considered messages. + No numeric argument means label all considered messages. + Numeric argument n (positive) means label the next n considered. + Numeric argument -n means unlabel the next n considered. + Numeric argument 0 means unlabel all considered messages. + +Label Message + Attach/remove a label to the current message. + Given negative argument, removes the specified label. + +Label Messages Containing String + Label search-selected messages. + 1st string argument is a string. Messages containing that string will + be labeled. + 2nd string argument is the label to add. + Given a numeric argument, it goes through the entire Babyl file, + rather than just forward from the current message. + Each message containing the given string is labeled with the given + label. + Note that the string is actually a Teco search string, so for + instance, if you want to label messages containing "foo" OR "bar", + you can provide the string "foobar". + +Mail With Template + Edit and send mail, with template initialization. + Describe Edit and Mail Buffer for details about message editing and + the general hooks available. + The message is initialized from a template, which may specify any + header or text components. The template is a variable, containing + a copy of what the mail editing buffer should be initialized to. + It can optionally start with a value for point, within brackets, + e.g. it might start: [35]To: + String argument is a template name. The template variable name is + formed from this name -- e.g. for a template named "Foo", the + variable is named Babyl Template Foo. If you are using the Babyl + V command the template name is read with completion. + If you give a numeric argument of 2, we will try to use 2 windows, + current message in top one, message being sent in bottom one. + See the M-X Set Mail Template command for aid in creating templates. + Runs the Teco program in the variable Babyl M Hook if one. This + program can check the variable Current Babyl Template Name, 0 for + normal mailing, if it wants to further process the template. + +Net Mail + Send off network mail in user directory + +Next Labeled Message + Move to next/previous message with some label. + | or 2| moves forward, -| or -2| moves backward. + No numeric arg, e.g. |, or -1 arg, e.g. -|, means use the last label + again. (If you explicitly give a string argument , though, it + will be used.) The label defaults initially to RemindNow, for + reminders. + With a numeric argument of -2, 1, or 2, will read the label to use. + +Output Labeled Messages + Write messages with some label to a file. + String argument is the label. + This is like going to each of these messages, and using the O command + to write it to the file, except that it does not read/write for + each message: it collects all the messages first, then writes the + file. + It asks whether the given label should be removed. E.g. the label + could be temporary, marking those files to output now. + Asks for filename. Also asks if can mark messages as deleted. (They + are deleted only after the file is successfully written.) + Default filename is based on the label, say foo: for ITS default is + FOO XMAIL, for TNX it is FOO.XMAIL. The version is controlled by + the variable Babyl File Version. See its description. + The filename may also be specified by a second string argument. + Numeric argument is number of labeled messages to output, from the + current message forward. + No numeric argument means output such-labeled all messages in mail + file. + There are two hooks that the user may provide: Babyl O Message Hook, + which is run on each outgoing message as it is collected, and + Babyl O Done Hook, which is run on each labeled message in the + current Babyl file (this hook is run only after the file has been + written). + +Process Babyl Init or Vars File + Find init or vars file and process it. + Babyl init and vars files are similar to EMACS ones, though these + should only be for customizing Babyl. If you only use Babyl from + WITHIN EMACS, you can customize it with your EMACS init or vars + file. You would then need no Babyl init or vars file. But if you + want to use Babyl outside EMACS, i.e. :BABYL on ITS or BABYL.EXE + on TNX, then you should put Babyl customizing in a Babyl init or + vars file. + Babyl checks your home directory for a Babyl init file, which should + be Teco code: BABYL INIT (ITS) or BABYL.INIT (TNX). + If no init file is found, it looks for a vars file: BABYL VARS (ITS) + or BABYL.VARS (TNX). This file should be in the same format as an + EMACS vars file. + This processing is only done the first time Babyl is loaded, for + reading or sending mail. If you edit your Babyl init or vars file + after this first entry to Babyl, you can give the M-X Process + Babyl Init or Vars File command manually so that Babyl takes + notice of the changes. + +Re-Enter Babyl + Mail file editor subsystem. + String argument is Babyl filename. It defaults, and can be + overriden. Describe the I command for details. + If Babyl was temporarily exited before, this command will re-enter it + instead of starting a new session. The # Babyl ^X command is + the one that temporarily exits Babyl. + Babyl init and vars files are similar to EMACS ones, though these + should only be for customizing Babyl. If you only use Babyl from + WITHIN EMACS, you can customize it with your EMACS init or vars + file. You would then need no Babyl init or vars file. But if you + want to use Babyl outside EMACS, i.e. :BABYL on ITS or BABYL.EXE + on TNX, then you should put Babyl customizing in a Babyl init or + vars file. + Babyl checks your home directory for a Babyl init file, which should + be Teco code: BABYL INIT (ITS) or BABYL.INIT (TNX). + If no init file is found, it looks for a vars file: BABYL VARS (ITS) + or BABYL.VARS (TNX). This file should be in the same format as an + EMACS vars file. + This processing is only done the first time Babyl is loaded, for + reading or sending mail. If you edit your Babyl init or vars file + after this first entry to Babyl, you can give the M-X Process + Babyl Init or Vars File command manually so that Babyl takes + notice of the changes. + +Remind Me Of This Message + (Un)Labels RemindNow. + Negative argument means remove the reminder label from this message. + +Set Mail Template + Create or reset a mail template from buffer contents. + See the M-X Mail With Template or # Babyl V command for using + templates. + String argument is a template name. If null, will read it in echo + area. + The template is taken to be the entire contents of the buffer. The + current point will be remembered in the template. This command is + generally given while in a recursive mail edit level. + +Shorten From Field For Hermes + Only username. + Forces the From field to be just Username at Host, no personal name + part. + Nice for Hermes, so other people can see your subject line in a + survey, since Hermes doesn't truncate a long From field. + +Survey Deleted Messages + Survey messages labeled "deleted". + Survey argument convention: + No argument means survey all deleted messages in the Babyl file. + One positive argument n means survey the next n deleted messages. + Two arguments m,n mean survey n deleted messages + starting with message number m. + +Survey Labeled Messages + Survey all or some messages with some label. + String argument is label. Messages with that label will be surveyed. + Survey argument convention: + No argument means survey all labeled messages in the Babyl file. + One positive argument n means survey the next n labeled messages. + Two arguments m,n mean survey n labeled messages + starting with message number m. + +Survey Menu + Edit Babyl file from a survey. + The last survey created is used, e.g. from a B command, or if none, + you are asked what kind of survey to first perform. + Babyl commands which are not control characters work as usual (plus + Control-D and Rubout), except that Space exits Survey Menu, just + like ^R Exit. + Control characters may be executed as Babyl commands by quoting them + with ^R Quoted Insert. + When the recursive edit level is exited we will go back to Babyl + buffer, selecting the current survey line's message. + The option variable Babyl Two Window Survey Menu, if non-0, says that + the survey should use one window, messages another. Back to one + window when exit Survey Menu. + The user can tailor Survey Menu by providing a Survey Mode Hook + variable, or by providing a Babyl Command Hook. + +Survey Messages Containing String + Surveys search-selected messages. + Surveys messages which contain a string (the string argument). + (Actually this is a Teco search string.) + Survey argument convention: + No argument means survey all matching messages in the Babyl file. + One positive argument n means survey the next n matching messages. + Two arguments m,n mean survey n matching messages + starting with message number m. + +Survey Reminders + Survey messages with RemindNow label. + Survey argument convention: + No argument means survey all reminder messages in the Babyl file. + One positive argument n means survey the next n reminder messages. + Two arguments m,n mean survey n reminder messages + starting with message number m. + +Survey Seen Messages + Survey messages not labeled "unseen". + Survey argument convention: + No argument means survey all seen messages in the Babyl file. + One positive argument n means survey the next n seen messages. + Two arguments m,n mean survey n seen messages + starting with message number m. + +Survey Undeleted Messages + Survey messages not labeled "deleted". + Survey argument convention: + No argument means survey all undeleted messages in the Babyl file. + One positive argument n means survey the next n undeleted messages. + Two arguments m,n mean survey n undeleted messages + starting with message number m. + +Survey Unlabeled Messages + Survey messages not labeled somehow. + Given no (or null) string argument, surveys messages with no (user) + labels. A string argument is a label; surveys messages without + that label. + Survey argument convention: + No argument means survey all unlabeled messages in the Babyl file. + One positive argument n means survey the next n unlabeled messages. + Two arguments m,n mean survey n unlabeled messages + starting with message number m. + +Survey Unseen Messages + Survey messages labeled "unseen". + Survey argument convention: + No argument means survey all unseen messages in the Babyl file. + One positive argument n means survey the next n unseen messages. + Two arguments m,n mean survey n unseen messages + starting with message number m. + +UnDelete Labeled Messages + Undelete messages that have some label. + Numeric argument is number of messages (with the label) to undelete, + from the current messageforward. + No numeric argument means undelete all the labeled messages. + +Undigestify Babyl Message + Break up a digest into individual messages. + The digest is assumed to be the currently selected message. It will + be replaced by the series of messages which made up the digest. A + "To:List-name" field will be added to each message header, for + replying and visual identification of the source digest list. + The option variable Undigestify Keep Digest controls what happens to + the original digest. This variable can have several values: + 0: digest is discarded + +n: digest is kept, before the individual messages + -n: digest is kept, after them + +1: digest is additionally marked Deleted + -1: same + If a precomma arg is given it is used instead of the value of the + variable. + + + + +Single-character commands in library BBOARD (Filename: BBOARD): + +^A: Add BBoard to Switch.ini. With nonzero argument, Remove BBoard. + If the name given is not a System BBoard, the user will be prompted + for the name of the Twenex Mail File to be read. + +^B: Look for new BBoard Notices to read, or on to next BBoard. + With an argument of 1, does not delete old notices. With an argument + of 2, queries about every BBoard whether or not it has new + notices. If BBoard Sans Query is nonzero then BBoard are + immediately read without querying. + +Node: OptionVariables, Previous: Commands, Up: Top, Next: OtherVariables + +Babyl option variables and default values: + +Babyl A Mode Display 1 + * Non-0 lets A update mode line + +Babyl Autolabel Messages 0 + * Non-0 causes autolabeling from subject fields + +Babyl CC To 0 + * Automatic CC field in mail if non-0 + +Babyl Day of Week Flag 0 + * (TNX only) If non-0 day of week is added to Date field of outgoing mail + +Babyl Default File 0 + * Set this to specify your normal Babyl file. If 0, + Babyl figures out the default filename to use. If that is + wrong, you can set this. Set it to a string, the filename. + This is especially for users whose Babyl file is not in their + home directory, or not named from the user name. E.g. you + might have a subdirectory full of mail-files, and set this + variable to (for Tops-20) PS:SMYTHE.BABYL + +Babyl Dont Reply To + * 0 or a Teco search string of CCs to remove (null means yourself) + +Babyl F Control 0 + * 0 (general edit), 1 (read To/Re then edit), 2 (read To/Re and send) + +Babyl Fcc To 0 + * Automatic Fcc field in Tenex or Tops-20 mail if non-0 + +Babyl File Version 0 + * 0: read max version, write back to same; + 1: read and write version 1, similar for other positive N; + -1: read max version, write back to next version + This only applies to Tenex or Tops-20 systems. + +Babyl Header/Text Separator --Text follows this line-- + * 1 line that separates header and text in recursive mail edit + +Babyl N After D 1 + * 1 means N after a D, -1 means N or P, 0 means no movement + +Babyl O Confirm New File 0 + * If non-0, you must confirm outputting a message to a new file + +Babyl Personal Name 0 + * (TNX only) A full name to use with user name as in Personal Name + +Babyl Reformation Control 0 + * Non-zero speeds up reformation process. + 1 - Do not worry about missing hosts. + 2 - Do not prettify recipient fields either. + +Babyl Reformation Flushes These Fields [Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Received] + + * Visibility control for fields. + 0 or a string, with format [fieldname1] [fieldname2] ... + Fields mentioned in this string, and otherwise unknown will be + removed from the visible header + +Babyl Reformation Merges From/Reply-To 1 + * Non-0: Reply-To merges with From. + This is part of header reformation which you can disable separately. + Surveys of merged messages will unfortunately mention the Reply-To, + not the From. + +Babyl Remail Control 0 + * 0 (read To field and send), non0 (read To then edit) + +Babyl Reply-To Field 0 + * Automatic Reply-To field in mail if non-0 + +Babyl Require Subjects 0 + * If non-0 Babyl will require you to have a subject in outgoing mail + +Babyl Strip Local Host 1 + * Non-zero removes local host from reformed headers + +Babyl Survey FROM/TO Control 3 + * Bits, 1 = enable prettification, 2 = shorten hosts, 4 = no hosts + Can also be a macro, which is given message, survey buffers as args. + Q1 gives point where from-to field starts in survey. It can update + that, e.g. if it wants to put something before the from-to area. + It should return number (bits as above). + +Babyl Trim Recipient List 1 + * 0 will disable all removal of reply recipients, +-1 will disable automatic removal of INFO-xxx,*machine and BBOARD@ recipients + +Babyl Two Window Survey Menu 0 + * If non-0, Survey Menu will use two windows. + +Babyl User Name 0 + * (TNX only) A name to use in From field possibly overriding username + + + + +BBOARD option variables and default values: + +BBoard Data File: 0 + * Complete file name if not Switch.ini on Home Directory + +BBoard Maximum Size: 10000 + * Maximum Size of BBoard file before deleting old notices + +BBoard Q on N at Last Notice: 0 + * If nonzero, N at Last Notice causes an automatic Q + +BBoard Sans Query: 0 + * Do not query user if this is nonzero + +Node: OtherVariables, Previous: OptionVariables, Up: Top, Next: MailingLists + +Other Babyl variables, of less general interest: + +Babyl C Hook 0 + 0 or a Teco program to run after C sets up its template + +Babyl Command Hook 0 + 0 or Teco program to run at times in command execution. + Its arg tells situation: + In normal Babyl com loop (Q0 has com char, Q5 has arg string): + 1 before display, 2 after, + 3 before com, 4 after. + In survey menu (Q..0 has com char): + 5 before com, 6 after. + 7 when entering SvM level (so you can bind things). + +Babyl Default Edit Mail Hook + m.m^R Babyl Yank[...Y + 1,m.m^R Fill Indented Mail Region[...\ + qParagraph Delimiteru2 + fq2"g :i22-'"# :i2-' + q2[Paragraph Delimiter + Describe Edit and Mail Buffer for details + +Babyl Edit Mail Hook 0 + 0 or a Teco program to run before recursive edit on mail to send + +Babyl F Done Hook 0 + 0 or a Teco program to run after F successfully exits + +Babyl F Hook 0 + 0 or a Teco program to run after F sets up its template + +Babyl G Done Hook 0 + User hook, run (if non0) after new mail is collected; + argument is 0 or message# for last new message + +Babyl Keep TNX Received Date 0 + If nonzero, add Rcvd-Date line to header + +Babyl M Hook 0 + 0 or a Teco program to run after M sets up its template + +Babyl O Done Hook 0 + If non-0, run when O is done + +Babyl Queuing Function & Default Babyl Queuing Function + Name of the mailer-dependent function for queuing mail + +Babyl R Done Hook + m(m.m& Babyl R Done Hook) + 0 or a Teco program to run after R successfully exits. + The default is to label the message answered. + +Babyl R Hook 0 + 0 or a Teco program to run after R sets up its template + +Babyl Remail Hook 0 + 0 or Teco program to run after message set up + +Babyl Setup Hook 0 + If non0, is run immediately after loading Babyl library + +Babyl Standalone Job 0 + Non0 means will exit to DDT/EXEC + +Babyl Subfork Control 0 + Controls handling of QUEUE-XMAIL subfork. + Non0 ==> Keep and read RSCAN; 0 ==> Dont keep and no RSCAN + Note that a special QUEUE-XMAIL is needed if you set this + +Before Babylizing File Hook 0 + Run after reading but before Babylizing non-Babyl files + +Current Babyl Template Name 0 + 0 or name of template in use + +Node: MailingLists, Previous: OtherVariables, Up: Top + +If you use Babyl, you should be on the INFO-BABYL at MIT-MC mailing +list. If you don't know how to add yourself to that list, send mail +to BUG-BABYL at MIT-MC asking one of the maintainers to add you to the +list. (Or to take you off.) + +You can also mail requests to BABYL-REQUEST or INFO-BABYL-REQUEST, +which are nearly synonymous with BUG-BABYL. Pick whichever you find +easiest to recall; when in doubt send to BUG-BABYL. + +All reports of incorrect Babyl operation should be mailed to BUG-BABYL +at MIT-MC. On the other hand, suggestions for new or changed +capabilities should be mailed to FEATURE-BABYL at MIT-MC. There are +several people, other than maintainers, who want to hear the +discussions about new features. (Feel free to add yourself to that +list.) Generally only maintainers or serious "Teco-hackers" will want +to be on the BUG-BABYL list -- it is verbose, talks a lot of Teco, and +well ... has a definite negative tone. + +The messages going out over these lists are collected in the following +files on MIT-MC: + +ECC; BABYL BUGS is the mail file for ECC; BABYL BUGYL, which is the +Babyl file collecting all the BUG-BABYL messages. + +ECC; BABYL FEATURE is the mail file for ECC; BABYL FEATYL, which is +the Babyl file collecting all the FEATURE-BABYL messages. + +ECC;BABYL INFO is the mail file collecting INFO-BABYL messages. +(There is no corresponding Babyl file.) + +Node: Internals, Next: File-Format, Up: Top + +This node is not a very complete guide to the internals of Babyl, but +will collect various pieces of documentation that have been written. +These will include the date written so the reader can get an idea how +current they are. + +The source files for Babyl are (as of 5 August 1983) on MIT-MC in +EMACS1; BABYL > and BABYLM >. They may also be found on MIT-OZ and +MIT-XX in PS:BABYL.EMACS and BABYLM.EMACS. As a starting point +for finding your way around the sources, note that the function Babyl +is the typical entrypoint for mail reading, and the function & Babyl +Execute Options is the top-level command loop -- studying it will tell +you about some conventions about q-registers, and command argument and +value passing. + +* Menu: + +* File-Format:: Details concerning the Babyl file format. + +Node: File-Format, Previous: Internals, Up: Top + +Format of Version 5 Babyl Files: + +Warning: + + This was written Tuesday, 12 April 1983, based on looking at +a particular Babyl file and recalling various issues. Therefore +it is not guaranteed to be complete, but it is a start, and I +will try to point the reader to various Babyl functions that will +serve to clarify certain format questions. + + Also note that this file will not contain control-characters, +but instead have two-character sequences starting with Uparrow. +Unless otherwise stated, an Uparrow is to be read as +Control-, e.g. ^L is a Control-L. + +Versions: + + First, note that each Babyl file contains in its BABYL +OPTIONS section the version for the Babyl file -- each version +change signals a change in the format of Babyl files, and Babyl +has a function that converts from one version to another: +Convert Babyl File Version. This file describes Version 5 +format. For other versions, look at the conversion function. + + +Overall Babyl File Structure: + + A Babyl file consists of a BABYL OPTIONS section followed by +0 or more message sections. The BABYL OPTIONS section starts +with the line "BABYL OPTIONS:". Message sections start with +Control-Underscore Control-L Return Linefeed. Each section ends +with a Control-Underscore. (That is also the first character +of the starter for the next section, if any.) Thus, a three +message Babyl file looks like: + +BABYL OPTIONS: +...the stuff within the Babyl Options section... +^_^L +...the stuff within the 1st message section... +^_^L +...the stuff within the 2nd message section... +^_^L +...the stuff within the last message section... +^_ + + Babyl is tolerant about some whitespace at the end of the +file -- the file may end with the final ^_ or it may have some +whitespace, e.g. a Return Linefeed, after it. + + +The BABYL OPTIONS Section: + + Each Babyl option is specified on one line (thus restricting +string values these options can currently have). Values are +either numbers or strings. The format is name, colon, and the +value, with whitespace after the colon ignored, e.g.: + +Owner: ECC +Append: 1 +Mail: PS:ECC-MAINT.MAIL.1 + + Here, the Owner option is the string "ECC", the Append option +is the number 1, and the Mail options is the string +"PS:ECC-MAINT.MAIL.1". + + Babyl allows options that is doesn't know about -- it just +ignores them. This is done so that other mail readers, in +particular the MIT Lisp Machine's ZMail, can also use the same +Babyl files but have some extra options of their own. The +function & Reset Babyl Options knows the list of options and +their default values. In general, default is 0, except for +Append (see below). Here are those options and the kind of +values currently expected (if not 0): + + XMail Filename, for TNX systems only. + XMail Append 0 or 1 (boolean), for TNX only. + MAIL Filename, the input mail file for this + Babyl file. + Version Number. + No Original 0 or 1 (boolean). + Owner User name string. + No Reformation 0 or 1 (boolean). + Labels String, list of labels, separated by commas. + Append 0, 1, 2, or 3 -- bit flags (booleans): + 1-bit is whether to append to Babyl file. + 2-bit is whether to reverse mail file + before sticking on Babyl file. + Default value is 0 on ITS, 2 on TNX. + + +Message Sections: + + A message section contains one message and information +associated with it. The first line is the "status line", which +contains a bit (0 or 1 character) saying whether the message has +been reformed yet, and a list of the labels attached to this +message. Certain labels, called basic labels, are built into +Babyl in a fundamental way, and are separated in the status line +for convenience of operation. For example, consider the status +line: + +1, answered,, zval, bug, + + The 1 means this message has been reformed. This message is +labeled "answered", "zval", and "bug". The first, "answered", is +a basic label, and the other two are user labels. The basic +labels come before the double-comma in the line. Each label is +preceded by ", " and followed by ",". (The last basic label is +in fact followed by ",,".) If this message had no labels at all, +it would look like: + +1,, + + Or, if it had two basic labels, "answered" and "deleted", it +would look like: + +1, answered, deleted,, zval, bug, + + The & Label Babyl Message knows which are the basic labels. +Currently they are: deleted, unseen, recent, and answered. + + After the status line comes the original header if any. +Following that is the EOOH line, which contains exactly the +characters "*** EOOH ***" (which stands for "end of original +header"). Note that the original header, if a network format +header, includes the trailing CRLF. And finally, following the +EOOH line is the visible message, header and text. For example, +here is a complete message section, starting with the message +starter, and ending with the terminator: + +^_^L +1,, wordab, eccmacs, +Date: 11 May 1982 21:40-EDT +From: Eugene C. Ciccarelli +Subject: notes +To: ECC at MIT-AI + +*** EOOH *** +Date: Tuesday, 11 May 1982 21:40-EDT +From: Eugene C. Ciccarelli +To: ECC +Re: notes + +Remember to pickup check at cashier's office, and deposit it +soon. Pay rent. +^_ + +;;; Babyl File BNF: + +;;; Overall Babyl file structure: + + +Babyl-File ::= Babyl-Options-Section (Message-Section)* + + +;;; Babyl Options section: + + +Babyl-Options-Section + ::= "BABYL OPTIONS:" CRLF (Babyl-Option)* Terminator + +Babyl-Option ::= Option-Name ":" Horiz-Whitespace BOptValue CRLF + +BOptValue ::= Number | 1-Line-String + + + +;;; Message section: + + +Message-Section ::= Message-Starter Status-Line Orig-Header + EOOH-Line Message Terminator + +Message-Starter ::= "^L" CRLF + +Status-Line ::= Bit-Char "," (Basic-Label)* "," (User-Label)* + CRLF + +Basic-Label ::= Space BLabel-Name "," + +User-Label ::= Space ULabel-Name "," + +EOOH-Line ::= "*** EOOH ***" CRLF + +Message ::= Visible-Header Message-Text + + +;;; Utilities: + +CRLF ::= Return Linefeed + +Terminator ::= "^_" + +Horiz-Whitespace + ::= (Space | Tab)* + +Bit-Char ::= "0" | "1" + + +!# Info C:! !C Finds command description for character you type.! + + "e .[0' + @fn|q0m(m.m& Info Select Location)| + [1[2 :i*CfsEchoDisplayw @ftGo to Babyl character:  fiu1 + q1:i2 + q1-33"L q1+100.u2 :i2^2' + q1-127"E :i2' + q1-8"E :i2' + q1-9"E :i2' + q1-10"E :i2' + q1-13"E :i2' + q1-27"E :i2' + q1-32"E :i2' + q1f1234567890,+-*/():"l :i2, , +, -, *, /, (, and )' + :i*Commands m(m.m& Info Select Node) + :s + +2:"e :i*2 is not a Babyl character commandfsErr' + @ft2 0u..n 0l .-bfsWindoww  + +!# Info V:! !C Finds a variable description.! + "e .[0' + @fn|q0m(m.m& Info Select Location)| + 1,m(m.m& Read Line)Go to Babyl variable: f"e'[1 + :i*OptionVariables m(m.m& Info Select Node) + :s + +1"e :i*OtherVariables m(m.m& Info Select Node) + :s + +1"e :i*1 is not a Babyl variablefsErr'' + 0u..n 0l .-bfsWindoww + +!# Info E:! !C Finds description of extended command.! + "e .[0' + @fn|q0m(m.m& Info Select Location)| + 1,m(m.m& Read Line)Go to Babyl extended command: f"e'[1 + :i*Commands m(m.m& Info Select Node) + :s + +1"e :i*1 is not a Babyl commandfsErr' + 0u..n 0l .-bfsWindoww + +Local Modes: +Fill Column:70 +MM # Info E: .[0 0fsVZwzj -s!# Info E:! 1,:m(.,zx*f(uMM # Info E)) +MM # Info V: .[0 0fsVZwzj -s!# Info V:! 1,:m(.,zx*f(uMM # Info V)) +MM # Info C: .[0 0fsVZwzj -s!# Info C:! 1,:m(.,zx*f(uMM # Info C)) +End: diff --git a/doc/programs.md b/doc/programs.md index 5abb6e9c..b2c3d166 100644 --- a/doc/programs.md +++ b/doc/programs.md @@ -29,6 +29,8 @@ - ATSIGN TARAKA, starts dragons. - ATSIGN TCP, TCP support. - BABEL, Chaosnet server. +- BABYL, mail reading/sending program for EMACS. +- BABYLM, mail sending program for EMACS. - BALANC/MOVDIR, balances directories. - BDAY, happy birthday demon. - BINPRT, display information about a binary executable file. diff --git a/src/emacs1/babyl.783 b/src/emacs1/babyl.783 new file mode 100755 index 00000000..76ce986c --- /dev/null +++ b/src/emacs1/babyl.783 @@ -0,0 +1,6727 @@ +!* -*-TECO-*- *! + +!* + + The latest sources for Babyl are AI: EMACS1; BABYL > and AI: EMACS1; BABYLM > + on ITS, EMACS:BABYL.EMACS.0 and EMACS:BABYLM.EMACS.0 on Twenex. On + Twenex, you can just use the Compile command. On ITS, you should first + do an input translation from EMACS:*;* EMACS to AI:EMACS1;* > and an + output translation from EMACS:*;* EMACS to whereever you want the + compiled result to go (once upon a time this was KL: ECC; XBABYL :EJ). + If you don't like this, think of a better scheme that doesn't screw more + people than this one does. + The source for the installed EMACS; BABYL :EJ is either some BABYL nnn + (see the automatically-generated description of & SetUp Compressed + BABYL Libraries) or AI: ECC; BABYL SOURCE if patched. (Rare) + The source for the installed EMACS; BABYL' :EJ is some BABYL nnn or AI: + ECC; BABYL' SOURCE. (Rare) + + Maintainers: Note that there are some conventions regarding documentation. + I (ECC) have a library that produces the INFO file command/variable + abstracts, that expects these conventions: First, use of SubDoc must come at + the end of documentation, and start out exactly alike, see an example. + Second, documentation may contain (anywhere) code to INSERT other + documentation. E.g. see documentation for |. + + Modification history: + + 02/07/88 783 SRA Another typo, radix screwup labeling wrong msgs. + 12/27/87 782 SRA Fix typo in & Autolabel TNX Bit Labels. + 11/20/87 781 SRA Add support for preserving the hardwired (MM.MAC) + MAIL.TXT flags (Seen,Flagged,Answered,Deleted) + as Babyl labels. This is kinda slow, and it is + just barely possible that somebody is depending + on the old broken behavior, so this is turned off + by default. Set Babyl Convert TNX Flags To Labels + nonzero to enable. + 8/24/87 780 SRA Merge XX and OZ versions back together again. Fix + Foner's version of M-X Compile that only works on OZ. + XX and OZ local changes were: + 11/15/86 SRA [XX version 779] Make In-Reply-To code use + the Message-ID iff present (flakey). + 1/09/86 SRA [XX version 778] Don't die in Survey One Message + if FL command fails. + 10/07/85 SRA [XX version 777] Reimplement local changes that + were lost in Hurricane Gloria (local addresses + in Undigestify, Twenex M-X Compile command). Recompile + with new BABYLM (v164, does right thing for MMAILR), + fix R command so gets rid of extra deletes that + overzealous MMAILR code may add. + 6/17/86 Foner [OZ version 774] Fixed local-modes so that Compile + works on OZ (only). + 1/25/85 KMP [OZ version 773] The warning about locked mail file + which used to read + "... some other program, such as MM, ..." + was changed to read + "... another program, such as MM or the mailer, ..." +10/09/84 772 ECC Have F take string args when called as subr, and not + have parse errors be fatal. Change Babyl Reformation + Merges From/Reply-To to default 0, less confusing. + 4/12/84 770 ECC ^T to show load average. Edit Labels List cleans up + ,,s and makes CRLFs separate labels. Added pushes to + *Babyl* so can use M-X instead of (in addition to) X + in SvMenu: Label Labeled Messages, Delete Labeled + Messages, UnDelete Labeled Messages, Output Labeled + Messages, Label Message, Edit Labels List, and + Label Messages Containing String. Slight problem: + SvM doesnt know resurveying needs to be done. + ***We still need to fix the bug about sorting, losing + bounds, and autolabeling. +01/05/84 765 KMP Added babyl options Expiration-Check-Interval + and Expiration-Check-Time. This should not affect + normal Babyl users but will be essential to ZBabyl + at some point. +11/30/83 764 KMP Make & Jump to Current Survey Line be much more + choosy about where it goes. +11/27/83 763 KMP Make & Babyl Set Mode Line do f[InsLen and f[SString + since it can go off at unpredictable times in the + middle of things which are relying on the default. +11/18/83 762 ECC Move trimming of BBOARD, SYSTEM, etc. out of & Setup + Reply Template as special cases to use vars. Also, + change & Babylize Buffer to handle either TNX or ITS + mail files on either system. Thus you can I to either + file on any system, for example. Fixed bug in & Form + Header, to not put space after colons in contin lines. +11/02/83 759 ECC Bump version number, since BabylM changed. +10/22/83 757 ECC Received: field flushed by default. ^S code cleaned + slightly -- :Ms and Ms made consistent, commented. + Clean up some documentation: ^C/^Z, ^X. +09/21/83 754 ECC Switching to use the new survey arg code. Consists of + deleteting the old survey functions, renaming the New + Survey.. functions to just Survey.., and deleting the + changeover helper Use New Survey Commands. + Changed default for Babyl Reformation Flushes These + Fields to be more conservative: no longer flushes + Redist.. and Keywords. Just low-level things. +08/06/83 752 ECC Extended Output Labeled Messages for use as subr. +06/26/83 750 SHSU Add # Babyl > and # Babyl < to get to end-begin of + current message. no :EJ file generated. +06/09/83 749 ECC Put in new survey arg code. For now, since + incompatible change, all replacement functions have + New... names, e.g. New # Babyl B. See & Setup... and + Use New Survey Commands function. In a few weeks or + so, after users have changed hooks etc., will fully + install these functions. More ITS 3F work. +06/08/83 745 ECC Worked on ITS 3F a bit. +06/06/83 744 ECC & Setup Reply Template made more robust when cannot + parse recipients. User can now continue, edit header. +05/26/83 742 ECC \ checks Fill Extra Space List. A revised so nA + doesn't iterate, printing survey headers etc. 3F + should now work on ITS (added :f6s). Labels list when + created will default to the semi-official default user + labels, e.g. RemindNow. +05/18/83 740 KRONJ Improve date reformatter. +04/14/83 739 ECC Fixed ^S prompting and ? bugs. +04/11/83 738 ECC Added Sam Hsu's ^W command. +04/10/83 737 ECC BabylM now calls Babyl Setup Hook, in its & Setup.. + Noisy warning of unknown babyl options commented out, + for ZMail options. Reformation customizing extended + by adding Babyl Reformation Control and Babyl + Reformation Flushes These Fields; users can now + specify which fields appear, which dont. | can take + negative args, & Map Over Labeled Messages too. B + takes negative args. Survey Undeleted Messages added. + ^SUx form added for Survey UN... R and F also query + for aborted mail. +03/09/83 734 ECC Remove OZ-hack in & Form Header, since XMAILR is now + taking care of USER@OZ, e.g. turning it into + USER%MIT-OZ@MIT-MC if it thinks it necessary. Changed + & Setup Reply Template so that Babyl CC To overrides + Babyl Dont Reply To, i.e. the auto-ccs are added after + pruning, if pruning is being done. Return-Path: not + shown in reformed headers. n^F and -n^F fixed to + search for the nth matching message. & Form Header + tries skipping leading day names in reforming dates. +02/12/83 729 SHSU Some cosmetic changes to In-reply-to: field; M will + confirm if last message aborted. REMAIL command on + 3F. For TNX, set read date on mail file before renaming + so FINGER and MAICHK will work right. +12/20/82 728 ECC Changes to BABYLM to do minimal RFC822 support: uses + @ instead of "at" in outgoing headers, if multiple @s, + the earlier ones turn into %s. Still work to do: + 1. If spaces in uname, make into a quoted string. + 2. Header reformation might know about %s. +12/15/82 727 ECC Dummy message message prettified. Adding a x=y label + works (Label Message and & Add to Labels Option + changed). Reply setup fixed for no-From/Reply-to and + to not reply to System or Forum. ^F doc improved and + n^F iter removed as useless. Added Babyl O Confirm + New File. +12/01/82 725 ECC Moved insertion of in-reply-to out of & Setup Reply + Template and into its own subr, called AFTER editing + the mail, so user never sees it. # Babyl R now sets + the current template name to Standard Reply, as a + signal. +11/18/82 723 LNZ Change # Babyl ^O to use the Rcvd-Date: field + rather than the current date and time if the message + to be output has a Rcvd-Date: field. +11/18/82 722 GZ If Babyl Trim Recipient List is negative, do not do + *machine, INFO-xxx and BBOARD@ trimming, but still + do duplicate and Babyl Dont Reply To removal. + Also, fixed Undigestify to allow topic separator + lines to have up to 85 dashes. +11/14/82 721 LNZ If Babyl Suppress In-Reply-To exists and is non-zero, + do not generate an In-Reply-To field. +11/12/82 720 LNZ Fixed code for Babyl Keep TNX Received Date to properly + handle messages that don't end in CRLF. + EAK Added ~ command to GC. +10/14/82 717 ECC 0Y flusheds K-text. Shh (;) uses fsTYISource and + should be more general and intuitive now, not + dangerous -- changed: ; and exec, added & Babyl TYI + Source. & Bounds Of Header fixed to return good + bounds if null text field (should fix F, R, and H + problems). + + NEW: Empty babyl files now handled fairly generally by + creating dummy messages in a few places: E, I, select, + & Initialize Babyl Buffer, & Reformed Bit, added & + Make Dummy Message. + + 9/12/82 716 Moon Make & Setup Reply Template put in In-reply-to field. + 8/25/82 713-5 ECC Fix bug just introduced into reformer where it no + longer removed excess CRLFs and dashes at end. Also + improved it so as not to remove dashes at end of the + last text line, e.g. -Foo- type signature. + Changed & Parse Header and & Form Header so that + duplicate recipient fields (e.g. two separate From + fields) get merged with a separating comma. All + variable declarations for recipient fields, e.g. + From:, have comments starting with a comma. Also, & + Form Header now indents multiple Date lines nicely. + ^T wont error if function not found. Have Create + Babyl File send its messages to something other than + BUG-BABYL, so if we want we can redirect them. + Add Babyl Variables Reset variable, so & Reset Babyl + Options and others can tell the exec to reset qregs. + 8/22/82 708-12 ECC & Form Header OZ-hack changed to use MC, not AI, since + AI is not reliable. Fix & Bounds Of Header and & + Reform Header re messages with no text field -- + extra-CRLF removal was removing the terminating blank + line and the original header therefore wasnt including + it. Broke 1H and F in cases where 1H had been done, + at least. + 7/18/82 704-7 ECC arg^L keeps window. Add Babyl Reformation Merges + From/Reply-To, so people can disable just this if they + find its change-of-meaning effect on survey From field + unacceptable. Fix D, U to not 1u..h unless is typeout. + 7/15/82 697-3 ECC Finishing touches: Fix return-value bugs in L, | -- + when aborted they left the Babyl arg around. Have + label completer use Return/Linefeed distinction -- + Return completes, Linefeed is for exactly what typed, + e.g. new label. Label abbrevs work in unlabelling. E + protects itself more when 0 messages left. Create.. + asks whether to send message re INFO-BABYL. Answered + is now a basic label, compatible with ZMail. Label + reading for several commands allows new ones. + Surveyor fixed to not expect FW to always work. + Put unseen-handling into standard code, no longer in + the Babyl Command Hook. Have default R Done hook + label answered, since now a basic label. Unseen + handling now done in code, not Babyl Command Hook. + User can still override it, though slightly trickier. + But our handling is better now than was. + Fix Os check of Append -- past space before number. + 7/14/82 695-6 ECC Extend Owner to allow several. & Reset Babyl Options + translates from list to just one. separated + from Babyl, for documentation purposes. Further fix + mode line check of buffer. Add Babyl Two Window + Survey Menu. Split creator into two commands: Create + Babyl File, and Edit Babyl Options. Change & Babyl + Survey One Message so that Babyl Survey FROM/TO + Control can also be a macro, to tailor survey a bit. + Improve documentation for several commands. Note + BABYLM additions for init/vars processing, templates. + 7/12/82 693-4 ECC Have T remove Unseen label, especially for SvM. + Have & SvMenu ^RNormal Macro and SvM T reform headers. + Change default Babyl Command Hook to remove unseen + after SvM T command, and only remove unseen in + exec if no typeout or typeahead. + Fix & Form Header bug re @ vs. at. + 7/11/82 692 KRONJ Add parens to reply-to funny-char list (again). + 7/08/82 690-1 ECC Added babyl reply-to field variable, used in F, M, R. + # Babyl G handles mail from old crash now, making two + passes. Fixed comments about what the argument to + Babyl G Done Hook is, what & Initialize Babyl Buffer + returns. Not # new, but # of last new message. G + keeps point and window if no new mail. + 7/08/82 688-9 ECC Special reformation to handle BABYLM changes for + MIT-OZ -- sending from OZ gives Sender: User at + MIT-OZ, but From: User at MIT-AI, so is legal Arpanet + and can be replied to. Yet reformation hack allows + Oz-to-Oz messages not to look ugly and lets them reply + directly without going through AI. + 7/05/82 685-7 ECC Finishing touches to this release: 1G handles any + kind of mail file on TNX or ITS, fix mode line + routine to handle empty file (e.g. called while + creating), 1G arg to & Read Filename. Refill some + documentation so will fit in info file when indented. + Fix incredibly dumb, disastrous bug in new version + control, to only set fsDVersion on TNX. Also fix + some wrong args to TNX & Read Filename. Make & Babyl + Execute Options check for empty file and quit. + 7/04/82 683-84 ECC Fixed & Push Message re fsWindow being B-relative. + Change & Babyl Set Mode Line so last "label" means + last undeleted message. See if slows down too much. + On OZ it is fine... Perhaps option? + More version work: be sure is TNX-robust, by having + file opened to [TECO].OUTPUT, then renamed when close. + This for writing over versions. Changed: Create.., + Output Labeled.., O, G, and see BABYLM. + 6/28/82 675-82 ECC Add Babyl File Version -- changed: I, Output + Labeled Messages, # Babyl O, Create Babyl File, & Read + Babyl File. Have 1G handle ITS mail/rmail files on + TNX, so people can FTP them over and merge them in. + Fix bug in Create.. so gives mail files correct + structure. Auto-N after D now tries P if cannot N if + option is -1. + 6/27/82 673-4 ECC Output Labeled Messages changed to have O collect + messages in a buffer, with OLM reading/writing and + running done-hook, and to offer to unlabel. + 6/27/82 672 ECC F command doesnt insert Babyl CC/FCC To variables. + Babyl O Filename can be a buffer, causing O to collect + messages in there, not writing each time. + 6/22/82 671 ECC Answering no to new-label confirm goes back to read + label. Lets user then type . + 6/21/82 670 ECC Also, change End (C-Alt) into Return instead of Q at + top-level. (Q is bad if type two Ends instead of one, + exiting mail edit.) + 6/20/82 669 ECC Fixed & Add to Labels Option to use @FO, fixing new + label Z not being added if ZZZ existed. Label + completer can handle new labels now. May be + controversial -- Lpre wont complete to + Lprefix. It takes pre as new. Now you must + Lpre. Abbrevs can get around this though. + 6/20/82 668 ECC Play with KMP's filler a bit, e.g. to handle Undoing + last fill if needed. Fix & Babyl Set Mode Line QNS + bug, & Read Babyl File to protect against errors in + Create Babyl File. Add Babyl O Message Hook. + 6/20/82 667 KMP Experimental change to ^R Fill Indented Mail Region + so that with an arg it can grok indented paragraphs. + 6/02/82 665 KRONJ Fix Edit Labels List to not leave blank + Labels option. Zap from of self in SvM. + 5/21/82 664 KRONJ Don't merge Reply-to into From if Reply-to + contains special chars (comma, angle brackets). + 4/21/82 663 LNZ Fixed & Setup Reply Template to properly handle the + case of Babyl CC To being nonzero. (zu5 was located + before the insertion of this name rather than after.) + 4/18/82 662 LNZ Fixed looping bug where Label Messages Containing + String expected # Babyl ^F to error at end of file. + 4/16/82 661 LNZ Added Babyl Keep TNX Received Date to control + adding a Rcvd-Date header line with the TNX received + date and time (in & ITSify TNX Mail). + 4/14/82 660 LNZ Fixed # Babyl O to correctly handle all three forms of + Append option (Append:, Append, or nothing). + 4/14/82 659 KRONJ Don't produce blank From: fields + 4/12/82 658 LNZ Fixed # babyl O UTC Error. + 4/12/82 657 LNZ Added Before Babylizing File Hook and fixed O + command to obey Append option of output file. + 3/15/82 656 EAK Added Babyl Default File for KRONJ. + 3/05/82 655 KRONJ Flush superfluous Reply-to: and Sender: headers, + merge Reply-to: into From: field when possible in + message reformation. + 3/04/82 654 Chiron Fixed Babyl reply command to not flush Babyl FCC To. + 1/16/82 653 ECC Various small changes suggested lately: add Babyl FCC + To for TNX, more care about Mail-From line for getting + host, new name Re-Enter Babyl for apropos use. +11/14/81 651 ECC Changing "badHeader" to "bad-header". + 9/14/81 649 ECC Do (BUG foo) and comment removal first in & Babyl + Survey One Message so comment contents, e.g. commas, + wont confuse later processing. + 8/18/81 648 KRONJ Abbreviate Stanford host names in SvM. + 8/12/81 647 EAK Remove TNX code to force Babyl files to be version 1. + 8/09/81 646 KMP Fixed & ITSify TNX Mail to allow for TNX message + length counts pointing past end of buffer. Some + mailers like to pad last word with nulls which TECO + treats as not there. + 7/30/81 645 ECC H works better for bad headers: user can edit the + visible header and then H. H will no longer complain + about the lack of original header -- thus also ok to H + if original header discarded. + 7/28/81 644 KRONJ Turn off auto fill mode within Edit Labels List. + Fix bug in # Babyl U where it wasn't catching the + lack of anything to undelete. + 5/29/81 642 ECC Fix Babyl/ZMail incompatibility: ZMail puts ^L + at end of Babyl files, and we werent trimming it + properly. Copied the code that does it to & Read + Babyl File, in addition to # Babyl G where it used to + be. (Probably ought to just be in one place, e.g. the + babylizer.) This should fix totalmsg# bugs, and NIBs + when appending new mail. + 4/07/81 639 Moon Fix handling of BABYL Append Option so that things + default reasonably, and add appropriate questions to + the babyl-file-creation dialogue. + 4/04/81 638 ECC & Babyl Set Mode Line only resets ..J if changed. + Mode line thus wont redisplay unless has changed. + Babyl G Done Hook does not get run if no-argument G + finds no MAIL option, but & Initialize Babyl Buffer + does get run since I needs it. + 3/28/81 636 KRONJ If there's no ^_ at end-of-file Babyl will still warn + but will insert it if continued. + 3/27/81 635 ECC Babyl G Done Hook now gets #messages argument, counted + by & Initialize Babyl Buffer. Rechecked URK handling + to never assume an URK cannot happen when consing or + inserting, but instead make it more failsoft. + Generalized Moon's useful change, e.g. to allow + reverse for appenders too (e.g. if mailer prepends + to their mail file) or for prependers to choose not. + 3/26/81 633 Moon When reading new mail, in Prepend mode, put the + messages in the correct order. Handle ..H correctly + in the command loop so that survey typeout gets + replaced by message display at the right time. + 3/25/81 631 ECC Made reforming URK-failsoft. Made the resurveyor use + the same 1st-text-line heuristic as the surveyor, and + fixed a couple of minor bugs in the resurveyor (q5 not + pushed, not always set). Moved F, V, R, and & Setup + Reply Template into BABYL from BABYLM to make latter + smaller; not needed there. + 2/22/81 626 ECC Added low-level mechanism for quiet surveys -- the + Survey Quietly variable. Changed one command to use + it -- # Babyl '. (Will hold all during that survey + menu invocation.) Renamed all *Brief*s to *Survey*s. + 2/22/81 625 ECC ^S K changed to ^S L. Fixed up T and Space -- were + all garbled from antiquity. E.g. Space wont reshow + header, will end with CRLF. T does header/200char + check properly. The SvM T changed: T types all of + message, nT just part of text (-nT header); in 2w, T + uses OTHER window, does so generally (EMACS switching, + so other window commands will work), nT displays just + text. Survey Menu binds window variables and uses + Babyl Command Hook so user can bind things. Default + value for Babyl Command Hook is code, now that IVORY + fixed to allow Altmodes in there. + 2/20/81 622 ECC Y sets Babyl Modified Messages, resurveyor tells ^R of + changes more precisely for better redisplay, SvM + fs^RNormal doesnt let Select Buffer set fsModeChange + (though this should soon be unnecessary when & Set + Mode Line has f=..J check), added 0K, K uses & Push + Message, Y and K ensure blank lines between killed + messages. + 2/18/81 617 ECC Fixed I bug not using default Babyl file. (Fix is + to have # Babyl S f[DFile.) + 2/12/81 613 ECC \ uses argument or Fill Column, not screen width. + 2/10/81 612 ECC Changed expunger algorithm to be two pass. Old way + was one pass but used a S...... which is 10 TIMES + SLOWER... Also changed status line hackers to not + touch fsWindow, since virtual buffer no longer + includes status line. + 2/04/81 610 ECC & Babyl Survey Several Messages no longers uses & + Maybe Flush Output, instead checking itself. Better, + since it will stop if user types Rubout. Sets + fsFlushed though, so others higher can use the + subroutine for convenience; fsFlushed reset to 0 in + command loop. Should stop the bug of + alternating survey line / Flushed when user types a + Space or Rubout ahead. Added Babyl Command Hook. + G allows multiple mail filenames in Mail option, but + currently only uses the first. Will later iterate + over them. This lets ZMail start using them. + 1/30/81 606 ECC # Babyl I should be more robust: it marks buffer read + only until all babylization and conversion is done, + and only then may mark buffer writable. + 1/27/81 601 ECC Made all dispatch table functions have documentation + class "C#". Changed the Babyl Helper accordingly. + Documentation now checks SubDoc to see if should + print information about subroutine use. Processes + active documentation. & Read Babyl File can ask for + another filename. See MC:ECC;BABSTR for command to + insert command, option, and variable abstracts, e.g. + for INFO file update. + 1/17/81 580 ECC Putting in the Version 5 stuff from now-empty BABYLV, + to with standardized version-converting routines. + 598 Terminology change: "key", "keyword" to "label", etc. + with several functions renamed for this. + Status bits now are basic labels, except reformed bit. + See & Convert Babyl File Version for format details. + Some new label routines. New basic label "recent". + G and O now may perform version conversion. More + robust G -- no leaving partial conversion or + babylization. See its comment. Message attribute + variables gone (e.g. Message Seen). Selector now just + bounds. E should be twice as fast since corrects + message# variables without another pass over file. + Line count in survey was +1, corrected. Quicker mode + line, no cache. O works on any bounds now, and + unlabels deleted and adds recent. ^S K not changed, + but maybe ought. +12/19/80 578 ECC Routines emptying *Brief* empty Babyl Modified + Messages since none to resurvey. It gets quite long. + Virtual bounds now just around the visible message, + not including old header or status line. No routine + should rely on whether bounds are set to get to status + line. Should make spurious display of EOOH etc + unlikely, improve use of two window operations, make + things safer and simpler for ^R command and X commands + that act on buffer, and prepare for day when Babyl + command loop disappears in favor of a Babyl mode. + Yanker changed in BABYLM to work with this. +12/14/80 575 ECC & Parse Header takes pre-comma numarg telling it not + to give error message about bad headers, but just + -1fsErrThrow so that the reformer can just mark it + and let the mode line tell the user about it. And + leaves point at top so EOOH line doesnt show. Other + callers though (e.g. R, F...) want the error message. + Also changed "Can't grok header" to more + understandable "Bad header -- not ITS nor NET style" + and "Bad header -- no colon in field". +12/08/80 573 GZ Changed & Babylize Digest Contents to not add a + "To:List-name" field if it is already there, and + to clean up any blanks/tabs on the "empty" line + separating the header from the message. Also + changed the use of some temporary q-regs so it will + be possible to have different host names for various + lists. Changed default host to MC, since SPACE is + not available at AI. + +11/30/80 570 ECC Merged KEYSET and SVMENU sources into BABYL, since + they do not change frequently anymore and will thus + simplify bookkeeping (and my directory). Here is + KEYSET history: + + 6/20 JP Under advisement from ECC, changed labeller to keep track of + changed messages for the (SvMenu) resurveyor. + 4/19 EC Changed to use keyword-reading with completion, with + keyword-abbrevs added and old crufty number defaults removed. + Added Undelete Keyset, changed | to use any keyset, added + Label Key Set. Made mapper not recalculate message#s since + that has awful paging behavior. Added Label Messages + Containing String. + ... Random changes over time... (lazy history keeping) + 9/?? EC Added and rearranged mapping stuff. + 8/26 EC Remind Me Of This Message takes negative argument to forget + message, fixed to start from next message correctly. + RemindNow is automatically declared a valid keyword. The + default filename for Output Key Set is made from the keyword. + Originated in the dark prehistoric days of late Spring 1979 or early + Summer of said-same year. Worked on considerably in July and released + to the world of Babyl on 12 August. + + Here is the SVMENU history: + Oct JP Changed to make use of fs^RNormal for intercepting printing + characters and interpreting them as Babyl commands. + + 7/4 ECC Born under colored patches of sky on 4 July, 1979. Worked on + considerably in late July and early August and released to the + world of Babyl on 12 August. After that, survey stuff + reworked to use real buffer and survey mode, use whatever last + survey was; T command changed and R added. Changed (along + with main-line Babyl) to keep track of altered messaged, and + to resurvey them. T command now tries to be clever with 2 + windows. + +11/15/80 568 KMP Fixed ^R Fill Indented Mail Region which was making + certain indented lines lose their indentation without + due cause. +11/09/80 564 ECC Added Gail Zacharias's M-x Undigestify Babyl Message, + & Babylize Digest Contents, & Find Digest Dash + Separator, and the option Undigestify Keep Digest. +11/08/80 563 ECC Merged in Kent Pitman's VBabyl extensions and + modifications: + Extended F (see BABYLM), added pre-comma argument to + M-x Babyl for DDT-run (^X exits to DDT if so), added + ^R Fill Indented Mail Region, & Estimate Mail-Line + Category, \, Tab. & Read Babyl File offers to create + a non-existant file. So M-x Babyl can create. + Fixed Create Babyl File messages, adding safe answers. + & Babyl Execute Options has fs^REnter reset to a nice + mode line macro, and ^R command does 1fsModeChange. + M-X Fill Mail Text is gone -- newer one is better. +10/02/80 536 JP Purged Babyl Abort Message in favor of throwing the + error message. Changed command lookup function. + Installed fs^RNormal hack in SvMenu. Installed hack + (by ECC) where if G gets a numeric argument, it will + prompt for a filename. Can grab system mail (ITS/20X) + as well as other Babyl files. Tweaked the + documentation a bit, plus some function names, so that + the help facility will work better. Fixed the bug + that crashes Babyl if the XMail file doesn't exist. + Installed the infamous missing-host heristic into the + header reformer. + 8/24/80 532 ECC Swapped names of ^F and F commands, so finder is now + ^F and forwarder F. Removed recipient-adders and + yanker to move them into BABYLM. + 7/17/80 526 ECC Create Babyl File will ask if want mail file, so TNX + users can say no -- they cant rubout-abort filenames. + # Babyl I and # Babyl E check if no messages, asking + user to either Q or I something else. Thus I think we + should now be able to have empty Babyl files without + trouble. D's N-after-D won't print message if no next + undeleted message. (N and ^N take 1, NUMARG.) + 6/20/80 514 JP Fixed parser to recognize Re: as synonym for Subject:. + 6/20/80 513 JP Installed various hacks of ECC's: Surveyor now takes + an option variable to limit the amount of effort it + will expend. New SvMenu hack keeps track of all + messages which have been munged -- when a survey is + reentered, modified messages are resurveyed in order + to keep the survey up to date. Also, & Initialize + Babyl Buffer now flushes the survey. + 6/11/80 511 ECC & Parse Header takes NUMARG telling about the + message, and won't reparse if possible. # Babyl T + and # Babyl R no longer uses ancient parser. R now + uses & Parse Header. & Initialize Babyl Buffer will + force reparsing. The ancient parser, & Babyl Parse + Header is gone. See at the end of this history the + large comment discussing Babyl parsing. + 6/11/80 510 ECC & Setup BabylM Library will set up Babyl ..D, thus + avoiding problems with calling & Process Recipient, + which expects it to be around. Also added local + variable Compile Command so can use M-X Compile. + 6/10/80 509 ECC Changed _BABYL _TEMP file to be [BABYL , in + order to avoid to avoid conflicts between users + sharing a directory. This will eventually be changed + again to avoid an intermediate file -- instead doing a + "transaction processing" approach, with the mail file + locked until the Babyl file is written. Also fixed + bug in # Babyl G that caused the Babyl file written + then (appending) to not have a good format: no + ^L or ^_ at the end. This is probably the + causes of all those strange crashes where there was no + ^_ at the right place -- someone had quit out of Babyl + without # Babyl Q or # Babyl S, and thus the Babyl + file written by # Babyl G was the one left. (Normally + the others clobber it to the correct format file.) + 5/21/80 503 ECC Moved Create Babyl File into here from BabylV, since I + want that library to only be sources of converters + and then only the out-of-date ones -- a history. The + creator should ask some questions about options. + 5/15/80 501 ECC ^R Babyl Yank has better window control -- won't go + to 1 window unless was Babyl in top, mail in bottom. + Similarly, # Babyl R will allow 2 windows to already + be in use, and just use the current window. Several + mail-sending routines removed to the BABYLM library. + It now needs to be compressed in with this, along with + KEYSET and SVMENU. + 4/26/80 497 ECC Changed # Babyl ^S prompting to work with new EMACS + prompting scheme, especially on printing tty. + Also added Babyl-Command-Abort catch and replaced + several fsERRs with throws to this. These are + "user mistakes", not internal errors. Added fsXMods. + 4/20/80 466 ECC Removed old keyword validation declarations, since + KEYSET now uses new completion scheme. Removed & Read + And Set Default that L used to use. Added Babyl + Keywords Option. + 4/17/80 493 ECC Added Survey Unlabelled Messages. Needs a little more + work, but mostly will benefit in efficiency from a + restructuring of the surveying routines. + 4/14/80 490 EAK FCC now appends directly to a TNX mail file. + 4/11/80 489 ECC Removed autoloading stuff for KEYSET and SVMENU, + since they are now to be compressed in. + 4/09/80 488 EAK Added Fcc: to & TNX Mail, and ^O command. + 3/03/80 472 EAK Removed FR before @V. + 2/27/80 470 ECC Renamed & Babyl Survey to & Babyl Survey Several + Messages to avoid naming conflicts being a prefix. + Added Babyl G Done Hook, though it needs more + work, concerning what conventions are, what state + should be before and after etc. Made mode line + display before message. Added Babyl Setup Hook. + 1/09/80 464 ECC Added Babyl File Consistent flag, which is + bound to 0 locally by & Babylize Buffer. & Read + Babyl File resets it locally to 0 before reading in + file, and then to 1 when done. Note that killing + the *Babyl* buffer will allow a new MM Babyl (it + checkes if *Babyl* is empty), but doing MM Babyl on + a non-empty *Babyl* which is marked inconsistent + will err. +12/07/79 461 ECC Added cheap forward command (^F). Made & Babyl + Parse Header set up its own ..D. +10/29/79 454 EAK Random cleanup. +10/03/79 439 ECC Changed format of modification history. Don't you + wish you knew what it used to be? +10/03/79 438 EAK Changed Q and S to use Write File. Finished + simplifying R's help. + 9/29/79 ECC Removed R's Submode stuff -- awaiting better, more + general help. Maybe should keep just [Mail] as + submode? Simplified R since TMACS now doesn't have + help or abort -- Babyl alone provides that. + 9/23/79 ECC Added Submode help message to R, added ^S command, + made F show its argument. + 9/19/79 ECC & TNX Mail Buffer copies message into a temporary + buffer before editing it. Original stays same, e.g. + for resending. + 9/18/79 ECC Added Babyl R Done Hook and Babyl O Done Hook, + e.g. for autolabelling messages "answered" or + "filed". Added Abort Babyl Mail Edit and Babyl R + Help Macro. + 9/13/79 EAK Added K and Y commands. Added 1R. + 9/06/79 ECC Continuing Catch Errors change: ^G is not rebound + by Babyl, and fsNoQuit is set to 0. + 9/03/79 ECC Changed to use new TMACS Catch Errors and have + fs^REnter bind it to 0 so errors don't exit  modes. + 8/15/79 ECC Worked on the survey commands: fixed up the unseen + handling to work with version 4. Spurious "Done"s + not printed by Survey Messages Containing String, B + prints "Done" or "Flushed". B takes pre-comma + NUMARG for not-emptying survey 1st and + not-typing-as-go. 0B just prints the label. & + Create Brief Variables is gone, replaced by & + Declare... & Push Message doesnt smash qregs 0 and + 1 now. ? command takes "*" instead of "?" to + document all commands. Survey Messages.. works on + the starting message too now. ' autoloads SVMENU. + 8/12/79 ECC Changed ? command to automatically generate its output. + 8/04/79 ECC Put & Babyl Get Message Keys into Babyl, from KEYSET. + Changed & Process Recipient Field to uppercase host + names in the recipient buffer, for TNX mailer. Made + most subroutine descriptions one-liners, with a + comment following so that Babyl takes less pure space. + 8/03/79 EAK,ECC Added & Process Recipient Field, used by & TNX Mail + Buffer and hopefully soon by lots of others -- is a + pretty fair RFC733 recipient field parser. + 8/02/79 EAK Fixed & Complete TNX Header - it wasn't narrowing + the bounds to just the header. + 8/01/79 ECC (And EAK a few days ago) Getting BABYL' ready for + installation. KEYSET loaded by L, |. Optional auto + labelling from subject fields. Cacheing used in + mode line setting. Status setting checks more + carefully that it is setting status bits, instead of + just bfing. + Bastille Day ECC Removed ..P to go into TMACS, changed to use & Declare + Load-Time Defaults, & Setup ensures that TMACS is + loaded. + 7/10/79 EAK Removed EOOH subroutines in a few places to restore + reasonable functionality (if you can get the proper + functionality with them then go ahead). Removed + blank line after ITS headers, and fixed bug in & Form + Header that deleted whitespace at beginning of message. + Fixed bug where things that begin with MSG: are + considered ITS messages. Things still need work. + 7/04/79 ECC Isolated EOOH handling into few subroutines, and + changed Babylization to start out by inserting EOOH + lines, simplifying other routines. In addition, + after Babylization, there is always a blank line + after the header, even for ITS headers. Added + routines for finding bounds of original and reformed + headers. & Reform no longer creates and kills its + variables each time -- I put that into the & setup, + in order to speed up reformation. The rest of the + changes were largely to help make Babyl more robust, + modular. + 7/03/79 ECC Merged Tenex/Twenex SEND-MAIL library into Babyl, so + that the reply command works on ITS, Tenex, and + Twenex now. + 6/30/79 ECC & Form Header trims away keywords in subject line, and + added & Push Message, new ..P, and Fill Mail Text. + Main command loop uses new ..p errset mechanism. + 4/30/79 ECC O can take 1, argument. + 3/21/79 EAK Added No Original option. + 3/18/79 EAK Removed Comment:s, added REPLY-TO. + 3/06/79 ECC Only set options if not exist already. + 3/05/79 ECC Add key-display support, in B and & Babyl Set Mode Line + 2/27/79 ECC Fix bugs and add minor features before doing major + keyset and survey- work. + < 2/79 EAK,ECC Ancient history beyond all recall... back in the days + when people were apes and Babyl was RMail. + *! + +!~FILENAME~:! !Mail subsystem! +BABYL + +!& SetUp BABYL Library:! !S Create option variables, call setup hook. +If the variable Babyl Setup Hook is non0 it is called at the end of Babyl's + setup, each time Babyl or BabylM is loaded.! + + m(m.m& Declare Load-Time Defaults) + SubDoc, + If non0, command documentation mentions subroutine use: 0 + Babyl Setup Hook, + If non0, is run immediately after loading Babyl library: 0 + + + !* & Setup BabylM Library will call the setup hook.! +  + + +!:! !S Mail file editor subsystem. +Same as the Babyl and Re-Enter Babyl commands.! +!* Separate just so that it does not appear in the automatically produced INFO! +!* section concerning commands.! + f:m(m.mBabyl) !* Turn into the other command.! + +!Babyl:! !Re-Enter Babyl:! !C Mail file editor subsystem. +String argument is Babyl filename. It defaults, and can be + overriden. Describe the I command for details. +If Babyl was temporarily exited before, this command will re-enter it + instead of starting a new session. The # Babyl ^X command is + the one that temporarily exits Babyl. +DOC +.(g(m.m~DOC~ Process Babyl Init or Vars File) + -:sSubDoc"l 0:l 2r .,zk)j kCOD +qSubDoc"n i +A pre-comma numeric argument means this should exit back to DDT or EXEC. +Remembers this in Babyl Standalone Job (non0 if exiting to DDT).'! + + m(m.m& Declare Load-Time Defaults) + Babyl Standalone Job, Non0 means will exit to DDT/EXEC: 0 + + m(m.m& Push to Buffer)*Babyl* !* Select BABYLs own buffer.! + 1f[^RMore !* use --MORE-- in mode line! + fsZ"e !* If buffer is new! + m(m.mText Mode) !* initialize its mode! + 1f !* If I ok, can continue.! +  > !* But if empty, exit.! + ' !* ...! + "# @ftReentering temporarily exited Babyl... + 0fsEchoActivew !* Remind user not new file.! + f*' !* Ignore but require a string! + !* argument for compatibility.! + "'nuBabyl Standalone Job !* Remember whether should exit back! + !* to DDT directly, not EMACS.! + fs^RMode"n :m(m.m& Babyl Execute Options)' + +!* Babyl expects to be inside a ^R. If that isnt so, we must call + a ^R, after arranging for the ^R to call & Babyl Execute Options. + *! + + @:i*| f]^REnter !* Reset to old fs^REnter now that! + !* we are in  mode. See below for! + !* where fs^REnter is pushed.! + m(m.m& Babyl Execute Options) !* call command processor! + fs^RExit !* exit stupid ^R mode! + | f[^REnter !* push fs^REnter to reset once! + !* inside  mode.! +  !* Enter  and call Babyl! +  + +!Edit Babyl Options:! !C Lets user change options for current Babyl file. +Will ask you about each of the various Babyl options that a Babyl file + may have. +This command should only be called from within Babyl. +qSubDoc"n iPre-comma numarg means called by creator: dont check buffer, + and dont print message about [..].! + + [U[Y [1[2[3[4[5[6[7[8[9 f[DFile + fsXUName:f6uU !* U: Uname! + 1f[FNamSyntax !* Lone filename becomes fn1 without! + !* changing fn2.! + m.m& Yes or NouY !* Y: Asks yes (-1) or no. (0)! + + "e !* Unless called from creator, check.! + .u1 !* 1: Original point.! + f~Buffer Name*Babyl*"n !* Check correct buffer.! + oBadFile' !* ...! + 0,(fsZ)fsBoundw j :ff~BABYL OPTIONS:"n oBadFile' !* ...! + :s +"e !BadFile! q1j !* No good Babyl file.! + :i*Edit Babyl Options must be used within BabylfsErr' !* ...! + q1j !* Restore point, so message push uses! + !* it. hmm...! + !* Restore point etc. carefully when done all this resetting: ! + m(m.m& Push Message)' !* ...! + + @fn|m(m.m& Reset Babyl Options)| !* And reset variables too.! + + j s + 0l b,.fsBoundw !* Bound to just BABYL OPTIONS.! + + !* Qregs 1-7 will collect the new options. Reset now to old values, so! + !* can use as defaults. Use values in buffer, for sureness. Could use! + !* variables, but at least Babyl Owner Option is not the same -- trimmed! + !* to one if this user is in an owner list. Note that at the moment, not! + !* all these old values are used as defaults. The others are Yes/No! + !* questions anyway, so easy to answer.! + + 1f[BothCase !* Case-independence in option names.! + j 0u1 :s +XMail:"l @f l :x1' !* 1: 0 or XMail filename.! + j 0u2 :s +Mail:"l @f l :x2' !* 2: 0 or Mail filename.! + j 0u5 :s +Owner:"l @f l :x5' !* 5: 0 or owner string.! + + + !* Ask for the new options: ! + + ff&2"e !* Caller might already have printed.! + ftTypical (and safe) answers to questions will be shown inside brackets, + as in: [Y]. +' + + q2"n et2' !* Try old mail option as default,! + "# etDSK: fsHSnamefsDSNamew !* or default to users directory.! + fsOSTecof"ew etU MAIL' !* ITS mail file.! + "#-1"e etMAIL.TXT.1' !* TWENEX mail file.! + "# etMESSAGE.TXT;1''' !* TENEX mail file.! + 0u2 !* 2: 0 if no mail file.! + ftIs there an incoming-mail file [Y]?  mY"n !* ...! + 1m(m.m& Read Filename)Mail filenameu2' !* 2: 0 or mail filename.! + q2"n et2 fsDFileu2' !* 2: 0 or full mail filename.! + + 0u4 !* 4: accumulates Babyl Append Option.! + ftDo you want new mail to be appended to the end (rather than inserted + at the beginning) of the Babyl file [Y]?  mY"n 1u4 ' !* 4: append.! + 1u8 !* 8: will be non0 if mailer appends.! + q2"n !* If the Babyl file has an incoming-mail file, then find out whether! + !* new mail needs to be reversed or not: ! + fsOSTeco"e !* ITS, where user can tell the mailer! + !* either to append or prepend to the! + !* mail file.! + ftDo you tell Comsat (R-OPTION APPEND) [N]?  mY"e 0u8'' !* 8: prepends! + q4-q8"e !* If do same thing (append/prepend)! + !* to both mail and Babyl file,! + !* messages are ordered.! + ftDo you want the incoming new mail reversed (this will make it + inconsistent with the BABYL file though) [N]? ' !* Prompt.! + "# ftDo you want the incoming new mail reversed (to be consistent + with the BABYL file) [Y]? ' !* Prompt.! + mY"n q4+2u4'' !* 4: add in whether should reverse.! + + q1"n et1' !* Use old XMail as default, if one,! + "# etXMAIL.TXT' !* or use standard default.! + 0u1 0u3 !* 1,3: 0 or XMail, XMail Append opts.! + q2"n fsOSTeco"n !* On TNX dont have mailing lists, so! + !* see if wants to fake one.! + ftDo you want an XMail file, which gets copies of all incoming mail as it + is added to the Babyl file [N]?  + mY"n m(m.m& Read Filename)XMail filenamef"nu1 !* yes.! + et1 fsDFileu1 !* 1: XMail filename.! + ftDo you want mail appended to the XMail file [Y]?  + mY"n 1u3''''' !* End of XMail option hacking.! + + q5f"ew qu'u8 !* 8: Default owner spec.! + 0u5 !* 5: Will be 0 or owner string.! + ftIs there an owner for this Babyl file [Y]?  mY"n !* yes.! + 1,m(m.m& Read Line)Owner user name (8): f"nu5 !* 5: Owner.! + fq5"e q8u5''' !* 5: If user typed CR, default owner.! + + ftHeader can be reformatted to look better and not show redundant or useless + fields, and missing host names will be added so other commands will work + better, e.g. the reply and forward commands. +Do you want headers to be reformed [Y]?  + mY"e 1u6 0u7' !* 6: No Reformation option.! + "# 0u6 !* 6: 0 means DO reformation.! + 0u7 !* 7: No Original, default 0.! + ftIn general the old headers are saved, so the 1H command can show them. +Should original headers be discarded [N]?  mY"N 1u7'' !* 7: No original.! + + !* Now that we have picked up all the options we can set them. (Dont want to! + !* set as go, since if user aborts with ^G, then some options would be reset,! + !* some not.)! + + j :s +Mail:"l 0lk' !* Default is for no mail file.! + q2"n jl iMail: 2 +' !* Put in Mail option if one, at top! + !* since is important. Not matter.! + j :s +Append"l 0lk' !* Remove old Append option.! + jl iAppend:  q4\ i + !* Insert new Append option.! + j :s +XMail:"l 0lk' !* Default is for no XMail.! + q1"n zj iXMail: 1 +' !* Insert new XMail if one.! + j :s +XMail Append"l 0lk' !* Default is for no XMail Ap..! + q1"n q3"n zj iXMail Append +'' !* Put in XMail Append if one.! + j :s +Owner:"l 0lk' !* Default is for no owner.! + q5"n jl iOwner: 5 +' !* Put in Owner if one.! + j :s +No Reformation"l 0lk' !* Default is for reformation.! + q6"n zj iNo Reformation +' !* Maybe turn off reformation.! + j :s +No Original"l 0lk' !* Defult is to keep originals.! + q7"n zj iNo Original +' !* Discard them if desired.! + + 0u..h !* Dont leave typeout on screen.! + + !* Not a real abort, since 0 causes no message. But forces & Babyl Execute! + !* Options to reset its qregs to pick up new option values: ! + + 0f;Babyl-Command-Abort + +!Create Babyl File:! !C Create a new Babyl file, with sample message. +Will ask you for the Babyl filename, or you can give it as a string + argument. With a standard default for a user's main Babyl file + that reads the user's mail file. Will ask you about each of the + various Babyl options that a Babyl file may have. +Offers to send a message to BABYL-REQUEST@MIT-MC, requesting that + you be added to INFO-BABYL@MIT-MC. +qSubDoc"n i +The filename may be passed as a pre-comma argument.'! + + m(m.m& Declare Load-Time Defaults) + Babyl File Version, * 0: read max version, write back to same; + 1: read and write version 1, similar for other positive N; + -1: read max version, write back to next version + This only applies to Tenex or Tops-20 systems.: 0 + + + [H[U[V[Y[1[2 0[3 f[DFile "e :i3 fq3"e 0u3'' !* 3: 0 or filename! + fsXUName:f6uU !* U: Uname! + 1:"n 0uh' !* H: Hostname or 0.! + fsOSTeco"e :ihMIT-h' !* H: Change AI, e.g., to MIT-AI.! + qBabyl File Versionuv !* V: Version spec.! + e[e\ fne^e]' !* Push I/O.! + 1f[FNamSyntax !* Lone filename becomes fn1 without! + !* changing fn2.! + m.m& Yes or NouY !* Y: Asks yes (-1) or no. (0)! + etDSK: fsHSnamefsDSNamew !* Default to users directory.! + etU BABYL !* Default Babyl filename.! + fsOSTeco"n qv"g qv'"# 0'fsDVersionw' !* Set version to 0 or N.! + + f"ew q3f"ew 1m(m.m& Read Filename)Babyl filenamef"ew'''u3 + + !* I think overwriting max is correct, even for Create -- not to mention the! + !* soon-to-be Edit Babyl Options: ! + et3 fsOSTeco"n fsDVersion"e !* TNX user didnt say particular N.! + qv"e !* If overwriting max, find N.! + 1u1 1:w q1fsDVersionw' !* ...! + "# qv"g qvfsDVersionw'''' !* Or set it from version spec.! + fsDFileu3 !* 3: Babyl filename.! + + ftCreating Babyl file 3. +Typical (and safe) answers to questions will be shown inside brackets, + as in: [Y]. + + + !* Clobber check only necessary on ITS (no version) or if specific version! + !* being used: ! + fsDVersion"n oCLOBCHK' !* Specific version mentioned.! + fsOSTeco"e !CLOBCHK! !* Check on ITS no matter what...! + e?"e ftClobber existing 3 [N]?  + mY"e ftAborted. 0''' !* ...! + + !* Will build a basic Babyl file in a temporary buffer, then call Edit! + !* Babyl Options to let user specify the options.! + + f[BBind !* Temporary buffer.! + + iBABYL OPTIONS: +Version:5 + +0, recent, unseen,, +*** EOOH *** +Date:  fsDATEfsFDConvertw i +From: BABYL at  qh"n gh'"# iHere' i +To: U at  qh"n gh'"# iHere' i +Subject: New Babyl file + +This is a sample message in the new Babyl file. +Feel free to delete it. + + + 1fw !* ...! + + 0,(fsZ)fsBoundw !* Widen bounds to whole buffer.! + et3 !* Set Babyl filename.! + f[DFile et[TECO] OUTPUT fsOSTeco"n 0fsDVersionw' !* On TNX, open to! + ei !* a safe file.! + f]DFile hpef !* Write out the file.! + fsOFileu1 @ft +Written: 1 + 0fsEchoActivew !* Tell user.! + + qh"n ftWould you like mail sent to BABYL-REQUEST@MIT-MC, requesting + that U@H be added to the INFO-BABYL@MIT-MC + mailing list?  mY"e ' !* No.! + hk !* Yes, clear way for message.! + iFrom: U at H +Sender: Babyl +To: BABYL-REQUEST at MIT-MC +Re: INFO-BABYL + +gBabyl Header/Text Separator i +Please add U@H to INFO-BABYL. + + 1:< fsOSTeco"e m(m.m& ITS Mail Buffer)' !* Send it off.! + "# m(m.m& TNX Mail Buffer)' + >"n ftCould not mail the request.' !* If we can...! +  + +!^R Fill Indented Mail Region:! !^R Fill Region being smart about indentation. +Fills region something like ^R Fill Region, but will keep + indentation and will not touch mail header or mail separator (e.g. + dashes) lines. +In particular, this is good for filling an indented message yanked + into a *Mail* buffer by the ^R Babyl Yank command. It will + respect indentation within the indented text too -- e.g. if the + yanked message contains within it another yanked message, etc. +Will also check for an ITS-header subject and put it on its own line, + in case the subject is very long and might be too long for the + screen width. +M-x Undo will bring back the old text, in case filling caused more + problems than it is worth. +With an explicit arg, this will try a different algorithm which may be + useful for filling messages with indented paragraphs, but which + will probably lose on some included messages.! + + [0[1[2[3[4[5[6[7[8[9[.0[.1[.2 + qFill Extra Space Listu.2 !* .2: Chars that want 2 spaces.! + [Fill Column qFill Columnu6 !* 6: Fill Column.! + f[VB f[VZ !* Save virtual bounds.! + m.m^R Back to Indentationu3 !* 3: Moves past indentation.! + m.m^R Delete Horizontal Spaceu4 !* 4: Deletes whitespace.! + m.m& Estimate Mail-Line Categoryu5 !* 5: Mail header detector.! + m.m^R Fill Regionu8 !* 8: ...! + m.m^R Indent Rigidlyu9 !* 9: ...! + + !* Before saving for our Undo, see if we should first Undo an immediately! + !* preceding mail-fill. This typically happens when the user used the! + !* default mail-filling, noticed that it fouled up paragraph indentation! + !* lines, and decides to mail-fill again, this time specifying the other! + !* method. We have to Undo first, since otherwise those paragraph! + !* indentation lines wont get merged back together, and will look like! + !* separate paragraphs, leaving the user with no improvement whatsoever.! + + .,(:)fu1u0 !* 0,1: sorted region points.! + q:..u(0!*buf!)-q..o"e !* Same buffer as previous Undo,! + q:..u(2!*start!)-q0"e !* same starting point,! + q:..u(3!*end!)-(fsZ-q1)"e !* same ending point,! + f~:..u(4!*desc!)message-fill"e !* and same description.! + !* All that rules out the easy cases of different. However, we! + !* still have to ask the user. E.g. inside mail edit, fills the! + !* whole message. Sends it off. Now another mail edit, with same! + !* header, and filling the whole text part. Has the same start and! + !* end "points', so it looks the "same'.! + ftIs this the very same message you filled before? (I.e. are you +correcting an immediately preceding fill of this message, perhaps by +giving different argument or Fill Column this time? +If unsure, safest thing is to answer no.)  + m(m.m& Yes or No)"n 1m(m.mUndo)w' 0u..h'''' !* ..H: Let redisplay.! + !* That should have reset Point and Mark, so we can use them below.! + + .,(:)ffsBoundw !* Set buffer bounds to region.! + hm(m.m& Save for Undo)message-fill !* Make this command undoable.! + 5*5fsQVector[..u @fn|q..ufsBKillw| !* Dont let ^R Fill Region mess up our! + !* undo qvector...sigh...! + + j 0l .u0 !* Start at head of line, put in q0! + q0f(:\u0 fn0jw )u0 !* Come back here when done! + .( zj 0f"n !* Make file end in a newline! + i +' !* ...! + )j !* ...! + + < .-z; 0l !* Loop from point to bottom! + m5"n l !' !* Skip mail header/separator lines.! + :f"e l !' !* Skip blank lines.! + + !* Found a line which can be filled. Now merge this line and each! + !* successive line with the same indentation. (As long as that line is! + !* not a header or separator or blank line: ! + + @m3w !* Skip past indentation.! + fsSHPosu1 !* 1: offset from head of line! + @m4w !* Get rid of initial indentation! + 0u.0 !* .0: flag saying if first time thru.! + < l m5:@; !* Next line. Exit if a header line.! + @m3 !* Skip past indentation.! + :f@; !* Exit if null line or at end.! + fsSHPosu.1 !* .1: Indentation for this line.! + q.1-q1"e !* Same indentation.! + 0:k @m4w !* .0: So merge it with previous line.! + 0,0af.2:"l i ' i  !* Need 2 spaces if after some chars.! + 1u.0 !' !* .0: Not first time through. Now go! + !* check next line..! + q.0"e !* If first time through! + ff"n !* and if paragraph-option ! + q.1-q1 f"l +9"g !* and indentation decreased 1-8! + -1l q1-q.1, i !* then reindent paragraph starter.! + l @m3w q.1u1 !* 1: Go back where we were, and reset! + !* current indentation for rest of! + !* paragraph.! + 0:k @m4w i  1u.0 !''w'' !* .0: and loop for more lines there.! + + 0; > !* Different indentation, so exit.! + + !* The previous line is now one long merged line that can be filled and! + !* then reindented: ! + + 0l .: -l !* Set the Region around that line.! + q6-q1uFill Column !* Account for indentation.! + @m8w !* Fill the merged lines.! + .-z( q1m9w )+zj !* Reindent them.! + > !* Go see if any more lines that can! + !* be filled.! + + q0j !* Jump to top again.! + + !* Now try to check for ITS header subjects and if long, put them on their! + !* own line. Will recognize one by seeing if a date-like thing is followed! + !* by Re: .! + + < :s:: Re: ; .u7 !* 7: Point where subject starts.! + :l fsSHPos-q6"g !* Subject goes past fill column.! + q7j -4d i +Subject:  !* Move subject to its own line.! + -l m3 fsSHPos(l), i' > !* Make indentation match.! + + + z: !* Set point after region altered.! + q0,z  !* Return region changed.! + +!& Estimate Mail-Line Category:! !S Categorize current line. +Return 0 if not mail-related, + 1 if header line, + 2 if separator line, + -1 if send header line.! +!* Heuristic, for use on mail text which might contain an embedded message.! + +!* A comment about the heuristics determining whether a line is a header field! +!* line and the effectiveness of them: Some lines will be considered not! +!* mail-related (0) which really are, e.g. a two-word field name or a! +!* continuation line. But these will frequently be ok, at least for the! +!* command ^R Fill Indented Mail Region since if the two-word field name line! +!* is surrounded by lines which are correctly categorized, it will not be! +!* merged into them. Similarly continuation lines will be filled together but! +!* not merged into surrounding lines since their indentation will be! +!* different. Thus, for ^R Fill Indented Mail Region at least, the! +!* 0-categorization is generally not detrimental.! +!* Note also that the filling of code -- especially code where there is much! +!* variance in indentation such as lisp -- will tend to do the right thing! +!* since lines will so often occur at different indentation levels that they! +!* will not get merged. Other languages -- eg, Midas -- which do not vary! +!* indentation much, will come out totally screwy, but this would be too slow! +!* if it tried to check too much unless someone can find a good heuristic for! +!* identifying language regions quickly! + + [0 0f[vbw f[vzw !* Open bounds above.! + !* First, ^_-related checks to protect the structural integrity of! + !* a Babyl file in case of uncontrolled (mistaken) filling.! + 0l 0,1a-"e 2' !* Babyl file separator line.! + -4f= +"e 2' !* Babyl file status line.! + + 1:fsBoundw !* Bind bounds to this line.! + qBabyl ..D[..d !* ..D: Use header syntax table.! + :g..du..d !* ..D: Make a copy of it.! + :*5:f..d  !* ..D: Modify to make : a word! + !* delimiter.! + !* Maybe Babyl ..D should standardly have word syntax for skipping over field! + !* name???! + + 1:"n j oLast' !* Maybe exit if past line end.! + + (-1,1a-:)*(-1,1a-@)"e j 1' !* Look for @ or : after first word! + 0l @f l !* Skip whitespace! + 12f=MESSAGE FROM"e j -1' !* Old style send header! + 13f=[MESSAGE FROM"e j -1' !* New style send header! + :ff~*** EOOH ***"e j 2' !* Call EOOH-line a separator.! + qBabyl Header/Text Separatoru0 !* 0: E.g. --Text follows...! + :ff~0"e j 2' !* This line is a separator.! + + !Last! !* Come here before giving up! + + @f l !* Past whitespace.! + :f"n @f-_l :f"e j 2'' !* If rest of line is dashes and! + !* underscores, call it a separator.! + j 0 !* Nothing special.! + +!Undigestify Babyl Message:! !C Break up a digest into individual messages. +The digest is assumed to be the currently selected message. It will + be replaced by the series of messages which made up the digest. A + "To:List-name" field will be added to each message header, for + replying and visual identification of the source digest list. +The option variable Undigestify Keep Digest controls what happens to + the original digest. This variable can have several values: + 0: digest is discarded + +n: digest is kept, before the individual messages + -n: digest is kept, after them + +1: digest is additionally marked Deleted + -1: same +If a precomma arg is given it is used instead of the value of the + variable.! + + m(m.m& Declare Load-Time Defaults) + Undigestify Keep Digest, + * Describe M-x Undigestify Babyl Message for details on values: 0 + + + [l[d + + m(m.m& Bounds of Header)w !* Move to start of message.! + @f +l !* Move to first non-blank.! + .,(fb   r).xl !* L:first word (list name).! + + m.m& Find Digest Dash SeparatoruD !* D: Separator finder.! + 65,85mD"e !* Find end of topics list.! + :i*Bad Digest formatFSErr' !* Not found - err out.! + f:m(m.m& Babylize Digest Contents) !* OK, so go undigestify.! + +!& Find Digest Dash Separator:! !S Find a line of numarg1 to numarg2 dashes. +Blanks before end of line are ignored. We move past the found line if any. +Returns 0 for failure, -1 for success.! + + f[SString [1 !* Save search default.! + ,-:i1 !* 1: minimal separator string of! + !* dashes.! + 0s +1 !* Set search default to line! + !* starting with minimal separator.! + fu1 !* 1: number of extra dashes allowed.! + + < :s"e 0' !* Find line starting with separator.! + !* If none, exit failing.! + q1,z-.f:u1w !* 1: min(q1, #chars-left-in-buffer),! + !* to avoid NIB error in F^B below.! + q1@f-l !* Move past extra separator chars,! + !* up to the number allowed.! + @f l !* Move to first non-blank character! + !* after those allowed dashes.! + .-(:l .)@; !* Exit if at end of line.! + > !* Else not it, loop.! + + 1l -1 !* Move to next line and exit! + !* successfully.! + +!& Babylize Digest Contents:! !S Does the work. +Bounds must be around a digest and . must be just past Topics section +separator, before contents of the digest. +QL must contain list name of digest. +QD must hold & Find Digest Dash Separator.! +!* This routine will: + 1. Save for Undo. + 2. Check Undigestify Keep Digest as well as precomma arg and + do the right thing as described for M-x Undigestify Babyl Message. + 3. Insert babyl-separators between messages past point. + 4. Update Message Number,Parsed Message Number and Number of + Babyl Messages. + 5. Flush the survey buffer, because message numbers changed. + 6. Select the Topics section as the current message.! + + m(m.m& Declare Load-Time Defaults) + Undigestify Keep Digest, + * Describe M-x Undigestify Babyl Message for details on values: 0 + + + [0[1 [b[t + fsmachineu0 + .-b[p !* P: offset of start of digest.! + qNumber of Babyl Messages !* N: Total # of messages before! + !* undigestifying.! + :itTo: l@0 + !* T: To: list-name at host line.! + !* Use our real host fer gossake! + b,zm(m.m& Save for Undo)undigestify !* Make us undoable.! + +!* Undo will work as long as no non-digest msgs are messed with however the! +!* message numbers will be really messed up... Need to do & Initialize Babyl! +!* Buffer to recover completely.! +!* No help for it I think -- cretinous undo facility in EMACS.. -- ECC! + + ff&2"e !* Get option or numarg.! + qUndigestify Keep Digest' "# 'u1 !* 1: ... Keep digest?! + q1"n !* Non-0 means yes: ! + hx0 bj g0 i + !* Make copy of entire message.! + %nw !* N: increment # of messages.! + q1-1"e !* 1, or -1, so mark digest deleted.! + .(q1"l z' "# b'j !* Move to the appropriate copy.! + m(m.m& Add Basic Label)deletedw !* Delete it,! + )j' !* and restore point.! + q1"l 4r fsZ-.fsVZw' !* Negative - work on 1st copy.! + "# .fsVBw !* Otherwise work on 2nd copy.! + %Message Numberw'' !* so increment Q$Message Number$.! + + b+qpj !* Go to start of messages.! + f[vb !* Save top of digest.! + fsbconsub !* B: temp buffer for parsing headers.! + f"n !* If still not a good header! + j 2lit +' !* make To:listname line the header.! + "# qb[..o gTo: gCc: !* Else get recepients in temp buffer! + j :sl ( !* and search for list name.! + hk ]..o !* (all done with temp buffer)! + )"e !* If listname not among recepients! + j 3l gt'' !* insert it as 2nd line of header.! + + < 27,33md"e f;Msgs' !* Find separator, exiting if not! + !* found.! + -:l.,(0l).@f  (2l)@; > !* Make sure really separator.! + !* The line before it should be blank.! + > !* Else do it again.! + + qbfsbkill !* Kill the temp buffer.! + + qnuNumber of Babyl Messages !* Updated total # of messages from QN! + 0uParsed Message Number !* Numbering changed, so don't rely on! + !* it.! + :iBabyl Modified Messages !* No messages to resurvey.! + fq*Survey* Buffer"g !* If non-empty survey buffer.! + q*Survey* Buffer[..o !* Select it.! + hk 0fsModifiedw 0fsXModifiedw !* Flush it since numbers changed.! + ]..o ' !* And return to original buffer.! + + f]vb j !* Go back to Topics section.! + :m(m.m& Babyl Select Message) !* And select it.! + +!Shorten From Field For Hermes:! !C Only username. +Forces the From field to be just Username at Host, no personal name + part. +Nice for Hermes, so other people can see your subject line in a + survey, since Hermes doesn't truncate a long From field.! + + fsOSTeco"e :i*Only intended for use on TNX fsErr' + z-.[1 !* 1: Original Z-.! + bj .,(i +).f !* Boundary condition.! + bj :s +From:"l 0lk'"# l' !* Kill old From if any.! + .,(iFrom:  g(fsXUName:f6) i + + ).f !* Just username.! + j .,(@f +k).f !* Remove boundary condition.! + z-q1j 1 !* Back to original point.! + +!# Babyl ^C:! +!# Babyl ^Z:! !C# (^C on ITS, ^Z on Tops-20) Return to DDT/EXEC temporarily.! + 100000.fsExit +  + +!# Babyl ^D:! !C# Delete message and move backward.! + -1,(f) :m(m.m# Babyl D) + +!# Babyl ^F:! !C# Find and select message containing a specific string. +Given no numeric argument the search is forward, starting with the message + after the current one. +Given a positive argument, N, searches forward for the Nth message to + contain the string. +Given a negative argument, -N, the search is backward, starting with the + message before the current one, for the Nth message to contain the + string. +If no match is found, returns to current message.! +!* +Pre-comma NUMARG is string to search for. If no pre-comma NUMARG, uses & Read +Line to ask for it. We return -1 on success and zero on failure. Diagnostic +is only issued if no pre-comma argument (e.g. we prompted the user for the +search string). Otherwise, we just return. +! + + m(m.m& Declare Load-Time Defaults) + Babyl F Default,: || + + + [0[1[2 + ff&2"n u0' !* 0: string passed as pre-comma.! + "# qBabyl F Defaultu1 !* 1: Default from last F.! + ff"n :\u2 :i22 '"# :i2' !* 2: Stringified NUMARG.! + 1,m(m.m& Read Line)2Find (Default "1"): u0 !''! + !* 0: string read from user.! + fq0"l ' !* Give up if rubbed out! + fq0"n q0uBabyl F Default'"# q1u0' !* Null string => use default; else! + ' !* it is new default.! + + 0f[vb 0f[vz .u1 @fn| q1j | !* save current state of things in! + !* case search fails! + f"ew 1',0f< !* Search for abs(N)th match.! + "l -':s !* Start at end/top of this message.! + "l -':s0"E !* Search for the string.! + ff&2"N 0' !* Not found -- exit quietly,! + :i*Not foundf;Babyl-Command-Abort' !* or not-so-quietly maybe.! + > !* ...! + ]..N ]*w ]*w !* Throw away saved state.! + m(m.m& Babyl Select Message) !* set bounds around found message! + m(m.m& Calculate Message Number) !* Figure out where we ended up.! + ff&2"N -1' + +!# Babyl ^H ~:! +!# Babyl :! !C# Move to previous screenfull.! + f @m(m.m^R Previous Screen)w +  + +!# Babyl ^I ~:! +!# Babyl :! !C# Reformat a losing message that contains ^J's, ^H's, etc. +Replace them with their visual counterparts... + ^H deletes character before it, + ^J inserts carriage return + whitespace + ^M becomes CRLF. +This is undoable. (I.e. M-X Undo brings back old message.)! + + [0[1 + m(m.m& Bounds Of Header):jw !* Go to top of header.! + .u1 fnq1j !* 1: Auto-restoring point.! + .f[VB :s"l r'"# zj' fsZ-.f[VZ !* Bounds around message.! + hm(m.m& Save for Undo)character fix !* Make this command undoable.! + + !* Convert LF to CRLF + whitespace: ! + j <:s + ; rd !* Delete stray linefeeds.! + fsHPosu0 !* 0: Current column. Not SHPos since! + !* wrapping should be handled as is! + !* visually.! + i + q0, i r > !* Put in CRLF, indentation.! + + !* Backspaces delete themselves and previous character (unless at beginning! + !* of line): ! + j <:s; 0f-1"g -2d'> !* ...! + + + !* Convert CRs to CRLFs: ! + j < :sî ; !* Find stray ^M.! + -d i + > !* Convert to CR LF.! + +  + +!# Babyl ^J ~:! +!# Babyl :! !C# Jump to next unseen message.! + + .[0[1 !* 0: Original point in case dont! + !* find anyone.! + m.m# Babyl ^N !* N: Next message mover.! + m.m& Check Message Label !* C: Label checker.! + qMessage Numberu1 !* In case we just happen to want to! + !* come back here.! + f"E ' !* Go until unseen.! + !* If control gets here, then we are! + !* ..throwing up [sic].! + q1m(m.m# Babyl J) !* Go back to starting message.! + :i*No more unseen f;Babyl-Command-Abort !* Change diagnostic and propogate! + !* ..the throw.! +  + +!# Babyl ^L:! !C# Clear screen. Given a numeric argument, keeps same window.! + ff&1"n fsWindow(f+)fsWindoww ' !* Keep same window.! + f+  + +!# Babyl ^M ~:! +!# Babyl :! !C# No-op, flushes argument, and goes to next line.! +!* & Babyl Execute Options has already echoed the return. So we simply! +!* get rid of the argument by returning no value -- returning a value! +!* means keep the argument that has accumulated in Q5.! + +  + +!# Babyl ^N:! !C# Move to next message, whether deleted or not. +If argument, n, goes to nth next. +qSubDoc"n i +1, NUMARG means dont print any error message (just throw quietly). +String precomma numarg is label to f;-throw to if fail.'! + -[1 [2 !* 1: Count messages moved past.! + !* 2: 0, 1, or f;-label.! + m.m& Babyl Select Message !* S: Message selector.! + < 0fsVZw !* Set wide bounds below.! + :s +; !* To next message if any.! + ms !* Select it.! + %Message Numberw !* Probably better to keep in loop so! + !* 1 case is best -- N does 1^N loop.! + %1; > !* 1: Count message, stop if done.! + q1"n ms !* Reset bounds, message status.! + q2fp"g f;2' !* Caller wants to catch this case.! + q2-1"n :i*Now at end, no next message '( !* Set error message if no 1,! + !* ..NUMARG.! + ) f;Babyl-Command-Abort ' !* And throw out of here.! +  + +!# Babyl ^O:! !C# Append current message to a TNX mail file.! + m(m.m& Declare Load-Time Defaults) + Babyl ^O Filename,: |FOO TXT| + + FS Date[0 !* Use current date and time. ! + 0F[V B 0F[V Z .[2 -S C :SRcvd-Date:+1"E @F L + FS FD Convert F"G U0 '' Q2J ]2 F]V Z F]V B !* unless Rcvd-Date: is present. ! + + [1 qBabyl ^O Filenamef"ew'f[DFile !* Bind default filename to ^O! + !* default if one exists.! + 5,f Add message tou1 et1 !* 1: Get filename.! + fsDFileuBabyl ^O Filename' !* Remember altered filenames! + e[ e\ fn e^ e] !* Push i/o.! + !* Assumably the message has been selected, and therefore bound. If not, we! + !* wont err, but strange stuff could be appended to the file. Should we! + !* bound carefully?! + q..ou1 f[BBind !* 1: Original buffer, message.! + g1 + :s +Re: + ++1"e @f l 0k iSubject: ' !* change Re: to Subject: ! + Q0:m(m.m& Append to TNX Mail File) !* append buffer to file! + +!# Babyl ^P:! !C# Move to previous message, whether deleted or not. +If argument, n, moves to nth previous.! + -[1 !* 1: Count messages moved past.! + qMessage Number-1< !* don't go back too far! + 0fsVBw !* Set wide bounds above.! + -:s; !* Back to end of previous message.! + 1:@:; !* Abort if error! + qMessage Number-1uMessage Number !* ...! + %1; > !* 1: Count message, stop if done.! + q1"n 1:< m(m.m& Babyl Select Message) !* Select that one! + >"n 1m(m.m# Babyl J)' !* If can.! + :i*Now at top, no previous message f;Babyl-Command-Abort' !* ...! +  + +!# Babyl ^R:! !C# Enter a recursive edit level on current message.! + + [0[1[2 [3[4 !* Temp registers.! + fsVB[3 fsVZ[4 !* Save prev bounds.! + 1fsModeChangew 0f[^RMore  !* Let user edit.! + qMessage Number:\u0 !* 0: Add message number to resurvey! + :fo..qBabyl Modified Messagesu2 !* ...list.! + q:..q(%2)u1 !* ...! + :i:..q(q2)10M0 + !* ..! + fsVB-q3"E fsVZ-q4"E q3+q4"N  ''' !* If bounds still same and narrow,! + !* ..assume only selected message was! + !* ..edited.! + m(m.m& Initialize Babyl Buffer) !* Otherwise, reset number variables.! +  + +!# Babyl ^S:! !C# Survey-prefix. Also ignores ^S^Q for VT52 lossage etc. +^S^A or ^SA is M-X Survey All Messages +^S^D or ^SD is M-X Survey Deleted Messages + ^SUD is M-X Survey Undeleted Messages +^S^L or ^SL is M-X Survey Labeled Messages (reads a label) + ^SUL is M-X Survey Unlabeled Messages (reads a label) +^S^M or ^SM is M-X Survey Messages Containing String (reads a string) +^S^F of ^SF is --ditto-- +^S^R or ^SR is M-X Survey Reminders + ^SS is M-X Survey Seen Messages + ^SUS is M-X Survey Unseen Messages +^S? shows this description and then reads another character. +To correct for stupid terminals, any number of ^S's followed by a ^Q + are ignored. This is for VT52s, H19s, maybe others.! + [1 0[2 !* 2: 0 if have not prompted.! + 20:"e !* If no typing from user, prompt.! + 1u2 !* 2: Remember that we prompted.! + :i*CfsEchoDisplay !* Clear prompt area.! + @ftKind of survey (A,D,L,M,R,S,UD,UL,US, or ?): ' !* ...! + < 2,m.i fi:fcu1 !* 1: Dispatch character.! + q1-:@; > !* Exit when not a ^S, thus we! + !* ignore ^S^S...^S^Q.! + (q1-177."'e)(q1-"'e)"n ' !* Exit quietly, no-op, if it was a! + !* rubout or ^Q.! + q1-32"l q1@u1' !* 1: Turn ^A to A, etc.! + q2"n @ft1' !* Extend the prompt.! + fsRGETTY"e ft +' !* New line if printing tty.! + q1-A"e !* ^S^A or ^SA.! + f:m(m.mSurvey All Messages)' !* ...! + q1-D"e !* ^S^D or ^SD.! + f:m(m.mSurvey Deleted Messages)' !* ...! + q1-L"e !* ^S^L or ^SL.! + !* Note that we cannot :M, since we need to pass a string arg: ! + fm(m.mSurvey Labeled Messages) ' !* Null STRARG means it should! + !* use the reader to get! + !* label.! + (q1-M"'e)(q1-F"'e)"n !* ^S^M or ^SM or ^S^F or ^SF.! + f:m(m.mSurvey Messages Containing String)' !* ...! + q1-R"e !* ^S^R or ^SR.! + f:m(m.mSurvey Reminders)' !* ...! + q1-S"e !* ^SS (not ^S^S...)! + f:m(m.mSurvey Seen Messages)' !* ...! + q1-U"e !* ^S^U or ^SU. Another char follows.! + < q2"e 20:"e !* If no typing from user, prompt.! + 1u2 !* 2: Remember that we prompted.! + :i*CfsEchoDisplay !* Clear prompt area.! + @ft^SU (D,L,S): '' !* ...! + 2,m.i fi:fc@u1 !* 1: Uppercase char.! + q2"n @ft1' !* Extend the prompt.! + q1-D"e f:m(m.mSurvey Undeleted Messages)' !* ^SUD.! + q1-L"e f:m(m.mSurvey Unlabeled Messages)' !* ^SUL.! + q1-S"e f:m(m.mSurvey Unseen Messages)' !* ^SUS.! + 1u2 fg @ft +^SU (D,L,S):  >' !* 2: Help and repeat if illegal.! + q1-?"e m(m.mDescribe)# Babyl ^S !* ? gives help and then! + f:m(m.m# Babyl ^S)' !* reads another character.! + fg  !* Illegal choice. Complain noisily.! + +!# Babyl ^T:! !C# Call ^R Display Load Average, for TNX users.! + 1,m.m^R Display Load Average[1 !* 1: Function or 0.! + q1"n @m1' !* Do it if can.! + "# fsOSTeco"n !* Else do it ourselves, if can.! + 1:< fsLoadAvu1 !* 1: Load av string.! + :i*CfsEchoDisplayw !* Clear echo area.! + @ft(Load average = 1)  !* Type message.! + 0fsEchoActivew >w'' !* Keep it around.! +  + +!# Babyl ^]:! +!# Babyl ^X:! !C# Temporarily exit Babyl. Doesn't file out. +Exits to EMACS or DDT/EXEC, depending on how Babyl was called: + If was 1,M-X Babyl or a BABYL job then will exit back to DDT/EXEC. +Repeating the M-X Babyl command will resume with state unchanged.! + m(m.m& Declare Load-Time Defaults) + Babyl Standalone Job, Non0 means will exit to DDT/EXEC: 0 + + :i*CfsEchoDisplayw !* Clear echo area.! + qBabyl Standalone Job"e f;Babyl-Catch' !* Exit to EMACS.! + 100000.fsExitw  !* Exit to DDT. When job is! + !* continued, exit back to Babyl.! + +!# Babyl ^[ ~:! +!# Babyl :! !C# Execute a TECO command string.! + f@m(m.m^R Execute Minibuffer)w +  + +!# Babyl ^V ~:! +!# Babyl ^` ~:! +!# Babyl :! !C# Print more of this message. +On printing terminal: prints rest of message. +On display terminal: goes to next screenful. + n scrolls up n lines. + 9999 Space (or any semi-infinite numeric argument) goes to the + end of the message.! + + + fsRGETTY"n 1:w ' !* Display, scroll.! + !* The errset is so passing a very! + !* large numeric argument will just go! + !* to the end without erring.! + + ft + !* On printing tty, print! + ff"n .,(l).t !* As many lines as specified (maybe! + m(m.m& Babyl --MORE--)' !* then --MORE--).! + "# .,zt !* Or all the rest of the lines.! + zj -2f= +"n ft +'' !* Supply a CRLF at end if need it.! +  + +!# Babyl ^W:! !C# What is left of this message? Gives line/window count.! + +!* The bounds are set around the current message. To calculate how many lines! +!* are left, we take the top line, go down size-of-window lines, and start! +!* counting from there.! + +m(m.m& Declare Load-Time Defaults) + Next Screen Context Lines,:1 + + [0[1[2[3[4 + .u0 fnq0j !* 0: Auto-restoring point.! + fsLinesf"ew !* If 0, have just one window.! + fsHeight-(fsEchoLines)-1( !* One window. -1 ignores mode line.! + )'u1 !* 1: Window size.! + fsWindow+bj !* To top of window.! + q0m(m.m& Count Screen Lines)+1u2 !* 2: Count, and include this line.! + !* @ftWindow size= q1@:= @ft Message lines= q2@:=! + :i*CfsEchoDisplayw !* Clear echo area.! + (q2-1)/q1u4 !* 4: how many screens left.! + q4"e @ftBottom of message. 0fsEchoActivew ' !* None.! + q2-q1u2 !* 2: lines not seen already.! + (q2-1)/(q1-qNext Screen Context Lines)+1u4 !* 4: How many screens,! + !* correcting for overlap.! + q2@:= @ft Line q2-1"g @fts' + @ft left in message  @ft( q4@:= @ft screen + q4-1"g @fts' @ft).  + 0fsEchoActivew !* Keep printout there.! +  + +!& Count Screen Lines:! !S Count number of physical screen lines from point. +Postcomma arg gives point to go back to. +Precomma arg means go backwards.! +0[0 !* count of lines! +[1 !* point to preserve! + @fn|q1j| !* point to return to when we exit! + ff&2"e !* given precomma arg?! +!* @ft Counting forwards! + < 1:<1,0:fm>"n 0;' !* go down one screen line! + %0 !* count it! + > + z-."e q0-1u0 ' !* EOB? not really another line! + '"# +!* @ft Counting backwards! + < 1:<-1,0@:fm>"n 0;' !* go up a screen line! + %0 !* count it! + > + ' + q1j !* back to where we belong! + fn !* now safe to clear this! + 0fsechoactive + q0 !* return our count! + +!# Babyl ':! !C# Into recursive edit level on survey. +No arguments means use the last survey. If no last survey, + we call . +M,N arguments means survey messages M through N. +N argument means survey next N messages. +-' is like ^S' but does not print while + surveying. (Except for a "Done" which is unavoidable without + serious work.) +For more details, see documentation for M-X Survey Menu.! +!* +This is a separate function from Survey Menu to work better with the EMACS +documentation facilities. +! + + m(m.m& Declare Load-Time Defaults) + Survey Quietly,:0 + + + "l 2[Survey Quietly !* Force quiet survey.! + @m(m.m# Babyl ^S)' !* Do a survey.! + "# f':m(m.mSurvey Menu) !* Pass arguments if not -1.! + +!# Babyl .:! !C# Return the message number of current message. +To reposition at top of current message, do .J! + qMessage Number:\[1 !* 1: no. as a string! + :i551 0 !* append to Q5, return something to! + !* say we have set Q5! + + +!# Babyl ;:! !C# Accumulate a line, then execute it with no display.! + m(m.m& Declare Load-Time Defaults) + Babyl Shh Text,: || + + !* Can sometime try to have more than one line accumulated...! + [..J :I..JBabyl-Shhh + m(m.m& Read Line);uBabyl Shh Text !* Save the text.! + m.m& Babyl TYI SourcefsTYISourcew !* Now FIs will read from this text.! +  + +!& Babyl TYI Source:! !S Uses ;-generated text, sets fsReread.! + m(m.m& Declare Load-Time Defaults) + Babyl Shh Text,: || + + qBabyl Shh Text[3 + fq3:"g 0fsTYISourcew 0' !* Done shh-rereading.! + 0:g3fsReReadw !* Next FI gets this char.! + 1,fq3:g3uBabyl Shh Text !* Remove that char.! + 0 + +!# Babyl =:! !C# Type value of numeric argument.! + =  + +!# Babyl 0 ~:! +!# Babyl 1 ~:! +!# Babyl 2 ~:! +!# Babyl 3 ~:! +!# Babyl 4 ~:! +!# Babyl 5 ~:! +!# Babyl 6 ~:! +!# Babyl 7 ~:! +!# Babyl 8 ~:! +!# Babyl 9 ~:! +!# Babyl + ~:! +!# Babyl - ~:! +!# Babyl , ~:! +!# Babyl * ~:! +!# Babyl / ~:! +!# Babyl ) ~:! +!# Babyl ( ~:! +!# Babyl , , +, -, *, /, (, and ):! +!# Argument Part:! !C# Part of a Babyl numeric argument.! +!* The extra, final name there will cause Describe to use a reasonable name --! +!* without it, you can ask to have 5 described and be confused when it uses! +!* the name # Babyl (. It must be first alphabetically.! + + :i550 0 + +!# Babyl A:! !C# Move to next message and summarize it. +Given an argument, moves forward that many undeleted messages, and + summarizes the intervening messages as well as the last one. +If the option variable Babyl A Mode Display is non-0, we will update + the mode line. (Default is to update it.) +Users on slow display terminals may want to disable updating, and use + an occasional Z= instead, to see how many messages there are.! + + m(m.m& Declare Load-Time Defaults) + Babyl A Mode Display, * Non-0 lets A update mode line: 1 + + !* End of declare.! + + qMessage Number[1[2 !* 1: Message# originally at.! + m(m.m# Babyl N) !* To next (nth) message.! + qMessage Numberu2 !* 2: Message# going to.! + qBabyl A Mode Display"n !* Update mode line if enabled.! + 1fsModeChw fr' !* Display mode line since B will! + !* inhibit it.! + m(m.m& Push Message) !* Will come back here when done.! + !* ***Change this for new scheme -- simpler.! + q1+1m(m.m# Babyl J) !* To original+1 message.! + q2-q1m(m.m& Babyl Survey Several Messages) !* Survey intervening msgs.! + !* This includes last one but not the! + !* original message.! +  + +!& Babyl Survey Several Messages:! !S survey next NUMARG2 msgs. +NUMARG1 has bits: +1, dont 1st empty survey buffer. +2, dont print as go. ORed with Survey Quietly. +0 NUMARG just makes a label.! +!* Leaves its summary in EMACS buffer *Survey*.! +!* Bits are used by higher level surveyor. E.g. dont-empty allows appending! +!* of several different surveys. Dont-print allows computing the survey, in! +!* *Survey*, without having to watch it. Good, e.g., for survey menu.! + + m(m.m& Declare Load-Time Defaults) + Survey Quietly,:0 + *Survey* Buffer,:0 + + [1[7[8[9 qSurvey Quietly[2 !* 2: 0 iff should print as go.! + qBabyl ..D[..d !* ..D: Be sure to use Babyl syntax,! + !* ignore any strange ..D user may have.! + .u7 @fn|0,fsZfsBoundw q7:j"e zj' m(m.m& Babyl Select Message)| [7[..o + !* Auto-restoring point.! + 0fsVBw -s  l .fsVBw !* Put top at status line.! + + -1f[Truncate !* do not continue, just excl overflow! + q..ou9 !* 9: mail buffer.! + q*Survey* Bufferu8 !* 8: 0 or summary buffer.! + q8fp"n !* If not a buffer, must create.! + [Previous Buffer !* Save default for ^XB.! + m(m.mSelect Buffer)*Survey* !* Create/select summary buffer.! + q..ou*Survey* Buffer !* Save buffer for quick access.! + q..ou8 !* 8: Summary buffer.! + m(m.mSelect Buffer)' !* Back to Babyl buffer. *! + q8u..o !* Select survey buffer.! + q2&1"e hk :iBabyl Modified Messages' !* Empty it if no 1, bit.! + !* This means none to resurvey.! + + q9u..o !* select mail buffer! + fsZ-z"e :i*C fsEchoDisplayw @ftNo Messages + 0fsEchoActivew q8u..o 0fsXModifiedw 0fsModifiedw ' + + qMessage Numberu7 !* 7: message no.! + m.m& Get Labels for Survey !* K: ditto.! + m.m& Babyl Survey One Message !* X: survey one message! + + ff&1"e 1'"# q8u..o i No. Lines From->To Subject or Text + q2&2"e -t' !* Label if NUMARG given. Type it! + !* if no 2, bit.! + + '< !* Iterate NUMARG or 1 times.! + q2&2"e fsListen"n :fi-32"n 1;''' !* Quit if non-Space typeahead. This! + !* includes stopping for Rubout,! + !* unlike using & Maybe Flush Output.! + !* More appropriate for surveys,! + !* unlike for --MORE--s.! + + q9u..o j !* To message buffer.! + s +*** EOOH *** + 2r .fsVBw !* Set bounds past original header.! + + q8u..o 3,q7\ !* Put in message #.! + + q9,q8mX !* survey message! + + q2&2"e -t' !* and display our handiwork if no! + !* 2, bit.! + !DEL! !* Come here to skip delete message.! + q9u..o zj !* Prepare to move to next message.! + 0,(fsZ)fsBoundw !* Widen bounds.! + 4f= +:@; !* Stop if no next message.! + %7w !* Else bump our temporary message no.! + l .,(sr). fsBoundw !* Bounds around next message.! + > + + q2&2"e !* if no 2, bit say we are done! + fsListen"n :fi-32"n ftFlushed. + 1fsFlushedw'' !* Be sure others stop, even if they! + !* use the standard & Maybe Flush! + !* Output which wouldnt otherwise stop! + !* if user types Rubout..! + "# -1"g ftDone. + ''' !* Say done if could have done more! + !* than one message.! + q8u..o 0fsXModifiedw 0fsModifiedw !* Unmodify summary buffer.! +  + +!& Babyl Survey One Message:! !S msgBuf,surveyBuf NUMARGs. +MsgBuf bound so starts with CRLF.! +!* CRLF start is for easier searching for header field names.! + + m(m.m& Declare Load-Time Defaults) + Babyl Survey FROM/TO Control, + * Bits, 1 = enable prettification, 2 = shorten hosts, 4 = no hosts + Can also be a macro, which is given message, survey buffers as args. + Q1 gives point where from-to field starts in survey. It can update + that, e.g. if it wants to put something before the from-to area. + It should return number (bits as above).: 3 + + [0[1[2[3[4[5 [7 + u..o !* Select message buffer.! + mku7u0 !* 7: User label list string.! + !* 0: Status character.! + -u1 <.-z;%1wl> !* 1: no. of lines in the message! + !* Note the -1 init since CRLF at top.! + u..o q0i 5,q1\ !* Insert status character, # lines.! + + 0u0 0u3 0u4 0u5 !* 0,3,4,5: initially no 1st lines,! + !* From:s, To:s, or Subject:s! + + u..o jl !* beginning of 1st line of message! + 4f=MSG:"e l !* Skip over MSG: line if system msg! + < 8f~DISTRIB:@:; !* DISTRIB: ?! + 8c @f l 1:x4 l > !* treat DISTRIB: like To: ! + < 8f~EXPIRES:@:; l > !* skip over EXPIRES: lines! + ' !* End of MSG:-handling! + 1:fb@:f"ew u..o i ??? !* Cant grok header. Truncate survey.! + oCGM' +1"e !* ITS header! + :s "e u..o i ??? !* Cant grok header. Truncate survey.! + oCGM' r 0x3 !* 3: ITS From.! + :fb Re: "l 1:x5' !* 5: subject! + l 4f~TO: "e 4c 1:x4 l' !* 4: To: line! + < 4f~TO: @:; l> !* skip over To lines! + < 4f~CC: @:; l> !* skip over cc lines! + 0l .u0 !* 0: Point of first line.! + ' !* end of ITS header conditional! + "# !* Network header! + :s + +"l 2r .u0 !* 0: Point of first line! + !* (before actually).! + '"# zj' fsz-.f[vz !* set bounds around header! + j < :s +From; @f l 1a-:"n !' !* find a From: line! + c @f l 1:x3 1; !* 3: the From field.! + > + j < :s +To; @f l 1a-:"n !' !* find a To: line! + c @f l 1:x4 1; !* 4: the To field.! + > + j < :s +Subject +Re; @f l 1a-:"n !' !* find a Subject: line! + c @f l 1:x5 1; !* 5: the subject field.! + > + f]vz !* restore bounds to whole message! + ' !* end of header conditional! + u..o i  .u1 q3"n g3' ! q4"n g4' !* < put in from->to! + + + !* Now we process the FROM and TO a little to prettify it if bit-1 of the! + !* control option is set. If from/to is a hook, it can reset q1 which! + !* specifies where from-to part starts.! + + qBabyl Survey FROM/TO Control[9 !* 9: Control bits. This should be! + !* set by & Babyl Survey Several! + !* Messages actually.! + + fq9"g ,m9+0u9' !* 9: If control is a macro, call it,! + !* and let it process first, then! + !* return to us the control bits.! + q9&1"n !* Prettification is enabled.! + + !* First process ITS structured names of BUG form and comments. By! + !* processing comments first, they wont confuse later stuff -- e.g.! + !* there can be commas in the comments.! + + q1j 0s(BUG !)! <:s; BUG- ful -d > !* Change (BUG FOO) to BUG-FOO.! + q1j < @:f(l!)! .-z; 1:"n:k' -@f k > !* Delete other! + !* comments.! + + !* Find any RFC733 names (e.g. Foo Fah ) and just keep! + !* the stuff inside the angle brackets -- the real username -- since it! + !* is probably briefer.! + + q1j <[5 >[6 !* setup for loop! + < @f,-6l .u2 !* 2: Point where next fields name! + !* starts.! + @:f,65l .-z; !* To /\<....> or end of field. (The! + !* close bracket is there to catch! + !* arrows.)! + 1a-q5"e !* We are at /\<....>.! + q2,.kd !* Kill name before <....> and kill the open! + !* bracket.! + @:f6l .-z; !* To <...../\>.! + d' !* Delete the close bracket. We are! + > !* now at the end of the field.! + !* (Usually -- if not, the next! + !* iteration will move us there.)! + + q1j 0s,  < :s; -d > !* Compress a bit.! + + q9&4"n !* Show no host names at all.! + q1j 0s at @ <:s; fkc @:f,6f(l0,1a-q6"e-1')k>' !* ...! + "# q9&2"n !* Show no local host names and! + !* shorten some others..! + q1j 0s at  < :s; @ > !* Canonicalize at to @.! + q1j 0s@MIT-Multics < :s; @MUL > !* shorten MIT-Multics! + q1j 0s@MIT- <:s; -4d > !* abbreviate MIT host names! + fsOSTeco"e q1j 0s@AI@MC@ML@DMS@DM <:s; fkd >' + !* Dont show ITSs if on one.! + "# q1j fsMachine:f6[2 0s@2 <:s; fkd > ]2' + !* Dont show own machine else.! + q1j 0s@SU-AI <:s; @SAIL > !* dont confuse SU-AI with MIT-AI.! + q1j 0s@SU- <:s; -3d> !* Shorten other Stanford sites.! + q1j 0s@USC-ISI <:s; -3c-4d > !* abbreviate ISI host names! + q1j 0s@CMU-10 <:s; -3D > !* abbreviate CMU host names.! + '' !* End of host shortening.! + + fsXUname:f6u2 zj i  !* Delete self.! + q1j fq2+2f~2->"e fq2d' !* Special case for if we sent it! + !* (because dash isn't a delimiter).! + < r :s2; r -fq2d !* Zap our user name.! + 1a-@"E <@:f,- k 1a--@:; q6,2a-q6@; d>'> !* Self at non-local! + !* ..host: zap host.! + ]6]5 !* Clean up. Hmm... ugh.! + ' !* End of prettification.! + + + !* Now work on the subject area: labels, subject, and/or 1st text line.! + + zj -d 33-(fsHPos)f"l d'"# ,32i' !* Subject/labels start at column 34.! + i 7 !* Insert user label list string. It! + !* ends with a space if non-null.! + q5"e q0"n !* If no subject but have 1st line,! + u..o 0fsZw q0j !* go to Babyl buffer and 1st! + !* text line.! + !* Errset is so FW doesnt bomb if text is not really text: ! + :<@f + l .-z; !* Past any whitespace.! + fw+1af@:-:; :l > !* Ignore line if 1st word! + !* ends in : - or @. (- there! + !* for things like mail-from.)! + .-z"e q0j @f + l' !* If heuristic obviously! + !* failed, dont use it.! + :x5 !* 5: And use 1st line instead of! + !* ..subject.! + u..o'' !* Back to brief buffer.! + + q5"n g5' !* Insert subject/1stLine.! + + 0fsHPosition-(fsWidth-2)f"g,0d i!'w !* Truncate the line.! + + + !CGM! !* come here if cannot grok message! + u..o i + !* end summary of this message! + +  + +!& Babyl Resurvey One Message:! !S Updates survey line. +Updates status char, length, labels, subject. +NUMARG is msg #. Buffer should be survey buf. This will be a +no-op if survey line not found. +Caller should bind: + K: & Get Labels for Survey + B: Babyl buffer + S: survey buffer + J: # Babyl J! + + .[0[1[2[3[4[5 !* 0: old survey line point.! + 3,:\u1 j:s +1"e q0j ' !* If not find message, quit.! + + qB[..o mJ !* To babyl buffer, message.! + 0fsVBw -s  l .fsVBw !* Rebound to include original header! + !* and status line.! + mku2u1 !* 1,2: Status character, labels.! + s +*** EOOH *** + !* At reformed header.! + .(0u3 <.-z;%3wl>)j !* 3: # lines in message.! + + !* Both ITS- and network-header messages may start with MSG: fields: ! + + 4f=MSG:"e l !* Skip over MSG: line if system msg! + < 8f~DISTRIB:@:; l > !* Skip over DISTRIB: lines.! + < 8f~EXPIRES:@:; l >' !* Skip over EXPIRES: lines.! + + !* Both clauses, for ITS and network header, will set q4 to the subject line! + !* or 0 if not found, and set q5 to the point where the 1st text line is.! + 0u4 !* 4: No subject yet.! + 1:fb@:f"ew  !* Quit if cant grok header.! + '+1"e !* ITS header.! + :fb Re: "l 1:x4' l !* 4: subject.! + < 4f~TO: @:; l> !* Skip over To lines.! + < 4f~CC: @:; l> !* Skip over cc lines.! + 0l .u5 !* 5: Start of 1st text line.! + ' !* end of ITS header conditional! + "# !* Network header.! + :s + +"e zj' .u5 !* 5: Start of 1st text line.! + < -:s +Subject +Re; !* Back to possible subject field.! + fkc @f l 1a-:"n 0l !' !* Make sure it is a real one.! + c @f l :x4 1; > !* 4: the subject field.! + ' !* End of header conditional.! + + !* If we have no real subject line, we will use the first text line. But we! + !* try a heuristic to get a good 1st text line, skipping ones that appear to! + !* be embedded header lines, e.g. if the message starts out with a yanked! + !* message: ! + + q4"e q5j !* No subject -- go to text.! + < @f + l .-z; !* Past any whitespace to next line.! + fw+1af@:-:; :l > !* Ignore line if 1st word ends in : -! + !* or @. (- there for things like! + !* mail-from.)! + .-z"e q5j @f + l' !* If heuristic obviously failed, dont! + !* use it.! + :x4' !* 4: Now subject or 1st line.! + + !* Now we have all the necessary stuff from the message: ! + !* 1: status character, 2: null or {label list}, 3: # lines, 4: subject! + !* or 1st text line.! + !* We will check new status character, line count, and labels+subject against! + !* the old and carefully tell Teco what changed, so that redisplay will not! + !* have to retype the entire line.! + + qSu..o 0l !* Back to survey buffer.! + 4c 0a-q1"n -d q1i -1f' !* Maybe reset the status character.! + @f l \-q3"n -5d 5,q3\ -5f' !* Maybe reset line count.! + 0,34:fm !* Move to column 34, where the! + !* labels+subject should be.! + !* Will compare label+subject together since usually have to move! + !* subject over by retyping if labels change anyway.! + :fx1 !* 1: Old labels+subject/text.! + .( g2 g4 !* Get labels and subject/text.! + 0fsHPosition-(fsWidth-2)f"g,0d i!'w !* Truncate the line.! + )j !* Back to start of labels.! + :ff=1f"nf"l*(-1)'cr :ff'w !* Tell Teco of any changes in labels! + !* + subject/text. Range starts at! + !* difference and goes to end of line.! +  + +!# Babyl D:! !C# S Delete this message, maybe select next. +Given numeric argument, n, means delete message n. +The option variable Babyl N After D controls whether Babyl + automatically moves to another undeleted message after deleting + this one. Values are: + 1: Try to do an automatic N -- move forward if can (default). + -1: Try an N (go forward), but if no next message, try a P (go + backward) instead. + 0: No movement. You view the deleted message. +qSubDoc"n i +Pre-comma NUMARG is amount to N after this, e.g. -1 for the ^D + command.'! + + m(m.m& Declare Load-Time Defaults) + Babyl N After D, + * 1 means N after a D, -1 means N or P, 0 means no movement: 1 + !* End of declare.! + + ff&1"n m(m.m# Babyl J)' !* Go to message NUMARG.! + m(m.m& Add Basic Label)deleted"n @ft +(Already deleted.)  !* Department of Redundancy Department! + 0fsEchoActivew' !* ...! + ff&1"n fsTypeout"g 1u..h'' !* Dont mess up possible brief.! + 1fw + qBabyl N After D"l 1m(m.m# Babyl P)' !* Maybe P if cannot N.! +  + +!# Babyl E:! !C# Expunge deleted messages. Handles empty file. +If expunging leaves the file with no messages, a dummy message is + inserted, since many Babyl commands don't work without some + message in the file.! + + m(m.m& Babyl Expunge) !* Expunge deleted messages.! + 1m(m.m& Initialize Babyl Buffer) !* Reset things, though not message#s! + !* since those are ok.! + !* The initialize selected the current message. Or if expunging left none,! + !* it created a dummy message and selected that.! + +  + +!# Babyl F:! !C# Forward current message. You can edit the message. +The mail will be set up to include the current message and a subject + based on the original one if any. You can then edit any of this + before sending it off. Describe Edit and Mail Buffer for details. +If you give a numeric argument of 2 we will try to use 2 windows, with + the current message in the top and the message being sent in the + bottom one. +If you give a numeric argument of 3 we will REMAIL the message instead + of forwarding it. The variable Babyl Remail Control controls the + action of 1F: 0 (read TO: and send); non0 (read TO: then edit and + send). Babyl Remail Hook should be a TECO macro to run after message + is set up. (Sorry. No 2 window mode yet...someday, 4F will do this.) +The option variable Babyl F Control controls the default action of F: + 0: You are put in a recursive edit level on the outgoing + message, which has an empty To: field (point is there), a + subject based on the original one, and the forwarded + message yanked into the text field. You can thus edit any + field and add comments. On terminals with insert/delete + line capability, we try to optimize redisplay. + 1: The To: and Subject: are read in the echo area, and you + are then put in a recursive edit level on the outgoing + message, with the header above the screen window, i.e. + with only the text field showing. (This may be desirable + for users with slow terminals without insert/delete line + capability, or for users with printing terminals.) Typing + Rubout to the subject prompt makes the message not have + any subject; typing Return makes the default subject be + used. + 2: Reads the To: and Subject: in the echo area, and then + mails the message, without entering a recursive edit + level. +1F or 2F will force the general default action -- i.e. as if Babyl F + Control were 0. (1F uses one window.) +After the message template is set up, runs any Teco program you + provide in the variable Babyl F Hook. +When successfully exited (not aborted) it will run any Teco program + you provide in the variable Babyl F Done Hook, passing it F's + arguments.! + + m(m.m& Declare Load-Time Defaults) + From:,,:0 + Subject:,:0 + Babyl Reply-To Field, * Automatic Reply-To field in mail if non-0: 0 + Babyl F Done Hook, 0 or a Teco program to run after F successfully exits: 0 + Babyl F Hook, 0 or a Teco program to run after F sets up its template: 0 + Babyl F Control, + * 0 (general edit), 1 (read To/Re then edit), 2 (read To/Re and send): 0 + Babyl Remail Control, + * 0 (read To field and send), non0 (read To then edit): 0 + Babyl Remail Hook, 0 or Teco program to run after message set up: 0 + Babyl Header/Text Separator, + * 1 line that separates header and text in recursive mail edit: + |--Text follows this line--| + + fsQPPtr[.0 [0[1[2[3[4[5[6[7[8[9 !* .0: Top level unwind point.! + !* If called as a subroutine, by M (not @M), then pick up To and Subject.! + !* Note that caller must provide both unconditionally.! + :f "g :i*( :i7 )u5' !* 5,7: To,Subj if M-called.! + -3u6 !* 6: controls whether doing remail.! + ff&1"n 0'"# qBabyl F Control'u2 !* 2: Controls reading,  entering.! + :i*To continue editing this message use the C command.( + )[Abort Resumption Message !* For Abort Recursive Edit.! + + .(1m(m.m& Parse Header)w)j !* Parse message, setting variables.! + !* Leave point where it was. The 1! + !* means we are parsing a numbered! + !* message.! + + fsQPPtru9 !* 9: Unwind to here to reselect back! + !* to message buffer.! + + -2"'e,1m(m.m& Push To Edit Mail) !* Use 2 windows if NUMARG=2 and reset! + !* buffer mode and filenames.! + fsModified"n !* Aborting leaves *Mail* modified .! + ft +Last message being composed seems to have been aborted. +Continue editing aborted message?  + m(m.m& Yes or No)"n q.0fsQPUnwindw !* Yes, so pop buffer etc. and! + f@:m(m.m# Babyl C)'' !* become a C command.! + + q6"e !* doing remail? ! + hk + 0fsWindoww + 1,4@m(m.m^R Babyl Yank)w + j :s + +"e zj' + .,z x3 !* 3: save msg text! + .,zk !* and leave header here! + j i + !* comment out some fields! + 0s +To: +Cc: +Fcc: !* Set search default just once.! + j <:s; 0l iOrig-> !* Comment out some fields.! + fsOSTeco"e 0s +Sender: +Date: !* For ITS, COMSAT will put in some! + !* things anyway,! + j <:s; 0l iOrig->' !* so comment original ones.! + + fsXUname:f6u6 + fsMachine:f6u8 + :i*6@8u8 !* default Sender! + + zj -@f + k + i + + fsOSTeco"n iReSent-From:  g8 i +' !* Not on ITS -- COMSAT puts on sender! + q5u8 :f "l 1,m(m.m& Read Line)Remail to: f"ew 'u8' !* 8: To! + iReSent-To:  g8 i + !* Unfortunately redun with TO on ITS,! + !* since COMSAT doesnt strip the BCC.! + !* But this emphasizes the remailing.! + fsOSTeco"n iReSent-Date:  212221000000.,fsDatefsFDConvertw i +' !* Just on TNX. On ITS, COMSAT will! + !* put in a DATE field.! + iBcc:  g8 i + !* On ITS, this will show as TO, a! + !* COMSAT bug of sorts.! + qFrom:u8 q8"e :i8Unknown? +' + fsOSTeco"n j :s +Sender:"e jl iSender:  g8'' !* On ITS, best not to bother?! + j @f + k !* Kill blank line at top.! + zj + gBabyl Header/Text Separator i + g3 + + qBabyl Remail Hookf"nu8 m8'w !* run hook if any.! + qBabyl Remail Control"n !* if wants edit, then! +  'w !* let user see it first! + fsOSTeco"e m(m.m& ITS Mail Buffer)' !* Just mail, without any! + "# m(m.m& TNX Mail Buffer)' !* editing.! + 0fsModifiedw 0fsXModifiedw !* mark success! +'"# !* begin FORWARD code! + !* Now set up the message template for editing. We will keep the same! + !* subject if any or make one.! + + !* Set up To: field: ! + hk iTo:  .u3 !* 3: Point we may restore later.! + 0fsWindoww !* Dont use any previous one.! + q2"g q5u1 :f "l 1,m(m.m& Read Line)To: f"ew 'u1' g1' + !* 1: Maybe read TO.! + i + !* End TO field.! + + !* No use of Babyl CC To or Babyl Fcc To, since forwarding is a different! + !* idea, isnt outgoing message of this person, and since this user already! + !* has a copy of the message, so use of cc-to for that reason doesnt help.! + !* Hmm... strictly not true? -- e.g. if forward has a comment by this! + !* user? But, user can always add a CC if wants to.! + + qBabyl Reply-To Fieldf"nu1 iReply-to:  g1 i + 'w !* Maybe insert Reply-to field.! + + !* Set up Re: (subject) field: ! + qFrom:u1 fq1"g !* There is a From to use.! + iRe: 1 !* Insert it for parsing.! + :i1??? !* 1: Uname, in case parse fails.! + fsQPPtr( fsBConsu4 @fn|q4fsBKill| !* 4: Temporary for parse.! + 1:< :i*,q4m(m.m& Process Recipient Field)Re !* Parse.! + q4[..o j @:f@x1 >w !* 1: Username part of from.! + )fsQPUnwindw !* Back to message.! + 0lk i[1: ' !* End of username part.! + "# i[???: ' !* Unknown from.! + qSubject:u1 fq1"g .(g1)j :l .,zk i]' !* Append original subject if! + !* one. But only 1 line.! + "# iforwarded]' !* Or make up something.! + 0fx1 !* 1: The default subject, removed.! + q2"g q7u4 :f "l 1,m(m.m& Read Line)Re: (1): u4' !* 4: Subject.! + fq4"n q4u1'' !* 1: 0 or subject line.! + fq1"g iRe: 1 + ' !* Done subject field.! + + gBabyl Header/Text Separator i + q2"g .u3' !* 3: Point we may restore.! + + j 0u1 < .-z; %1w l > !* 1: number of lines being added.! + .fsWindoww !* This makes the @:f work.! + .( 1,4@m(m.m^R Babyl Yank)w !* Yank message to forward, without! + !* indenting it, and keep 2 windows if! + !* have them.! + )j q2"e q1@:f' !* Scroll down, if possible, by number! + !* of lines added. Only if showing! + !* new header.! + x1 !* 1: 1st line of yanked message.! + + q3j !* Put point in TO or at top of text.! + + qBabyl F Hookf"nu0 fm0'w !* Run F hook if any.! + + q2-2"l m(m.mEdit and Mail Buffer)' !* Let user edit the mail and then! + !* mail it off.! + "# fsOSTeco"e m(m.m& ITS Mail Buffer)' !* Just mail, without any! + "# m(m.m& TNX Mail Buffer)'' !* editing.! + j :s +1"l fkc l .u1 0u0 j !* 0,1: VPos,. for 1st message line.! + !* If can, scroll the yanked message back up to top screen line to! + !* optimize probably redisplay when go back to Babyl message! + !* display: ! + fsTopLine+q0fs^RVPosw q1j q2"e 0@:f'' +' !* end of remail conditional! + q9fsQPUnwindw !* Back to Babyl buffer for done hook.! + qBabyl F Done Hookf"nu1 m1'w !* Run any done hook.! +  + +!# Babyl G:! !C# Get any new mail received since Babyl was started. +1G means get mail from another mail file. You will be asked for its + filename. Any kind of mail file can be read in (it figures out + which kind it is): ITS or TNX mail file, an RMail file, or + another Babyl file. The file will NOT be deleted -- you must do + this manually, if desired. +The Append option (at the top of the Babyl file) determines where the + new messages are put in the Babyl file and in what order: + 0: prepend messages to beginning of Babyl file + 1: append messages to end + 2: prepend and reverse order of new messages + 3: append and reverse + Reversal is only done for the primary mail file, for the owner. +When G is done, it will run any Teco code in the variable Babyl G Done + Hook. Argument is 0 if no new mail, or the number of the last new + message. +qSubDoc"n i +Pre-comma NUMARG of 1 means not a manual G -- called by I.'! + + m(m.m& Declare Load-Time Defaults) + Babyl G Done Hook, + User hook, run (if non0) after new mail is collected; + argument is 0 or message# for last new message: 0 + + + [1[2[3[4[5[6[7[8 f[DFile !* save! + "e .'"# -1'u7 fsWindowu8 !* 7,8: Original point, window, so! + !* manual G stays if no new mail. Or! + !* -1 if auto-G, meaning not to! + !* restore point.! + qBuffer Filenamesu3 !* Q3: buffer filenames! + qBabyl Mail Optionu2 !* 2: 0 (or n...), filename, or list.! + q2fp"g 0,(,f2f"lw fq2'):g2u2'"# 0u2' !* 2: 0 or filename.! + !* For now, ignore others in list.! + ff&1"e !* No argument, use mail option.! + q2"e m(m.m& Initialize Babyl Buffer)w ' !* Return if no mail option.! + !* Just initialize, no G done hook.! + et2 fsDFileu2 !* 2: full mail filename. Directory! + ' !* now defaults to one with mail file.! + "# q2"n et2' !* Default to current mail file.! + 4m(m.m& Read Filename)Mail filef"ew'u2 !* 2: Filename.! + et2 fsDFileu2 !* 2: Full mail filename.! + 0u3' !* Make this a non-destructive read.! + + !* Note that when done, just before the following cleanup, buffer bounds will! + !* be wide (B=0) iff we got NO new mail. If we did get new mail, the bounds! + !* are set around that new mail. (Even if all messages are new, the BABYL! + !* OPTIONS section will still be out of bounds, and thus B~=0). & Initialize! + !* Babyl Buffer will return the number of the last new message, which will be! + !* the total number (appending mail) or the number of new messages! + !* (prepending mail). The multiplication by B (0) or 1 translates this into! + !* 0 or that value. Because the bounds are wide or around new mail, the q7:j! + !* should restore point only if no new mail.! + + @fn| q7:ju3 !* 3: -1 if able to restore point.! + bf"nw1'*(m(m.m& Initialize Babyl Buffer))u1 !* 1: 0 or last #.! + !* Note that a select just happend, putting point at the top of the! + !* message. So if our q7:j worked but was not at message top, we need! + !* to redo it: (the :J in case original point was meaningless, e.g. in! + !* Babyl Options).! + q3"l q7:j"l q8fsWindoww'' !* Restore point and window.! + qBabyl G Done Hookf"nu2 q1m2'w | !* Run Babyl G Done Hook.! + + !REDO-G! !* Comes here for second round if! + !* picking up mail from crash.! + + !* ***AFTER HERE DO NOT SMASH Q2 or Q3 -- they need to be the original values! + !* when we come back for the second round.! + + + 0,fsZfsBoundw !* widen bounds! + + !* Possible errors should come after user types 1G string arg so user will be! + !* able to type ? to error if it happens: ! + qBabyl Append Option&1"n zj !* Append. Will trim final whitespace! + !* just in case user put it there.! + !* This trimming stuff perhaps should go into just the Babylizer, and then! + !* have & Read Babyl file call the babylizer even if the file is a Babyl! + !* file -- it should do all the validity checking/trimming. --ECC! + -@f +  :d !* Trim any whitespace and ^L at end,! + !* since ZMail might put them there.! + !* Avoid K since .,.K modifies! + !* buffer.! + 0a-"n :i*Babyl bug: no ^_ at end of filefsErr !* Warn... ! + i'' !* Put it in if continued ! + "# j s' !* Prepend.! + + !* Note that we do Babylization in the Babyl file, instead of in a temporary! + !* buffer. Thus we save space (fewer URKS for large files), but we have to! + !* worry about errors leaving a Babyl file with part of it not yet Babylized! + !* or partially version converted. So, we set up a ..N to do an HK and! + !* when we know it is ok, 0u..N.! + + q3"e !* If perusing, just read in mail.! + !* This is true for 1G, or just! + !* reading some Babyl file without! + !* wriing back allowed.! + .,.fsBoundw fn hk  !* ..N: Discard unless know is ok.! + 1:< 1,er @y >w !* Read in file.! + 0u6 !* 6: Will figure type of mail file.! + :f~BABYL OPTIONS:"e 1u6 !* 6: This is a Babyl file.! + 1,m(m.mConvert Babyl File Version)w !* Convert if need.! + j :s b,.k' !* Discard BABYL OPTIONS section.! + "# :f~*APPEND*"e 2u6 k' !* 6: RMail file, chop off top.! + !* Try to figure out if this is an ITS or TNX mail (or RMail, without! + !* an *APPEND*) file: ! + "# !* Not Babyl or appending RMail file.! + zj -@f + l !* To end. Backup over whitespace.! + 0,0a-"e !* Ends with a ^_, so likely ITS...! + j:l -@f0123456789l !* To first line, end, back over! + !* digits. Maybe should just be 01?! + 0,0a-;"n 2u6'''' !* Not ;nn...nn, so IS an ITS file.! + j q6-1"e 14.,1a-14."n :i*Babyl bug: should be ^L herefsErrw'' + "# q6m(m.m& Babylize Buffer)' !* If not Babyl file convert.! + 0u..n !* ..N: Buffer is now consistent.! + j ' !* Dont append or delete.! + + fsXUName:f6u1 !* 1: Username.! + + !* First check if there is no previous temporary file from a crashed Babyl,! + !* and if there is, we will skip the rename-mail-to[BABYL for the moment and! + !* use the existing [BABYL file. But we will set a flag to remind us to redo! + !* G later. It seems to be hard to have this crash mail combined with the! + !* real new stuff for the G Done Hook, but we print a message, so it may not! + !* really matter much -- rare.! + + 0u4 !* 4: Will redo G if becomes 1.! + e?[BABYL 1"e fsDFileu1 !* 1: Full temporary filename.! + ftThere is some mail from a previous Babyl crash. +It is being read in, and will be  !* Warning.! + qBabyl Append Option&1"e ftafter'"# ftbefore' !* ! + ft your new mail if any. +It is possible that it does not belong to this particular Babyl file. +(If you only have one Babyl file then it will belong. Otherwise you may want +to sort the messages out, using the O command to write them to other files.) + + 1u4' !* 4: Redo G later.! + "# !* No [BABYL file already.! + q2fsDFilew !* Default is mail filename.! + e?"n !* New mail not found.! + q4"e @ft(No new mail) 0fsEchoActivew' ' !* Do tell.! + fsOSTeco"n :'1< er ec !* open/close to set read date! + enABYL 1 !* Rename for safety.! + >+0"n fg ftCannot get new mail (cannot rename mail file). + Perhaps another program, such as MM or the mailer, has locked the mail file. + ' !* Typical case on TNX.! + 0u4' !* 4: Do not need another G.! + + .,.fsBoundw !* set bounds to .,.! + e[fne] !* ..N: Push input. THIS ..N PUSHING! + !* MUST BE BEFORE THE HK-ONE SO THE! + !* 0U..N LATER WILL 0 THE RIGHT ..N.! + fn hk  !* ..N: Discard new stuff if not known! + !* to be consistent.! + !* NO MORE FNs UNTIL THE 0U..N.! + :i*AReading Mail file 2fsEchoDisplayw + er fsIFileu5 !* 5: Name of read-in mail file, the! + !* [BABYL one.! + @y @ft + !* print CRLF when done! + + qBabyl XMail Optionf"n u1 !* 1: XMail filename.! + e?1"N et1 eief ' !* If not there, create it.! + qBabyl XMail Append Option"n !* We are to append new mail.! + :i*AAppending to XMail filefsEchoDisplay + q1m(m.m& Babyl Append)"e !* Try fancy append.! + !* Didnt work.! + bj er1 fy !* Insert XMail at beginning.! + -@fk 0,0a-14."e -d' !* Strip off padding.! + f[DFile et[TECO] OUTPUT fsOSTeco"n 0fsDVersionw' !* Open to! + ei !* a safe (TNX) file.! + f]DFile hpef !* Write out new XMail file.! + b,.k' !* Kill old XMail part.! + fsOFileu1 !* 1: New XMail filename complete.! + @ft 1 + 0fsEchoActivew' !* Tell user what took time.! + + "# + :i*APrepending to XMail filefsEchoDisplay + zj er1 @a !* Prepend new mail to XMail file.! + f[DFile et[TECO] OUTPUT fsOSTeco"n 0fsDVersionw' !* Open to! + ei !* a safe (TNX) file.! + f]DFile hpef !* Write out new XMail file.! + .,zk !* Kill old XMail stuff.! + fsOFileu1 !* 1: New XMail filename complete.! + @ft 1 + 0fsEchoActive''w !* Done XMail hacking.! + + :f~BABYL OPTIONS:"e 1,m(m.mConvert Babyl File Version)w !* If need.! + j:s b,.k' !* Babyl file, chop off top.! + "# :f~*APPEND*"e k'' !* RMail file, chop off top.! + 14.,1a-14."n !* If not Babyl file convert.! + m(m.m& Babylize Buffer)' j !* ...! + + qBABYL Append Option&2"n !* User wants reversal.! +   -.  :s$w ' !* Keep Space after . there, else the! + !* sort is a no-op for some reason...! + + + 0u..n !* ..N: Buffer now ok, can keep it.! + + qBabyl Append Option&1"n !* Append.! + :i*AAppending to Babyl filefsEchoDisplay !* Tell user.! + q3m(m.m& Babyl Append)"n !* Can append?! + @ft 3 + 0fsEchoActivew' !* Yes, do it.! + "# m(m.m# Babyl S)'' !* No, just write full combined.! + "# m(m.m# Babyl S)' !* Prepend: write out combined files! + ed5 !* delete mail file! + q4"n oREDO-G' !* If all that just brought in mail! + !* from last crash, go check for some! + !* real mail.! +  + +!# Babyl H:! !C# Reform or display original header. +If no argument, this forces the original header to be reformed. (You + can thus manually reform selected messages even if you don't have + messages normally reformed automatically -- i.e. if you set the No + Reformation option.) Reparse original header. +If argument, e.g. 1H, makes the original header be the visible header, + i.e. it unreforms.! + + [1[2 !* save registers! + 0,(fsZ)fsBoundw !* Wide bounds to include original.! + m(m.m& Reformed Bit)"n !* Message was reformed.! + m(m.m& Bounds Of Original Header)u2u1 !* 1,2: Bound original header.! + q1,q2x1 !* 1: Original header.! + fq1"e m(m.m& Babyl Select Message) !* Rebound message.! + !* There is no original header. Either it was discarded, or because! + !* of a bad header, the refBit was set and the original header is! + !* actually the visible one. In either case, we can just reset the! + !* refBit to 0, and try reforming. Nothing to lose, and if the user! + !* has edited the visible header to correct any problems, we can then! + !* reform ok.! + 0m(m.m& Reformed Bit)w' !* Turn off the bit.! + "# :g1u2 0u2 !* Ensure room in address space.! + !* For a moment the address space held the old visible header + 2! + !* copies of the original header. This ensures that the G1 below will! + !* not get an urk and leave us without a visible header.! + m(m.m& Bounds Of Header)k !* Kill visible header, & jump there.! + g1'' !* Put original header in its place.! + + m(m.m& Remove Basic Label)bad-headerw !* In case was bad, user! + !* corrected. If still bad,! + !* will be relabled.! + ff"e !* No NUMARG: wants reformation.! + m(m.m& Reform Header)' !* ...! + m(m.m& Babyl Select Message) !* Set bounds around message . is in.! +  + +!# Babyl I:! !C# File out Babyl file, read in another. +After saving the current Babyl file (if necessary), asks for a Babyl + file. Default filename is DSK:homedir;username BABYL on ITS, + DSK:username.BABYL on TNX. You can override this with + the option variable Babyl Default File. +If the Babyl file has an Owner option (either one user name or several + user names separated by commas), then only the specified user(s) + can modify the file. +If file is not a Babyl file, we just read -- no deleting, no writing. +The variable Babyl File Version controls the version written. See its + description for details. +If you try to read in a Babyl file that does not exist, offers to + create one, asking you about the various options. +If a numeric argument is given (e.g. 1I), deleting and writing are + inhibited. This is like forcing this user to definitely NOT be an + owner. +Teco programmers: describe the variable Before Babylizing File Hook. +qSubDoc"n i +A pre-comma NUMARG is a filename, so wont ask.'! + +!* We try to assure robustness (not leaving a Babyl file with an inconsistent! +!* format, e.g. partially version converted) by first marking the buffer read! +!* only. Only after done do we mark it writable. (Not if 1I or not the owner! +!* though.)! + + m(m.m& Declare Load-Time Defaults) + Babyl Filenames,: 0 + Babyl O Filename,: 0 + Babyl File Version, * 0: read max version, write back to same; + 1: read and write version 1, similar for other positive N; + -1: read max version, write back to next version + This only applies to Tenex or Tops-20 systems.: 0 + Babyl Default File, * Set this to specify your normal Babyl file. If 0, + Babyl figures out the default filename to use. If that is + wrong, you can set this. Set it to a string, the filename. + This is especially for users whose Babyl file is not in their + home directory, or not named from the user name. E.g. you + might have a subdirectory full of mail-files, and set this + variable to (for Tops-20) PS:SMYTHE.BABYL: 0 + + + [1 0[2 [3[4 !* 2: 1 if will find that Babyl file! + f[DFile !* should be writable.! + qBabyl File Versionu4 !* 4: Default version control.! + 1f[FnamSyntax !* Lone fn is FN1, keeping FN2.! + + !* Get filename of new Babyl file: *! + + fsXUname:f6u1 etDSK:1 BABYL !* Default fn is BABYL! + fsHSname fsDSnamew !* Default dir is home dir! + fsOSTeco"n q4+1"e 0'"# q4'fsDVersionw' !* For prompt. -1 means 0 for read.! + qBabyl Default Filef"n fsDFile'w !* Let user change default.! + ff&2"e !* no pre-comma NUMARG! + 0[Buffer Filenames !* 0 so default filename printed! + m(m.m& Read Filename)Babyl fileu1 !* 1: Babyl filename! + ]Buffer Filenames !* Restore.! + q1"e ' !* 0, abort.! + !* If user didnt specify version (or said 0 -- we cant tell), then maybe! + !* use a specific version: ! + et1 !* Set for TNX version control.! + fsOSTeco"n q4"g fsDVersion"e q4fsDVersionw fsDFileu1'''' !* 1: Use! + !* version N.! + "# u1' !* 1: New MAIL file from pre-comma.! + + !* Now that we have the filename, cleanup old Babyl file if any: *! + + 1,m(m.m# Babyl Q) !* cleanup, save previous Babyl! + !* file if necessary.! + :i*CfsEchoDisplay !* clear echo area! + + !* Now we bring in the new Babyl file: ! + + et1 !* Set Babyl filename. Includes! + !* proper version by this time.! + fsDFilem(m.m& Read Babyl File)"n !* If read in a real Babyl file...! + ff&1"e 1u2'' !* 2: Non0 if can write.! + !* It reset fsDFile to be what was actually read. E.g. user may pick another! + !* filename. However, its version may be 0, and might need to be changed to! + !* specific N for writing back, if Babyl File Version is 0.! + fsOSTeco"n q4"e !* User wants writing back to same.! + fsDVersion"e !* Greatest was read in.! + fsIFVersionfsDVersionw''' !* So reset to use version read.! + fsDFileuBabyl Filenames !* Remember this filename.! + 0uBuffer Filenames !* Mark it read only for now.! + 0u:.b(qBuffer Index+2) !* ...! + -1uInhibit Write !* ...! + m(m.mConvert Babyl File Version)u3 !* 3: Non0 if version converted.! + m(m.m& Reset Babyl Options) !* Set options for this Babyl file.! + qBabyl Owner Optionf"n u1 f~(fsXUname:f6)1"n !* Owner?! + 0u2''w !* 2: No, so no writeback.! + q2"n !* Allow write back if ok.! + fsDFilef(uBuffer Filenames !* ...! + )u:.b(qBuffer Index+2) !* ...! + 0uInhibit Write !* ...! + !* Later we may only append to Babyl file. Dont want to append version! + !* n+1 stuff to version n Babyl file so save if converted.! + q3"n @m(m.m# Babyl S)'' !* Save if converted and writable.! + qBabyl Append Option&1"n zj -1'"# j's !* Put point at a good place,! + !* in case G gets nothing and thus! + !* keeps point where it is now.! + 0u..h !* Allow redisplay when we are done,! + !* unless a user hook in G types.! + + 1,m(m.m# Babyl G) !* Get new mail, if any.! + + qBabyl O Filename"e !* If havent yet got a default O! + et XMAIL !* filename, set it from the Babyls.! + fsOSTeco"n q4f"g fsDVersion'w' !* Set its version number now if N.! + fsDFileuBabyl O Filename' !* O may still fiddle with versions.! + + qNumber of Babyl Messages"e !* Empty file. Shouldnt happen now.! + :i*Babyl bug: empty file. Please report the circumstancesfsErr + !* In case continued: ! + :@m(m.m# Babyl Q)' !* ...! + + :m(m.m& Babyl Select Message) !* Can select since are some messages! + !* there. Or it will create a dummy.! + +!# Babyl J:! !C# Jump to message with given number. +nJ goes to message n whether deleted or not. ZJ goes to last message. +J goes to first non-deleted message. +-J goes to last non-deleted message.! + + .[1 0fsVB[2 0fsVZ[3 [4 !* save . and bounds! + + ff&1"e !* No argument means first message! + 1m(m.m# Babyl J) !* ...! + m(m.m& Check Message Label)deleted"e ' !* if is not deleted.! + 1:m(m.m# Babyl N)' !* Else call N to try next one.! + + "l !* -J means last undeleted.! + qNumber Of Babyl Messagesm(m.m# Babyl J) !* ...! + m(m.m& Check Message Label)deleted"e ' !* Last message not deleted.! + 1:m(m.m# Babyl P)' !* Was deleted, search for non.! + + !* Here is where we try to optimize the movement. The safest way to move, + * that doesnt rely on Message Number and Number Of Babyl Messages + * being correct, is to go to the top and then search for N messages. + * However, I think we now maintain these variables pretty solidly, and so + * can trust them, unless we get an error, in which case they should be + * recalculated. So, we choose the best of these searches: from point + * forward, backward, from top forward, from bottome backward. + * ! + + -qMessage Numberf"gu4 !* 4: Moving forward n.! + !* ft(Moving forward)! + qNumber Of Babyl Messages--q4f"l+q4u4 !* 4: Faster searching! + !* ft(Searching Z back)! + !* backwards from end of buffer.! + !* Will leave point at end of! + !* desired message.! + !* Note: the f"l:s...' etc are because stupid 0:s wont return a value! + zj -q4f"l:s + "e oNoSuch''w'"#w !* 4: Faster searching forwards from! + !* ft(Searching . forward)! + !* point. Leave point at top of! + !* desired message.! + q4f"g:s + "e oNoSuch''w'' + + "#w !* ft(Moving backward)! + -(qMessage Number-)f"lw !* Moving back n.! + !* ft(Searching J forward)! + j f"ew 1':s + "e oNoSuch'' !* To top, then past NUMARG messages.! + "#-u4 !* 4: Move back -q4 from point.! + !* ft(Searching . backward)! + !* Will leave point at end of! + !* desired message.! + q4f"l:s + "e !NoSuch! !* Nada.! + q1j q2fsVBw q3fsVZw !* Nope, restore . and bounds! + :i*No Such Message f;Babyl-Command-Abort''w''w !* Message number! + !* ..unchanged.! + f"ew 1'uMessage Number !* Found it, set its number.! + + m(m.m& Babyl Select Message) !* Select message . is in! +  + +!# Babyl K:! !C# Delete message and append to text to be Y(ank)ed. +K kills current message. nK kills message n. +0K kills current message, but only appends the text of the message.! + + m(m.m& Declare Load-Time Defaults) + Babyl K Text,: || + + + [1[2 + m(m.m& Push Message) !* Will come back here when done.! + ff&1*"e !* No or 0 argument, select current! + m(m.m& Babyl Select Message)' !* message.! + "# m(m.m# Babyl J)' !* Go to message NUMARG.! + m(m.m& Add Basic Label)deletedw !* Mark it deleted.! + "e m(m.m& Bounds of Header)w' !* Move past header if 0K.! + .,zx1 !* 1: Killed text of this message.! + zj 0a-10"n :i11 +' !* 1: Ensure it ends with CRLF.! + qBabyl K Textu2 !* 2: Old killed text.! + :iBabyl K Text2 +1 !* Append to killed text.! +  + +!# Babyl L:! !C# Attach/remove a label to the current message. +Given negative argument, removes the specified label.! +!* This is separate for documentation purposes.! + f@m(m.mLabel Message)w  !* Be sure to return NO value, so that! + !* the Babyl arg gets flushed.! + +!Label Message:! !C Attach/remove a label to the current message. +Given negative argument, removes the specified label.! + + m(m.m& Declare Load-Time Defaults) + Babyl Label Abbrevs Spec,: 0 + + [1[2[3 + :f "g :i*'"# 0'u1 !* 1: 0 or label STRARG.! + m(m.m& Push To Buffer)*Babyl* !* So works in SvM too.! + + "l !* Unlabeling.! + + !* We will bind Babyl Labels Option rather than the CRL arguments! + !* since this will cause other stuff, e.g. validation, to work more! + !* correctly and is less space. Note that forcing it to first be set to! + !* the labels option is really just for forcing computation of the! + !* abbrevs-only spec, so we can use them. Abbrevs work for unlabeling.! + + m(m.m& Babyl Get Message Labels)f"ew :i*Not labeledfsErr'( + )u2 !* 2: Labels on this message.! + m(m.m& Use Babyl Label Table) !* Force computation of abbrevs.! + qBabyl Label Abbrevs Specu3 !* 3: String defining the abbrevs.! + :i*2,3( !* Message labels + abbrevs.! + )m(m.m& Make Babyl Label Table)[Babyl Labels Option !* ...! + @fn| qBabyl Labels OptionfsBKillw| !* Garbage collect the qvector! + !* when done with it.! + !* Only complete over this messages! + !* labels.! + :i2Remove !* 2: Prompt part.! + 1u3' !* 3: 1 means do not confirm if label! + !* typed by user is not in list, since! + !* unlabeler will complain anyway.! +"# !* Labeling.! + :i2Attach !* 2: Prompt part.! + 0u3' !* 3: 0 means confirm a label typed by! + !* user if not in list.! + + m(m.m& Use Babyl Label Table) !* Complete over right list.! + + !* 2-bit turned on below for labeling -- allows non-matches, i.e. new labels.! + + :"l 2+'q3,q1m(m.m& Read Babyl Label)2 label: f"e'u1 !* 1: Label.! + f m(m.m& Label Babyl Message)1' !* (Un)Label the message.! +  + +!# Babyl N:! !C# Go forward to next undeleted message. +If numeric argument, n, goes forward n undeleted messages. +qSubDoc"n i +Pre-comma NUMARG of 1 means not to print any error message if + no next message. Or pre-comma numarg of string is label to f; to.'! + + [1[2[3[4 + "e ' !* That was easy -- 0 NUMARG.! + "l -m(m.m# Babyl P)' !* Go backwards if negative.! + -u1 !* 1: - Repetition count.! + qMessage Numberu2 !* 2: Come back if fail.! + q2u3 .u4 !* 3: Original message#.! + !* 4: Original point.! + + m.m# Babyl ^N !* N: Next message mover.! + m.m& Check Message Label !* C: Label checker.! + + @fn| mCdeleted"n !* Ended on deleted message.! + q2m(m.m# Babyl J) !* Ensure that we end on original or! + !* undeleted message.! + q2-q3"e q4:jw'' !* If ended on original, restore! + | !* original point.! + + < ,1mN !* To next message, deleted or not.! + mCdeleted"e !* Not labeled deleted.! + qMessage Numberu2 !* 2: Come back if no more! + !* undeleted messages.! + %1;' !* Undeleted message, see if done.! + > +  + +!# Babyl O:! !C# Write message to a Babyl file. +The message will be labeled recent in the file. Any deleted label it + had will be removed in that file. Other labels remain. +The variable Babyl File Version controls the default version. See its + description. +If the variable Babyl O Confirm New File is non-0, you will be asked + to confirm writing a message to a new file. The default is 0. +Runs Babyl O Message Hook on the message in the file being written + to. (For instance, this might remove some temporary label, e.g. + "file", used to mark messages for filing with the M-X Output + Labeled Messages command.) +Runs Babyl O Done Hook when successfully done. This runs in the + current Babyl file -- not in the file just written to. +qSubDoc"n i +Pre-comma NUMARG means dont ask for filename -- just output to the default + for O which is in Babyl O Filename. If that variable is set to a buffer + object, not a string, then output to the buffer, letting caller write the + whole file. The buffer should start with the whole current file.'! + + m(m.m& Declare Load-Time Defaults) + Babyl O Confirm New File, + * If non-0, you must confirm outputting a message to a new file: 0 + Babyl O Done Hook, If non-0, run when O is done: 0 + Babyl O Filename,: 0 + Babyl O Message Hook,: 0 + Babyl File Version, * 0: read max version, write back to same; + 1: read and write version 1, similar for other positive N; + -1: read max version, write back to next version + This only applies to Tenex or Tops-20 systems.: 0 + + + [1[2 qBabyl O Filename[3[4 !* 3: 0, filename, or buffer.! + q3fp-99"g q3'f[DFile !* Bind default filename to O! + !* default if one exists.! + !* Babyl O Filename should already have version control reflected in it, from! + !* last use of it, or when init.! + e[ e\ fn e^ e] !* Push i/o, arrange cleanup - might! + !* as well, though may not need it.! + ff&2"e !* Ask if no pre-comma NUMARG.! + 5,f Add message tou1 !* 1: Get filename.! + qBabyl File Versionu4 !* 4: Version control.! + et1 fsOSTeco"n fsDVersion"e !* If TNX user didnt say N, and wants! + q4"e !* ...! + 1u2 1:w !* 2: write-over-max, find N.! + q2fsDVersionw' !* ...! + "# q4fsDVersionw''' !* Or if wants next or specific, set.! + fsDFileuBabyl O Filename' !* Remember altered filenames! + + fsQPPtr( !* remember place to unwind to for! + !* running hook! + 0f[VB 0f[VZ !* Save, open bounds.! + .:\u1 fn1j !* 1: string point, auto-restoring.! + -s + c .,(s).fsBoundariesw !* Bound ^L CRLF status line, old! + !* header, EOOH, message, and ^_.! + q..ou1 !* 1: Original buffer, message.! + q3fp"e q3[..o !* If given output-buffer, select.! + fsZ"e oNEW'' !* And see if need to init it.! + "# !* Not given buffer, use file.! + f[BBind !* Select a temp buffer.! + fsOSTeco-2"e !* For TENEX only we have to avoid E?! + 1:"n oNEW' !* and use the unsafe errset method.! + @y' !* For some reason E? doesnt work! + !* on Tenex.! + "# !* ITS or TWENEX can use E?.! + e?"e er @y' !* XMAIL file exists. Read it in.! + "# !NEW! !* XMAIL file doesnt exist, will make.! + qBabyl O Confirm New File"n !* Maybe confirm.! + @ftOutput message to new file?  1m(m.m& Yes or No)"e '' !* ! + iBABYL OPTIONS: +Version:5 +Append:1 +''' !* That is the new XMAIL files BABYL! + !* OPTIONS section (append to end). ! + m(m.mConvert Babyl File Version)w !* Convert if have to.! + j :s +Append:+1"e @f l !* If Append: option specified. ! + \&1"n !* Append to file. ! + zj !* Move to end. ! + -@f + k 0a- "e -d'' !* Trim any garbage at end. ZMail may! + !* leave ^L there, people may! + !* mistakenly put CRLFs.! + "# j s '' !* Else prepend past options section. ! + "# j:s +Append ++1"e !* If Old form of Append option. ! + zj !* Move to end. ! + -@f + k 0a- "e -d'' !* Trim any garbage at end. ZMail may! + !* leave ^L there, people may! + !* mistakenly put CRLFs.! + "# j s'' !* Prepend, past options section.! + .(g1)j !* Get the message.! + l :fb, deleted,"l fk+1d' !* Remove any deleted label.! + 0l :fb, recent,"e 2c i recent,' !* Add a recent label if necessary.! + 0l qBabyl O Message Hookf"nu1 !* 1: User hook.! + m(m.m& Babyl Select Message) !* Set bounds for hook.! + m1'w !* Run hook.! + 0,(fsZ)fsBoundw !* Open, in case hook left narrow.! + q3fp"n !* Maybe write new contents of file.! + f[DFile et[TECO] OUTPUT fsOSTeco"n 0fsDVersionw' !* For TNX,! + ei !* open file to something safe.! + f]DFile hpef' !* When close, rename to proper file.! + )fsQPUnwind + qBabyl O Done Hookf"nu1 m1'w !* Run hook if any when done, and! + !* when popped back to Babyl buffer.! +  + +!& Babyl O Done Hook:! !S Label this message "filed". +Designed to go on Babyl O Done Hook.! + + 1,m(m.m& Label Babyl Message)filed  !* 1, means dont say! + !* anything if already labeled.! + +!# Babyl P:! !C# Move to previous undeleted message.! + + "e ' !* That was easy -- 0 NUMARG.! + "l -:m(m.m# Babyl N)' !* If negative NUMARG, do N.! + + -[1[2 !* 1: - Repetition count.! + qMessage Numberu2 !* 2: Come back if fail.! + + @fn| m(m.m& Check Message Label)deleted"n + q2:m(m.m# Babyl J)' | !* Ensure end on undeleted or! + !* original message.! + m.m# Babyl ^P !* P: Previous message mover.! + + < 1mP !* To prev message, deleted or not.! + m(m.m& Check Message Label)deleted"e + qMessage Numberu2 !* 2: Come back if no more! + !* undeleted messages.! + %1;' !* 1: Undeleted message, see if done.! + > + +  + +!# Babyl Q:! !C# File out Babyl file and exit Babyl. +Deleted messages are expunged from the file before exiting, and the + survey buffer is emptied. +Giving a numeric argument of 1 means do not expunge, just exit. +qSubDoc"n i +1, NUMARG means just cleanup and file away, but dont exit.'! + + qBuffer Filenames"n !* if not (RO)! + ff&1"e 1,m(m.m& Babyl Expunge)' !* If no NUMARG, expunge.! + m(m.m# Babyl S)' !* save babyl file if changed! + + 0,fsZfsBoundw hk f? !* Kill all of buffer Babyl so that! + !* next MM Babyl knows it must start! + !* from scratch! + 0fsXModifiedw 0fsModifiedw !* MM Save All Files shouldnt save! + !* this empty buffer! + 0uBabyl Filenames + 0uBuffer Filenames + 0u:.b(qBuffer Index+2) + + :iBabyl Modified Messages !* No messages to resurvey.! + fq*Survey* Buffer"G !* Stuff left from last survey.! + q*Survey* Buffer[..o !* Select survey buffer if its there,! + hk 0fsModifiedw 0fsXModifiedw !* and purge it.! + ]..o ' !* Back to Babyl buffer.! + + ff&2"n ' !* Have 1, NUMARG so dont exit Babyl.! + f;Babyl-Catch !* Quit to EMACS.! + +!& Babyl R Done Hook:! !S Label message "answered", remove any "reply" label. +This is a function that is designed to go on Babyl R Done Hook.! + + m.m& Label Babyl Message !* L: labeler.! + 1,mLanswered !* 1, means dont say anything if! + !* already labeled.! + 1,-1mLreply !* 1, means dont say anything if not! + !* already labeled.! +  + +!# Babyl S:! !C# Write out the Babyl file.! + + qBuffer Filenamesf"ew  !* Do no saving if file is read-only.! + '[1 f[DFile !* Write File smashes default.! + fsModified"e !* Dont write if not modified.! + :i*CfsEchoDisplay !* Tell user.! + @ft(No changes need to be written) + 0fsEchoActivew ' !* ...! + + !* Buffer Filenames proably has the correct version for writing, unless the! + !* user has changed Babyl File Version while visiting this Babyl file.! + !* But even so, I think that we should write to what the mode line shows,! + !* i.e. to Buffer Filenames. Next file read will use the new spec. -ECC.! + + 1,m(m.mWrite File)1 !* Write, using Buffer Filenames.! +  + +!# Babyl R:! !C# Reply to message using bottom window, with message in top. +Describe Edit and Mail Buffer for details about message editing, and + the general hooks available. +Numeric argument of 1 means just reply to the FROM field. +Numeric argument of 3 means automatically yank the message. It will + have the reformed header. +Numeric argument of 4 means automatically yank the message but with + the original header. +Recipient names that start with INFO-, BBOARD@, or * will not be + included in a CC. (Thus you won't mistakenly reply to INFO-EMACS + or *ITS or *AI etc.) +Some variables may be set by the user to control header formation if + they are non-0: +Babyl Trim Recipient List: By making this 0 you can turn off any of + this removal (including INFO-, BBOARD@, *, etc.) -- you get just + the basic TOs and CCs based on the FROM, TO, CC, and Babyl CC To + variable. By making this negative, you disable the automatic INFO-, + etc. removal only (duplicates and Babyl Dont Reply To are still + removed). +Babyl CC To: should be a string, automatically inserted as a CC field. +Babyl Fcc To: should be a string, automatically inserted as a Fcc + field on Tenex or Tops-20 systems. +Babyl Reply-To Field: should be a string, automatically inserted in a + Reply-To field. +Babyl Require Subjects: if you don't supply a subject field, you will + be asked for one before mailing. +Babyl Dont Reply To: should be a Teco search string, selecting CC + people to remove. Each recipient mailbox name (the user@host part + only, not any personal name parts) is searched -- if the search is + successful that recipient is removed. This does not affect the + INFO-xxx, BBOARD@, or *machine checks. If this is 0, no removal + searching is done; if it is a null string, any CCs to yourself + are removed, as if the string were "yourname@". +Babyl R Hook: a Teco program run just before entering the recursive + edit level. +Babyl R Done Hook: a Teco program run when R completes successfully. + By default, this hook labels the message "answered".! + + m(m.m& Declare Load-Time Defaults) + Babyl R Done Hook, 0 or a Teco program to run after R successfully exits. + The default is to label the message answered.: | + m(m.m& Babyl R Done Hook)| + Babyl R Hook, 0 or a Teco program to run after R sets up its template: 0 + Current Babyl Template Name, 0 or name of template in use: 0 + + + fsQPPtr[0 [1[2 !* 0: Top level unwind point.! + :i*Standard Reply[Current Babyl Template Name !* Signal that this is! + !* a reply, e.g. used for inserting! + !* the in-reply-to before mail sent.! + :i*To continue editing this message use the C command( + )[Abort Resumption Message !* For Abort Recursive Edit.! + + .( 1m(m.m& Parse Header) )j !* Parse message, setting variables.! + !* Leave point where it was. The 1! + !* NUMARG means that we are parsing a! + !* numbered message.! + + fsQPPtru2 !* 2: Unwind to here to reselect back! + !* to message buffer.! + + (-3"'e)(-4"'e)"n !* 3 or 4 NUMARG means yank.! + 0'"# 1',1m(m.m& Push to Edit Mail) !* Switch to *Mail* buffer,! + !* reset it, and use 2 windows! + !* if not yanking.! + fsModified"n !* Aborting leaves *Mail* modified .! + ft +Last message being composed seems to have been aborted. + Continue editing aborted message?  + m(m.m& Yes or No)"n q0fsQPUnwindw !* Yes, so pop buffer etc. and! + f@:m(m.m# Babyl C)'' !* become a C command.! + + fm(m.m& Setup Reply Template) !* Give it our arguments so it can! + !* figure exactly what template to! + !* create.! + + j <:s›; -d> zj !* Get rid of deletes that may! + !* have accidently appeared! + + qBabyl R Hookf"nu1 m1'w !* Run R hook if any.! + + m(m.mEdit and Mail Buffer) !* Let user edit the mail and then! + !* mail it off.! + + q2fsQPUnwind !* Unwind till reselect Babyl buffer! + !* since done hook should go off! + !* there, not in *Mail*.! + + qBabyl R Done Hookf"nu1 m1'w !* Done successfully (didnt abort out)! + !* so run the done hook.! + +  + +!& Setup Reply Template:! !S Form the message template in buffer. +An internal routine of # Babyl R, and it should pass us its arguments. +Original message should be already parsed, and the *Mail* buffer selected.! + + m(m.m& Declare Load-Time Defaults) + From:,,:0 + Reply-To:,,:0 + Subject:,:0 + To:,,:0 + Cc:,,:0 + Babyl CC To, * Automatic CC field in mail if non-0: 0 + Babyl Fcc To, * Automatic Fcc field in Tenex or Tops-20 mail if non-0: 0 + Babyl Reply-To Field, * Automatic Reply-To field in mail if non-0: 0 + Babyl Header/Text Separator, + * 1 line that separates header and text in recursive mail edit: + |--Text follows this line--| + Babyl Trim Recipient List, + * 0 will disable all removal of reply recipients, +-1 will disable automatic removal of INFO-xxx,*machine and BBOARD@ recipients:1 + Babyl Dont Reply To, + * 0 or a Teco search string of CCs to remove (null means yourself): || + + + [1[2[3[4[5[6 qBabyl Trim Recipient List[7 [8[9 !* 7: Trim control.! + 1f[BothCase 1f[^PCase + !* We will form a header based on the message being replied to, with From! + !* becoming To, To and Cc becoming Cc, and any Babyl CC To added as Cc.! + + !* If Babyl Trim Recipient List is non-0 we will then massage this list of! + !* recipients to see who to remove.! + + !* The TO and CCs are parsed and CCs merged into one CC field. The parsing! + !* gives us a list of mailbox/recipient-spec pairs. We prune this list of! + !* recipients using the Babyl Dont Reply To search string and maybe remove! + !* INFO-xxx, System@, Forum@, BBOARD@, and *machine recipients. Would be! + !* nice if this could be driven from BBOARD name list?? The Babyl CC To! + !* recipients are added in after the pruning, to ensure that they dont get! + !* pruned. Duplicates are removed, and finally this recipient list is used! + !* to form a new TO and CC. First set up the TO and CC fields in the reply: ! + + 0u0 !* 0: Will be set to the sender.! + 0fsWindoww !* Dont use any previous one.! + hk iTo:  !* FROM or REPLY-TO will be To.! + qReply-to:u0 fq0"g g0' !* 0: Use reply-to if one.! + "# qFrom:u0 fq0"g g0' !* 0: Otherwise use the from.! + "# :i*Cannot reply -- no FROM or REPLY-TO field f;Babyl-Command-Abort'' + !* No To field.! + + + zj ff&1"n '-1"n !* Full reply -- not 1R.! + qTo:u1 fq1"g icc:  gTo:' !* TOs become CCs.! + qCc:u1 fq1"g icc:  gCc:'' !* CCs stay CCs.! + + !* The Babyl CC To will be added in NOW only if we are not pruning -- if so,! + !* then we add Babyl CC To in AFTER the pruning: ! + + q7"e zj qBabyl CC Tof"nu1 icc:  g1 i + '' !* Insert automatic-CC if one.! + +zu5 !* 5: End of TOs and CCs.! + + fsOSTeco"n zj qBabyl Fcc Tof"nu1 iFcc:  g1 i + '' !* And auto-FCC if on TNX.! + + qBabyl Reply-To Fieldf"nu1 iReply-to:  g1 i + 'w + + zj -2f= +"n i + ' !* Ensure blank line at end.! + + + !* Finish up the header preparation by inserting subject and separator: ! + + + zj qSubject:u1 fq1"g .(iRe: 1)j l.,zk' !* Keep same subject, if one,! + !* but at most 1 line.! + + zj gBabyl Header/Text Separator i + !* Put in separator.! + + -3"e @fn|@m(m.m^R Babyl Yank)w|' !* Auto-yank message if arg=3.! + -4"e @fn|16@m(m.m^R Babyl Yank)w|' !* Auto-yank message with original! + !* header if argument = 4.! + + q7"e ' !* User wants none of the prune.! + !* 7: negative to skip * pruning.! + + z-q5u5 !* 5: Z-. for end of TOs and CCs.! + + !* Now parse the TO and CC fields, collecting the recipient list in a buffer! + !* in Q2. The TO is parsed first so its recipient will be at the top, thus! + !* ensuring (1) that we dont prune it (we skip 1st one), and (2) if TO and! + !* some CC are the same, the TO is preferred.! + + fsBConsu2 !* 2: Recipient list buffer.! + m.m& Process Recipient Field !* P: Parser.! + !* Care in the case of parsing errors, so that the user gets at least some! + !* capability to reply. Perhaps we could do better -- just skip the! + !* offending recipient(s)?! + :i9 !* 9: Collect erring field names.! + 0fo..qDebugging Babyl"e :'1< !* Errset unless debugging.! + fsMachine:f6,q2 mpTO !* 2: Collect parse of TO field.! + !* The +0 allows this to be an errset or not, since non-errset returns no! + !* value but the +0 will then make it a no-error value.! + >+0"n :i9TO field' !* 9: TO field has an error.! + + fq2u3 !* 3: Point in recipient buffer where! + !* TOs end.! + 0fo..qDebugging Babyl"e :'1< !* Errset unless debugging.! + fsMachine:f6,q2 mpCC !* 2: Collect parse of CC field and! + !* merge into one.! + >+0"n fq9"g :i99 and ' :i99CC field' !* 9: CC has error.! + + fq9"g fg ftWarning! Parsing error(s) in the 9. +The recipient pruning stage has been skipped. +Do you want to continue, so that you can edit the header yourself to + correct this problem?  + m(m.m& Yes or No)"e 0u..h !* No. So clear typeout, and abort.! + :i*Aborting the reply f;Babyl-Command-Abort' + ' !* Give up. Let user hack it.! + + !* Now remove any unwanted recipients from recipient buffer. The Dont Reply! + !* To search string is used to check the entire mailbox name, with the search! + !* done over username@host. The INFO-xxx, *machine, etc.! + !* tests are made separately, but the user can disable them by setting Babyl! + !* Trim Recipient List negative. The user can completely specify a mailbox! + !* or hostname by ending with a CRLF. No way now to completely specify the! + !* username part except how it ends... Should come up with something?! + + q..ou4 q2u..o j !* 4: Message buffer. Switch to! + !* recipient list buffer.! + fq0"g q3j .,zfsBoundariesw' !* There is a TO field, will ignore it! + !* in the list (2 lines) for a while.! + + fsXUName:f6u1 0s +1@ !* Set removal-search default for self! + !* at any host.! + qBabyl Dont Reply Tou1 !* 1: 0, null, or search string.! + q1fp"g 0s1' !* If null or string, set search! + !* default again. (Null would keep! + !* same one.)! + + j i + !* CRLF to start first username.! + + < .-z; .u6 !* 6: At next mailbox name line.! + q7"g !* If wants general pruning, do it.! + !* First a couple of special case checks, since they are not filters on! + !* the entire uname part: ! + 1a-*"e 2k !' !* Starts with *, so dont CC.! + 5f~INFO-"e 2k !' !* Starts with INFO-, so dont CC.! + !* Now remove certain unames. These are intended generally to be set by! + !* the site-specific EMACS:BABYL.VARS, though perhaps the user might! + !* have some vars set too. (Though the user could also use Babyl Dont! + !* Reply To.)! + :@f%@x8 !* 8: Uname.! + 0fo..qBabyl No 8 Reply"n !* If supposed to trim out this one,! + 2k !'' !* then remove it.! + q1"n !* User wants some pruning.! + 2r 2f:fb"l q6j 2k !' !* This mailbox matches, so prune.! + q6j' !* Doesnt match, back to mailbox.! + 2l > !* Keep this CC recipient.! + + j 2d !* Remove CRLF at top.! + + + !* Pruning is done, so ok to add in the explicitly-wanted auto-cc specified! + !* by the Babyl CC To variable. We will parse-collect this from a TEMP! + !* buffer, so that we dont re-collect the already-pruned CCs. Note that we! + !* dont have to insert into the message buffer now, since we will later be! + !* creating whole new To and CC fields, made from the recipient buffer.! + + qBabyl CC Tof"nu1 !* 1: auto-cc field.! + zj !* Will add at end of recip buffer.! + f[BBind icc:  g1 i + !* Put it into a temp buffer.! + fsMachine:f6,q2 mpCC !* 2: Collect those new CCs.! + f]BBind' !* Back to recipient buffer.! + + + !* Remove duplicate recipients (based on mailbox) in the CCs. Will handle! + !* TOs shortly. When removing a duplicate, the 1st appearing recipient is! + !* preferred -- these may be if in their full recipient (not mailbox) forms.! + !* Also note that we compare with case ignored.! + +   l  l  !* Sort on mailbox names, each sort! + !* record being a recipient line pair.! + :i1 !* 1: Initial comparison will fail.! + < .-z; ff~1"e 2k' !* A duplicate -- remove it.! + "# x1 2l' > !* 1: Not a duplicate, so reset the! + !* name to compare against.! + + !* Now remove any CC which have the same mailbox as a TO.! + + j 0fsVBw !* Open bounds to include TOs.! + < .@; -2l x1 !* 1: Get another TO mailbox.! + .( 2l <.-z; ff~1"e 2k'"# 2l'> )j !* Remove duplicates of it! + !* among the CCs.! + > !* Iterate over the TOs.! + + + !* Now time to form the real header out of the recipient list we have. Note! + !* that it is being massaged in the recipient buffer, not the message buffer.! + !* Doesnt really matter -- seems a little easier to debug, having both! + !* around.! + + j .,q3fsBoundariesw !* Bound to just TOs.! + + z"g iTo:  !* 1: There is a TO field.! + < .u1 k :l i,  !* 1: Start of this TO. Keep only the! + !* full recipient form.! + fsSHPOS-70"g q1j i + ' !* Auto-fill if need to.! + :l 2d .-z; > !* To next TO mailbox line.! + -2d i +' !* Delete final Comma Space and finish! + !* field with a CRLF.! + + 0fsVZw .-z"l iCc:  !* Open to CCs if there are any.! + < .u1 k :l i,  !* 1: Start of this CC. Keep only the! + !* full recipient form.! + fsSHPOS-70"g q1j i + ' !* Auto-fill if need to.! + :l 2d .-z; > !* To next CC mailbox line.! + -2d i +' !* Delete final Comma Space and finish! + !* field with a CRLF.! + + + !* Now put this header in the message buffer, and we are ready for the user! + !* in all his or her gory editing, messing up all the trouble we just took.! + + q4u..o !* Switch to message buffer.! + b,(z-q5)k !* Kill old TOs and CCs.! + g2 q2fsBKillw !* Get new TOs and CCs, and kill the! + !* recipient buffer.! + zj  !* Leave point at end and we are done.! + +!# Babyl T:! !C# Type some or all of this message. +Numeric argument is optional message number.! +!* Will leave point after typed part of message, so Space will print from! +!* there.! + + ff"n m(m.m# Babyl J)' !* Goto message# argument.! + fsz-z"e ftEnd of file + ' !* Nothing to type.! + [0[1 [3[4[5 + ft +#  qMessage Number= !* Label with message number.! + m(m.m& Bounds Of Header)u4u5 !* 5,4: header.! + q5j 1u3 !* 3: Number of lines in message.! + q5f[vb j4l .-b-200"g b+200j .u1 :l fshpos-120"g q1j '"# l '' + !* Print min(4 lines, 200 chars+#till! + !* end of line).! + .-q4"l q4j ' !* But print at least all relevant! + !* header lines.! + z-.-150"l zj ' !* If less than 150 chars left, print! + !* all.! + b,.t -2f= +"n ft +' !* Then type CR unless stuff typed! + !* ended with one.! + :m(m.m& Babyl --MORE--) !* Do more processing.! + +!# Babyl U:! !C# Undelete a message. +Giving no numeric argument means undelete current message if deleted, + or go back to one that is deleted and undelete that. +Giving a numeric argument, n, means undelete message number n.! + + [0[1 + ff&1"n fsTypeout"g 1u..h' !* dont mess up possible brief! + m(m.m# Babyl J) !* Go to message NUMARG.! + m(m.m& Check Message Label)deleted"e !* Not deleted?! + :i*Message not deletedf;Babyl-Command-Abort'' !* Bitch.! + "# !* Have no NUMARG.! + .u0 !* 0: Original point in case fail.! + qMessage Numberu1 !* 1: Orig message number in case.! + m.m# Babyl ^P !* P: Previous message mover.! + f"n q1m(m.m# Babyl J) !* Found no one, back home.! + q0j !* ...! + :i*No previous deleted message f;Babyl-Command-Abort'' !* ...! + + m(m.m& Remove Basic Label)deletedw !* Unmark deleted.! +  + +!# Babyl V:! !C# Edit and send mail, with template initialization. +DOC .(g(m.m~DOC~ Mail With Template))j k COD! +!* +This is separate for documentation purposes! + f:m(m.mMail With Template) + +!# Babyl W:! !C# Access whole file.! + fsVB+(fsWindow)fsWindoww !* fix window! + 0,fsZfsBoundw !* widen bounds! +  + +!# Babyl X:! !C# Execute an extended EMACS command. +This is just like the EMACS ^R Extended Command command.! + fm(m.m^R Extended Command)w  !* dont return anything! + +!# Babyl Y:! !C# Yank and reset (empty) text saved by K. +nY yanks into message number n. +0Y or -nY just discards the saved text, in case you mistakenly typed K.! + + m(m.m& Declare Load-Time Defaults) + Babyl Modified Messages,: || + Babyl K Text,: || + + + [0[1[2 + ff&1"n "g m(m.m# Babyl J)' !* goto message NUMARG! + "# :iBabyl K Text '' !* 0 or -n means just reset.! + .( zj 0a-10"n i +' !* Ensure CRLF after 1st message.! + gBabyl K Text )j !* Append Babyl K Text to end of! + !* this message.! + :iBabyl K Text !* and put null in Babyl K Text! + qMessage Number:\u0 !* 0: message# as string.! + :fo..qBabyl Modified Messagesu1 !* 1: index of old list/macro.! + q:..q(%1)u2 !* 2: old list/macro.! + :i:..q(q1)20m0 + !* Add in our part. (Line count has! + !* changed).! +  + +!# Babyl Z:! !C# Return no. of messages in current file.! + qNumber of Babyl Messages:\[1 !* 1: no. of messages as a string! + :i551 0 !* append to Q5, return something to! + !* say we have set Q5! + +!# Babyl <:! !C# Go to the beginning of the current message.! + bj !* Bounds are around current message.! + !* Just jump to beginning of virtual! + !* buffer.! +  + +!# Babyl >:! !C# Go to the end of the current message.! + zj !* Bounds are around message.! +  + +!# Babyl \:! !C# Refill the current message. +The numeric argument specifies one or two things: the fill column, + and whether to consider indented lines as paragraph starters, as + opposed to lines of a yanked message. +Fill Column: If no argument, or a 0 argument, is given, the variable + Fill Column is used. Otherwise the absolute value of the argument + is used. +Positive argument says to do default filling -- indented lines are not + paragraph starters. +0 or negative argument says they are paragraph starters. +Thus, for example, plain \ does default, using default Fill Column. + 0\ does paragraph like filling, using default Fill Column. +This will not touch header or mail separator lines, and will respect + indentation. E.g. any yanked messages will be filled separately, + keeping their indentation. +M-x Undo will bring back the old message in case filling caused + problems.! + + [1 + m(m.m& Bounds Of Header)u1u1 !* 1: Top of header.! + fnq1j !* Auto-restore point there.! + .: :s"l r'"# zj' !* Region around message text.! + ff"n "n ''[Fill Column !* Use abs(NUMARG) or variable.! + ff"n :"g !* Maybe use alternate fill style! + 1''@m(m.m^R Fill Indented Mail Region)w  !* Refill the text.! + +!# Babyl ?:! !C# Generate a list of Babyl commands, or just describe 1 character.! +!* +This is separate for documentation purposes.! + f:m(m.mthe Babyl Helper) + +!# Babyl |:! !C# Move to next message with some label. +DOC .(g(m.m~DOC~ Next Labeled Message))j k COD! +!* This is separate for documentation purposes.! + f@m(m.mNext Labeled Message)w  !* Be sure to return NO value, so that! + !* the Babyl arg gets flushed.! + +!the Babyl Helper:! !S Quick help for Babyl commands. +Invoked from Babyl with ?, this function prompts for a Babyl command +character and describes what that command does. If user answers the +prompt with *, all commands are described. Typing [HELP] at the +prompt will get the standard EMACS helper.! + +!* Should it also do a list commands on the Babyl (or all???) file? + * Asks for a character (* for all) and documents that.! +!* Maybe we can call something used by Wall Chart to insert the list, and + * then we can mung it? It is too bad that & List One File doesnt allow the + * option of inserting rather than typing.! + + [1[2[f @ft +Type a Babyl command character to describe, "*" for all of them:  + @:fi-233."e îfsReRead' !* Control-Altmode (End) acts like Return.! + fiu1 !* Read a character.! + + q1-*"n 1,q1m(m.m& Babyl Macro Get) ' !* Single character describe.! + + ft +Single-character Babyl commands: + + + m.m& Babyl Macro Getu2 !* cache this.! + m.m& Maybe Flush Outputuf !* and this.! + A-1u1 Z-A+1< 2,%1m2 mf > !* A-Z.! + ft0-9: Accumulate a numeric argument + + -1u1 0< 2,%1m2 mf > !* Control characters.! + 9u1 A-9-1< 2,%1m2 mf > !* Punctuation.! + Zu1 a-Z-1< 2,%1m2 mf > !* More punct.! + zu1 ­z< 2,%1m2 mf > !* Yet more.! + + ft +Extended commands (invoked with "X"): + !''! + m(m.m& Get Library Pointer)BABYL m(m.m& List One File)C  + !* Using "C " and not "C#" will result in skipping the dispatch table! + !* functions which have already been listed.! +  + +!# Babyl ~:! !C Collect TECO garbage.! + -f?  + +!# Babyl :! !C# Delete the last character from accumulating argument. +Period, Z, digits, comma, plus, minus, etc. are characters that + make up arguments. +If you rubout the entire argument, the echo area is cleared.! + +!* Q5 is a global q-register that Babyl uses to collect the characters! +!* that make up the argument. (It is actually a little macro.) Also note! +!* that & Babyl Execute Options has echoed the rubout, and that will erase it! +!* from the screen, sort of... (Does a backspace-space-backspace.) This! +!* causes a problem if the user rubs out past the beginning of the! +!* argument -- one character of the previous command history echoing will! +!* be erased. To avoid this inaccurate history, we just clear the echo area.! + + fq5"g !* There are some characters to! + !* rubout.! + 0,fq5-1:g5u5 !* 5: So remove the last one.! + 0' !* Tell our caller that we have left! + !* an argument to use.! + + :i*C fsEchoDisplayw  !* Clear echo area. Return no! + !* valu, which means the! + !* accumulated argument should be! + !* flushed if any.! + +!& Babyl Select Message:! !S Bound msg . is in. +Create dummy message if empty file.! +!* If after last message in buffer, selects the last one. + If before first message, selects the first one. + Sets point at the beginning of the message.! + + [1 + 0,fsZ fsBoundariesw !* Open wide for message search.! + + !* Put virtual buffer boundaries around message of message: ! + + :s"e zj -s !* If at end of buffer, use last.! + !* ***Maybe should -:s there and create dummy header?? -ECC! + qNumber of Babyl MessagesuMessage Number' !* Be sure of it.! + "# r' !* Now point is before end .! + fsZ-.fsVZw !* Find end of message, set virtual! + !* end.! + -:s +"e !* Oops -- trying to select the BABYL! + !* OPTIONS section.! + 0fsVZw :s +"e !* Babyl file has no messages (just Babyl Options section), so create a! + !* dummy message, deleted, so the rest of Babyl can operate: ! + m(m.m& Make Dummy Message) !* Updates Number of Babyl Messages.! + r' !* Leave point inside the dummy.! + 1uMessage Number !* Be sure to get correct number.! + :m(m.m& Babyl Select Message)' !* Move to and select 1st message.! + :s +*** EOOH *** +"e :i*Babyl bug: no EOOH linefsErr' + .fsVBw !* Set virtual beginning at top of! + !* user visible message.! +  + +!& Babyl Expunge:! !S Remove deleted msgs, unlabels recent. +Sets msg# variables.! + +!* Changed to try the two-pass method, first removing deleted! +!* messages, second removing recent labels. Should be about twice as! +!* slow as old BABYL way (which had only one pass) but 5 times faster! +!* than current BABYL' way with 10-times-slower OR-search.! + +!* This routine knowns more than most about status line.! + + [0[1 0[2 [3[4[5[x !* 2: counts # expunged.! + qMessage Numberu5 !* 5: Current message #.! + 0,fsZfsBoundw !* Set bounds to whole buffer.! + .u0 j !* 0: original point.! + + !* First pass: remove deleted messages.! + + 0s, deleted, !* Set search default.! + < :s; !* Find label-likely string.! + 0l -4f= + "n l !' !* Not on the status line, so skip it.! + 0l .-3,(@:flc).f(k)u1 !* Expunge message, 1: # of! + !* characters removed.! + q0,.fux,q0-q1fu0w !* 0: stays in original message or! + !* becomes the next if the current is! + !* expunged.! + !* X: ignored. Used to get rid of the! + !* value.! + .-q0"l q5-1u5' !* 5: Decrement current message# if! + !* that message is after the one just! + !* expunged.! + %2w > !* 2: Count # messages expunged.! + + !* Second pass: remove recent labels.! + + j 0s, recent, !* Reset search default.! + < :s; .u4 !* 4: Find label-likely string.! + 0l -4f= + "n l !' !* Not on the status line, so skip it.! + q4j -8d !* Remove the label.! + q0,.fux,q0-8fu0w !* 0: stays in original message.! + > !* X: ignored.! + + q0:jw !* Go back to original message.! + qNumber of Babyl Messages-q2f(uNumber of Babyl Messages !* Correct.! + ),q5f:uMessage Numberw !* Correct. Note that q5 will be 1! + !* too large if the current message is! + !* the last and it is deleted. That! + !* is the case the sorting fixes.! +  + +!& Calculate Message Number:! !S sets msg# var! + .[0[1[2 !* 0: Original point.! + 0f[vb 0f[vz !* Bounds wide.! + :s"l r' .u2 !* 2: Be sure to start well within the! + !* message so no problems of being! + !* midway through the ^L.! + 0s + !* Out of loop so faster.! + 0u1 !* 1: Message number counter.! + j < .,q2:fb; %1w > !* Count until at home.! + q1uMessage Number !* Do what we were told.! + q0j !* Restore point.! + +!& Push Message:! !S So return to original msg, window when caller exits.! +!* Tries to be careful about points not existing. Always leaves original + message selected. Also tries to be careful so no qregs are smashed, and + not to leave too much stuff pushed.! + + q0,q1( !* Dont push these on qreg pdl or! + !* else will leave smashed for caller! + .:\u0 fsWindow+b:\u1 !* 0,1: Point, window strings for! + !* numbers. Window as absolute.! + @fn| 0fsVBw 0fsVZw !* Wide bounds for jump back.! + 0:j"e zj' !* Restore original point or as! + !* close as we can. Should we trust! + !* Message Number if need to zj?! + m(m.m& Babyl Select Message) !* Select original message.! + 0-b"l b'"# 0-z"g z'"# 0''j !* Restore point.! + + 1-b"l b'"# 1-z"g z'"# 1''-bfsWindoww !* Restore window.! + | + [Message Number + )u1u0 !* Restore 0 and 1 from paren pdl! + : !* Exit without popping.! + +!& Bounds Of Header:! !S Return .,. around (reformed) header. +Point left at end of header.! +!* This is the header that is visible -- the reformed one if reformation has! +!* occurred, the original if it has not. All the special Babyl message! +!* information is above the header.! + +!* Some assumptions to be as general as possible, allowing use in non-Babyl! +!* buffers (e.g. after yanking) and allowing different point and bounds: ! +!* 1. There may be no ^_^L separator line above point.! +!* 2. There may be no EOOH line.! +!* 3. There may be no blank line after a NET style header.! +!* 4. Point may be anywhere in the envelope -- message plus original header! +!* plus status line.! +!* 5. Bounds may be anything. Let caller worry if what we return causes! +!* trouble.! + + [1 0f[VB 0f[VZ !* Wide bounds.! + -:s "e j'"# l' !* To status line. if any.! + :s +*** EOOH *** +w !* Past original header section if! + !* any.! + .u1 !* 1: Top of header.! + 4f~MSG:"e l !* If ITS message, move past special! + < 8f~DISTRIB:@:; l > !* header fields for them, DISTRIB,! + < 8f~EXPIRES:@:; l >' !* and EXPIRES.! + :fb:@f"ew :i*Bad header -- not ITS or NET stylefsErr + '+1"e :s + ++1f"e q1,. !* Found blank line, ends net header.! + '+1"e r q1,.' !* No blank line, ends at ^_.! + "# zj'' !* No blank line, no ^_, ends at Z.! + + l !* Is an ITS style header.! + <4f~TO: @:; l> !* Move past any ITS To,! + <4f~CC: @:; l> !* and CC fields.! + q1,. !* Return ITS header bounds.! + +!& Bounds Of Original Header:! !S Return .,. around original header +-. +Point is left at end of original header.! +!* +This is the (possibly nonexistant) header that is not visible. +If reformation has not occurred, this will be null. +If reformation has occurred, this is the original header if it has been + kept. +Bounds are like those of & Bounds Of Header.! + +!* Some assumptions to be as general as possible, allowing use in non-Babyl! +!* buffers (e.g. after yanking) and allowing different point and bounds: ! +!* 1. There may be no ^_^L separator line above point.! +!* 2. There may be no EOOH line.! +!* 3. Point may be anywhere in the envelope -- message plus original header! +!* plus status line.! +!* 4. Bounds may be anything. Let caller worry if what we return causes! +!* trouble.! + + 0f[VB 0f[VZ !* Wide bounds.! + -:s "e j'"# 2l' !* To top of original header section! + !* (past status line) if any.! + .( 2:rw :s +*** EOOH *** + "l -l' ),. !* Return bounds. (Null region if no! + !* EOOH line found.)! + +!& Babyl Execute Options:! !S Babyl command loop. +Note variable Babyl Command Hook.! +!* Global q-register usage in Babyl: + q5 (local) holds the argument to most commands. + Thus Q5 is vulnerable to smashing by buggy functions or random + user arbitrariness. Will just hope... + + Other q-registers used here are pushed during command execution to protect + them. + + Q2, Q4, Q6, Q7, Q8, and Q9 are used here to cache some variables. + Routines (e.g. & Reset Babyl Options) that change those variables should + signal us to reset these qregs by setting the variable + Babyl Variables Reset.! + + m(m.m& Declare Load-Time Defaults) + Babyl Variables Reset,: 0 + Babyl Command Hook, + 0 or Teco program to run at times in command execution. + Its arg tells situation: + In normal Babyl com loop (Q0 has com char, Q5 has arg string): + 1 before display, 2 after, + 3 before com, 4 after. + In survey menu (Q..0 has com char): + 5 before com, 6 after. + 7 when entering SvM level (so you can bind things).: 0 + + + [0[1[2[3[4[5[6[7[8[9 [..j + :i*Babyl[Editor Name !* While inside subsystem, this will! + !* cause mode lines to be recomputed! + !* whenever Babyl is first on the! + !* line. Could perhaps make Babyl be! + !* editor type, but more to type...! + + m(m.m& Babyl Select Message) !* Does this have something to do with! + !* allowing empty Babyl files??? ! + + fsModeMacm.vPre-Babyl Mode Macrow !* Just used by fs^REnter.! + m.m& Babyl Set Mode Linef[ModeMac !* update mode line using this! + !* function! + fs^REnteru0 !* But not in recursive levels.! + @:i*| qPre-Babyl Mode Macrof[ModeMacro !* ...! + 0|f[^REnter !* ...! + -1u0 !* 0: Initialize command character for! + !* hooks if they want to check.! + + ff"L u1 !* End of the error catch, which is! + !* also a loop, so only exit if error! + @ft +1.  0fsEchoActive'w !* Print thrown text, if any.! + + > !* loop back to Babyl-Catch, thus! + !* re-entering the error catch! + +!& Babyl Macro Get:! !S Returns 1char-command function for ASCII arg or: +1, means type its doc-string. +2, means type 1line brief doc.! + + [1[2 !* Save some registers.! + + fsReReadw fiu1 !* Strip off funny bits.! + -4110."E ?u1' !* (but look for [HELP] character)! + q1:i2 !* Get character as a string.! + + q1-33"L q1+100.u2 :i2^2' !* Controlify control-characters.! + "# q1-127"E :i2'' !* Give rubout a name.! + + "E 1,m.m# Babyl 2f"N 'w' !* Look up function.! + + q1-8"E :i2' !* Additional long names.! + "# q1-9"E :i2' !* ..! + "# q1-10"E :i2' !* ..! + "# q1-13"E :i2' !* ..! + "# q1-27"E :i2' !* ..! + "# q1-32"E :i2'''''' !* ..! + + "E :i*2 is not a Babyl command f;Babyl-Command-Abort ' + + 1,m.m~DOC~ # Babyl 2f"Ew -1"G  ' !* Get doc! + :i*- is Not a Babyl Command.'u1 !* ...! + -1"e !* Full documentation.! + ft2:  !* Character name.! + !* Following taken from Describe.! + f[BBind !* Check for ... stuff.! + g1 j:@f k d !* Describe had a [0???! + < :s; !* Find active documentation.! + b,.-1t b,.k !* Type stuff before it.! + .,(s -d).fx1 !* 1: Stuff between s.! + 0:g1-"e m1' !* Call it if ....! + "# 2,m(m.mWhere Is)1"e !* Or find what key.! + ft1'' !* Or just type the stuff.! + > !* Done active.! + ft..o + ' !* Type stuff after ....! + "# !* Just type 1-liner.! + 2,(îf1f"L wfq1'):g1u1 !* 1: Trim it to 1 line.! + ft2: 1 + ' !* Type it.! +  + +!& Babyl --MORE--:! !S Maybe print --MORE-- and # of lines left in msg.! + + [1[2 + .-z"n !* No-op if no more of message.! + .( 0u2 <%2wl.-z;> )j !* 2: # of lines left to print.! + ft( q2:= z-./(fsWidth*q2) !* Type # lines, plus stars if avg! + ft lines)--MORE--' !* linel is more than tty linelength.! +  + +!& Reform Header:! !S Format header on msg. Bounds set.! +!* The header we are reformatting is the one after the EOOH line (probably + the only one in the message, since generally the space above the EOOH + line is empty before reformation). +Original header is left at the beginning of the message, before the vbuf. +The user option variables Babyl Reformation Flushes These Fields and + Babyl Reformation Control affect & Form Header. See its code for details. +The reformatted header is then inserted after the EOOH line. +Doesnt call & Reformed Bit, just because it is so simple and quick to set + the bit ourselves. +We do things in an order that preserves Babyl file structure and + header information in the case of an error/abort (typically an + URK). In particular, the following will remain true: + 1. Any header in the Babyl file (that we deal with) will remain intact + and be visible or accessible by 1H. + 2. The original header will be visible or accessible by 1H if the user + wants it kept. + 3. There will be a visible header. Thus forming of the reformed + header is done in a temporary buffer. There is a small chance that + an error could abort leaving TWO visible headers, with the original + header strictly being part of the text field. However an URK will + not cause this kind of abort. Note that the original header will + not be discarded (for that user option) until the reformed header + is installed.! + + m(m.m& Declare Load-Time Defaults) + Babyl Reformation Merges From/Reply-To, + * Non-0: Reply-To merges with From. + This is part of header reformation which you can disable separately. + Surveys of merged messages will unfortunately mention the Reply-To, + not the From.: 0 + Babyl Reformation Flushes These Fields, + * Visibility control for fields. + 0 or a string, with format [fieldname1] [fieldname2] ... + Fields mentioned in this string, and otherwise unknown will be + removed from the visible header: + |[Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Received] + | + Unknown Field Flusher,: 0 + + [1[2 + 0fsVBw -s + l .fsVBw !* Bound before status line.! + f1 !* Set reformed bit. (So in case any! + !* bad trouble, avoid infinitely! + !* repeating it.)! + 0fsVZw s r z-.fsVZw !* Now have bounds around status line,! + !* old header, EOOH line, and message.! + -2f= +"e 2r'"# i + 2r' !* Ensure a CRLF at message end.! + + !* Set cleanup handler that removes extra CRLFs at message end. Do this! + !* when exit, not now, so that when we pick up the original header, we will! + !* include any blank line at its end -- if there is no text field, the! + !* extra-crlf removal done now would remove that terminating blank line! + !* first. We also remove lines consisting of dashes.! + + @fn| !* Cleanup handler.! + zj2r .,(-@f + -l 0f"n :l').:d !* Delete extra CRLFs at message end.! + !* Careful about hyphens at end of a! + !* text line, e.g. signature.! + j !* D not K, so if no deletion, doesnt! + !* set fsModified. (.,.K does)! + | !* End of cleanup handler.! + + !* We have a message to reform: ! + qBabyl Reformation Flushes These Fields[Unknown Field Flusher !* Tell the! + !* parser to ignore some fields.! + 1@:< !* Catch errors to avoid trouble! + 1,m(m.m& Parse Header) !* Set field variables.! + !* The 1, tells it to just -1fsErrThrow if bad header.! + !* The 0 NUMARG tells it that it shouldnt reuse the parse variables! + !* next time but instead reparse, parsing the reformed rather than (as! + !* now) original header. Leave . at end of parsed header if ok.! + >"n !* If anything goes wrong, just punt.! + m(m.m& Add Basic Label)bad-headerw !* Indicate lossage, and! + j s +*** EOOH *** + .fsVBw ' !* leave message bound.! + + qBabyl Reformation Merges From/Reply-To"n !* Maybe play with the From,! + m(m.m& Babyl Process Sender Fields)' !* Sender, and Reply-to.! + + !* If parse was successful, point is at end of header.! + z-.u1 !* Z-q1: end of header.! + j :l !* Down past status line.! + .,(s +*** EOOH *** + fkc).k !* Empty anything in original-header! + !* area, i.e. between status and EOOH! + !* lines.! + 2l !* Point is at top of header.! + qBabyl No Original Option"e !* User wants a copy of original! + !* header kept.! + .,z-q1x2 !* 2: Copy of original header.! + -l g2 l' !* Copy original header to area before! + !* EOOH line.! + .fsVBw !* Reset bounds to just message.! + f[BBind !* Temporary buffer to form header in.! + m(m.m& Form Header) !* Build the reformed header.! + zj i + !* Add extra CRLF to be sure the! + !* header separate from original, even! + !* if ITS style formed.! + hx2 !* 2: Reformed header.! + f]BBind !* Back to Babyl buffer, killing! + !* temporary buffer.! + g2 !* Get the reformed header. The! + !* original header follows, part of! + !* the text now.! + .-2,z-q1k !* Safe to discard original header! + !* now, plus the extra CRLF.! + j + 0uParsed Message Number !* Pretend we didnt parse this, since! + !* the header we formed doesnt quite! + !* match the parse. This way, the! + !* reply header former will benefit! + !* from our hairyness.! +  + +!& Parse Header:! !S Parse header into field-name variables. +& Process Recipient Field parses a recipient field. +Leaves . at end of header if all ok. +0 NUMARG means this is not a numbered message (e.g. outgoing mail). +1 NUMARG means it is a numbered message (and thus we can perhaps avoid redoing + the parse). +Pre-comma NUMARG says to be silent about a recognized bad header, and just + -1fsErrThrow leaving point at top. Else gives an error message. +The variable Unknown Field Flusher is 0 or a flusher string over the field + name. See code for details.! + +!* If a field does not have a variable defined for it -- which would indicate! +!* that some code is interested in that field -- it is added to the variable! +!* Unknown:, unless it is flushed by the string Unknown Field Flusher. This! +!* string has field names surrounded by brackets. The parser searches the! +!* string for the field name and brackets. If found, it ignores the field.! +!* The intent is that the high-level, calling, function will bind this from! +!* some user option variable, e.g. to control which fields are flushed from! +!* the header.! + +!* Note: The comment field of recipient field variables, e.g. From:, must! +!* start with a comma (maybe JUST be a comma). This is used to say that! +!* continuation lines made because of a duplicate field encountered should be! +!* separated from the previous lines contents by a comma. For instance, if! +!* the original header has! +!* From: One@Host! +!* From: Two@Host! +!* this will be parsed into the From: variable as One@Host,Two@Host.! +!* (This only applies for net headers.)! + + m(m.m& Declare Load-Time Defaults) + Parsed Message Number,: 0 + Date:,: 0 + From:,,: 0 + Sender:,,: 0 + Subject:,: 0 + To:,,: 0 + Cc:,,: 0 + Reply-To:,,: 0 + MSG:,: 0 + Mail-from:,: 0 + Message-ID:,: 0 + Redistributed-By:,,: 0 + Rcvd-Date:,: 0 + Unknown:,: 0 + Unknown Field Flusher,: 0 + !* end of declare! + + [1[2[3[4[5 !* save registers! + + !* First see if we have to do the parse or if we have already parsed this! + !* message before. If the message is a numbered one, we might have. But! + !* un-numbered messages always have to be reparsed.! + + :fo..qParsed Message Number+1u1 !* 1: ..q index for old# value.! + :fo..qMessage Number+1u2 !* 2: ..q index for this# value.! + + "n !* Caller says this is a numbered! + !* message.! + q:..q(q1)-q:..q(q2)"e !* Same as the one we parsed last time.! + m(m.m& Bounds Of Header)jw ' !* So just leave point at header end.! + "# !* Different numbered message.! + q:..q(q2)u:..q(q1)'' !* Reset Parsed Message Number to be! + !* this Message Number.! + "# !* Caller says this is not a numbered! + !* message.! + 0u:..q(q1)' !* Reset Parsed Message Number to 0,! + !* so wont think it is any numbered! + !* message.! + + + :i1 !* 1: Null string for initializing! + !* variables! + q1uDate: + q1uFrom: + q1uSender: + q1uSubject: + q1uTo: + q1uCc: + q1uReply-to: + q1uMSG: + q1uMail-from: + q1uMessage-ID: + q1uRedistributed-By: + q1uRcvd-Date: + q1uUnknown: + + q..o( f[BBind gUnknown Field Flusher !* Get string for flushing.! + !* If inserts a 0, no matter. Will! + !* act ok -- not find any fields.! + q..ou5 [..o !* 5: Buffer with the flush-string.! + )u..o !* Back to message buffer.! + + 0f[VB -s  l .fsVBw !* To status line. and set bounds! + !* there so others below can jump up.! + s +*** EOOH *** + !* Jump to top of header.! + + 4f=MSG:"e 4c @f r @xMSG: l !* Pick up MSG: line if system msg! + < 8f~DISTRIB:@:; !* DISTRIB:?! + 8c @f r @xTo: l > !* Treat the DISTRIB: line of the! + !* message as a To: line! + < 8f~EXPIRES:@:; l > !* skip over EXPIRES: lines! + ' !* End of MSG:-handling! + + .u1 !* 1: start of header! + + !* determine header variety! + :fb@:f"ew ff&2"n j -1fsErrThrow' !* Silently err if precomma.! + :i*Bad header -- not ITS or NET stylefsErr'+1"e !* ITS! + s  r 0x4 :iFrom:4 + !* Get From! + c 9f=(Sent by "e 9c .,(fb) ).-2x4 :iSender:4 +' !* Get Sender! + .u2 !* Q2: Start of date! + :fb Re: "l @f l xSubject: 5r' !* Pick up subject.! + "# :l' !* No subject.! + q2,.x4 :iDate:4 + l !* Get Date! + < 4f~TO: @:; 3c @f l @xTo: l > !* Get To! + < 4f~CC: @:; 3c @f l @xcc: l > !* Get cc! + ' !* end of ITS header parsing! + "# q1j :s + +"e zj'"# @f +d 2r' !* find end of net style header! + fsZ-.f[VZ !* Set bounds to just header! + q1j < .-z; .,(:fb:"e ff&2"n j -1fsErrThrow' !* Silent err! + :i*Bad header -- no colon in fieldfsErr' + !* Maybe should give line in message?! + r -@f r).x1 c !* 1: field-name.! + f~1Sent-by"e :i1Sender' !* 1: convert to standard names! + f~1Received-date"e :i1Rcvd-Date' !* ...! + f~1Re"e :i1Subject' !* ...! + @f l x2 !* 2: 1st line (after white) of the! + !* field text.! + < l .-z; !* pick up text associated with! + 1af :; !* field-name, add subsequent lines! + @x2 > !* if they start with whitespace! + !* Check if field-name recognized, and get any previous contents: ! + 0fo..q1:f"nu3 fq3"g !* 3: Previous contents.! + !* Will add new stuff, which will be a new line, with! + !* continuation, since CRLFs are included in old contents. If! + !* the variable comment starts with a comma, we separate old and! + !* new contents by a comma -- for recipient fields.! + 0:g:..q(:fo..q1:+2)-,"e !* A recipient field.! + 0,fq3-2:g3u3 !* 3: Remove trailing CRLF.! + :i*3, + 2'"# !* Non-recipient field. No comma: ! + :i*3 2''"# q2'u1:' !* New contents.! + "#w !* Field is unknown. See if we are to collect it: ! + q5[..o j :s[1]"e !* Will collect it if not in list.! + .(g1i:g2),.@fxUnknown:' !* Field-name not recognized,! + ]..o' !* add to list of unknowns! + > !* End of get field-name iteration! + f]VZ 2:cw !* Bounds back to whole message! + ' !* End of NET header conditional! +  + +!& Babyl Process Sender Fields:! !S Reformat From:, Sender:, Reply-to: fields! + +!* From: Foo Fah + Reply-to: Baz at SITE + becomes + From: Foo Fah + + redundant Sender: and Reply-to: fields are flushed. + ! + + m(m.m& Declare Load-Time Defaults) + From:,,:0 + Sender:,,:0 + Reply-To:,,:0 + + +!* From, Sender, and Reply-to will have spaces around them ...! + + [0[1[2[3 f[BBind + + @:i*|j @f +kzj -@f +k|[S !* S: space-killer! + + gSender: mS hfx2 !* 2: Sender field! + gReply-to: mS hfx3 !* 3: Reply-to field! + + gFrom: mS !* put From field in buffer! + j :s<"n !* look for RFC type header! + .-1u1 :s>"e ' !* save point, look for close bracket! + .-z"n ' !* don't complain -- someone else will! + -d q1jd !* flush brackets! + q1,zfx1' !* 1: < ... > text! + "# :i1' !* 1: null string if no < ... >! + mS hfx0 !* 0: main part of From! + g1 mS hfx1 !* remove spaces from q1! + + fq1"e !* if < ... > text is null! + g3j @:f,()<>l .-z"e !* and no special chars in reply-to! + hf~0"n q3u1' !* maybe copy Reply-to into from! + :i3'"# hk'' !* and flush Reply-to! + "# f~13"e :i3'' !* else flush Reply-to if redundant! + + fq1"e f~02"e :i2'' !* compare Sender with From! + "# f~12"e :i2'' !* and flush if they are the same! + + fq1"g :iFrom:0 <1> +' !* insert RFC733 from if q1 non-null! + "# fq0"g :iFrom:0 +'' !* else simple from! + + fq2"e q2uSender:' !* if Sender is non-null! + "# :iSender:2 +' !* make Sender! + + fq3"e q3uReply-to:' !* if Reply-to is non-null! + "# :iReply-to:3 +' !* make Reply-to! +  + +!& Form Header:! !S Create NET message header, inserted at point.! +!* +Goes to some effort to determine the originating host name, which is used in + addressees which are missing a host. +Strips leding Re:s from subject, for stupid Hermes messages. +Babyl Remove Subject Labels non-0 means we should trim subject lines that + start of with excl (implying a reminder) or {...} (a label). +Exactly one blank line separates header from text.! + + m(m.m& Declare Load-Time Defaults) + Babyl Reformation Control, + * Non-zero speeds up reformation process. + 1 - Do not worry about missing hosts. + 2 - Do not prettify recipient fields either.: 0 + Date:,: 0 + From:,,: 0 + Sender:,,: 0 + Subject:,: 0 + To:,,: 0 + Cc:,,: 0 + Reply-To:,,: 0 + Redistributed-By:,,: 0 + Mail-from:,: 0 + Rcvd-Date:,: 0 + Unknown:,: 0 + Babyl Reformation Flushes These Fields, + * Visibility control for fields. + 0 or a string, with format [fieldname1] [fieldname2] ... + Fields mentioned in this string, and otherwise unknown will be + removed from the visible header: + |[Message-id] [Return-Path] [In-Reply-To] [Mail-From] [Rcvd-Date] + [Received] + | + + !* End of declare.! + + [0[1[2[3[4[5[6[7[8[9 [P .f[VB fsZ-.f[VZ !* set buffer bounds to .,.! + fsBCONSu5 fsBCONSu9 !* 5: Temp buffer for parser.! + @fn|q5fsBKillw q9fsBKill| !* 9: Temp buffer for flush checks.! + q9[..o gBabyl Reformation Flushes These Fields ]..o !* ...! + fsMachine:f6u7 !* 7: Local host.! + fsOSTeco"E :i7MIT-7 ' !* (Special hack for MIT)! + qBabyl Reformation Controlu0 !* 0: Control bits.! + + 0u4 !* 4: 0 or originating host, for! + !* handling missing hosts.! + q0-1"l !* Handle missing host names more! + !* cleverly.! + + !* Cons up macro (in 1) for extracting a host name from a 733ish address.! + !* Returns non-zero when successful: ! + :@i1|:i2 fq2::"G 0' !* Field name into 2.! + .,(g2:).( !* Yank it in temporarily.! + j :s@ at "l !* Found a host. Win, Win.! + @f l .,( @:f + ,<>()l !* Find end of host-name.! + ).x4' !* 4: Pick up the host name.! + )k q4| !* Kill the text.! + + m1Redistributed-by"E !* If redistributed, then this is the! + !* ..originating host.! + m1From"E !* If From: has a host, then this is! + !* ..the next best possible guess. ! + m1Sender"E !* Sender:??? ! + + fqMail-from:"G !* TNX mailers hackish Mail-from.! + !* Next best guess. Care required since various formats.! + f[BBind gMail-from: !* Get mail-from line.! + qBabyl ..D[..d 0u4 !* 4: 0 until host name.! + !* Known kinds of syntax are: ! + !* MAIL-FROM: network HOST host RCVD AT time! + !* MAIL-FROM: host RCVD AT time! + !* MAIL-FROM: host! + !* MAIL-FROM: user CREATED AT time! + j :s HOST "l !* 1st part matches.! + .u4 :s RCVD AT "l q4j !* 2nd part does too.! + :@fll @flf(x4)l' !* 4: Host name.! + "# 0u4'' !* 4: 2nd part didnt match, no host.! + "# j @f l @flf(x4)l !* 4: Possible host name, move! + 9f~ RCVD AT "n !* Ok if followed by RCVD AT,! + :f"n 0u4''' !* or if at end of field/line.! + ]..d f]BBind''''' !* End of missing-host setup.! + + q4"E q7u4 ' !* 4: If all else fails, use local! + !* host.! + + !* === Start forming header === ! + + !* 6: Macro for inserting non-address fields into header, with indentation.! + !* Pre-comma arg means is required for visible header -- cannot be flushed: ! + + :@i6|:i2 fq2:"E' !* Quit if field is null.! + "e q9[..o j:s[2]"l' ]..o' !* Or if flushing this field.! + i2: 5-(fsHPos)f"lw0'+1,40.i !* indent uniformly,! + .(g2:)j l <.-z;i l>| !* as we insert the text.! + + !* 1: Macro for inserting addressee fields into the header: ! + !* So far, this macro is redundant -- just calls 6. But it may be appended! + !* to, if doing prettification (filling, @-to-at).! + + :@i1|:i2 fq2:"E' !* Quit if field is null.! + fm62| !* Else, just insert.! + + q0-2"l !* Maybe prettify recipient fields.! + m.m& Process Recipient FielduP !* Cache this for later use...! + :@i1|1 !* Start out the same...! + 0fo..qDebugging Babyl"e !* Non-hackers dont check the errors.! + :'1< q4,q5mP2w !* but add missing host names...! + !* +0 below handles case of no : for Debugging Babyl.! + >+0"n :i* Parsing error in 2:-fieldfg' !* ...maybe.! + zj|' !* Done.! + + m6MSG !* Insert any MSG: field.! + + fqDate:"n q9[..o j:s[Date]( ]..o )"e !* Date: field, if non-null! + !* and if not flushing.! + .(1,m6Date)+6u2 !* First insert and do line! + !* indentation. Smashes 2.! + !* 2: Point after Date:.! + fsOSTeco"n !* Be fancy on TNX...! + q2j :x8 !* 8: Old date.! + :l 0a-)"e -flk -@f k' !* Flush comment at end of line.! + -4c 1a- "e di-' !* Turn zone space into dash.! + q2j 1a"a @:f, l @f, l' !* Back to start, maybe skip weekday.! + fsFDConvertu3 q3+1"e r' !* Try to convert into internal form.! + :f"e q2,.k !* If then at end of line, kill the! + !* ..old one.! + 332221000000.,q3fsFDConvert !* And get the new one.! + -s  i ' !* Add extra sp between date and time.! + "# q2j :k g8' !* Else get back original date.! + zj''' !* Go to end of date, header.! + + m1From !* Do it...! + fqSender:"n qSender:u2 f~From:2"n m1Sender'' !* Do Sender! + !* only if not clearly same as From.! + + m1Reply-To + m1Redistributed-By + m1To + m1cc + + fqSubject:"n !* Subject: ! + q9[..o j:s[Subject][Re]( ]..o )"e !* Insert if not flushing.! + .(1,m6Subject)j 8diRe:  !* Call it Re: for brevity.! + 0fo..qBabyl Remove Subject Labels"n !* Auto-labeling found some! + !* labels in subject.! + < !* Iterate over all labels.! + @f k !* Trim leading whitespace.! + 0,1a-!"n 0,1a-{"n 1;'' !* Neither reminder nor { label.! + 0,1a-!"e d' !* A reminder excl -- trim it.! + 0,1a-{"e .,(:fb};).k' !* A label -- trim it.! + >' + + < @f k !* Trim whitespace.! + 3f~Re:@:; 3d > !* Stip off Re:s.! + zj'' !* Done subject field.! + + !* Now for fields that by default are not inserted -- but which have! + !* variables defined for them, since some code is interested in them. We! + !* must m1 or m6 them here to allow the user control over whether they are! + !* seen: ! + + m1Mail-From !* ...! + m1Rcvd-Date !* ...! + m6Redistributed-By !* ...! + + fqUnknown:"G gUnknown: fkc !* If any unknowns, yank in.! + < .-z; !* Stop at end of field.! + 1af "l !* If not a continuation line,! + :fb:w 5-(fsHPos)f"lw0'+1,40.i' !* indent prettily after field name.! + l > ' !* ...! + + !* If flushing left us with no fields at all, insert something, since Babyl! + !* requires some header visible: ! + z-b"e iMessage: + ' + + i + !* put in blank line after header.! +  + +!& Read Babyl File:! !S and Babylize. Leaves wide buffer. +Arg is filename. +May offer to create or ask for another filename. Resets fsDFile. +Returns nonzero iff file was a Babyl file.! + m(m.m& Declare Load-Time Defaults) + Before Babylizing File Hook, + Run after reading but before Babylizing non-Babyl files: 0 + Babyl File Version, * 0: read max version, write back to same; + 1: read and write version 1, similar for other positive N; + -1: read max version, write back to next version + This only applies to Tenex or Tops-20 systems.: 0 + + !* End of declare.! + + fsZ-(z-b)"n :i*Bounds not widefsErr' !* do error check! + [1[2[3[4 fsDFilew hk + e[e\ fne^e] !* Push I/O in case is open.! + m.m& Yes or No + qBabyl File Versionu3 !* 3: Version control.! + + !RETRY! + e?"n !* No such file.! + fsDFileu1 ftThere is no Babyl file 1. +Do you want to create one?  !* ...! + my"n !* Yes.! + 1@:< 0u2 !* 2: 0 until successfully create.! + fsDFile, m(m.mCreate Babyl File) !* This might err,! + 1u2 >w q2"e oRETRY'' !* which is why the err catch.! + "# ftWant to specify another filename?  !* No.! + my"n m(m.m& Read Filename)Babyl fileu1 !* 1: Filename.! + q1"n et1 fsOSTeco"n fsDVersion"e !* TNX user didnt say! + !* a version.! + q3"l 0u4' !* 4: Will use version 0.! + "# q3"g q3u4' !* 4: Will use version controls N.! + "# !* Overwriting max version if one.! + 1u4 1:w'' !* 4: Find N.! + q4fsDVersionw'' !* Set rest of default.! + oRETRY'' !* Go try that filename.! + :i*No Babyl file f;Babyl-Catch'' !* Abort.! + + :i*AReading Babyl filefsEchoDisplay + er fsIFileu1 !* 1: mail filename! + @ft 1 !* print filename! + @y !* Yank in the Babyl file.! + @ft + !* print CRLF to say were done! + 0fsXModifiedw 0fsModifiedw + + j 1f~BABYL OPTIONS: +"e !* Got a Babyl file. Just in case ZMail has added its typical ^L at! + !* the end, trim that, since it confuses Babyl: ! + zj -@f +  :d !* Trim any whitespace and ^L at end,! + !* since ZMail might put them there.! + !* Avoid K since .,.K modifies! + !* buffer.! + 0a-"n :i*Babyl bug: no ^_ at end of filefsErr !* Warn... ! + i' !* Put it in if continued ! + j 1' !* Assume its ok if has BABYL OPTIONS! + + !* Was not a Babyl file, so make it one: ! + QBefore Babylizing File HookF"N U0 M0'W !* But first run user hook. ! + + iBABYL OPTIONS: +Version:5 + !* Else put one on, and check it out.! + 10f~*APPEND* +"e 10d jl iAppend + ' !* If old-style *APPEND*, change to! + !* the new-style Append option.! + j s .fsVBw !* Point just after , bound below! + !* I think this is buggy, but am not sure -- seems like babylizer wants! + !* a ^L beyond fsVZ that isnt there??? -- ECC, 29 May 1981.! + m(m.m& Babylize Buffer) !* Go check for good format of file.! + 0,fsZfsBoundariesw !* widen bounds.! + 0 !* return zero to say this wasnt a! + !* Babyl file! + +!Convert Babyl File Version:! !C Numeric argument is desired version to go to. +This command is invoked automatically by Babyl when necessary, so + you probably will never need to use this yourself. +If you give no numeric argument, the conversion will be to the version + that this Babyl assumes. +Buffer should contain a Babyl file. +Point is left at the top. +You may convert up or down in versions. +qSubDoc"n i +1, means convert virtual buffer which means copying. +Returns non-0 if conversion was necessary, 0 if not.'! + + [1[2[3[4 + ff&1"n '"# 5'u2 !* 2: Version to go to.! + !* This version of Babyl wants V5.! + j :ff~BABYL OPTIONS:"n !* Check.! + :i*Not a Babyl file (no BABYL OPTIONS section)fsErr' !* ...! + :s +Version:+1"n :i*No version found in BABYL OPTIONS sectionfsErr' + @f l !* Past legal whitespace.! + !* Digit check just in case user edited and maybe stuck in space or tab.! + 1a:"d :i*Version must start with a digitfsErr' !* ...! + \u1 !* 1: Version coming from.! + q1-q2"e j 0' !* Already at desired version.! + ff&2"n !* Convert a copy.! + fsQPPtru4 !* 4: Unwind point.! + hfx3 !* 3: Copy.! + f[BBind g3 !* Copy into temporary buffer.! + 0u3' !* 3: 0 to prevent URKs.! + q1,q2m(m.m& Convert Babyl File Version) !* Do grungy work.! + 0,(fsZ)fsBoundariesw j :s +Version:+1"n !* Very bad -- converter busted.! + :i*No version found in BABYL OPTIONS section after conversion!!fsErr' + :k q2\ !* Insert new version.! + ff&2"n !* Must copy back.! + hfx3 !* 3: Converted copy.! + q4fsQPUnwindw !* Back to original buffer! + g3 0u3' !* 3: ...and discard copy.! + j ft +Done. 1 + +!& Convert Babyl File Version:! !S Internal routine. +NUMARG1 is from-version, NUMARG2 is to-version.! + + [3[4 fsQPPtr[0 !* 0: Unwind point.! + 0,(fsZ)fsBoundariesw !* Wide bounds.! + :\u3 :\u4 !* 3,4: Version from/to as strings.! + ft +Converting Babyl file from version 3 to 4... + + :oCV 3 to 4 !* If can go convert.! + + !* Could not convert directly.! + ft by steps: + -"l !* Going up in version.! + --1"e :i*I do not know how to convert 3 to 4fsErr' + ,+1m(m.m& Convert Babyl File Version) !* Try converting to next! + !* version up first.! + +1,:m(m.m& Convert Babyl File Version)' !* And from there up! + !* to the final, maybe stepping up.! + !* Going down in version.! + --1"e :i*I do not know how to convert 3 to 4fsErr' + q0fsQPUnwindw !* Pop q-registers.! + ,-1m(m.m& Convert Babyl File Version) !* Try stepping down.! + -1,:m(m.m& Convert Babyl File Version) !* ...! + + + !CV 3 to 4! !* From version 3. Ensure EOOH lines. Ensures that! + !* every message has an EOOH line. Leaves point at! + !* top of buffer. Expects file to be a Babyl file --! + !* has an options section. Leaves wide bounds.! + + [1 + j< :s + ; .u1 !* 1: Next message, start of status! + !* line.! + :s +*** EOOH *** ++2"e !* End of message found before EOOH.! + q1j l i*** EOOH *** + ' !* So put one in.! + q1j > !* Back to status, then to next! + !* message.! +  + + + + !CV 4 to 3! !* From version 4. Just change version. Since! + !* version 4 is just requiring EOOH lines, changing! + !* back to version 3 is just a matter of saying 3! + !* instead of 4.! + +  !* Whew.! + + + + + + !CV 4 to 5! + + !* From version 4. Converts from status bits and old {foo} {fah}! + !* label format. Version 5 has standard labels like "deleted" instead! + !* of bits, and has a label line format that is "pretty" and good for! + !* grabbing for mode line or surveys and yet distinguishes between! + !* basic (bit) labels and user labels. Also Babyl Keywords Option! + !* renamed to Babyl Labels Option. For ZMail users, we recognize bits! + !* 10 and 20 as answered and filed and make those basic labels.! + +!* Sample status lines: +0, unseen,, +1, deleted,, filed, junkmail, +0, bad-header,, +The is a 0 or 1 character signalling whether the header has been +reformed -- that isn't a user-visible label. The old bits had: + D00nn or 100nn, with nn being 2-digit encoding of following bits: + 1: Reformed -- now the . + 2: Seen -- now the absence of an "unseen" label. + 4: Ungrokable header -- now the "bad-header" label. +Leaves point at top of buffer. +Expects file to be a Babyl file -- has an options section. +Leaves wide bounds.! + + [1[2[3 + j :s +Keywords:+1"e fk+2d iLabels:' !* Rename Keywords option.! + j< :s +; @f + k .-z; !* Remove any spurious CRLFs, and! + !* allow a final ^_^L since ZMail does! + !* that.! + .u1 !* 1: Next message, start of status! + !* line.! + + !* In the following, note that legally the current format is more! + !* flexible than we might want. There can be arbitrary number of! + !* spaces between close and open braces.! + + < :fb{; -d -@f k i,  !* { becomes <,Space> before label.! + :fb}"e :i*Oops -- no } after label!!fsErr' + -d > :l -@f k i, !* Line ends with one Comma.! + + !* That should have left us with exactly one Comma-Space before each! + !* label, and exactly one Comma after each label, e.g. the line might be! + !* 10000, foo, fah, fum,. If didnt have any labels we have a single comma! + !* after the status bits, which is right.! + + q1+1j 8f[IBase \u2 f]IBase !* 2: Pick up status bits,! + !* sans deleted bit-ha-ha.! + q1+6j i, !* Half of the double comma.! + q2&4"n q1+6j i bad-header,' !* Convert bad-header bit to label.! + q2&2"e q1+6j i unseen,' !* Seen (no label)/unseen.! + q2&10."n q1+6j i answered,' !* ZMail bit.! + q2&20."n q1+6j i filed,' !* ZMail bit.! + q1j 1a-D"e q1+6j i deleted,' !* Deleted.! + + !* The 1-bit becomes the only bit we have in version 5, the .! + q1j 5d q2&1+0i !* Either 0 or 1 character.! + > + + + !CV 5 to 4! !* From version 5. Converts back to status bits and! + !* old {foo} {fah} label format. Recent label! + !* is discarded. Renames Babyl Labels option to! + !* Keywords option. Answered/filed become ZMail bits! + !* iff they are found as basic labels.! + + [1[2[3 + j :s +Labels:+1"e fk+2d iKeywords:' !* Rename to old option name.! + j< :s +; @f + k .-z; !* Allow/fix spurious CRLFs.! + 0l :fb, recent,"l fk+1d' !* Throw away recent.! + 0l 1a-0u2 d !* 2: is bit1, and delete it.! + 0l :fb, unseen,"l fk+1d'"# q22u2' !* OR in seen-bit if has no! + !* unseen label.! + 0l :fb, bad-header,"l fk+1d q24u2' !* 2: OR in the bad header! + !* bit, bit4, and delete the label.! + 0l :fb, answered,,,+1"e fk+1d q210.u2' !* 2: OR in ZMail answered.! + 0l :fb, filed,,,+1"e fk+1d q220.u2' !* 2: OR in ZMail filed.! + 8[..e 10000.+q2:\u2 ]..e !* 2: Convert to string, with high bit! + !* meaning not deleted.! + 0l :fb, deleted,"l fk+1d 0:f2D' !* 2: Turn on (off?) the D bit, ha! + !* ha..., and delete the label.! + 0l :fb,,"e :i*Ooops--broken assumptionfsErr' -d !* Dont need to! + !* separate the basic and user labels.! + 0l g2 !* Insert the old-style bits.! + 0s,  <:fb; } {> !* <,Space>