"PF2PS--a text-to-PostScript translator," by B.E. Chi (bec@nysernet.org), was published in the Spring 2000 issue of _VM Update_ magazine. This file contains the code described in that article. Phil Norcross editor, VM Update 22 June 2000 webmaster@sdsusa.com www.sdsusa.com/vmupdate P.S: Readers are cautioned that VM Update presents this code in good faith, but neither SDS nor the authors of the code give any warranty; neither SDS nor the contributing organizations or individuals accept any liability of any kind whatsoever arising out of the use of this code. Readers should satisfy themselves as to the correctness and relevance to their circumstances of all advice, information, code, JCL, EXECs, and other contents of this journal before making any use of it. /* V 1.2. © Copyright 2000, B. E. Chi, bec@nysernet.org PF2PS fn1 ft1 fm1 fn2 ft2 fm2 [([CC|PAG|NOH][) [n] [L]]] reads a file and translates it to PostScript format, writing the result in . If the input file has printer control characters in column 1 (either ASA or channel commands), use the CC option. Otherwise the file will be formatted 55 lines/page with a header on each page, giving the same appearance as does the standard CMS PRINT (NOCC) command, unless the PAG option is given, in which case there will be page numbers but no header, or the NOH option is given, in which case the file will be formatted 58 lines/page with neither header nor page numbers. Options CC, PAG and NOH are mutually exclusive: if more than one are specified, all but the first is ignored. The parameter n following the options causes n copies of each page to be printed as it is encountered. If n be unspecified, n = 1 is assumed. The flag L following the options causes printing to occur in landscape mode. (The font size is reduced to permit the same number of lines/page as for portrait, with a resulting line width of about 150 characters.) Defaults: ft1 = LISTING; fm1 = *; fn2 = fn1; ft2 = PS, fm2 = A1. Any existing is overwritten without warning. */ /* Configurable parameters (fix up help text above if changed): */ version = "1.0" /* Base release. */ version = "1.1" /* Added %%Page:, %%Trailer, %%Pages comments to */ /* make Pageview and Ultrix previewer happy. */ version = "1.2" /* Added P option: page numbers w/o header. */ sysname = "IBM 9672 R20" /* For NOCC header line. */ pw = 8.5 /* Page width (inches). */ ph = 11.0 /* Page height. */ lm = 0.5 /* Left margin. */ tm = 0.8 /* Top margin. */ font = "Courier" /* Type font. Must be monopitch. */ fs = 11 /* Font size (points). */ ls = 12 /* Line spacing (points). */ lpp = 55 /* Lines/page for NOCC input. */ ppnc = 71 /* Portrait column where "Page n" starts in NOCC header. */ lpnc = 135 /* Landscape column where "Page n" starts in NOCC header. */ ARG fn1 ft1 fm1 fn2 ft2 fm2 "("options")" flags IF fn1 = "" | fn1 = "?" THEN DO PARSE SOURCE . . fn ft fm . "PIPE <" fn ft fm "| FRLAB | TOLAB */| CONSOLE" EXIT 0 END IF ft1 = "" THEN ft1 = "LISTING" IF fm1 = "" THEN fm1 = "*" IF nc = "" THEN nc = 1 /* Number of (decollated) copies. */ "PIPE CMS LISTFILE" fn1 ft1 fm1 "(NOH ALLOC | VAR X" IF RC ^= 0 THEN DO /* See if input file exists, */ SAY x EXIT RC /* and if it does, get its mode and size. */ END ELSE PARSE VAR x . . fm1 . lrecl recs . IF fn2 = "" THEN fn2 = fn1 IF ft2 = "" THEN ft2 = "PS" IF fm2 = "" THEN fm2 = "A1" IF lrecl*recs > 65535 THEN long = "LONG" ELSE long = "" pw = TRUNC(72*pw+0.5); ph = TRUNC(72*ph+0.5) /* Convert inch */ lm = TRUNC(72*lm+0.5); tm = TRUNC(72*tm+0.5) /* specs to points. */ bbw = pw; bbh = ph /* For Bounding Box. */ PARSE SOURCE . . source . /* For "%%CREATOR" comment. */ nc = 1 /* Number of (decollated) copies to print. */ rot = "" /* Assume portrait mode. */ pnc = ppnc DO WHILE flags ^= "" PARSE VAR flags x flags IF x = "L" THEN DO /* Set up for landscape */ scale = TRUNC(pw/ph,3) rot = "90 rotate 0 -"pw" translate" scale scale "scale " pnc = lpnc bbw = ph; bbh = pw /* For Bounding Box. */ END ELSE IF DATATYPE(x,"W") THEN nc = x /* Number of copies. */ END PARSE VALUE STRIP(options) WITH option 2 /* C, N or P. */ IF option = "C" THEN preprocess = "MCTOASA" /* Insure file contains ASA control characters. */ ELSE IF option = "N" THEN /* File must be formatted. */ preprocess =, /* (Neither headers nor page numbers.) */ "JOIN" lpp+2 "STRING /"'3F'X"/", /* Concatenate lpp+3 lines, */ "| SPEC /1/ 1 1-* 2", /* precede first line with newpage code, */ "| SPLIT BEFORE 3F", /* split lines back apart, */ "| CHANGE /"'3F'X"/ /" /* preceding each except 1st with blank. */ ELSE DO /* File must be formatted with headers. */ IF option = "P" THEN hdr = "" /* Just page numbers. */ ELSE DO /* Headers and page numbers. */ PARSE VALUE DIAG(8,"QUERY CPLEVEL") WITH "/"a . . b"," hdr = "FILE:", /* Page header text. */ LEFT(fn1,9)LEFT(ft1,9)LEFT(fm1,3)sysname a b END preprocess =, "JOIN" lpp-1 "STRING /"'3F'X"/", /* Concatenate lpp lines, */ "| SPEC /1"hdr"/ 1", /* precede with header or page number, */ "/Page/" pnc+1 "RECNO" pnc+6 "LEFT X3E NEXT 1-* NEXT", "| SPLIT BEFORE 3E-3F", /* split lines back apart, */ "| CHANGE /"'3F'X"/ /", /* preceding each except hdr with blank, */ "| CHANGE /"'3E'X"/-/" /* but triple-space before 1st text line. */ END s.1 = "%!PS-Adobe-2.0" /* Begin standard PostScript boilerplate. */ s.2 = "%%Title:" fn2 ft2 fm2 s.3 = "%%Source:" fn1 ft1 fm1 s.4 = "%%Creator:" source version s.5 = "%%CreationDate:" DATE("U") TIME() s.6 = "%%BoundingBox: 0 0" bbw bbh s.7 = "%%EndComments" s.8 = "gsave 0 setgray" s.9 = "/#copies" nc "def" s.10 = "/"font "findfont" fs "scalefont setfont" s.11 = "/cr {"lm "vp moveto} def" /* "Carriage return" w/o linefeed. */ s.12 = "/nl {/vp vp" ls "sub def cr} def" /* New line. */ s.13 = "/np {"rot"/vp" ph-tm "def cr} def" /* New page. */ s.14 = "%%Page: 1 1" s.15 = "np" s.0 = 15 bigpipe =, "PIPE ("long "END !)", " STEM s. ", /* First write boilerplate. */ "| a: FANIN ", /* Modified input records come here. */ "| JOIN * /"'3C'X"/", /* Combine all records with 3C separator. */ "| SPLIT AT 3D", /* Split after each showpage. */ "| SPEC RECNO 1 LEFT 1-* 11", /* Insert %%Page: n n. */ "| SPEC /%%Page:/ 1 W1 NEXTW W1 NEXTW /"'3C'X"/ NEXTW 11-* NEXT", "| SPLIT AT 3C", /* Split records back apart. */ "| DROP 1", /* (Spurious %%Page: 1 1 at top.) */ "| d: FANOUT", /* Make 2nd copy for counting pages. */ "| e: FANIN", /* All records come here to be written. */ "| >" fn2 ft2 fm2; bigpipe = bigpipe||, "! <" fn1 ft1 fm1, /* Read input file, */ "| XLATE *-* 00-3F BC", /* change all non-printing codes to inv ?, */ "|" preprocess, /* and insure that it's in ASA format. */ "| b: TAKE 1 ", "| CHANGE 1-1 /1/+/", /* Remove any formfeed from line 1. */ "| c: FANIN", /* For each line, */ "| CHANGE /\/\\/", /* precede any \, (, ) with escape character \. */ "| CHANGE /(/\(/", "| CHANGE /)/\)/", "| CHANGE 1-1 /+/cr (/", /* Replace ASA + with cr operator, */ "| CHANGE 1-1 / /nl (/", /* blank with nl operator, */ "| CHANGE 1-1 /0/nl nl (/", /* 0 with two nl operators, */ "| CHANGE 1-1 /-/nl nl nl (/", /* etc. */ "| CHANGE 1-1 /1/showpage"'3D'X"np (/"; bigpipe = bigpipe||, "| STRIP TRAILING", /* Discard trailing blanks. */ "| SPEC 1-* 1 /) show/ NEXT", /* Encl text in (), append show opr. */ "| CHANGE 1-10 /nl () show/nl/",/* Eliminate shows for empty lines. */ "| a:", /* Write modified line to output file. */ "! b:", /* Second and subsequent lines come here. */ "| c:", /* Edit and write as for line 1. */ "! LITERAL showpage"'3C'X"/#copies 1 def"'3C'X"grestore", "| a:", /* Append these commands to the end of the output file. */ "! d:", /* 2nd copy of modified file comes here. */ "| FIND %%Page:"||, /* Count pages. */ "| COUNT LINES", "| SPEC /%%Pages: / 1 1-* NEXT", /* %%Pages n comment to output. */ "| LITERAL %%Trailer", "| e:" bigpipe EXIT RC