home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / pstext / part01 / pstext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-06  |  11.1 KB  |  396 lines

  1. /* 
  2.   pstext
  3.   by Dan Judd
  4.      St. Olaf College
  5.      11/29/89
  6.   
  7.   This program takes plain ascii text and converts it to Postscript.
  8.   It takes a few options.
  9.   [-p ] prints portrait mode 1 page (default)
  10.   [-l ] prints landscape mode 1 page
  11.   [-ld ] dual landscape mode 2 pages per page
  12.   [-d ] dual portrait mode, prints 2 pages per page
  13.   [-n number] number of lines per page
  14.   [-t tabstring ] use a different tabstring size (NNNNNNNN default)
  15.   [-f fontname ] use a different font (Courier default)
  16.   [-s pointsize ] use a different point size (12 default)
  17.   [-i pointoffset ] offset pointoffset points from normal (0 default)
  18.  
  19.   It handles tabs and backspaces in an intelligent way in any font.
  20.  
  21.   Copyright Dan Judd 1989
  22.   This program is freely redistributable, but may not be sold.
  23.   send bug fixes to danjudd@thor.acc.stolaf.edu
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <strings.h>
  28. #include <ctype.h>
  29. #define TRUE 1
  30. #define FALSE 0
  31. #define DFLT_PTSIZE 12
  32. #define DFLT_FONT "Courier"
  33. #define DFLT_TABSTRING "NNNNNNNN"
  34. #define INDENT 0
  35. #define DFLT_STYLE 1
  36. #define DFLT_LINES 0
  37.  
  38. main(argc,argv)
  39. int argc;
  40. char *argv[];
  41. {
  42.  double ptsize=DFLT_PTSIZE;
  43.  char *font;
  44.  char *tabstring;
  45.  int style=DFLT_STYLE;
  46.  int numlines=DFLT_LINES;
  47.  int indent=INDENT;
  48.  FILE *fpout=stdout;
  49.  FILE *fpin=stdin;
  50.  short badflag=FALSE;
  51.  char ch;
  52.  char *progname;
  53.  double atof();
  54.  
  55.  font=(char *) malloc(sizeof(DFLT_FONT));
  56.  strcpy(font,DFLT_FONT);
  57.  tabstring=(char *) malloc(sizeof(DFLT_TABSTRING));
  58.  strcpy(tabstring,DFLT_TABSTRING);
  59.  /* parse args */
  60.  progname=*argv++;
  61.  
  62.  while ((--argc > 0)&&(*argv[0]=='-')) {
  63.    switch(*++argv[0]) {
  64.     
  65.     case 'l':    if(*++argv[0]=='d') {
  66.           style=3;
  67.           }
  68.          else {
  69.           style=4;
  70.           };
  71.         break;
  72.     case 'p':    style=1;
  73.         break;
  74.     case 'd':    style=2;
  75.         break;
  76.     case 'f':    if (*++argv[0] !='\0'){
  77.           font=*argv;
  78.          }
  79.         else
  80.          if (--argc) {
  81.           font=*++argv;
  82.           }
  83.          else {
  84.           badflag=TRUE;
  85.           }
  86.         break;
  87.     case 't':    if (*++argv[0] !='\0'){
  88.           tabstring=*argv;
  89.          }
  90.         else
  91.          if (--argc) {
  92.           tabstring=*++argv;
  93.           }
  94.          else {
  95.           badflag=TRUE;
  96.           }
  97.         break;
  98.     case 'n':    if (*++argv[0] !='\0'){
  99.           if((numlines=atof(*argv)) <= 0){
  100.             fprintf(stderr,"specify a line number 1 or more\n");
  101.             badflag=TRUE;
  102.             }
  103.         }
  104.         else
  105.         if (--argc) {
  106.           if((numlines=atof(*++argv)) <= 0){
  107.             fprintf(stderr,"specify a line number 1 or more\n");
  108.             badflag=TRUE;
  109.             }
  110.           }
  111.          else {
  112.           badflag=TRUE;
  113.           }
  114.         break;
  115.     case 'i':    if (*++argv[0] !='\0'){
  116.           if((indent=atof(*argv)) <= 0){
  117.             fprintf(stderr,"specify a point offset of 1 or more\n");
  118.             badflag=TRUE;
  119.             }
  120.         }
  121.         else
  122.         if (--argc) {
  123.           if((indent=atof(*++argv)) <= 0){
  124.             fprintf(stderr,"specify a point offset of 1 or more\n");
  125.             badflag=TRUE;
  126.             }
  127.           }
  128.          else {
  129.           badflag=TRUE;
  130.           }
  131.         break;
  132.     case 's':    if (*++argv[0] !='\0'){
  133.           if((ptsize=atof(*argv)) <= 0){
  134.             fprintf(stderr,"specify a point size greater than 0\n");
  135.             badflag=TRUE;
  136.             }
  137.         }
  138.         else
  139.         if (--argc) {
  140.           if((ptsize=atof(*++argv)) <= 0){
  141.             fprintf(stderr,"specify a point size greater than 0\n");
  142.             badflag=TRUE;
  143.             }
  144.           }
  145.          else {
  146.           badflag=TRUE;
  147.           }
  148.         break;
  149.     default:    badflag=TRUE;
  150.         break;
  151.  
  152.     }
  153. if(badflag) {
  154.  fprintf(stderr,"Usage: %s [-p] [-l] [-ld] [-d] [-n lines ] [-t ",progname);
  155.  fprintf(stderr,"tabstring] [-f fontname] [-s pointsize] [-i point offset]");
  156.  fprintf(stderr,"[file1 ... ]\n");
  157.  exit(1);
  158.   }
  159.     *argv++;
  160.     }
  161.  
  162.  /* set up postscript header */
  163.  
  164.  printhead(fpout,font,ptsize,style,numlines,tabstring,indent);
  165.  /* read files */
  166.  if (argc ==0) {
  167.    getfile(stdin,fpout);
  168.    }
  169.   else {
  170.    while(argc--!=0) {
  171.     if((fpin=fopen(*argv,"r"))!=NULL) {
  172.       getfile(fpin,fpout);
  173.       fclose(fpin);
  174.       *argv++;
  175.       }
  176.      else{
  177.       fprintf(stderr,"Unable to open file %s\n",*argv);
  178.       fprintf(fpout,"\nlp\n");
  179.       exit(1);
  180.       }
  181.     }
  182.   }
  183.  /* makesure showpage is done so last page prints */
  184.  fprintf(fpout,"\nlp\n");
  185.  exit(0);
  186.  }
  187.  
  188.  /*
  189.    getfile(fpin,fpout)
  190.     FILE *fpin,fpout;
  191.    Read in text from a file and output appropriate postscript
  192.   */
  193.  getfile(fpin,fpout)
  194.   FILE *fpin,*fpout;
  195.   {
  196.    char ch;
  197.  
  198.    fprintf(fpout,"(");
  199.    while ((ch=getc(fpin))!=EOF) {
  200.    if(isprint(ch)) {
  201.     switch (ch ) {
  202.      case '(':
  203.      case ')':
  204.      case '\\':
  205.         fprintf(fpout,"\\%c",ch);
  206.         break;
  207.      default:    fprintf(fpout,"%c",ch);
  208.         break;
  209.      }
  210.    }
  211.   else {
  212.     switch (ch ) {
  213.      case '\n':    fprintf(fpout,")s\n(");
  214.         break;
  215.      case '\t':    fprintf(fpout,")S\nht (");
  216.         break;
  217.      case '\b':    fprintf(fpout,")S\nbs(");
  218.         break;
  219.      case '\r':    fprintf(fpout,")S\ncr(");
  220.         break;
  221.      case '\f':    fprintf(fpout,")S\nnp(");
  222.         break;
  223.      default:
  224.         break;
  225.         }
  226.       }
  227.    }
  228.  /* send trailer */
  229.  fprintf(fpout,")s\nnp\n");
  230.  }
  231. printhead(fp,font,size,style,numlines,tabstring,indent)
  232.  FILE *fp;
  233.  char *font;
  234.  double size;
  235.  int style;
  236.  int numlines;
  237.  char *tabstring;
  238.  int indent;
  239.  {
  240.   fprintf(fp,"%%! PS - Adobe\n");
  241.   fprintf(fp,"%% Created by pstext by Dan Judd\n");
  242.   fprintf(fp,"/PAGE_STYLE %d def\n",style);
  243.   fprintf(fp,"/NUM_LINES %d def\n",numlines);
  244.   fprintf(fp,"/FONT (%s) cvn def\n",font);
  245.   fprintf(fp,"/FONT_SIZE %lf def\n",size);
  246.   fprintf(fp,"%%check if font exists\n");
  247.  
  248. /* this is vaguely device depenent, FontDirectory is standard, but */
  249. /* the Next uses SharedFontDirectory instead. The program won't crash,*/
  250. /* but the only font you can use is Courier. Blech. */
  251. /* if this is a problem just comment out the next line */
  252.  
  253.   fprintf(fp,"FontDirectory FONT known not { /FONT (Courier) cvn def} if\n");
  254.   fprintf(fp,"%%misc hardware defs\n");
  255.   if (style > 2) {
  256.     fprintf(fp,"/XLMARGIN 18 def\n");
  257.     }
  258.    else
  259.     {
  260.     fprintf(fp,"/XLMARGIN %d def\n",(indent+18));
  261.     }
  262.   fprintf(fp,"/XRMARGIN 14 def\n");
  263.   fprintf(fp,"/XPAGE 612 def\n");
  264.   fprintf(fp,"/YPAGE 792 def\n");
  265.   fprintf(fp,"/YTMARGIN 8 def\n");
  266.   if (style < 3) {
  267.     fprintf(fp,"/YBMARGIN 13 def\n");
  268.     }
  269.    else
  270.     {
  271.     fprintf(fp,"/YBMARGIN %d def\n",(indent+13));
  272.     }
  273.   fprintf(fp,"/PAGENUM 1 def\n");
  274.   fprintf(fp,"%%\n");
  275.   fprintf(fp,"%%short defs to save space\n");
  276.   fprintf(fp,"%%\n");
  277.   fprintf(fp,"/bd {bind def} bind def\n");
  278.   fprintf(fp,"/m {moveto} bd\n");
  279.   fprintf(fp,"/l {lineto}bd\n");
  280.   fprintf(fp,"/gs {gsave}bd\n");
  281.   fprintf(fp,"/gr {grestore}bd\n");
  282.   fprintf(fp,"/tr {translate} bd\n");
  283.   fprintf(fp,"/rt {rotate} bd\n");
  284.   fprintf(fp,"%%\n");
  285.   fprintf(fp,"%%Set up vars and np depending on PAGE_STYLE\n");
  286.   fprintf(fp,"%%\n");
  287.   fprintf(fp,"%% Style 1\n");
  288.   fprintf(fp,"1 PAGE_STYLE eq {\n");
  289.   fprintf(fp,"    /PAGES_PER_SHEET 1 def\n");
  290.   fprintf(fp,"    /sp {/SAVEOBJ save def} def\n");
  291.   fprintf(fp,"    /np { showpage SAVEOBJ restore sp bp } bd\n");
  292.   fprintf(fp,"    } if\n");
  293.   fprintf(fp,"%% Style 2\n");
  294.   fprintf(fp,"2 PAGE_STYLE eq {\n");
  295.   fprintf(fp,"    /PAGES_PER_SHEET 2 def\n");
  296.   fprintf(fp,"    /sp {/SAVEOBJ save def gs XPAGE 2 div dup 0 m YPAGE l stroke\n");
  297.   fprintf(fp,"        newpath 0 0 m 0 YPAGE l XPAGE 2 div XRMARGIN sub dup\n");
  298.   fprintf(fp,"        YPAGE l 0 l 0 0 l clip\n");
  299.   fprintf(fp,"        } bd\n");
  300.   fprintf(fp,"    /np { /PAGENUM 1 PAGENUM add def\n");
  301.   fprintf(fp,"        PAGENUM PAGES_PER_SHEET\n");
  302.   fprintf(fp,"        gt {gr showpage SAVEOBJ restore sp /PAGENUM 1 def }\n");
  303.   fprintf(fp,"        {gr gs XPAGE 2 div 0 tr} ifelse\n");
  304.   fprintf(fp,"        bp\n");
  305.   fprintf(fp,"        } bd\n");
  306.   fprintf(fp,"    } if\n");
  307.   fprintf(fp,"%% Style 3\n");
  308.   fprintf(fp,"3 PAGE_STYLE eq {\n");
  309.   /* define if you want double page landscape mode to have fonts */
  310.   /* proportional to single page portrait */
  311. #ifdef LANDPROP
  312.   fprintf(fp,"    /FONT_SIZE FONT_SIZE .642 mul def\n");
  313. #endif
  314.   fprintf(fp,"    /TMP XPAGE def\n");
  315.   fprintf(fp,"    /XPAGE YPAGE def\n");
  316.   fprintf(fp,"    /YPAGE TMP def\n");
  317.   fprintf(fp,"    /TMP XRMARGIN def\n");
  318.   fprintf(fp,"    /XRMARGIN YTMARGIN def\n");
  319.   fprintf(fp,"    /YTMARGIN TMP def\n");
  320.   fprintf(fp,"    /TMP XLMARGIN def\n");
  321.   fprintf(fp,"    /XLMARGIN YBMARGIN def\n");
  322.   fprintf(fp,"    /YBMARGIN TMP def\n");
  323.   fprintf(fp,"    /PAGES_PER_SHEET 2 def\n");
  324.   fprintf(fp,"    /sp {/SAVEOBJ save def gs 0 XPAGE tr -90 rt\n");
  325.   fprintf(fp,"        XPAGE 2 div dup 0 moveto YPAGE l stroke\n");
  326.   fprintf(fp,"        newpath 0 0 m 0 YPAGE l XPAGE 2 div XRMARGIN sub dup\n");
  327.   fprintf(fp,"        YPAGE l 0 l 0 0 l clip\n");
  328.   fprintf(fp,"        } bd\n");
  329.   fprintf(fp,"    /np { /PAGENUM 1 PAGENUM add def\n");
  330.   fprintf(fp,"        PAGENUM PAGES_PER_SHEET\n");
  331.   fprintf(fp,"        gt {gr showpage SAVEOBJ restore sp /PAGENUM 1 def }\n");
  332.   fprintf(fp,"        {gr gs 0 XPAGE 2 div tr -90 rt } ifelse\n");
  333.   fprintf(fp,"        bp\n");
  334.   fprintf(fp,"        } bd\n");
  335.   fprintf(fp,"    } if\n");
  336.   fprintf(fp,"%% Style 4\n");
  337.   fprintf(fp,"4 PAGE_STYLE eq {\n");
  338.   fprintf(fp,"    /TMP XPAGE def\n");
  339.   fprintf(fp,"    /XPAGE YPAGE def\n");
  340.   fprintf(fp,"    /YPAGE TMP def\n");
  341.   fprintf(fp,"    /TMP XRMARGIN def\n");
  342.   fprintf(fp,"    /XRMARGIN YTMARGIN def\n");
  343.   fprintf(fp,"    /YTMARGIN TMP def\n");
  344.   fprintf(fp,"    /TMP XLMARGIN def\n");
  345.   fprintf(fp,"    /XLMARGIN YBMARGIN def\n");
  346.   fprintf(fp,"    /YBMARGIN TMP def\n");
  347.   fprintf(fp,"    /PAGES_PER_SHEET 1 def\n");
  348.   fprintf(fp,"    /sp {/SAVEOBJ save def gs 0 XPAGE tr -90 rt\n");
  349.   fprintf(fp,"        } bd\n");
  350.   fprintf(fp,"    /np { gr showpage SAVEOBJ restore sp bp} bd\n");
  351.   fprintf(fp,"    } if\n");
  352.   fprintf(fp,"%%\n");
  353.   fprintf(fp,"%%set up fonts\n");
  354.   fprintf(fp,"%%\n");
  355.   fprintf(fp,"NUM_LINES 1 ge {FONT findfont 1 scalefont setfont\n");
  356.   fprintf(fp,"    /FONT_HT currentfont /FontBBox get 3 get 0 exch\n");
  357.   fprintf(fp,"        currentfont /FontMatrix get transform exch pop\n");
  358.   fprintf(fp,"        currentfont /FontBBox get 0 get 0 exch\n");
  359.   fprintf(fp,"        currentfont /FontMatrix get transform exch pop\n");
  360.   fprintf(fp,"        sub def\n");
  361.   fprintf(fp,"    /TMP FONT_HT 1 sub def\n");
  362.   fprintf(fp,"    /FONT_SIZE YPAGE YBMARGIN sub YTMARGIN sub 1 sub dup\n");
  363.   fprintf(fp,"    NUM_LINES div TMP mul sub NUM_LINES div def\n");
  364.   fprintf(fp,"    } if\n");
  365.   fprintf(fp,"FONT findfont FONT_SIZE scalefont setfont\n");
  366.   fprintf(fp,"%%get height of font set tolerances\n");
  367.   fprintf(fp,"/FONT_HT currentfont  /FontBBox get 3 get 0 exch\n");
  368.   fprintf(fp,"    currentfont  /FontMatrix get transform exch pop\n");
  369.   fprintf(fp,"    currentfont  /FontBBox  get 0 get 0 exch\n");
  370.   fprintf(fp,"    currentfont  /FontMatrix get transform exch pop\n");
  371.   fprintf(fp,"    sub  def\n");
  372.   fprintf(fp,"/FONT_TOL FONT_HT YBMARGIN add def\n");
  373.   fprintf(fp,"%%\n");
  374.   fprintf(fp,"%%Routines common to all page styles\n");
  375.   fprintf(fp,"%%\n");
  376.   fprintf(fp,"/bp { XLMARGIN YPAGE YTMARGIN sub FONT_SIZE sub m\n");
  377.   fprintf(fp,"    } bd\n");
  378.   fprintf(fp,"/s { show  currentpoint exch pop dup FONT_TOL\n");
  379.   fprintf(fp,"    gt {FONT_SIZE sub XLMARGIN  exch m} {np} ifelse}  bd\n");
  380.   fprintf(fp,"/S {show} bd\n");
  381.   fprintf(fp,"/OFFSET (_) stringwidth pop neg def\n");
  382.   fprintf(fp,"/bs { OFFSET 0 rmoveto } bd\n");
  383.   fprintf(fp,"/bs {XLMARGIN currentpoint pop OFFSET add lt {OFFSET 0 rmoveto}");
  384.   fprintf(fp,"{XLMARGIN currentpoint exch pop m}ifelse} bd");
  385.   fprintf(fp,"/TABLEN (%s) stringwidth pop def\n",tabstring);
  386.   fprintf(fp,"/ht {currentpoint exch XLMARGIN sub TABLEN div cvi 1 add TABLEN\n");
  387.   fprintf(fp,"    mul XLMARGIN add exch m}bd\n");
  388.   fprintf(fp,"/cr {currentpoint XLMARGIN exch m pop} bd\n");
  389.   fprintf(fp,"/lp {gr 1 PAGENUM ne {showpage}if} bd\n");
  390.   fprintf(fp,"%%\n");
  391.   fprintf(fp,"%%begin data et al\n");
  392.   fprintf(fp,"%%\n");
  393.   fprintf(fp,"sp\n");
  394.   fprintf(fp,"bp\n");
  395.  }
  396.