\section{Programming Aids} \label{Programming Aids} In addition to the command string editing capabilities described in Chapter \ref{Command String Editing}, TECO includes various features to facilitate programming. These are described in the following sections. \subsection{Text Formatting} \label{Text Formatting} The characters carriage return, line feed, and space are ignored in command strings, except when they appear as part of a text argument. Numeric values are not affected. (Inserting a space between digits within a digit string may cause unpredictable results). These characters may be inserted between any two TECO commands to lend clarity to a long command string. The carriage return/line feed combination is particularly useful for typing command strings which are too long to fit on a single line. If the character form feed is encountered in a command string and it is not part of a text argument, a form feed is output to the terminal. This can be used to format terminal output. On TECO-10, execution of the form feed command will clear the screen if TECO is in scope command string editing mode ({\tt 2\&ET} on). \subsection{Comments} \label{Comments} One of the most powerful features of TECO is its ability to store very long command strings so that a given sequence of commands may be executed whenever needed. Long command strings may be thought of as editing programs and, like any other type of program, they should be documented by means of comments. Comments may be inserted between any two commands by using a tag construction of the form: \centerline{\tt !THIS IS A COMMENT!} \medskip Comments may contain any number of characters and any characters except the special characters. Thus a long TECO macro might look like: \begin{verbatim} TECO commands !This comment describes line 1! TECO commands !This comment describes line 2! more commands more commands !end of comment string! \end{verbatim} Do not use {\tt } characters to format long command strings! Only {\tt }, {\tt }, and {\tt } can be used to format command strings since {\tt } is an insertion command. Good TECO code is well structured and adequately commented. Unfortunately, massive comments in a TECO macro tend to slow execution, especially if they appear within text scanned by GOTOs or unsatisfied conditionals. Unless speed is not a goal, it is common practice in larger TECO programs to strip out comments before loading up TECO macros. Thus the TECO program can be adequately commented, yet still run efficiently. A large TECO program can start by placing a comment stripper in a Q-register, say Q-register C. Then it can successively put subroutines (macro text) into the text buffer, do an {\tt MC}, and load the appropriate Q-register with the resulting text buffer, until all the subroutines have been loaded. Finally, Q-register C can be zeroed and the program started. In order for you to strip the comments without losing essential tags, you must make a convention for the format of your comments so that your comment stripper can distinguish them from tags. There are two common conventions. In one, the first character in every comment after the initial {\tt !} is some distinctive character, such as {\tt *}. In the other, all tags start in the left margin and all comments are embedded within the text. Any large comment that wants to be on a line by itself starts with a {\tt } before the {\tt !}. Both methods allow for readable code and easy comment stripping. \subsection{Messages} \label{Messages} The {\tt } command may be used to print out a statement at any point during the execution of a command string. The {\tt } command has the general form: \begin{verbatim} ^Atext: - or - @^A/text/ \end{verbatim} The first \caret{\tt A} is the actual command, which may be entered by striking the \fbox{Ctrl} key and the \fbox{A} key simultaneously or by typing a caret (\caret) followed by an {\tt A} character. The second {\tt } character of the first form shown is the command terminator, which must be entered by typing the \fbox{Ctrl} key and the \fbox{A} key simultaneously. In the second form, the second occurrence of the delimiting character (shown as slash in the example) terminates the message. Upon execution, this command causes TECO to print the specified message at the terminal. The \caret{\tt Amessage} command is particularly useful when it precedes a command whose numeric argument contains \caret{\tt T} or \caret{\tt F} characters. The message may contain instructions notifying the user as to what sort of input is required. \section{Tracing} \label{Tracing} A question mark entered betweeen any two commands in a command string causes TECO to print all subsequent commands at the terminal as they are executed. Commands will be printed as they are executed until another question mark character is encountered or the command string terminates. \section{Convenience Characters} \label{Convenience Characters} In addition to the characters mentioned in Section \ref{Text Formatting}, there are several characters which have no special meaning to TECO but which may be used to help format your TECO programs and command strings. Judicious use of these commands will make your program easier to read and maintain. These characters are described in the table below: \begin{table}[h] \caption{\bf{Convenience Characters}} \label{Convenience Characters} \end{table} \nopagebreak \begin{list}{}{\labelsep 20pt} \item[{\em CHARACTER}] {\em MEANING} \item[{\tt }] A null (ASCII 0) encountered as a TECO command will be ignored. Numeric values are not affected. A null read in from an input file will be discarded (except under RSX-11 and VAX/VMS). A null typed in from a terminal will be ignored. \item[{\tt }] An ESCape that is executed as a TECO command (as distinct from an immediate action command or an ESCape that is part of the syntax of some other TECO command) is ignored by TECO. However, any pending numeric values are discarded. This command is useful for discarding the value returned from a command (such as {\tt n\%q} or {\tt m,n:W}) when you don't want that value to affect execution of the following command. \item[{\tt \caret \[}] Same as {\tt }. Like any other TECO command that is a control character, ESCape may be entered in up-arrow mode. Sometimes easier to type, \caret{\tt [} is also useful on systems whose line-printer spoolers do not visibly print the ESCape character. Any pending numeric values are discarded. This command is useful for discarding the value returned from a command (such as {\tt n\%q} or {\tt m,n:W}) when you don't want that value to affect execution of the following command. \item[{\tt }] Some older terminals may have no \fbox{Escape} key, but instead a key labelled \fbox{ALTMODE} or \fbox{PREFIX} which sends TECO a character whose ASCII value is 175 or 176. In such a case, TECO will treat these characters as if they were typed in as an ESCape (octal 33), provided lower to upper case conversion is enabled. \iftecotenonly \item[{\tt \$} (dollar sign)] Same as {\tt }, but as a command only, not as a string terminator. {\em [TECO-10 only]} \fi Note that {\tt } and {\tt
} are valid TECO commands and must not be used as aids to formatting TECO programs. \end{list} \iftecotenonly \section{Memory Expansion} \label{Memory Expansion} The {\tt nEC} command can be used to make TECO reclaim lost space after it had expanded memory usage. {\tt nEC} tells TECO to expand or contract until it uses {\tt nK} words of memory. If this is not possible, then TECO's memory usage does not change. The {\tt 0EC} command tells TECO to shrink back to its original size (use the least amount of memory possible). {\em [TECO-10 only]} \fi \subsection{Case Control} \label{Case Control} The {\tt } and {\tt } TECO commands are used to specify automatic case control for alphabetic characters typed into strings. \begin{table}[h] \caption{\bf{Case Control Characters}} \label{Case Control Characters} \end{table} \nopagebreak \begin{list}{}{\labelsep 20pt} \item[{\em CHARACTER}] {\em MEANING} \iftecotenonly \item[\caret {\tt V}] {\tt } puts TECO into lower case conversion mode. In this mode, all alphabetic characters in string arguments are automatically changed to lower case. This mode can be overridden by explicit case control within the search string. This command makes all strings behave as if they began with a \caret{\tt V}\caret{\tt V}. {\em [TECO-10 only]} \item[\caret {\tt W}] {\tt } puts TECO into upper case conversion mode. In this mode, all alphabetic characters in string arguments are automatically changed to upper case. This mode can be overriden by explicit case control within the search string. This command makes all strings behave as if they began with \caret{\tt W}\caret{\tt W}. {\em [TECO-10 only]} \item[{\tt 0}\caret {\tt V}] Returns TECO to its original mode. No special case conversion occurs within strings except those case conversions that are explicitly specified by \caret{\tt V} and \caret{\tt W} string build constructs located within the string. {\em [TECO-10 only]} \item[{\tt 0}\caret {\tt W}] Same as \caret{\tt V}. {\em [TECO-10 only]} \fi \end{list} \section{Manipulating Large Pages} \label{Manipulating Large Pages} TECO is designed to operate most efficiently when editing files that contain no more than several thousand characters per page. (TECO storage includes Q-register storage and buffer space. The size of the text storage area is dynamic and depends on the amount of available memory.) If any page of an input file is too large to fit in the text area, the TECO input commands will terminate reading that page into memory when the first line feed is encountered after a point that the buffer is 3/4 full. (See appendices for details.) You can make room by positioning the pointer past a section of text at the beginning of the buffer and moving that section out of the buffer with the commands: \centerline{\tt 0,.PW0,.K} It is sometimes advantageous to restrict the amount of the file that is present in the buffer. For example, each insert and delete command must move the entire text that is beyond the point of insertion or deletion. An operation that does many small inserts or deletes may therefore run extremely slowly if the text buffer is large. Such an operation can be sped up substantially by reading the input file with {\tt n:A} commands and explicitly writing the processed text. \section{Techniques And Examples} \label{Techniques And Examples} The most elementary TECO application, described in Chapter \ref{Basics of TECO} of this manual, is creating and editing ASCII files on-line. The user enters short command strings, often consisting of a single command, and proceeds from task to task until the file is completely edited. Since every editing job is simply a long sequence of TECO commands, you may accomplish an entire job with one long command string made up of all the short command strings placed end to end with the intervening double {\tt } characters removed. A long command string that performs a certain editing task can be considered a TECO {\em editing program}. Editing programs may be written (using TECO) and stored in the same manner as any other ASCII file. Whenever the program is needed, it may be read into the buffer as text, stored in a Q-register, and executed by an {\tt Mq} command. For more complex editing jobs, you may want to write and maintain a collection of specialized {\em editing subroutines}. TECO subroutines can perform such elementary functions as replacing every occurrence of two or more consecutive spaces with a tabulation character, for example, or ensuring that words are not hyphenated across a page boundary. When an editing problem arises, you can load the right combination of subroutines into various Q-registers, augment them with additional commands if necessary, and call them by a {\em mainline} command string. Editing subroutines are essentially macros; that is, sequences of commands which perform commonly required editing functions. The most powerful application of TECO is the creation and use of a macro library. As you perform an editing job, look for sequences of operations which might be required in future editing assignments. Load all of the TECO commands required to perform such an operation into a Q-register. When the job is finished, write the contents of the Q-register onto an output file (via the buffer) and save it in the macro library. The {\tt nMq} and {\tt m,nMq} commands, which were designed to facilitate use of macros, permit run-time numeric arguments to be passed to a macro. TECO macros can preserve the user's radix, flag values, etc. By using the Q-register push-down list, the macro can save and then restore values and/or text. For example: \begin{verbatim} [0 [1 [2 ! Save contents of Q-registers 0, 1 and 2 ! +0U0 ! Put any calling argument into Q-register 0 ! 10U1 ! Put a 10 (if radix is decimal) or 8 (if radix is octal) into Q-register 1 ! ^D ! Ensure that the current radix is now decimal ! EUU2 ! Save the case flagging flag ! -1EU ! Ensure no case flagging ! Q0"E 3U0 ' ! Default calling argument to 3 ! ... Q2EU ! Restore the case flagging flag ! 10-Q1"N \caret O ' ! Restore radix as octal if needed ! ]2 ]1 ]0 ! Restore contents of Q-registers 2, 1, and 0 ! \end{verbatim} The {\tt EI} command is particularly useful for executing macros from a library, since with it they may be read without disturbing the current input file. This makes it unnecessary to plan in advance which macros might be needed; it also saves Q-register storage space. You can retrieve two kinds of TECO command files with an {\tt EI} command: a file containing a TECO command that loads the macro into a Q-register for later use, or a file containing just the macro (which must be retrieved with {\tt EI} each time it is used). The following examples are intended to illustrate some of the techniques discussed above. It would not be practical to include examples of the use of every TECO command, since most of the commands apply to many diverse situations. Instead, you are encouraged to experiment with the individual commands on scratch files. \subsection*{EXAMPLE 1: SPLITTING, MERGING, AND REARRANGING FILES} Assume that there is a file named {\tt PROG.DAT} on the system disk and that this file contains data in the following form: \begin{verbatim} AB CD EF GH IJ KL MN OP \end{verbatim} where each of the letters {\tt A}, {\tt B}, {\tt C} etc., represents 20 lines of text and {\tt } represents a form feed character. The user intends to rearrange the file so that it appears in the following format: \begin{verbatim} AOB D MN EF ICJ KL P GH \end{verbatim} The following sequence of commands will achieve this rearrangement. (Search command arguments are not listed explicitly.) \centerline{Start TECO.} \begin{verbatim} *2ED`` Allow all Y commands. *EBPROG.DAT`Y`` Specify input file and get first page. *NC`` Search for a character string in C, writing A and B on the output file. *J20X1`` Save all of C in Q-register 1. *20K`` Delete C from the buffer. *NG`` Search for a character string in G, writing D, E, and F on the output file. *HX2`` Save G and H in Q-register 2. *Y`` Delete GH from the buffer and read IJ. *20L`` Move the pointer to the beginning of J. *G1`` Insert C, which was stored in Q-register 1. *NM`` Search for a character string in M, writing ICJ and KL on the output file. *HX1`` Save MN in Q-register 1 (the previous contents is overwritten). *Y`` Delete MN and read OP *J20X3`` Save all of O in Q-register 3. *20K`` Delete O from the buffer. *PWHK`` Write P onto the output file, appending a form feed, and clear the text buffer. *G2`` Bring GH into the buffer from Q-register 2. *HPEF`` Write GH on the output file and close it. *EBPROG.DAT`Y`` Open the partially revised file. *20L`` Move the pointer to the beginning of B. *G3`` Insert all of O from Q-register 3. *ND`` Search for a character string in D writing AOB on the output file. *PWHK`` Write D on the output file and clear buffer. *G1`` Bring all of MN from Q-register 1 into the buffer. *EX`` Write MN onto the output file, then close the file and exit. \end{verbatim} At this point the file has been rearranged in the desired format. Of course, this rearrangement could have been accomplished in fewer steps if the commands listed above had been combined into longer command strings. Note that the asterisks shown at the left margin in this example are generated by TECO, and not typed by the user. Assume, now, that the same input file, containing data in the form: \begin{verbatim} AB CD EF ... OP \end{verbatim} is to be split into two separate files, with the first file containing {\tt AB CD} and the second file containing {\tt KL M,} while the rest of the data is to be discarded. The following commands could be used to achieve this rearrangement: \medskip \centerline{Start TECO.} \begin{verbatim} *2ED`` Allow all Y commands. *ERFILE`EWFILE1`` Open the input file and the first output file. *Y`` Read AB into the buffer. *P`` Write AB onto the output file and read CD into the buffer. *HPEF`` Write CD onto the output file (without appending a form feed), and close the first output file. *_K`` Search for a character string in K. After this command has been executed, the buffer will contain KL. No output is generated. *EWFILE2`P`` Open the second output file and write KL onto it. Read MN into the buffer. *20L0,.P`` Move the pointer to the end of M, then write M onto the output file. *EF`` Close the output file. *HKEX`` Clear the buffer and exit. \end{verbatim} As a final example of file manipulation techniques, assume that there are two files. One file is {\tt MATH.ONE}, which contains information in the form: \begin{verbatim} AB CD EF GH IJ KL \end{verbatim} and the other is {\tt MATH.TWO}, which contains: \begin{verbatim} MN OP QR \end{verbatim} If both of these files are stored on {\tt DK1}, the following sequence of commands may be used to merge the two files into a single file, {\tt MATH.NEW}, which contains all of {\tt MATH.TWO} followed by the latter half of file {\tt MATH.ONE} in the following format: \begin{verbatim} MN OP QR GH IJ KL \end{verbatim} \centerline{Start TECO.} \begin{verbatim} *2ED`` Allow all Y commands. *ERDK1:MATH.TWO`` Open the first input file. *EWMATH.NEW`` Open the output file on the default device. *Y`` Read MN into the text buffer. *NR`` Search for a character string in R, writing MN and OP onto the output file. *PW`` Write QR onto the output file, appending a form feed. *ERDK1:MATH.ONE`` Open the second input file. *HKY`` Read AB into the buffer. QR is over-written. *_G`` Search for a character string in G, deleting AB, CD, and EF, leaving GH in the buffer. *NK`` Search for a character string in K, writing GH and IJ on the output file, leaving KL in the buffer. *HPEFHKEX`` Write KL onto the output file (without appending a form feed) and close the file, then exit. \end{verbatim} \subsection*{EXAMPLE 2: ALPHABETIZING BY INTERCHANGE SORT} Assume that TECO is running and that the buffer contains many short lines of text beginning with an alphabetic character at the left margin (i.e., immediately following a line feed). The lines might consist of names in a roster, for example, or entries in an index. The following command string will rearrange the lines into rough alphabetical order, grouping all lines which begin with the character {\tt A} at the beginning of the page, followed by all lines with {\tt B}, and so on. Note that the algorithm could be extended to place the entries in strict alphabetical order by having it loop back to perform the same sorting operation on successive characters in each line. \begin{verbatim} !START! J 0AUA !Load first character of first line into Q-register A ! !CONT! L 0AUB !Load first character of next line into Q-register B ! QA-QB"G XA K -L GA 1UZ ' !If A>B, switch the lines and set a flag (Q-register Z) ! QBUA !Load B into A ! L Z-."G -L @O/CONT/ ' !Loop back if there is another line in the buffer ! QZ"G 0UZ @O/START/ ' !Repeat if a switch was made on the last pass ! \end{verbatim} The same algorithm can be coded in a more structured way as follows: \begin{verbatim} 0UZ !clear repeat flag! B, switch the lines and set a flag ! QBUA !Load B into A ! L .-Z;> !Loop back if there is another line in the buffer ! QZ;> !Repeat if a switch was made on the last pass ! \end{verbatim} This example is a bit shorter and does not use any GOTOs. It will also run somewhat faster.