home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / pr2 < prev    next >
Encoding:
Text File  |  1992-04-10  |  27.1 KB  |  1,075 lines

  1. Newsgroups: comp.sources.unix
  2. From: jearls@blackbird.csc.calpoly.edu (Johnson Earls)
  3. Subject: v26i007: pr2 - a simple page formatter similar to `pr'
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: jearls@blackbird.csc.calpoly.edu (Johnson Earls)
  8. Posting-Number: Volume 26, Issue 7
  9. Archive-Name: pr2
  10.  
  11. [ I edited the Makefile to get rid of some localized pathnames and to get it
  12.   down under 80 characters per line.  --vix ]
  13.  
  14. pr2.c   --  a simple page formatter similar to `pr'
  15.  
  16. usage:
  17.     pr2  [options/filenames...]
  18.  
  19. options:
  20.     -T <#>      Set number of rows in the top margin.
  21.     -B <#>      Set number of rows in the bottom margin.
  22.     -L <#>      Set number of cols in the left margin.
  23.     -R <#>      Set number of cols in the right margin.
  24.     -w <#>      Set number of cols on a page.
  25.     -l <#>      Set number of rows on a page.
  26.     -s <#>      Set the line spacing.
  27.     -p <#>      Set the page number.
  28.     -pr         Set page numbering to roman numerals
  29.     -pa         Set page numbering to arabic numerals
  30.  
  31.     -t#text     Assign 'text' to title # and turn it on.
  32.     -h#[yn]     Turn title # on or off.
  33.     -h#[tb][lcr]
  34.                 Set the position of the title:  t=top,
  35.                 b=bottom, l=left, c=center, r=right.
  36.                 Examples: tc=top center, bl=bottom left.
  37.  
  38.     -v          Displays the version number of pr2.  If
  39.                 this option is given and no files are
  40.                 specified on the command line, pr2 will
  41.                 quit immediately rather than wait for
  42.                 text from standard input.
  43.  
  44. #! /bin/sh
  45. # This is a shell archive.  Remove anything before this line, then unpack
  46. # it by saving it into a file and typing "sh file".  To overwrite existing
  47. # files, type "sh file -c".  You can also feed this as standard input via
  48. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  49. # will see the following message at the end:
  50. #        "End of shell archive."
  51. # Contents:  CHANGES INSTALL MANIFEST Makefile README pr2.c pr2.man
  52. #   pr2.test.suite
  53. # Wrapped by vixie@cognition.pa.dec.com on Sat Apr 11 15:45:59 1992
  54. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  55. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  56.   echo shar: Will not clobber existing file \"'CHANGES'\"
  57. else
  58. echo shar: Extracting \"'CHANGES'\" \(236 characters\)
  59. sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  60. Revision 2.2  91/12/02  12:03:13  jearls
  61. Added -v option
  62. X
  63. Revision 2.1  91/11/24  10:10:24  jearls
  64. Added -s option for line spacing.
  65. Added usage info to header for -t, -h, -s.
  66. X
  67. Revision 2.0  91/11/24  00:57:58  jearls
  68. Initial Revision
  69. X
  70. END_OF_FILE
  71. if test 236 -ne `wc -c <'CHANGES'`; then
  72.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  73. fi
  74. # end of 'CHANGES'
  75. fi
  76. if test -f 'INSTALL' -a "${1}" != "-c" ; then 
  77.   echo shar: Will not clobber existing file \"'INSTALL'\"
  78. else
  79. echo shar: Extracting \"'INSTALL'\" \(1277 characters\)
  80. sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
  81. Installation instructions for pr2:
  82. X
  83. X
  84. Updating the `Tweakables' section of the Makefile:
  85. X
  86. X  For most systems, you will need to change BINDIR and
  87. X  MANDIR to the appropriate directories for installation,
  88. X  SECTION for which section of the manual you want to
  89. X  install under, and possibly CC for an ANSI-compatible C
  90. X  compiler.  If you don't want the executable to be
  91. X  stripped, change the STRIP symbol to `touch' rather than
  92. X  `strip' and CFLAGS to contain -g rather than -O.
  93. X
  94. X  Build by running `make' alone.  This will create the
  95. X  executable file and the man page.  You can verify that
  96. X  the man page is correct by the command `nroff -man
  97. X  pr2.X', where X is the section number the man page was
  98. X  built for (`n' by default).
  99. X
  100. X  When you are ready to install pr2, type `make info' to
  101. X  check that the directories are correct.  If so, type
  102. X  `make install'.  If the directories aren't correct,
  103. X  modify the Makefile and re-make.
  104. X
  105. If you have any problems compiling or installing pr2, mail
  106. a description of the problems encountered and a description
  107. of the system on which you are trying to install to:
  108. X
  109. X    jearls@blackbird.csc.calpoly.edu
  110. X
  111. Be prepared to send a script of the `make' process -- but
  112. not until I ask you for it.  :)
  113. X
  114. Suggestions and comments are also welcome.
  115. END_OF_FILE
  116. if test 1277 -ne `wc -c <'INSTALL'`; then
  117.     echo shar: \"'INSTALL'\" unpacked with wrong size!
  118. fi
  119. # end of 'INSTALL'
  120. fi
  121. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  123. else
  124. echo shar: Extracting \"'MANIFEST'\" \(497 characters\)
  125. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  126. X   File Name        Archive #    Description
  127. X-----------------------------------------------------------
  128. X CHANGES                    1    Changes in the source since v2.0
  129. X INSTALL                    1    Installation instructions
  130. X MANIFEST                   1    This list
  131. X Makefile                   1    Build file
  132. X README                     1    Description of pr2
  133. X pr2.c                      1    The source
  134. X pr2.man                    1    Template for the man page
  135. X pr2.test.suite             1    Test data for validation
  136. END_OF_FILE
  137. if test 497 -ne `wc -c <'MANIFEST'`; then
  138.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  139. fi
  140. # end of 'MANIFEST'
  141. fi
  142. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  143.   echo shar: Will not clobber existing file \"'Makefile'\"
  144. else
  145. echo shar: Extracting \"'Makefile'\" \(3264 characters\)
  146. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  147. X#
  148. X# Makefile for $(PROG)
  149. X#
  150. X# Tweakables:
  151. X#
  152. X
  153. X# Your CC must grok ANSI C
  154. CC =        gcc
  155. X#CC =        cc
  156. X
  157. CFLAGS =    -O
  158. X#CFLAGS =    -g
  159. X
  160. STRIP =        strip
  161. X#STRIP =    touch    # use if you don't want the
  162. X#            # executable strip'd
  163. X
  164. SECTION =    n
  165. X
  166. DESTROOT =
  167. DESTSHR = $(DESTROOT)/usr/share
  168. DESTSYS = $(DESTROOT)/usr/local
  169. X
  170. BIN =        $(DESTSYS)/bin
  171. MAN =        $(DESTSHR)/man
  172. X
  173. X########### Don't change anything below this line ##########
  174. X
  175. PROG =        pr2
  176. OBJS =        pr2.o
  177. SRCS =        pr2.c
  178. MANPAGE =    $(PROG).$(SECTION)
  179. MANDIR =    $(MAN)/man$(SECTION)
  180. X
  181. all:        $(PROG) $(MANPAGE)
  182. X
  183. X$(PROG):    $(OBJS)
  184. X    $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LDFLAGS) $(LIBS)
  185. X    $(STRIP) $(PROG)
  186. X
  187. X$(MANPAGE):    $(PROG).man sedscript
  188. X    ./sedscript < $(PROG).man > $(MANPAGE)
  189. X
  190. info:
  191. X    @echo
  192. X    @echo '`'"make install' will install" \
  193. X        "$(PROG) into $(BIN)"
  194. X    @echo "and $(MANPAGE) into $(MANDIR)."
  195. X    @echo
  196. X
  197. install:    $(PROG) $(MANPAGE)
  198. X    -if test ! -d $(BIN) ; then mkdir $(BIN) ; fi
  199. X    -if test -r $(BIN)/$(PROG) ; then \
  200. X        rm -f $(BIN)/$(PROG).old ; \
  201. X        mv $(BIN)/$(PROG) $(BIN)/$(PROG).old ; \
  202. X    fi
  203. X    cp $(PROG) $(BIN)/$(PROG)
  204. X    -if test ! -d $(MAN) ; then mkdir $(MAN) ; fi
  205. X    -if test ! -d $(MANDIR) ; then mkdir $(MANDIR) ; fi
  206. X    -if test -r $(MANDIR)/$(MANPAGE) ; then \
  207. X        rm -f $(MANDIR)/$(MANPAGE).old ; \
  208. X        mv $(MANDIR)/$(MANPAGE) $(MANDIR)/$(MANPAGE).old ; \
  209. X    fi
  210. X    cp $(MANPAGE) $(MANDIR)/$(MANPAGE)
  211. X
  212. sedscript:    Makefile
  213. X    @echo building sedscript...
  214. X    @rm -f sedscript
  215. X    @echo "#!/bin/sh" > sedscript
  216. X    @echo 'set `date`' >> sedscript
  217. X    @echo 'DATE="$$3 $$2 $$6"' >> sedscript
  218. X    @echo 'set '"'"'"'"'"'`grep "^\*.*Revision" $(SRCS)`'"'"'"'"'" \
  219. X        >> sedscript
  220. X    @echo 'VERSION="$$3"' >> sedscript
  221. X    @echo \
  222. X'sed "s/%V%/$$VERSION/g" | sed "s/%D%/$$DATE/g" | sed "s/%S%/$(SECTION)/g"' \
  223. X>> sedscript
  224. X    @chmod 700 sedscript
  225. X
  226. clean:
  227. X        rm -f *.o $(PROG) $(MANPAGE) sedscript
  228. X
  229. verify:        $(PROG) sedscript
  230. X    echo "$(PROG) test suite:  version %V%" | sedscript > test.suite
  231. X    @./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 $(SRCS) > size.source ; \
  232. X        wc size.source >> test.suite ; rm size.source
  233. X    @./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 $(PROG).man > size.$(PROG).man ; \
  234. X        wc size.$(PROG).man >> test.suite ; rm size.$(PROG).man
  235. X    @./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 README > size.README ; \
  236. X        wc size.README >> test.suite ; rm size.README
  237. X    diff test.suite $(PROG).test.suite
  238. X    rm test.suite
  239. X
  240. X############################################################
  241. X#
  242. X# The following are what I use to make a distribution.  They
  243. X# probably won't be very helpful to you.
  244. X#
  245. X############################################################
  246. X
  247. package:    $(PROG).test.suite $(SRCS) $(PROG).man Makefile \
  248. X        MANIFEST CHANGES README INSTALL
  249. X    @echo "Creating package..."
  250. X    makekit -m
  251. X
  252. CHANGES:    $(SRCS)
  253. X    sed '1,/Modification/d' $(SRCS) \
  254. X        | sed '/\*\*\*\*/,$$d' \
  255. X        | sed 's/^........//' > CHANGES
  256. X
  257. X$(PROG).test.suite:    $(PROG) sedscript
  258. X    rm -f $(PROG).test.suite
  259. X    echo "$(PROG) test suite:  version %V%" \
  260. X        | sedscript > $(PROG).test.suite
  261. X    ./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 $(SRCS) > size.source ; \
  262. X        wc size.source >> $(PROG).test.suite ; rm size.source
  263. X    ./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 $(PROG).man > size.$(PROG).man ; \
  264. X        wc size.$(PROG).man >> $(PROG).test.suite ; rm size.$(PROG).man
  265. X    ./$(PROG) -T2 -B4 -L6 -R8 -w40 -l20 README > size.README ; \
  266. X        wc size.README >> $(PROG).test.suite ; rm size.README
  267. END_OF_FILE
  268. if test 3264 -ne `wc -c <'Makefile'`; then
  269.     echo shar: \"'Makefile'\" unpacked with wrong size!
  270. fi
  271. # end of 'Makefile'
  272. fi
  273. if test -f 'README' -a "${1}" != "-c" ; then 
  274.   echo shar: Will not clobber existing file \"'README'\"
  275. else
  276. echo shar: Extracting \"'README'\" \(1141 characters\)
  277. sed "s/^X//" >'README' <<'END_OF_FILE'
  278. pr2.c   --  a simple page formatter similar to `pr'
  279. X
  280. usage:
  281. X    pr2  [options/filenames...]
  282. X
  283. options:
  284. X    -T <#>      Set number of rows in the top margin.
  285. X    -B <#>      Set number of rows in the bottom margin.
  286. X    -L <#>      Set number of cols in the left margin.
  287. X    -R <#>      Set number of cols in the right margin.
  288. X    -w <#>      Set number of cols on a page.
  289. X    -l <#>      Set number of rows on a page.
  290. X    -s <#>      Set the line spacing.
  291. X    -p <#>      Set the page number.
  292. X    -pr         Set page numbering to roman numerals
  293. X    -pa         Set page numbering to arabic numerals
  294. X
  295. X    -t#text     Assign 'text' to title # and turn it on.
  296. X    -h#[yn]     Turn title # on or off.
  297. X    -h#[tb][lcr]
  298. X                Set the position of the title:  t=top,
  299. X                b=bottom, l=left, c=center, r=right.
  300. X                Examples: tc=top center, bl=bottom left.
  301. X
  302. X    -v          Displays the version number of pr2.  If
  303. X                this option is given and no files are
  304. X                specified on the command line, pr2 will
  305. X                quit immediately rather than wait for
  306. X                text from standard input.
  307. END_OF_FILE
  308. if test 1141 -ne `wc -c <'README'`; then
  309.     echo shar: \"'README'\" unpacked with wrong size!
  310. fi
  311. # end of 'README'
  312. fi
  313. if test -f 'pr2.c' -a "${1}" != "-c" ; then 
  314.   echo shar: Will not clobber existing file \"'pr2.c'\"
  315. else
  316. echo shar: Extracting \"'pr2.c'\" \(13395 characters\)
  317. sed "s/^X//" >'pr2.c' <<'END_OF_FILE'
  318. X/***********************************************************
  319. X**
  320. X**  pr2.c   --  a new (better?) file paginator
  321. X**
  322. X**  usage:
  323. X**      pr2  [options/filenames...]
  324. X**
  325. X**  options:
  326. X**      -T <#>      Set number of rows in the top margin.
  327. X**      -B <#>      Set number of rows in the bottom margin.
  328. X**      -L <#>      Set number of cols in the left margin.
  329. X**      -R <#>      Set number of cols in the right margin.
  330. X**      -w <#>      Set number of cols on a page.
  331. X**      -l <#>      Set number of rows on a page.
  332. X**      -s <#>      Set the line spacing.
  333. X**      -p <#>      Set the page number.
  334. X**      -pr         Set page numbering to roman numerals
  335. X**      -pa         Set page numbering to arabic numerals
  336. X**
  337. X**      -t#text     Assign 'text' to title # and turn it on.
  338. X**      -h#[yn]     Turn title # on or off.
  339. X**      -h#[tb][lcr]
  340. X**                  Set the position of the title:  t=top,
  341. X**                  b=bottom, l=left, c=center, r=right.
  342. X**                  Examples: tc=top center, bl=bottom left.
  343. X**
  344. X**      -v          Displays the version number of pr2.  If
  345. X**                  this option is given and no files are
  346. X**                  specified on the command line, pr2 will
  347. X**                  quit immediately rather than wait for
  348. X**                  text from standard input.
  349. X**
  350. X**  $Revision: 2.2 $
  351. X**
  352. X**    $Author: jearls $
  353. X**      $Date: 91/12/02 12:03:13 $
  354. X**
  355. X**  Modification History:  $Log:    pr2.c,v $
  356. X**      Revision 2.2  91/12/02  12:03:13  jearls
  357. X**      Added -v option
  358. X**      
  359. X**      Revision 2.1  91/11/24  10:10:24  jearls
  360. X**      Added -s option for line spacing.
  361. X**      Added usage info to header for -t, -h, -s.
  362. X**      
  363. X**      Revision 2.0  91/11/24  00:57:58  jearls
  364. X**      Initial Revision
  365. X**      
  366. X***********************************************************/
  367. X
  368. X#include <stdio.h>
  369. X#include <strings.h>
  370. X#include <ctype.h>
  371. X
  372. typedef struct  Title
  373. X{
  374. X  char   *text;
  375. X  int     pos;    /* 1 = left, 2 = right, 3 = center */
  376. X  int     header; /* 1 = header, 0 = footer */
  377. X  int     flag;   /* 1 = print, 0 = don't */
  378. X} Title;
  379. X
  380. typedef struct  Page
  381. X{
  382. X  int rows, cols, top, bottom, left, right;
  383. X} Page;
  384. X
  385. static  Title   titles[6] =
  386. X{
  387. X  { "%f", 3, 1, 1 },
  388. X  { "- %p -", 3, 0, 1 },
  389. X  { "", 1, 1, 0 },
  390. X  { "", 2, 1, 0 },
  391. X  { "", 1, 0, 0 },
  392. X  { "", 2, 0, 0 }
  393. X} ;
  394. X
  395. static  Page    page = { 66, 80, 6, 6, 10, 10 };
  396. X
  397. static  int     linenum = 0, charnum = 0,
  398. X                pagenum = 1, pageform = 1,  /* 0 = roman, 1 = arabic */
  399. X                lineSpacing = 1;
  400. static  char   *curFilename, *progName, pagestr[10];
  401. X
  402. char   *strdup(char *s)
  403. X{
  404. X  char *p;
  405. X
  406. X  p = (char *)malloc(1+strlen(s));
  407. X  if (p)
  408. X    (void)strcpy(p, s);
  409. X  return(p);
  410. X}
  411. X
  412. char   *instr(char *str, char *sub)
  413. X{
  414. X  char *p, *q, *index();
  415. X
  416. X  while (str = index(str, *sub))
  417. X  {
  418. X    p = str; q = sub;
  419. X    while (*(++q) && ((*++p) == (*q)));
  420. X    if (!(*q))
  421. X      return(str);
  422. X    str++;
  423. X  }
  424. X  return((char *)NULL);
  425. X}
  426. X
  427. char   *subst(char *orig, char *old, char *new)
  428. X{
  429. X  char *p, *q;
  430. X  int expand = strlen(new)-strlen(old) + 1;
  431. X
  432. X  while(q = instr(orig, old))
  433. X  {
  434. X    p = (char *)malloc(strlen(orig) + expand);
  435. X    *q = '\0';
  436. X    (void)strcpy(p, orig);
  437. X    (void)strcat(p, new);
  438. X    (void)strcat(p, q+strlen(old));
  439. X    free(orig);
  440. X    orig = p;
  441. X  }
  442. X
  443. X  return(orig);
  444. X}
  445. X
  446. void    addTitle(char *line, Title title, int header)
  447. X{
  448. X  char   *txt, *p;
  449. X  int     col, len;
  450. X
  451. X  if ((title.flag) && (title.header == header))
  452. X  {
  453. X    txt = strdup(title.text);
  454. X    txt = subst(txt, "%f", curFilename);
  455. X    txt = subst(txt, "%p", pagestr);
  456. X    col = 0;
  457. X    if (title.pos != 1)
  458. X      col = page.cols - page.right - strlen(txt);
  459. X    if (title.pos == 3)
  460. X      col = (col - page.left) / 2;
  461. X    if (title.pos != 2)
  462. X      col += page.left;
  463. X    len = strlen(line);
  464. X    while (len < col)
  465. X      line[len++] = ' ';
  466. X    p = txt;
  467. X    while (*txt)
  468. X      line[col++] = *(txt++);
  469. X    if (col > len)
  470. X      line[col] = '\0';
  471. X    free(p);
  472. X  }
  473. X}
  474. X
  475. void addRoman(char **s, int num, int pos, char c1, char c5, char c10)
  476. X{
  477. X  int dig = (num/pos) % 10;
  478. X
  479. X  if (dig == 9)
  480. X  {
  481. X    *((*s)++) = c1;
  482. X    *((*s)++) = c10;
  483. X  } else
  484. X    if (dig == 4)
  485. X    {
  486. X      *((*s)++) = c1;
  487. X      *((*s)++) = c5;
  488. X    } else {
  489. X      if (dig > 4)
  490. X        *((*s)++) = c5;
  491. X      dig %= 5;
  492. X      while (dig--)
  493. X        *((*s)++) = c1;
  494. X    }
  495. X}
  496. X
  497. void roman(char *s, int num)
  498. X{
  499. X  addRoman(&s, num, 1000, 'm', '?', '?');
  500. X  num %= 1000;
  501. X  addRoman(&s, num, 100, 'c', 'd', 'm');
  502. X  num %= 100;
  503. X  addRoman(&s, num, 10, 'x', 'l', 'c');
  504. X  num %= 10;
  505. X  addRoman(&s, num, 1, 'i', 'v', 'x');
  506. X  *s = '\0';
  507. X}
  508. X
  509. void    print_header()
  510. X{
  511. X  char *line;
  512. X  int lp;
  513. X
  514. X  if (page.top > 1)
  515. X  {
  516. X    if (pageform)
  517. X      (void)sprintf(pagestr, "%d", pagenum);
  518. X    else
  519. X      roman(pagestr, pagenum);
  520. X
  521. X    line = (char *)malloc(page.cols);
  522. X    *line = '\0';
  523. X
  524. X    for (lp=0; lp<6; lp++)
  525. X      addTitle(line, titles[lp], 1);
  526. X
  527. X    linenum = lp = (page.top - 1) / 2;
  528. X
  529. X    while (lp--)
  530. X      putchar('\n');
  531. X
  532. X    puts(line);
  533. X    free(line);
  534. X
  535. X    linenum++;
  536. X  }
  537. X
  538. X  while (linenum < page.top)
  539. X  {
  540. X    putchar('\n');
  541. X    linenum++;
  542. X  }
  543. X
  544. X  charnum = 0;
  545. X}
  546. X
  547. void    print_footer()
  548. X{
  549. X  char *line;
  550. X  int lp;
  551. X
  552. X  if (page.bottom > 1)
  553. X  {
  554. X    if (pageform)
  555. X      (void)sprintf(pagestr, "%d", pagenum++);
  556. X    else
  557. X      roman(pagestr, pagenum++);
  558. X
  559. X    line = (char *)malloc(page.cols);
  560. X    *line = '\0';
  561. X
  562. X    for (lp=0; lp<6; lp++)
  563. X      addTitle(line, titles[lp], 0);
  564. X
  565. X    linenum += lp = page.bottom / 2;
  566. X
  567. X    while (lp--)
  568. X      putchar('\n');
  569. X
  570. X    puts(line);
  571. X    free(line);
  572. X
  573. X    linenum++;
  574. X  }
  575. X
  576. X  while (linenum < page.rows)
  577. X  {
  578. X    putchar('\n');
  579. X    linenum++;
  580. X  }
  581. X
  582. X  linenum = charnum = 0;
  583. X}
  584. X
  585. void    out(char c)
  586. X{
  587. X  int lp;
  588. X
  589. X  if ((isprint(c)) || (isspace(c)))
  590. X  {
  591. X    if ((c != '\014') && (linenum == page.rows - page.bottom))
  592. X      print_footer();
  593. X    if (linenum < page.top)
  594. X      print_header();
  595. X    if (isprint(c))
  596. X    {
  597. X      if (charnum == page.cols - page.right)
  598. X      out('\n');
  599. X      while (charnum < page.left)
  600. X      {
  601. X        putchar(' ');
  602. X        charnum++;
  603. X      }
  604. X      putchar(c);
  605. X      charnum++;
  606. X    } else
  607. X      switch(c)
  608. X      {
  609. X        case '\t'     :
  610. X          out(' ');
  611. X          while ((charnum - page.left) % 8)
  612. X            out(' ');
  613. X          break;
  614. X        case '\r'     :
  615. X        case '\013'   :
  616. X        case '\n'     :
  617. X          for (lp=lineSpacing; lp--;)
  618. X          {
  619. X            if (linenum == page.rows - page.bottom)
  620. X            {
  621. X              print_footer();
  622. X              print_header();
  623. X            }
  624. X            putchar('\n');
  625. X            linenum++;
  626. X          }
  627. X          charnum = 0;
  628. X          break;
  629. X        case '\014'   :
  630. X          while (linenum < page.rows-page.bottom)
  631. X            out('\n');
  632. X          print_footer();
  633. X          break;
  634. X        }
  635. X    }
  636. X}
  637. X
  638. void doFile(char *fn)
  639. X{
  640. X  int c;
  641. X  FILE *f;
  642. X
  643. X  if (curFilename = fn)
  644. X    f = fopen(fn, "r");
  645. X  else
  646. X  {
  647. X    curFilename = "stdin";
  648. X    f = stdin;
  649. X  }
  650. X
  651. X  if (f == (FILE *)NULL)
  652. X    perror(fn);
  653. X  else
  654. X  {
  655. X    while ((c = getc(f)) != EOF)
  656. X      out((char)c);
  657. X    if (linenum)
  658. X      out('\014');
  659. X
  660. X    if (fn)
  661. X      fclose(f);
  662. X  }
  663. X}
  664. X
  665. void usage(char *err)
  666. X{
  667. X  fprintf(stderr, "%s:  %s\n", progName, err);
  668. X  exit(1);
  669. X}
  670. X
  671. int isnumber(char *s)
  672. X{
  673. X  if (!(*s)) return(0);
  674. X  while ((*s) && (isdigit(*s))) s++;
  675. X  return(!(*s));
  676. X}
  677. X
  678. void main(int argc, char **argv)
  679. X{
  680. X  int fileFlag = 0, tmp, tmp2;
  681. X  char buf[128], *p;
  682. X
  683. X  progName = *argv;
  684. X
  685. X  while (--argc) 
  686. X    if (**(++argv) == '-')
  687. X    {
  688. X      switch((p = *argv)[1])
  689. X      {
  690. X        case 'T' :
  691. X          if (p[2])
  692. X            if (isnumber(p+2))
  693. X              page.top = atoi(p+2);
  694. X            else
  695. X              usage("-T :  Numeric argument needed.");
  696. X          else if (argc--)
  697. X            if (isnumber(*(++argv)))
  698. X              page.top = atoi(*argv);
  699. X            else
  700. X              usage("-T :  Numeric argument needed.");
  701. X          else
  702. X            usage("-T :  Numeric argument needed.");
  703. X          break;
  704. X
  705. X        case 'B' :
  706. X          if (p[2])
  707. X            if (isnumber(p+2))
  708. X              page.bottom = atoi(p+2);
  709. X            else
  710. X              usage("-B :  Numeric argument needed.");
  711. X          else if (argc--)
  712. X            if (isnumber(*(++argv)))
  713. X              page.bottom = atoi(*argv);
  714. X            else
  715. X              usage("-B :  Numeric argument needed.");
  716. X          else
  717. X            usage("-B :  Numeric argument needed.");
  718. X          break;
  719. X
  720. X        case 'L' :
  721. X          if (p[2])
  722. X            if (isnumber(p+2))
  723. X              page.left = atoi(p+2);
  724. X            else
  725. X              usage("-L :  Numeric argument needed.");
  726. X          else if (argc--)
  727. X            if (isnumber(*(++argv)))
  728. X              page.left = atoi(*argv);
  729. X            else
  730. X              usage("-L :  Numeric argument needed.");
  731. X          else
  732. X            usage("-L :  Numeric argument needed.");
  733. X          break;
  734. X
  735. X        case 'R' :
  736. X          if (p[2])
  737. X            if (isnumber(p+2))
  738. X              page.right = atoi(p+2);
  739. X            else
  740. X              usage("-R :  Numeric argument needed.");
  741. X          else if (argc--)
  742. X            if (isnumber(*(++argv)))
  743. X              page.right = atoi(*argv);
  744. X            else
  745. X              usage("-R :  Numeric argument needed.");
  746. X          else
  747. X            usage("-R :  Numeric argument needed.");
  748. X          break;
  749. X
  750. X        case 'l' :
  751. X          if (p[2])
  752. X            if (isnumber(p+2))
  753. X              page.rows = atoi(p+2);
  754. X            else
  755. X              usage("-l :  Numeric argument needed.");
  756. X          else if (argc--)
  757. X            if (isnumber(*(++argv)))
  758. X              page.rows = atoi(*argv);
  759. X            else
  760. X              usage("-l :  Numeric argument needed.");
  761. X          else
  762. X            usage("-l :  Numeric argument needed.");
  763. X          break;
  764. X
  765. X        case 'w' :
  766. X          if (p[2])
  767. X            if (isnumber(p+2))
  768. X              page.cols = atoi(p+2);
  769. X            else
  770. X              usage("-w :  Numeric argument needed.");
  771. X          else if (argc--)
  772. X            if (isnumber(*(++argv)))
  773. X              page.cols = atoi(*argv);
  774. X            else
  775. X              usage("-w :  Numeric argument needed.");
  776. X          else
  777. X            usage("-w :  Numeric argument needed.");
  778. X          break;
  779. X
  780. X        case 's' :
  781. X          if (p[2])
  782. X            if (isnumber(p+2))
  783. X              lineSpacing = atoi(p+2);
  784. X            else
  785. X              usage("-s :  Numeric argument needed.");
  786. X          else if (argc--)
  787. X            if (isnumber(*(++argv)))
  788. X              lineSpacing = atoi(*argv);
  789. X            else
  790. X              usage("-s :  Numeric argument needed.");
  791. X          else
  792. X            usage("-s :  Numeric argument needed.");
  793. X          break;
  794. X
  795. X        case 'p' :
  796. X          if (p[2])
  797. X        if (p[2] == 'a')
  798. X          pageform = 1;
  799. X        else
  800. X          if (p[2] == 'r')
  801. X        pageform = 0;
  802. X          else
  803. X        if (isnumber(p+2))
  804. X          pagenum = atoi(p+2);
  805. X        else
  806. X          usage("-p :  Numeric argument needed.");
  807. X          else if (argc--)
  808. X            if (isnumber(*(++argv)))
  809. X              pagenum = atoi(*argv);
  810. X            else
  811. X              usage("-p :  Numeric argument needed.");
  812. X          else
  813. X            usage("-p :  Numeric argument needed.");
  814. X          break;
  815. X
  816. X        case 't' :
  817. X          if ((p[2] < '1') || (p[2] > '6'))
  818. X          {
  819. X            (void)sprintf(buf,
  820. X              "-t:  %c:  Illegal title specifier.", p[2]);
  821. X            usage(buf);
  822. X          }
  823. X
  824. X          tmp = p[2] - '1';
  825. X          p += 3;
  826. X          if ((!(*p)) && (argc))
  827. X          {
  828. X            p = *(++argv);
  829. X            argc--;
  830. X          }
  831. X          if (!(*p))
  832. X          {
  833. X            fprintf(stderr,
  834. X              "Warning:  no text given for title %d; ",
  835. X              tmp);
  836. X            fprintf(stderr,
  837. X              "turning title off and clearing.\n");
  838. X            titles[tmp].flag = 0;
  839. X          } else
  840. X            titles[tmp].flag = 1;
  841. X
  842. X          titles[tmp].text = p;
  843. X          break;
  844. X
  845. X        case 'h' :
  846. X          if ((p[2] < '1') || (p[2] > '6'))
  847. X          {
  848. X            (void)sprintf(buf,
  849. X              "-h:  %c:  Illegal title specifier.", p[2]);
  850. X            usage(buf);
  851. X          }
  852. X
  853. X          tmp = p[2] - '1';
  854. X          switch (p[3])
  855. X          {
  856. X            case 'Y'  :
  857. X            case 'y'  : titles[tmp].flag = 1;
  858. X                        tmp = -1; break;
  859. X            case 'N'  :
  860. X            case 'n'  : titles[tmp].flag = 0;
  861. X                        tmp = -1; break;
  862. X            case 'T'  :
  863. X            case 't'  : titles[tmp].header = 1; break;
  864. X            case 'B'  :
  865. X            case 'b'  : titles[tmp].header = 0; break;
  866. X            default   : sprintf(buf,
  867. X                          "%s:  Illegal title position.",
  868. X                          *argv);
  869. X                        usage(buf);
  870. X          }
  871. X
  872. X          if (tmp > -1)
  873. X            switch(p[4])
  874. X            {
  875. X              case 'L'  :
  876. X              case 'l'  : titles[tmp].pos = 1; break;
  877. X              case 'R'  :
  878. X              case 'r'  : titles[tmp].pos = 2; break;
  879. X              case 'C'  :
  880. X              case 'c'  : titles[tmp].pos = 3; break;
  881. X              default   : sprintf(buf,
  882. X                            "%s:  Illegal title position.",
  883. X                            *argv);
  884. X                          usage(buf);
  885. X            }
  886. X          break;
  887. X
  888. X    case 'v'  :
  889. X      puts("$Revision: 2.2 $");
  890. X      fileFlag = 1;
  891. X      break;
  892. X
  893. X        case '\0' :
  894. X          doFile(NULL);
  895. X          fileFlag = 1;
  896. X          break;
  897. X
  898. X        default :
  899. X          (void)sprintf(buf, "-%c :  Unknown flag.", p[1]);
  900. X          usage(buf);
  901. X      }
  902. X    } else {
  903. X      doFile(*argv);
  904. X      fileFlag = 1;
  905. X    }
  906. X
  907. X  if (!fileFlag)
  908. X    doFile(NULL);
  909. X}
  910. END_OF_FILE
  911. if test 13395 -ne `wc -c <'pr2.c'`; then
  912.     echo shar: \"'pr2.c'\" unpacked with wrong size!
  913. fi
  914. # end of 'pr2.c'
  915. fi
  916. if test -f 'pr2.man' -a "${1}" != "-c" ; then 
  917.   echo shar: Will not clobber existing file \"'pr2.man'\"
  918. else
  919. echo shar: Extracting \"'pr2.man'\" \(2020 characters\)
  920. sed "s/^X//" >'pr2.man' <<'END_OF_FILE'
  921. X.\"    @(#)pr2.%S%    %V%    created by:    Johnson Earls    %D%
  922. X.\"
  923. X.TH PR2 %S% "%D%"
  924. X.SH NAME
  925. pr2 \- a simple text formatter similar to `pr'
  926. X.SH SYNOPSIS
  927. X.B pr2
  928. X[
  929. X.BI \-T n
  930. X.BI \-B n
  931. X.BI \-L n
  932. X.BI \-R n
  933. X.BI \-w n
  934. X.BI \-l n
  935. X.BI \-s n
  936. X.BI \-p n
  937. X.BR \-p [ RA ]
  938. X.BI \-t #text
  939. X.BR \-h\fI# [ YN ]
  940. X.BR \-h\fI# [ TB ][ LCR ]
  941. X.B \-v
  942. X]
  943. X.I filename
  944. X\&.\|.\|.
  945. X.SH DESCRIPTION
  946. X.LP
  947. XFor each
  948. X.IR filename ,
  949. X.B pr2
  950. formats the file with modifyable margins, line-spacing, and possible
  951. titles and page numbers.
  952. X.SH OPTIONS
  953. X.TP
  954. X.BI \-T n
  955. X.PD 0
  956. X.TP
  957. X.BI \-B n
  958. X.TP
  959. X.BI \-L n
  960. X.TP
  961. X.BI \-R n
  962. Set the top, bottom, left, and right margin, respectively, to
  963. X.I n
  964. rows or columns.
  965. X.PD
  966. X.TP
  967. X.BI \-w n
  968. Sets the width of the page to
  969. X.I n
  970. columns.
  971. X.TP
  972. X.BI \-l n
  973. Sets the length of the page to
  974. X.I n
  975. rows.
  976. X.TP
  977. X.BI \-s n
  978. Sets the line spacing to
  979. X.I n
  980. rows.
  981. X.TP
  982. X.BI \-p n
  983. Sets the initial page number to
  984. X.IR n .
  985. X.TP
  986. X.BR \-p [ RA ]
  987. Sets the page numbering to
  988. X.BR R oman
  989. or
  990. X.BR A rabic
  991. numerals.
  992. X.TP
  993. X.BI \-t #text
  994. Sets the text of title number
  995. X.I #
  996. to
  997. X.IR text .
  998. X.TP
  999. X.BR \-h\fI# [ YN ]
  1000. Turns title number
  1001. X.I #
  1002. on
  1003. X.RB ( Y )
  1004. or off
  1005. X.RB ( N ).
  1006. X.TP
  1007. X.BR \-h\fI# [ TB ][ LCR ]
  1008. Sets the position of title number
  1009. X.IR # .
  1010. The first character specifies either the
  1011. X.BR T op
  1012. or
  1013. X.BR B ottom
  1014. margin.  The second character is for
  1015. X.BR L eft,
  1016. X.BR C enter,
  1017. or
  1018. X.BR R ight
  1019. justification.
  1020. X.TP
  1021. X.B  \-v
  1022. Displays
  1023. X.BR pr2 's
  1024. version number.
  1025. X.SH TITLES
  1026. X.B Pr2
  1027. allows you to set up to six titles in the margins of your
  1028. document.  Each title can be placed either in the top or bottom
  1029. margin, and can be centered or placed against the left or right
  1030. margin.  When the title is printed, a
  1031. X.B %f
  1032. inside the title will be replaced by the current
  1033. X.IR filename ,
  1034. X.B %n
  1035. will be replaced by the page number, and
  1036. X.B %%
  1037. will be replaced by a single
  1038. X.BR % .
  1039. Note that if two or more titles are placed in the same position,
  1040. later titles will overwrite previous titles.
  1041. X.SH VERSION
  1042. This describes
  1043. X.B pr2
  1044. version %V%.  To see what version of
  1045. X.B pr2
  1046. you are running, use the
  1047. X.B \-v
  1048. option.
  1049. X.SH SEE ALSO
  1050. X.PD
  1051. X.BR pr (1)
  1052. END_OF_FILE
  1053. if test 2020 -ne `wc -c <'pr2.man'`; then
  1054.     echo shar: \"'pr2.man'\" unpacked with wrong size!
  1055. fi
  1056. # end of 'pr2.man'
  1057. fi
  1058. if test -f 'pr2.test.suite' -a "${1}" != "-c" ; then 
  1059.   echo shar: Will not clobber existing file \"'pr2.test.suite'\"
  1060. else
  1061. echo shar: Extracting \"'pr2.test.suite'\" \(141 characters\)
  1062. sed "s/^X//" >'pr2.test.suite' <<'END_OF_FILE'
  1063. pr2 test suite:  version 2.2
  1064. X    1200    2018   21354 size.source
  1065. X     240     507    3636 size.pr2.man
  1066. X     100     206    1793 size.README
  1067. END_OF_FILE
  1068. if test 141 -ne `wc -c <'pr2.test.suite'`; then
  1069.     echo shar: \"'pr2.test.suite'\" unpacked with wrong size!
  1070. fi
  1071. # end of 'pr2.test.suite'
  1072. fi
  1073. echo shar: End of shell archive.
  1074. exit 0
  1075.