home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / OUT18.ZIP / OUTFILEX.INC < prev    next >
Encoding:
Text File  |  1986-10-01  |  13.3 KB  |  505 lines

  1.  
  2. (*
  3.  * outline - a simple "outline" oriented document generator
  4.  *
  5.  * outfiles.inc - this module contains all of the file access
  6.  *                procedures.  Saves and Loads are
  7.  *                handled by the procedures in this module.
  8.  *
  9.  * Author:  Samuel H. Smith, 11-Jan-86
  10.  *
  11.  *)
  12.  
  13.  
  14. procedure select_file(pattern:    anystring;
  15.                       prompt:     linestring;
  16.                       var name:   anystring;
  17.                       var key:    char);     {select a filename for reading
  18.                                               or writing; this may give a
  19.                                               directory of files in a future
  20.                                               version}
  21. var
  22.    i:    integer;
  23.    x, y: integer;
  24.    n:    integer;
  25.    sel:  anystring;
  26.    dir:  anystring;
  27.  
  28. begin
  29.    clrscr;
  30.    getdir(0,dir);
  31.    getfiles(pattern, filetable, filecount);    {get the files matching
  32.                                                 the pattern}
  33.    clrscr;
  34.    lowvideo;
  35.    gotoxy(1, 1);
  36.    displn('List of files matching '+ pattern+ ' in directory '+dir);
  37.  
  38.    normvideo;
  39.    x := 4;
  40.    y := 2;
  41.    for i := 1 to filecount do                  {display the filenames in
  42.                                                 up to 5 columns on screen}
  43.    begin
  44.       gotoxy(x, y);
  45.       disp(filetable[i]);
  46.  
  47.       y := y + 1;
  48.       if y > 15 then
  49.       begin
  50.          y := 2;
  51.          x := x + 16;
  52.       end;
  53.    end;
  54.  
  55.  
  56.    gotoxy(1, 18);
  57.    normvideo;
  58.    displn(prompt+' ──────────────');  {display the prompt and give a little
  59.                                        help with keys in this function}
  60.    gotoxy(1, 25);
  61.    lowvideo;
  62.    disp('Enter a filename,  UP or DOWN to select from the directory,  ESC to cancel');
  63.    gotoxy(1, 20);
  64.    disp('File name: ');
  65.    n := 0;
  66.  
  67.    normvideo;
  68.    repeat
  69.       if n = 0 then
  70.          sel := name
  71.       else
  72.          sel := filetable[n];
  73.  
  74.       gotoxy(12, 20);
  75.       disp(sel);
  76.       i := length(sel) + 1;
  77.       edit_string(12, 20, i, sel, key, 64);   {allow user to edit a filename
  78.                                                or to press a function key}
  79.  
  80.       case key of
  81.  
  82.          UP:   begin
  83.                   n := n - 1;
  84.                   if n < 0 then
  85.                      n := filecount;
  86.                end;
  87.  
  88.  
  89.          DOWN: begin
  90.                   n := n + 1;
  91.                   if n > filecount then
  92.                      n := 0;
  93.                end;
  94.  
  95.  
  96.          NEWLINE, 
  97.          ESC:  ;
  98.  
  99.  
  100.          else  write(^G);
  101.      end;
  102.  
  103.    until (key in [NEWLINE, ESC]);
  104.  
  105.  
  106.    name := sel;
  107.    for i := 1 to length(name) do
  108.       name[i] := upcase(name[i]);      {map the filename to all upper case}
  109.  
  110.    gotoxy(1, 25);
  111.    clreol;
  112.    gotoxy(1, 21);                      {remove extra prompts from screen so
  113.                                         that the caller can print some
  114.                                         more, if needed}
  115. end;
  116.  
  117.  
  118.  
  119. function file_exists(name:  anystring): boolean;      {check to see if a file
  120.                                                        already exists.  knows
  121.                                                        about special devices
  122.                                                        and won't complain
  123.                                                        about them}
  124. var
  125.    fd:  textfile;
  126.    i:   integer;
  127.    dev: anystring;
  128.  
  129. begin
  130.  
  131.    dev := copy(name, 1, 4);
  132.    if dev[4] in [':', '.'] then
  133.       dev := copy(dev, 1, 3);                {get the 3 letter device name
  134.                                               from the filename, if any was
  135.                                               present}
  136.  
  137.    file_exists := false;
  138.    if dev = 'LST' then exit;
  139.    if dev = 'AUX' then exit;
  140.    if dev = 'NUL' then exit;
  141.    if dev = 'CON' then exit;
  142.    if dev = 'PRN' then exit;                 {don't bother checking on these
  143.                                               files; they are special}
  144.  
  145.  
  146.    assign(fd, name);                {it looks like an ordinary disk file;
  147.                                      try to open it to see if it is there}
  148. {$I-}
  149.    reset(fd);
  150. {$I+}
  151.    if ioresult = 0 then
  152.    begin
  153.       file_exists := true;
  154.       close(fd);
  155.    end
  156.    else
  157.       file_exists := false;
  158. end;
  159.  
  160.  
  161. procedure save_section(var sec: section_ptr;
  162.                        var fd:  textfile);       {save a section in special
  163.                                                   .OLF format; recursively
  164.                                                   calls itself for sub-
  165.                                                   sections}
  166. var
  167.    i:           integer;
  168.    textcount:   integer;
  169.    subscount:   integer;
  170.    ifd:         text;
  171.    name:        anystring;
  172.    c:           char;
  173.  
  174. begin
  175.    with sec^ do
  176.    begin
  177.       writeln(fd, title);                   {save the title}
  178.  
  179.       if (text^[1][1] = '@') and
  180.          (text^[2][1] = '@') and
  181.          (text^[3][1] = '@') then
  182.       begin
  183.          name := text^[2];
  184.          i := pos('.',name);
  185.          if i > 0 then
  186.          if copy(name,i,4) = '.scr' then
  187.          begin
  188.            name := copy(name,2,i-1) + 'inc';
  189.            writeln;
  190.            writeln('about to split into file ',name);
  191.            for i := 4 to max_text do
  192.               if text^[i] <> '' then
  193.                  writeln(text^[i]);
  194.  
  195.            write('ok? (Y/N) ');
  196.            read(kbd,c);
  197.            if c = 'Y' then
  198.            begin
  199.  
  200.             assign(ifd,name);
  201.             rewrite(ifd);
  202.  
  203.             writeln('include file created: ',name);
  204.             for i := 4 to max_text do
  205.                if text^[i] <> '' then
  206.                begin
  207.                   writeln(ifd,text^[i]);
  208.                   text^[i] := '';
  209.                end;
  210.             close(ifd);
  211.             text^[4] := '@' + name;
  212.  
  213.            end;
  214.          end;
  215.       end;
  216.  
  217.       textcount := 0;
  218.       for i := 1 to max_text do
  219.          if text^[i] <> '' then
  220.             textcount := textcount + 1;     {count the lines of text}
  221.  
  222.       writeln(fd, textcount, ' ',estimate:7:2, ' ', onpage);
  223.       for i := 1 to max_text do
  224.          if text^[i] <> '' then
  225.             writeln(fd, text^[i]);           {save the text lines}
  226.  
  227.  
  228.       subscount := 0;
  229.       for i := 1 to max_subsects do
  230.          if subsect[i] <> nil then
  231.             if subsect[i]^.title <> '' then
  232.                subscount := subscount + 1;     {count the subsections}
  233.  
  234.       writeln(fd, subscount);
  235.       for i := 1 to max_subsects do
  236.          if subsect[i] <> nil then
  237.             if subsect[i]^.title <> '' then
  238.                save_section(subsect[i], fd);   {save all the subsections}
  239.    end;
  240. end;
  241.  
  242.  
  243. procedure save_document;       {user interface for saving the current
  244.                                 outline to a file so that it can be
  245.                                 loaded at a later time}
  246. var
  247.    fd:      textfile;
  248.    key:     char;
  249.  
  250. begin
  251.  
  252.    select_file('*.OLF', 'Save outline to a file', docfile, key);
  253.  
  254.    if (key <> NEWLINE) or (docfile = '') then
  255.       exit;
  256.  
  257.    if pos('.', docfile) = 0 then
  258.       docfile := docfile + '.OLF';
  259.  
  260.    if file_exists(docfile) then
  261.    begin
  262.       writeln;
  263.       displn('WARNING:  The file '+ docfile+ ' already exists!  ');
  264.       disp('Overwrite it? (Y/N) ');
  265.  
  266.       if upcase(getkey) <> 'Y' then
  267.          exit;
  268.  
  269.       displn('Yes');
  270.    end;
  271.  
  272.    assign(fd, docfile);
  273.    rewrite(fd);
  274.  
  275.    writeln(fd,'OUTLINE OLF 3');
  276.    save_section(document, fd);
  277.    close(fd);
  278.  
  279.    saved := true;
  280. end;
  281.  
  282.  
  283.  
  284.  
  285. function load_section(var fd:  textfile):  section_ptr;
  286.                                               {loads a single section
  287.                                                of an outline from
  288.                                                an .OLF format file.
  289.                                                returns section
  290.                                                pointer for the loaded
  291.                                                section.  recursively
  292.                                                calls itself for
  293.                                                loading subsections}
  294. var
  295.    i:       integer;
  296.    count:   integer;
  297.    sec:     section_ptr;
  298.    tfd:     text;
  299.    tname:   anystring;
  300.  
  301. begin
  302.    if eof(fd) then
  303.    begin
  304.       load_section := nil;
  305.       displn('ERROR:  Unexpected end of file!!!'^G^G^G);
  306.       exit;
  307.    end;
  308.  
  309.    sec := new_section;             {create the section to load}
  310.  
  311.    with sec^ do
  312.    begin
  313.       readln(fd, title);           {get the section title}
  314.  
  315.       case olf_format of
  316.          2: readln(fd, count, estimate);
  317.          3: readln(fd, count, estimate, onpage);
  318.          else
  319.             readln(fd, count);
  320.       end;
  321.  
  322.       if count <> 0 then
  323.       begin
  324.          allocate_text(sec);
  325.          for i := 1 to count do
  326.             readln(fd, text^[i]);      {get all text lines for this section}
  327.  
  328.          if text^[count][1] = '@' then
  329.          begin
  330.             tname := copy(text^[count],2,99);
  331.             if copy(tname,length(tname)-3,4) = '.inc' then
  332.             begin
  333.                count := count-1;
  334.                assign(tfd,tname);
  335.                reset(tfd);
  336.                while not eof(tfd) do
  337.                begin
  338.                   count := count + 1;
  339.                   readln(tfd,text^[count]);
  340.                end;
  341.                close(tfd);
  342.             end;
  343.          end;
  344.       end;
  345.  
  346.       readln(fd, count);
  347.       for i := 1 to count do
  348.          subsect[i] := load_section(fd);
  349.                                    {recursively load all subsections for
  350.                                     this section}
  351.    end;
  352.  
  353.    load_section := sec;            {return pointer to the loaded section}
  354. end;
  355.  
  356.  
  357. procedure save_if_needed;
  358. var
  359.    key: char;
  360.  
  361. begin
  362.    if not saved then
  363.    begin
  364.       clrscr;
  365.       gotoxy(1,15);
  366.       displn('WARNING:  There are unsaved changes in the current outline.'^G);
  367.       writeln;
  368.       disp  ('          Do you want to save? (Y/N) ');
  369.  
  370.       repeat
  371.          key := upcase(getkey);
  372.       until key in ['Y','N'];
  373.  
  374.       if key = 'Y' then
  375.          save_document;
  376.    end;
  377.  
  378.    clrscr;
  379. end;
  380.  
  381.  
  382. procedure load_document;      {user interface to load an outline from
  383.                                a .OLF format file}
  384. var
  385.    fd:      textfile;
  386.    key:     char;
  387.  
  388. begin
  389.  
  390.    save_if_needed;
  391.    select_file('*.OLF', 'Load outline from a file', docfile, key);
  392.  
  393.    if (key <> NEWLINE) or (docfile = '') then
  394.       exit;
  395.  
  396.    if pos('.', docfile) = 0 then
  397.       docfile := docfile + '.OLF';
  398.  
  399.  
  400.    docfile := locate_file(docfile);
  401.    if not file_exists(docfile) then
  402.    begin
  403.       displn('I can''t find '+ docfile+ ';  try another filename.'^G);
  404.       delay(3000);
  405.       exit;
  406.    end;
  407.  
  408.  
  409.    assign(fd, docfile);
  410.    reset(fd);
  411.  
  412.    readln(fd,lineout);            {determine outline file format.  some
  413.                                    old formats need different handling}
  414.  
  415.    if lineout = 'OUTLINE OLF 2' then
  416.       olf_format := 2
  417.    else
  418.    if lineout = 'OUTLINE OLF 3' then
  419.       olf_format := 3
  420.    else
  421.    begin
  422.       olf_format := 1;
  423.       close(fd);
  424.       reset(fd);
  425.    end;
  426.  
  427.    marksec := nil;
  428.    marksub := 0;                   {remove any markers that are
  429.                                     set when we go to a new section
  430.  
  431.    delete_section(document);       {delete the current document from memory}
  432.  
  433.    document := load_section(fd);   {load in a new document.  note that this
  434.                                     could be used to load in a subsection
  435.                                     if there was a user interface for it.
  436.                                     that would then allow you to "merge"
  437.                                     outlines}
  438.  
  439.    close(fd);
  440.    saved := true;
  441. end;
  442.  
  443.  
  444.  
  445. procedure load_options;           {load in the options file and set the
  446.                                    various program paremeters accordingly}
  447. var
  448.    fd:     text;
  449.    par:    integer;
  450.    name:   anystring;
  451. begin
  452.  
  453.    name := locate_file('outline.opt');
  454.    if not file_exists(name) then
  455.    begin
  456.       displn('Can''t open option file: '+name);
  457.       halt;
  458.    end;
  459.  
  460.    assign(fd,name);
  461.    reset(fd);
  462.  
  463.    readln(fd);                  {skip initial comment line}
  464.  
  465.    readln(fd,pagelen);          {max number of lines to print on a page}
  466.  
  467.    readln(fd,minlines);         {minimum number of lines on a page before
  468.                                  a new page can be started}
  469.  
  470.    readln(fd,indentation);      {amount of indentation for each level of
  471.                                  subsection nesting in printouts}
  472.  
  473.    readln(fd,right_margin);     {right margin for reformatted print file
  474.                                  outputs}
  475.  
  476.    read(fd,underline_character);
  477.    readln(fd);                  {characters printed to underline section
  478.                                  titles in detail format printouts}
  479.  
  480.    readln(fd,par);
  481.    if par = 1 then
  482.       paragraph_reformat := true
  483.    else
  484.       paragraph_reformat := false;
  485.                                 {should paragraphs of text be reformatted?}
  486.  
  487.    readln(fd,par);
  488.    if par = 1 then
  489.       break_into_pages := true
  490.    else
  491.       break_into_pages := false;
  492.                                 {should output be divided into pages?}
  493.  
  494.    readln(fd,par);
  495.    textmode(par);               {set text modes}
  496.  
  497. {$I-}
  498.    close(fd);
  499. writeln('ioresult=',ioresult); delay(100);
  500. {$I+}
  501. end;
  502.  
  503.  
  504.  
  505.