1 :Info: ted_support.gi:
  2 11/19/82 ted_support.gi
  3 
  4 
  5 Ted can invoke external requests.  These requests be either standard
  6 system routines or user supplied.  In this way a user is able to add
  7 specialized editing requests to ted.
  8 Syntax:
  9 [.,.] |xyz rest-of-line
 10 
 11 
 12 Function:  A request like this will cause ted to try to execute
 13 ted_xyz_$ted_xyz_.
 14 
 15 
 16 Syntax:
 17 help |xyz
 18    An external request may also have info available for the ted help
 19    request.  The info is in standard help file format.  The help file
 20    must be named ted_xyz_.info.  The ted help request uses the info
 21    search rules, but for this instance adds the name of the directory
 22    where ted_xyz_ is found (via system search rules).
 23 
 24 
 25 Global processing:  A mechanism is available whereby the writer of a
 26 function may get a global type of action (g or v) without having to
 27 bother with figuring out how to do all of the details which are neces-
 28 sary.  The ted_support structure contains a pair of entry variables for
 29 this purpose.  The syntax of a global function is one of two forms:
 30   |function /expression/additional-info/ rest-of-line
 31   |function /expression/ rest-of-line
 32 
 33 
 34 call proc_expr (ted_support_p, msg, code);
 35    This procedure is called when a global expression needs to be
 36    processed.  A globally executing function could be written to always
 37    use the remembered expression, but it usually is not.  proc_expr
 38    takes the first non-blank character to be the delimiter, scan and
 39    compiles the expression, and leaves the second delimiter as the cur-
 40    rent character.  If it returns with a zero return code, everything
 41    is ready to process any additional info which the function may
 42    require.
 43 
 44 
 45 call do_global (worker, mode, ted_support_p, msg, code);
 46    This procedure does all the global overhead.  "worker" is an inter-
 47    nal procedure which actually does the function to be performed.  It
 48    will be called once for each line in the addressed range which
 49    matches the criteria.  When it is called, inp.sb points to the first
 50    character of the line to be processed and inp.se points to the NL of
 51    this line.  These two values may not be modified.  "mode" is either
 52    a "g" or "v" to indicate which kind of operation is needed.  The
 53    last 3 args are the same ones which the function itself was called
 54    with.
 55 
 56 
 57 Regular expression processing:  Regular expressions may be utilized
 58 with 2 and maybe 3 easy steps.  The steps are 1) initialization of an
 59 expression area, 2) compilation of an expression, and 3) searching with
 60 an expression.
 61 call tedsrch_$init_exp (addr (someplace), size (someplace));
 62    This entry would not usually be used.  This exists for the condition
 63    where a function wishes to make use of regular expressions without
 64    impacting ted's remembered expression.  The 2 args are where the
 65    hold area is and how long it is.
 66 
 67 
 68 call tedsrch_$compile (ex_p,ex_l,re_p,lmod,rmod,msg,code);
 69    This compiles a regular expression into its internal form.  Usually
 70    an expression is compiled once and then used for searching many
 71    times.  "ex_p" points to first character of the expression to be
 72    compiled.  "ex_l" is the number of characters in the expression.
 73    "re_p" points to the area to hold the compiled expression.  ted's
 74    area may be used by referencing ted_support.reg_exp_p.  "lmod" is
 75    "1"b for line mode, ""b for string mode.  "rmod" is "1"b for regular
 76    expression mode, ""b for literal mode.  The last 2 args are the last
 77    2 function paramters.
 78 
 79 
 80 call tedsrch_$search (re_p,cb_p,sb,se,mb,me,me2,msg,code);
 81    This searches for an expression in a string within a buffer.
 82    Searching may be done in the input string but not the output string
 83    since it is not a buffer.  "re_p" points to the area containing the
 84    compiled expression.  "cb_p" points to the control block associated
 85    with the input data.  "sb" is the offset in the buffer string where
 86    the search is to begin.  "se" is the offset where it is to end.
 87    "mb" is the offset of where a match began.  "me" is the offset of
 88    where a match ended.  "me2" is the last character used to find the
 89    match (sometimes higher than "me").  The last 2 args are the last 2
 90    function paramters.
 91 
 92 
 93 List of standard support functions:
 94 [.] |ax
 95    append LINES after addressed line (after Speedtype expansion)
 96 [.,.] |cx
 97    change addressed lines, replacing with LINES (after Speedtype expan-
 98    sion)
 99 [.] |ix
