http://qs321.pair.com?node_id=618943
Category: Text Processing
Author/Contact Info Minimiscience
Description: For each filename passed as an argument, this script will produce a PostScript file that neatly typesets the text of the original file, complete with a simple header on each page, page numbers, numbering of every fifth line, & long lines broken up with red hyphens. The primary purpose is for printing source code beautifully (for a given value of "beautiful"), though it will work on any kind of ASCII text document, as long as the file name has an extension & there are no backslashes or parentheses in the filename (otherwise, bad things happen).
#!/usr/bin/perl -w
use strict;

foreach (@ARGV) {
 open CODE, '<', $_ or die "Error opening $_: $!\n";
 (my $ps = $_) =~ s/\.[^.]+$/.ps/;
 open PS, '>', $ps or die "Error opening $ps: $!\n";
 print PS <<EOT;
%!PS-Adobe-3.0
/Courier findfont 10 scalefont setfont
/pageNo 0 def /lineNo 0 def
/linefeed {y 84 le {showpage startPage} if /y y 12 sub def 1 eq {/line
+No lineNo 1 add def lineNo 5 mod 0 eq {61 y lineNo printNum} if} if 6
+6 y moveto} def
/hyphen {1 0 0 setrgbcolor (-) show 0 0 0 setrgbcolor 0 linefeed} def
/startPage {/pageNo pageNo 1 add def 66 725 moveto ($_) show 546 725 p
+ageNo printNum 66 722.5 moveto 480 0 rlineto stroke /y 722 def} def
/printNum {/str 20 string def str cvs stringwidth pop 3 2 roll sub neg
+ exch moveto str show} def
startPage
EOT
 while (<CODE>) {
  chomp;
  1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;
  print PS "1 linefeed\n";
  getline: my $line = substr $_, 0, length > 80 ? 79 : 80, '';
  $line =~ s/([()\\])/\\$1/g;
  print PS "($line) show ";
  if ($_) {print PS "hyphen "; goto getline; }
 }
 print PS "showpage\n";
}
Replies are listed 'Best First'.
Re: Code Typesetter
by derby (Abbot) on Jun 03, 2007 at 11:12 UTC

    While I ++ your code, have you seen enscript.

    -derby
Re: Code Typesetter
by ursus (Acolyte) on Jul 23, 2007 at 20:25 UTC

    In line 6, I recommend (my $ps = $_) =~ s/(\.[^.]+)?$/.ps/;

    This should eliminate the extension requirement.

    I also recommend at line 20, using while (condition) { } as it clarifies the intent of the statement (IMO).

    All in all, an excellent idea. I'll probably use it sometime.

      Also, it should probably use STDIN and STDOUT if !@ARGV