home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / TURBOPAS / TP / UTL2 / TURBOENV.PZS / TURBOENV.PAS
Pascal/Delphi Source File  |  2000-06-30  |  13KB  |  394 lines

  1. {Would you believe another envelope typing program?  Well, this one is
  2. special 'cause its written in Turbo Pascal (look ma, no GOTO's), can
  3. save your return address on disk, and can be edited so that you select
  4. control keys for cursor movements, delete, etc.}
  5.  
  6. { >>>--->      Written by Jim Zisfein and uploaded to       <---<<<
  7.   >>>--->       Blaise Pascal RCP/M - (718)-604-1930        <---<<<
  8.   >>>--->     September 23, 1985 for the public domain.     <---<<< }
  9.  
  10. program TurboEnv {TURBO ENVELOPE v1.0}; {$R+}
  11. type
  12.   string40=string[40];
  13.   linetype=1..15;
  14.   positiontype=1..40;
  15. const
  16.  
  17. {These control key assignments will seem normal only if you are also an
  18. aficionado of Perfect Writer.  Wordstar users will prefer ^E, ^S, ^D, and ^X
  19. for up, left, right, and down, DEL and ^G for delleft and delright, etc.
  20. Well...what are you waiting for?  Change them!}
  21.  
  22.      {Cursor commands}
  23.  
  24.   left=^B;
  25.   right=^F;
  26.   up=^P;
  27.   down=^N;
  28.   lineleft=^A;        {go to beginning of line}
  29.   lineright=^E;       {go to end of line}
  30.  
  31.      {Delete commands}
  32.  
  33.   delleft=^H;         {delete character to left of cursor}
  34.   delright=#127;      {delete character under cursor (#127 is DEL key)}
  35.   delline=^D;         {erase entire line}
  36.   chopline=^C;        {erase line to right of cursor}
  37.  
  38.      {Miscellaneous commands}
  39.  
  40.   insert=^I;          {toggles insert function on/off}
  41.   options=^X;         {first half of two character commands}
  42.  
  43.      {Two character commands: e.g., ^X^C = quit}
  44.  
  45.   help=^X;            {calls up expanded help menu}
  46.   newenv=^E;          {erases entire buffer}
  47.   readenv=^R;         {reads ENVELOPE.SAV from disk to buffer}
  48.   printenv=^P;        {sends buffer to printer device}
  49.   saveenv=^S;         {writes buffer to disk as ENVELOPE.SAV}
  50.   quit=^C;            {exits to your system}
  51.  
  52.      {Strings sent to printer before and after printing buffer contents}
  53.  
  54.   startprinter='';    {you don't HAVE to send anything}
  55.   stopprinter=^L;     {I use a formfeed to eject envelope after printing}
  56.  
  57.      {Appearance of printed envelope}
  58.  
  59.   xreturn=1;
  60.   yreturn=1;          {return address begins at column 1, line 1}
  61.   xmailing=40;
  62.   ymailing=12;        {mailing address begins at column 40, line 12}
  63.   xattn=1;
  64.   yattn=18;           {attn: begins at column 1, line 18}
  65.  
  66.      {Other user-selectable constants}
  67.  
  68.   startline=1;        {line to start editing: 1=return address, 7=mailing}
  69.   cr=^M^J;            {cr/lf sequence for your printer}
  70.   inserton: boolean=true;  {insert mode on at start of editing}
  71.   beepon: boolean=true;    {beep if illegal character is hit}
  72.  
  73. {BUFFER is the edit buffer: 15 lines of up to 40 characters each, using:
  74. for RETURN ADDRESS: lines 1-6,
  75. for MAILING ADDRESS: lines 7-12,
  76. for ATTN INSTRUCTIONS: lines 13-15.}
  77.  
  78. var
  79.   buffer: array[linetype] of string40;    {see above}
  80.   line: linetype;            {line number currently being processed}
  81.   printline: integer;        {line of printed output}
  82.   position: positiontype;    {cursor position in line being edited}
  83.   tex: text;                 {disk file for reading/writing}
  84.   ch: char;                  {character input from keyboard}
  85.   i: integer;                {all purpose counter}
  86.  
  87. {Functions x and y provide screen coordinates for buffer display.  If you
  88. have other than an 80x24 screen, you will need to alter these functions.}
  89.  
  90. function x: integer; begin if line in[7..12] then x:=39 else x:=6; end;
  91. function y: integer; begin y:=line+2; end;
  92.  
  93. function cch(ch: char): string40;  {translates control characters for display}
  94. begin
  95.   case ch of
  96.     #0..#31: cch:='^'+chr(ord(ch)+64);
  97.     #32..#126: cch:=ch;
  98.     #127: cch:='DEL';
  99.   end;
  100. end;
  101.  
  102. procedure HelpMenu1;   {displays an abbreviated help menu at all times}
  103. begin
  104.   writeln(' Cursor:   Left=',cch(left),'    Right=',cch(right),
  105.     '    Up=',cch(up),'    Down=',cch(down));
  106.   writeln(' Jump:     Beginning of line=',cch(lineleft),
  107.     '    End of line=',cch(lineright));
  108.   writeln(' Delete:   Left=',cch(delleft),'    Right=',cch(delright),
  109.     '    Delete line=',cch(delline),'    Delete line right=',cch(chopline));
  110.   if inserton then writeln(' Insert:   Now ON.  To switch off=',cch(insert))
  111.     else writeln(' Insert:   Now OFF.  To switch on=',cch(insert));
  112.   write(' Other:    Help=',cch(options),cch(help),
  113.     '  New=',cch(options),cch(newenv),
  114.     '  Read=',cch(options),cch(readenv),
  115.     '  Print=',cch(options),cch(printenv),
  116.     '  Save=',cch(options),cch(saveenv),
  117.     '  Quit=',cch(options),cch(quit));
  118. end;
  119.  
  120. {HelpMenu2 is an expanded help menu called up by ^X^X, or whatever you
  121. select.  Note that if you change a command, it will AUTOMATICALLY be
  122. reflected in this menu as well as HelpMenu1.  Wouldn't it be nice if
  123. all software were this friendly?}
  124.  
  125. procedure HelpMenu2;
  126. begin
  127.   clrscr;
  128.   write('Turbo Envelope Help Menu (^=control character)'^M^J^J);
  129.   HelpMenu1;
  130.   write(^M^J^J'Control keys can be changed EASILY by editing source text.',
  131.     ^M^J^J'<RETURN> goes to beginning of next line, same as ',cch(down),'.',
  132.     ^M^J^J'Delete character keys ',cch(delleft),',',cch(delright),
  133.     ' do not function when insert mode is off.',
  134.     ^M^J^J,cch(options),cch(newenv),' erases editing buffer but does ',
  135.     'not perform disk read/write.',
  136.     ^M^J^J,cch(options),cch(readenv),' and ',cch(options),cch(saveenv),
  137.     ' read and write to file ENVELOPE.SAV for retrieving/saving',
  138.     ^M^J'return addresses, etc.',
  139.     ^M^J^J,cch(options),cch(printenv),' sends the buffer contents to your ',
  140.     'printer (LST:) device.  Be sure',
  141.     ^M^J'that printer is on and print head is at upper left corner ',
  142.     'of envelope.',
  143.     ^M^J'Mailing address will be indented ',xmailing,' spaces.',
  144.     ^M^J^J'Hit any key to return to editing...');
  145.   repeat until keypressed;
  146. end;
  147.  
  148. procedure DisplayLine;  {displays a single line of buffer}
  149. begin
  150.   gotoxy(x-3,y);
  151.   write('--> ',buffer[line]);
  152.   clreol;
  153. end;
  154.  
  155. procedure DisplayBuffer;  {displays buffer contents}
  156. begin
  157.   for line:=1 to 15 do DisplayLine;
  158. end;
  159.  
  160. procedure DisplayScreen;  {displays envelope mock-up; assumes 80x24 screen}
  161. begin
  162.   clrscr;
  163.   writeln(' Turbo Envelope Typing Program v1.0');
  164.   for i:=1 to 79 do write('-'); writeln;
  165.   for i:=1 to 16 do writeln('|');
  166.   for i:=1 to 79 do write('-'); writeln;
  167.   HelpMenu1;
  168.   DisplayBuffer;
  169. end;
  170.  
  171. procedure MoveLeft;  {adjusts cursor position during line editing}
  172. begin
  173.   if position>1 then position:=position-1;
  174. end;
  175.  
  176. procedure MoveRight;  {adjusts cursor position during line editing}
  177. begin
  178.   if position<40 then position:=position+1;
  179. end;
  180.  
  181. {PrEnv is called thrice when the command is given to print the envelope:
  182. for the return address, mailing address, and attn instructions.  Linestart
  183. and lineend are lines in the edit buffer.  X and Y are locations (column
  184. and row) on the printed envelope.}
  185.  
  186. procedure PrEnv(linestart,lineend,xprint,yprint: integer);
  187. begin
  188.   while printline<yprint do begin
  189.     write(lst,cr);
  190.     printline:=printline+1;
  191.   end;
  192.   for line:=linestart to lineend do begin
  193.     for i:=2 to xprint do write(lst,' ');
  194.     write(lst,buffer[line],cr);
  195.     printline:=printline+1;
  196.   end;
  197. end;
  198.  
  199. {EditEnvelope is called by main program to process each character typed
  200. at the keyboard.  The routine first insures that the character position
  201. is within the line being edited (buffer[line]) or at the end of it.
  202. The cursor is then placed on that character.  Read(kbd,ch) pauses for
  203. keyboard input, and the case statement does the rest.}
  204.  
  205. procedure EditEnvelope;
  206. begin
  207.   if position>length(buffer[line]) then position:=length(buffer[line])+1;
  208.   gotoxy(x+position,y);
  209.   read(kbd,ch);
  210.   case ch of
  211.  
  212. {Printable characters are inserted or added to the end of the line if
  213. insert mode is on; otherwise they are substituted for existing characters.
  214. The position counter is then incremented, and the line is redisplayed.}
  215.  
  216.     ' '..'~': begin
  217.       if inserton or (position>length(buffer[line]))
  218.         then insert(ch,buffer[line],position)
  219.         else buffer[line][position]:=ch;
  220.       MoveRight;
  221.       DisplayLine;
  222.     end;
  223.  
  224. {Cursor movements.  Note that trailing spaces are deleted before moving
  225. to right end of line.}
  226.  
  227.     left: MoveLeft;
  228.     right: MoveRight;
  229.     lineleft: position:=1;
  230.     lineright: if buffer[line]>'' then begin
  231.       position:=length(buffer[line]);
  232.       while (position>1) and (buffer[line][position]=' ') do begin
  233.         delete(buffer[line],position,1);
  234.         MoveLeft;
  235.       end;
  236.       MoveRight;
  237.     end;
  238.  
  239. {Commands to delete characters (delleft, delright) work only in insert mode.
  240. Entire line is redisplayed after all deletions.}
  241.  
  242.     delleft: if position>1 then begin
  243.       MoveLeft;
  244.       if inserton then begin
  245.         delete(buffer[line],position,1);
  246.         DisplayLine;
  247.       end;
  248.     end;
  249.     delright: if inserton then begin
  250.       delete(buffer[line],position,1);
  251.       DisplayLine;
  252.     end;
  253.  
  254. {Delline erases entire line.  Chopline erases character at the cursor and
  255. everything to the right.}
  256.  
  257.     delline: begin
  258.       buffer[line]:='';
  259.       DisplayLine;
  260.     end;
  261.     chopline: begin
  262.       delete(buffer[line],position,40);
  263.       DisplayLine;
  264.     end;
  265.  
  266. {Insert toggles between inserton=true and inserton=false.
  267. I find the insert-off mode totally useless, but here it is anyway.}
  268.  
  269.     insert: begin
  270.       inserton:=not inserton;
  271.       gotoxy(1,20); HelpMenu1;
  272.     end;
  273.  
  274. {<RETURN> starts beginning of the next line, as does user-selectable
  275. Down key.  Up starts beginning of previous line.}
  276.  
  277.     up: begin
  278.       if line=1 then line:=15 else line:=line-1;
  279.       position:=1;
  280.     end;
  281.     down,^M: begin
  282.       if line=15 then line:=1 else line:=line+1;
  283.       position:=1;
  284.     end;
  285.  
  286. {For NONE OF THE ABOVE (other than the options key), you get beeped at.
  287. If this offends you, select beepon=false in the program heading.}
  288.  
  289.   else if ch<>options then write(^G);
  290.   end;
  291. end;
  292.  
  293. {SelectOption: if OPTIONS was pressed, the next character is processed here.
  294. These "two-character" commands activate the expanded help menu, read from
  295. disk, save to disk, exit to system, and, oh yes, print your envelope.}
  296.  
  297. procedure SelectOption;
  298.  
  299. {To allow editing to resume after SelectOption on the same line it was on,
  300. the line number (line) is saved as EDITLINE.}
  301.  
  302. var
  303.   editline: linetype;
  304.   iok: boolean;       {false if output error occurs}
  305.  
  306. begin
  307.   editline:=line;     {editing line number memorized}
  308.   gotoxy(7,24);       {cursor removed from envelope mock-up}
  309.   read(kbd,ch);       {pauses for key to be pressed}
  310.   case ch of
  311.  
  312. {Help displays the expanded help menu.}
  313.  
  314.     help: begin HelpMenu2; DisplayScreen; end;
  315.  
  316. {Newenv erases the buffer.}
  317.  
  318.     newenv: begin
  319.       for line:=1 to 15 do buffer[line]:='';
  320.       DisplayBuffer;
  321.     end;
  322.  
  323. {Readenv loads ENVELOPE.SAV from disk.  In most cases, the user will use
  324. this file for his return address.  No error message occurs if file
  325. is not found.}
  326.  
  327.     readenv: begin
  328.       {$I-} reset(tex); {$I+}
  329.       if ioresult=0 then begin
  330.         for line:=1 to 15 do readln(tex,buffer[line]);
  331.         close(tex);
  332.         DisplayBuffer;
  333.       end;
  334.     end;
  335.  
  336. {Printenv dumps buffer to the printer.  Envelope of standard
  337. business size is expected with upper left corner under print
  338. head.  Strings STARTPRINTER and STOPPRINTER are sent before
  339. and after buffer and should be used for any initialization
  340. and termination sequences your printer requires.}
  341.  
  342.     printenv: begin
  343.       write(lst,startprinter);
  344.       printline:=1;
  345.       PrEnv(1,6,xreturn,yreturn);     {print return address}
  346.       PrEnv(7,12,xmailing,ymailing);  {print mailing address}
  347.       PrEnv(13,15,xattn,yattn);       {print attn instructions}
  348.       write(lst,stopprinter);
  349.     end;
  350.  
  351. {Saveenv saves buffer to disk file ENVELOPE.SAV.  A message is printed if
  352. an I/O error occurs}
  353.  
  354.     saveenv: begin
  355.       iok:=true; {$I-}
  356.       rewrite(tex); iok:=(ioresult=0);
  357.       for line:=1 to 15 do begin
  358.         writeln(tex,buffer[line]);
  359.         iok:=iok and (ioresult=0);
  360.       end;
  361.       close(tex); iok:=iok and (ioresult=0); {$I+}
  362.       if not iok then begin
  363.         gotoxy(45,18); write(^G'File not written.  Press <RETURN>');
  364.         repeat until keypressed;
  365.         gotoxy(45,18); clreol;
  366.       end;
  367.     end;
  368.  
  369. {Editing now resumes on line it was previously on.}
  370.  
  371.   end;
  372.   line:=editline;
  373. end;
  374.  
  375. {The skeletal main program assigns the textfile, initializes the buffer
  376. to empty, displays a mock-up of an envelope, and starts editing on
  377. user-selectable line STARTLINE and on position 1.  The editing routine
  378. EditEnvelope analyzes each keyboard character.  When the OPTIONS character
  379. is received, control is transferred (for next character only) to
  380. SelectOption.}
  381.  
  382. begin {main program}
  383.   assign(tex,'ENVELOPE.SAV');
  384.   for line:=1 to 15 do buffer[line]:='';
  385.   DisplayScreen;
  386.   line:=startline;
  387.   position:=1;
  388.   repeat
  389.     repeat EditEnvelope until ch=options;
  390.     SelectOption;
  391.   until ch=quit;
  392.   for i:=1 to 24 do writeln;
  393. end.
  394.