program indexer; {$I-,R+,A-,B-}
{-------------------------------------------------------------  }
{                                                               }
{            INDEX  CREATION  FROM  THE  KEYBOARD               }
{                                                               }
{    David E. Cortesi, 2340 Tasso St., Palo Alto CA 94301.      }
{                  (compuserve 72155,450)                       }
{                                                               }
{ Accepts index entries for a book from the keyboard, sorts     }
{ the entries and sub-entries, collates page references,        }
{ and creates an ASCII file that can be printed or edited.      }
{                                                               }
{ Term Recall is an unusual feature of the user interaction.    }
{ If, when entering an index term, the user hits the ESC key,   }
{ the program will find the least term that matches the input   }
{ to that point and fill in its characters on the input line.   }
{ Hitting ESC again retracts those letters and displays the     }
{ letters of the next-higher matching term.  This can save      }
{ considerable typing -- a long term can be entered as only     }
{ a couple of letters plus ESC -- and it allows the user to     }
{ review the terms entered to that point in alpha order.        }
{                                                               }
{ Creates files INDEXER.OUT, the index-document file, and       }
{ INDEXER.TRE, an internal record of the tree which will be     }
{ reloaded on the next run if it then exists.                   }
{---------------------------------------------------------------}

const
    nullch = 0;                 { the null, end-of-string       }
    strmax = 65;                { max size of a string (64,00h) }
    sbufsize = 2046;            { page size of a string buffer  }
    sbufnum = 16;               { allow up to 32K of buffers    }
    maxdepth = 20;              { stack size for tree-walks     }
    asciibel = 7;               { names for ascii characters    }
    asciibs = 8;
    asciilf = 10;
    asciicr = 13;
    asciiesc = 27;
    asciiblank = 32;
    asciidel = 127;

type
    strindex = 1..strmax;       { indices over strings          }
    strlength= 0..strmax;       { lengths of strings            }
    relation = (less,equal,more); { result of comparisons       }
    nchar = 0..255;             { numeric characters are bytes  }
    str = record                { an independent string is      }
            len : strlength;    { ..a length and some bytes,    }
            val : array[strindex] of nchar  { ending in 00h     }
            end;
    strbuff = record            { a string buffer is a compact  }
            free : 0..sbufsize; { collection of strings.        }
            data : array[1..sbufsize] of nchar
            end;
    stref = record              { an indirect string is the     }
            nb : 1..sbufnum;    { index of an strbuff's address }
            bo : 1..sbufsize    { and an index into it.         }
            end;
    ppage = ^page;
    page = record               { a page on which a term is     }
            next : ppage;       { ..referenced, and ^next one   }
            num  : integer
            end;
    pnode = ^node;
    node = record               { one node of a binary tree     }
            lson, rson,         { descendant trees              }
            subt : pnode;       { subtree of sub-terms          }
            iref, uref : stref; { original and uppercase terms  }
            phead : ppage;      { head of chain of page-refs    }
            skip : boolean;     { phony node "M" starts a tree  }
            end;
    treewalk = record           { current state of an inorder   }
            current : pnode;    { ..walk of a tree: this node,  }
            top : 0..maxdepth;  { stack-top pointer, stacked    }
            stack : array[1..maxdepth] of pnode;{ nodes, mark   }
            goneleft : boolean  { true when backing out of leaf }
            end;

var
    sbufptrs : array[1..sbufnum] of ^strbuff; { blocks of bytes }
    sbufcnt  : 0..sbufnum;      { how many blocks are active    }
    maintree : pnode;           { root of the term-tree         }
    initerm  : str;             { "M" term for starting trees   }
    indlevel : 0..9;            { subterm nesting (indent) lev. }
    outfile  : text;            { the output document           }
    loadtree,                   { the input saved tree and      }
    savetree : file of nchar;   { the output one                }
{$I IXS1.PAS }
{$I IXS2.PAS }
{$I IXT1.PAS }
{$I IXT2.PAS }
{$I IXP1.PAS }
{$I IXP2.PAS }
{$I IXP0.PAS }
{$I IXP3.PAS }
{-------------------------------------------------------------- }
{ The main program, at last.....                                }
{-------------------------------------------------------------- }

begin
writeln('[program loaded]');
    init;
    loadall;
writeln('[initialized]');
writeln;
    load(maintree);
writeln;
writeln('[ending..]');
    saveall;
writeln('[..tree saved]');
    dump;
writeln('[..text written]');
end.
);
writeln;
writeln('[ending..]');
    saveall;
writeln('[..tree saved]');
    dump;
writeln('[..text writt