(*   This simple text editor program reads a preconnected file of characters,
interprets certain control characters, and echoes the input to the default
OUTPUT file.  It also reports the number of times each capital letter occurs.

The program recognizes the following control characters:
        () ignore all enclosed characters
        *  start a new output line
        /  exchange preceding and following characters
        +  delete preceding character

Variables - 
   LParen, RParen, Asterisk, Slash, Plus - control character constants
   Ch - character variable to hold input character
   TempCh - temporary character variable used for output character
   CharInput - input file of characters which is preconnected
   NewLine - boolean variable to determine when a new line is needed
   CapitalLetter - character set of capitol letters of the alphabet
   CapCount - integer array to hold the count of each letter
   Edit - set of editing control characters       *)

program TextEdit(CharInput,Output);

const  LParen = '(';  Rparen = ')';
       Asterisk = '*';  Slash = '/';
       Plus = '+';

var    Ch,TempCh : char;
       CharInput : text;
       NewLine : boolean;
       CapitalLetter : set of 'A'..'Z';
       CapCount : array['A'..'Z'] of integer;
       Edit : set of Lparen..Slash;

begin 
    CapitalLetter := ['A'..'Z'];             (* perform initialization *)
    Edit := ['(','+','*','/']; 
    for Ch := 'A' to 'Z' do CapCount[Ch] := 0;
    reset(CharInput);   
    TempCh := '*';      

    while not eof(CharInput) do begin
        read(CharInput,Ch);           (* input a character *)
        if [Ch] * CapitalLetter <> [] then CapCount[Ch] := CapCount[Ch] + 1;
        if [Ch] * Edit <> [] then
            case Ch of                    (* action for control characters *)
                LParen : begin                (* ignore embedded text *)
                    repeat read(CharInput,Ch) until Ch = RParen;
                    read(CharInput,Ch)
                    end;
                Asterisk : NewLine := true;    (* flag a new line *)
                Plus : read(CharInput,TempCh); (* delete preceding character *)
                Slash : begin                  (* perform character exchange *)
                    Ch := TempCh;
                    read(CharInput,TempCh);
                    end
            end;(* case *)
        if [TempCh] * Edit = [] then write(TempCh);
        if NewLine then begin
            writeln;
            NewLine := false
            end; (* if *)
        TempCh := Ch                (* assign output character for next loop *)
        end; (* while *)

    writeln(TempCh); writeln;         (* write out last character *)
    for Ch := 'A' to 'Z' do write(Ch : 3,CapCount[Ch] : 2);
    writeln
end. (* TextEdit *)
