program wsutil;

{WordStar file utility  --  3-27-85 Ver B5   }
{Copyright 1985 by David W. Carroll          }
{                                            }
{Converts WordStar files to ASCII text files }
{with options.                               }

{Written for Turbo Pascal Corner column in
 Micro/Systems Journal, May/June 1985 }

const
   nummax      = 200;   {Maximum input line length}

   version     = 'B5';
   date        = 'March 27, 1985';

   null        = 00;
   bell        = 07;
   lf          = 10;
   ff          = 12;
   cr          = 13;
   nobrksp     = 15;   {no break space ^O}
   softhyph1   = 30;   {mid-text soft hyphen}
   softhyph2   = 31;   {eol soft hyphen}
   space       = 32;
   hyph        = 45;
   period      = 46;
   softlf      = 138;  {soft line feed}
   softcr      = 141;  {soft carriage return}
   softsp      = 160;  {soft space}

   ctlb        = 02;
   ctld        = 04;
   ctls        = 19;
   ctlt        = 20;
   ctlv        = 22;

{ arrays pcon and pcoff contain the strings that are  }
{ substituted for WordStar print control characters   }
{ ^b, ^d, ^s, ^t, and ^v. Constant pc is the total    }
{ number of WS print control characters supported.    }

   pc          = 05;
   spc:   array[1..pc] of byte = (ctlb, ctld, ctls, ctlt, ctlv);
   pcon:  array[1..pc] of string[10] =
            ('[bf]','[ds]','[us]','[sup]','[sub]');
   pcoff: array[1..pc] of string[10] =
            ('[ebf]','[eds]','[eus]','[esup]','[esub]');

var
   infile       :  text;
   outfile      :  text;
   numlist      :  array[1..nummax] of byte;
   flagpc       :  array[1..pc] of boolean;
   totchrin     :  real;
   totchrout    :  real;
   cnt          :  integer;
   quit         :  boolean;
   stripsp      :  boolean;
   striplf      :  boolean;
   chgpc        :  boolean;
   stripdc      :  boolean;
   strippc      :  boolean;
   translt      :  boolean;

procedure open_files;
var
   infname      :  string[20];
   outfname     :  string[20];
   ans          :  string[10];
   goodfile     :  boolean;

begin
     window (1,5,80,25);
     repeat
        ClrScr;
        write ('Input filename  -->  ');
        readln (infname);
        assign(infile,infname);
        {$I-} reset(infile) {$I+};
        goodfile := (IOresult = 0);
        if not goodfile then
        begin
          write (chr(bell));
          writeln ('FILE ',infname,' NOT FOUND');
          delay(3000)
        end;
     until goodfile;
     window (1,6,80,25);
     repeat
        ClrScr;
        write ('Output filename -->  ');
        readln (outfname);
        assign (outfile,outfname);
        {$I-} reset(outfile) {$I+};
        goodfile := (IOresult <> 0);
        if not goodfile then
        begin
          write (chr(bell));
          write ('FILE ',outfname,' EXISTS, OVERWRITE? (y/n) ');
          readln (ans);
          goodfile := (UpCase(ans[1])='Y')
        end;
     until goodfile;
     rewrite(outfile)
end;

procedure get_line;
var
   ch    : char;
   num   : byte;
   lonum : byte;

begin
  ch:=chr(0);
  lonum:=0;
  num:=0;
  cnt:=0;

  while not eof(infile) and (lonum<>lf) do
  begin
    cnt:=cnt+1;
    read(infile,ch);
    totchrin := totchrin + 1;
    num:=ord(ch);
    lonum:=(num and 127);
    numlist[cnt]:=num;
  end
end;

procedure test_line;
begin
     translt := true;
     if stripdc then
       if numlist[1]=period then translt := false;
end;

procedure translate_line;
var
   spstr  :  string[10];
   indx1  :  integer;
   indx2  :  integer;
   indx3  :  integer;
   num    :  byte;
   chnum  :  byte;
   lonum  :  byte;
   exch   :  boolean;

begin
  for indx1:=1 to cnt do
  begin
    exch := false;
    num:=numlist[indx1];
    chnum := num and 127;
    lonum :=chnum;

    if (num=softhyph2) then
       chnum := hyph
    else if (num=softhyph1) then
       chnum := null;

    if num=nobrksp then chnum := space;

    if chgpc then
    begin
      for indx2:=1 to pc do
      begin
        if lonum = spc[indx2] then
        begin
          chnum := null;
          exch := true;
          if flagpc[indx2] then
            spstr := pcoff[indx2]
          else
            spstr := pcon[indx2];
          flagpc[indx2] := not flagpc[indx2]
        end
      end
    end;

    if stripsp and (num=softsp) then chnum := null;
    if striplf and (lonum=lf) then chnum := null;

    if strippc then
      for indx3 := 1 to pc do
        if lonum = spc[indx3] then chnum := null;

    if chnum <> null then
    begin
      write (outfile, chr(chnum));
      totchrout := totchrout+1
    end;
    if exch then
    begin
      write(outfile,spstr);
      totchrout := totchrout + length(spstr)
    end
  end
end;

function inyn : boolean;
var
  ans  : string[10];

begin
  write('[y/n] ');
  readln(ans);
  inyn := (Upcase(ans[1]) = 'Y')
end;

procedure menu;
begin
      writeln;
      writeln('Wordstar to ASCII Conversion');
      writeln;
      writeln;
      write(' 1.  Strip soft-spaces (un-justify)?   ');
      stripsp := inyn;
      write(' 2.  Strip line feeds?                 ');
      striplf := inyn;
      write(' 3.  Change control (print) commands?  ');
      chgpc   := inyn;
      write(' 4.  Strip dot commands?               ');
      stripdc := inyn;
      if chgpc = false then
      begin
        write(' 5.  Strip print commands?             ');
        strippc := inyn;
      end
      else
        strippc := false;
      writeln;
      write(' Quit?                                 ');
      quit := inyn;
end;

procedure process;
var
   line  :  integer;
   indx  :  integer;

begin
     window(1,7,80,25);
     ClrScr;
     line:=0;
     totchrin:=0;
     totchrout:=0;

     for indx :=1 to pc do
       flagpc[indx] := false;

     while not eof(infile) do
     begin
        line:=line+1;
        get_line;
        test_line;
        if translt then
          begin
            translate_line;
            window(1,12,80,16);
            ClrScr;
            writeln('Line # ',line:5);
            writeln('Total characters input:    ',totchrin:6:0);
            writeln('Total characters output:   ',totchrout:6:0);
            writeln('Total filtered(+)/added(-):',(totchrin-totchrout):6:0);
          end
     end
end;

procedure exit;
begin
     window(1,23,80,25);
     ClrScr;
     writeln('Translation completed!');
     writeln(outfile);
     close(infile);
     close(outfile)
end;

begin
     ClrScr;
     writeln;
     writeln('WordStar File Conversion Program');
     writeln('Copyright 1985 by David W. Carroll');
     writeln('Version #',version,' of ',date,'.');
     writeln;
     window(1,5,80,25);
     ClrScr;
     menu;
     ClrScr;
     if not quit then
     begin
       open_files;
       process;
       exit
     end
     else
       writeln('Translation cancelled.');
end.
