richard@gryphon.CTS.COM (Richard Sexton) (01/28/88)
Alright. I'm sick of seeing those "where can I get the include
files printed two columns to a page" postings.
Here is a program that splits text into any number of columns
and produces a postscript file, suitable for framing.
It handles any font, any size, you can specify # of lines
per page, all that good stuff.
It probably isn't as good as the one Clayton Cramer announced
in comp.newprod, but it's free.
This is not a great example of intelli... inteli... intael.. real
swift PostScript programming, but it works.
======== snip snip snip =================== snippity snip snip ===========
#include "stdio.h"
/* Copyright 1988 Richard John Sexton */
/* All rights reserved */
/* Not to be used for commercial purposes without the express written
permission of the author.
Richard J. Sexton
richard@gryphon.CTS.COM
rutgers!marque!gryphon!richard
*/
#define CR 10
#define LF 13
#define TRUE 1
#define FALSE 0
#define TOP_MARGIN_DEFAULT 25
#define BOTTOM_MARGIN_DEFAULT 25
#define POINTS_ACROSS ((85 * 72) / 10)
#define POINTS_DOWN ((110 * 72) / 10)
FILE *in, *out;
unsigned char *fword, swarray [26], fontname[256] = "Helvetica";
unsigned long swvalues [26];
short i, fontsize, pt_row_cntr, lines, linecntr, col_nbr, nbr_cols, xpos;
short ypos, yils, page_nbr, colums = 1, rotate = 0, maxx, maxy, temp1;
short temp2, switch_num, border_value, lm_offset, title;
short top_margin, bottom_margin;
unsigned char outfilename[50];
char *pp = "%%";
main (argc, argv)
short argc;
unsigned char *argv[];
{
unsigned short ctemp;
unsigned char c, *s, *d;
printf ("\n Copyright 1988 by Richard J. Sexton. All rights reserved.\n May not sold for profit.\n\n");
init_data ();
/* Get values of switches, if any */
for (i = 1; i < argc; i++)
{
if (*argv[i] == '-')
{
c = (*(argv[i] + 1));
if (c >= 'a' && c <= 'z')
{
c &= 0xdf;
}
if (c <= '9' && c >= '0')
{
ctemp = c;
switch_num = ctemp;
}
if (c <= 'Z' && c >= 'A')
{
register short tt;
static unsigned short kk;
long temp;
swarray[c - 'A'] = 1;
if (*(argv[i] + 2))
{
tt = sscanf ((argv[i] + 2), "%d", &kk);
temp = kk;
swvalues[c - 'A'] = (long)temp;
if (!tt)
{
swvalues[c - 'A'] = (unsigned char *)(argv[i] + 2);
}
}
}
}
}
if (argc == 1)
{
printf ("\n Usage: '%s file', output goes to 'file.ps'.\n\n '%s -h' displays help screen.\n\n", argv[0], argv[0]);
exit (3);
}
if (swarray['H' - 'A'])
{
/* Bozo asked for help */
print_help (argv, swvalues['H' - 'A']);
exit (0);
}
if (switch_num != (-1))
{
switch (switch_num)
{
case '1':
{
fontsize = 6; nbr_cols = 2;
break;
}
case '2':
{
set_rotate (1);
fontsize = 6; nbr_cols = 2;
break;
}
case '3':
{
fontsize = 18;
scopy ("Times-Roman", fontname);
}
}
}
set_params_from_switches ();
if (!lines) /* %% */
{
lines = (rotate ? 500 : 675) / (((fontsize ? fontsize : 10) * 3) / 2);
}
in = fopen (argv[1], "r");
d = outfilename;
s = argv[1];
for (;*s;)
{
*d++ = *s++;
}
*d++ = '.'; *d++ = 'p'; *d++ = 's'; *d++ = 0;
out = fopen (outfilename, "w");
if (in == 0) {printf ("(%s): Can't open file '%s' for input.\n", argv[0], argv[1]); exit(1);}
if (out == 0) {printf ("(%s): Can't open %s.ps for output.\n", argv[0], argv[1]); exit (2);}
printf ("\n%s --> %s\n", argv[1], outfilename);
/* Insert stupid Adobe header */
fprintf (out, "%s!PS-Adobe-1.0\n", pp);
fprintf (out, "%sCreator: The program '%s'\n", pp, argv[0]);
fprintf (out, "%sTitle: %s\n", pp, outfilename);
fprintf (out, "%sPages: (atend)\n", pp);
fprintf (out, "%sDocumentFonts: (atend)\n", pp);
fprintf (out, "%sEndComments\n\n", pp);
fprintf (out, "/yline %d def\n/xline %d def\n/%s findfont %d scalefont setfont\n/yils %d def\n",
(rotate ? (-lm_offset) : 725), lm_offset, fontname, fontsize, fontsize + (fontsize / 2));
/* Define clipping path(s) */
for (i = 0; i < nbr_cols; i++)
{
temp1 = lm_offset + (((maxx - 110) / (nbr_cols)) * i);
temp2 = lm_offset + (((maxx - 110) / (nbr_cols)) * (i + 1));
temp2 -= 6;
fprintf (out, "/clippath%d { newpath %d 999 moveto %d -999 lineto",
i, temp1, temp1);
fprintf (out, " %d -999 lineto %d 999 lineto closepath} def\n",
temp2, temp2);
}
fprintf (out, "/nl {/yline yline yils sub def xline yline moveto show } def\n");
fprintf (out, "/move {moveto} def\n/draw {lineto} def\n");
if (rotate)
{
fprintf (out, "90 rotate\n");
}
fprintf (out, "gsave\nclippath0 clip\n");
fprintf (out, "%sEndProlog\n%sPage 0 1\n", pp, pp);
fprintf (out, "\n(");
while ((c = getc (in)) != 0xff)
{
if ((c == CR) || (c == LF))
{
/* Hit a CR or LF, move to a new line */
/* If your files have CR LF then you have a problem */
/* Mine don't */
fprintf (out, ") nl");
pt_row_cntr -= yils;
linecntr++;
if (((lines == 0) && (pt_row_cntr <= 150)) ||
((lines) && (linecntr == lines)))
{
colum_break ();
pt_row_cntr = maxy;
linecntr = 0;
}
fprintf (out, "\n(");
}
else
{
/* Output a line of text */
if (c == '(' || c == ')')
{
fprintf (out, "\\");
}
fprintf (out, "%c", c);
}
}
fprintf (out, ")\n/yline yline yils sub def\nxline yline moveto\nshow\n");
draw_border ();
draw_title ();
fprintf (out, "showpage\n grestore\n");
fprintf (out, "%sTrailer\n%sDocumentFonts: %s\n%sPages: %d\n",
pp, pp, fontname, pp, page_nbr);
fclose (out);
fclose (in);
printf ("\n%d page%s printed.\n", page_nbr, (page_nbr == 1 ? "" : "s"));
}
/*************** switch and debug routines ********************/
dump_switches ()
{
short i;
for (i = 0; i < 26; i++)
{
if (swarray[i])
{
/* printf ("switch -%c = %d ", i + 'A', swvalues[i]); */
}
}
}
/******************** Local support routines ***************************/
scopy (s, d)
unsigned char *s, *d;
{
while (*s) *d++ = *s++; *d = 0;
}
colum_break ()
{
if (col_nbr++ >= nbr_cols - 1)
{
page_break ();
col_nbr = 0;
}
else
{
xpos = lm_offset + (((maxx - 110) / (nbr_cols)) * col_nbr); /* used to be nbr_cols + 1 */
ypos = rotate ? (-lm_offset) : 725;
fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
}
fprintf (out, "grestore gsave\nclippath%d clip\n", col_nbr);
}
page_break()
{
draw_border ();
draw_title ();
fprintf (out, "\nshowpage\n");
fprintf (out, "%sPage %d %d\n", pp, page_nbr - 1, page_nbr);
if (rotate) fprintf (out, "90 rotate");
xpos = lm_offset; ypos = (rotate ? (-lm_offset) : 725);
fprintf (out, "/yline %d def\n/xline %d def\n", ypos, xpos);
col_nbr = 0;
page_nbr++;
}
init_data ()
{
register unsigned short i;
fontsize = 10; /* Set default font size */
yils = 15; /* Y InterLine Spacing = fontsize * 1.5 */
pt_row_cntr = POINTS_DOWN; /* Start counter (in points) at T.O.P - 725 */
col_nbr = 0;
nbr_cols = 1;
linecntr = 0;
page_nbr = 1;
border_value = 0;
lines = 0;
switch_num = -1;
lm_offset = 45; /* Left margin offset */
title = 0; /* default to no title */
top_margin = TOP_MARGIN_DEFAULT;
bottom_margin = BOTTOM_MARGIN_DEFAULT;
maxx = POINTS_ACROSS; maxy = POINTS_DOWN;
for (i = 0; i < 26; i++)
{
swarray[i] = 0;
swvalues[i] = 0;
}
}
print_help (argv, helpqual)
unsigned char *argv[], *helpqual;
{
unsigned char num;
num = (*helpqual) & 0xdf;
switch (num)
{
case 0:
{
printf ("\n Usage: '%s file', output goes to 'file.ps'.\n\n '%s -h' displays help screen.\n", argv[0], argv[0]);
printf ("\n Options are:\n");
printf (" -b[n] Draw border around text [optional format 'n']\n");
printf (" -cn Set text in 'n' colums across\n");
printf (" -fname Set text in font 'name'\n");
printf (" -h[s] '%s -h' gets help. '%s -hs' gets help about subject 's'.\n", argv[0], argv[0]);
printf (" -ln Limit text to 'n' lines per column\n");
printf (" -n Print 'n' copies\n");
printf (" -on Orientation 'n'. n = l for landscape, p for portrait\n");
printf (" -pn Set text 'n' points tall\n");
printf (" -n Use predefined format n:\n");
printf ("\n 1 = portrait, 2 columns of 6pt Helvetica\n");
printf (" 2 = landscape, 2 columns of 6pt Helvetica\n");
printf (" 3 = landscape, 1 column, 18pt Times Roman\n\n");
printf (" -ttext Print title = text on every page (also date and page #)\n");
printf ("\nThe default output format is portrait, 10pt Helvetica\n");
break;
}
case 'B':
{
printf ("\n ** Border formats **\n\n");
printf (" The qualifier for the -b switch is a number 0 - 127.\n");
printf (" The default, -b with no qualifier, draws a box around every column.\n\n");
printf (" The individual lines are binary encoded as follows:\n\n");
/*border shit */ printf (" 1 = left border line 2 = top line\n");
printf (" 4 = right border line 8 = bottom line\n");
printf (" 16 = middle line (does not connect with top and bottom\n");
printf (" 32 = middle connecting line (top)\n");
printf (" 64 = middle connecting line (bottom)\n\n");
printf (" These last two connect the middle line to the top and bottom and\n");
printf (" draw a small cross where they intersect to aid registration.\n\n");
printf (" These numbers can be used alone or added together. For example:\n\n");
printf (" -b16 would draw a line between columns\n");
printf (" -b15 would draw the four lines forming a box around the column(s)\n");
printf (" (15 = 8 + 4 + 2 + 1)\n");
break;
}
case 'C':
{
break;
}
case 'F':
{
break;
}
case 'H':
{
break;
}
case 'L':
{
break;
}
case 'N':
{
break;
}
case 'O':
{
break;
}
case 'P':
{
}
} /* End switch */
exit (0);
}
set_params_from_switches ()
{
/* Columns per page */
if (swarray['C' - 'A'])
{
nbr_cols = swvalues['C' - 'A'];
}
/* Font name */
if (swarray['F' - 'A'])
{
if (swvalues['F' - 'A'])
{
setfont ();
}
}
/* Orientation: 'l' = landscape */
if (swarray['O' - 'A'])
{
if (swvalues['O' - 'A'])
{
fword = (char *)swvalues['O' - 'A'];
if ((*fword & 0xdf) == 'P')
{
set_rotate (0);
}
if ((*fword & 0xdf) == 'L')
{
set_rotate (1);
}
}
}
/* Lines per column */
if (swarray['L' - 'A'])
{
lines = swvalues['L' - 'A'];
}
/* Border value */
if (swarray['B' - 'A'])
{
if (swvalues['B' - 'A'])
{
border_value = swvalues['B' - 'A']; /* Get qualifier of '-b' switch */
}
else
{
border_value = 15;
}
}
/* if (!border_value)
{
Hmm, no qualifier, Default = all bits on
border_value = 15;
} */
/* Point size */
if (swarray['P' - 'A'])
{
fontsize = swvalues['P' - 'A'];
}
/* Title ? */
if (swarray['T' - 'A'])
{
title = 1;
}
/* End of processing switches */
}
set_rotate (num)
short num;
{
short t;
if (num != rotate)
{
t = maxx; maxx = maxy; maxy = t;
pt_row_cntr = maxy;
rotate ^= 1;
}
}
setfont()
{
scopy (swvalues['F' - 'A'], fontname);
}
draw_border ()
{
short tx1, ty1, tx2, ty2;
if (border_value)
{
tx1 = 40; ty1 = rotate ? (-lm_offset) : 760;
tx2 = rotate ? 750 : 580; ty2 = rotate ? (-580) : 35;
/* %% */
fprintf (out, "\ngrestore gsave newpath\n");
fprintf (out, "%d %d move ", tx1, ty1);
/* Draw */
if (border_value & 1)
{
fprintf (out, "%d %d draw ", tx1, ty2);
}
else
{
fprintf (out, "%d %d move ", tx1, ty2);
}
if (border_value & 8)
{
fprintf (out, "%d %d draw ", tx2, ty2);
}
else
{
fprintf (out, "%d %d move ", tx2, ty2);
}
if (border_value & 4)
{
fprintf (out, "%d %d draw ", tx2, ty1);
}
else
{
fprintf (out, "%d %d move ", tx2, ty1);
}
if (border_value & 2)
{
fprintf (out, "%d %d draw ", tx1, ty1);
}
else
{
fprintf (out, "%d %d move ", tx1, ty1);
}
fprintf (out, "\nclosepath\n");
if (border_value & (16 + 32 + 64))
{
short tempx, indx;
for (indx = 0; indx < nbr_cols - 1; indx++)
{
tempx = lm_offset + (((maxx - 110) / (nbr_cols)) * (indx + 1));
tempx -= 6; /* Bump over a bit */
if (border_value & 16)
{
fprintf (out, "%d %d move %d %d draw\n",
tempx, 740, tempx, 55);
}
if (border_value & 32)
{
fprintf (out, "%d %d move %d %d draw\n",
tempx, 760, tempx, 740);
fprintf (out, "%d %d move %d %d draw\n",
tempx - 20, 760, tempx + 20, 760);
}
if (border_value & 64)
{
fprintf (out, "%d %d move %d %d draw\n",
tempx, 35, tempx, 55);
fprintf (out, "%d %d move %d %d draw\n",
tempx - 20, 35, tempx + 20, 35);
}
}
}
fprintf (out, "stroke\n");
}
}
draw_title ()
{
if (title) fprintf (out, " 400 25 move (%s) show\n", outfilename);
}
========= wow ! you made it ! ===================== more snipping ============
Makefile ? You gotta be kidding. try 'cc split' and see if you cant figure
it out.
If you make any neat additions, I'd appreciate a copy.
Cheers.
--
"...and before too long I might, see those flashing red lights"
richard@gryphon.CTS.COM
{ihnp4!scgvaxd!cadovax, philabs!cadovax, codas!ddsw1} gryphon!richard