everson@CompSci.Bristol.AC.UK (Phill Everson ) (01/08/90)
This is to introduce official patch #6 (it might be #7 by now, I seem to have lost count) to thack, a troff to postscript filter. I would appriecate it if anyone who makes modifications to this or any other program would send me the output of a 'diff -c' with a known version of the software rather a full copy from which I have to extract your modifications myself. We can reduce network traffic and also make official patch creation easier when there is more than one group working on the code at the same time. Here are the changes: -------------------------------------------------------------------------- I got thack to work under OpenWindows 1.0 as part of a manual page previewer. Here are some changes to thack that I found needed or helpful. Permit 'thack filename'; this is required if we want to use thack in Sun's 'man -t' command by setting the environment variable TCAT to 'thack'. Upgrade to (my limited understanding of) PS-Adobe-2.0 EPSF-2.0 format. Put 'thack: ' in the front of error messages. (It isolates them better in a pipeline.) Keep better track of errors for thack's exit status. Fix minor spacing and font problems in man page. -- Paul Eggert <eggert@twinsun.com> -------------------------------------------------------------------------- The main fix is to generate smaller output; on a large computer science paper ("Eli: A Complete, Flexible Compiler Construction System") the new output is 28% smaller than the old. On the thack man page itself, the savings is only 21% because the output is so small. The savings comes from outputting smaller numbers, and from eliminating some unneeded newlines, turning some blanks into newlines so that no long lines are generated. For example, where the old thack generated 60 TR F (T)270 4533 P (H)307 X (A)350 X (C)393 X (K)433 X the new thack generates 60 TR(T)270 1511 P(H)37 X(A)43 X(C)43 X(K)40 X A minor fix: npages is now unsigned. -- Paul Eggert <eggert@twinsun.com> ---------------------------------------------------------------------------- Here is a patch to thack that adds support for the characters circle, 1/4, 1/2, 3/4, and Bell System logo. For the logo, I use the same character that Adobe TranScript uses; it displays as an Apple logo on our LaserWriter (and on Sun's OpenWindows 1.0). Also, the square is patched to look more like a square. While I was at it I put the prolog text into a table; this should make things a tad smaller and/or faster. -- Paul Eggert <eggert@twinsun.com> Thanks Phillip G. Everson ---------------------------------------------------------------------------- Medical Imaging Senior Software Engineer Dept Comp Sci Philips Radiotherapy Systems University of Bristol, UK Horfield Road, Bristol, UK *** README Mon Jan 8 08:49:53 1990 --- README.orig Mon Jan 8 08:35:08 1990 *************** *** 14,21 **** It does not claim to be perfect, but I personally have used it for printing many documents in the past, especially manual pages and found ! it very useful. It has also been used under OpenWindows1.0 aspart of a ! manual page previewer. It was written under SunOS3.5, but has been run on a 3B2 running System V and produces particularly nice output under SunOS4.0 or later as Sun --- 14,20 ---- It does not claim to be perfect, but I personally have used it for printing many documents in the past, especially manual pages and found ! it very useful. It was written under SunOS3.5, but has been run on a 3B2 running System V and produces particularly nice output under SunOS4.0 or later as Sun *** thack.1 Mon Jan 8 08:45:52 1990 --- thack.1.orig Mon Jan 8 08:35:08 1990 *************** *** 1,5 **** .\" .TH name section cent-foot ! .TH THACK 1 "8 January 1990" .SH NAME .\" name \- function thack \- hack about with TROFF output --- 1,5 ---- .\" .TH name section cent-foot ! .TH THACK 1 "28 August 1987" .SH NAME .\" name \- function thack \- hack about with TROFF output *************** *** 6,14 **** .SH SYNOPSIS .\" Bold keywords, Italic variables, [] options, | alternatives. .B thack - [ - .IR filename .\|.\|. - ] .SH DESCRIPTION .\" Italic files, commands, IR manual-entry (manual-section) .I Thack --- 6,11 ---- *************** *** 15,21 **** is a hack to convert .IR troff (1) ! output into postscript. The postscript it produces is not highly --- 12,18 ---- is a hack to convert .IR troff (1) ! output into postscript. The postscript it produces is not highly *************** *** 37,45 **** that an uncatered for code has been sent (24 have yet to be identified). More interesting messages such ! as `Sequence Bell Logo is not allowed' ! are also printed. There are five of these ! cases. However, some illegal sequences are intercepted and used as additional font information. .SH BUGS --- 34,42 ---- that an uncatered for code has been sent (24 have yet to be identified). More interesting messages such ! as 'Sequence Bell Logo is not allowed' ! are also printed. There are five of these ! cases. However, some illegal sequences are intercepted and used as additional font information. .SH BUGS *************** *** 50,56 **** .br Many Special characters are Wrong. .br ! .IR Eqn (1) ! and ! .IR tbl (1) ! are not 100% compatible. --- 47,50 ---- .br Many Special characters are Wrong. .br ! Eqn(1) & Tbl(1) are not 100% compatible. *** thack.c Mon Jan 8 08:37:29 1990 --- thack.c.orig Mon Jan 8 08:35:08 1990 *************** *** 1,8 **** #include "th.h" ! int error; ! unsigned npages; ! int xpos, ypos, cx, cy; int font, cfont, size, csize, tfont, tsize; char *pstr, *cstr(); --- 1,7 ---- #include "th.h" ! int npages; ! int xpos, ypos, cy; int font, cfont, size, csize, tfont, tsize; char *pstr, *cstr(); *************** *** 21,50 **** #define Y_INITIAL ((int)(PAGELENGTH*144 + 0.5)) #endif ! #define POINTS_PER_INCH 72 ! ! int ! main(argc, argv) ! int argc; ! char **argv; { - if (argc <= 1) - thack(); - else { - char **a = argv; - while (*++a) - if (freopen(*a, "r", stdin)) - thack(); - else { - fprintf(stderr, "thack: %s: cannot open\n", *a); - error = 1; - } - } - return error || ferror(stdout); - } - - thack() - { int c; int sflag; int hdist, vdist; --- 20,27 ---- #define Y_INITIAL ((int)(PAGELENGTH*144 + 0.5)) #endif ! main() { int c; int sflag; int hdist, vdist; *************** *** 57,63 **** tsize = size = 12; esc = lead = 1; cy = ypos = Y_INITIAL; ! cx = xpos = 0; sflag = 0; prolog(); newpage(); --- 34,40 ---- tsize = size = 12; esc = lead = 1; cy = ypos = Y_INITIAL; ! xpos = 0; sflag = 0; prolog(); newpage(); *************** *** 91,108 **** pstr = "\\320"; break; /* \(em */ case 28: ! pstr = " (1)(4)R"; break; /* \(14 */ case 30: ! pstr = " (1)(2)R"; break; /* \(12 */ case 38: ! pstr = " (3)(4)R"; break; /* \(34 */ default: ! fprintf(stderr, "thack: >>>>> L%d/%d\n", font, c & 0x3f); pstr = "?"; - error = 1; } else switch (c & 0x3f) { --- 68,84 ---- pstr = "\\320"; break; /* \(em */ case 28: ! illegal("1/4"); break; /* \(14 */ case 30: ! illegal("1/2"); break; /* \(12 */ case 38: ! illegal("3/4"); break; /* \(34 */ default: ! fprintf(stderr, ">>>>> L%d/%d\n", font, c & 0x3f); pstr = "?"; } else switch (c & 0x3f) { *************** *** 146,157 **** fontps(3, size, "\\323"); break; /* c'right */ case 44: ! pstr = " SQ"; ! break; /* square */ default: ! fprintf(stderr, "thack: >>>>> U%d/%d\n", font, c & 0x3f); pstr = "?"; - error = 1; } else if (fh == 0) switch (c & 0x3f) { --- 122,132 ---- fontps(3, size, "\\323"); break; /* c'right */ case 44: ! pstr = "\\250"; ! break; /* square ? */ default: ! fprintf(stderr, ">>>>> U%d/%d\n", font, c & 0x3f); pstr = "?"; } else if (fh == 0) switch (c & 0x3f) { *************** *** 177,183 **** fontps(0, size, "\\\\"); break; /* Backslash ! */ case 35: ! pstr = "\\360"; break; /* Bell Logo */ case 36: pstr = "\\245"; --- 152,158 ---- fontps(0, size, "\\\\"); break; /* Backslash ! */ case 35: ! illegal("Bell Logo"); break; /* Bell Logo */ case 36: pstr = "\\245"; *************** *** 222,230 **** pstr = "\\273"; break; /* ~= */ default: ! fprintf(stderr, "thack: >>>>> L%d/%d\n", font, c & 0x3f); pstr = "?"; - error = 1; } else switch (c & 0x3f) { --- 197,204 ---- pstr = "\\273"; break; /* ~= */ default: ! fprintf(stderr, ">>>>> L%d/%d\n", font, c & 0x3f); pstr = "?"; } else switch (c & 0x3f) { *************** *** 316,322 **** pstr = "\\315"; break; /* impr. subset */ case 41: ! pstr = " O"; break; /* circle */ case 44: pstr = "\\256"; --- 290,296 ---- pstr = "\\315"; break; /* impr. subset */ case 41: ! illegal("circle"); break; /* circle */ case 44: pstr = "\\256"; *************** *** 325,333 **** fontps(0, size, "\\247"); break; /* section */ default: ! fprintf(stderr, "thack: >>>>> U%d/%d\n", font, c & 0x3f); pstr = "?"; - error = 1; } } else { --- 299,306 ---- fontps(0, size, "\\247"); break; /* section */ default: ! fprintf(stderr, ">>>>> U%d/%d\n", font, c & 0x3f); pstr = "?"; } } else { *************** *** 394,401 **** size = 36; break; default: ! fprintf(stderr, "thack: Size: %x\n", c & 0x0f); ! error = 1; } crsize(csize, size); tsize = size; --- 367,373 ---- size = 36; break; default: ! fprintf(stderr, "Size: %x\n", c & 0x0f); } crsize(csize, size); tsize = size; *************** *** 403,409 **** else if ((c & 0xf0) == 0x40) { c &= 0xf; switch (c) { ! case 0:/* fputs("thack: INIT\n", stderr); error = 1; */ break; case 1: font &= 30; --- 375,381 ---- else if ((c & 0xf0) == 0x40) { c &= 0xf; switch (c) { ! case 0:/* fprintf(stderr,"INIT\n"); */ break; case 1: font &= 30; *************** *** 429,435 **** case 8: esc = -1; break; ! case 9:/* fputs("thack: STOP\n", stderr); error = 1; */ break; case 10: lead = 1; --- 401,407 ---- case 8: esc = -1; break; ! case 9:/* fprintf(stderr,"STOP\n"); */ break; case 10: lead = 1; *************** *** 444,451 **** font &= 27; break; default: ! fputs( "thack: ILLEGAL\n", stderr ); ! error = 1; break; } tfont = font; --- 416,422 ---- font &= 27; break; default: ! fputs( "ILLEGAL\n", stderr ); break; } tfont = font; *************** *** 454,535 **** if (sflag) endpage(); epilog(); } tprint() { if (font != cfont || size != csize) { ! char *fontname; switch (font) { case 0: ! fontname = "TR"; break; case 1: ! fontname = "TI"; break; case 2: ! fontname = "TB"; break; case 3: ! fontname = "S"; break; case 8: ! fontname = "H"; break; case 9: ! fontname = "HO"; break; case 10: ! fontname = "HB"; break; case 11: ! fontname = "S"; break; case 16: ! fontname = "C"; break; case 17: ! fontname = "CO"; break; case 18: ! fontname = "CB"; break; case 19: ! fontname = "S"; break; case 24: ! fontname = "TBI"; break; case 25: ! fontname = "HBO"; break; case 26: ! fontname = "CBO"; break; case 27: ! fontname = "S"; break; default: ! fprintf(stderr, "thack: Illegal Font %d\n", font); ! error = 1; ! fontname = "TR"; } ! printf("\n%d %s", size * 6, fontname); cfont = font; csize = size; } ! if (*pstr == ' ') ! printf(" %d %d\nM%s", xpos, ypos, pstr+1); ! else if (ypos != cy) ! printf("(%s)%d %d\nP", pstr, xpos, ypos); ! else { ! int dx = xpos - cx; ! if (dx < 0) ! printf("(%s)%d\nx", pstr, -dx); ! else ! printf("(%s)%d\nX", pstr, dx); ! } ! cx = xpos; cy = ypos; } --- 425,498 ---- if (sflag) endpage(); epilog(); + return 0; } tprint() { if (font != cfont || size != csize) { ! printf("%d ", size * 6); switch (font) { case 0: ! fputs("TR", stdout); break; case 1: ! fputs("TI", stdout); break; case 2: ! fputs("TB", stdout); break; case 3: ! fputs("S", stdout); break; case 8: ! fputs("H", stdout); break; case 9: ! fputs("HO", stdout); break; case 10: ! fputs("HB", stdout); break; case 11: ! fputs("S", stdout); break; case 16: ! fputs("C", stdout); break; case 17: ! fputs("CO", stdout); break; case 18: ! fputs("CB", stdout); break; case 19: ! fputs("S", stdout); break; case 24: ! fputs("TBI", stdout); break; case 25: ! fputs("HBO", stdout); break; case 26: ! fputs("CBO", stdout); break; case 27: ! fputs("S", stdout); break; default: ! fprintf(stderr, "Illegal Font %d\n", font); ! fputs("TR", stdout); } ! fputs(" F\n", stdout); cfont = font; csize = size; } ! if (ypos == cy) ! printf("(%s)%d X\n", pstr, xpos); ! else ! printf("(%s)%d %d P\n", pstr, xpos, 3 * ypos); cy = ypos; } *************** *** 541,546 **** --- 504,516 ---- font = f1; } + illegal(s) + char *s; + { + pstr = s; + fprintf(stderr, "Sequence \\(%s is not allowed\n", s); + } + crsize(old, new) { if ((old == 16 || old >= 20) && (new != 16 && new < 20)) *************** *** 562,637 **** newpage() { ++npages; ! printf("\n%%%%Page: %u %u\nsave", npages, npages); } - static char *prolog_text[] = { - "%%Title: troff output", - "%%Creator: (thack - contact <everson@cs.bris.ac.uk>)", - "%%Pages: (atend)", - "%%DocumentFonts: Times-Roman Times-Italic Times-Bold \ - Symbol Helvetica Helvetica-Oblique Helvetica-Bold Courier \ - Courier-Oblique Courier-Bold Times-BoldItalic Helvetica-BoldOblique \ - Courier-BoldOblique", - "%%EndComments", - - "/M{3 mul moveto}bind def", - "/P{M gsave show grestore}bind def", - "/X{0 rmoveto gsave show grestore}bind def", - "/x{neg X}bind def", - "/F{findfont exch scalefont setfont}bind def", - "/TR{/Times-Roman F}bind def", - "/TI{/Times-Italic F}bind def", - "/TB{/Times-Bold F}bind def", - "/S{/Symbol F}bind def", - "/H{/Helvetica F}bind def", - "/HO{/Helvetica-Oblique F}bind def", - "/HB{/Helvetica-Bold F}bind def", - "/C{/Courier F}bind def", - "/CO{/Courier-Oblique F}bind def", - "/CB{/Courier-Bold F}bind def", - "/TBI{/Times-BoldItalic F}bind def", - "/HBO{/Helvetica-BoldOblique F}bind def", - "/CBO{/Courier-BoldOblique F}bind def", - "/MR[.65 0 0 .6 0 0]def", - "/1H{gsave newpath 0 0 moveto(1)true charpath flattenpath pathbbox", - " 4 1 roll pop pop pop grestore}bind def", - "/DR{gsave 1H 18 div setlinewidth currentpoint translate}bind def", - "/Z{0 0 transform exch round exch round itransform moveto}bind def", - "/O{DR newpath 1H 2 div dup dup 0 360 arc stroke grestore}bind def", - "/SQ{DR Z newpath 0 0 moveto 1H 0 rlineto 0 1H rlineto 1H neg 0 rlineto", - " closepath stroke grestore}bind def", - "/R{gsave 0 1H .4 mul 2 copy rmoveto currentfont dup MR makefont dup", - " setfont exch 6 -1 roll show setfont 3 1 roll neg rmoveto(\\244)show", - " setfont show grestore}bind def", - "1 6 div dup scale", - "%%EndProlog", - 0 - }; - prolog() { time_t clock = time((time_t *)0); ! char **p; ! printf("%s%s%s%g\n", ! "%!PS-Adobe-2.0 EPSF-2.0\n%%CreationDate: ", asctime(localtime(&clock)), ! "%%BoundingBox: 0 0 542.88 ", PAGELENGTH*POINTS_PER_INCH ! ); ! for (p = prolog_text; *p; p++) ! puts(*p); ! ! npages = 0; } endpage() { ! printf("\nshowpage\nrestore"); cfont = csize = -1; /* Doing this will cause a new font message */ } epilog() { ! printf("\n%%%%Trailer\n%%%%Pages: %u\n", npages); } --- 532,587 ---- newpage() { ++npages; ! printf("%%%%Page: %d %d\n", npages, npages); ! printf("save\n"); } prolog() { time_t clock = time((time_t *)0); ! ! printf("%%!PS-Adobe-\n"); ! printf("%%%%Creator: (thack - contact <everson@cs.bris.ac.uk>)\n"); ! printf("%%%%Title: unknown\n"); ! printf("%%%%CreationDate: %s", asctime (localtime (&clock))); ! printf("%%%%Pages: (atend)\n"); ! printf("%%%%DocumentFonts: Times-Roman Times-Italic Times-Bold \ ! Symbol Helvetica Helvetica-Oblique Helvetica-Bold Courier \ ! Courier-Oblique Courier-Bold Times-BoldItalic Helvetica-BoldOblique \ ! Courier-BoldOblique\n"); ! printf("%%%%EndComments\n"); ! printf("/P {moveto show} bind def\n"); ! printf("/X {currentpoint exch pop moveto show} bind def\n"); ! printf("/F {findfont exch scalefont setfont} bind def\n"); ! printf("/TR /Times-Roman def\n"); ! printf("/TI /Times-Italic def\n"); ! printf("/TB /Times-Bold def\n"); ! printf("/S /Symbol def\n"); ! printf("/H /Helvetica def\n"); ! printf("/HO /Helvetica-Oblique def\n"); ! printf("/HB /Helvetica-Bold def\n"); ! printf("/C /Courier def\n"); ! printf("/CO /Courier-Oblique def\n"); ! printf("/CB /Courier-Bold def\n"); ! printf("/TBI /Times-BoldItalic def\n"); ! printf("/HBO /Helvetica-BoldOblique def\n"); ! printf("/CBO /Courier-BoldOblique def\n"); ! printf("1 6 div dup scale\n"); ! printf("%%%%EndProlog\n"); ! npages = 0; } endpage() { ! printf("showpage\n"); ! printf("restore\n"); cfont = csize = -1; /* Doing this will cause a new font message */ } epilog() { ! printf("%%%%Trailer\n"); ! printf("%%%%Pages: %d\n", npages); }