A Simple Text Editor

Osvaldo Ramirez

You can use this line-oriented Editor for simple word processing, or even to edit BASIC programs stored with the LIST "D:" command.

This program is a modification of Arnie Lee's and Steve Gradigan's text editor published in COMPUTE!, issues no. 9 and 20. The original program was written for the PET machine. This modification is for the Atari 800 and will work with an Epson MX 80 F/T printer with the Graftrax option. The program itself requires 9676 bytes, but goes up to 31865 bytes once the buffer is initiated. The buffer accommodates five pages of 54 lines each, 80 characters per line. Two extra lines were added for string manipulations. Each page requires 4405 bytes. This amount may be reduced for machines with less memory by changing the DIM statement in line 20 and the string clearing routine in line 30. The translation was accomplished using Charles Brannon's suggestions in COMPUTE!, issue no. 16 and Teri Li's in Byte of January 1981.

I added a few extra routines that enhance an already useful program. Each function now has its own screen. In addition to the bell warning that there are five spaces left to fill the input string, there are now five reverse video spaces to be overwritten so that the user has visual control of the spaces left for proper hyphenation, when needed. If the string length (the M value) exceeds 76, a new line will be displayed on the TV. It will not affect the buffer or the printing.

A new line exchange function and a block move of lines were added. These two new routines increase editing flexibility. They can be accessed with the B and the E commands, respectively.

The loading function will automatically append to whatever program is resident in the machine's memory if it is not deleted before loading the new text.

The printing routine formats to 54 lines per page and exits printing with a top of form command. It will number pages automatically at the top, with right justification starting at the second page while retaining the 54 line format. It stops at the end of each page and prompts the user to continue when ready. This feature allows for the insertion of a new page if you are using cut paper instead of fanfold. The printer will respond to the Atari control characters, allowing for different fonts in the same line.

The string change function will accept from one line up to the entire document for search and substitution. It will display on the screen the line selected or the first line of the block of lines to search. The program takes about two minutes to scan each page.

The program was renumbered to maintain the same routine locations as in the original listing of Lee and Gradijan. This way you can refer to their original articles for documentation. The renumber was done using one of the utility programs from the Atari Program Exchange.

When keying in this program, remember the five reverse video characters in line 10100, the five left arrow characters in line 10080, and one down arrow in line 21010 right after the colon.

PROGRAM. A Simple Text Editor For The Atari

