home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- 'di';
- 'ig00';
-
- # "i2ps" text to PostScript filter written in perl by Gisle Aas, NCC 1990
- # $Id: i2ps,v 1.5 90/10/18 10:26:45 aas Exp $
- #
- # Whish list: (this may become a feature some time)
- # Marking (by some funny char) truncation and wrapping of lines
- # Faster execution (rewrite the hole thing in C?)
- # Parsing of backspace to produce bold and underlined fonts.
-
- #
- # $Log: i2ps,v $
- # Revision 1.5 90/10/18 10:26:45 aas
- # Changed the name from a2ps to i2ps. Merged the manual-page with the
- # program. I2ps now rejects garbage files. I2ps was confused about what
- # to put in the header when some of the specified files did not exist.
- # Some minor spelling corrections.
- #
- # Revision 1.4 90/10/01 15:57:46 aas
- # Simplify reencoding to ISO-Latin1. (newencode)
- # Fixed problem with showpage after page level restore. Graphic state
- # initialized on each page. Included the ISOLatin1Encoding-vector
- # in the script. Linenumber on last line when the -l option is used.
- # Linenumbers are moved to the left margin.
- #
- # Revision 1.3 90/09/27 14:05:31 aas
- # Cleaned up the use of A4 variables.
- #
- # Revision 1.2 90/09/27 13:18:31 aas
- # Removed sccs-stuff, replaced it with rcs-stuff.
- #
-
- # Some configuration constants, meassured in points (1/72 inch)
- sub page_top { 841; } # A4 = 297mm x 210mm = 841pt x 595pt
- sub page_right_edge { 595; }
- # Uncomment next line if your printer doesn't have iso encoding builtin.
- #$isoencoding_not_builtin = 1; #true
-
- # The next few entries are from the AFM file for Adobe's font Courier
- sub cour_char_width { 600; } # The width of each char in 1000x1000 square
- #sub underline_position { -82; } # Where underline goes relative to baseline
- #sub underline_thickness { 40; } # and it's thickness
-
- # Parse command line for options and flags
- $prog = substr(__FILE__,rindex(__FILE__,"/")+1,999);
- require 'getopts.pl';
- unless (&Getopts('nrth123s:b:lg')) {
- print STDERR "Usage: $prog [-<options>] [file]...\n";
- print STDERR "Options: -l print with line numbers\n";
- print STDERR " -r rotated, landscape orientation\n";
- print STDERR " -t truncate long lines, " .
- "default is to wrap lines\n";
- print STDERR " -b\"text\" replaces the text in the page header\n";
- print STDERR " -h no page headers\n";
- print STDERR " -2 set text in two columns format\n";
- print STDERR " -3 set text in three columns format\n";
- print STDERR " -s<size> select new text fontsize, default 10pt\n";
- print STDERR " -g don't reject garbage files\n";
- print STDERR " -n norwegian 7bit-ascii encoding\n";
- exit(1);
- }
-
- # Set default values, some based on command line options
- $left_margin = 80;
- $right_margin = 40;
- $tb_margin = 45;
- $font = "Courier";
- $font_size = 10; $font_size = $opt_s if ($opt_s > 0);
- $header_font = "Helvetica-Bold";
- $header_font_size = 12;
- $line_number_font = "Helvetica";
- $line_number_size = 5;
-
- $line_height = $font_size * 1.08;
- $no_columns = defined($opt_2) ? 2 : defined($opt_3) ? 3 : 1;
- $col_separation = 30;
- $sep_bars = 0; # false
- $landscape = defined($opt_r);
- $header_height = 30;
- $show_header = !defined($opt_h);
- $wrap_lines = !defined($opt_t);
- $truncate_lines = !$wrap_lines; # don't change this
- $norsk_ascii = defined($opt_n);
-
- # Some initial values
- $opt_b = &ps_string($opt_b) if ($opt_b);
- $form_feed = 0; # false;
- $page_no = 0;
- $line_no = 0;
- if ($landscape) {
- $top = &page_right_edge;
- $right_edge = &page_top;
- $left_margin = $right_margin; # this is a dirty one
- } else {
- $top = &page_top;
- $right_edge = &page_right_edge;
- }
- $home_pos = $top - $tb_margin - ($show_header ? $header_height : 0);
- $col_width = ($right_edge - $left_margin - $right_margin
- - ($no_columns - 1) * $col_separation) / $no_columns;
- $char_width = &cour_char_width * $font_size / 1000;
- $chars_per_line = int ($col_width / $char_width + 1);
-
- &prolog;
-
- unshift(@ARGV,'-') if $#ARGV < $[;
- FILE:
- while ($FILEHAND = shift) {
- unless (open(FILEHAND)) {
- print STDERR "Can't open \"$FILEHAND\"\n";
- next FILE;
- }
- if (!defined($opt_g) && -B FILEHAND) {
- print STDERR "Skipping binary file \"$FILEHAND\"\n";
- close(FILEHAND);
- next FILE;
- }
- $file_name = &ps_string($FILEHAND);
- $cur_pos = -1; # this will force a new column next time
- $cur_col = 100; # this will force a new page next time
- $line_no = 0;
- LINE:
- while (<FILEHAND>) {
- chop;
- $line_no++;
- if (ord == 014) { # form feed
- s/.//; # chop off first char
- $cur_pos = -1;
- next LINE if (length == 0);
- }
- while (s/\t/' ' x (8 - length($`) % 8)/e) {} # expand tabs
- do {
- if ($cur_pos < $tb_margin) {
- $cur_pos = $home_pos;
- if ($cur_col < $no_columns) {
- $cur_col++;
- } else {
- $cur_col = 1;
- &new_page;
- }
- }
- $text = substr($_,0,$chars_per_line);
- $_ = $truncate_lines ? '' : substr($_,$chars_per_line,10000);
- if ($text =~ s/^ +//) { # suppress leading blanks
- $indent = $char_width * length($&);
- } else {
- $indent = 0;
- }
- # Make suitable as a postscript string, same as calling
- # "ps_string", but the overhead of calling a function is
- # not acceptable here.
- $text =~ s/[\\\(\)]/\\$&/g;
- $text =~ s/[\000-\037\177-\377]/sprintf("\\%03o",ord($&))/ge;
- # Calculate position
- $x = $left_margin +
- ($cur_col - 1) * ($col_width + $col_separation);
- $cur_pos -= $line_height;
- printf "(%s)%.1f %.1f S\n", $text, $x + $indent, $cur_pos
- if (length($text));
- if ($opt_l && (($line_no % 5) == 0 || eof)) { # print line numbers
- printf "F2 SF($line_no)%.1f %.1f S F1 SF\n",
- $x + $col_width + 5, $cur_pos;
- }
- } while (length($_));
- } # while (each line)
- } # while (each file)
- &end_page;
- print "%%Trailer\n";
- print "%%Pages: $page_no\n";
- # printf "($prog: $page_no page%s for $user\n) print\n",
- # $page_no != 1 ? "s" : "";
-
- #--end of main-------------------------------------------------------
-
-
- sub prolog {
- $user = getlogin || "(unknown)";
- local($sec,$min,$hour,$mday,$mon,$year) = localtime;
- $date = sprintf("(%s %d, %d) (%2d:%02d)",
- ('January','February','March','April','May','June',
- 'July','August','October','November','Desember')[$mon],
- $mday, $year+1900, $hour,$min);
- print "%!PS-Adobe-2.0\n";
- print "%%Title: @ARGV\n" if (@ARGV);
- print <<"EOT";
- %%Creator: $prog, Text to PostScript filter in perl, (C) 1990 Gisle Aas, NCC
- %%CreationDate: $date
- %%For: $user
- %%Pages: (atend)
- EOT
- print "%%DocumentFonts: $font";
- print " $line_number_font" if ($opt_l);
- print " $header_font" if ($show_header);
- print "\n";
- print <<"EOT";
- %%EndComments
- /S{moveto show}bind def
- /M/moveto load def
- /L/lineto load def
- /SF/setfont load def
- EOT
- print <<"EOT" if ($isoencoding_not_builtin && !$norsk_ascii);
- ISOLatin1Encoding where { pop } { ISOLatin1Encoding
- [/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space
- /exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
- /parenleft/parenright/asterisk/plus/comma/minus/period/slash/zero/one
- /two/three/four/five/six/seven/eight/nine/colon/semicolon/less/equal
- /greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S
- /T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum
- /underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s
- /t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
- /.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/dotlessi/grave
- /acute/circumflex/tilde/macron/breve/dotaccent/dieresis/.notdef/ring
- /cedilla/.notdef/hungarumlaut/ogonek/caron/space/exclamdown/cent
- /sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine
- /guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus
- /twosuperior/threesuperior/acute/mu/paragraph/periodcentered/cedilla
- /onesuperior/ordmasculine/guillemotright/onequarter/onehalf/threequarters
- /questiondown/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE
- /Ccedilla/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
- /Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
- /multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn
- /germandbls/agrave/aacute/acircumflex/atilde/adieresis/aring/ae
- /ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumflex
- /idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis/divide
- /oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis]
- def %ISOLatin1Encoding
- } ifelse
- EOT
- print <<"EOT" if ($norsk_ascii);
- %%BeginProcSet: reencode 1.0 0
- /RE { %def
- findfont begin
- currentdict dup length dict begin
- { %forall
- 1 index/FID ne {def} {pop pop} ifelse
- } forall
- /FontName exch def
- dup length 0 ne { %if
- /Encoding Encoding 256 array copy def
- 0 exch { %forall
- dup type /nametype eq { %ifelse
- Encoding 2 index 2 index put
- pop 1 add
- }{%else
- exch pop
- } ifelse
- } forall
- } if pop
- currentdict dup
- end
- end
- /FontName get exch definefont pop
- } bind def
- %%EndProcSet: reencode 1.0 0
- EOT
- print <<"EOT" if (!$norsk_ascii);
- %%BeginProcSet: newencode 1.0 0
- /NE { %def
- findfont begin
- currentdict dup length dict begin
- { %forall
- 1 index/FID ne {def} {pop pop} ifelse
- } forall
- /FontName exch def
- /Encoding exch def
- currentdict dup
- end
- end
- /FontName get exch definefont pop
- } bind def
- %%EndProcSet: newencode 1.0 0
- EOT
- print "%%EndProlog\n%%BeginSetup\n";
- if ($norsk_ascii) {
- print "[8#133 /AE/Oslash/Aring 8#173 /ae/oslash/aring] dup\n";
- print "/$font-ISO/$font RE\n";
- print "/$header_font-ISO/$header_font RE\n" if ($show_header);
- } else {
- print "ISOLatin1Encoding /$font-ISO/$font NE\n";
- print "ISOLatin1Encoding /$header_font-ISO/$header_font NE\n"
- if ($show_header);
- }
- print "/F1/$font-ISO findfont $font_size scalefont def\n";
- print "/F2/$line_number_font findfont $line_number_size scalefont def\n"
- if ($opt_l);
- print "/F3/$header_font-ISO findfont $header_font_size scalefont def\n"
- if ($show_header);
- print "F1 SF\n";
- print "%%EndSetup\n";
- }
-
-
-
- sub new_page {
- &end_page unless ($page_no == 0);
- $page_no++;
- print "%%Page: $page_no $page_no\n";
- print "%%BeginPageSetup\n";
- print "/page_save save def\n";
- printf "90 rotate 0 -%d translate %% landscape mode\n",&page_right_edge
- if ($landscape);
- print "0.15 setlinewidth\n" if ($show_header);
- print "%%EndPageSetup\n";
- if ($show_header) {
- # First print a box
- local($llx,$lly,$urx,$ury) = ($left_margin - 10,
- $top - $tb_margin - $header_font_size * 1.3,
- $right_edge - $right_margin + 10, $top - $tb_margin);
- printf "%.1f %.1f M %.1f %.1f L %.1f %.1f L ",
- $llx,$lly, $urx,$lly, $urx, $ury;
- printf "%.1f %.1f L closepath \n",$llx,$ury;
- print "gsave .95 setgray fill grestore stroke\n";
- # Then the banner or the filename
- print "F3 SF\n";
- if ($opt_b) {
- printf "($opt_b)%.1f %.1f S\n",
- $left_margin,$top - $tb_margin - $header_font_size;
- }
- elsif ($file_name) {
- printf "(%s)%.1f %.1f S\n", $file_name,
- $left_margin,
- $top - $tb_margin - $header_font_size;
- }
- # Then print page number
- printf "%.1f %.1f M($page_no)dup stringwidth pop neg 0 rmoveto show\n",
- $right_edge - $right_margin,
- $top - $tb_margin - $header_font_size;
- print "F1 SF\n";
- }
- if ($sep_bars) {
- print "% Some postscript code to draw horizontal bars.\n";
- print "% Not implemented yet\n";
- }
- }
-
- sub end_page {
- unless ($page_no == 0) {
- print "page_save restore\n";
- print "showpage\n";
- }
- }
-
- sub ps_string
- {
- # Prepare text for printing
- local($_) = shift;
- s/[\\\(\)]/\\$&/g;
- s/[\001-\037\177-\377]/sprintf("\\%03o",ord($&))/ge;
- $_; # return string
- }
-
-
- ###########################################################################
- # These next few lines are legal in both Perl and nroff.
-
- .00; # finish .ig
-
- 'di \" finish diversion--previous line must be blank
- .nr nl 0-1 \" fake up transition to first page again
- .nr % 0 \" start at page 1
- ';<<'.ex'; #__END__ #### From here on it's a standard manual page #########
- .TH I2PS 1 "October 1990"
- .SH NAME
- i2ps \- convert ISO Latin1 text to PostScript
- .SH SYNOPSIS
- .B i2ps
- [
- .B \-nlrth23g
- ] [
- .B \-b
- .I "text"
- ] [
- .B \-s
- .I size
- ] [
- .I filename
- \&.\|.\|.
- ]
- .SH DESCRIPTION
- The
- .B i2ps
- program is used to print simple
- text files (e.g. program listings) on a PostScript\*R device.
- The name
- .B i2ps
- stands for iso-to-postscript. The program handles the whole
- ISO Latin1 (ISO 8859/1) character set.
- Efforts have been made to ensure that
- .B i2ps
- produces good looking and effective PostScript code.
- The output conforms to Adobe's
- document structuring conventions (version 2.1). The
- .B i2ps
- program
- assumes that the page format on the output device is A4.
- (Change the definitions of &page_top and &page_right_edge if you
- want something else.)
- The meaning of form feed (^L) characters in the input stream is understood.
- .PP
- The
- .B i2ps
- program is written in
- .I perl.
- So if there is something you don't like about how
- .B i2ps
- works, you can "easily" fix it yourself.
- .SH OPTIONS
- .TP 5
- .B \-n
- use the norwegian version of ISO 646 (7-bit ascii) to encode the text.
- Norwegian letters will replace the left/right braces, left/right
- brackets, backslash and horizontal bar characters.
- .TP 5
- .B \-l
- produces line numbers on each 5'th and the last line.
- Nice for program listings.
- .TP 5
- .B \-t
- truncate lines that are to long. The default is to wrap
- long lines so that they continue on the next line on the printed output.
- .TP 5
- .B \-r
- rotate the output page 90 degrees. This is called
- .I landscape
- mode by some people.
- .TP 5
- .B \-h
- suppress generation of page headers.
- .TP 5
- .B \-2
- use two column format.
- .TP 5
- .B \-3
- use three column format.
- .TP 5
- .BI \-b " text"
- the
- .I text
- parameter replaces the default text in the header of the pages.
- The default text is the filename of the file to be printed. There is no
- default if the text comes from standard input.
- .TP 5
- .BI \-s " size"
- specifies a new font size for the body text. The default is 10 point.
- .TP 5
- .B \-g
- eat garbage.
- .B I2ps
- normally skips binary files. This option means "print it anyway".
- .SH EXAMPLES
- To print files on a PostScript printer:
- .nf
- i2ps -l *.[ch] | lpr
- .fi
- .PP
- To find out how many pages i2ps will produce for a given file:
- .nf
- i2ps file.txt | tail -1
- .fi
- .PP
- Our printer stacks the pages the wrong way. To fix it try:
- .nf
- cat file.txt | i2ps -b "some text" | psrev | lpr
- .fi
- .SH SEE ALSO
- .BR perl (1),
- .BR enscript (1),
- .BR psrev (1),
- .BR ISO8859 (7),
- .BR PostScript (7)
- .SH BUGS
- There is no easy way to change the margins or the fonts that
- .B i2ps
- insists on using.
- The
- .B i2ps
- filter ought to understand the meaning of the backspace character. It is used
- to produce boldfaced and underlined text by programs like
- .BR nroff (1).
- .SH AUTHOR
- Gisle Aas, Norwegian Computing Center (NR), Oslo, Norway.
- <Gisle.Aas@nr.no>
- .ex
-