home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / USCX / PGMUT-11.ZIP / DETAB.PAS < prev    next >
Pascal/Delphi Source File  |  1983-12-24  |  10KB  |  262 lines

  1. {$LINESIZE:130,$TITLE:'Detab  -  a file'}
  2. {$SYMTAB-}
  3. {$DEBUG-}
  4. {
  5. +*************************************************************+
  6. |                                                             |
  7. |                     D E T A B                               |
  8. |                                                             |
  9. |    This program removes tabs from a file.                   |
  10. |                                                             |
  11. |    This syntax is:                                          |
  12. |      DETAB FileName /T#                                     |
  13. |                                                             |
  14. |       # is the tab value; the default value is 8.           |
  15. |                                                             |
  16. |       FileName is the input file.                           |
  17. |       FileName may be a DOS 2.0 path name.                  |
  18. |       Output is directed to standard out.                   |
  19. |                                                             |
  20. |       Enterring just  DETAB as a command will cause         |
  21. |       output of this explanation.                           |
  22. |                                                             |
  23. +*************************************************************+
  24. |                  Copyright (c) 1983                         |
  25. |                    Ray Turner                               |
  26. |              Fountain Valley, California                    |
  27. |                                                             |
  28. |       Permission to copy for non-commercial use is          |
  29. |       freely granted and even encouraged.                   |
  30. |                                                             |
  31. +*************************************************************+
  32. }
  33. {
  34.  
  35.                         L I M I T A T I O N S
  36.  
  37.  
  38. The program currently requires that the file end with a CR to 
  39.  satisfy a READLN; else a Pascal runtime error will occur.
  40.  
  41.             ******************************************
  42.  
  43.                             N O T E S
  44.  
  45. The tab algorithm matches that of The Final Word; other editors
  46.  may  be different. This may be alterred in DeTabs. The algorithm is: 
  47.  
  48. Text following a tab begins in the column following the next tab
  49.  column, where tab columns are at n, 2n, 3n, ... if  n  is the
  50.  tab value enterred on the comand line. Thus col. 4 would contain
  51.  the text following a tab as the first character on a line.
  52.  
  53. This program uses a DOS interface package written in assembler,
  54.  which is also included. 
  55.  
  56.  
  57.             ******************************************
  58.  
  59. }
  60.  
  61. {$PAGE+}
  62. {
  63. +*************************************************************+
  64. |                                                             |
  65. |                          D E T A B                          |
  66. |                                                             |
  67. +*************************************************************+
  68. }
  69.  
  70. PROGRAM DETAB ( Input, Output );
  71.  
  72.  
  73. function GetNextArg(var SwitchType,Numeric:boolean;var SwitchChar:char;
  74.             var StringArg:lstring;var NumericArg:integer):boolean;external;
  75.             { returns next argument from command line }
  76.             { returns true if there was an argument }
  77.             { arguments are fields separated by spaces or a slash (/) }
  78. {            SwitchType      true if argument begins with a slash
  79.             Numeric         true if argument is an integer
  80.             SwitchChar      char following / for switch type args
  81.                                  (SwitchChar is folded to upper case)
  82.             StringArg       contains the ASCII argument (not the /)
  83.             NumericArg      contains the value of arg, if applicable
  84.  
  85.             double quotes ("...") must be used to enclose an arg 
  86.                 containing a space or slash (/). 
  87. }
  88.  
  89.  
  90. VAR
  91.  i          : integer;
  92.  ch         : char;
  93.  Tabs       : integer;        { tab stop value }
  94.  LineNum    : integer;             { current line number }
  95.  OutLine    : Lstring(255);    { De-tabbed string to output }
  96.  Line       : Lstring(132);    { string to hold lines being read in }
  97.  CommandError : boolean;
  98.  FileSpec   : Lstring(64);     { File specifier from command line }
  99.  InputFile  : text; 
  100.  
  101.  
  102. {*************************************************************}
  103. {                                                             }
  104. {             C O N V E R T  T A B S   to  S P A C E S        }
  105. {                                                             }
  106. {*************************************************************}
  107.  
  108.     PROCEDURE DeTabs (Tabval:integer;var InString,OutString:Lstring;
  109.                             limit:integer);
  110. {
  111.     DeTabs converts tab characters into the appropriate number of spaces
  112.     while moving the string from InString to OutString.
  113.    limit is the maximum length of OutString. 
  114.     TabVal is the number of columns between tab stops.
  115. }
  116.  
  117.         var nt,i,j,len  : integer;
  118.              ch,tab  : char;
  119.  
  120.         BEGIN
  121.             len := ord(InString.len);
  122.             tab := chr(9);            {horizontal tab char.}
  123.             j := 1;
  124.             OutString[0] := chr(0);        {init. string to null}
  125.  
  126.             for i := 1 to len do begin
  127.                 ch := InString[i];
  128.                 if ch = tab then begin 
  129.  
  130.                     { magic formula matching Final Word tabs }
  131.                     nt := Tabval - ( (j - 1) MOD Tabval);
  132.  
  133.                     while nt > 0 do begin
  134.                         concat (OutString,' ');
  135.                         j := j + 1;
  136.                         if j >= limit then BREAK;
  137.                         nt := nt - 1
  138.                     end;   {while}
  139.                 end
  140.                 else { not a tab char } begin
  141.                     j := j + 1;
  142.                     if j >= limit then BREAK;
  143.                     concat(OutString,ch)
  144.                 end {if}
  145.             end; {for}
  146.         END;     {DeTab}
  147.  
  148. {$page+,$subtitle:'directions'}
  149.  
  150.  PROCEDURE PrintDirections;  { print directions if no args given }
  151.    begin
  152.  
  153. writeln('+----------------------------------------------------------+');
  154. writeln('|                                                          |');
  155. writeln('|                     D E T A B                            |');
  156. writeln('|                                                          |');
  157. writeln('|    This program expands tabs into spaces.                |');
  158. writeln('|                                                          |');
  159. writeln('|    This syntax is:                                       |');
  160. writeln('|      DETAB FileName /T#                                  |');
  161. writeln('|                                                          |');
  162. writeln('|      # is the tab value; the default is 8.               |');
  163. writeln('|                                                          |');
  164. writeln('|       FileName is the input file.                        |');
  165. writeln('|       FileName may be a DOS 2.0 path name.               |');
  166. writeln('|       Output is to standard output.                      |');
  167. writeln('|                                                          |');
  168. writeln('+----------------------------------------------------------+');
  169. writeln('|                  Copyright (c) 1983                      |');
  170. writeln('|                    Ray Turner                            |');
  171. writeln('|              Fountain Valley, California                 |');
  172. writeln('+----------------------------------------------------------+');
  173. writeln;
  174. CommandError := TRUE; { to stop any attemp at processing }
  175. END;
  176.  
  177.  
  178.  
  179. PROCEDURE Asciiz (var str:lstring);        {add a null byte to end of string}
  180. begin
  181.     concat(str,chr(0));
  182. end;
  183.  
  184.  
  185. PROCEDURE MoveUntil (var ToString:lstring;var FromString:lstring;
  186.                             Fstart:integer;ch:char;limit:integer);
  187.      {move chars from one string to another until a 
  188.                                 spec'd char is encountered.}
  189.      {chars are concatenated onto ToString from FromString[Fstart]. 
  190.      Limit sets a max on scan. 
  191.       FromString is VAR just for efficiency sake.}
  192.  
  193. var i,count : integer;
  194. begin
  195.     count := scaneq(limit,ch,FromString,Fstart); { = # chars. skipped }
  196.     for i := 0 to (count - 1) do
  197.         concat(ToString,FromString[Fstart + i]);
  198. end;
  199.  
  200.  
  201.  
  202. {$PAGE+,$SUBTITLE:'Process Command Line'}
  203. {
  204. ***************************************************************
  205. |                                                             |
  206. |                  C O M M A N D S                            |
  207. |                                                             |
  208. |   This procedure retrieves the parameters passed to DETAB   |
  209. |   from the user command line and interprets them.           |
  210. |                                                             |
  211. ***************************************************************
  212. }
  213.  
  214. PROCEDURE Commands;
  215.  
  216. VAR
  217.     SwitchType,Numeric : boolean;
  218.     SwitchChar : char;
  219.     StringArg : Lstring(80);
  220.     NumericArg : integer;
  221.  
  222.  
  223. BEGIN                                         {COMMANDS}
  224.       CommandError := FALSE;
  225.  
  226.     if not GetNextArg(SwitchType,Numeric,SwitchChar,FileSpec,NumericArg)
  227.         then { null command line } PrintDirections
  228.     else if SwitchType then begin
  229.         CommandError := true;
  230.         writeln('Missing, misplaced, or invalid File Specifier');
  231.     end else begin { get tab # arg if any }
  232.       if GetNextArg(SwitchType,Numeric,SwitchChar,StringArg,NumericArg)
  233.             then Tabs := NumericArg
  234.         else Tabs := 8; 
  235.     end; {else}
  236. END;          { Commands }
  237.  
  238. {$PAGE+,$subtitle:'Main Program'}
  239.  
  240. {*************************************************************}
  241. {                                                             }
  242. {                  T H E   P R O G R A M                      }
  243. {                                                             }
  244. {*************************************************************}
  245.  
  246. BEGIN
  247.     Commands;            { read and interpret command line }
  248.     if not CommandError then begin { detab the stuff }
  249.         LineNum := 0;
  250.         assign(InputFile,FileSpec);
  251.         reset(InputFile);
  252.  
  253.         While not eof(InputFile) do begin
  254.             readln(InputFile,Line);
  255.             LineNum := LineNum +1;
  256.             DeTabs(Tabs,Line,OutLine,250);        {convert tabs to blanks}
  257.             writeln(OutLine);
  258.         end;
  259.     end; { if }
  260.  
  261. END.
  262.