100    insert LINES before addressed line (after Speedtype expansion)
101 [.,.] |comment
102    add comments to addressed lines.
103 [.,.] |tabin
104    convert spaces to HTs where possible.
105 
106 
107 [.,.] |gtabout `RE`C,n,n...`
108    (global |tabout) convert pseudo-tab C to spaces on all lines which
109    match the expression RE.
110 [.,.] |vtabout `RE`C,n,n...`
111    (exclusive |tabout) convert pseudo-tab C to spaces on all lines
112    which do not match the expression RE.
113 [.,.] |tabout     `C,n,n...`
114    convert pseudo-tab C to spaces using tabstops defined by n,n,...
115 [.,.] |fiad `STR`L,R{,I`
116    Fill the addressed data and adjust to make an even right margin.
117 [.,.] |fina `STR`L,R{,I`
118    Fill the addressed data without adjusting.
119 
120 
121 [.,.] |dumpl
122    dump (long) addressed string in octal and ASCII 20 across (needs 110
123    print positions)
124 [.,.] |dumps
125    dump (short) addressed string in octal and ASCII 10 across (needs 65
126    print positions)
127 [.,.] |dumpvs
128    dump (very-short) addressed string in octal and ASCII 5 across
129    (needs 39 print positions)
130 [.,.] |dump
131    dump addressed string in octal and ASCII using long, short, or
132    very-short depending on current linelength
133 
134 
135    Action taken:  It is assumed that external requests are likely to
136    fit in the same mold and certain actions are taken to ease the bur-
137    den on them.  A request may work in some other fashion if it wishes,
138    however.  Processing is done from an input string to an output seg-
139    ment.  The input string is all of the data in the buffer with the
140    addressed portion indicated.  The request may do whatever it wishes
141    to the output segment.  It may not modify the input string in any
142    way, and may not count on the string being in the same location if
143    called again in the same buffer.  These actions are performed by
144    ted:
145 
146 
147 1) Copy all of the input string which precedes the address range into
148    the output buffer.
149 2) Call the routine.  The call is done this way:
150       dcl ted_xyz_ entry (ptr, char (168)var, fixed bin (35));
151       call ted_xyz_ (addr (ted_support), msg, code);
152 3) Copy input string following the address range to the output buffer.
153    The end-of-address location may be updated by the routine to
154    end-of-string if it has already taken care of this task.
155 4) Make this output string be the buffer contents.
156 5) Set the current location if specified.
157 
158 
159 Options:  The return code may specify that step 4 is to be omitted,
160 that 4 & 5 are to be omitted (no change), or that an error has
161 occurred.
162 
163 The "rest-of-line" is passed to the request with the assumption that
164 everything which follows is information for the request.  The request
165 may then
166 1) Do nothing.  A new line will be read for execution.
167 2) Set the next location just after any data utilized by the request.
168    In this case, execution will continue on the rest of the line.
169 3) Supply a new value and length for the data in the request line and
170    set the next location back to 1.  In this case, execution will com-
171    mence with the line supplied by the request.
172 
173 
174 Example:  A request to convert vowels to uppercase, both regular and
175 globally.
176 
177 ted_uppercase_: proc (ted_support_p, msg, code);
178 /* This routine converts all vowels to uppercase in the range addressed.     */
179 /* It also can do this action globally (g | v).                              */
180 /* It does not allow any request to follow in the same line.                 */
181 /* Usage: {.,.} |uppercase {ignored}                                         */
182     mode = " ";
183     goto common;
184 
185 ted_guppercase_: entry (ted_support_p, msg, code);
186 /* Usage: {.,.} |guppercase /regexp/ {ignored}                               */
187     mode = "g";
188     goto common;
189 
190 ted_vuppercase_: entry (ted_support_p, msg, code);
191 /* Usage: {.,.} |vuppercase /regexp/ {ignored}                               */
192     mode = "v";
193 
194 common:
195     if (ted_support_version_2 ^= ted_support.version)
196     then do;                            /* check for proper version          */
197        code = error_table_$unimplemented_version;
198        return;                          /* can't handle this one.            */
199     end;
200     if (inp.de = 0)
201     then do;                            /* must be some data to work on      */
202        msg = "Buffer Empty.";           /* supply the message text           */
203        code = tederror_table_$Error_Msg;/* say that a message is present     */
204     end;
205     else do;
206        if (mode = " ")
207        then call worker;
208        else do;
209           call proc_expr (ted_support_p, msg, code);
210           if (code ^= 0)
211           then return;
212           call do_global (worker, mode, ted_support_p, msg, code);
213        end;
214        current = out.de;                /* and say that "." is there         */
215        code = tederror_table_$Copy_Set; /* tell ted to finish up             */
216     end;
217 
218 worker: proc;
219        i = inp.se - inp.sb + 1;         /* calc how much to process          */
220        substr (ostr, out.de+1, i)
221           = translate (substr (istr, inp.sb, i),
222           "AEIOU", "aeiou");            /* translate that much               */
223        out.de = out.de + i;             /* update the output length          */
224     end worker;
225 
226 dcl (msg            char (168)var,
227       code          fixed bin (35)) parm;
228 dcl mode            char (1);
229 dcl  i              fixed bin (24);
230 %include ted_support;
231  end ted_uppercase_;
232 
233 
234 Example:  a request to renumber a range of a buffer.
235 
236 ted_renumber_: proc (ted_support_p, msg, code);
237 
238 /* This routine renumbers the addressed portion of the buffer. It takes 1 or */
239 /*  2 arguments within a delimited string. The 1st argument is the beginning */
240 /*  number; the 2nd argument specifies the increment to use (assumes 10).    */
241 /*  Whatever follows the argument string will be left for further ted        */
242 /*  execution.                                                               */
243 
244 /* --- This is not robust code. It does not include exhaustive error         */
245 /* --- checking. It is intended only to show how to use the interface        */
246 /* --- stucture's various data.                                              */
247 
248 /* Usage: {1,$} |renumber /from,incr/                                        */
249 
250 dcl  msg char (168)var,                 /* error message text          (OUT) */
251      code fixed bin (35);               /* error code                  (OUT) */
252 
253     if (ted_support_version_2 ^= ted_support.version)
254     then do;                            /* make sure its correct version     */
255        code = error_table_$unimplemented_version;
256        return;                          /* can't handle this                 */
257     end;
258     if (inp.de = 0)
259     then do;                            /* must be some data to process      */
260        msg = "Buffer Empty.";
261        code = tederror_table_$Error_Msg;
262        return;
263     end;
264 /**** 1) Parse the arg list                                                  */
265     req.nc = req.cc;                    /* move back to current location     */
266     delim = rchr (req.nc);              /* save the delimiter char           */
267     if (delim = " ") | (delim = NL)
268     then do;
269        code = tederror_table_$No_Delim1;
270        return;
271     end;
272     req.nc = req.nc + 1;                /* skip over it                      */
273     i = verify (substr (rstr, req.nc), "0123456789") -1;
274     ln = fixed (substr (rstr, req.nc, i)); /* get starting line number       */
275     req.nc = req.nc + i;                /* skip over part used up            */
276     if (rchr (req.nc) = ",")
277     then do;                            /* 2nd arg is present                */
278        req.nc = req.nc + 1;             /* skip over the comma               */
279        i = verify (substr (rstr, req.nc), "0123456789") -1;
280        incr = fixed (substr (rstr, req.nc, i));  /* get increment            */
281        req.nc = req.nc + i;             /* skip over part used up            */
282     end;
283     else incr = 10;                     /* supply the default                */
284     if (rchr (req.nc) ^= delim)
285     then do;
286        msg = "Only 2 args allowed";
287        code = tederror_table_$Error_Msg;
288        return;
289     end;
290     req.nc = req.nc + 1;                /* leave "next" for continued        */
291                                         /*  execution of request line data   */
292 /**** 2) see if default address needed                                       */
293     if addr_ct = 0
294     then do;
295        inp.sb = 1;                      /* the default is 1,$                */
296        inp.se = inp.de;
297        out.de = 0;                      /* forget anything already done here */
298     end;
299 /**** 3) do all lines in address range                                       */
300     do while (inp.sb <= inp.se);
301        i = verify (substr (istr, inp.sb), "0123456789") -1;
302        inp.sb = inp.sb + i;             /* strip any existing line number    */
303        pic5 = ln;                       /* get display form of line number   */
304        substr (ostr, out.de+1, 5) = pic5;
305        out.de = out.de + 5;             /* place new number in output        */
306        i = index (substr (istr, inp.sb), NL); /* find line length            */
307        substr (ostr, out.de+1, i) = substr (istr, inp.sb, i);
308        out.de = out.de + i;             /* add in the line of data           */
309        inp.sb = inp.sb + i;             /* account for user-up input data    */
310        ln = ln + incr;                  /* move on to next number value      */
311     end;
312 /**** 4) tell ted its AOK                                                    */
313     code = tederror_table_$Copy_Set;
314 
315 dcl  i fixed bin (24);
316 dcl  delim char (1);                    /* arg list delimiter                */
317 dcl  ln fixed bin;                      /* line number value                 */
318 dcl  incr fixed bin;                    /* line number increment             */
319 dcl  pic5 pic "99999";                  /* display form of line number       */
320 dcl  NL char (1) int static options (constant) init ("
321 ");
322 %include ted_support;
323 
324 end ted_renumber_;
325 
326 
327 :Info: ted_ax_: ted_cx_: ted_ix_:
328 12/05/78 Speedtype input mode
329 [.] |ax
330    append LINES after addressed line
331 [.,.] |cx
332    change addressed lines, replacing with LINES
333 [.] |ix
334    insert LINES before addressed line
335 
336    LINES are read from user_input.  speedtype expansion is done on each
337    line.  End of input signal is \F.  Requests on line after this
338    request are executed after end of input is signalled.
339 
340 
341 
342 
343 
344 
345 
346 
347 
348 
349 
350 
351 :Info: ted_comment_:
352 08/03/82 Add comments
353 [.,.] |comment
354    add comments to addressed lines.  Each non-blank line is typed out
355    without a NL.  Then, whatever you type is added to the end of the
356    line.  However, the last two characters can be one of these control
357    sequences:
358     \d delete the displayed line
359     \F \f end of input (no data inserted)
360     \i insert next line typed, then examine for \a.
361     \a append next line typed, then examine for another \a.
362 
363 
364 
365 
366 
367 
368 
369 
370 
371 
372 
373 
374 :Info: ted_tabin_:
375 08/03/82 Process in HTs
376 [.,.] |tabin
377    convert spaces to HTs where possible.  Also, trailing white space is
378    removed from all lines.
379 
380 
381 :Info: ted_tabout_: ted_gtabout_: ted_vtabout_:
382 11/03/82 Process out pseudo-tabs
383 [.,.] |gtabout `RE`C,n,n...`
384    (global |tabout) convert pseudo-tab C to spaces on all lines which
385    match the expression RE.
386 [.,.] |vtabout `RE`C,n,n...`
387    (exclusive |tabout) convert pseudo-tab C to spaces on all lines
388    which do not match the expression RE.
389 [.,.] |tabout     `C,n,n...`
390    convert pseudo-tab C to spaces using tabstops defined by n,n,...
391    Tabstop specifications are of this form:
392        n - set text left
393        nL - set text left
394        nC - set text centered
395        nR - set text right
396     "n" represents the column where the character following the tab
397    character is to be placed.  It must be in the range 1 thru 200.
398 
399    When the left or center options are selected, they apply to the text
400    leading up to the tabstop.  The location of each tabstop in turn is
401    remembered.  Then when a left/center is called for, the data since
402    the last tabstop is involved.  The number of spaces needed is calcu-
403    lated; then if centering, half of this number is placed before the
404    data and the rest after.  Otherwise all the spaces are placed before
405    the data.
406 
407 
408 
409 
410 
411 
412 
413 
414 
415 
416 
417 
418 :Info: ted_dump_: ted_dumpl_: ted_dumps_: ted_dumpvs_:
419 08/03/82 Octal/alpha dumping
420 [.,.] |dumpl
421    dump (long) addressed string in octal and ASCII 20 across (needs 110
422    print positions)
423 [.,.] |dumps
424    dump (short) addressed string in octal and ASCII 10 across (needs 65
425    print positions)
426 [.,.] |dumpvs
427    dump (very-short) addressed string in octal and ASCII 5 across
428    (needs 39 print positions)
429 [.,.] |dump
430    dump addressed string in octal and ASCII using long, short, or
431    very-short depending on current linelength
432 
433 
434 
435 
436 
437 
438 
439 
440 
441 
442 
443 
444 :Info: ted_fiad_: ted_fina_:
445 11/03/82 Fill and adjust/no-adjust
446 [.,.] |fiad `STR`L,R{,I`
447    Fill the addressed data and adjust to make an even right margin.
448 [.,.] |fina `STR`L,R{,I`
449    Fill the addressed data without adjusting.
450 
451    STR is a string (NOT regular expression) and may be null.  If
452    non-null, each line which begins with that string will be left as-is
453    during the filling process.  The line will remain in place, that is,
454    filling does not span the line.
455 
456 
457    L is the left margin value, R is the right margin value, and I is
458    the optional indent value.  If I is not present, the value of L is
459    assumed.  The indent value is applied to all "first" lines.  The
460    most obvious "first" line is the line where processing begins.  Emp-
461    ty lines will always remain as empty lines.  Each text line after an
462    empty line is also considered to be a "first".  Thus a series of
463    paragraphs may be filled in a consistent manner.  Three paragraph
464    forms are available depending on the relationship of L and I:
465 
466       L=I L<I L>I
467      xxxx xxx xxxxx
468      xxxx xxxx xxxx
469      xxxx xxxx xxxx