home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Product / Product.zip / sc621_3.zip / src / help.c < prev    next >
C/C++ Source or Header  |  1993-11-10  |  22KB  |  631 lines

  1. /*
  2.  * Help functions for sc 
  3.  * R. Bond, 1988
  4.  * J. Buhrt 1990
  5.  * $Revision: 6.21 $
  6.  */
  7.  
  8. #ifdef QREF
  9. #include <stdio.h>
  10. char    *header = " Quick Reference";
  11. char    *revision = "$Revision: 6.21 $";
  12. #else
  13. #include <curses.h>
  14. #include "sc.h"
  15. #endif /* QREF */
  16.  
  17. char *intro[] = {
  18. " ",
  19. #if defined(QREF) && defined(TROFF)
  20. ".SH",
  21. #endif
  22. " Overview:",
  23. " ",
  24. #if defined(QREF) && defined(TROFF)
  25. ".Lp",
  26. #endif
  27. " A:   This overview",
  28. " B:   Toggle Options",
  29. " C:   Set Options",
  30. " D:   Cursor movement commands",
  31. " E:   Cell entry and editing commands",
  32. " F:   Line Editing",
  33. " G:   File commands",
  34. " H:   Row and column commands",
  35. " I:   Range commands",
  36. " J:   Miscellaneous commands",
  37. " K:   Variable names/Expressions",
  38. " L:   Range functions",
  39. " M:   Numeric functions",
  40. " N:   String functions",
  41. " O:   Financial functions",
  42. " P:   Time and date functions",
  43. " ",
  44. " Q:   Return to main spreadsheet",
  45. (char *)0
  46. };
  47.  
  48. char *toggleoptions[] = {
  49. " ",
  50. #if defined(QREF) && defined(TROFF)
  51. ".SH",
  52. #endif
  53. " B: Toggle Options",
  54. " ",
  55. #if defined(QREF) && defined(TROFF)
  56. ".Lp",
  57. #endif
  58. "     ^To  Toggle options. Toggle one option selected by o:",
  59. "          a    Recalculate automatically or on ``@'' commands.",
  60. "          c    Current cell highlighting enable/disable.",  
  61. "          e    External function execution enable/disable.",
  62. "          l    Autolabeling defined cells enable/disable.",
  63. "          n    If enabled, a digit starts a numeric value.",
  64. "          t    Top line display enable/disable.",
  65. #if !defined(VMS) && !defined(MSDOS) && defined(CRYPT_PATH)
  66. "          x    Encrypt/decrypt database and listing files.",
  67. #else
  68. "          x    Encrypt/decrypt database and listing files (Not available).",
  69. #endif
  70. "          $    Dollar prescale.  If enabled, all numeric constants",
  71. "               (not expressions) entered are multipled by 0.01.",
  72. "          r    Newline action.  Toggle between no action, move down",
  73. "               after entry and move right after entry.",
  74. "          z    Set the newline action limits to the current row and column",
  75. "            (for r && z see also set rowlimit=n, collimit=n)",
  76. (char *)0
  77. };
  78.  
  79. char *setoptions[] = {
  80. " ",
  81. #if defined(QREF) && defined(TROFF)
  82. ".SH",
  83. #endif
  84. " C: Set Options",
  85. " ",
  86. #if defined(QREF) && defined(TROFF)
  87. ".Lp",
  88. #endif
  89. "     S  Set options.  Options include:",
  90. "          byrows        Recalculate in row order. (default)",
  91. "          bycols        Recalculate in column order.",
  92. "          iterations=n  Set the number of iterations allowed. (10)",
  93. "          tblstyle=xx   Set ``T'' output style to:",
  94. "                        0 (none), tex, latex, slatex, or tbl.",
  95. "          rndinfinity   Round to infinity (round .5 up vs to nearest even).",
  96. "          rowlimit=n    Set the remembered row limit for newline action.",
  97. "          collimit=n    Set the remembered column limit for newline action.",
  98. "                     (rowlimit and collimit can both be set by ^Tz)",
  99. (char *)0
  100. };
  101.  
  102. char *cursor[] = {
  103. " ",
  104. #if defined(QREF) && defined(TROFF)
  105. ".SH",
  106. #endif
  107. " D: Cell cursor movement (always OK):",
  108. " ",
  109. #if defined(QREF) && defined(TROFF)
  110. ".Lp",
  111. #endif
  112. "     ^N ^P ^B ^F Down, up, back, forward",
  113. "     ^Ed         Go to end of range.  Follow ^E by a direction indicator",
  114. "                 such as ^P or j.",
  115. "     Arrow keys (if the terminal and termcap support them.)",
  116. " ",
  117. " Cell cursor movement if no prompt active:",
  118. "     j,k,l,h    Down, up, right, left",
  119. "     J,K,L,H    Down, up, right, left by 1/2 pages",
  120. "     SPACE      Forward",
  121. "     ^H         Back",
  122. "     TAB        Forward, otherwise starts/ends a range",
  123. "     ^          Up to row 0 of the current column.",
  124. "     #          Down to the last valid row of the current column.",
  125. "     0          Back to column A.  Preface with ^U if numeric mode.",
  126. "     $          Forward to the last valid column of the current row.",
  127. "     b          Back then up to the previous valid cell.",
  128. "     w          Forward then down to the next valid cell.",
  129. "     g          Go to a cell.  Cell name, range name, quoted string,",
  130. "                a number, 'error', or 'invalid' to specify which cell.",
  131. (char *)0
  132. };
  133.  
  134.  
  135. char *cell[] = {
  136. " ",
  137. #if defined(QREF) && defined(TROFF)
  138. ".SH",
  139. #endif
  140. " E: Cell entry and editing commands:",
  141. " ",
  142. #if defined(QREF) && defined(TROFF)
  143. ".Lp",
  144. #endif
  145. "     =    Enter a numeric constant or expression.",
  146. "     <    Enter a left justified string or string expression.",
  147. "     \"    Enter a centered label.",
  148. "     >    Enter a right justified string or string expression.",
  149. "     e    Edit the current cell's numeric value.",
  150. "     E    Edit the current cell's string part.",
  151. "     F    Assign a format to the current cell's numeric value.",
  152. "     x    Clear the current cell.",
  153. "     c    Copy the last marked cell to the current cell.",
  154. "     m    Mark a cell to be used as the source for ``c''",
  155. "     +    Increment numeric part",
  156. "     -    Decrement numeric part",
  157. "  RETURN  Enter insert mode if the input line was empty (ESC to edit)",
  158. " ",
  159. "     In numeric mode, a decimal digit, ``+'', ``-'', and ``.'' all start",
  160. "     a new numeric constant or expression.",
  161. (char *)0
  162. };
  163.  
  164.  
  165. char *vi[] = {
  166. " ",
  167. #if defined(QREF) && defined(TROFF)
  168. ".SH",
  169. #endif
  170. " F: Line Editor",
  171. " ",
  172. #if defined(QREF) && defined(TROFF)
  173. ".Lp",
  174. #endif
  175. "     Hitting the ESC key while entering any command on the top line",
  176. "     will start a one-line vi-style editor.  Supported commands:",
  177. " ",
  178. "     ESC q        Abort command entry.",
  179. "     h l          Move cursor forward, backward.",
  180. "     0 $          Move cursor to the beginning, end of the line.",
  181. "     b w          Move cursor forward/back one word.",
  182. "     fc           Move cursor to character c.",
  183. "     tc           Move the cursor the the character before c.",
  184. "     i a          Enter insert mode before/after the cursor.",
  185. "     I A          Move to column 0/end of line and enter insert mode.",
  186. "     x X          Delete the character under/before the cursor.",
  187. "     rc           Replace the character under the cursor with c.",
  188. "     cm           Change - m = b,f,h,l,t or w.",
  189. "     dm           Delete - m = b,f,h,l,t or w.",
  190. "     R            Enter replace (overstrike) mode.",
  191. "     + j - k /    Forward/backward/search the command history.",
  192. "     n            Repeat last history search.",
  193. "     . u          Repeat/undo the last command.",
  194. (char *)0
  195. };
  196.  
  197. char *file[] = {
  198. " ",
  199. #if defined(QREF) && defined(TROFF)
  200. ".SH",
  201. #endif
  202. " G: File commands:",
  203. " ",
  204. #if defined(QREF) && defined(TROFF)
  205. ".Lp",
  206. #endif
  207. "     G    Get a new database from a file. ",
  208. "     M    Merge a new file into the current database.",
  209. "     P    Put the current database into a file.",
  210. "     W    Write a listing of the current database into a file in",
  211. "          a form that matches its appearance on the screen.",
  212. "     T    Write a listing of the current database to a file, but",
  213. "          put delimiters between each pair of fields.",
  214. "          Optionally brackets output with control lines for ``tbl'',",
  215. "          ``LaTeX'', ``SLaTex'', or ``TeX''.",
  216. " ",
  217. #if !defined(VMS) && !defined(MSDOS) && defined(CRYPT_PATH)
  218. "     If encryption mode is set, file I/O will be encrypted/decrypted.",
  219. "     ``\"| program\"'' for a file name will pipe (unencrypted) output to",
  220. #else
  221. "     ``\"| program\"'' for a file name will pipe output to",
  222. #endif
  223. "     a program for Put, Write and Table.  If a cell name is used",
  224. "     as the file name, the cell's string part will be used as the",
  225. "     file name.",
  226. (char *)0
  227. };
  228.  
  229.  
  230. char *row[] = {
  231. " ",
  232. #if defined(QREF) && defined(TROFF)
  233. ".SH",
  234. #endif
  235. " H: Row and column commands:",
  236. " ",
  237. #if defined(QREF) && defined(TROFF)
  238. ".Lp",
  239. #endif
  240. "     ir, ic      Insert a new, empty row (column)",
  241. "     ar, ac      Append a new copy of the current row (column)",
  242. "     dr, dc      Delete the current row (column)",
  243. "     pr, pc, pm  Pull deleted cells back into the spreadsheet",
  244. "                 Insert rows, columns or merge the cells.",
  245. "     vr, vc      Remove expressions from the affected rows (columns),",
  246. "                 leaving only the values.",
  247. "     zr, zc      Hide (``zap'') the current row (column)",
  248. "     sr, sc      Show hidden rows (columns)",
  249. "     f           Set the output format to be used with the values of",
  250. "                 each cell in this column.  Enter field width and",
  251. "                 number of fractional digits.  A preceding count can be",
  252. "                 used to change more than one column.",
  253. " ",
  254. "     Commands which move or copy cells also modify the row and column ",
  255. "     references in the new cell expressions.  Use ``fixed'' or the",
  256. "     ``$'' style cell reference to supress the change.",
  257. " ",
  258. "     @myrow, @mycol    return the row or column of the current cell",
  259. (char *)0
  260. };
  261.  
  262.  
  263. char *range[] = {
  264. " ",
  265. #if defined(QREF) && defined(TROFF)
  266. ".SH",
  267. #endif
  268. " I: Range commands:",
  269. #if defined(QREF) && defined(TROFF)
  270. ".Lp",
  271. #endif
  272. "     /x   Clear a range. ",
  273. "     /v   Remove the expressions from a range of cells, leaving ",
  274. "          just the values.",
  275. "     /c   Copy a source range to a destination range.",
  276. "     /f   Fill a range with constant values starting with a given",
  277. "          value and increasing by a given increment.",
  278. "     /d   Assign a name to a cell or a range of cells.  Give the",
  279. "          the name, surrounded by quotes, and either a cell name such",
  280. "          as ``A10'' or a range such as ``a1:b20''.",
  281. "     /l   Locks a cell or a range of cells, i.e makes it unchangeable.",
  282. "     /U   Unlocks a locked cell, i.e makes it changeable.",
  283. "     /s   Shows the currently defined range names.  Pipe output to",
  284. "          sort, then to less.",
  285. "     /u   Use this command to undefine a previously defined range name.",
  286. "     /F   Assign a format string to a range of cells.",
  287. " ",
  288. "     Range operations affect a rectangular region on the screen",
  289. "     defined by the upper left and lower right cells in the region.",
  290. "     A range is specified by giving the cell names separated by ``:'',",
  291. "     such as ``a20:k52''.  Another way to refer to a range is to use",
  292. "     a name previously defined using ``/d''.",
  293. (char *)0
  294. };
  295.  
  296.  
  297. char *misc[] = {
  298. " ",
  299. #if defined(QREF) && defined(TROFF)
  300. ".SH",
  301. #endif
  302. " J: Miscellaneous commands:",
  303. " ",
  304. #if defined(QREF) && defined(TROFF)
  305. ".Lp",
  306. #endif
  307. "     Q q ^C   Exit from the program.",
  308. "     ^G ESC   Abort entry of the current command.",
  309. "     ?        Help",
  310. "     !        Shell escape.  Enter a command to run.  ``!!'' repeats",
  311. "              the last command.  Just ``!'' starts an interactive shell.",
  312. "     ^L       Redraw the screen.",
  313. "     ^R       Redraw the screen.  Highlight cells with values but no",
  314. "              expressions.",
  315. "     ^X       Redraw the screen.  Show formulas, not values.",
  316. "     @        Recalculate the spreadsheet.",
  317. "     ^V       Type, in the command line, the name of the current cell.",
  318. "     ^W       Type, in the command line, the current cell's expression.",
  319. "     ^A       Type, in the command line, the current cell's numeric value.",
  320. "     TAB      When the character cursor is on the top line TAB can be used",
  321. "              to start or stop the display of the default range.",
  322. (char *)0
  323. };
  324.  
  325. char *var[] = {
  326. " ",
  327. #if defined(QREF) && defined(TROFF)
  328. ".SH",
  329. #endif
  330. " K: Variable names:",
  331. " ",
  332. #if defined(QREF) && defined(TROFF)
  333. ".Lp",
  334. #endif
  335. "     K20    Row and column can vary on copies.",
  336. "     $K$20  Row and column stay fixed on copies.",
  337. "     $K20   Row can vary; column stays fixed on copies.",
  338. "     K$20   Row stays fixed; column can vary on copies.",
  339. "     fixed  holds following expession fixed on copies.",
  340. "     Cells and ranges can be given a symbolic name via ``/d''.",
  341. " ",
  342. " Expressions:",
  343. "     -e      Negation                e<=e  Less than or equal",
  344. "     e+e     Addition                e=e   Equal",
  345. "     e-e     Subtraction             e!=e  Not Equal",
  346. "     e*e     Multiplication          e>=e  Greater than or equal",
  347. "     e/e     Division                e>e  Greater than",
  348. "     e%e     Modulo                  e<e  Less than",
  349. "     e^e     Exponentiation          e&e  Boolean operator AND.",
  350. "     ~e      Boolean operator NOT    e|e  Boolean operator OR",
  351. "     e?e1:e2  or @if(e,e1,e2)",
  352. "             Conditional: If e is non zero then then e1, else e2.",
  353. "     Terms may be constants, variables, and parenthesized expressions.",
  354. (char *)0
  355. };
  356.  
  357. char *rangef[] = {
  358. " ",
  359. #if defined(QREF) && defined(TROFF)
  360. ".SH",
  361. #endif
  362. " L: Range functions:",
  363. " ",
  364. #if defined(QREF) && defined(TROFF)
  365. ".Lp",
  366. #endif
  367. "     @sum(r)           Sum all valid cells in the range.",
  368. "     @prod(r)          Multiply together all valid cells in the range.",
  369. "     @avg(r)           Average all valid cells in the range.",
  370. "     @count(r)         Count all valid cells in the range.",
  371. "     @max(r)           Return the maximum value in the range.",
  372. "     @min(r)           Return the minimum value in the range.",
  373. "     @stddev(r)        Return the sample standard deviation of ",
  374. "                       the cells in the range.",
  375. "     @index(e,r) @stindex(e,r)",
  376. "                       Return the numeric (string) value of the cell at",
  377. "                       index e into range r.",
  378. "     @lookup(e,r) @hlookup(e,r,n) @vlookup(e,r,n)",
  379. "                       Search through the range r for a value that",
  380. "                       matches e.  If e is numeric, the last value <= e",
  381. "                       matches; if string, an exact match is required.",
  382. "                       @lookup searches a single row (column) and returns",
  383. "                       the value from the next column (row); @hlookup",
  384. "                       (@vlookup) searches the first row (column) in r and",
  385. "                       returns the value n columns (rows) from the match.",
  386. (char *)0
  387. };
  388.  
  389. char *numericf[] = {
  390. " ",
  391. #if defined(QREF) && defined(TROFF)
  392. ".SH",
  393. #endif
  394. " M: Numeric functions:",
  395. " ",
  396. #if defined(QREF) && defined(TROFF)
  397. ".Lp",
  398. #endif
  399. "     @atan2(e1,e2)     Arc tangent of e1/e2.",
  400. "     @ceil(e)          Smallest integer not less than e.",
  401. "     @eqs(se1,se2)     1 if string expr se1 has the same value as se2.",
  402. "     @exp(e)           Exponential function of e.",
  403. "     @abs(e) @fabs(e)  Absolute value of e.",
  404. "     @floor(e)         The largest integer not greater than e.",
  405. "     @hypot(x,y)       Sqrt(x*x+y*y).",
  406. "     @max(e1,e2,...)   The maximum of the values of the e's.",
  407. "     @min(e1,e2,...)   The minimum of the values of the e's",
  408. "     @nval(se,e)       The numeric value of a named cell.",
  409. "     pi       @pi      A constant quite close to pi.",
  410. "     @pow(e1,e2)       e1 raised to the power of e2.",
  411. "     @rnd(e)           Round e to the nearest integer.",
  412. "     @round(e,n)       Round e to n decimal places.",
  413. "     @sqrt(e)          Square root of e.",
  414. "     @ston(se)         Convert string expr se to a numeric",
  415. "     @ln(e)   @log(e)           Natural/base 10 logarithm of e.",
  416. "     @dtr(e)  @rtd(e)           Convert degrees to/from radians.",
  417. "     @cos(e)  @sin(e)  @tan(e)  Trig functions of radian arguments.",
  418. "     @asin(e) @acos(e) @atan(e) Inverse trig function.",
  419. (char *)0
  420. };
  421.  
  422. char *stringf[] = {
  423. " ",
  424. #if defined(QREF) && defined(TROFF)
  425. ".SH",
  426. #endif
  427. " N: String functions:",
  428. #if defined(QREF) && defined(TROFF)
  429. ".Lp",
  430. #endif
  431. "     #                 Concatenate strings.  For example, the",
  432. "                       string expression ``A0 # \"zy dog\"'' yields",
  433. "                       ``the lazy dog'' if A0 is ``the la''.",
  434. "     @substr(se,e1,e2) Extract characters e1 through e2 from the",
  435. "                       string expression se.  For example,",
  436. "                       ``@substr(\"Nice jacket\" 4, 7)'' yields ",
  437. "                       ``e ja''.",
  438. "     @fmt(se,e)        Convert a number to a string using sprintf(3).",
  439. "                       For example,  ``@fmt(\"*%6.3f*\",10.5)'' yields",
  440. "                       ``*10.500*''.  Use formats are e, E, f, g, and G.", 
  441. "     @sval(se,e)       Return the string value of a cell selected by name.",
  442. "     @ext(se,e)        Call an external function (program or",
  443. "                       script).  Convert e to a string and append it",
  444. "                       to the command line as an argument.  @ext yields",
  445. "                       a string: the first line printed to standard",
  446. "                       output by the command.",
  447. "     @coltoa(e)        Return the column letter(s) from the passed number",
  448. "     @upper(e) @lower(e)   Return the string in upper/lower case",
  449. "     @capital(e)       Return the string with words in upper case",
  450. "     String expressions are made up of constant strings (characters",
  451. "     surrounded by quotes), variables, and string functions.",
  452. (char *)0
  453. };
  454.  
  455.  
  456. char *finf[] = {
  457. " ",
  458. #if defined(QREF) && defined(TROFF)
  459. ".SH",
  460. #endif
  461. " O: Financial functions:",
  462. " ",
  463. #if defined(QREF) && defined(TROFF)
  464. ".Lp",
  465. #endif
  466. "     @pmt(e1,e2,e3)    @pmt(60000,.01,360) computes the monthly",
  467. "                       payments for a $60000 mortgage at 12%",
  468. "                       annual interest (.01 per month) for 30",
  469. "                       years (360 months).",
  470. " ",
  471. "     @fv(e1,e2,e3)     @fv(100,.005,36) computes the future value",
  472. "                       of 36 monthly payments of $100 at 6%",
  473. "                       interest (.005 per month).  It answers the",
  474. "                       question:  ``How much will I have in 36",
  475. "                       months if I deposit $100 per month in a",
  476. "                       savings account paying 6% interest com-",
  477. "                       pounded monthly?''",
  478. " ",
  479. "     @pv(e1,e2,e3)     @pv(1000,.015,36) computes the present",
  480. "                       value of an ordinary annuity of 36",
  481. "                       monthly payments of $1000 at 18% annual",
  482. "                       interest.  It answers the question: ``How",
  483. "                       much can I borrow at 18% for 30 years if I",
  484. "                       pay $1000 per month?''",
  485. (char *)0
  486. };
  487.  
  488.  
  489. char *timef[] = {
  490. " ",
  491. #if defined(QREF) && defined(TROFF)
  492. ".SH",
  493. #endif
  494. " P: Time and date functions:",
  495. " ",
  496. #if defined(QREF) && defined(TROFF)
  497. ".Lp",
  498. #endif
  499. "     @now              Return the time encoded in seconds since 1970.",
  500. "     @dts(m,d,y)       Return m/d/y encoded in seconds since 1970.",
  501. "     @tts(h,m,s)       Return h:m:s encoded in seconds since midnight.",
  502. " ",
  503. "     All of the following take an argument expressed in seconds:",
  504. " ",
  505. "     @date(e)          Convert the time in seconds to a date",
  506. "                       string 24 characters long in the following",
  507. "                       form: ``Sun Sep 16 01:03:52 1973''.  Note",
  508. "                       that you can extract pieces of this fixed format",
  509. "                       string with @substr.",
  510. "     @year(e)          Return the year.  Valid years begin with 1970.",
  511. "     @month(e)         Return the month: 1 (Jan) to 12 (Dec).",
  512. "     @day(e)           Return the day of the month: 1 to 31.",
  513. "     @hour(e)          Return the number of hours since midnight: 0 to 23.",
  514. "     @minute(e)        Return the number of minutes since the",
  515. "                       last full hour: 0 to 59.",
  516. "     @second(e)        Return the number of seconds since the",
  517. "                       last full minute: 0 to 59.",
  518. (char *)0
  519. };
  520.  
  521. #ifndef QREF
  522. static    int    pscreen();
  523.  
  524. void
  525. help()
  526. {
  527.     int option;
  528.     char **ns = intro;
  529.  
  530.     while((option = pscreen(ns)) != 'q' && option != 'Q') {
  531.         switch (option) {
  532.     case 'a': case 'A': ns = intro; break;
  533.     case 'b': case 'B': ns = toggleoptions; break;
  534.     case 'c': case 'C': ns = setoptions; break;
  535.     case 'd': case 'D': ns = cursor; break;
  536.     case 'e': case 'E': ns = cell; break;
  537.     case 'f': case 'F': ns = vi; break;
  538.     case 'g': case 'G': ns = file; break;
  539.     case 'h': case 'H': ns = row; break;
  540.     case 'i': case 'I': ns = range; break;
  541.     case 'j': case 'J': ns = misc; break;
  542.     case 'k': case 'K': ns = var; break;
  543.     case 'l': case 'L': ns = rangef; break;
  544.     case 'm': case 'M': ns = numericf; break;
  545.     case 'n': case 'N': ns = stringf; break;
  546.     case 'o': case 'O': ns = finf; break;
  547.     case 'p': case 'P': ns = timef; break;
  548.     default: ns = intro; break;
  549.     }
  550.     }
  551.     FullUpdate++;
  552.     (void) move(1,0);
  553.     (void) clrtobot();
  554. }
  555.  
  556. static    int
  557. pscreen(screen)
  558. char *screen[];
  559. {
  560.     int lineno;
  561.     int dbline;
  562.  
  563.     (void) move(1,0);
  564.     (void) clrtobot();
  565.     dbline = 1;
  566.     for (lineno = 0; screen[lineno]; lineno++) {
  567.     (void) move(dbline++, 4);
  568.     (void) addstr (screen[lineno]);
  569.     (void) clrtoeol();
  570.     }
  571.     (void) move(0,0);
  572.     (void) printw("Which Screen? [a-o, q]");
  573.     (void) clrtoeol();
  574.     (void) refresh();
  575.     return(nmgetch());
  576. }
  577. #else
  578. char    ** pages[] = { intro, toggleoptions, setoptions, cursor, cell, vi,
  579.             file, row, range, misc, var, rangef, numericf, stringf,
  580.             finf, timef, NULL};
  581.  
  582. void
  583. main()
  584. {   int    lineno;
  585.     char    ***pagep = pages;
  586. #ifdef TROFF
  587.     int    pageno = 0;
  588. #endif
  589.  
  590. #ifdef TROFF
  591. puts(".nr PS 12");
  592. puts(".nr VS 14");
  593. puts(".nr HM 1i");
  594. puts(".nr FM 1i");
  595. puts(".nr PO 0.5i");
  596. printf(".EH '%s%s''%s'\n", SCNAME, header, revision);
  597. printf(".OH '%s%s''%s'\n", SCNAME, header, revision);
  598. puts(".EF ''%''");
  599. puts(".OF ''%''");
  600. puts(".de Lp");
  601. puts(".LP");
  602. puts(".ft CW");
  603. puts(".na");
  604. puts(".nf");
  605. puts("..");
  606. puts(".P1");
  607. puts(".LP");
  608. #endif
  609.  
  610.     while (*pagep)
  611.     {
  612. #ifndef TROFF
  613.     (void) printf("%s%s\n%s", SCNAME, header, revision);
  614. #endif
  615.  
  616.     for (lineno = 0; (*pagep)[lineno]; lineno++) {
  617.         (void) puts((*pagep)[lineno]);
  618.     }
  619. #if !defined(TROFF)
  620.     (void) putchar('\f');
  621. #endif
  622.     pagep++;
  623. #ifdef TROFF
  624.     pageno++;
  625.     if (!(pageno%2)) puts(".bp");
  626. #endif
  627.     }
  628.     (void) exit(0);
  629. }
  630. #endif /* QREF */
  631.