home *** CD-ROM | disk | FTP | other *** search
- {$S+}{}
- program index(input,output) ;
-
- {
- This PASCAL MT+ index generator program is placed in
- the public domain on the understanding that it is for
- non-profit redistribution via individuals for through
- RCPM systems
- Donated 23/6/83
- Matthew Starr P.O. Box 25 Wahroonga N.S.W 2076
- Australia
-
- Matthew Starr 13/12/81
-
- WordStar index generator program which will
- read through WordStar disk file output files
- and include strings delimited by ^Q and ^W as
- Major and Minor references respectively, creating
- an index which is then sorted and output as a
- WordStar source file.
-
- A required option for the Disk-file print is
- form feed page separation. (See procedure HELP)
- }
-
- const
- main_code = 17 ; {code for boldface ref}
- sub_code = 23 ; {code for normal ref}
- bold_code = 2 ; {makes it boldface}
- formfeed = 12 ;
- stringz = 50 ; {P.S. also change assgmnt}
- max_entries = 500 ; {max # different entries}
- max_refs = 5 ; {max # refs of either type}
-
-
- type
- my_string = packed array[1 .. stringz] of char ;
- pointer = ^entry_type ;
- entry_type =
- record
- subject : my_string ;
- n_mains : integer ;
- mains : array[1 .. max_refs] of integer ;
- n_subs : integer ;
- subs : array[1 .. max_refs] of integer ;
- end ; { entry decl. }
- table_type = array[1 .. maxentries] of pointer ;
-
- ws_file = file of char ;
- index_file = file of entry_type ;
-
-
- var
- index : index_file ;
- text_in : ws_file ;
- text_out : text ;
-
- end_file : entry_type ;
- table : table_type ;
- filename,response : string ;
- i, num_entries, result : integer ;
-
-
- procedure addentry(var table:table_type; var tablength:integer; newentry:entry_type) ;
-
- begin
- if tablength >= max_entries
- then writeln('Too many entries - entry table full')
- else
- begin
- tablength := tablength+1 ;
- new(table[tablength]) ;
- table[tablength]^ := newentry
- end { else there is room }
- end;
-
-
- procedure readarray(var name:my_string) ;
-
- var
- ch : char;
- nameindex : 0 .. stringz;
-
- procedure uppercase(var ch:char) ;
- begin
- if ord(ch)>127
- then ch := chr( ord(ch) - 128 ) ;
- if (ch >= 'a') and (ch <='z')
- then ch := chr( ord(ch)-(ord('a')-ord('A')) );
- end ; {uppercase}
-
- begin
- name := ' ' ;
- nameindex := 0 ;
- read(text_in,ch) ;
- uppercase(ch) ;
- while (name_index<stringz)
- and (ord(ch)<>main_code) and (ord(ch)<>sub_code) do
- begin
- nameindex := nameindex+1 ;
- name[nameindex] := ch ;
- read(text_in,ch) ;
- uppercase(ch)
- { and throw away terminating control code }
- end {while}
- end ; {readarray}
-
-
- procedure get_main
- (var table:tabletype; var tablength:integer; var page, created, added_to:integer);
-
- var
- name: my_string;
- this_entry: entry_type;
- i: integer;
-
- begin
- readarray(name);
- i := 1 ;
- while (i<=num_entries) and (name<>table[i]^.subject) do
- i:=i+1 ;
- if i>num_entries { i.e. if not found }
-
- then
- begin { create a new entry }
- with this_entry do
- begin
- created := created + 1 ;
- subject := name ;
- n_mains := 1 ;
- n_subs := 0 ;
- mains[1] := page
- end { with } ;
- addentry(table,tablength,this_entry)
- end {then}
-
- else {add to the ith entry}
- with table[i]^ do
- begin
- added_to := added_to + 1 ;
- if n_mains >= max_refs
- then
- writeln('Too many main references to ',subject)
- else
- begin
- n_mains := n_mains+1 ;
- mains[n_mains] := page
- end {else}
- end {with}
- end ; {get_main}
-
-
- procedure get_sub
- (var table:tabletype; var tablength:integer; var page, created, added_to:integer);
-
- var
- name: my_string;
- this_entry: entry_type;
- i: integer;
-
- begin
- readarray(name);
- i := 1 ;
- while (i<=num_entries) and (name<>table[i]^.subject) do
- i:=i+1 ;
-
- if i>num_entries {i.e. was it found ?}
- then
- begin { create a new entry }
- with this_entry do
- begin
- created := created + 1 ;
- subject := name ;
- n_mains := 0 ;
- n_subs := 1 ;
- subs[1] := page ;
- end { with } ;
- addentry(table,tablength,this_entry)
- end {then}
-
- else
- with table[i]^ do
- begin
- added_to := added_to + 1 ;
- if n_subs >= max_refs
- then
- writeln('Too many minor references to ',subject)
- else
- begin
- n_subs := n_subs+1 ;
- subs[n_subs] := page
- end {else}
- end {with}
- end ; {get_sub}
-
-
- procedure scanfile
- (var table:tabletype; var tablength:integer; filename:string);
-
- var
- ch:char ;
- page, created, added_to : integer ;
-
- begin
- created := 0 ;
- added_to := 0 ;
- assign(text_in,filename) ;
- reset(text_in) ;
- if ioresult = 255
- then writeln('Could not open ',filename)
- else
- begin
- write('Page number start for this file? ');
- read(page) ;
- while not eof(text_in) do
- begin
- read(text_in,ch) ;
- if ord(ch)=formfeed
- then page := page + 1
- else if ord(ch)=main_code
- then get_main(table,tablength,page, created, added_to)
- else if ord(ch)=sub_code
- then get_sub(table,tablength,page, created, added_to)
- end ;
- writeln(created,' new entries created');
- writeln(added_to,' references added to existing subjects.')
- end { else file opened successfully }
- end ; { scanfile }
-
-
- function lessthan(el1,el2 : pointer) : boolean ;
- {compare the two entries as per ascii}
-
- begin
- lessthan := el1^.subject < el2^.subject
- end ; {compare}
-
- procedure swap(var el1,el2 : pointer) ;
- {swap two entries pointed to by el1, el2}
- var
- temporary : pointer ;
- begin
- temporary := el1 ;
- el1 := el2 ;
- el2 := temporary
- end {swap} ;
-
-
- procedure split( var splitee :table_type;
- low,high :integer;
- var midindex :integer) ;
- var
- middle : pointer ;
- flag,up,down : integer ;
- begin
- up := low ;
- down := high+1 ;
- middle := splitee[low]; {split from first entry}
- flag := 1 ;
- while up < down do
- if flag = 1
- then {search downwards for a wrong one}
- begin
- down := down-1 ;
- if (up<>down) and not lessthan(middle,splitee[down])
- then
- begin
- flag := 0 ;
- splitee[up] := splitee[down]
- end {THEN it's out of place}
- end {THEN try and find a wrong one down}
- else {search upwards for a wrong one}
- begin
- up := up + 1 ;
- if (up <> down) and lessthan(middle,splitee[up])
- then
- begin
- flag := 1 ;
- splitee[down] := splitee[up]
- end {THEN it's out of place}
- end {ELSE try finding a wrong one upwards};
- splitee[up] := middle ; {fit splitting element back}
- midindex := up ; {where it was split}
- end ; {split}
-
- procedure quicksort(var sortee: table_type; lower,upper:integer) ;
- var
- centre : integer ;
- begin
- if lower < upper
- then
- begin
- split(sortee,lower,upper,centre) ;
- quicksort(sortee,lower,centre-1) ;
- quicksort(sortee,centre+1,upper)
- end {then}
- end; {quicksort}
-
- procedure writeentry(var outfile:text; item : entry_type) ;
-
- var
- j : integer ;
-
- begin
- with item do
- begin
- write(outfile,subject) ;
- if n_mains <> 0
- then
- begin
- write(outfile,chr(bold_code)) ;
- write(outfile,mains[1]:1) ;
- for j := 2 to n_mains do
- write(outfile,',',mains[j]:1) ;
- write(outfile,chr(bold_code)) ;
- if n_subs <> 0
- then write(outfile,',')
- end ; {then}
- if n_subs <> 0
- then
- begin
- write(outfile,subs[1]:1) ;
- for j := 2 to n_subs do
- write(outfile,',',subs[j]:1)
- end ; { then }
- writeln(outfile)
- end {with}
- end ; {writeentry}
-
-
- procedure help;
-
- var
- null_line : string ;
- begin
- writeln(' This program generates a WordStar source') ;
- writeln('file of an index for manuals, etc.') ;
- writeln(' The index can be compiled from many files') ;
- writeln('which may be scanned at different times.') ;
- writeln(' The cumulative index file is stored in a') ;
- writeln('file called "index" and is updated after') ;
- writeln('each run of this program, so ERAse it when') ;
- writeln('you want to restart the index compilation') ;
- writeln(' The input files you are prompted for MUST') ;
- writeln('be "DISK FILE OUTPUT"s from the WordStar') ;
- writeln('Print command, with the FORMFEED option') ;
- writeln(' The output file is WordStar compatible,') ;
- writeln('and may be ^K Read into an index framework');
- write('Press return') ; read (null_line) ;
- writeln(' To mark an item for inclusion as one of');
- writeln('the main references, use ^KQ.') ;
- writeln(' To mark a minor reference, use ^KW') ;
- writeln(' These markers must SURROUND the reference');
- writeln('as for underlining.') ;
- writeln(' The main references are listed first in');
- writeln('BOLD type, and the minors after that in') ;
- writeln('normal type') ;
- writeln(' All marked text is converted to UPPER case');
- writeln('The max. number of references per subject');
- writeln('is ',max_refs,', and the maximum number of');
- writeln('subjects is ',max_entries)
- end ; {help}
-
-
- begin {main program}
-
- assign(index,'index') ;
-
- { read in as much of the index as has been done already }
- num_entries := 0 ;
- reset(index) ;
- if ioresult <> 255
- then
- begin
- while (index^.n_mains<>-1) and not eof(index)do
- begin
- addentry(table,num_entries,index^) ;
- get(index)
- end {while}
- end ; {then}
- writeln(num_entries,' entries read from old index file');
-
- { read in the new WordStar source files to be scanned }
- repeat
- writeln('Enter name of WordStar print file, or CR to continue') ;
- read(filename) ;
- if filename <> ''
- then
- if (filename = 'help') or (filename = 'HELP')
- then help
- else scanfile(table,num_entries,filename)
- until filename = '' ;
-
- { sort the new index }
- quicksort(table,1,num_entries) ;
-
- { save the new index }
- rewrite(index) ;
- if ioresult = 255
- then writeln('Could not update index file')
- else
- begin
- { write index to the file }
- for i := 1 to num_entries do
- write(index,table[i]^) ;
- { now add end of file mark with n_mains =-1 }
- end_file.n_mains := -1 ;
- write(index,end_file) ;
-
- close(index,result) ;
- if ioresult = 255
- then writeln('Could not close index file')
- else writeln(num_entries,' entries written to index file')
- end {else} ;
-
- { ask if a WordStar output file is required yet }
- write('Is a WordStar output file required yet (y/n) ? ') ;
- read(response) ;
- if (response[1] = 'y') or (response[1] = 'Y')
- then
- begin
- write('What filename ? ') ;
- read(filename) ;
- assign(text_out,filename) ;
- rewrite(text_out) ;
- if ioresult = 255
- then writeln('Could not create ',filename)
- else
- begin
- for i := 1 to num_entries do
- writeentry(text_out,table[i]^);
- close(text_out,result)
- end {else}
- end {then}
- end. {index}