home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug117.arc / FOLD.PZS / FOLD.PAS
Pascal/Delphi Source File  |  1979-12-31  |  10KB  |  382 lines

  1. PROGRAM FOLDFILE;
  2.  
  3. {-----------------------------------------------------------------------------}
  4. {Programme to page a file like this:                                          }
  5. {                                                                             }
  6. { line 1 \     / line 1            line pageLength+1    line 2*pageLength+1   }
  7. { line 2 |     | line 2             ...                  ...                  }
  8. { line 3 |     | line 3             ...                  ...                  }
  9. { line 4 |     |  ...                                                         }
  10. {  ...   | --> |  ...                                                         }
  11. {        |     |                                                              }
  12. {        |     |                                                              }
  13. {  ...   |     |  ...               ...                                       }
  14. { line n /     \ line pageLength   line 2*pageLength                          }
  15. {                                                                             }
  16. {-----------------------------------------------------------------------------}
  17.  
  18. {$C+}
  19. {$R+}
  20.  
  21. CONST
  22.    defPageWidth = 79;   {default values}
  23.    defPageLength = 22;
  24.    defNumCols = 3;
  25.    defFenceChar = '-';
  26.    maxPageLength = 100; {as big as the memory limitations allow}
  27. TYPE
  28.    CPMname = string[14];
  29.    fcbname = string[11];
  30.    anyStr = string[255];
  31.    pageArray = array [1..maxPageLength] of anyStr;
  32. VAR
  33.    pageWidth,pageLength : integer;
  34.    inFile,outFile : text;
  35.    inFname,outFname : CPMname;
  36.    lineNumber: integer;
  37.    lineNumbers : boolean;
  38.    currPage : pageArray;
  39.    fenced : boolean;
  40.    fenceChar : char; {appears between pages}
  41.    numCols : integer;
  42.  
  43. PROCEDURE showSummary;
  44. begin
  45. writeln ('*****************************************************************************');
  46. writeln;
  47. writeln ('command: FOLD - A programme that folds files into pages of columns.');
  48. writeln;
  49. writeln ('syntax:  FOLD infile.ext outfile.ext  {F{c}} {N} {Cn} {Ln} {Wn}} ');
  50. writeln ('                                       |      |   |    |    |');
  51. writeln ('         page break fence char --------+      |   |    |    |');
  52. writeln ('           turn on line numbering ------------+   |    |    |');
  53. writeln ('             n columns per page [3] --------------+    |    |');
  54. writeln ('               n lines per page [22] ------------------+    |');
  55. writeln ('                 n chars per line (excess truncated) [80] --+');
  56. writeln;
  57. writeln ('example: FOLD PROG.PAS PROGLIST.PAS L60 C2 W132 F= N');
  58. writeln;
  59. writeln ('Sam Lander 1988');
  60. writeln;
  61. writeln ('*****************************************************************************');
  62. end;
  63.  
  64. FUNCTION checkFile(filename : CPMname) : boolean;
  65. var
  66.    checkfl :file;
  67. begin
  68. assign(checkfl,filename);
  69.    {$I-}
  70.    reset(checkfl);
  71.    close(checkfl);
  72.    {$I+}
  73. checkFile:= (IOresult = 0);
  74. end;
  75.  
  76. FUNCTION defaultDrive: char;
  77. begin
  78. DefaultDrive:= chr(Mem[4] + 65);
  79. end;
  80.  
  81. PROCEDURE warning(s:anystr);
  82. begin
  83. clreol;
  84. writeln('WARNING: ',s);
  85. end;
  86.  
  87. PROCEDURE error(s:anystr);
  88. {Writes the string and halts}
  89. begin
  90. writeln;
  91. clreol;
  92. writeln(^g,'ERROR: ',s,'.');
  93. writeln;
  94. showSummary;
  95. halt;
  96. end;
  97.  
  98. PROCEDURE waitForAck(s:anystr);
  99. {Wait for the user to press a key}
  100. begin
  101. write (^g,'MESSAGE: ',s,' <RET>');
  102. repeat until keypressed;
  103. writeln;
  104. end;
  105.  
  106. FUNCTION flagSet(c:char): boolean;
  107. var
  108.    i : integer;
  109.    found : boolean;
  110.    testStr : string[2];
  111. begin
  112. found := false;
  113. i := 2; {skip the first two arguments, which are strings}
  114. while (not found) and (i <= paramCount) do
  115.    begin
  116.    i := i+1;
  117.    testStr := paramStr(i);
  118.    if (testStr[1] = upcase(c)) then
  119.       found := true;
  120.    end;
  121. flagSet := found;
  122. end;
  123.  
  124. FUNCTION flagValue(c:char): integer;
  125. {Returns -1 if the flag '-c' is not found, the value following it otherwise}
  126. var
  127.    i : integer;
  128.    found : boolean;
  129.    testStr : string[7];
  130.    argument,code : integer;
  131. begin
  132. found := false;
  133. flagValue := -1;
  134. i := 3; {skip the first two arguments, which are strings}
  135. argument := 0;
  136. while (not found) and (i <= paramCount) do
  137.    begin
  138.    testStr := paramStr(i);
  139.    if (testStr[1]= upcase(c)) then
  140.       begin
  141.       delete (testStr,1,1);
  142.       val(testStr,argument,code);
  143.       if code = 0 then
  144.          begin
  145.          flagValue := argument;
  146.          found := true;
  147.          end
  148.       else
  149.          error('Numeric argument to '+upcase(c)+' out of range')
  150.       end;
  151.    i := i+1;
  152.    end;
  153. end;
  154.  
  155. FUNCTION flagString (flagch:char): anystr;
  156. var
  157.    temp: anystr;
  158.    p : byte;
  159.    found : boolean;
  160. begin
  161. found := false;
  162. flagString := '';
  163. p := 3; {skip the first two arguments, which are strings}
  164. while (p<= paramCount) and not(found) do
  165.    begin
  166.    temp := paramStr(p);
  167.    if (temp[1] = upCase(flagch)) then
  168.          begin
  169.          delete(temp,1,1);
  170.          flagString := temp;
  171.          found := true;
  172.          end;
  173.    p := p+1;
  174.    end;
  175. end;
  176.  
  177. PROCEDURE showSettings;
  178. begin
  179. writeln ('Folding file ',inFname,' to file ',outFname,' using the following settings:');
  180. writeln;
  181. writeln ('   ',numcols,' columns across the page.');
  182. writeln ('   Page width: ',pageWidth,' characters.');
  183. writeln ('   Page length: ',pageLength,' lines.');
  184. write('   Line numbering ');
  185. if linenumbers then
  186.    writeln('on.') else writeln('off.');
  187. if fenced then
  188.    writeln ('   Fence character "',fenceChar,'".')
  189. else
  190.    writeln ('   No fence between pages.');
  191. writeln;
  192. end;
  193.  
  194. PROCEDURE handleCommandFlags;
  195. {Looks at the command line and changes global variables}
  196. var
  197.    fenceString: string[1];
  198. begin
  199. pageWidth := flagValue('w');
  200. if pageWidth = -1 then
  201.    pagewidth := defPageWidth;
  202. pageLength := flagValue ('l');
  203. if pageLength = -1 then
  204.    pageLength := defPageLength;
  205. numCols := flagValue ('c');
  206. if numCols = -1 then
  207.    numCols := defNumCols;
  208. if flagset('f') then
  209.    begin
  210.    fenced := true;
  211.    fenceString := flagString ('f');
  212.    if fenceString = '' then
  213.       fenceChar := defFenceChar
  214.    else
  215.       fenceChar := fenceString[1];
  216.    end
  217. else
  218.    fenced := false;
  219. if flagSet ('n') then
  220.    linenumbers := true
  221. else
  222.    linenumbers := false;
  223. showSettings;
  224. end;
  225.  
  226. PROCEDURE init;
  227. begin
  228. lineNumber := 1;
  229. end;
  230.  
  231. PROCEDURE padOut (var s: anyStr; c: char; n: byte);
  232. {fills the string s out to n characters with c}
  233. var
  234.    i,oldlen : byte;
  235. begin
  236. oldlen := length(s);
  237. s[0] := chr(n);
  238. for i := oldlen+1 to n do
  239.    s[i] := c;
  240. end;
  241.  
  242. FUNCTION stringArg (snum: byte): anyStr;
  243. {returns the ith string in the command line, -x are ignored}
  244. var
  245.    s : anyStr;
  246.    c,sCount : byte;
  247. begin
  248. stringArg:= '';
  249. sCount := 1;
  250. for c := 1 to paramCount do
  251.    begin
  252.    s := paramstr(c);
  253.    if s[1] <> '-' then
  254.       begin
  255.       if sCount = snum then
  256.          stringArg := s;
  257.       sCount := sCount+1;
  258.       end;
  259.    end;
  260. end;
  261.  
  262. PROCEDURE getLine(len: integer; var s: anyStr);
  263. var
  264.    errStr:string[40];
  265. begin
  266. s:='';
  267. if not eof(infile) then
  268.    readln (inFile,s)
  269. else
  270.    padout (s,' ',len);
  271. if length(s) > len then
  272.    begin
  273.    errStr := s; {some is truncated off}
  274.    if length (errStr) = 40 then
  275.       warning('Truncated "'+errStr+'..."')
  276.    else
  277.       warning('Truncated "'+errStr+'"');
  278.    s[0] := chr(len);
  279.    end
  280. else
  281.    padout (s,' ',len);
  282. end;
  283.  
  284. PROCEDURE openFiles;
  285. var
  286.    present : boolean;
  287. begin
  288. inFname := stringArg(1);
  289. if inFname = '' then
  290.    error ('no input file supplied');
  291. present := checkFile (inFname);
  292. if not present then
  293.    error('cannot find file '+inFname);
  294. assign (inFile,inFname);
  295. reset (inFile);
  296. outFname := stringArg(2);
  297. if outFname = '' then
  298.    error ('no output file supplied');
  299. present := checkFile (outFname);
  300. if present then
  301.    waitForAck ('overwriting file '+outFname+'.');
  302. assign (outFile,outFname);
  303. rewrite (outFile);
  304. end;
  305.  
  306. PROCEDURE closeFiles;
  307. begin
  308. close (inFile);
  309. close(outFile);
  310. end;
  311.  
  312. PROCEDURE writePage(var p:pageArray); {var parameter to save time and space}
  313. var
  314.    pageLine : integer;
  315. begin
  316. pageLine := 1;
  317. for pageLine := 1 to pageLength do
  318.    writeln (outFile,p[pageLine]);
  319. end;
  320.  
  321. PROCEDURE blankPage (var p: pagearray);
  322. var i: integer;
  323. begin
  324. for i := 1 to maxPageLength do
  325.    p[i] := '';
  326. end;
  327.  
  328. PROCEDURE getPage(var p: pageArray);
  329. var
  330.    temp : anyStr;
  331.    extras: byte;
  332.    prefix : string[5];
  333.    pageLine,colWidth,colNum : integer;
  334.    i,start : integer;
  335. begin
  336. blankpage(p);
  337. {first, fix up a page boundary}
  338. if fenced then
  339.    begin
  340.    p[1][0] := chr(pageWidth);
  341.    for i := 1 to pageWidth do
  342.       p[1][i] := fenceChar;
  343.    start := 2;
  344.    end
  345. else
  346.    start := 1;
  347. if lineNumbers then
  348.    extras := numCols*6 + numcols  {digits and a space for a separator}
  349. else
  350.    extras := numcols; {for a separator}
  351. colwidth := trunc((pageWidth-extras) / numCols) - 1;
  352. for colNum := 1 to numCols do
  353.    for pageLine := start to pageLength do
  354.       begin
  355.       getline (colwidth,temp);
  356.       if lineNumbers then
  357.          begin
  358.          str(lineNumber:5,prefix);
  359.          temp := prefix+' '+temp;
  360.          end;
  361.       temp := temp + ' ';
  362.       p[pageline] := p[pageline] + temp;
  363.       lineNumber := lineNumber+1;
  364.       end;
  365. end;
  366. {---   Main bit   ------------------------------------------------------------}
  367. begin
  368. init;
  369. openFiles;
  370. handleCommandFlags;
  371. while not eof(infile) do
  372.    begin
  373.    getpage(currPage);
  374.    writePage(currPage);
  375.    end;
  376. closeFiles;
  377. end.
  378.  
  379.  
  380.  
  381.  
  382.