home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1990 / 09 / dtp / pstext.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-04  |  25.9 KB  |  776 lines

  1. /* ------------------------------------------------------ */
  2. /*                        PSTEXT                          */
  3. /*       PostScript-Universaltreiber für ASCII-Text       */
  4. /*           (c) 1990 David Geffen & TOOLBOX              */
  5. /* ------------------------------------------------------ */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9.  
  10. #define FALSE         0
  11. #define TRUE          !FALSE
  12.  
  13. #define TOP_MARGIN    72  /* Default-Wert oberer Rand: 1" */
  14. #define LEFT_MARGIN   72  /* Default-Wert linker Rand: 1" */
  15. #define END_Y         72 /* Default-Wert unterer Rand: 1" */
  16.  
  17. #define A4_Y          841           /* 29.7cm = 841Punkte */
  18. #define A4_X          595           /* 21.0cm = 595Punkte */
  19. #define A4_QUER       (float)(0.7070707)
  20.  
  21. #define MAX_X         (A4_X-startX)
  22. #define MAX_Y         (A4_Y-startY)
  23. #define MAX_LINES    ((startY-endY+points)/(points+spacing))
  24.                                      /* Zeilen pro Spalte */
  25. #define MAX_COLUMNS   200            /* Spalten pro Seite */
  26. #define MAX_SPACING   800                   /* Durchschuß */
  27. #define MAX_CHARS     8192           /* maximale Absatzlänge
  28.                                                in Zeichen */
  29. #define MAX_FILENAME  63               /* Dateinamenlänge */
  30. #define MAX_FILES     10               /* Eingabe-Dateien */
  31. #define MAX_FONTNAME  80                /* Fontnamenlänge */
  32.  
  33. #define COLS_ON_LINE  (((MAX_X/LandScape) \
  34.                        / default_cols) / points)
  35.                                     /* Zeichen pro Spalte */
  36.  
  37. void i2a (int, char *, int, int);
  38. void usage (char *);
  39. void error (char *);
  40.  
  41. char breaks[] = { " +-\t)*/^%]}|" };
  42.                                  /* Mögliche 'Break'-Zeichen
  43.                                              für Wordwrap */
  44. char specials[150];             /* ASCII-Codes, die in Oktal
  45.                                  ausgegeben werden müssen */
  46. char files[MAX_FILES][MAX_FILENAME];
  47.                                        /* Eingabe-Dateien */
  48. int      next_file;               /* Eingabe-Datei-Zähler */
  49. unsigned int default_lines;          /* Zeilen pro Spalte */
  50. unsigned int default_cols;           /* Spalten pro Seite */
  51. unsigned int ln_count;           /* Aktuelle Zeilennummer */
  52. unsigned int wrap;             /* Index für Wordwrap-Test */
  53. unsigned int blanks;                /* Anzahl Leerzeichen */
  54. unsigned int colwidth;                   /* Spaltenbreite */
  55.  
  56. /*  Variablen, die verschiedene Optionen beschreiben.
  57.     Diese Variablen werden in der Funktion set_defaults()
  58.     bzw. getopts() gesetzt.
  59. */
  60. char prolog_filename[MAX_FILENAME];  /* PS-Präambel-Datei */
  61. char font[MAX_FONTNAME];                      /* Fontname */
  62. FILE     *fp;                       /* Input-File Pointer */
  63. unsigned points;                          /* Schriftgröße */
  64. signed   lines;                      /* Zeilen pro Spalte */
  65. unsigned cols;                       /* Spalten pro Seite */
  66. signed   startX, startY, endY;      /* Anfangs-Positionen */
  67. unsigned spacing;                           /* Durchschuß */
  68. float    LandScape;              /* Hoch- oder Querformat */
  69. int      numbering;                  /* Zeilennumerierung */
  70. char     text_on_page;               /* Flag für nextpage */
  71. unsigned ln_interval;                 /* Zeilennumerierungs-
  72.                                                 Intervall */
  73. signed   cols_on_line;                 /* Wordwrap-Spalte */
  74.  
  75. /* ----  Unterprogramme  -------------------------------- */
  76.  
  77. /*  get_blanks() zählt die Leerzeichen
  78.     am Anfang der Zeile
  79. */
  80. get_blanks( char *s )
  81. {
  82.     int blanks;
  83.  
  84.     blanks = 0;
  85.     while( *s++ == ' ' )
  86.         blanks++;
  87.     return( blanks );
  88. }
  89.  
  90. /*  put_blanks() gibt 'blanks' Leerzeichen aus
  91. */
  92. void put_blanks( blanks )
  93. {
  94.     while( blanks-- )
  95.         fputc( ' ', stdout );
  96. }
  97.  
  98. /*  ispage() prüft, ob die Spalte voll ist
  99.     und fügt in diesem Fall ein 'nextcol' bzw. 'nextpage'
  100.     ein.
  101. */
  102. void ispage()
  103. {
  104.    /*  Sind wir am Seitenende? "Ja" bedeutet 'nextpage'
  105.        oder 'nextcol'
  106.    */
  107.    if (!(--lines))
  108.    {
  109.        lines = default_lines;
  110.        if (!(--cols))
  111.        {
  112.            if (text_on_page)
  113.                fputs( "nextpage\n", stdout );
  114.            text_on_page = FALSE;
  115.            cols = default_cols;
  116.        }
  117.        else
  118.            fputs( "nextcol\n", stdout );
  119.     }
  120. }
  121.  
  122. void process_char( unsigned char c )
  123. {
  124.     char s[5];      /* Platz für ein Oktal-Zeichen (\xxx) */
  125.  
  126.     if ( strchr( specials, c ) )
  127.     {
  128.         fputc( '\\', stdout );
  129.         i2a( c, s, 3, 8 );
  130.         fputs( s, stdout );
  131.     }
  132.     else
  133.         fputc( c, stdout );
  134. }
  135.  
  136. /*  Diese Funktion setzt die globalen Defaultwerte
  137. */
  138. void set_defaults()
  139. {
  140.     LandScape     = 1.0;          /* Default ist Portrait */
  141.     fp            = stdin;         /* ermöglicht 'Piping' */
  142.     strcpy( font, "Courier" ); /* unproportionale Schrift */
  143.     points        = 12;                  /* Standardgröße */
  144.     default_cols  = 1;  /* einspaltige Ausgabe als Default*/
  145.     cols          = default_cols;        /* setze Default */
  146.     startX        = LEFT_MARGIN;                 /* links */
  147.     endY          = END_Y;                       /* unten */
  148.     spacing       = 1;              /* 1 Punkt Durchschuß */
  149.     default_lines = MAX_LINES;
  150.     strcpy( prolog_filename, "pstext.ini" );
  151.                                       /* PS-Präambeldatei */
  152.     colwidth      = A4_X;
  153.     ln_count      = 1;
  154.     ln_interval   = 1;
  155.     numbering     = FALSE;           /* Zeilennumerierung */
  156.  
  157.     /*  Die folgenden Variablen sind abhängig
  158.         von anderen Variablen und werden nur
  159.         als 'noch ohne Wert' gekennzeichnet
  160.     */
  161.     cols_on_line  = -1;
  162.     lines         = -1;
  163.     startY        = -1;
  164. }
  165.  
  166. /*  Eingabe-Parameter analysieren
  167. */
  168. void getopts( int argc, char *argv[] )
  169. {
  170.     int i;           /* Index-Integer, zählt die Optionen */
  171.     char s[40];             /* String für Fehlermeldungen */
  172.  
  173.     for (i = 1; i < argc; i++)
  174.     {
  175.         /*  Erlaubte 'Schalter'-Symbole sind '-' und '/'.
  176.             Falls keines davon zu finden, wird der Parameter
  177.             als Dateiname interpretiert
  178.         */
  179.         if (*argv[i] != '/' && *argv[i] != '-')
  180.         {
  181.             if (next_file < MAX_FILES)
  182.                 strncpy( files[next_file++], argv[i],\
  183.                          MAX_FILENAME );
  184.         }
  185.         else
  186.      if (strlen( argv[i] ) < 3 )
  187.      {
  188.          usage( argv[0] );
  189.          error( "" );
  190.      }
  191.      else
  192.      if (strlen( argv[i] ) > 2 )
  193.      {
  194.          switch ( tolower( *(argv[i]+1) ) )
  195.          {
  196.           case 'c':
  197.             cols = atoi( argv[i]+2 );
  198.             if ( (cols < 1) || (cols > MAX_COLUMNS) )
  199.             {
  200.                sprintf( s, "Kann nicht %d "\
  201.                                  "Spalten drucken!", cols );
  202.                      error( s );
  203.                   }
  204.                   default_cols = cols;
  205.                   break;
  206.                 case 'd':
  207.                   spacing = atoi( argv[i]+2 );
  208.                   if (  (spacing < 0)
  209.                      || (spacing > MAX_SPACING) )
  210.                   {
  211.                     sprintf( s, "Kann keinen Durchschuß "\
  212.                                 "von %d setzen!", spacing );
  213.                     error( s );
  214.                   }
  215.                   break;
  216.                 case 'f':
  217.                   /*
  218.                       Schriftart auswählen:
  219.                       Der Anwender will einen eigenen Font-
  220.                       namen benutzen, wenn er mehr als ein
  221.                       Zeichen hinter '-f' eingegeben hat
  222.                   */
  223.                   if (strlen( argv[i] + 2 ) > 1)
  224.                       strncpy( font, argv[i]+2, \
  225.                                MAX_FONTNAME );
  226.                   else
  227.                       switch( tolower( *(argv[i]+2) ) )
  228.                       {
  229.                         case 'a':
  230.                           strcpy( font, "AvantGarde" );
  231.                           break;
  232.                         case 'b':
  233.                           strcpy( font, "Bookman" );
  234.                           break;
  235.                         case 'c':
  236.                           strcpy( font, "Courier" );
  237.                           break;
  238.                         case 'h':
  239.                           strcpy( font, "Helvetica" );
  240.                           break;
  241.                         case 'p':
  242.                           strcpy( font, "Palatino" );
  243.                           break;
  244.                         case 's':
  245.                           strcpy( font, "Symbol" );
  246.                           break;
  247.                         case 't':
  248.                           strcpy( font, "Times-Roman" );
  249.                           break;
  250.                         default:
  251.                           strncpy( font, argv[i]+2, \
  252.                                    MAX_FONTNAME );
  253.                           break;
  254.                       }
  255.                   break;
  256.                 case 'l':
  257.                   lines = atoi( argv[i]+2 );
  258.                   if (lines < 1)
  259.                   {
  260.                      sprintf( s, "Kann nicht %d Zeilen per"\
  261.                                  " Seite drucken!", lines );
  262.                      error( s );
  263.                   }
  264.                   default_lines = lines;
  265.                   break;
  266.                 case 'n':
  267.                   ln_interval = atoi( argv[i]+2 );
  268.                   if (ln_interval < 0)
  269.                   {
  270.                      sprintf( s, "Kann nicht mit Intervall"\
  271.                            " %d numerieren!", ln_interval );
  272.                      error( s );
  273.                   }
  274.                   else
  275.                   if (ln_interval == 0) ln_interval = 1;
  276.                   numbering = TRUE;
  277.                   break;
  278.                 case 'o':
  279.                   switch ( tolower( *(argv[i]+2) ) )
  280.                   {
  281.                       case 'l':
  282.                           LandScape = A4_QUER;
  283.                           colwidth = A4_Y;     break;
  284.                       case 'p':
  285.                           LandScape = 1.0;
  286.                           colwidth = A4_X;     break;
  287.                       default:
  288.                           sprintf( s, "Orientierung ist "\
  289.                                  "entweder 'l' oder 'p'!" );
  290.                           error( s );
  291.                   }
  292.                   break;
  293.                 case 'p':
  294.                   points = atoi( argv[i]+2 );
  295.                   if (points < 4)
  296.                   {
  297.                      sprintf( s, "Kann nicht %d "\
  298.                                  "Punkt drucken!", points );
  299.                      error( s );
  300.                   }
  301.                   break;
  302.                 case 'w':
  303.                   cols_on_line = atoi( argv[i]+2 );
  304.                   if (cols_on_line < 1)
  305.                   {
  306.                     sprintf( s, "Kann Zeile nicht in der "\
  307.                     "%d. Spalte umbrechen!", cols_on_line );
  308.                     error( s );
  309.                   }
  310.                   break;
  311.                 case 'x':
  312.                   startX = atoi( argv[i]+2 );
  313.                   if ( (startX < 0) || (startX > A4_X) )
  314.                   {
  315.                       sprintf( s, "X-Anfangsposition (%d) "\
  316.                                   "ist illegal!", startX );
  317.                       error( s );
  318.                   }
  319.                   break;
  320.                 case 'y':
  321.                   startY = atoi( argv[i]+2 );
  322.                   if ( (startY < 0) || (startY > A4_Y) )
  323.                   {
  324.                       sprintf( s, "Y-Anfangsposition (%d) "\
  325.                                   "ist illegal!", startY );
  326.                       error( s );
  327.                   }
  328.                   break;
  329.                 default:
  330.                   sprintf( s, "Option '%c' ist nicht "\
  331.                               "vorhanden!",            \
  332.                               tolower( *(argv[i]+1) ) );
  333.                   error( s );
  334.                   break;
  335.             }
  336.         }
  337.     }
  338.     /*  'colwidth', 'cols_on_line', 'startY'
  339.         und 'lines', die von anderen Variablen
  340.         abhängig sind, müssen neu berechnet werden.
  341.     */
  342.     colwidth = (colwidth - startX) / cols;
  343.  
  344.     if (cols_on_line == -1)
  345.         cols_on_line = COLS_ON_LINE;
  346.  
  347.     if (startY == -1)
  348.         startY = ((A4_Y-TOP_MARGIN)*LandScape) - points;
  349.  
  350.     if (lines == -1)
  351.     {
  352.         default_lines = MAX_LINES;
  353.         lines = default_lines;
  354.     }
  355. }
  356.  
  357. /*  Funktion header() beschreibt die PostScript-
  358.     Funktionen, die später aufgerufen werden
  359. */
  360. void header()
  361. {
  362.     char s[MAX_CHARS];
  363.     char buf[MAX_CHARS];
  364.     FILE *fp;
  365.     int  i;
  366.     /*
  367.         Hier wird die PostScript-Präambeldatei gelesen.
  368.         Wenn die Datei nicht vorhanden ist, werden nur
  369.         die Default-Daten ausgegeben.
  370. */
  371.  
  372.     fp = fopen( prolog_filename, "rt" );
  373.     if ( fp != NULL )
  374.     {
  375.         while( fgets( s, MAX_CHARS, fp ) != NULL )
  376.         {
  377.             /*  Aufpassen! 'i' wird innerhalb der Schleife
  378.                 inkrementiert. Obwohl in jedem 'case'-Befehl
  379.                 enthalten, wird das nur einmal vom Compiler
  380.                 expandiert, wenn der Optimierer
  381.                 eingeschaltet ist.
  382.             */
  383.             for (i = 0; i < strlen( s ); i++)
  384.             {
  385.                 if ( (s[i] == '.') && (s[i+2] == '.') \
  386.                 && ((i+2) < strlen(s) ))
  387.                 {
  388.                     switch (tolower(s[i+1]))
  389.                     {
  390.                         case 'd':
  391.                             sprintf( buf, "%d", spacing );
  392.                             fputs( buf, stdout );
  393.                    i += 2;
  394.                             break;
  395.                         case 'f':
  396.                             fputs( font, stdout );
  397.                             i += 2;
  398.                             break;
  399.                         case 'p':
  400.                             sprintf( buf, "%d", points );
  401.                             fputs( buf, stdout );
  402.                             i += 2;
  403.                             break;
  404.                         case 't':
  405.                             if (LandScape == A4_QUER)
  406.                             {
  407.                                sprintf( buf, "%d 0 "  \
  408.                                "translate 90 rotate", A4_X);
  409.                                fputs( buf, stdout );
  410.                             }
  411.                             i += 2;
  412.                             break;
  413.                         case 'w':
  414.                             sprintf( buf, "%d", colwidth );
  415.                             fputs( buf, stdout );
  416.                             i += 2;
  417.                             break;
  418.                         case 'x':
  419.                             sprintf( buf, "%d", startX );
  420.                             fputs( buf, stdout );
  421.                             i += 2;
  422.                             break;
  423.                         case 'y':
  424.                             sprintf( buf, "%d", startY );
  425.                             fputs( buf, stdout );
  426.                             i += 2;
  427.                             break;
  428.                         default:
  429.                             fputc( s[i], stdout );
  430.                             break;
  431.                     }
  432.                 }
  433.                 else
  434.                 {
  435.                     fputc( s[i], stdout );
  436.                 }
  437.             }
  438.         }
  439.         fclose( fp );
  440.     }
  441.     else
  442.     {
  443.         fputs( "%!PS-Adobe-2.0\n", stdout );
  444.         fputs( "%%Creator: PSTEXT-Treiber\n", stdout );
  445.         fputs( "% (C) 1990, " \
  446.                       "David Geffen & TOOLBOX\n", stdout );
  447.         fputs( "%%Title:   PSTEXT Header File\n", stdout );
  448.         fputs( "%%EndComments\n", stdout );
  449.  
  450.         fputs( "% Umlaut Functions\n", stdout );
  451.         fputs( "/reencsmalldict 12 dict def\n", stdout );
  452.         fputs( "/ReEncodeSmall\n", stdout );
  453.         fputs( "{\n", stdout );
  454.         fputs( "    reencsmalldict begin\n", stdout );
  455.         fputs( "    /newcodesandnames exch def\n", stdout );
  456.         fputs( "    /newfontname exch def\n", stdout );
  457.         fputs( "    /basefontname exch def\n", stdout );
  458.         fputs( "    /basefontdict basefontname "\
  459.                     "findfont def\n", stdout );
  460.         fputs( "    /newfont basefontdict maxlength "\
  461.                     "dict def\n", stdout );
  462.         fputs( "    basefontdict\n", stdout );
  463.         fputs( "    {\n", stdout );
  464.         fputs( "        exch dup /FID ne\n", stdout );
  465.         fputs( "        {\n", stdout );
  466.         fputs( "            dup /Encoding eq\n", stdout );
  467.         fputs( "            {\n", stdout );
  468.         fputs( "                exch dup length array "\
  469.                                "copy\n", stdout );
  470.         fputs( "                newfont 3 1 roll put\n",\
  471.                                 stdout );
  472.         fputs( "            }\n", stdout );
  473.         fputs( "            {\n", stdout );
  474.         fputs( "                exch newfont 3 1 roll "\
  475.                                 "put\n", stdout );
  476.         fputs( "            }\n", stdout );
  477.         fputs( "            ifelse\n", stdout );
  478.         fputs( "        }\n", stdout );
  479.         fputs( "        {\n", stdout );
  480.         fputs( "            pop pop\n", stdout );
  481.         fputs( "        }\n", stdout );
  482.         fputs( "        ifelse\n", stdout );
  483.         fputs( "    }\n", stdout );
  484.         fputs( "    forall\n", stdout );
  485.  
  486.         fputs( "    newfont /FontName newfontname "\
  487.                     "put\n", stdout );
  488.         fputs( "    newcodesandnames aload pop\n", \
  489.                     stdout );
  490.  
  491.         fputs( "    newcodesandnames length 2 idiv\n", \
  492.                     stdout );
  493.         fputs( "    {\n", stdout );
  494.         fputs( "        newfont /Encoding get 3 1 roll"\
  495.                         " put\n", stdout );
  496.         fputs( "    }\n", stdout );
  497.         fputs( "    repeat\n", stdout );
  498.  
  499.         fputs( "    newfontname newfont definefont pop\n",\
  500.                     stdout );
  501.         fputs( "    end\n", stdout );
  502.         fputs( "} \n", stdout );
  503.         fputs( "def\n", stdout );
  504.  
  505.         fputs( "/umlauts [\n", stdout );
  506.         fputs( "8#204 /adieresis\n", stdout );
  507.         fputs( "8#224 /odieresis\n", stdout );
  508.         fputs( "8#201 /udieresis\n", stdout );
  509.         fputs( "8#216 /Adieresis\n", stdout );
  510.         fputs( "8#231 /Odieresis\n", stdout );
  511.         fputs( "8#232 /Udieresis\n", stdout );
  512.         fputs( "8#341 /germandbls\n", stdout );
  513.         fputs( "] def\n", stdout );
  514.  
  515.         sprintf( s, "/%s /%s-Umlaut umlauts\n", font, font);
  516.         fputs( s, stdout );
  517.         fputs( "ReEncodeSmall\n", stdout );
  518.         fputs( "% End of Preparation for Umlaut "\
  519.                "Functions\n", stdout );
  520.  
  521.         fputs( "% Global Variables\n", stdout );
  522.         fputs( "/", stdout );
  523.         fputs( font, stdout );
  524.         fputs( "-Umlaut findfont\n", stdout );
  525.         sprintf( s, "%d", points );
  526.         fputs( s, stdout );
  527.         fputs( " scalefont setfont\n", stdout );
  528.  
  529.         sprintf( s, "/X %d def\n", startX );
  530.         fputs( s, stdout );
  531.         sprintf( s, "/Y %d def\n", startY );
  532.         fputs( s, stdout );
  533.  
  534.         fputs( "/lineheight {", stdout );
  535.         sprintf( s, "%d %d", points, spacing );
  536.         fputs( s, stdout );
  537.         fputs( " add} def\n", stdout );
  538.  
  539.         fputs( "/colwidth {", stdout );
  540.         sprintf( s, "%d} def \n", colwidth );
  541.         fputs( s, stdout );
  542.  
  543.         fputs( "% shline shows a line and updates Y\n", \
  544.                 stdout );
  545.         fputs( "/shline\n", stdout );
  546.         fputs( "{\n", stdout );
  547.         fputs( "    show\n", stdout );
  548.         fputs( "    Y lineheight sub\n", stdout );
  549.         fputs( "    /Y exch def\n", stdout );
  550.         fputs( "    X Y moveto\n", stdout );
  551.         fputs( "} def\n", stdout );
  552.  
  553.         fputs( "% show page and update X and Y\n", stdout );
  554.         fputs( "/nextpage \n", stdout );
  555.         fputs( "{ \n", stdout );
  556.         fputs( "    showpage \n", stdout );
  557.         sprintf( s, "    /X %d def\n", startX );
  558.         fputs( s, stdout );
  559.         sprintf( s, "    /Y %d def\n", startY );
  560.         fputs( s, stdout );
  561.         if (LandScape == A4_QUER)
  562.         {
  563.             sprintf( s, "    %u 0 translate\n"\
  564.                         "    90 rotate\n", A4_X );
  565.             fputs( s, stdout );
  566.         }
  567.         fputs( "    X Y moveto \n", stdout );
  568.         fputs( "} def\n", stdout );
  569.  
  570.         fputs( "% nextcol prepares the next column\n",\
  571.                stdout );
  572.         fputs( "/nextcol\n", stdout );
  573.         fputs( "{\n", stdout );
  574.         fputs( "    X colwidth add\n", stdout );
  575.         fputs( "    /X exch def\n", stdout );
  576.         sprintf( s, "    /Y %d def\n", startY );
  577.         fputs( s, stdout );
  578.         fputs( "    X Y moveto\n", stdout );
  579.         fputs( "} def\n", stdout );
  580.  
  581.         if (LandScape == A4_QUER)
  582.         {
  583.             sprintf( s, "\n%d 0 translate\n", A4_X );
  584.             fputs( s, stdout );
  585.             fputs( "90 rotate\n", stdout );
  586.         }
  587.         fputs( "X Y moveto\n", stdout );
  588.     }
  589. }
  590.  
  591. /*  i2a() übersetzt 'val' in einen 'places'-stelligen
  592.     'radix'-Wert und schreibt ihn in 's'.
  593.     Es wird also immer mit 'places' Zeichen geschrieben,
  594.     mit entsprechend vielen führenden Nullen.
  595. */
  596.  
  597. void i2a ( int val, char *s, int places, int radix )
  598. {
  599.     s[places--] = 0;
  600.     do
  601.     {
  602.         s[places] = val % radix + '0';
  603.         val /= radix;
  604.     }
  605.     while ( places-- );
  606. }
  607.  
  608. /*  'usage'-Funktion zeigt die möglichen Optionen
  609. */
  610. void usage( char *s )
  611. {
  612.     fprintf( stdout, "Aufruf: \t%s [Optionen]\n", s );
  613.     fprintf( stdout, "\tDie Optionen sind:\n" );
  614.     fprintf( stdout, "\t[Filename...]\n" );
  615.     fprintf( stdout, "\t[-cColumns]\n" );
  616.     fprintf( stdout, "\t[-dDurchschuß]\n" );
  617.     fprintf( stdout, "\t[-fFont]\n" );
  618.     fprintf( stdout, "\t[-lZeilen]\n" );
  619.     fprintf( stdout, "\t[-nZeilennumerierung]\n" );
  620.     fprintf( stdout, "\t[-oOrientierung]\n" );
  621.     fprintf( stdout, "\t[-pSchriftgröße]\n" );
  622.     fprintf( stdout, "\t[-wWordwrap-Spalte]\n" );
  623.     fprintf( stdout, "\t[-xAnfangspunkt]\n" );
  624.     fprintf( stdout, "\t[-yAnfangspunkt]\n" );
  625. }
  626.  
  627. /*  error() gibt eine Fehlermeldung aus und
  628.     beendet das Programm.
  629. */
  630. void error( char *s )
  631. {
  632.     fprintf( stderr, s );
  633.     exit( 1 );
  634. }
  635.  
  636. /* --- HAUPTPROGRAMM ------------------------------------ */
  637. int main( argc, argv )
  638. int argc;
  639. char *argv[];
  640. {
  641.     char filename[MAX_FILENAME];
  642.     char s[MAX_CHARS + 10];
  643.     char *sp;
  644.     unsigned int end_flag, back;
  645.     int i, splen;
  646.  
  647.     /*  Defaultoptionen setzen und
  648.         Anwender-Optionen analysieren
  649.     */
  650.     if ( argc == 1 ) {
  651.       usage( argv[0] );
  652.       error( "" );
  653.       exit(1);
  654.     }
  655.  
  656.     set_defaults();
  657.     getopts( argc, argv );
  658.  
  659.     /*  array 'specials' enthält die Sonderzeichen, die nur
  660.         in Oktal ausgegeben werden dürfen
  661.     */
  662.     for (i = 0; i < 128; i++) specials[i] = i + 128;
  663.     strcat( specials, "\\/()<>[]{}%" );
  664.  
  665.     /*  Vorbereitung des PostScript-Headers
  666.     */
  667.     header();
  668.  
  669.     /*  Jede Zeile wird in Klammern geschrieben,
  670.         mit einem 'shline'-Funktionsaufruf am Ende:
  671.         z.B. "(Text) shline"
  672.     */
  673.  
  674.     if (!next_file)
  675.         next_file++;
  676.  
  677.     while( next_file-- )
  678.     {
  679.         ln_count     = 1;
  680.         lines        = default_lines;
  681.         cols         = default_cols;
  682.  
  683.         if (!(*files[next_file]))
  684.             fp = stdin;
  685.         else
  686.            if ((fp = fopen(files[next_file], "rt")) == NULL)
  687.            {
  688.                error("Datei konnte nicht geöffnet werden!");
  689.            }
  690.  
  691.         while( fgets( s, MAX_CHARS, fp ) != NULL )
  692.         {
  693.             sp = s;
  694.             fputs( "(", stdout );
  695.             /*
  696.                 Flag für nextpage setzen
  697.             */
  698.             text_on_page = TRUE;
  699.  
  700.             if (numbering)
  701.             {
  702.                if (!((ln_count) % ln_interval))
  703.                {
  704.                    fprintf( stdout, "%-5d ", ln_count );
  705.                }
  706.                else
  707.                    /* 6 Leerzeichen */
  708.                    fprintf( stdout, "      " );
  709.             }
  710.  
  711.             /*  Weg mit dem '\n', sofern vorhanden.
  712.                 Beim Dateiende gibt es keins.
  713.             */
  714.             splen = strlen( sp );
  715.             if (strchr( sp, '\n' ))
  716.                 back = 1;
  717.             else
  718.                 back = 0;
  719.             strcpy( &sp[strlen(sp) - back], ") shline\n" );
  720.  
  721.             blanks = get_blanks( sp );
  722.             blanks %= cols_on_line;
  723.             if (numbering) blanks += 6;
  724.  
  725.             /*  String ausgeben und gleichzeitig prüfen, ob
  726.                 Wordwrap nötig ist.
  727.                 Alles zwischen '(' und ')' ausdrucken.
  728.                 Nach der Schleife wird ') shline'
  729.                 ausgegeben.
  730.             */
  731.  
  732.             wrap = 0;
  733.             i = 0;
  734.             while (i < (int)(splen - back ) )
  735.             {
  736.                 process_char( *sp );
  737.                 wrap++; i++;
  738.                 if ((wrap > cols_on_line)
  739.                    && strchr( breaks, *sp ))
  740.                 {
  741.                     fputs( ") shline\n", stdout );
  742.                     text_on_page = TRUE;
  743.                     ispage();
  744.                     wrap = 0;
  745.                     if (strlen(sp) > strlen(") shline\n"))
  746.                     {
  747.                         fputs( "(", stdout );
  748.                         /*
  749.                             Gleiche Anzahl von Blanks am
  750.                             Zeilenanfang nicht vergessen
  751.                         */
  752.                         put_blanks( blanks );
  753.                     }
  754.                 }
  755.                 sp++;
  756.             }
  757.  
  758.             /*  den Rest ausgeben
  759.             */
  760.             fputs( sp, stdout );
  761.             ispage();
  762.             /*
  763.                 Egal, ob es Wordwrap gab oder nicht -
  764.                 dies zählt nur als eine Zeile
  765.             */
  766.             ln_count++;
  767.         }
  768.  
  769.         if (text_on_page)
  770.             fputs( "nextpage\n", stdout );
  771.         fclose( fp );
  772.     }
  773. return(0);
  774. }
  775. /* ---------------   Ende von PSTEXT.C   ---------------- */
  776.