######################################################################## # Copyright (c) 1999 Annelise Anderson # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $Id: pcl.awk,v 1.0 1999/08/26 aanderson Exp $ ####################################################################### # pcl.awk processes files from a text editor for printing. # It adjusts line lengths using the size of the type, which it # reads from pcl codes placed in the file, and font width. It # adjusts vertical line spacing using type size. If pcl codes to # set up the printer to accept unix line endings are used, no # printing filters are necessary. It accepts four command-line # variables, TABLEN, port, land, and justify. (It attempts to # justify only fixed-width fonts, and does so imperfectly.) The # variables port and land set the default characters per line to # print for courier 12 point (10 pitch) for portrait and landscape # printing respectively; other fonts and font sizes use this info # to determine characters per line to print. BEGIN { TABLEN = " " port = 66 land = 92 justify = 0 blankline = "^[ \t]*$" orient = 0 typesize = 12 pitch = 10 } # If a block of text is marked as a table, print each record # without further processing, thus preserving white space; delete # markers. Best to put markers on separate lines. These # lines will print as blanks. /TBLB/,/TBLE/ { if ($0 ~ /TBLB/) sub(/TBLB/,"") else if ($0 ~ /TBLE/) sub(/TBLE/,"") else print ($0) next } function do_charperline() { if ( orient == 0 ) charperline = int(port * (12 / typesize) * (50.7 / fontindex)) else if ( orient == 1 ) charperline = int(land * (12 / typesize) * (50.7 / fontindex)) return } function do_charperline2() { if ( orient == 0 ) charperline = int(port * 12 / typesize) if ( orient == 1 ) charperline = int(land * 12 / typesize) return } function do_charperline3() { if ( orient == 0 ) charperline = int(port * 12 / ( 120 / pitch )) if ( orient == 1 ) charperline = int(land * 12 / ( 120 / pitch )) return } # if document has no font codes to determine charperline, set up default; # needs to be done after port and land variables become available if # they are changed on the command line { if ( charperline == "" ) do_charperline2() } # print blank lines as they occur $0 ~ blankline { print } # preserve initial spaces and tabs; substitute spaces for tabs (change # TABLEN above to adjust). Split lines into an array of words; put two # spaces after words ending with most punctuation marks, otherwise one. $0 !~ blankline { indentstr = "" if ( match($0,/^[ \t]+/ )) { indentstr = substr($0,RSTART,RLENGTH ) gsub(/\t/,TABLEN,indentstr ) } nf = split( $0, word, "[ \t]+" ) { for ( i = 1; i <= nf; i++ ) { if (word[i] ~ /[.?!:;]$/ ) line = sprintf( "%s%s", word[i] , " " ) else line = sprintf( "%s%s", word[i], " " ) oldline = newline if (( i == 1 ) && (indentstr != "" )) newline = indentstr line else newline = newline line # get and save orientation (landscape or portrait) orientstr = $0 while (match(orientstr,/&l[01]O/)) { orient = substr(orientstr,RSTART + 2, 1) orientstr = substr(orientstr,RSTART + RLENGTH) } # get the printer font codes and save the font size; calculate the # length of the printer font and other codes so it can be deducted # from permissible line length codelen = 0 # do all short code lengths strline = newline while ( match(strline,/[&(][a-z][-+]?[0-9]*[A-Z@]/ )) { codelen += RLENGTH + 1 strline = substr(strline,RSTART + RLENGTH) } # do code lengths for fonts v or h except lineprinter if ( match(newline,/s[01]p[0-9][0-9]?[vh][0-5]s[0-4]b[0-9]+T/ )) codelen += RLENGTH + 2 # do code lengths for dj fonts with both v and h if ( match(newline,/s0p[0-9][0-9]?\.?[0-9]?[0-9]?h[0-9][0-9]?\.?[0-9]?[0-9]?v[0-5]s[0-3]b[0-9]+T/ )) { codelen += RLENGTH + 2 prop = 0 afontstr = substr(newline, RSTART, RLENGTH ) parts = split(afontstr,strparts, "[hv]" ) pitch = substr(strparts[1], 4, (length(strparts[1]) -3)) typesize = strparts[2] do_charperline3() } # all lj fixed fonts except lineprinter (no v) if ( match(newline,/s0p[0-9][0-9]?h[0-5]s[0-3]b[0-9]+T/ )) { prop = 0 pitch = substr(newline, RSTART + 3, 2) # problem? typesize = 120 / pitch do_charperline2() } # special handling for lineprinter (lj) # probably unnecessary given dj block if (match(newline,/s0p16.67h8.5v0s0b0T/)) { codelen += RLENGTH + 2 prop = 0 pitch = 16.67 typesize = 120 / 16.67 do_charperline2() } # all proportional-width fonts if ( match(newline,/s1p[0-9][0-9]?v[0-5]s[0-4]b[0-9]+T/ )) { prop = 1 typesize = substr(newline, RSTART + 3, 2) # ok fontstr = substr(newline, RSTART , RLENGTH) fontindex = 0 # may be unnec # start of font block: all univers not condensed if (fontstr ~ /v[01]s[03]b4148T|v[01]s[03]b52T/) { fontindex = 41.9 do_charperline() } # end of font block # start of font block: universcond, universcondi else if (fontstr ~ /v[45]s0b4148T/) { fontindex = 29.4 do_charperline() } # end of font block # start of font block: universboldcond, universboldcondi else if (fontstr ~ /v[45]s3b4148T/) { fontindex = 34.5 do_charperline() } # end of font block # cgtimes and times new roman, reg and ital; clarendon condensed # start of font block else if (fontstr ~ /v[01]s0b4101T|v[01]s0b16901T|v4s3b4140T/) { fontindex = 36.2 do_charperline() } # end of font block # omega, omega ital, garamond halbfett # start of font block else if (fontstr ~ /v[01]s0b4113T|v0s3b4197T/) { fontindex = 38.8 do_charperline() } # end of font block # start of font block: omegab, omegabi, arial, ariali else if (fontstr ~ /v[01]s3b4113T|v[01]s0b16602T|v0s3b16602T/) { fontindex = 40 do_charperline() } # end of font block # start of font block: coronet, marigold else if (fontstr ~ /v1s0b4116T|v0s0b4297T/) { fontindex = 22 do_charperline() } # end of font block # start of font block: cgtb, tnb, gkh, albmed else if (fontstr ~ /v0s3b4101T|v0s3b16901T|v1s3b4197T|v0s1b4362T/) { fontindex = 38.3 do_charperline() } # end of font block # start of font block: antique olive, antique olive ital # if (match(fontstr,/v[01]s0b4168T/)) else if (fontstr ~ /v[01]s0b4168T/) { fontindex = 47 do_charperline() } # end of font block # start of font block: arialbi, albextrab, symbol else if (fontstr ~ /v1s3b16602T|v0s4b4362T|v0s0b16686T/) { fontindex = 43 do_charperline() } # end of font block # start of font block: antique olive bold else if (fontstr ~ /v0s3b4168T/) { fontindex = 52.2 do_charperline() } # end of font block # if there's no font block, default else { if (orient == 0 ) charperline = int(( port * 12 ) / ( 0.7 * typesize )) if (orient == 1 ) charperline = int(( land * 12 ) / ( 0.7 * typesize )) } } # if a series of words is too long to print, drop off a word and print # that line. Get another word and test again. If the array has no more # words, print what's left. Insert code for line spacing. if ((( length( newline)) - codelen ) > charperline ) { printline = oldline newline = line if ( justify && !prop ) { # get ltrcount before more code is added, establish hmi ltrcount = length(printline) if ( ltrcount && charperline ) { hmi = 120 / (( ltrcount / (charperline + codelen)) * pitch ) hmicode = sprintf("&k%sH",hmi) } } fontmatch = 0 # next line covers vh (deskjets) too if ( match(printline,/s[01]p[0-9][0-9]?[vh][0-5]s[0-4]b[0-9]+T/ )) { fontmatch = 1 # maybe add this # print the vertical motion index code for single space printf("&l%sC" , (int((typesize +1) * 2/3)) ) typestr = substr(printline, RSTART, RLENGTH) # hmi code needs to go after typestr, before # the rest of the printline if ( justify && !prop ) { sub(typestr, typestr hmicode, printline) } } if ( !fontmatch ) { if ( justify && !prop ) # error here now (seems okay) printf("%s", hmicode) } if (printline ~ /s0p16.67h8.5v0s0b0T/) { printf("&l%sC" , (int((typesize +1) * 2/3)) ) } printf ( "%s\n", printline ) } if ( i < nf ) continue else if ( i == nf ) { # vh added here if (newline ~ /s[01]p[0-9][0-9]?[vh][0-5]s[0-4]b[0-9]+T|s0p[0-9][0-9]?\.?[0-9]?[0-9]?h[0-9][0-9]?\.?[0-9]?[0-9]?v[0-5 ]s[0-3]b[0-9]+T/ ) printf("&l%sC", (int((typesize +1) * 2/3)) ) printf ( "%s\n", newline ) newline = "" } } } }