      PROGRAM EDITOR
************************************************************************
* Program to perform some basic text-editing functions on lines of     *
* text.  The basic operation is replacing a substring of the text      *
* with another string.  This replacement is accomplished by a command  *
* of the form                                                          *
*                    oldstring/newstring/                              *
* where oldstring specifies the substring in the text to be replaced   *
* with newstring; newstring may be an empty string, which then causes  *
* oldstring (if found) to be deleted.  The text lines are read from a  *
* file, and after editing, the edited lines are written to another     *
* file.  Identifiers used are:                                         *
*     OLDFIL  : name of the input file                                 *
*     NEWFIL  : name of the output file                                *
*     EOF     : end-of-file indicator                                  *
*     TEXT    : a character string representing a line of text         *
*     LENGTH  : length of text line                                    *
*     CHANGE  : a character string specifying the edit operation       *
*               Value is of the form:                                  *
*                         'oldstring/newstring/'                       *
*     RESPON  : user response (Y or N)                                 *
*                                                                      *
* Input (keyboard):  OLDFIL, NEWFIL, TEXT, CHANGE, RESPON              *
* Output (screen):   User prompts, TEXT                                *
* Input (file):      Lines of text                                     *
* Output (file):     Edited lines of text                              *
************************************************************************

      INTEGER LENGTH, EOF
      PARAMETER (LENGTH = 80)
      CHARACTER*(LENGTH) TEXT, CHANGE, OLDFIL*20, NEWFIL*20, RESPON*1

      PRINT *, 'ENTER THE NAME OF THE INPUT FILE'
      READ '(A)', OLDFIL
      PRINT *, 'ENTER THE NAME OF THE OUTPUT FILE'
      READ '(A)', NEWFIL
      OPEN (UNIT = 15, FILE = OLDFIL, STATUS = 'OLD')
      OPEN (UNIT = 16, FILE = NEWFIL, STATUS = 'NEW')

* While there is more data, read a line of text and edit it.
      READ (15, '(A)', IOSTAT = EOF) TEXT
10    IF (EOF .GE. 0) THEN
          PRINT *, TEXT
          PRINT *, 'EDIT THIS LINE (Y OR N)?'
          READ '(A)', RESPON

*         While RESPON <> 'N', get editing change, modify the
*         line of text, and display the edited line.
20        IF (RESPON .NE. 'N') THEN
               PRINT *, 'ENTER EDIT CHANGE'
               READ '(A)', CHANGE
               CALL EDIT(TEXT, CHANGE)
               PRINT *, TEXT
               PRINT *, 'MORE EDITING (Y OR N)'
               READ '(A)', RESPON
          GO TO 20
          END IF

          WRITE (16, '(A)') TEXT
          PRINT *
          READ (15, '(A)', IOSTAT = EOF) TEXT
      GO TO 10
      END IF

      CLOSE(15)
      CLOSE(16)
      END

**EDIT******************************************************************
* Subroutine to edit a line of TEXT by replacing a substring of the    *
* text by another string as specified by the command CHANGE, which has *
* the form                                                             *
*                    oldstring/newstring/                              *
* newstring (which may be empty) replaces the first occurrence of      *
* oldstring in TEXT.  Local identifiers used are:                      *
*     TXTEND  : last part of edited text                               *
*     SLASH1  : position of first slash (/) in CHANGE                  *
*     SLASH2  : position of second slash (/) in CHANGE                 *
*     OLDSTR  : old string -- to be replaced                           *
*     OLDLEN  : actual length of OLDSTR                                *
*     NEWSTR  : new replacement string                                 *
*     NEWLEN  : actual length of NEWSTR                                *
*     INDOLD  : index of old string in TEXT                            *
*                                                                      *
* Accepts:  TEXT, CHANGE                                               *
* Returns:  TEXT (modified)                                            *
************************************************************************

      SUBROUTINE EDIT(TEXT, CHANGE)

      INTEGER LENGTH, SLASH1, SLASH2, OLDLEN, NEWLEN, INDOLD 
      PARAMETER (LENGTH = 80)
      CHARACTER*(LENGTH) TEXT, CHANGE, OLDSTR, NEWSTR, TXTEND  
 
* Attempt to locate slash delimiters in CHANGE     
      SLASH1 = INDEX(CHANGE, '/')
      SLASH2 = SLASH1 + INDEX(CHANGE(SLASH1 + 1 : ), '/')
      IF (SLASH1 .LT. 0 .OR. SLASH2 .EQ. SLASH1) THEN
          PRINT *, 'MISSING SLASH'
          RETURN
      END IF

* Slashes were found, so continue with editing
* First extract OLDSTR and NEWSTR from CHANGE, and locate
* OLDSTR in TEXT.

      OLDLEN = SLASH1 - 1
      OLDSTR = CHANGE( : OLDLEN)
      NEWLEN = SLASH2 - SLASH1 - 1
      NEWSTR = CHANGE(SLASH1 + 1: SLASH2 - 1)
      INDOLD = INDEX(TEXT, OLDSTR( : OLDLEN))
      IF (INDOLD .GT. 0) THEN

*         Append text following OLDSTR to NEWSTR.
          TXTEND = NEWSTR( :NEWLEN) // TEXT(INDOLD + OLDLEN : )

*         Prepend text preceding OLDSTR (if any) to form edited TEXT.
          IF (INDOLD .EQ. 1) THEN
              TEXT = TXTEND 
          ELSE
              TEXT = TEXT( : INDOLD - 1) // TXTEND 
          END IF
      END IF

      END
