home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / OUT18.ZIP / FORM.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1986-10-03  |  5.3 KB  |  209 lines

  1.  
  2. (*
  3.  * form - reformat a textfile
  4.  * shs 3-oct-86
  5.  *
  6.  *)
  7.  
  8. {$p2048,g512}
  9.  
  10. type
  11.    linestring = string[128];
  12.    anystring = linestring;
  13.  
  14. var
  15.    lineout: linestring;
  16.  
  17. const
  18.    right_margin = 72;
  19.    justify = true;
  20.  
  21. procedure pflush(var fd: text); begin flush(fd); end;
  22.  
  23.  
  24. type
  25.    word_info_rec = record
  26.       word: string[40];
  27.       spaces: integer;
  28.    end;
  29.  
  30. var
  31.    words:       array[1..40] of word_info_rec;
  32.    word_count:  integer;
  33.  
  34.  
  35. procedure justify_line(indent:  integer);
  36. var
  37.    i,j:   integer;
  38.    need:  integer;
  39.  
  40. begin
  41.    need := (right_margin - indent) - length(lineout);
  42.    while (need>0) and (word_count>2) do
  43.    begin
  44.       i := random(word_count-1);
  45.       with words[i] do
  46.          if random(spaces*spaces+1) = 1 then    {don't allot big spaces}
  47.          begin
  48.             words[i].spaces := words[i].spaces + 1;
  49.             need := need - 1;
  50.          end;
  51.  
  52.    end;
  53.  
  54.    lineout := '';
  55.    for i := 1 to word_count do
  56.    with words[i] do
  57.       lineout := lineout + word + copy('          ',1,spaces);
  58. end;
  59.  
  60.  
  61. procedure reformat_line(var fd:     text;
  62.                         linein:     linestring;
  63.                         indent:     integer;
  64.                         var lines:  integer);    {reformat one or more
  65.                                                   lines of text to fit
  66.                                                   the margins between
  67.                                                   'indent' and right_margin;
  68.                                                   also counts output lines}
  69.  
  70. var
  71.    i:           integer;
  72.    word:        anystring;
  73.    c:           char;
  74.  
  75. begin                 {this procedure is by far the slowest part
  76.                        of printing to a file.   there are several
  77.                        "tricky" things done here for the sake
  78.                        of greater speed.  mostly this involves taking
  79.                        advantage of the fact that str[0] is the length
  80.                        of str, and that whole string assignment generates
  81.                        code to move the whole string to/from the stack}
  82.  
  83.  
  84.    if (linein = '') or (linein[1] = ' ') then   {if this is a blank line or
  85.                                                  the start of a new paragraph}
  86.    begin
  87.       if lineout <> '' then                 {write any partial line}
  88.       begin
  89.          writeln(fd, '':indent, lineout);
  90.          pflush(fd);
  91.          lines := lines + 1;
  92.          lineout := '';
  93.          word_count := 0;
  94.       end;
  95.  
  96.       writeln(fd);                          {write a blank line}
  97.       pflush(fd);
  98.       lines := lines + 1;
  99.    end;
  100.  
  101.  
  102.    linein := linein + ' ';            {the line will now be reformatted;
  103.                                        make sure last word on the
  104.                                        line is terminated}
  105.    word := '';
  106.  
  107.    for i := 1 to length(linein) do
  108.    begin
  109.       c := linein[i];
  110.  
  111.       if c = ' ' then                   {if at the end of a word}
  112.       begin
  113.  
  114.          if (ord(word[0]) + ord(lineout[0]) + indent) >= right_margin then
  115.                                             {and the word won't fit
  116.                                              on this output line}
  117.          begin
  118.             if justify then
  119.                justify_line(indent);     {justify the line if needed}
  120.  
  121.             writeln(fd, '':indent, lineout);
  122.             pflush(fd);
  123.             lines := lines + 1;
  124.  
  125.             if word = '' then
  126.             begin
  127.                lineout := '';
  128.                word_count := 0;
  129.             end
  130.             else
  131.             begin
  132.                lineout := word + c;          {then start a new line}
  133.                word_count := 1;
  134.                words[1].word := word;
  135.                words[1].spaces := 1;
  136.             end;
  137.          end
  138.          else
  139.  
  140.          if word <> '' then
  141.          begin
  142.             word_count := word_count + 1;
  143.             words[word_count].word := word;
  144.             words[word_count].spaces := 1;
  145.             lineout := lineout + word + ' ';
  146.          end;                              {else add a word to this line.
  147.                                             a lot of time is spent on this
  148.                                             line.  how to make it faster?}
  149.  
  150.          word := '';                         {consume the word}
  151.  
  152.       end
  153.       else
  154.       begin
  155.  
  156.          word[0] := succ(word[0]);
  157.          word[ord(word[0])] := c;   {not a space, build up a word.
  158.                                      this is a faster version of
  159.                                        word := word + c;}
  160.          case c of
  161.             '.',',',';',':':
  162.                word := word + ' ';
  163.          end;
  164.       end;
  165.    end;
  166.  
  167. end;
  168.  
  169.  
  170.  
  171. procedure format_file(name:  anystring);
  172. var
  173.    lines:      integer;
  174.    line:       linestring;
  175.    i:          integer;
  176.    fd:         text;
  177.  
  178. const
  179.    indent = 6;
  180.  
  181. begin
  182.    assign(fd,name);
  183.    reset(fd);
  184.  
  185.    lineout := '';
  186.    lines := 0;
  187.  
  188.    while not eof(fd) do
  189.    begin
  190.       readln(fd,line);
  191.       reformat_line(output, line, indent, lines)
  192.    end;
  193.  
  194.    if lineout <> '' then      {output last reformatted line}
  195.    begin
  196.       writeln(output, '':indent, lineout);
  197.       lines := lines + 1;
  198.       lineout := '';
  199.    end;
  200.  
  201.    close(fd);
  202. end;
  203.  
  204.  
  205. begin
  206.    format_file('tandem.doc');
  207.  
  208. end.
  209.