10 REM -A SIMPLE TEXT EDITOR FOR ATARI
11 REM BY O. RAMIREZ - MARCH 1982
12 REM ORIGINAL PROGRAMS BY A. LEE AND S. GRAD IJAN
13 REM COMPUTE #9 AND #20
20 DIM T$(21760), L$(80), B$(80), A$(13)
30 T$(1) = " " : T$(21760) = " " : T$(2) = T$
40 DIM DM$(2), FR$(80), TS$(80)
50 L$(1) = " " : L$(80) = " " : L$(2) = L$
60 DIM FI$(12), NL$(80), F$(2)
70 OPEN #1, 4, 0, "K :"
80 POKE 82, 0
90 LL = 1 : M = 79
100 A$ = "ABCDEFILMPQRS"
110 ? "{CLEAR} {10 SPACES} SOFTWARE LINE EDITOR"
120 ? : ? : ? "FUNCTIONS :"
130 ?
140 POKE 85, 10 : ? "A.append to end of text/start"
150 POKE 85, 15 : ? "@ = 5 space tab"
160 POKE 85, 15 : ? "@ + RETURN = skip a line"
170 POKE 85, 10 : ? "B.block move"
180 POKE 85, 10 : ? "C.change string"
190 POKE 85, 10 : ? "D.delete a line"
200 POKE 85, 10 : ? "E.exchange lines"
210 POKE 85, 10 : ? "F.filer commands"
220 POKE 85, 10 : ? "I.insert before line"
230 POKE 85, 10 : ? "L.list line(s)"
240 POKE 85, 10 : ? "M.menu display"
250 POKE 85, 10 : ? "P.print lines"
260 POKE 85, 10 : ? "Q.quit editor"
270 POKE 85, 10 : ? "R.replace a line"
280 POKE 85, 10 : ? "S.set margins"
290 ? : ?
300 B = 0 : ? "ENTER SELECTION -- > ";
310 GOTO 330
320 TRAP 40000 : ? : ? "ENTER : A, B, C, D, E, F, I, L, P, Q, R, S, M - > ";
330 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 330
340 J = 0 : FOR I = 1 TO 13 : IF A$(I, I) = B$(1, 1) THEN J = I
350 NEXT I : I = 13
360 ? B$
370 IF J = 0 THEN 320
380 ON J GOTO 1000, 12000, 2000, 3000, 11000, 4000, 5000, 6000, 110, 9000, 8000, 7000, 21000
1000 ? "{CLEAR} APPEND TO END OF TEXT OR STAR T"
1010 ? LL;" > "
1020 GOSUB 10000
1030 IF LEN(L$) = 0 THEN 320
1040 T$((LL * 80) - 79, (LL * 80)) = L$
1050 LL = LL + 1
1060 GOTO 1010
2000 ? "{CLEAR}CHANGE "; : GOSUB 16000
2010 IF HI = 0 THEN 320
2020 J2 = L0
2030 ? "CHANGE STRINGS - > " : ? J2; " > "; T$(J2 * 80 - 79, J2 * 80 - 80 + M) : GOSUB 10000
2040 L = LEN(L$)
2050 IF L = 0 THEN 320
2060 IF L < 4 THEN 2000
2070 DM$ = L$(1, 1)
2080 IF L$(LEN(L$))< >DM$ THEN ? "* WRONG, TRY AGAIN" : FOR I = 1 TO 200 : NEXT I : GOTO 2000
2090 J = 0 : FOR I = 2 TO L - 1
2100 IF L$(I, I) = DM$ THEN J = I
2110 NEXT I
2120 IF J = 0 THEN 2000
2130 IF J = 2 THEN 2000
2140 FR$ = L$(2, J - 1)
2150 IF J + 1 = L THEN TS$ = " " : GOTO 2170
2160 TS$ = L$(J + 1, L - 1)
2170 F = LEN(FR$)
2180 POP : FOR I = LO TO HI
2190 T = M : S = 1 : NL$ = " "
2200 FOR J = 1 TO T - F + 1
2210 IF T$(I * 80 - 80 + J, I * 80 - 80 + J + F - 1)< >FR$ THEN 2250
2220 IF J = 1 THEN NL$ = TS$ : GOTO 2240
2230 NL$(LEN(NL$) + 1) = T$(I * 80 - 80 + S, I * 80 - 80 + J - 1) : NL$(LEN(NL$) + 1) = TS$
2240 S = J + F
2250 NEXT J
2260 IF S< >1 THEN NL$(LEN(NL$) + 1) = T$(I * 80 - 80 + S, I * 80 - 80 + M + 1) : T$(I * 80 - 79, I * 80) = T$((LL + 1) * 80 - 79, (LL + 1) * 80)
2265 T$(I * 80 - 79, I * 80) = NL$
2270 NEXT I
2280 GOTO 320
3000 ? "{CLEAR}DELETE "; : GOSUB 16000
3010 IF DF = 0 THEN 3060
3020 ? "DELETE THE ENTIRE FILE?(Y/N)";
3030 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 3030
3040 ? B$ : IF B$ = "N" THEN 320
3050 IF B$< >"Y" THEN 3020
3060 IF HI > LL - 1 THEN 320
3070 IF HI = LL - 1 THEN TRAP 320 : T$'HI * 80 - 79, HI * 80) = T$((LL + 1) * 80 - 79, (LL + 1) * 80) : LL = L0 : GOTO 320
3080 J = HI - LO + 1
3090 FOR I = LO TO LL + 1
3100 T$(I * 80 - 79, I * 80) = T$((I + J) * 80 - 79, (I + J) * 80)
3110 NEXT I
3120 LL = LL - (HI - LO) - 1
3130 GOTO 320
4000 ? "{CLEAR}FILE COMMANDS : ENTER L = LOAD, S - SAVE - > ";
4010 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 4010
4020 IF B$ = CHR$(155) THEN ? " " : GOTO 320
4030 IF B$< >"L" AND B$< >"S" THEN ? : GOTO 4000
4040 ? B$ : F$ = B$
4045 ? : ? : POKE 85, 10 : ? "INSERT STORAGE DISK" : ? : ?
4050 POKE 85, 20 : ? " | --------.--- |"
4060 POKE 85, 5 : ? "ENTER FILENAME - > ";
4070 GOSUB 10000
4080 IF LEN(L$) = 0 THEN 320
4090 IF LEN(L$) > 12 THEN ? "USE LESS THAN 12 CHARACTERS" : GOTO 4050
4100 FI$ = L$
4110 B$ = "D :"
4120 B$(LEN(B$) + 1) = FI$
4130 IF F$ = "L" THEN 4210
4140 IF LL = 1 THEN ? "NO FILE TO SAVE" : GOTO 320
4150 CLOSE #3 : OPEN #3, 8, 0, B$
4160 FOR I = 1 TO LL - 1
4170 ? #3; T$(I * 80 - 79, I * 80)
4180 NEXT I
4190 CLOSE #3 : ? : ? FI$; " SAVED"
4200 GOTO 320
4210 CLOSE #3 : TRAP 4280 : OPEN #3, 4, 0, B$
4220 IF LL > 1 THEN LL = LL - 1 : GOTO 4230
4225 LL = 0
4230 LL = LL + 1 : T$(LL * 80 - 79, LL * 80) = " "
4240 L$ = " "
4250 TRAP 4270 : INPUT #3;L$ : T$(LL * 80 - 79, LL * 80) = L$
4260 GOTO 4230
4270 TRAP 40000 : CLOSE #3 : GOTO 320
4280 CLOSE #3 : TRAP 40000 : ? "FILE NOT ON DISK" : GOTO 320
5000 ? "{CLEAR}INSERT BEFORE "; : GOSUB 17000
5010 IF L0 > LL OR L0 < 1 THEN 5000
5020 ? : ? LO; " > ";
5030 GOSUB 10000
5040 IF LEN(L$) = 0 THEN 320
5050 LL = LL + 1
5060 FOR I = LL TO LO STEP -1
5070 IF I = 1 THEN 5090
5080 T$(I * 80 - 79, I * 80) = T$((I - 1) * 80 - 79, (I - 1) * 80)
5090 NEXT I
5100 T$(LO * 80 - 79, LO * 80) = T$((LL + 2) * 80 - 79, (LL + 2) * 80)
5110 T$(LO * 80 - 79, LO * 80 - 80 + M) = L$
5120 LO = LO + 1
5130 GOTO 5020
6000 ? "{CLEAR}LIST" ; : GOSUB 16000
6010 IF HI = 0 THEN 320
6020 FOR J = LO TO HI
6030 ? J; " > "; T$(J * 80 - 79, J * 80 - 80 + M)
6040 IF J / 10 = INT(J / 10) THEN POSITION 3, 23 : ? "HIT E TO END, RETURN TO CONTINUE– > "; : GET #1, B : ? CHR$(B) : IF B = 69 THEN 320
6050 NEXT J
6060 GOTO 320
7000 ? "{CLEAR}REPLACE "; : GOSUB 17000
7010 IF LO >= LL OR LO < 1 THEN 7000
7020 ? "LINE TO REPLACE : "
7030 ? LO; " > "; T$(LO * 80 - 79, LO * 80)
7040 ? : ? LO; " > ";
7050 GOSUB 10000
7060 IF LEN(L$) = 0 THEN 320
7080 T$(LO * 80 - 79, LO * 80) = T$((LL + 1) * 80 - 79, (LL + 1) * 80)
7090 T$(LO * 80 - 79, LO * 80) = L$
7100 GOTO 320
8000 ? "{CLEAR}" : POSITION 4, 10 : ? "LEAVE EDIT OR : ARE YOU SURE? (Y/N)";
8010 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 8010
8020 IF B$< >"Y" AND B$< >"N" THEN 8000
8030 IF B$ = "N" THEN ? : ? : ? : ? : ? : GOTO 320
8040 POKE 752, 1 : POSITION 9, 12 : ? CHR$(253); "END OF EDITOR PROGRAM. . ." : FOR I = 1 TO 200 : NEXT I : GRAPHICS 0 : END
9000 CLOSE #2 : TRAP 9200 : OPEN #2, 8, 0, "P : "
9010 ? "{CLEAR}PRINT "; : GOSUB 16000
9020 ? "NUMBER OF SPACES BETWEEN LINES(1 - 2)"; : INPUT S1
9030 ? "IF THIS IS THE FIRST PAGE ENTER 1"
9040 ? "OTHERWISE ENTER APPROPIATE NO. . . ."; : INPUT PP
9050 IF HI = 0 THEN 320
9060 CT = 0
9070 ? #2; CHR$(27); "D"; CHR$(SP); CHR$(0)
9080 FOR I = LO TO HI
9090 ? #2; CHR$(137); T$(I * 80 - 79, I * 80 - 80 + M)
9100 CT = CT + 1
9110 IF S1 = 2 THEN ? #2 : CT = CT + 1
9120 IF CT / 54 = INT(CT / 54) THEN GOSUB 23000
9130 NEXT I
9140 ? #2; CHR$(12)
9150 CLOSE #2 : GOTO 320
9200 ? : ? : POKE 85, 10 : ? "TURN PRINTER ON" : TRAP 40000 : GOTO 320
10000 L$ = " "
10010 REM
10020 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 10020
10030 IF B$ = CHR$(155) THEN POKE 752, 0 : ? : RETURN
10040 IF B$ = CHR$(126) THEN L$(LEN(L$)) = " " : ? B$; : GOTO 10110
10050 IF B$ = " " THEN B$ = "{5 SPACES}"
10060 IF LEN(L$) = M - 6 THEN ? CHR$(253);
10070 IF LEN(L$) = M THEN POKE 752, 0 : GOTO 10120
10080 IF LEN(L$) = M - 5 THEN ? "{5 LEFT}";
10090 L$(LEN(L$) + 1) = B$ : ? B$;
10100 IF LEN(L$) = M - 5 THEN POKE 752, 1 : ? "{5 SPACES}";
10110 GOTO 10010
10120 ? "ERROR-LINE TUNCATED" : RETURN
11000 ? "EXCHANGE LINES"
11010 ? "ENTER LOWER NUMBER FIRST"
11030 ? "ENTER "; : GOSUB 16000
11040 IF L = 0 THEN 320
11060 TS$ = " " : TS$ = T$(LO * 80 - 79, LO * 80)
11070 T$(LO * 80 - 79, LO * 80) = T$(HI * 80 - 79, HI * 80)
11080 T$(HI * 80 - 79, HI * 80) = " "
11090 T$(HI * 80 - 79, HI * 80) = TS$ : TS$ = " "
11100 ? LO; " > "; T$(LO * 80 - 79, LO * 80)
11110 ? : ? HI; " > "; T$(HI * 80 - 79, HI * 80)
11120 GOTO 320
12000 ? "{CLEAR} MOVE A BLOCK OF LINES"
12010 ? "INSERT BEFORE LINE NO.- > "; : INPUT B$ : IF LEN(B$) = 0 THEN 320
12015 A = VAL(B$) : B$ = " "
12020 ? : ? "BLOCK TO MOVE "; : GOSUB 16000
12030 IF LO = A THEN 12000
12040 CTR = 0
12050 IF LO < A THEN 12200
12060 IF HI > LL -1 THEN 320
12080 I = 0 : FOR I = LL + 1 TO A STEP -1
12090 T$(I * 80 - 79, I * 80) = T$((I - 1) * 80 - 79, (I - 1) * 80)
12100 NEXT I
12110 T$(A * 80 - 79, A * 80) = T$((HI + 1) * 80 - 79, (HI + 1) * 80)
12120 I = 0 : FOR I = HI + 1 TO LL + 1
12130 T$(I * 80 - 79, I * 80) = T$((I + 1) * 80 - 79, (I + 1) * 80)
12140 NEXT I
12160 CTR = CTR + 1
12170 IF CTR = HI - LO + 1 THEN 320
12180 GOTO 12080
12200 I = 0 : FOR I = LL + 1 TO A STEP -1
12210 T$(I * 80 - 79, I * 80) = T$((I - 1) * 80 - 79, (I - 1) * 80)
12220 NEXT I
12230 T$(A * 80 - 79, A * 80) = T$(LO * 80 - 79, LO * 80)
12240 I = 0 : FOR I = LO TO LL + 1
12250 T$(I * 80 - 79, I * 80) = T$((I + 1) * 80 - 79, (I + 1) * 80)
12260 NEXT I
12280 CTR = CTR + 1
12290 IF CTR = HI - LO + 1 THEN 320
12300 GOTO 12200
16000 ? "RANGE(LOW - HIGH) = > ";
16010 GOSUB 10000
16020 LO = 1 : HI = LL - 1
16030 L = LEN(L$)
16040 DF = O : IF L = 0 THEN DF = -1 : GOTO 16170
16050 J = O : FOR I = 1 TO L
16060 B$ = L$(I, I)
16070 IF B$ >= "O" AND B$ <= "9" THEN 16110
16080 IF B$ = "-" THEN J = I : GOTO 16110
16100 J = 99 : I = 99
16110 NEXT I
16120 IF J = 99 THEN 16000
16130 IF J = 0 THEN LO = VAL(L$) : HI = LO : RETURN
16140 IF J > 1 THEN LO = VAL(L$(1, J - 1))
16150 IF J < L THEN HI = VAL(L$(J + 1, LEN(L$)))
16160 IF LO > HI THEN 16000
16170 RETURN
17000 ? " - LINE NO. - > ";
17010 GOSUB 10000
17020 L = LEN(L$)
17030 IF L = 0 THEN 320
17040 J = 0
17050 FOR I = 1 TO L
17060 B$ = L$(I, I)
17070 IF B$ >= "O" AND B$ <= "9" THEN 17090
17080 J = 99 : I = L
17090 NEXT I
17100 IF J = 99 THEN 17000
17110 LO = VAL(L$)
17120 RETURN
21000 ? "{CLEAR} SET MARGINS"
21010 POKE 85, 7 : ? "MARGIN SIZE : {DOWN} N. none"
21020 POKE 85, 19 : ? "S.small (0.5 in.)"
21030 POKE 85, 19 : ? "M.medium (1.0 in.)"
21040 POKE 85, 19 : ? "L.large (1.5 in.)"
21050 POKE 85, 19 : ? "O.own design"
21060 B = 0 : ? : ? "SELECT MARGIN SIZE - > ";
21070 GET #1, B : B$ = CHR$(B) : IF B$ = " " THEN 21070
21080 ? B$
21085 IF B$< >"N" AND B$< >"S" AND B$< >"M" AND B$< >"L" AND B$< >"O" THEN 21060
21090 IF B$ = "N" THEN M = 79 : SP = 0 : GOTO 320
21100 IF B$ = "S" THEN M = 74 : SP = 3 : GOTO 320
21110 IF B$ = "M" THEN M = 64 : SP = 8 : GOTO 320
21120 IF B$ = "L" THEN M = 54 : SP = 13 : GOTO 320
21130 IF B$ = "O" THEN ? : ? "INCHES FOR LEFT MARGIN = "; : INPUT SP
21140 ? : ? "INCHES FOR RIGHT MARGIN = "; : INPUT RM
21150 SP = INT((SP - 0.2) * 10) : M = 79 - SP - INT((RM - 0.25) * 10)
21160 GOTO 320
23000 ? : ? "PRESS RETURN TO PRINT NEXT PAGE"; : INPUT B$
23010 ? #2; CHR$(12)
23020 P1 = 6 : IF PP > 9 THEN P1 = 7
23030 PP = PP + 1 : CT = CT + 1
23040 FOR I1 = 1 TO SP + M - P1 : PUT #2, 32 : NEXT I1 : ? #2; "Page "; PP
23045 IF S1 = 2 THEN ? #2 : CT = CT + 1
23050 RETURN

Return to Table of Contents | Previous Section | Next Section