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