summaryrefslogtreecommitdiff
path: root/fonts/utilities/psposter/psposter.awk
diff options
context:
space:
mode:
Diffstat (limited to 'fonts/utilities/psposter/psposter.awk')
-rw-r--r--fonts/utilities/psposter/psposter.awk1184
1 files changed, 1184 insertions, 0 deletions
diff --git a/fonts/utilities/psposter/psposter.awk b/fonts/utilities/psposter/psposter.awk
new file mode 100644
index 0000000000..cf6163161a
--- /dev/null
+++ b/fonts/utilities/psposter/psposter.awk
@@ -0,0 +1,1184 @@
+### ====================================================================
+### @Awk-file{
+### author = "Nelson H. F. Beebe",
+### version = "0.08",
+### date = "16 January 1995",
+### time = "14:49:41 MST",
+### filename = "psposter.sh",
+### address = "Center for Scientific Computing
+### Department of Mathematics
+### University of Utah
+### Salt Lake City, UT 84112
+### USA",
+### telephone = "+1 801 581 5254",
+### FAX = "+1 801 581 4148",
+### checksum = "19029 1184 5360 42015",
+### email = "beebe@math.utah.edu (Internet)",
+### codetable = "ISO/ASCII",
+### keywords = "poster, PostScript",
+### supported = "yes",
+### docstring = "Display a centered message in a very large
+### font for a poster, which is represented as an
+### output Encapsulated PostScript file which
+### will produce exactly one page.
+###
+### Usage:
+### psposter [+author] [+bd color] [+bg color]
+### [+bs factor] [+bw dimension]
+### [+c nnn] [+copyright] [+d ]
+### [+fg color] [+fn fontname]
+### [+h dimension] [+help] [+l]
+### [+mw dimension] [+p dimension]
+### [+paper form] [+s factor]
+### [+table {8/o | 8/h | 16/o | 16/h}]
+### [+version] [+w dimension]
+### [+x dimension] [+y dimension]
+### ['?'] [++]
+### [word(s) or <infile] >PostScript-file
+###
+### The font size is normally chosen
+### automatically so that the longest line fills
+### the page, but a fixed font size may be
+### requested if required.
+###
+### If there are too many lines to fit on one
+### page, lines will be lost at the top and
+### bottom of the page.
+###
+### Options are provided to change colors, to
+### request multiple copies, to adjust the
+### position, scale, and orientation, and to
+### select the font.
+###
+### Each poster line consists of one argument,
+### if the words come from the command line, or
+### one line, if the words come from a file.
+###
+### The checksum field above contains a CRC-16
+### checksum as the first value, followed by the
+### equivalent of the standard UNIX wc (word
+### count) utility output of lines, words, and
+### characters. This is produced by Robert
+### Solovay's checksum utility.",
+### }
+### ====================================================================
+BEGIN {
+ VERSION_NUMBER = "0.08"
+ VERSION = "Version " VERSION_NUMBER " [16-Jan-1995]"
+ AFMPATH = ENVIRON["AFMPATH"]
+ if (AFMPATH == "") # supply default fallback search path
+ AFMPATH = "/usr/local/lib/afm"
+ split(AFMPATH,afmpath,":")
+ AFMMAPFILE = find_file(afmpath,"afmfonts.map")
+ if (AFMMAPFILE == "")
+ warning("Cannot find font mapping file [afmfonts.map]")
+
+ DEFAULT_FONT_NAME = "Times-Bold"
+
+ RGBPATH = ENVIRON["RGBPATH"]
+ if (RGBPATH == "") # supply default fallback search path
+ RGBPATH = "/usr/lib/X11:/usr/openwin/lib/X11:/usr/local/lib/X11:/usr/local/X11R5/lib"
+ split(RGBPATH,rgbpath,":")
+ RGBTXTFILE = find_file(rgbpath,"rgb.txt")
+ if (RGBTXTFILE == "")
+ warning("Cannot find X11 color data base file [rgb.txt]")
+
+ angle = "" # empty string means unset
+ background = "0.9 0.9 0.9" # 10% gray
+ baseline_skip = 1.2
+ border_color = "0.5 0.5 0.5" # 50% gray
+ border_width = 10 # big points
+ copies = 1
+ display_fontsize = 0
+ font_name = DEFAULT_FONT_NAME
+ foreground = "0 0 0" # black
+ height = 0
+ width = 0
+ landscape = 0
+ make_font_table = 0
+ margin_width = "" # empty string means unset
+ paper_name = ""
+ point_size = 0
+ ScaleFactor = 1
+ x_offset = 0
+ y_offset = 0
+
+ initialize_paper_table()
+
+ for (k = 1; k < ARGC; ++k) # preserve original command-line arguments
+ OLD_ARGV[k] = ARGV[k]
+
+ for (k = 1; k < ARGC; k++) # collect +switches
+ {
+ if (ARGV[k] == "+author")
+ author()
+ else if (ARGV[k] == "+bd")
+ {
+ border_color = ARGV[++k]
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+bg")
+ {
+ background = ARGV[++k]
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+bs")
+ {
+ baseline_skip = ARGV[++k] + 0
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+bw")
+ {
+ border_width = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+c")
+ {
+ copies = ARGV[++k] + 0
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+copyright")
+ copyright()
+ else if (ARGV[k] == "+d")
+ display_fontsize = 1
+ else if (ARGV[k] == "+fg")
+ {
+ foreground = ARGV[++k]
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+fn")
+ {
+ font_name = ARGV[++k]
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+h")
+ {
+ height = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if ((ARGV[k] == "+help") || (ARGV[k] == "?"))
+ usage()
+ else if (ARGV[k] == "+l")
+ {
+ landscape = 1
+ angle = +90
+ }
+ else if (ARGV[k] == "+mw")
+ {
+ margin_width = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+s")
+ {
+ ScaleFactor = ARGV[++k] + 0
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+table")
+ {
+ parse_table_type(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+p")
+ {
+ point_size = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+paper")
+ {
+ set_paper_dimensions(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+r")
+ {
+ angle = ARGV[++k] + 0
+ ARGV[k] = "" # forget this argument
+ angle = angle % 360 # reduce to -360 .. 360
+ if (angle < 0) # and reduce again to 0 .. 359
+ angle += 360
+ if (!((angle == 0) || (angle == 90) || (angle == 180) || (angle == 270)))
+ error("rotation angle is not a multiple of 90 degrees in -360 .. +360")
+ }
+ else if (ARGV[k] == "+version")
+ version()
+ else if (ARGV[k] == "+w")
+ {
+ width = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+x")
+ {
+ x_offset = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "+y")
+ {
+ y_offset = bigpoint(ARGV[++k])
+ ARGV[k] = "" # forget this argument
+ }
+ else if (ARGV[k] == "++") # no more arguments
+ {
+ while (k < ARGC) # remaining words are for poster text
+ {
+ word[++n] = ARGV[++k]
+ ARGV[k] = "" # forget this argument
+ }
+ }
+ else if (ARGV[k] ~ /^[ \t]*[+]/)
+ error("unrecognized option [" ARGV[k] "]: try +help for more information")
+ else
+ word[++n] = ARGV[k]
+ }
+
+ if ((n == 0) && (make_font_table == 0))
+ { # no words supplied, so read stdin for lines to print
+ while (getline <"/dev/stdin" > 0)
+ word[++n] = $0
+ }
+
+ if (paper_name == "")
+ set_paper_dimensions("A")
+
+ if (margin_width == "")
+ margin_width = (paper_left + paper_right + paper_top + paper_bottom)/4
+ if (height == 0)
+ height = paper_height
+ if (width == 0)
+ width = paper_width
+
+ #
+ # Here is what the picture will look like. Ps mark the PAGE
+ # boundary, enclosing a region of size (PageWidth,PageHeight).
+ # Ms mark the MARGIN, and Bs mark the border; both have
+ # constant width on all four edges. The inner frame contains
+ # the poster text; it has width W (TextWidth) and height H
+ # (TextHeight). The lower-left corner of the MARGIN area is at
+ # (xoffset,yoffset) from the lower-left page corner. The
+ # BoundingBox surrounds the border rectangle marked by Bs.
+ #
+ # For full page posters, normally (xoffset,yoffset) = (0,0),
+ # but the MarginWidth is non-zero, because most PostScript
+ # output devices are incapable of printing closer than about
+ # 5mm to the edge of the printing surface.
+ #
+ # The inner frame may be further scaled by ScaleFactor;
+ # that scaling applies to everything, EXCEPT
+ # (xoffset,yoffset), because those offsets are used to
+ # position the scaled picture on the page.
+ #
+ # PPPPPPPPPPPPPPPPPPPPPPPP
+ # P P
+ # P P
+ # P MMMMMMMMMMMMMMMMMM P
+ # P MMMMMMMMMMMMMMMMMM P
+ # P MMBBBBBBBBBBBBBBMM P
+ # P MMB ^ BMM P
+ # P MMB | BMM P
+ # P MMB<-+----W--->BMM P
+ # P MMB | BMM P
+ # P MMB | BMM P
+ # P MMB H BMM P
+ # P MMB | BMM P
+ # P MMB | BMM P
+ # P MMB | BMM P
+ # P MMB | BMM P
+ # P MMB | BMM P
+ # P MMB v BMM P
+ # P MMBBBBBBBBBBBBBBMM P
+ # P MMMMMMMMMMMMMMMMMM P
+ # P MMMMMMMMMMMMMMMMMM P
+ # ^ P P
+ # | P P
+ # yoffset | P P
+ # | P P
+ # v PPPPPPPPPPPPPPPPPPPPPPPP
+ # <->xoffset
+ #
+
+ # NB: text_width and text_height must match the definitions of the
+ # PostScript values TextWidth and TextHeight below
+ text_width = width - 2*margin_width - 2*border_width
+ text_height = height - 2*margin_width - 2*border_width
+
+ "date" | getline current_date_and_time
+ if ("USER" in ENVIRON)
+ username = ENVIRON["USER"]
+ else if ("LOGNAME" in ENVIRON)
+ username = ENVIRON["LOGNAME"]
+ else
+ username = "unknown"
+ "awk -F: '/^" username "/ {print $5}' /etc/passwd" | \
+ getline personal_name
+ "hostname" | getline hostname
+
+ print "%!PS-Adobe-3.0 EPSF-3.0"
+ printf("%%%%Title: psposter")
+ for (k = 1; k < ARGC; ++k)
+ printf(" %s",OLD_ARGV[k])
+ print ""
+
+ print "%%CreationDate:", current_date_and_time
+ print "%%Creator: psposter", VERSION
+ print "%%For: " personal_name " <" username "@" hostname ">"
+ print "%%BoundingBox:", \
+ floor(x_offset + ScaleFactor * margin_width), \
+ floor(y_offset + ScaleFactor * margin_width), \
+ ceil(x_offset + \
+ ScaleFactor * (margin_width + text_width + 2*border_width)), \
+ ceil(y_offset + \
+ ScaleFactor * (margin_width + text_height + 2*border_width))
+ print "%%DocumentMedia:", paper_name, \
+ ceil(paper_width), ceil(paper_height), "() () ()"
+ print "%%DocumentData: Clean7Bit"
+ print "%%DocumentFonts: font",font_name
+ print "%%DocumentNeededResources: font", font_name
+ print "%%Orientation:", (landscape ? "Landscape" : "Portrait")
+ print "%%PageOrder: Ascend"
+ print "%%Pages: 1"
+ print "%%EndComments"
+ print "%======================================================================="
+ print "%%BeginProlog"
+ print "/psposterdict 50 dict def"
+ print "psposterdict begin"
+ print "/inch { 72 mul } def"
+ print "/BackgroundColor {", getcolor(background), "} def %",background
+ print "/BaselineSkipFactor", baseline_skip, "def"
+ print "/BorderColor {", getcolor(border_color), "} def %",border_color
+ print "/BorderWidth", border_width, "def"
+ print "/CapHeight"
+ print "{"
+ print "\tgsave newpath 0 0 moveto (M) true charpath pathbbox"
+ print "\texch pop sub neg exch pop grestore"
+ print "} def"
+ print "/ForegroundColor {", getcolor(foreground), "} def %",foreground
+ if (angle != "") # "+rotation angle" overrides "+l"
+ landscape = (angle / 90) % 2
+ print "/LandscapeMode", (landscape ? "true" : "false"), "def"
+ print "/MarginWidth", margin_width, "def"
+ print "/PageHeight", paper_height, "def"
+ print "/PageWidth", paper_width, "def"
+ print "/Height", height, "def"
+ print "/Width", width, "def"
+ print "/PointSize", point_size, "def"
+ print "/ROTATE_0 {} def"
+ print "/ROTATE_90 {Width 0 translate 90 rotate} bind def"
+ print "/ROTATE_180 {Width Height translate 180 rotate} bind def"
+ print "/ROTATE_270 {0 Height translate 270 rotate} bind def"
+ print "/ScaleFactor", ScaleFactor, "def"
+
+ print "LandscapeMode"
+ print "{"
+ print "\t/TextHeight Width MarginWidth 2 mul sub BorderWidth 2 mul sub def"
+ print "\t/TextWidth Height MarginWidth 2 mul sub BorderWidth 2 mul sub def"
+ print "}"
+ print "{"
+ print "\t/TextHeight Height MarginWidth 2 mul sub BorderWidth 2 mul sub def"
+ print "\t/TextWidth Width MarginWidth 2 mul sub BorderWidth 2 mul sub def"
+ print "}"
+ print "ifelse"
+
+ print "/XOffset", x_offset, "def"
+ print "/YOffset", y_offset, "def"
+
+ print "% Center and show a string at the current point, leaving"
+ print "% point at the center of the next line."
+ print "% Usage: (string) cshow"
+ print "/cshow"
+ print "{"
+ print "\tcurrentpoint /cpy exch def /cpx exch def"
+ print "\tdup stringwidth pop 0.5 mul neg 0 rmoveto show"
+ print "\tcpx cpy moveto"
+ print "\tNewLine"
+ print "} def"
+
+ print "/max"
+ print "{"
+ print "\t/a exch def"
+ print "\t/b exch def"
+ print "\ta b gt { a } { b } ifelse"
+ print "} def"
+
+ print "/min"
+ print "{"
+ print "\t/a exch def"
+ print "\t/b exch def"
+ print "\ta b lt { a } { b } ifelse"
+ print "} def"
+
+ print "/TheFont /" font_name " def"
+
+ print "% Set the font size so that longest PosterLines string fills the TextWidth"
+ print "% Usage: setfontsize"
+ print "/setfontsize"
+ print "{"
+ print "\tTheFont findfont 10 scalefont setfont"
+ print "\t% Set TheFontSize according to maximum string width"
+ print "\t0 PosterLines { stringwidth pop max } forall TextWidth exch div 10 mul"
+ print "\t/TheFontSize exch def"
+ print "\t% Adjust TheFontSize according to the number of text lines"
+ print "\tLineCount TheFontSize mul BaselineSkipFactor mul"
+ print "\tTextHeight div"
+ print "\tdup 1 gt { TheFontSize exch div /TheFontSize exch def } { pop } ifelse"
+ if (point_size > 0) # override
+ {
+ print "\t% NB: The following definition silently overrides the previous one"
+ print "\t/TheFontSize PointSize def"
+ }
+ print "\t/BaselineSkip BaselineSkipFactor TheFontSize mul def"
+ print "\tTheFont findfont TheFontSize scalefont setfont"
+ print "} def"
+
+ print "/NewLine {0 BaselineSkip neg rmoveto} def"
+
+ print "/PosterLines"
+ print "["
+ for (k = 1; k <= n; ++k)
+ print "\t(" word[k] ")"
+ print "] def"
+ print "/LineCount PosterLines length 1 max def"
+ if (make_font_table)
+ print_font_table_macros()
+ print "end % psposterdict"
+ print "%%EndProlog"
+
+ print "%======================================================================="
+ print "%%BeginSetup"
+ print "/#copies", copies," def"
+
+ # Now see if we have a font that must be downloaded. If we do not
+ # find it, we silently assume that it is a resident font on the
+ # output PostScript device. AFMMAPFILE lines look like this:
+ # ZapfChancery-MediumItalic = ZapChaMI % Optional comment
+
+ if (AFMMAPFILE == "")
+ mapline = ""
+ else
+ "grep 2>/dev/null \"^" font_name "[ \t]\" " AFMMAPFILE | getline mapline
+
+ k = index(mapline,"=")
+ if (k > 0) # copy font using mapped filename
+ {
+ basename = substr(mapline,k+1)
+ gsub(/%.*$/,"",basename) # discard inline comment
+ gsub(/[ \t]/,"",basename) # and spaces
+ }
+ else # try to copy font using native file name
+ basename = font_name
+
+ filename = find_file(afmpath, basename ".pfa")
+ if (filename == "")
+ filename = find_file(afmpath, basename ".pfb")
+ if (filename == "")
+ filename = find_file(afmpath, basename ".pfa.gz")
+ if (filename == "")
+ filename = find_file(afmpath, basename ".pfa.Z")
+ if (filename == "")
+ filename = find_file(afmpath, basename ".pfb.gz")
+ if (filename == "")
+ filename = find_file(afmpath, basename ".pfb.Z")
+ if (filename != "") # download the font
+ copyfont(filename)
+
+ print "%%EndSetup"
+
+ print "%======================================================================="
+ print "%%Page: 1 1"
+ print "%%BeginPageSetup"
+ print "psposterdict begin"
+ print "XOffset YOffset translate"
+ print "ScaleFactor dup scale"
+ print "ROTATE_" (angle + 0)
+ print "end % psposterdict"
+ print "%%EndPageSetup"
+ print ""
+ print "psposterdict begin"
+ print "% Draw a frame box and fill it with the background color, and a border color."
+ print "BorderWidth setlinewidth"
+ print "newpath"
+ print "MarginWidth BorderWidth 0.5 mul add dup moveto"
+ print "TextWidth BorderWidth add 0 rlineto"
+ print "0 TextHeight BorderWidth add rlineto"
+ print "TextWidth BorderWidth add neg 0 rlineto"
+ print "closepath"
+ print "BackgroundColor setrgbcolor gsave fill grestore"
+ print "BorderColor setrgbcolor stroke"
+
+ print ""
+ print "0 0 0 setrgbcolor % revert to black"
+
+ print ""
+ print "% Set the clipping path to the text region"
+ print "0 setlinewidth"
+ print "newpath"
+ print "MarginWidth BorderWidth add dup moveto"
+ print "TextWidth 0 rlineto"
+ print "0 TextHeight rlineto"
+ print "TextWidth neg 0 rlineto"
+ print "closepath"
+ print "clip"
+
+ print ""
+ print "% Move origin to text box center, since x = 0 is a convenient"
+ print "% value for centering text."
+ print "LandscapeMode"
+ print "\t{ Height 0.5 mul Width 0.5 mul translate }"
+ print "\t{ Width 0.5 mul Height 0.5 mul translate }"
+ print "ifelse"
+
+ if (make_font_table)
+ {
+ print "% Typeset the poster text."
+ print "TheFont MakeFontTable"
+ }
+ else
+ {
+ print "% Set font size so that the longest line just fills the TextWidth."
+ print "setfontsize"
+ print "% Center the text vertically, such that the middle line has its text"
+ print "% (rather than baseline distance) centered on a horizontal line"
+ print "% passing through the center of the picture."
+ print "0 LineCount 0.5 mul BaselineSkip mul BaselineSkip sub moveto"
+
+ print "0 BaselineSkip CapHeight sub 0.5 mul rmoveto"
+
+ print "ForegroundColor setrgbcolor"
+ print "% Typeset the poster text."
+ print "PosterLines { cshow } forall"
+ }
+ print "end % psposterdict"
+ print "showpage"
+ print "%%PageTrailer"
+
+ if (display_fontsize)
+ {
+ print "%%Page: 2 2"
+ print "%%BeginPageSetup"
+ print "psposterdict begin"
+ print "/tempstr 25 string def"
+ print "/Courier findfont 20 scalefont setfont"
+ print "/BaselineSkip 20 1.2 mul def"
+ print "72 PageHeight 2 div moveto"
+ print "(Set font pointsize by) show"
+ print "/Courier-BoldOblique findfont 20 scalefont setfont"
+ print "( +p ) show"
+ print "TheFontSize ScaleFactor div tempstr cvs show"
+ print "(bp) show"
+ print "showpage"
+ print "end % psposterdict"
+ print "%%PageTrailer"
+ }
+
+ print "%======================================================================="
+ print "%%Trailer"
+ print "%%EOF"
+
+ exit (0) # all done (no command-line words are files)
+}
+
+function author()
+{
+ print \
+ "Author:\n" \
+ "\tNelson H. F. Beebe\n" \
+ "\tCenter for Scientific Computing\n" \
+ "\tDepartment of Mathematics\n" \
+ "\tUniversity of Utah\n" \
+ "\tSalt Lake City UT 84112\n" \
+ "\tUSA\n" \
+ "\tTel: +1 801 581 5254\n" \
+ "\tFAX: +1 801 581 4801\n" \
+ "\tEmail: <beebe@math.utah.edu>\n"
+ url()
+ exit (0)
+}
+
+function bigpoint(dimension)
+{
+ return (72 * inch(dimension))
+}
+
+function ceil(x, n)
+{
+ n = int(x)
+ if (n < x) ++n
+ return (n)
+}
+
+function copyfont(filename, filter,fontline)
+{
+ # NB: .pfb files are binary: gawk can copy them, but nawk cannot.
+ # Even so, before the font can be included in a PostScript file,
+ # it must be converted to ASCII form. We therefore invoke t1ascii
+ # on-the-fly to handle the conversion, plus gunzip or uncompress,
+ # if needed for decompression. t1ascii writes a version banner
+ # to stderr, so we redirect it to /dev/null.
+
+ print "%%BeginResource: font " font_name
+ if (filename ~ /.pfb$/) # convert from .pfb to .pfa on-the-fly
+ filter = "t1ascii 2>/dev/null " filename
+ else if (filename ~ /.pfa.gz$/) # convert from .pfa.gz to .pfa on-the-fly
+ filter = "gunzip <" filename
+ else if (filename ~ /.pfb.gz$/) # convert from .pfb.gz to .pfa on-the-fly
+ filter = "gunzip <" filename " | t1ascii 2>/dev/null "
+ else if (filename ~ /.pfa.Z$/) # convert from .pfa.Z to .pfa on-the-fly
+ filter = "uncompress <" filename
+ else if (filename ~ /.pfb.Z$/) # convert from .pfb.Z to .pfa on-the-fly
+ filter = "uncompress <" filename " | t1ascii 2>/dev/null "
+ else
+ filter = "cat " filename
+ print "% file:", filename
+ if (filter !~ /^cat /) print "% filter:", filter
+ while (filter | getline fontline)
+ print fontline
+ close (filter)
+ print "% font:",font_name
+ print "% file:",filename
+ print "%%EndResource"
+}
+
+function copyright()
+{
+ print \
+ "*********************************************\n" \
+ "*********************************************\n" \
+ "*** This program is in the PUBLIC DOMAIN. ***\n" \
+ "*********************************************\n" \
+ "*********************************************\n"
+ url()
+ exit (0)
+}
+
+function error(message)
+{
+ print message > "/dev/tty"
+ exit (1)
+}
+
+function file_exists(filename)
+{
+ # Unfortunately, getline in both nawk and gawk will hang if its
+ # file does not exist, so we need to test for file existence by
+ # invoking a shell command, sigh...
+
+ return (system("test -f " filename) == 0)
+}
+
+function find_file(path,filename, fullname,k)
+{
+ for (k = 1; k in path; ++k)
+ {
+ fullname = path[k] "/" filename
+ if (file_exists(fullname))
+ return (fullname)
+ }
+ return ("")
+}
+
+function floor(x, n)
+{
+ n = int(x)
+ if (n > x) --n
+ return (n)
+}
+
+function getcolor(value)
+{ # value is e.g. "0.5/0.25/0.9" or "yellow"
+ if (value ~ /[A-Za-z]/) # named color
+ {
+ if (RGBTXTFILE == "")
+ rgbline = "0 0 0" # default to black
+ else
+ ("grep 2>/dev/null -i '^[0-9 \t]*" value "[ \t]*$' " RGBTXTFILE) | \
+ getline rgbline
+ split(rgbline,rgb," ")
+ value = (rgb[1] / 255) " " (rgb[2] / 255) " " (rgb[3] / 255)
+ }
+ else # expect numbered color
+ gsub(/[^0-9.]/," ",value) # eliminate punctuation
+ return (value)
+}
+
+function inch(units, value)
+{
+ value = units + 0 # coerce to number
+
+ if (units ~ "[-+]?[0-9]+[.]?[0-9]*bp") # big points
+ value /= 72.0
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*in") # inches
+ ; # NO-OP
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*cm") # centimeters
+ value /= 2.54
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*pt") # points
+ value /= 72.27
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*cc") # cicero
+ value *= 12.0 * (1238.0 / 1157.0) / 72.27
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*dd") # didot points
+ value *= (1238.0 / 1157.0) / 72.27
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*mm") # millimeters
+ value /= 25.4
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*pc") # pica
+ value *= 12.0 / 72.27
+ else if (units ~ "[-+]?[0-9]+[.]?[0-9]*sp") # scaled points
+ value /= (65536.0 * 72.27)
+ else
+ error("unrecognized dimension " units)
+ return (value)
+}
+
+function initialize_paper_table()
+{
+ # name width height left right bottom top
+
+ # ANSI (note that B folded in half becomes A, etc.) (portrait)
+
+ paper["A"] = "8.5in 11in 1in 1in 1in 1in"
+ paper["B"] = "11in 17in 1in 1in 1in 1in"
+ paper["C"] = "17in 22in 1in 1in 1in 1in"
+ paper["D"] = "22in 34in 1in 1in 1in 1in"
+ paper["E"] = "34in 44in 1in 1in 1in 1in"
+
+ # Common US designations (portrait)
+
+ paper["Computer-1411"] = "14in 11in 1in 1in 1in 1in"
+ paper["Legal"] = "8.5in 13in 1in 1in 1in 1in"
+ paper["Letter"] = "8.5in 11in 1in 1in 1in 1in"
+ paper["US-Legal"] = "8.5in 14in 1in 1in 1in 1in"
+
+ # Common US designations (landscape)
+
+ paper["A-L"] = "11in 8.5in 1in 1in 1in 1in"
+ paper["Computer-1411-L"] = "11in 14in 1in 1in 1in 1in"
+ paper["Legal-L"] = "13in 8.5in 1in 1in 1in 1in"
+ paper["Letter-L"] = "11in 8.5in 1in 1in 1in 1in"
+ paper["US-Legal-L"] = "14in 8.5in 1in 1in 1in 1in"
+
+ # Additional paper and envelope sizes taken from <<Hewlett-Packard
+ # LaserJet Family Paper Specification Guide>> (1992).
+
+ paper["COM10"] = "4.1in 9.5in 1in 1in 1in 1in"
+ paper["DL"] = "110mm 220mm 25mm 25mm 25mm 25mm"
+ paper["Executive"] = "7.25in 10.5in 1in 1in 1in 1in"
+ paper["Monarch"] = "3.9in 7.5in 1in 1in 1in 1in"
+
+ # Miscellaneous and Imagen Ultrascript paper sizes
+
+ paper["A4Small"] = "210mm 297mm 25mm 25mm 25mm 25mm"
+ paper["Ledger"] = "11in 17in 1in 1in 1in 1in"
+ paper["LetterSmall"] = "8.5in 11in 1in 1in 1in 1in"
+ paper["Note"] = "8.5in 11in 1in 1in 1in 1in"
+
+ # ISO standard paper A-series (portrait). Note that Xn folded in half
+ # becomes Xn+1 (X = A, B, C)
+
+ paper["A0"] = "841mm 1189mm 25mm 25mm 25mm 25mm"
+ paper["A1"] = "594mm 841mm 25mm 25mm 25mm 25mm"
+ paper["A2"] = "420mm 594mm 25mm 25mm 25mm 25mm"
+ paper["A3"] = "297mm 420mm 25mm 25mm 25mm 25mm"
+ paper["A4"] = "210mm 297mm 25mm 25mm 25mm 25mm"
+ paper["A5"] = "148mm 210mm 25mm 25mm 25mm 25mm"
+ paper["A6"] = "105mm 148mm 25mm 25mm 25mm 25mm"
+ paper["A7"] = "74mm 105mm 25mm 25mm 25mm 25mm"
+ paper["A8"] = "52mm 74mm 25mm 25mm 25mm 25mm"
+ paper["A9"] = "37mm 52mm 25mm 25mm 25mm 25mm"
+ paper["A10"] = "26mm 37mm 25mm 25mm 25mm 25mm"
+
+ # ISO standard paper A-series (landscape). Note that the final L
+ # is NOT prefixed by a hyphen.
+
+ paper["A0L"] = "1189mm 841mm 25mm 25mm 25mm 25mm"
+ paper["A1L"] = "841mm 594mm 25mm 25mm 25mm 25mm"
+ paper["A2L"] = "594mm 420mm 25mm 25mm 25mm 25mm"
+ paper["A3L"] = "420mm 297mm 25mm 25mm 25mm 25mm"
+ paper["A4L"] = "297mm 210mm 25mm 25mm 25mm 25mm"
+ paper["A5L"] = "210mm 148mm 25mm 25mm 25mm 25mm"
+ paper["A6L"] = "148mm 105mm 25mm 25mm 25mm 25mm"
+ paper["A7L"] = "105mm 74mm 25mm 25mm 25mm 25mm"
+ paper["A8L"] = "74mm 52mm 25mm 25mm 25mm 25mm"
+ paper["A9L"] = "52mm 37mm 25mm 25mm 25mm 25mm"
+ paper["A10L"] = "37mm 26mm 25mm 25mm 25mm 25mm"
+
+ # ISO intermediate paper B-series (portrait)
+
+ paper["B0"] = "1000mm 1414mm 25mm 25mm 25mm 25mm"
+ paper["B1"] = "707mm 1000mm 25mm 25mm 25mm 25mm"
+ paper["B2"] = "500mm 707mm 25mm 25mm 25mm 25mm"
+ paper["B3"] = "353mm 500mm 25mm 25mm 25mm 25mm"
+ paper["B4"] = "250mm 353mm 25mm 25mm 25mm 25mm"
+ paper["B5"] = "176mm 250mm 25mm 25mm 25mm 25mm"
+ paper["B6"] = "125mm 176mm 25mm 25mm 25mm 25mm"
+
+ # ISO intermediate paper B-series (landscape)
+
+ paper["B0L"] = "1414mm 1000mm 25mm 25mm 25mm 25mm"
+ paper["B1L"] = "1000mm 707mm 25mm 25mm 25mm 25mm"
+ paper["B2L"] = "707mm 500mm 25mm 25mm 25mm 25mm"
+ paper["B3L"] = "500mm 353mm 25mm 25mm 25mm 25mm"
+ paper["B4L"] = "353mm 250mm 25mm 25mm 25mm 25mm"
+ paper["B5L"] = "250mm 176mm 25mm 25mm 25mm 25mm"
+ paper["B6L"] = "176mm 125mm 25mm 25mm 25mm 25mm"
+
+ # ISO envelopes for A-series
+
+ paper["C0"] = "1294mm 916mm 25mm 25mm 25mm 25mm"
+ paper["C1"] = "916mm 647mm 25mm 25mm 25mm 25mm"
+ paper["C2"] = "647mm 458mm 25mm 25mm 25mm 25mm"
+ paper["C3"] = "458mm 323mm 25mm 25mm 25mm 25mm"
+ paper["C4"] = "323mm 229mm 25mm 25mm 25mm 25mm"
+ paper["C5"] = "229mm 161mm 25mm 25mm 25mm 25mm"
+ paper["C6"] = "161mm 114mm 25mm 25mm 25mm 25mm"
+
+ # British paper sizes (some are also used in the USA)
+
+ paper["Octavo"] = "5in 8in 1in 1in 1in 1in"
+ paper["Sixmo"] = "6.5in 8in 1in 1in 1in 1in"
+ paper["Quarto"] = "8in 10in 1in 1in 1in 1in"
+ paper["Foolscap"] = "8.5in 13in 1in 1in 1in 1in"
+ paper["Government-legal"] = "8.5in 13in 1in 1in 1in 1in"
+ paper["Folio"] = "8.3in 13in 1in 1in 1in 1in"
+}
+
+function parse_table_type(s, parts,t)
+{
+ t = s
+ gsub(/[^0-9A-Za-z]/," ",t)
+ split(t,parts," ")
+ table_columns = 0 + parts[1]
+ label_base = (parts[2] ~ /^[oO]$/) ? 8 : ((parts[2] ~ /^[hH]$/) ? 16 : 0)
+ if (((table_columns != 8) && (table_columns != 16)) || \
+ ((label_base != 8) && (label_base != 16)))
+ {
+ warning("Unrecognized +table value `" s \
+ "': expected one of 8/o 16/o 8/h 16/h. Defaulting to 8/o.")
+ parse_table_type("8/o")
+ }
+ make_font_table = s
+}
+
+function print_font_table_macros()
+{
+ print "/Black { 0 0 0 } def"
+ print "/LabelBase " label_base " def"
+ print "/TableColumns " table_columns " def"
+ print "/LabelChars 3 def % 0x3_ or \\12_; 3 looks better than 4"
+ print "/RowChars TableColumns def"
+ print "/TheRow RowChars string def % 8 or 16 characters"
+ print "/TitleLines TableColumns 8 eq LabelBase 16 eq and { 3 } { 2 } ifelse def"
+ print "/TableLines 256 TableColumns div TitleLines add def % 16 or 32 char rows and 2 or 3 title rows"
+ print "PointSize 0 eq"
+ print "\t{"
+ print "\t\t/dx"
+ print "\t\t\tTextWidth RowChars LabelChars add div"
+ print "\t\t\tTextHeight TableLines BaselineSkipFactor mul div"
+ print "\t\t\tmin"
+ print "\t\t\tcvi"
+ print "\t\tdef"
+ print "\t}"
+ print "\t{"
+ print "\t\t/dx PointSize def"
+ print "\t}"
+ print "ifelse"
+ print "/TheFontSize dx def"
+ print "/BaselineSkip BaselineSkipFactor TheFontSize mul def"
+ print "/LabelWidth dx LabelChars mul def"
+ print "/TableHeight BaselineSkip TableLines mul def"
+ print "/TableWidth dx 2 mul RowChars mul dx add LabelWidth add def"
+ print "/TitleBoxHeight BaselineSkip TitleLines mul def"
+ print ""
+ print "/KernShow"
+ print "{ % Usage: (string) KernShow % show with characters of width 2*dx"
+ print "\tSavePosition"
+ print "\t{ % stack: c(n) c(n+1)"
+ print "\t\tpop pop"
+ print "\t\t/x x dx 2 mul add def"
+ print "\t\tx y moveto"
+ print "\t}"
+ print "\texch kshow"
+ print "} def"
+ print "/MakeFontTable"
+ print "{ % Usage: /fontname MakeFontTable"
+ print " % (0,0) is at page center"
+ print "\tfindfont TheFontSize scalefont setfont"
+ print "\tTableWidth -2 div TableHeight 2 div moveto"
+ print "\tShowTableTitle"
+ print "\tgsave"
+ print "\t\tSetLabelFont"
+ print "\t\tSetLabelColor"
+ print "\t\tLabelWidth dx add 0 rmoveto"
+ print "\t\tTableColumns 16 eq"
+ print "\t\t\t{"
+ print "\t\t\t\tLabelBase 16 eq"
+ print "\t\t\t\t\t{(0123456789abcdef)}"
+ print "\t\t\t\t\t{(0123456701234567)}"
+ print "\t\t\t\tifelse"
+ print "\t\t\t}"
+ print "\t\t\t{"
+ print "\t\t\t\t(01234567)"
+ print "\t\t\t}"
+ print "\t\tifelse"
+ print "\t\tKernShow"
+ print "\tgrestore"
+ print "\tTableColumns 8 eq LabelBase 16 eq and"
+ print "\t\t{"
+ print "\t\t\tNewLine"
+ print "\t\t\tgsave"
+ print "\t\t\t\tSetLabelFont"
+ print "\t\t\t\tSetLabelColor"
+ print "\t\t\t\tLabelWidth dx add 0 rmoveto"
+ print "\t\t\t\t(89abcdef) KernShow"
+ print "\t\t\tgrestore"
+ print "\t\t}"
+ print "\tif"
+ print "\tSavePosition"
+ print "\t1 setlinewidth"
+ print "\tSetLabelColor"
+ print "\tx y TitleBoxHeight add TableWidth ShowHorizontalRule"
+ print "\tx y TableWidth ShowHorizontalRule"
+ print "\tx y TitleBoxHeight add TableHeight ShowVerticalRule"
+ print "\tx LabelWidth add y TitleBoxHeight add TableHeight ShowVerticalRule"
+ print "\tx TableWidth add y TitleBoxHeight add TableHeight ShowVerticalRule"
+ print "\tTableColumns 16 eq"
+ print "\t\t{"
+ print "\t\t\tx LabelWidth add TableWidth LabelWidth sub 2 div add"
+ print "\t\t\ty TableHeight TitleBoxHeight sub ShowVerticalRule"
+ print "\t\t}"
+ print "\tif"
+ print "\tx y moveto"
+ print "\tNewLine"
+ print "\tForegroundColor setrgbcolor"
+ print "\tShowCharacterTable"
+ print "\tSetLabelColor"
+ print "\tReverseNewline"
+ print "\tx y TableWidth ShowHorizontalRule"
+ print "} def"
+ print "\t/NewLine {0 BaselineSkip neg rmoveto SavePosition} def"
+ print "/ReverseNewline {0 BaselineSkip rmoveto SavePosition} def"
+ print "/RuleVerticalOffset BaselineSkip -0.2 mul def"
+ print "/SavePosition { currentpoint /y exch def /x exch def } def"
+ print "/SetLabelColor { Black setrgbcolor } def"
+ print "/SetLabelFont"
+ print "{"
+ print "\t/Times-BoldItalic findfont TheFontSize scalefont setfont"
+ print "} def"
+ print "/ShowCharacterTable"
+ print "{"
+ print "\t0 TableColumns 255"
+ print "\t{"
+ print "\t\t/n exch def"
+ print "\t\tn 8#100 mod 8#070 eq"
+ print "\t\t{"
+ print "\t\t\tgsave"
+ print "\t\t\t SetLabelColor"
+ print "\t\t\t x y TableWidth ShowHorizontalRule"
+ print "\t\t\tgrestore"
+ print "\t\t} if"
+ print "\t\tShowRowLabel"
+ print "\t\tgsave"
+ print "\t\t\tLabelWidth dx add 0 rmoveto"
+ print "\t\t\tShowRow"
+ print "\t\tgrestore"
+ print "\t\tNewLine"
+ print "\t} for"
+ print "} def"
+ print "/ShowHorizontalRule"
+ print "{ % Usage: x y len ShowHorizontalRule"
+ print "\tgsave"
+ print "\t\t/r exch def"
+ print "\t\tnewpath"
+ print "\t\t\tmoveto"
+ print "\t\t\t0 RuleVerticalOffset rmoveto"
+ print "\t\t\tr 0 rlineto"
+ print "\t\tstroke"
+ print "\tgrestore"
+ print "} def"
+ print "/ShowRow"
+ print "{ % Usage: ShowRow"
+ print "\tgsave"
+ print "\t\t0 1 TableColumns 1 sub"
+ print "\t\t{"
+ print "\t\t\t/k exch def"
+ print "\t\t\tTheRow k n k add put % char"
+ print "\t\t} for % create character row"
+ print "\t\tSavePosition"
+ print "\t\tTheRow KernShow"
+ print "\tgrestore"
+ print "} def"
+ print "/ShowRowLabel"
+ print "{ % Usage: ShowRowLabel"
+ print "\tcurrentpoint"
+ print "\tgsave"
+ print "\t\tSetLabelColor"
+ print "\t\tSetLabelFont"
+ print "\t\tLabelBase 16 eq"
+ print "\t\t\t{"
+ print "\t\t\t\t/TempStr 5 string def"
+ print "\t\t\t\tTempStr 0 ( ) putinterval"
+ print "\t\t\t\tn 16 idiv 8#10000 add 16 TempStr cvrs pop"
+ print "\t\t\t\t/k 0 def"
+ print "\t\t\t\tTempStr"
+ print "\t\t\t\t{ % convert to lowercase"
+ print "\t\t\t\t\tdup dup 8#100 ge exch 8#107 le and { 32 add } if"
+ print "\t\t\t\t\tTempStr exch k exch put"
+ print "\t\t\t\t\t/k k 1 add def"
+ print "\t\t\t\t} forall"
+ print "\t\t\t\tTempStr 0 (\\\\0x) putinterval"
+ print "\t\t\tTempStr 4 (_) putinterval"
+ print "\t\t\t}"
+ print "\t\t\t{"
+ print "\t\t\t\t/TempStr 4 string def"
+ print "\t\t\t\tTempStr 0 ( ) putinterval"
+ print "\t\t\t\tn 8 idiv 8#100 add 8 TempStr cvrs pop"
+ print "\t\t\t\tTempStr 0 (\\\\) putinterval"
+ print "\t\t\t\tTempStr 3 (_) putinterval"
+ print "\t\t\t}"
+ print "\t\tifelse"
+ print "\t\tLabelWidth 2 div 0 rmoveto"
+ print "\t\tTempStr cshow"
+ print "\tgrestore"
+ print "\tmoveto"
+ print "\tSavePosition"
+ print "} def"
+ print "/ShowTableTitle"
+ print "{ % Usage: ShowTableTitle"
+ print "\tNewLine"
+ print "\tgsave"
+ print "\t\tSetLabelColor"
+ print "\t\tSetLabelFont"
+ print "\t\tLabelWidth 0 rmoveto"
+ print "\t\tTableWidth LabelWidth sub 2 div 0 rmoveto"
+ print "\t\t% Create centered title, e.g. 23bp FontName"
+ print "\t\t/TitleString TheFont length 5 add string def"
+ print "\t\tTitleString 0 TheFontSize 4 string cvs putinterval"
+ print "\t\tTitleString 2 (bp ) putinterval"
+ print "\t\tTitleString 5 TheFont dup length string cvs putinterval"
+ print "\t\tTitleString cshow"
+ print "\tgrestore"
+ print "\tNewLine"
+ print "} def"
+ print "/ShowVerticalRule"
+ print "{ % Usage: x y len ShowVerticalRule"
+ print "\tgsave"
+ print "\t\t/r exch def"
+ print "\t\tnewpath"
+ print "\t\t\tmoveto"
+ print "\t\t\t0 RuleVerticalOffset rmoveto"
+ print "\t\t\t0 r neg rlineto"
+ print "\t\tstroke"
+ print "\tgrestore"
+ print "} def"
+}
+
+function set_paper_dimensions(name, n,swap,value)
+{
+ if (name in paper)
+ {
+ n = split(paper[name],value," ")
+ if (n == 6)
+ {
+ paper_name = name
+ paper_width = bigpoint(value[1])
+ paper_height = bigpoint(value[2])
+ paper_left = bigpoint(value[3])
+ paper_right = bigpoint(value[4])
+ paper_bottom = bigpoint(value[5])
+ paper_top = bigpoint(value[6])
+ }
+ else
+ error("internal error: corrupt paper dimensions for paper type " name)
+ }
+ else
+ { # expect something like 8.5inx11in
+ n = split(name,value,"x")
+ if (n == 2)
+ {
+ paper_name = name
+ paper_width = bigpoint(value[1])
+ paper_height = bigpoint(value[2])
+ paper_left = bigpoint("1in")
+ paper_right = bigpoint("1in")
+ paper_bottom = bigpoint("1in")
+ paper_top = bigpoint("1in")
+ }
+ else
+ error("unrecognized paper type " name)
+ }
+ if (paper_width > paper_height)
+ landscape = 1
+}
+
+function url()
+{
+ print \
+ "Internet source distribution:\n" \
+ "\tURL: ftp://ftp.math.utah.edu/pub/misc/psposter-" \
+ VERSION_NUMBER ".tar.z\n" \
+ "\tURL: ftp://ftp.math.utah.edu/pub/misc/psposter-" \
+ VERSION_NUMBER ".zip\n" \
+ "\tURL: ftp://ftp.math.utah.edu/pub/misc/psposter-" \
+ VERSION_NUMBER ".zoo"
+}
+
+
+function usage()
+{
+ print "Usage: psposter [+option value] ... word1 word2 ..."
+ print ""
+ print "Recognized options are:"
+ print "\t+author display program author and quit"
+ print "\t+bd color set border color"
+ print "\t+bg color set background color"
+ print "\t+bs factor set baselineskip to factor times font pointsize"
+ print "\t+bw dimension set border width"
+ print "\t+c nnn number of copies to print"
+ print "\t+copyright display program copyright and quit"
+ print "\t+d display font pointsize on second page"
+ print "\t+fg color set foreground color"
+ print "\t+fn fontname select PostScript font"
+ print "\t+h dimension poster height"
+ print "\t+help display this message and quit"
+ print "\t+l landscape (instead of portrait) orientation"
+ print "\t+mw dimension set margin width"
+ print "\t+p dimension set font pointsize"
+ print "\t+paper form set paper size"
+ print "\t+r angle set text rotation angle in degrees (only multiples of 90)"
+ print "\t+s factor set poster scale factor"
+ print "\t+table {8/o | 8/h | 16/o | 16/h} show font character table"
+ print "\t+version display program version and quit"
+ print "\t+w dimension set poster width"
+ print "\t+x dimension set x offset"
+ print "\t+y dimension set y offset"
+ print "\t? display this message and quit"
+ print "\t++ no more options: remaining words are for poster text"
+ print ""
+ print "Any command-line arguments that are not recognized as options will be"
+ print "typeset on the poster, one argument per line. If no poster text words"
+ print "are supplied on the command line, then poster lines are read from"
+ print "standard input."
+ print ""
+ print "Color names may be any named X Window System color, or red/green/blue"
+ print "values in 0..1 separated by characters other than digits or period."
+ print "E.g. 0/1/0 is green, and 0.5:0.5:0.5 is 50% grey."
+ print ""
+ print "Dimensions consist of a (possibly signed) number followed by a TeX"
+ print "dimension unit: bp (big points), cc (ciceros), cm (centimeters), dd"
+ print "(didot points), in (inches), mm (millimeters), pc (picas), pt (points),"
+ print "or sp (scaled points). E.g. 72bp, 2.54cm, 67.542dd, 1in, 25.4mm,"
+ print "6.023pc, 72.27pt, and 4736286.72sp all specify a dimension of one inch."
+ print ""
+ print "Paper names may be either standard ones like A, A4, Foolscap, etc., or"
+ print "width and height dimensions separated by an x, so that 210mmx297mm and"
+ print "A4 are equivalent, and 8.5inx11in and A are too."
+
+ exit (0)
+}
+
+function version()
+{
+ print "psposter", VERSION "\n"
+ url()
+ exit (0)
+}
+
+
+function warning(message)
+{
+ print message >"/dev/tty"
+}