home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TPTOOL5.ZIP / TREELIB.INC < prev   
Encoding:
Text File  |  1987-03-28  |  6.1 KB  |  241 lines

  1.  
  2. const treelib_tag: string[90]
  3.    = #0'@(#)CURRENT_FILE LAST_UPDATE Visual tree library 1.0'#0;
  4. #log Visual tree library 1.0
  5.  
  6. (*
  7.  * treelib.inc - Utility library to build, sort and output trees
  8.  *               in a real visual "tree" format.
  9.  *
  10.  * Author: Samuel H. Smith, 5-Apr-86
  11.  *
  12.  *)
  13.  
  14. const
  15.    maxsubs = 150;                  {maximum number of subnodes for
  16.                                     any single node in the tree}
  17.  
  18.    ascii_tree: boolean = false;    {set to true for ASCII only tree
  19.                                     output; full IBM character set is
  20.                                     used by default}
  21.  
  22.  
  23. type
  24.    long_string = string[255];       {maximum length of an output line}
  25.  
  26.    subnode_index = 0..maxsubs;
  27.  
  28.    name_string = string[40];        {maximum length of the name of a single
  29.                                     tree node}
  30.  
  31.    subnode_table = ^subnode_tabletype;
  32.    node_ptr = ^node_rec;
  33.    subnode_tabletype = array[1..maxsubs] of node_ptr;
  34.  
  35.    node_rec = record
  36.       name:   name_string;          {the name of the node}
  37.  
  38.       count:  subnode_index;        {the count of subnodes}
  39.  
  40.       subs:   subnode_table;        {pointer to subnode table, if any}
  41.    end;
  42.  
  43.  
  44. type
  45.    connector_codes =
  46.      (horizontal, tee, top, cross, middle, bottom, vertical, spaces, empty);
  47.  
  48. const
  49.    connector_strings: array [boolean, connector_codes] of string[3] =
  50.      (('───', '─┬─', ' ┌─', '─┼─', ' ├─', ' └─', ' │ ', '   ', ''),
  51.  
  52.       ('---', '-+-', ' +-', '-|-', ' |-', ' +-', ' | ', '   ', ''));
  53.  
  54.  
  55.  
  56. (*
  57.  * new_node - create and return a new empty node
  58.  *
  59.  * note:  the subnode table node^.subs must be allocated
  60.  *        by the user before any subnodes can be
  61.  *        created.  this was done to eliminate the
  62.  *        space needed by the subnode table on the
  63.  *        terminal nodes in the tree.
  64.  *
  65.  *)
  66.  
  67. function new_node: node_ptr;
  68. var
  69.    node: node_ptr;
  70.    i:    subnode_index;
  71.  
  72. begin
  73.    new (node);
  74.    node^.name := '';
  75.    node^.count := 0;
  76.    node^.subs := nil;
  77.    new_node := node;
  78. end;
  79.  
  80.  
  81.  
  82. (*
  83.  * dispose_tree - dispose of a tree
  84.  *
  85.  *)
  86.  
  87. procedure dispose_tree(var node:  node_ptr);
  88. var
  89.    i:      subnode_index;
  90.  
  91. begin
  92.    if node <> nil then
  93.    begin
  94.       with node^ do
  95.          for i := 1 to count do
  96.             dispose_tree(subs^[i]);
  97.  
  98.       if node^.subs <> nil then
  99.          dispose(node^.subs);
  100.  
  101.       dispose(node);
  102.       node := nil;
  103.    end;
  104. end;
  105.  
  106.  
  107.  
  108. (*
  109.  * sort_node - sort the entries in a node
  110.  *
  111.  *)
  112.  
  113. procedure sort_node(node: node_ptr);
  114. var
  115.    i:        subnode_index;
  116.    swapped:  boolean;
  117.    temp:     node_ptr;
  118.  
  119. begin
  120.    with node^ do
  121.       repeat
  122.          swapped := false;
  123.  
  124.          for i := 1 to count-1 do
  125.             if subs^[i]^.name > subs^[i+1]^.name then
  126.             begin
  127.                temp := subs^[i];
  128.                subs^[i] := subs^[i+1];
  129.                subs^[i+1] := temp;
  130.                swapped := true;
  131.             end;
  132.  
  133.       until swapped = false;
  134. end;
  135.  
  136.  
  137.  
  138. function blanks (len: integer): long_string;
  139. var
  140.    str: long_string;
  141.  
  142. begin
  143.    str := '';
  144.  
  145.    while length (str) < len do
  146.       str := str + ' ';
  147.  
  148.    blanks := str;
  149. end;
  150.  
  151.  
  152.  
  153. function connector (code: connector_codes): long_string;
  154. begin
  155.    connector := connector_strings [ascii_tree, code];
  156. end;
  157.  
  158.  
  159.  
  160. procedure put_node (var fd:     text;              {output file}
  161.                     node:       node_ptr;          {node to output}
  162.                     beforetab:  long_string;       {tabs if before title}
  163.                     titletab:   long_string;       {tabs for title}
  164.                     aftertab:   long_string;       {tabs if after title}
  165.                     before:     connector_codes;   {next tab before title}
  166.                     title:      connector_codes;   {next tab for title}
  167.                     after:      connector_codes);  {next tab after title}
  168.  
  169. var
  170.    i:             subnode_index;
  171.    titlesub:      subnode_index;
  172.  
  173. begin
  174.    with node^ do
  175.    begin
  176.       beforetab := beforetab + connector (before) + blanks (length (name));
  177.       titletab  := titletab  + connector (title ) + name;
  178.       aftertab  := aftertab  + connector (after ) + blanks (length (name));
  179.  
  180.       case count of
  181.          0:     {terminal node with title only}
  182.             writeln (fd, titletab);
  183.  
  184.          1:     {node with 1 subnode}
  185.             put_node (fd, subs^[1], beforetab, titletab, aftertab,
  186.                                     spaces, horizontal, spaces);
  187.  
  188.          2:     {node with 2 subnodes}
  189.             begin
  190.                put_node (fd, subs^[1], beforetab, titletab, aftertab,
  191.                                        spaces, tee, vertical);
  192.  
  193.                put_node (fd, subs^[2], aftertab, aftertab, aftertab,
  194.                                        vertical, bottom, spaces);
  195.             end;
  196.  
  197.          else   {node with n subnodes}
  198.             begin
  199.                titlesub := (count+1) div 2;
  200.  
  201.                writeln (fd, beforetab);
  202.  
  203.                put_node (fd, subs^[1], beforetab, beforetab, beforetab,
  204.                                        spaces, top, vertical);
  205.  
  206.                for i := 2 to titlesub-1 do
  207.                   put_node (fd, subs^[i], beforetab, beforetab, beforetab,
  208.                                           vertical, middle, vertical);
  209.  
  210.                put_node (fd, subs^[titlesub], beforetab, titletab, aftertab,
  211.                                               vertical, cross, vertical);
  212.  
  213.                for i := titlesub+1 to count-1 do
  214.                   put_node (fd, subs^[i], aftertab, aftertab, aftertab,
  215.                                           vertical, middle, vertical);
  216.  
  217.                put_node (fd, subs^[count], aftertab, aftertab, aftertab,
  218.                                            vertical, bottom, spaces);
  219.             end;
  220.       end;
  221.  
  222.    end;
  223.  
  224. end;
  225.  
  226.  
  227.  
  228. (*
  229.  * put_tree - format a tree for output and write it to a file
  230.  *
  231.  *)
  232.  
  233. procedure put_tree (var fd:  text;
  234.                     root:    node_ptr);
  235. begin
  236.    put_node (fd, root, '', '', '', empty, empty, empty);
  237.    flush (fd);
  238. end;
  239.  
  240.  
  241.