home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / txtutl / spel204.arc / SPELWELL.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1987-05-16  |  11.9 KB  |  504 lines

  1. program SPELWELL (input,output);
  2.  
  3. const
  4.  
  5.   version         ='2.04';
  6.   dictionary_file ='DX.DAT';
  7.   spellfile       ='MISSPELL.DAT';
  8.   dxsize          = 3855; {max number words in dictionary}
  9.   wordlen         = 16;
  10.   listsize        = 1000; {max number misspelled words}
  11.  
  12. type
  13.  
  14.   dxtype   = array[1..dxsize] of string[wordlen];
  15.   dxptr    = ^dxtype;
  16.   line     = string[80];
  17.  
  18. var
  19.  
  20.   ch,
  21.   choice      :char;
  22.   dxfile,
  23.   infile,
  24.   mispfile    : text;
  25.   entry       : dxptr; {dictionary entry}
  26.   list        : array [0..listsize] of string[wordlen]; {misspelled list}
  27.   num_entries,
  28.   wordno      : integer;
  29.   filename    : string[14];
  30.   i,j,k,
  31.   pos,
  32.   size        : integer;
  33.   word        : string[16];
  34.   yes         : boolean;
  35.   endoftext,
  36.   found,
  37.   goodfile    : boolean;
  38.   suffix1     : char;
  39.   suffix2     : string[2];
  40.  
  41. procedure alarm;
  42. var
  43.   num:integer;
  44. begin
  45.   num:=0;
  46.   repeat
  47.     write(#7);
  48.     delay(100);
  49.     write(#7);
  50.     delay(300);
  51.     num:=num+1;
  52.   until (num=10) or keypressed;
  53. end;
  54.  
  55. function allcaps(instring:line):line;
  56. var
  57.   temp:line;
  58. begin
  59.   temp:='';
  60.   for j:=1 to length(instring) do temp:=temp+upcase(instring[j]);
  61.   allcaps:=temp;
  62. end;
  63.  
  64. procedure beep;begin write(chr(7));end;
  65.  
  66. procedure dashline;
  67.   begin
  68.    writeln('==============================================================================');
  69.   end;
  70.  
  71. procedure query(bias:boolean);
  72. var
  73.   yesno       :char;
  74. begin
  75.   yes:=bias;
  76.   readln(yesno);
  77.   if yesno in ['Y','y'] then yes:=true;
  78.   if yesno in ['N','n'] then yes:=false;
  79. end;
  80.  
  81. procedure waitkey;begin
  82.   writeln;
  83.   write('* Press any key to continue ');
  84.   repeat until keypressed;
  85. end;
  86.  
  87. procedure read_file;
  88. var
  89.   i: integer;
  90. begin
  91.   assign(dxfile,dictionary_file);
  92.   reset(dxfile);
  93.   i:=0;
  94.   while not eof(dxfile) do begin
  95.       i:=i+1;
  96.       readln(dxfile,entry^[i]);
  97.     end;
  98.   close(dxfile);
  99.   num_entries:=i;
  100. end;
  101.  
  102. procedure test_filename;begin
  103.   goodfile:=false;
  104.   assign(infile,filename);
  105.   {$I-} reset(infile) {$I+};
  106.   goodfile:=(ioresult=0);
  107. end;
  108.  
  109. procedure show_directory;
  110. type
  111.   entrytype   = string[12];
  112.   result_type = record
  113.                  ax,bx,cx,dx,bp,si,di,ds,es,flags:integer;
  114.                end;
  115. const
  116.   maxfiles = 64;
  117.   fcb1     = $5C;
  118.   fcb      = $80;
  119. var
  120.   num_entries,
  121.   num_rows,
  122.   i,j,k:integer;
  123.   dtabuf:array[1..130] of byte;
  124.   drive:integer;
  125.   dir_buf:array[1..maxfiles] of entrytype;
  126.   result:result_type;
  127.   x:integer;
  128.  
  129.     procedure shell_sort;
  130.     var
  131.       done  :boolean;
  132.       jump,
  133.       i,
  134.       j,
  135.       swno  :integer;
  136.  
  137.     function firstjump(length: integer): integer;
  138.     var
  139.       temp : integer;
  140.     begin
  141.       temp:=1;
  142.       while temp<=length do
  143.         temp:=temp*2;
  144.       firstjump:=temp
  145.     end;
  146.  
  147.     procedure swap (var p,q: entrytype);
  148.     var
  149.       hold :entrytype;
  150.     begin
  151.       hold:=p;
  152.       p:=q;
  153.       q:=hold
  154.     end;
  155.  
  156.     begin
  157.       swno:=0;
  158.       jump:=firstjump(num_entries);
  159.       while jump>1 do begin
  160.         jump:=(jump-1) div 2;
  161.           repeat
  162.             done:=true;
  163.             for j:=1 to num_entries-jump do begin
  164.               i:=j+jump;
  165.               if dir_buf[j]>dir_buf[i] then begin
  166.                 swno:=swno+1;
  167.                 swap(dir_buf[j],dir_buf[i]);
  168.                 done:=false;
  169.               end;
  170.             end;
  171.           until done
  172.       end;
  173.     end;
  174.  
  175. begin {dir}
  176.   drive:=0;
  177.   writeln;write('* Enter drive (1="A", 2="B", 3="C") > ');
  178.   readln(drive);writeln;
  179.   mem[seg(dtabuf[1]):$5c]:=drive;   {default drive}
  180.   for i:=1 to 11 do begin mem[seg(dtabuf[1]):$5c+i]:=ord('?');end;
  181.   for i:=12 to 36 do begin mem[seg(dtabuf[1]):$5c+i]:=0;end;
  182.   fillchar(dir_buf,sizeof(dir_buf),' ');
  183.   i:=1;
  184.   with result do begin
  185.     dx:=ofs(dtabuf[1]);    {offset of DTA}
  186.     ax:=$1a shl 8;        {set AH=26}
  187.     ds:=seg(dtabuf[1]);
  188.   end;
  189.   msdos(result);
  190.   with result do begin
  191.     dx:=$5c;
  192.     ax:=$11 shl 8;           {set AH=$11}
  193.     ds:=seg(dtabuf[1]);
  194.   end;
  195.   msdos(result);
  196.   with result do begin
  197.     j:=ax and $00ff;      {result in AL}
  198.   end;
  199.   if j<255
  200.   then begin
  201.     dtabuf[j*32+1]:=11;
  202.     move(dtabuf[j*32+1],dir_buf[i],12);
  203.     with result do begin
  204.       DX:=$005c;
  205.       AX:=$12 shl 8;
  206.       ds:=seg(dtabuf[1]);
  207.     end;
  208.     msdos(result);
  209.     with result do begin
  210.       j:=ax and $00ff;
  211.     end;
  212.     while j<255 do begin
  213.       i:=i+1;
  214.       dtabuf[j*32+1]:=11;
  215.       move(dtabuf[j*32+1],dir_buf[i],12);
  216.       with result do begin
  217.         DX:=$005c;
  218.         AX:=$12 shl 8;
  219.         ds:=seg(dtabuf[1]);
  220.       end;
  221.       msdos(result);
  222.       with result do begin j:=ax and $00ff;end;
  223.     end;
  224.     with result do begin
  225.       DX:=fcb;
  226.       AX:=$1a shl 8;
  227.     end;
  228.     msdos(result);
  229.     for j:=1 to i do insert('.',dir_buf[j],9);
  230.     num_entries:=i;
  231.     shell_sort;
  232.     num_rows:=(i div 5);
  233.     if i mod 5>0 then num_rows:=num_rows+1;
  234.     for i:=num_entries+1 to num_rows*5 do dir_buf[i]:='';
  235.     j:=1;
  236.     while j<=num_rows do begin
  237.       for k:=0 to 4 do write(dir_buf[j+k*num_rows],'  ');
  238.       writeln;
  239.       j:=j+1
  240.     end;
  241.   end;
  242. end; {dir}
  243.  
  244. procedure lowercase;begin
  245.   if ord(ch)<91 then ch:=chr(ord(ch)+32);
  246. end;
  247.  
  248. procedure getnextword;
  249. type
  250.   spaceset=set of char;
  251.   wordset=set of char;
  252. var
  253.   spacechars:spaceset;
  254.   wordchars:wordset;
  255. begin
  256.   word:='';
  257.   wordchars:=['A'..'Z','a'..'z'];
  258.   spacechars:=[chr(10),chr(13),chr(23),' '..'/',':'..'@','['..'`','{'..'~','0'..'9',chr(208)];
  259.   if not eof(infile) then          {find beginning of word}
  260.     repeat
  261.       read(infile,ch);
  262.     until (ch in wordchars) or eof(infile);
  263.   if not eof(infile) then begin
  264.       repeat
  265.         lowercase;
  266.         word:=word+ch;
  267.         read(infile,ch);
  268.       until (ch in spacechars) or eof(infile);
  269.     end
  270.   else endoftext:=true;
  271. end;
  272.  
  273. procedure bsearch;
  274.  
  275. var
  276.   lower,
  277.   upper,
  278.   center : integer;
  279.  
  280. begin
  281.   lower:=1;
  282.   upper:=num_entries;
  283.   found:=false;
  284.   while (upper>=lower) and (not found) do begin
  285.     center:=(lower+upper) div 2;
  286.     if word=entry^[center] then begin
  287.         found:=true;
  288.       end
  289.     else
  290.       if word>entry^[center] then
  291.         lower:=center+1
  292.       else
  293.         upper:=center-1
  294.   end;
  295.   wordno:=center;
  296. end;
  297.  
  298. procedure addtolist;
  299. var
  300.   word_found     : boolean;
  301.   i,
  302.   j              : 1..listsize;
  303.   position       : integer;
  304.  
  305.   procedure find_position;
  306.  
  307.   var
  308.     bottom_list,
  309.     top_list            : integer;
  310.  
  311.   begin
  312.     bottom_list:=1;
  313.     top_list:=size;
  314.     word_found:=false;
  315.     while (top_list>=bottom_list) and (not word_found) do begin
  316.       position:=(bottom_list+top_list) div 2;
  317.       if word=list[position] then begin
  318.           word_found:=true;
  319.         end
  320.       else
  321.         if word>list[position] then
  322.           bottom_list:=position+1
  323.         else
  324.           top_list:=position-1
  325.     end;
  326.   end;
  327.  
  328. begin
  329.   find_position;
  330.   if not word_found then begin
  331.     size:=size+1;
  332.     if word>list[position] then position:=position+1;
  333.     for j:=size downto position do list[j]:=list[j-1];
  334.     list[position]:=word;
  335.   end;
  336. end;
  337.  
  338. procedure screen;
  339. var
  340.   i : integer;
  341. begin
  342.   writeln;writeln;
  343.   for i:=2 to size-1 do begin
  344.     writeln(i-1,'  ',list[i]);
  345.     if i mod 23=0 then repeat until keypressed;
  346.   end;
  347. end;
  348.  
  349. procedure single;
  350. var
  351.   i : integer;
  352. begin
  353.   writeln(lst,'          File = ',filename,'     No. Misspelled Words = ',size-2);writeln(lst);
  354.   for i:=2 to size-1 do begin
  355.     writeln(lst,'          ',list[i]);
  356.     if i mod 53=0 then begin
  357.         writeln;writeln('Change paper and press any key to continue');
  358.         repeat until keypressed;
  359.       end;
  360.   end;
  361. end;
  362.  
  363. procedure continuous;
  364. var
  365.   i : integer;
  366.  
  367. begin
  368.   writeln(lst);writeln(lst);writeln(lst);writeln(lst);writeln(lst);
  369.   writeln(lst,'          File = ',filename,'     No. Misspelled Words = ',size-2);writeln(lst);
  370.   for i:=2 to size-1 do begin
  371.     writeln(lst,'          ',list[i]);
  372.     if i mod 53=0
  373.     then begin
  374.       writeln(lst);writeln(lst);writeln(lst);writeln(lst);writeln(lst);
  375.       writeln(lst);writeln(lst);writeln(lst);writeln(lst);writeln(lst);
  376.     end;
  377.   end;
  378. end;
  379.  
  380. procedure disk;
  381. var
  382.   i: integer;
  383. begin
  384.   assign(mispfile,spellfile);
  385.   rewrite(mispfile);
  386.   for i:=2 to size-1 do begin
  387.     writeln(mispfile,list[i]);
  388.   end;
  389.   close(mispfile);
  390. end;
  391.  
  392. procedure output_list;begin
  393.   writeln('* A disk file of "misspelled" words will automatically be created.');
  394.   writeln;write('  Printed List Also ? (Y/N) <Y> ');
  395.   query(true);
  396.   if yes then begin
  397.     writeln;writeln('* Select Printed Output To:');writeln;
  398.     writeln('  1 - Screen');
  399.     writeln('  2 - Printer, Single Sheet');
  400.     writeln('  3 - Printer, Continuous Form');
  401.     writeln('  4 - Omit Printout');writeln;
  402.     write('  Choice --> ');readln(choice);
  403.     case choice of
  404.     '1':screen;
  405.     '2':single;
  406.     '3':continuous;
  407.     end;
  408.   end;
  409. end;
  410.  
  411. procedure initialize;
  412. var
  413.   i : integer;
  414.  
  415. begin
  416.   for i:=1 to listsize do list[i]:='';
  417.   list[1]:='!!!!!!!!!!!!!!!!';
  418.   list[2]:='~~~~~~~~~~~~~~~~';
  419.   size:=2;
  420.   endoftext:=false;
  421. end;
  422.  
  423. procedure title;begin
  424.   clrscr;
  425.   dashline;
  426.   writeln('SPELWELL  Ver. ',version,'  Copr. 1985, 1987  M. Lee Murrah.  All Rights Reserved.');
  427.   dashline;writeln;
  428.   writeln('A simple spelling checker program.  Users are granted the right to');
  429.   writeln('make and transfer copies so long as no consideration is charged.  Author');
  430.   writeln('reserves exclusive right to prepare updates and derivative works for dist-');
  431.   writeln('ribution.  Suggestions for changes and improvements, and information regarding');
  432.   writeln('bugs should be directed to the author at 10 Cottage Grove Woods, SE, Cedar');
  433.   writeln('Rapids, IA 52403, Tel: 319-365-6530.');
  434.   writeln;writeln;write('* Loading Dictionary > ');
  435.   read_file;
  436.   writeln(num_entries,' entries');
  437.   initialize;
  438.   waitkey;
  439. end;
  440.  
  441. begin
  442.   new(entry);
  443.   title;
  444.   clrscr;
  445.   dashline;
  446.   writeln('SPELWELL  Ver. ',version,' Copr. 1985, 1987  M. Lee Murrah.  All Rights Reserved.');
  447.   dashline;writeln;
  448.   repeat
  449.     writeln;write('* Enter name of file to be checked > ');readln(filename);
  450.     filename:=allcaps(filename);writeln;
  451.     if filename<>'QUIT' then begin
  452.       test_filename;
  453.       if not goodfile then begin
  454.         writeln('  BAD FILE NAME');writeln;beep;
  455.         write('* Do you want a directory listing (Y/N) <N> ? > ');query(false);
  456.         if yes then show_directory;
  457.       end
  458.     end;
  459.   until goodfile or (filename='QUIT');
  460.   if filename<>'QUIT' then begin
  461.     write('* Working...');
  462.     assign(infile,filename);
  463.     reset(infile);
  464.     getnextword;
  465.     while not endoftext do begin
  466.         bsearch;
  467.         if not found then begin
  468.             suffix1:=copy(word,length(word),1);
  469.             if suffix1 in ['d','s'] then begin
  470.                 word:=copy(word,1,length(word)-1);
  471.                 bsearch;
  472.                 if not found then word:=word+suffix1;
  473.               end;
  474.             if length(word)>2 then begin
  475.               suffix2:=copy(word,length(word)-1,2);
  476.               if (suffix2='ed') or (suffix2='es') then begin
  477.                   word:=copy(word,1,length(word)-2);
  478.                   bsearch;
  479.                    if not found then word:=word+suffix2
  480.                 end;
  481.             end;
  482.           end;
  483.         if not found and (length(word)>1) then
  484.           addtolist;
  485.         getnextword;
  486.       end;
  487.     close(infile);
  488.     writeln;writeln;
  489.     writeln('  Number misspelled or missing words > ',size-2);
  490.     writeln;write('* Spelling check completed. Press any key to continue. ');
  491.     alarm;writeln;writeln;
  492.     if size>2 then begin
  493.         output_list;
  494.         waitkey;
  495.         writeln;writeln;write('* Outputting misspelled words to disk file [MISSPELL.DAT]');
  496.         disk;writeln;
  497.       end
  498.     else begin
  499.         writeln('* No misspelled words in document');
  500.       end;
  501.   end;
  502.   writeln;writeln('* Thanks for using SPELWELL');writeln;
  503. end.
  504.