home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / TURBOPAS / PASCAL.ZIP / EDIT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1980-01-01  |  43.2 KB  |  1,576 lines

  1.  
  2. PROGRAM EDIT ;
  3.   {$V-}
  4.  
  5.   CONST 
  6.     Blank = ' ' ;                           {A blank character}
  7.     NullString = '' ;                       {A null string}
  8.     MaxLines = 1000 ;                       {Maximum # of lines}
  9.     EndOfLine = 79 ;                        {Maximum length of line}
  10.     BottomOfScreen = 25 ;                   {Depth of window}
  11.     BeginningOfLine = 1 ;                   {Left side of window}
  12.     TopOfScreen = 1 ;                       {Top of window}
  13.     Up = 1 ;                                {Cursor directions}
  14.     Down = 2 ;
  15.     Left = 3 ;
  16.     Right = 4 ;
  17.     ReadIt = TRUE ;                         {Control OpenFile}
  18.     WriteIt = FALSE ;                       {Control OpenFile}
  19.     BigCursor = 1 ;                         {Large editing cursor}
  20.     SmallCursor = 2 ;                       {Normal cursor}
  21.     RealBigCursor = 3 ;                     {Very large cursor}
  22.     NoCursor = 4 ;                          {Cursor off}
  23.  
  24.   TYPE
  25.     Lines = STRING[80] ;
  26.     NotPtr = ^NotRec ;
  27.     NotRec = RECORD
  28.                Line : Lines ;
  29.                InBlock : BOOLEAN ;
  30.                Next : NotPtr ;
  31.                Prev : NotPtr ;
  32.              END ;
  33.     TotFileName = STRING[14] ;
  34.  
  35.   VAR 
  36.     NotFile : TotFileName ;
  37.     IntNotFile : TEXT ;
  38.     Colr,NoMoreRoom,BlockBeginMarked,BlockEndMarked,Top : BOOLEAN ;
  39.     NotCt : Byte ;
  40.     BeginPtr,EndPtr,CurrLinePtr,NotTopPtr,NotBotPtr,ScrTopPtr : NotPtr ;
  41.     I,J : Byte ;
  42.     Ch : CHAR ;
  43.     KeyChr,MKeystroke : CHAR ;
  44.     MFKey : BOOLEAN ;
  45.     X,Y,LinesThisPage,WordPtr,LineIdx : Byte ;
  46.     Found,Ok,Funckey : BOOLEAN ;
  47.     InChar : CHAR ;
  48.     SearchString : Lines ;
  49.     TempPtr : NotPtr ;
  50.  
  51.   PROCEDURE AddNode(Info:Lines) ;
  52.     {Adds a node to the list following the line on which the cursor resides}
  53.  
  54.     VAR 
  55.       TempPtr : NotPtr ;
  56.  
  57.     BEGIN
  58.       NEW(TempPtr) ;
  59.       TempPtr^.Prev := NIL ;
  60.       TempPtr^.Next := NIL ;
  61.       TempPtr^.Line := Info ;
  62.       TempPtr^.InBlock := FALSE ;
  63.       NotCt := NotCt + 1 ;
  64.       IF (NotCt = MaxLines) THEN
  65.         NoMoreRoom := TRUE ;
  66.       IF CurrLinePtr = NotBotPtr THEN
  67.         BEGIN
  68.           CurrLinePtr^.Next := TempPtr ;
  69.           TempPtr^.Prev := CurrLinePtr ;
  70.           NotBotPtr := TempPtr ;
  71.         END
  72.       ELSE 
  73.         BEGIN
  74.           CurrLinePtr^.Next^.Prev := TempPtr ;
  75.           TempPtr^.Prev := CurrLinePtr ;
  76.           TempPtr^.Next := CurrLinePtr^.Next ;
  77.           CurrLinePtr^.Next := TempPtr ;
  78.         END ;
  79.     END ;
  80.  
  81.   PROCEDURE BeepSound ;
  82.     { Make a "beep" sound to alert the user of an invalid keystroke. }
  83.  
  84.     BEGIN
  85.       Sound(660) ;
  86.       Delay(100) ;
  87.       Sound(880) ;
  88.       Delay(50) ;
  89.       NoSound ;
  90.     END ;
  91.  
  92.   PROCEDURE ReadKeyStroke(VAR ch:CHAR ;
  93.                           VAR FuncKey:BOOLEAN) ;
  94.     { Reads keystroke from the keyboard without echoing it to the screen.     }
  95.     { It distinguishes between "extended code" and "single code" key pressed. }
  96.  
  97.     BEGIN
  98.       Funckey := FALSE ;
  99.       READ(Kbd,ch) ;
  100.       IF (ch = #27) AND KeyPressed THEN
  101.         BEGIN
  102.           READ(Kbd,ch) ;
  103.           FuncKey := TRUE ;
  104.         END ;
  105.     END ;
  106.  
  107.   PROCEDURE SetSystemColors ;
  108.     {Returns to system colors}
  109.  
  110.     BEGIN
  111.       TextColor(15) ;
  112.       TextBackGround(0) ;
  113.     END ;
  114.  
  115.   PROCEDURE CursorSize(HowBig:Byte) ;
  116.     { Depending on the in-parameter this procedure either turns off the cursor }
  117.     { or turns it on and sets the cursor size to small/big or superbig resp.   }
  118.  
  119.     TYPE
  120.       register = RECORD
  121.                    CASE BOOLEAN OF 
  122.                      TRUE : (ax,bx,cx,dx,bp,si,di,ds,es,flags:INTEGER) ;
  123.                      FALSE : (al,ah,bl,bh,cl,ch,dl,dh:Byte) ;
  124.                  END ;
  125.  
  126.     VAR 
  127.       Regs : Register ;
  128.  
  129.     BEGIN
  130.       WITH regs DO 
  131.         BEGIN
  132.           CASE HowBig OF 
  133.             BigCursor : BEGIN
  134.                           IF Colr THEN
  135.                             cx := $0307
  136.                           ELSE 
  137.                             cx := $080D
  138.                         END ;
  139.             SmallCursor : BEGIN
  140.                             IF Colr THEN
  141.                               cx := $0607
  142.                             ELSE 
  143.                               cx := $0B0D
  144.                           END ;
  145.             RealBigCursor : BEGIN
  146.                               IF Colr THEN
  147.                                 cx := $0007
  148.                               ELSE 
  149.                                 cx := $000D
  150.                             END ;
  151.             NoCursor : cx := $3200 ;
  152.           END ;
  153.           ah := $01 ;
  154.           bx := $0 ;
  155.           Intr($10,Regs) ;
  156.         END ;
  157.     END ;
  158.  
  159.   PROCEDURE DetermineDisplay ;
  160.     { Set ScreenBase to $B000 or $B800, depending on which display is in use.}
  161.     { Sets global variable COLR to true if color screen, false if monochrome }
  162.  
  163.     VAR 
  164.       t : Byte ;
  165.  
  166.     BEGIN
  167.       t := (Mem[0000:$0410] AND $0030) ;
  168.       IF (t = $0030) THEN
  169.         colr := FALSE
  170.       ELSE 
  171.         colr := TRUE ;
  172.     END ;
  173.  
  174.   PROCEDURE Regress(VAR ThePtr:NotPtr) ;
  175.     {Moves a pointer towards top of the list}
  176.  
  177.     BEGIN
  178.       ThePtr := ThePtr^.Prev ;
  179.     END ;
  180.  
  181.   PROCEDURE Advance(VAR ThePtr:NotPtr) ;
  182.     {Moves a pointer towards bottom of the list}
  183.  
  184.     BEGIN
  185.       ThePtr := ThePtr^.Next ;
  186.     END ;
  187.  
  188.   PROCEDURE Inc(VAR TheValue:Byte) ;
  189.  
  190.     BEGIN
  191.       TheValue := TheValue + 1 ;
  192.     END ;
  193.  
  194.   PROCEDURE Dec(VAR TheValue:Byte) ;
  195.  
  196.     BEGIN
  197.       TheValue := TheValue - 1 ;
  198.     END ;
  199.  
  200.   PROCEDURE CheckPosition(VAR ScreenCol,ScreenRow:Byte) ;
  201.     {This procedure gets and returns the screen position via}
  202.     {the standard Turbo WhereX and WhereY}
  203.  
  204.     BEGIN
  205.       ScreenCol := WhereX ;
  206.       ScreenRow := WhereY ;
  207.     END ;
  208.  
  209.   PROCEDURE RvsOn ;
  210.     {Turns on reverse video}
  211.  
  212.     BEGIN
  213.       IF Colr THEN
  214.         BEGIN
  215.           TextBackGround(14) ;
  216.           TextColor(1) ;
  217.         END
  218.       ELSE 
  219.         BEGIN
  220.           TextBackGround(7) ;
  221.           TextColor(0) ;
  222.         END
  223.     END ;
  224.  
  225.   PROCEDURE RvsOff ;
  226.     {Turns off reverse video}
  227.  
  228.     BEGIN
  229.       TextBackGround(0) ;
  230.       IF Colr THEN
  231.         TextColor(14)
  232.       ELSE 
  233.         TextColor(15)
  234.     END ;
  235.  
  236.   FUNCTION LengthThisLine : Byte ;
  237.     {Returns the length of the current line}
  238.  
  239.     BEGIN
  240.       LengthThisLine := LENGTH(CurrLinePtr^.Line) ;
  241.     END ;
  242.  
  243.   FUNCTION ThereIsASpace : BOOLEAN ;
  244.  
  245.     BEGIN
  246.       ThereIsASpace := FALSE ;
  247.       FOR i := 1 TO LengthThisLine DO 
  248.         IF CurrLinePtr^.Line[i] = #32 THEN
  249.           ThereIsASpace := TRUE ;
  250.     END ;
  251.  
  252.   FUNCTION SpacesOnly : BOOLEAN ;
  253.     {Returns true if no characters other than space on line}
  254.  
  255.     BEGIN
  256.       SpacesOnly := TRUE ;
  257.       FOR i := 1 TO LengthThisLine DO 
  258.         IF CurrLinePtr^.Line[i] <> #32 THEN
  259.           SpacesOnly := FALSE ;
  260.     END ;
  261.  
  262.   FUNCTION BlockMarkedOK : BOOLEAN ;
  263.     {Returns true if proper block of text marked}
  264.  
  265.     BEGIN
  266.       IF BlockBeginMarked AND BlockEndMarked THEN
  267.         BEGIN
  268.           BlockMarkedOK := TRUE ;
  269.           TempPtr := NotTopPtr ;
  270.           WHILE TempPtr <> BeginPtr DO 
  271.             IF TempPtr = EndPtr THEN
  272.               BEGIN
  273.                 BlockMarkedOK := FALSE ;
  274.                 exit ;
  275.               END
  276.             ELSE 
  277.               Advance(TempPtr) ;
  278.         END
  279.       ELSE 
  280.         BlockMarkedOK := FALSE ;
  281.     END ;
  282.  
  283.   FUNCTION OkToMove : BOOLEAN ;
  284.     {Returns true if its ok to move a block of text}
  285.  
  286.     BEGIN
  287.       OkToMove := FALSE ;
  288.       IF BlockMarkedOk THEN
  289.         BEGIN
  290.           OkToMove := TRUE ;
  291.           TempPtr := BeginPtr ;
  292.           WHILE TempPtr <> EndPtr DO 
  293.             BEGIN
  294.               IF CurrLinePtr = TempPtr THEN
  295.                 BEGIN
  296.                   OkToMove := FALSE ;
  297.                   exit ;
  298.                 END ;
  299.               Advance(TempPtr) ;
  300.             END ;
  301.           IF CurrLinePtr = EndPtr THEN
  302.             OkToMove := FALSE ;
  303.         END ;
  304.     END ;
  305.  
  306.   PROCEDURE DrawScreen ;
  307.     {This procedure draws the text to the screen when the entire}
  308.     {screen needs to be refreshed.}
  309.  
  310.     BEGIN
  311.       ClrScr ;
  312.       TempPtr := ScrTopPtr ;
  313.       LinesThisPage := 0 ;
  314.       WHILE (LinesThisPage < BottomOfScreen) AND (TempPtr <> NIL) DO 
  315.         BEGIN
  316.           Inc(LinesThisPage) ;
  317.           GotoXY(BeginningOfLine,LinesThisPage) ;
  318.           IF TempPtr^.InBlock THEN
  319.             RvsOn ;
  320.           WRITE(TempPtr^.Line) ;
  321.           RvsOff ;
  322.           Advance(TempPtr) ;
  323.         END ;
  324.     END ;
  325.  
  326.   PROCEDURE HelpScrn ;
  327.     { Gets specified help-file from disk and displays on screen line by line }
  328.     { from specified help-file. }
  329.  
  330.     VAR 
  331.       Hlpfile : TEXT ;
  332.       hlpname : STRING [64] ;
  333.       helpbuff : STRING [73] ;
  334.       KeyStroke : CHAR ;
  335.       Fkey : BOOLEAN ;
  336.       HelpScript : STRING [15] ;
  337.  
  338.     BEGIN
  339.       ClrScr ;
  340.       Hlpname := 'NPD.hlp' ;
  341.       GotoXY(27,24) ;
  342.       WRITE(' Press ESC to exit Help. ') ;
  343.       Window(4,3,77,24) ;
  344.       GotoXY(1,1) ;
  345.       i := POS(hlpname,#32) ;
  346.       IF i <> 0 THEN
  347.         hlpname[0] := CHR(i - 1) ;
  348.       Assign(hlpfile,hlpname) ;
  349.       {$I-}
  350.       RESET(hlpfile) ;
  351.       {$I+}
  352.       GotoXY(1,1) ;
  353.       WHILE NOT EOF(hlpfile) DO 
  354.         BEGIN
  355.           READLN(hlpfile,helpbuff) ;
  356.           WRITELN(helpbuff) ;
  357.         END ;
  358.       CLOSE(hlpfile) ;
  359.     END ;
  360.  
  361.   PROCEDURE Disphelp ;
  362.     { Puts up the general help-window on the screen and calls HelpScrn to }
  363.     { write the specified help-information on the screen.                 }
  364.  
  365.     VAR 
  366.       Keystroke : CHAR ;
  367.       FKey : BOOLEAN ;
  368.  
  369.     BEGIN
  370.       Window(1,1,80,25) ;
  371.       HelpScrn ;
  372.       REPEAT
  373.         BEGIN
  374.           ReadKeyStroke(KeyStroke,Fkey) ;
  375.           IF (FKey = TRUE) THEN             { "Extended Code" keys pressed }
  376.             BeepSound
  377.           ELSE IF (KeyStroke <> #27) THEN
  378.             BeepSound ;
  379.         END ;
  380.       UNTIL (KeyStroke = #27) ;
  381.       ClrScr ;
  382.       DrawScreen ;
  383.     END ;
  384.  
  385.   PROCEDURE SetBlock ;
  386.     {Establishes a a marked block and readies it to move}
  387.  
  388.     BEGIN
  389.       IF BeginPtr^.Prev = NIL THEN
  390.         BEGIN
  391.           NotTopPtr := EndPtr^.Next ;
  392.           NotTopPtr^.Prev := NIL ;
  393.           EndPtr^.Next := NIL ;
  394.         END
  395.       ELSE IF EndPtr^.Next = NIL THEN
  396.         BEGIN
  397.           NotBotPtr := BeginPtr^.Prev ;
  398.           NotBotPtr^.Next := NIL ;
  399.           BeginPtr^.Prev := NIL ;
  400.         END
  401.       ELSE 
  402.         BEGIN
  403.           BeginPtr^.Prev^.Next := EndPtr^.Next ;
  404.           EndPtr^.Next^.Prev := BeginPtr^.Prev ;
  405.           BeginPtr^.Prev := NIL ;
  406.           EndPtr^.Next := NIL ;
  407.         END ;
  408.     END ;
  409.   {PROCEDURE SetBlock}
  410.  
  411.   PROCEDURE ShowBlock(Status:BOOLEAN) ;
  412.     {Set block to be displayed in reverse video}
  413.  
  414.     BEGIN
  415.       TempPtr := BeginPtr ;
  416.       TempPtr^.InBlock := Status ;
  417.       WHILE TempPtr <> EndPtr DO 
  418.         BEGIN
  419.           Advance(TempPtr) ;
  420.           TempPtr^.InBlock := Status ;
  421.         END ;
  422.     END ;
  423.   {PROCEDURE ShowBlock}
  424.  
  425.   PROCEDURE MoveBlock ;
  426.     {Moves a block of text}
  427.  
  428.     BEGIN
  429.       SetBlock ;
  430.       IF CurrLinePtr = NotTopPtr THEN       {move block to top of notepad}
  431.         BEGIN
  432.           CurrLinePtr^.Prev := EndPtr ;
  433.           EndPtr^.Next := CurrLinePtr ;
  434.           NotTopPtr := BeginPtr ;
  435.         END
  436.       ELSE 
  437.         BEGIN
  438.           CurrLinePtr^.Prev^.Next := BeginPtr ;
  439.           EndPtr^.Next := CurrLinePtr ;
  440.           BeginPtr^.Prev := CurrLinePtr^.Prev ;
  441.           CurrLinePtr^.Prev := EndPtr ;
  442.         END ;
  443.       CurrLinePtr := BeginPtr ;
  444.       ScrTopPtr := CurrLinePtr ;
  445.       LineIdx := 0 ;
  446.       DrawScreen ;
  447.       GotoXY(BeginningOfLine,TopOfScreen) ;
  448.     END ;
  449.  
  450.   PROCEDURE DeleteBlock ;
  451.     {Deletes a block of text}
  452.  
  453.     BEGIN
  454.       SetBlock ;
  455.       WHILE BeginPtr <> EndPtr DO 
  456.         BEGIN
  457.           TempPtr := BeginPtr ;
  458.           Advance(BeginPtr) ;
  459.           BeginPtr^.Prev := NIL ;
  460.           Dispose(TempPtr) ;
  461.           Dec(NotCt) ;
  462.         END ;
  463.       Dispose(BeginPtr) ;
  464.       Dec(NotCt) ;
  465.       BlockBeginMarked := FALSE ;
  466.       BlockEndMarked := FALSE ;
  467.       ScrTopPtr := CurrLinePtr ;
  468.       LineIdx := 0 ;
  469.       DrawScreen ;
  470.       GotoXY(BeginningOfLine,TopOfScreen) ;
  471.       NoMoreRoom := FALSE ;
  472.     END ;
  473.   {PROCEDURE DeleteBlock}
  474.  
  475.   PROCEDURE SortBlock ;
  476.     {Sorts a marked block of notepad text using ASCII string values}
  477.  
  478.     VAR 
  479.       LineHolder,TempLine1,TempLine2 : Lines ;
  480.       Done : BOOLEAN ;
  481.       TempPtr1,TempPtr2 : NotPtr ;
  482.  
  483.     FUNCTION AllCaps(TempLine:Lines) : Lines ;
  484.  
  485.       VAR 
  486.         TempCaps : Lines ;
  487.  
  488.       BEGIN
  489.         TempCaps := NullString ;
  490.         FOR I := 1 TO LENGTH(TempLine) DO 
  491.           IF TempLine[I] <> ' ' THEN
  492.             TempCaps := TempCaps + (UpCase(TempLine[I])) ;
  493.         AllCaps := TempCaps
  494.       END ;
  495.     {FUNCTION AllCaps}
  496.  
  497.   BEGIN
  498.     IF BlockMarkedOk THEN
  499.       BEGIN
  500.         Done := FALSE ;
  501.         TempPtr2 := EndPtr ;
  502.         WHILE NOT Done DO 
  503.           BEGIN
  504.             TempPtr1 := BeginPtr ;
  505.             Done := TRUE ;
  506.             WHILE TempPtr1 <> TempPtr2 DO 
  507.               BEGIN
  508.                 TempLine1 := AllCaps(TempPtr1^.Line) ;
  509.                 TempLine2 := AllCaps(TempPtr1^.Next^.Line) ;
  510.                 IF TempLine1 > TempLine2 THEN
  511.                   BEGIN
  512.                     LineHolder := TempPtr1^.Line ;
  513.                     TempPtr1^.Line := TempPtr1^.Next^.Line ;
  514.                     TempPtr1^.Next^.Line := LineHolder ;
  515.                     Done := FALSE ;
  516.                   END ;
  517.                 Advance(TempPtr1) ;
  518.               END ;
  519.             Regress(TempPtr2) ;
  520.           END ;
  521.         CheckPosition(X,Y) ;
  522.         DrawScreen ;
  523.         GotoXY(X,Y) ;
  524.       END
  525.     ELSE 
  526.       BeepSound ;
  527.   END ;
  528.   {PROCEDURE SortBlock}
  529.  
  530.   PROCEDURE SetNoteColors ;
  531.     {Sets colors for color or mono screen}
  532.  
  533.     BEGIN
  534.       IF Colr THEN
  535.         BEGIN
  536.           TextColor(1) ;
  537.           TextBackGround(0) ;
  538.         END
  539.       ELSE 
  540.         BEGIN
  541.           TextColor(15) ;
  542.           TextBackGround(0) ;
  543.         END ;
  544.     END ;
  545.  
  546.   PROCEDURE MarkBegin ;
  547.     {Set mark begin pointer}
  548.  
  549.     BEGIN
  550.       IF NOT BlockMarkedOK THEN
  551.         BEGIN
  552.           BeginPtr := CurrLinePtr ;
  553.           BlockBeginMarked := TRUE ;
  554.           IF BlockEndMarked THEN
  555.             IF BlockMarkedOk THEN
  556.               BEGIN
  557.                 ShowBlock(TRUE) ;
  558.                 CheckPosition(X,Y) ;
  559.                 DrawScreen ;
  560.                 GotoXY(X,Y) ;
  561.               END
  562.             ELSE 
  563.               BEGIN
  564.                 BlockBeginMarked := FALSE ;
  565.                 BeepSound ;
  566.               END ;
  567.         END
  568.       ELSE 
  569.         BeepSound ;
  570.     END ;
  571.  
  572.   PROCEDURE MarkEnd ;
  573.     {Set mark end pointer}
  574.  
  575.     BEGIN
  576.       IF NOT BlockMarkedOK THEN
  577.         BEGIN
  578.           EndPtr := CurrLinePtr ;
  579.           BlockEndMarked := TRUE ;
  580.           IF BlockBeginMarked THEN
  581.             IF BlockMarkedOK THEN
  582.               BEGIN
  583.                 ShowBlock(TRUE) ;
  584.                 CheckPosition(X,Y) ;
  585.                 DrawScreen ;
  586.                 GotoXY(X,Y) ;
  587.               END
  588.             ELSE 
  589.               BEGIN
  590.                 BlockBeginMarked := FALSE ;
  591.                 BeepSound ;
  592.               END ;
  593.         END
  594.       ELSE 
  595.         BeepSound ;
  596.     END ;
  597.  
  598.   PROCEDURE UnMarkBlock ;
  599.  
  600.     BEGIN
  601.       IF BlockMarkedOK THEN
  602.         BEGIN
  603.           ShowBlock(FALSE) ;
  604.           CheckPosition(X,Y) ;
  605.           DrawScreen ;
  606.           GotoXY(X,Y) ;
  607.           BlockBeginMarked := FALSE ;
  608.           BlockEndMarked := FALSE ;
  609.           BeginPtr := NIL ;
  610.           EndPtr := NIL ;
  611.         END
  612.       ELSE 
  613.         BeepSound ;
  614.     END ;
  615.   {PROCEDURE UnMarkBlock}
  616.  
  617.   PROCEDURE InitializePad ;
  618.  
  619.     BEGIN
  620.       OK := FALSE ;
  621.       WordPtr := BeginningOfLine ;
  622.       LineIdx := 0 ;
  623.       CursorSize(BigCursor) ;
  624.       SetNoteColors ;
  625.     END ;
  626.  
  627.   PROCEDURE AddChar ;
  628.     {Inserts a character into current line then adjusts its length}
  629.  
  630.     BEGIN
  631.       RvsOn ;
  632.       IF LineIdx = LengthThisLine THEN
  633.         BEGIN
  634.           Inc(LineIdx) ;
  635.           CurrLinePtr^.Line[0] := CHR(LineIdx) ;
  636.         END
  637.       ELSE 
  638.         Inc(LineIdx) ;
  639.       CurrLinePtr^.Line[LineIdx] := InChar ;
  640.       WRITE(InChar) ;
  641.       RvsOff ;
  642.     END ;
  643.  
  644.   PROCEDURE Home ;
  645.     {Moves cursor to beginning of current line and sets line index}
  646.  
  647.     BEGIN
  648.       IF LineIdx > 0 THEN
  649.         BEGIN
  650.           CheckPosition(X,Y) ;
  651.           LineIdx := 0 ;
  652.           GotoXY(BeginningOfLine,Y) ;
  653.         END
  654.       ELSE 
  655.         BeepSound ;
  656.     END ;
  657.  
  658.   PROCEDURE GoToEnd ;
  659.     {Moves Cursor to end of current line and sets line index}
  660.  
  661.     BEGIN
  662.       CheckPosition(X,Y) ;
  663.       IF X <= LengthThisLine THEN
  664.         BEGIN
  665.           LineIdx := LengthThisLine ;
  666.           GotoXY(LineIdx + 1,Y) ;
  667.         END
  668.       ELSE 
  669.         BeepSound ;
  670.     END ;
  671.  
  672.   PROCEDURE Tab ;
  673.     {Moves five spaces to right inserting blanks till end of line}
  674.     {if no characters on line yet.  Otherwise just moves five spaces}
  675.     {without inserting blanks}
  676.  
  677.     BEGIN
  678.       CheckPosition(X,Y) ;
  679.       IF (X < LengthThisLine) THEN
  680.         BEGIN
  681.           IF ((X + 5) < LengthThisLine) THEN
  682.             BEGIN
  683.               LineIdx := LineIdx + 5 ;
  684.               GotoXY(X + 5,Y) ;
  685.             END
  686.           ELSE 
  687.             BEGIN
  688.               LineIdx := LengthThisLine ;
  689.               GotoXY(LengthThisLine + 1,Y) ;
  690.             END ;
  691.         END
  692.       ELSE IF (LineIdx = 0) OR SpacesOnly THEN
  693.         BEGIN
  694.           InChar := Blank ;
  695.           IF (LineIdx + 5) < EndOfLine THEN
  696.             FOR i := 1 TO 5 DO 
  697.               AddChar
  698.           ELSE 
  699.             FOR i := LineIdx + 1 TO EndOfLine - 1 DO 
  700.               AddChar ;
  701.         END ;
  702.     END ;
  703.  
  704.   PROCEDURE FindWordPtr ;
  705.     {Finds first non-space character after a space on the current line}
  706.  
  707.     BEGIN
  708.       FOR i := BeginningOfLine TO EndOfLine DO 
  709.         IF (CurrLinePtr^.Line[i] = #32) THEN
  710.           WordPtr := i + 1 ;
  711.     END ;
  712.  
  713.   PROCEDURE DeleteCharLeft ;
  714.     {Backspace deletion of character to left of cursor}
  715.  
  716.     BEGIN
  717.       CheckPosition(X,Y) ;
  718.       IF X > BeginningOfLine THEN
  719.         BEGIN
  720.           Dec(LineIdx) ;                    {Decrement line index}
  721.           CurrLinePtr^.Line[X - 1] := Blank ;  {Insert a blank}
  722.           GotoXY(X - 1,Y) ;
  723.           WRITE(Blank) ;
  724.           GotoXY(X - 1,Y) ;
  725.         END
  726.       ELSE 
  727.         BeepSound ;
  728.     END ;
  729.  
  730.   PROCEDURE DeleteCharRight ;
  731.     {Del key deletion of character to right of cursor}
  732.  
  733.     BEGIN
  734.       CheckPosition(X,Y) ;
  735.       IF (LengthThisLine > 0) AND (X <= LengthThisLine) THEN
  736.         BEGIN
  737.           GotoXY(LengthThisLine,Y) ;
  738.           WRITE(Blank) ;
  739.           FOR i := X TO LengthThisLine - 1 DO 
  740.             CurrLinePtr^.Line[i] := CurrLinePtr^.Line[i + 1] ;
  741.           IF LengthThisLine > 0 THEN
  742.             CurrLinePtr^.Line[0] := CHR(LengthThisLine - 1)
  743.           ELSE 
  744.             CurrLinePtr^.Line[0] := CHR(0) ;
  745.           GotoXY(X,Y) ;
  746.           FOR i := X TO LengthThisLine DO 
  747.             WRITE(CurrLinePtr^.Line[i]) ;
  748.           GotoXY(X,Y) ;
  749.         END
  750.       ELSE 
  751.         BeepSound ;
  752.     END ;
  753.  
  754.   PROCEDURE SetCursor(LengthLastLine,LinesLastPage:Byte) ;
  755.     {Adjusts cursor so it rests at the end of line on page}
  756.     {if page is shorter or end of line if line is shorter}
  757.     {If neither of these is true it goes to same line at same position}
  758.  
  759.     BEGIN
  760.       IF LinesThisPage >= LinesLastPage THEN
  761.         BEGIN
  762.           IF (LengthThisLine <= LengthLastLine) AND (LengthThisLine <> 0) THEN
  763.             BEGIN
  764.               GotoXY(LengthThisLine + 1,LinesLastPage) ;
  765.               LineIdx := LengthThisLine ;
  766.             END
  767.           ELSE IF LengthThisLine = 0 THEN
  768.             BEGIN
  769.               GotoXY(BeginningOfLine,LinesLastPage) ;
  770.               LineIdx := 0 ;
  771.             END
  772.           ELSE 
  773.             BEGIN
  774.               GotoXY(LengthLastLine,LinesLastPage) ;
  775.               LineIdx := LengthLastLine - 1 ;
  776.             END
  777.         END
  778.       ELSE 
  779.         BEGIN
  780.           IF (LengthThisLine <= LengthLastLine) AND (LengthThisLine <> 0) THEN
  781.             BEGIN
  782.               GotoXY(LengthThisLine + 1,LinesThisPage) ;
  783.               LineIdx := LengthThisLine ;
  784.             END
  785.           ELSE IF LengthThisLine = 0 THEN
  786.             BEGIN
  787.               GotoXY(BeginningOfLine,LinesThisPage) ;
  788.               LineIdx := 0 ;
  789.             END
  790.           ELSE 
  791.             BEGIN
  792.               GotoXY(LengthLastLine,LinesThisPage) ;
  793.               LineIdx := LengthLastLine - 1 ;
  794.             END ;
  795.         END ;
  796.     END ;
  797.  
  798.   PROCEDURE DeleteNode ;
  799.     {Deletes the line upon which the cursor resides and moves all lines up}
  800.  
  801.     BEGIN
  802.       Dec(NotCt) ;
  803.       IF NotCt < MaxLines THEN
  804.         NoMoreRoom := FALSE ;
  805.       IF CurrLinePtr = NotTopPtr THEN
  806.         BEGIN
  807.           TempPtr := CurrLinePtr ;
  808.           NotTopPtr := CurrLinePtr^.Next ;
  809.           NotTopPtr^.Prev := NIL ;
  810.           CurrLinePtr := NotTopPtr ;
  811.           ScrTopPtr := NotTopPtr ;
  812.           Dispose(TempPtr) ;
  813.         END
  814.       ELSE IF CurrLinePtr = NotBotPtr THEN
  815.         BEGIN
  816.           TempPtr := CurrLinePtr ;
  817.           NotBotPtr := CurrLinePtr^.Prev ;
  818.           NotBotPtr^.Next := NIL ;
  819.           CurrLinePtr := NotBotPtr ;
  820.           ScrTopPtr := NotBotPtr ;
  821.           Dispose(TempPtr) ;
  822.         END
  823.       ELSE 
  824.         BEGIN
  825.           IF CurrLinePtr = ScrTopPtr THEN
  826.             Advance(ScrTopPtr)
  827.           ELSE IF ScrTopPtr = NotBotPtr THEN
  828.             Regress(ScrTopPtr) ;
  829.           TempPtr := CurrLinePtr ;
  830.           TempPtr^.Next^.Prev := TempPtr^.Prev ;
  831.           TempPtr^.Prev^.Next := TempPtr^.Next ;
  832.           CurrLinePtr := TempPtr^.Next ;
  833.           Dispose(TempPtr) ;
  834.         END ;
  835.     END ;
  836.  
  837.   PROCEDURE LineInBlock(ThisLinePtr:NotPtr) ;
  838.  
  839.     BEGIN
  840.       IF (BlockMarkedOk) AND ( NOT OkToMove) THEN
  841.         ThisLinePtr^.InBlock := TRUE ;
  842.     END ;
  843.   {PROCEDURE LineInBlock}
  844.  
  845.   PROCEDURE InsertLine ;
  846.     {Inserts a line above the current line and moves all lines down}
  847.  
  848.     BEGIN
  849.       CheckPosition(X,Y) ;
  850.       AddNode(CurrLinePtr^.Line) ;
  851.       LineInBlock(CurrLinePtr^.Next) ;
  852.       CurrLinePtr^.Line := NullString ;
  853.       LineIdx := 0 ;
  854.       DrawScreen ;
  855.       GotoXY(BeginningOfLine,Y) ;
  856.     END ;
  857.  
  858.   PROCEDURE DeleteLine ;
  859.     {Deletes the line on which the cursor resides}
  860.  
  861.     BEGIN
  862.       IF (BlockMarkedOk) AND ( NOT OkToMove) THEN
  863.         IF BeginPtr <> EndPtr THEN
  864.           IF CurrLinePtr = BeginPtr THEN
  865.             BeginPtr := BeginPtr^.Next
  866.           ELSE IF CurrLinePtr = EndPtr THEN
  867.             EndPtr := EndPtr^.Prev ;
  868.       CheckPosition(X,Y) ;
  869.       DeleteNode ;
  870.       DrawScreen ;
  871.       SetCursor(x,y) ;
  872.     END ;
  873.  
  874.   PROCEDURE StartFresh ;
  875.     {Creates a new note list}
  876.  
  877.     BEGIN
  878.       NEW(NotTopPtr) ;
  879.       NotTopPtr^.Next := NIL ;
  880.       NotTopPtr^.Prev := NIL ;
  881.       NotTopPtr^.Line := NullString ;
  882.       NotTopPtr^.InBlock := FALSE ;
  883.       ScrTopPtr := NotTopPtr ;
  884.       NotBotPtr := NotTopPtr ;
  885.       CurrLinePtr := NotTopPtr ;
  886.       NotCt := 1 ;
  887.       OK := TRUE ;
  888.       DrawScreen ;
  889.       GotoXY(BeginningOfLine,TopOfScreen) ;
  890.     END ;
  891.  
  892.   PROCEDURE MoveCursor(ArrowKey:Byte) ;
  893.     {Moves cursor appropriately when arrow keys are pressed}
  894.  
  895.     BEGIN
  896.       CheckPosition(X,Y) ;
  897.       IF NOT ((X = BeginningOfLine) AND (ArrowKey = Left)) THEN
  898.         IF NOT ((X > LengthThisLine) AND (ArrowKey = Right)) THEN
  899.           CASE ArrowKey OF 
  900.             Up : IF (CurrLinePtr = ScrTopPtr) AND (CurrLinePtr <> NotTopPtr) 
  901.                         THEN
  902.                    BEGIN
  903.                      Regress(CurrLinePtr) ;
  904.                      Regress(ScrTopPtr) ;
  905.                      DrawScreen ;
  906.                      SetCursor(X,Y) ;
  907.                    END
  908.                  ELSE IF (CurrLinePtr <> ScrTopPtr) AND (CurrLinePtr <> 
  909.                         NotTopPtr) THEN
  910.                    BEGIN
  911.                      Regress(CurrLinePtr) ;
  912.                      SetCursor(X,Y - 1) ;
  913.                    END
  914.                  ELSE 
  915.                    BeepSound ;
  916.             Down : IF (Y = BottomOfScreen) AND (CurrLinePtr <> NotBotPtr) THEN
  917.                      BEGIN
  918.                        Advance(CurrLinePtr) ;
  919.                        Advance(ScrTopPtr) ;
  920.                        DrawScreen ;
  921.                        SetCursor(X,Y) ;
  922.                      END
  923.                    ELSE IF (Y <> BottomOfScreen) AND (CurrLinePtr <> NotBotPtr)
  924.                           THEN
  925.                      BEGIN
  926.                        Advance(CurrLinePtr) ;
  927.                        SetCursor(X,Y + 1) ;
  928.                      END
  929.                    ELSE 
  930.                      BeepSound ;
  931.             Left : BEGIN
  932.                      GotoXY(X - 1,Y) ;
  933.                      Dec(LineIdx) ;
  934.                    END ;
  935.             Right : BEGIN
  936.                       GotoXY(X + 1,Y) ;
  937.                       Inc(LineIdx) ;
  938.                     END ;
  939.           END                               {CASE}
  940.         ELSE 
  941.           BeepSound
  942.       ELSE 
  943.         BeepSound ;
  944.     END ;
  945.  
  946.   PROCEDURE PageUp ;
  947.     {Moves up one page or as far as possible if less than one page left}
  948.  
  949.     BEGIN
  950.       IF ScrTopPtr <> NotTopPtr THEN
  951.         BEGIN
  952.           i := 0 ;
  953.           WHILE (i < BottomOfScreen) AND (ScrTopPtr^.Prev <> NIL) DO 
  954.             BEGIN
  955.               Inc(i) ;
  956.               Regress(ScrTopPtr) ;
  957.               Regress(CurrLinePtr) ;
  958.             END ;
  959.           DrawScreen ;
  960.         END
  961.       ELSE 
  962.         BeepSound ;
  963.     END ;
  964.  
  965.   PROCEDURE PageDown ;
  966.     {Moves down one page or as far as possible if less than one page left}
  967.  
  968.     BEGIN
  969.       IF LinesThisPage > 1 THEN
  970.         BEGIN
  971.           i := 0 ;
  972.           j := 0 ;
  973.           WHILE (i < BottomOfScreen) AND (ScrTopPtr^.Next <> NIL) DO 
  974.             BEGIN
  975.               Inc(i) ;
  976.               Advance(ScrTopPtr) ;
  977.             END ;
  978.           WHILE (j < i) AND (CurrLinePtr^.Next <> NIL) DO 
  979.             BEGIN
  980.               Inc(j) ;
  981.               Advance(CurrLinePtr) ;
  982.             END ;
  983.           DrawScreen ;
  984.         END
  985.       ELSE 
  986.         BeepSound ;
  987.     END ;
  988.  
  989.   PROCEDURE WordWrap ;
  990.     {The following procedure is called from the main driver when}
  991.     {an entire word must be moved to the Next line.  It causes all }
  992.     {characters written to the screen since the last space to be}
  993.     {moved to the Next line and the preceeding line to be shortened by}
  994.     {the length of the word which was wrapped!.}
  995.  
  996.     VAR 
  997.       TempString : Lines ;
  998.  
  999.     BEGIN
  1000.       FindWordPtr ;
  1001.       CheckPosition(X,Y) ;
  1002.       TempString := NullString ;
  1003.       i := WordPtr ;
  1004.       WHILE i <= EndOfLine DO 
  1005.         BEGIN
  1006.           TempString := TempString + CurrLinePtr^.Line[i] ;
  1007.           Inc(i) ;
  1008.         END ;
  1009.       TempString := TempString + InChar ;
  1010.       CurrLinePtr^.Line[0] := CHR(LengthThisLine - LENGTH(TempString) + 1) ;
  1011.       LineIdx := LENGTH(TempString) ;
  1012.       AddNode(TempString) ;
  1013.       Advance(CurrLinePtr) ;
  1014.       LineInBlock(CurrLinePtr) ;
  1015.       IF Y = BottomOfScreen THEN
  1016.         BEGIN
  1017.           Advance(ScrTopPtr) ;
  1018.           Dec(Y) ;
  1019.         END ;
  1020.       DrawScreen ;
  1021.       GotoXY(LineIdx + 1,Y + 1) ;
  1022.     END ;
  1023.  
  1024.   PROCEDURE WrapAround ;
  1025.     {If no wordwrap required, this adds a new node and continues writing}
  1026.     {characters at the beginning of the Next line}
  1027.  
  1028.     BEGIN
  1029.       CheckPosition(X,Y) ;
  1030.       LineIdx := 0 ;
  1031.       AddNode(NullString) ;
  1032.       Advance(CurrLinePtr) ;
  1033.       LineInBlock(CurrLinePtr) ;
  1034.       IF Y = BottomOfScreen THEN
  1035.         BEGIN
  1036.           Advance(ScrTopPtr) ;
  1037.           Dec(Y) ;
  1038.         END ;
  1039.       DrawScreen ;
  1040.       GotoXY(LineIdx + 1,Y + 1) ;
  1041.       AddChar ;
  1042.     END ;
  1043.  
  1044.   PROCEDURE EitherEndOfFile(WhichEnd:NotPtr) ;
  1045.     {Moves to very beginning or end of notes}
  1046.  
  1047.     BEGIN
  1048.       IF CurrLinePtr <> WhichEnd THEN
  1049.         BEGIN
  1050.           CurrLinePtr := WhichEnd ;
  1051.           ScrTopPtr := WhichEnd ;
  1052.           LineIdx := 0 ;
  1053.           DrawScreen ;
  1054.           GotoXY(BeginningOfLine,TopOfScreen) ;
  1055.         END
  1056.       ELSE 
  1057.         BeepSound ;
  1058.     END ;
  1059.  
  1060.   PROCEDURE EraseToEnd ;
  1061.     {Erases line from character at current cursor position to end of line}
  1062.  
  1063.     BEGIN
  1064.       IF ((LineIdx = 0) AND SpacesOnly) OR (LineIdx = LengthThisLine) THEN
  1065.         BeepSound
  1066.       ELSE 
  1067.         BEGIN
  1068.           CheckPosition(X,Y) ;
  1069.           CurrLinePtr^.Line[0] := CHR(X - 1) ;
  1070.           DrawScreen ;
  1071.           GotoXY(X,Y) ;
  1072.         END ;
  1073.     END ;
  1074.  
  1075.   PROCEDURE Search(StringToFind:Lines) ;
  1076.     {This procedure finds a string in the notes if it exists}
  1077.  
  1078.     TYPE
  1079.       StringIndex = 1..EndOfLine ;
  1080.       StringLength = 0..EndOfLine ;
  1081.  
  1082.     VAR 
  1083.       SubLength,FullLength,MatchCount,WindowPosition : StringLength ;
  1084.       SubIndex : StringIndex ;
  1085.  
  1086.     PROCEDURE FindString(StringToSearch:Lines) ;
  1087.       {This is the actual search routine}
  1088.  
  1089.       BEGIN
  1090.         MatchCount := 0 ;
  1091.         WindowPosition := 0 ;
  1092.         SubIndex := 1 ;
  1093.         FullLength := LENGTH(StringToSearch) ;
  1094.         WHILE (MatchCount < SubLength) AND ((WindowPosition + Sublength) <= 
  1095.                                             FullLength) DO 
  1096.           IF TempPtr^.Line[WindowPosition + SubIndex] = StringToFind[SubIndex] 
  1097.                  THEN
  1098.             BEGIN
  1099.               MatchCount := MatchCount + 1 ;
  1100.               SubIndex := SubIndex MOD SubLength + 1 ;
  1101.             END
  1102.           ELSE 
  1103.             BEGIN
  1104.               MatchCount := 0 ;
  1105.               WindowPosition := WindowPosition + 1 ;
  1106.             END ;
  1107.         IF MatchCount = SubLength THEN
  1108.           Found := TRUE
  1109.         ELSE 
  1110.           Found := FALSE ;
  1111.       END ;
  1112.     BEGIN
  1113.       SubLength := LENGTH(StringToFind) ;
  1114.       Found := FALSE ;
  1115.       TempPtr := CurrLinePtr ;
  1116.       WHILE (TempPtr <> NIL) AND NOT Found DO 
  1117.         BEGIN
  1118.           FindString(TempPtr^.Line) ;
  1119.           IF NOT Found THEN
  1120.             Advance(TempPtr) ;
  1121.         END ;
  1122.       IF Found THEN
  1123.         BEGIN
  1124.           CurrLinePtr := TempPtr ;
  1125.           ScrTopPtr := TempPtr ;
  1126.           IF WindowPosition = 0 THEN
  1127.             WindowPosition := 1 ;
  1128.           LineIdx := WindowPosition - 1 ;
  1129.           DrawScreen ;
  1130.           GotoXY(WindowPosition,TopOfScreen) ;
  1131.         END
  1132.       ELSE 
  1133.         BEGIN
  1134.           ClrScr ;
  1135.           GotoXY(5,4) ;
  1136.           RvsOn ;
  1137.           WRITE('Search String Not Found - Press Enter To Continue') ;
  1138.           READ ;
  1139.           RvsOff ;
  1140.           DrawScreen ;
  1141.           GotoXY(X,Y) ;
  1142.         END ;
  1143.     END ;
  1144.  
  1145.   PROCEDURE InsertChar ;
  1146.     {Inserts a character to the right of the cursor and pushes all other}
  1147.     {characters to the right}
  1148.  
  1149.     BEGIN
  1150.       CheckPosition(X,Y) ;
  1151.       IF (LengthThisLine < EndOfLine) AND (LineIdx >= 0) THEN
  1152.         BEGIN
  1153.           CurrLinePtr^.Line[0] := CHR(LengthThisLine + 1) ;
  1154.           FOR i := LengthThisLine DOWNTO LineIdx + 1 DO 
  1155.             BEGIN
  1156.               CurrLinePtr^.Line[i] := CurrLinePtr^.Line[i - 1] ;
  1157.               GotoXY(i,Y) ;
  1158.               WRITE(CurrLinePtr^.Line[i]) ;
  1159.             END ;
  1160.           GotoXY(X,Y) ;
  1161.           AddChar ;
  1162.         END
  1163.       ELSE 
  1164.         BeepSound ;
  1165.     END ;
  1166.  
  1167.   PROCEDURE WriteFile ;
  1168.     {This procedure writes the list of note line records to disk as a record}
  1169.     {the file must already have been opened with OpedFile}
  1170.  
  1171.     BEGIN
  1172.       TempPtr := NotTopPtr ;
  1173.       WHILE TempPtr <> NIL DO 
  1174.         BEGIN
  1175.           WRITELN(IntNotFile,TempPtr^.Line) ;
  1176.           Advance(TempPtr) ;
  1177.         END ;
  1178.       CLOSE(IntNotFile) ;
  1179.     END ;
  1180.  
  1181.   PROCEDURE ReadFile ;
  1182.     {This procedure reads a file of records and builds the internal}
  1183.     {line list while adjusting the screen top pointer, the note bottom}
  1184.     {pointer and the current line ptr. It also counts the records into}
  1185.     {the module golbal variable NotCt.  The file must have been previously}
  1186.     {opened by OpenFile}
  1187.  
  1188.     VAR 
  1189.       ALine : Lines ;
  1190.  
  1191.     BEGIN
  1192.       NEW(NotTopPtr) ;
  1193.       NotTopPtr^.Prev := NIL ;
  1194.       NotTopPtr^.Next := NIL ;
  1195.       NotTopPtr^.Line := NullString ;
  1196.       NotTopPtr^.InBlock := FALSE ;
  1197.       READLN(IntNotFile,NotTopPtr^.Line) ;
  1198.       CurrLinePtr := NotTopPtr ;
  1199.       ScrTopPtr := NotTopPtr ;
  1200.       NotBotPtr := NotTopPtr ;
  1201.       NotCt := 1 ;
  1202.       WHILE NOT EOF(IntNotFile) DO 
  1203.         BEGIN
  1204.           READLN(IntNotFile,ALine) ;
  1205.           AddNode(ALine) ;
  1206.           LineInBlock(CurrLinePtr) ;
  1207.           CurrLinePtr := NotBotPtr ;
  1208.         END ;
  1209.       CurrLinePtr := NotTopPtr ;
  1210.       CLOSE(IntNotFile) ;
  1211.     END ;
  1212.  
  1213.   PROCEDURE OpenFile(Resett:BOOLEAN) ;
  1214.     {This procedure opens the file with the specified name in the variable}
  1215.     {notfile for either reading or writing depending upon the value of the}
  1216.     {the boolean resett.  If true the file is opened for reading, otherwise}
  1217.     {it is opened for writing}
  1218.  
  1219.     BEGIN
  1220.       Assign(IntNotFile,NotFile) ;
  1221.       {$I-}
  1222.       IF Resett THEN
  1223.         RESET(IntNotFile)
  1224.       ELSE 
  1225.         REWRITE(IntNotFile) ;
  1226.       {$I+}
  1227.       Ok := (IOResult = 0) ;
  1228.       i := 0 ;
  1229.       WHILE ( NOT Ok) AND (i < 2) DO 
  1230.         BEGIN
  1231.           ClrScr ;
  1232.           Inc(i) ;
  1233.           GotoXY(11,2) ;
  1234.           TextColor(15) ;
  1235.           RvsOn ;
  1236.           WRITE('Error With Disk Or Incorrect File Name !') ;
  1237.           RvsOff ;
  1238.           GotoXY(7,4) ;
  1239.           TextColor(7) ;
  1240.           WRITE('Please Check ') ;
  1241.           WRITE(' Drive and Press Enter When Ready') ;
  1242.           READ ;
  1243.           ClrScr ;
  1244.           {$I-}
  1245.           IF Resett THEN
  1246.             RESET(IntNotFile)
  1247.           ELSE 
  1248.             REWRITE(IntNotFile) ;
  1249.           {$I+}
  1250.           Ok := (IOResult = 0) ;
  1251.         END ;
  1252.       SetNoteColors ;
  1253.     END ;
  1254.  
  1255.   PROCEDURE SaveFile ;
  1256.  
  1257.     BEGIN
  1258.       ClrScr ;
  1259.       GotoXY(12,7) ;
  1260.       WRITE('Do You Want To Save Notes (Y/N) ?') ;
  1261.       REPEAT
  1262.         ReadKeyStroke(InChar,FuncKey) ;
  1263.         InChar := UpCase(InChar) ;
  1264.         IF InChar = 'Y' THEN
  1265.           BEGIN
  1266.             REPEAT
  1267.               OpenFile(WriteIt) ;
  1268.             UNTIL Ok ;
  1269.             WriteFile ;
  1270.           END
  1271.         ELSE IF InChar = 'N' THEN
  1272.           BEGIN
  1273.             GotoXY(20,8) ;
  1274.             WRITE('Are You Sure (Y/N) ?') ;
  1275.             ReadKeyStroke(InChar,FuncKey) ;
  1276.             InChar := UpCase(InChar) ;
  1277.           END
  1278.         ELSE 
  1279.           BeepSound ;
  1280.       UNTIL InChar IN ['Y','N'] ;
  1281.       IF InChar = 'N' THEN
  1282.         BEGIN
  1283.           REPEAT
  1284.             OpenFile(WriteIt) ;
  1285.           UNTIL Ok ;
  1286.           WriteFile ;
  1287.         END ;
  1288.     END ;
  1289.  
  1290.   PROCEDURE GetFileName ;
  1291.     {Gets the file name}
  1292.  
  1293.     VAR 
  1294.       FirstCharNum : BOOLEAN ;
  1295.  
  1296.     BEGIN
  1297.       NotFile := NullString ;
  1298.       GotoXY(29,6) ;
  1299.       ClrEol ;
  1300.       GotoXY(29,6) ;
  1301.       RvsOn ;
  1302.       WRITE('            ') ;
  1303.       RvsOff ;
  1304.       GotoXY(29,6) ;
  1305.       REPEAT
  1306.         IF (NotFile = NullString) AND (InChar IN [#48..#57]) THEN
  1307.           FirstCharNum := TRUE
  1308.         ELSE 
  1309.           FirstCharNum := FALSE ;
  1310.         WHILE FuncKey OR NOT (InChar IN [#8,#13,#46,#65..#90,#48..#57]) OR 
  1311.                FirstCharNum DO 
  1312.           BEGIN
  1313.             BeepSound ;
  1314.             ReadKeyStroke(InChar,FuncKey) ;
  1315.             InChar := UpCase(InChar) ;
  1316.             IF (NotFile = NullString) AND (InChar IN [#48..#57]) THEN
  1317.               FirstCharNum := TRUE
  1318.             ELSE 
  1319.               FirstCharNum := FALSE ;
  1320.           END ;
  1321.         IF (InChar = #8) AND NOT (NotFile = NullString) THEN
  1322.           BEGIN
  1323.             CheckPosition(X,Y) ;
  1324.             GotoXY(X - 1,Y) ;
  1325.             RvsOn ;
  1326.             WRITE(Blank) ;
  1327.             RvsOff ;
  1328.             GotoXY(X - 1,Y) ;
  1329.             NotFile[0] := CHR(LENGTH(NotFile) - 1) ;
  1330.           END
  1331.         ELSE IF (InChar = #8) AND (NotFile = NullString) THEN
  1332.           BeepSound ;
  1333.         IF InChar IN [#65..#90,#46,#48..#57] THEN
  1334.           BEGIN
  1335.             WRITE(InChar) ;
  1336.             NotFile := NotFile + InChar ;
  1337.           END ;
  1338.         ReadKeyStroke(InChar,FuncKey) ;
  1339.         InChar := UpCase(InChar) ;
  1340.       UNTIL (LENGTH(NotFile) = 12) OR (InChar = #13) ;
  1341.       IF NotFile = NullString THEN
  1342.         NotFile := 'DEFAULT.DOC' ;
  1343.       GotoXY(x -1,y);  {### This is a guess original (}
  1344. end;
  1345.  
  1346. procedure FileDriver ;
  1347.     {This procedure is called by notepad when initializing.  It prints the}
  1348.     {default file name and prompts for a new file name.  If enter is pressed,}
  1349.     {the default file is loaded otherwise the user is asked weather the file is}
  1350.     {a new file, if so no file is opened but the screen is drawn and the cursor}
  1351.     {is positioned at the first column, first row.  If it is an old file, the}
  1352.     {file is opened and read and the screen drawn}
  1353.  
  1354.     BEGIN
  1355.       REPEAT
  1356.         Ok := FALSE ;
  1357.         ClrScr ;
  1358.         GotoXY(19,3) ;
  1359.         WRITE('Please Enter a New FileName') ;
  1360.         GotoXY(30,4) ;
  1361.         WRITE('OR') ;
  1362.         GotoXY(19,5) ;
  1363.         WRITE('Press <ENTER> for Default File') ;
  1364.         GotoXY(19,6) ;
  1365.         WRITE('FileName: ') ;
  1366.         GotoXY(29,6) ;
  1367.         WRITE('DEFAULT.DOC') ;
  1368.         REPEAT
  1369.           ReadKeyStroke(InChar,FuncKey) ;
  1370.           InChar := UpCase(InChar) ;
  1371.           IF FuncKey THEN
  1372.             BeepSound ;
  1373.         UNTIL NOT FuncKey ;
  1374.         IF (InChar IN ['A'..'Z','a'..'z']) THEN
  1375.           BEGIN
  1376.             GetFileName ;
  1377.             GotoXY(19,8) ;
  1378.             WRITE('Is This a New File (Y/N) ? ') ;
  1379.             REPEAT
  1380.               ReadKeyStroke(InChar,FuncKey) ;
  1381.               InChar := UpCase(InChar) ;
  1382.               IF InChar = 'Y' THEN
  1383.                 StartFresh
  1384.               ELSE IF InChar = 'N' THEN
  1385.                 BEGIN
  1386.                   OpenFile(ReadIt) ;
  1387.                   IF OK THEN
  1388.                     BEGIN
  1389.                       ReadFile ;
  1390.                       CheckPosition(X,Y) ;
  1391.                       DrawScreen ;
  1392.                       GotoXY(BeginningOfLine,TopOfScreen) ;
  1393.                     END ;
  1394.                 END
  1395.               ELSE 
  1396.                 BeepSound ;
  1397.             UNTIL InChar IN ['Y','N'] ;
  1398.           END
  1399.         ELSE IF InChar = #13 THEN
  1400.           BEGIN
  1401.             NotFile := 'Default.Doc' ;
  1402.             OpenFile(ReadIt) ;
  1403.             IF OK THEN
  1404.               BEGIN
  1405.                 ReadFile ;
  1406.                 CheckPosition(X,Y) ;
  1407.                 DrawScreen ;
  1408.                 GotoXY(BeginningOfLine,TopOfScreen) ;
  1409.               END ;
  1410.           END
  1411.         ELSE 
  1412.           BeepSound ;
  1413.       UNTIL OK ;
  1414.     END ;
  1415.  
  1416.   PROCEDURE BigCase ;
  1417.     {Case to act on extended code keys}
  1418.  
  1419.     BEGIN
  1420.       CASE InChar OF 
  1421.         #23 : IF NotCt < MaxLines THEN
  1422.                 InsertLine
  1423.               ELSE 
  1424.                 BeepSound ;
  1425.         #32 : IF NotCt > 1 THEN
  1426.                 DeleteLine
  1427.               ELSE 
  1428.                 BEGIN
  1429.                   BeepSound ;
  1430.                   StartFresh ;
  1431.                 END ;
  1432.         #48 : MarkBegin ;
  1433.         #18 : MarkEnd ;
  1434.         #47 : IF OkToMove THEN
  1435.                 MoveBlock
  1436.               ELSE 
  1437.                 BeepSound ;
  1438.         #22 : UnMarkBlock ;
  1439.         #72 : MoveCursor(Up) ;
  1440.         #80 : MoveCursor(Down) ;
  1441.         #75 : MoveCursor(Left) ;
  1442.         #77 : MoveCursor(Right) ;
  1443.         #82 : BEGIN
  1444.                 CursorSize(RealBigCursor) ;
  1445.                 ReadKeyStroke(InChar,FuncKey) ;
  1446.                 WHILE NOT (FuncKey AND (InChar = #82)) DO 
  1447.                   BEGIN
  1448.                     IF (InChar IN [#32..#125]) AND NOT (FuncKey) THEN
  1449.                       InsertChar
  1450.                     ELSE 
  1451.                       BeepSound ;
  1452.                     ReadKeyStroke(InChar,FuncKey) ;
  1453.                   END ;
  1454.                 CursorSize(BigCursor) ;
  1455.               END ;
  1456.         #73 : BEGIN
  1457.                 CheckPosition(X,Y) ;
  1458.                 PageUp ;
  1459.                 SetCursor(X,Y) ;
  1460.               END ;
  1461.         #19 : IF OkToMove THEN
  1462.                 DeleteBlock
  1463.               ELSE 
  1464.                 BeepSound ;
  1465.         #24 : SortBlock ;
  1466.         #33 : BEGIN
  1467.                 CheckPosition(X,Y) ;
  1468.                 ClrScr ;
  1469.                 SearchString := NullString ;
  1470.                 GotoXY(2,4) ;
  1471.                 WRITE('ENTER SEARCH STRING: ') ;
  1472.                 READLN(SearchString) ;
  1473.                 Search(SearchString) ;
  1474.               END ;
  1475.         #71 : Home ;
  1476.         #79 : GoToEnd ;
  1477.         #34 : EitherEndOfFile(NotTopPtr) ;
  1478.         #49 : EitherEndOfFile(NotBotPtr) ;
  1479.         #46 : EraseToEnd ;
  1480.         #59 : DispHelp ;
  1481.         #81 : BEGIN
  1482.                 CheckPosition(X,Y) ;
  1483.                 PageDown ;
  1484.                 SetCursor(X,Y) ;
  1485.               END ;
  1486.         #83 : DeleteCharRight ;
  1487.         ELSE
  1488.           BeepSound ;
  1489.       END ;
  1490.     END ;
  1491.  
  1492.   PROCEDURE LittleCase ;
  1493.     {Case to act on non-extended code keys}
  1494.  
  1495.     BEGIN
  1496.       CASE InChar OF 
  1497.         #32..#125 : BEGIN
  1498.                       IF (LengthThisLine = EndOfLine) AND ThereIsASpace AND (
  1499.                              LineIdx = EndOfLine) THEN
  1500.                         WordWrap
  1501.                       ELSE IF (LengthThisLine = EndOfLine) AND (LineIdx = 
  1502.                              EndOfLine) THEN
  1503.                         WrapAround
  1504.                       ELSE 
  1505.                         AddChar ;
  1506.                     END ;
  1507.         #8 : DeleteCharLeft ;
  1508.         #9 : Tab ;
  1509.         #13 : IF NotCt < MaxLines THEN
  1510.                 BEGIN
  1511.                   CheckPosition(X,Y) ;
  1512.                   LineIdx := 0 ;
  1513.                   WordPtr := BeginningOfLine ;
  1514.                   AddNode(NullString) ;
  1515.                   Advance(CurrLinePtr) ;
  1516.                   LineInBlock(CurrLinePtr) ;
  1517.                   IF Y = BottomOfScreen THEN
  1518.                     Advance(ScrTopPtr)
  1519.                   ELSE 
  1520.                     Inc(Y) ;
  1521.                   DrawScreen ;
  1522.                   GotoXY(BeginningOfLine,Y) ;
  1523.                 END
  1524.               ELSE 
  1525.                 BeepSound ;
  1526.         ELSE IF NOT (InChar = #27) THEN
  1527.           BeepSound ;
  1528.       END ;
  1529.     END ;
  1530.  
  1531.   PROCEDURE GetUserInput ;
  1532.  
  1533.     BEGIN
  1534.       REPEAT
  1535.         ReadKeyStroke(InChar,FuncKey) ;
  1536.         IF NotCt = MaxLines THEN
  1537.           IF (FuncKey AND (InChar = #23)) OR (InChar = #13) OR ( NOT FuncKey 
  1538.                  AND (InChar IN [#32..#125]) AND (LengthThisLine = EndOfLine) 
  1539.                  AND (LineIdx = EndOfLine)) OR ((InChar = #82) AND (
  1540.                                                 LengthThisLine = EndOfLine)) 
  1541.                  THEN
  1542.             BEGIN
  1543.               ClrScr ;
  1544.               GotoXY(17,5) ;
  1545.               WRITE('         Edit Full - Leaving Edit') ;
  1546.               Delay(3000) ;
  1547.               Exit ;
  1548.             END ;
  1549.         IF FuncKey THEN
  1550.           BigCase
  1551.         ELSE 
  1552.           LittleCase ;
  1553.       UNTIL (InChar = #27) ;
  1554.     END ;
  1555.   {=============================================================}
  1556.   {                MAIN NOTEPAD                                 }
  1557.   {=============================================================}
  1558.  
  1559.   BEGIN
  1560.     DetermineDisplay ;
  1561.     InitializePad ;
  1562.     NotFile := NullString ;
  1563.     NotCt := 0 ;
  1564.     BeginPtr := NIL ;
  1565.     EndPtr := NIL ;
  1566.     BlockBeginMarked := FALSE ;
  1567.     BlockEndMarked := FALSE ;
  1568.     FileDriver ;
  1569.     GetUserInput ;
  1570.      SaveFile ;
  1571.     CursorSize(NoCursor) ;
  1572.     SetSystemColors ;
  1573.     CursorSize(SmallCursor) ;
  1574.     ClrScr ;
  1575.   END.
  1576.