#!/usr/bin/perl
#
# txt2pdf.pl from mcollins@fcnetwork.com
#
# MC's Q&D text to PDF converter.
#
# FYI,
#
# I wrote a simple text file to PDF converter that uses PDF::API2::Lite.
# It isn't full-featured by any stretch but it does illustrate one of the
# many uses of this cool module. I'm submitting it here for your perusal.
# If you think of any useful things to add to it please let me know.
# Fredo, please feel free to include it in the contributed items if you
# would like.
#
# Thanks! (Sorry about the long comments that wrap around to the next
# line...)
#
# -MC
#
use strict;
use warnings;
use PDF::API2::Lite;
use Getopt::Long;
use File::Basename;
$|++; # turn off buffering
my $pdf; # main PDF document object
my $page; # current page being processed
my $text; # current page's text object
my $font; # current font being used
# variables from the command line
my $left; # left margin/starting point; default = 36pts from page
my $top; # top margin/starting point; default = 36pts from page
my $infile; # input path & file (from cmd line arg - could be glob)
my $lpp; # lines per page
my $layout; # portrait or landscape; default = portrait
my $landscape; # landscape cmd line flag
my $fontsize; # font size; default = 7.25
my $bold; # set to 1 for bold on; default = 0;
my $spacing; # text spacing ($pdf->textlead); default = 8
# other variables
my @FILES; # list of input files, in case of glob
my $file; # Current file being converted
my $destpath; # destination path
my $outfile; # output path & file
my $linecount; # how many lines have been processed on this page
my $arg; # command line argument being processed
my $help; # Flag for displaying help
$fontsize = 7.25; # unless otherwise specified, font size is 7.25
$spacing = 8; # unless otherwise specified, spacing is 8
$layout = "Portrait"; # default page layout
if ($#ARGV < 0) {
print "Usage:\n";
print "txt2pdf <options> <textfilename>\n";
exit(1);
}
# get those cmd line args!
my $opts_okay = GetOptions(
'h' => \$help,
'help' => \$help, # Can use -h or --help
'lpp=i' => \$lpp,
'left=f' => \$left,
'top=f' => \$top,
'fontsize=f' => \$fontsize,
'spacing=f' => \$spacing,
'b' => \$bold,
'l' => \$landscape,
'in=s' => \$infile,
'dir=s' => \$destpath,
);
# if help, then display usage
if ( $help ) { &usage; exit(0); }
# Check filename
if ( ! $infile ) {
die "Please specify a file name or glob with --in=<filename>\n";
exit(1);
}
# Check path
if ( ! $destpath ) { $destpath = '/default/path/'; }
# Check for filename vs. filespec(glob)
if ( $infile =~ m/\*|\?/ ) {
print "Found glob spec, checking...\n";
@FILES = glob($infile);
if ( ! @FILES ) {
die "No files match spec: '$infile', exiting...\n";
} # if no files match
print "Found file";
if ( $#FILES > 0 ) { print "s"; } # Be nice, use plural
print ":\n";
foreach ( @FILES ) {
print "$_\n";
} # foreach @FILES
} else {
if ( ! -f $infile ) {
die "Could not locate file '$infile', exiting...\n";
} # if $infile not found
@FILES = ( $infile );
} # if $infile contains wildcards
# Validate remaining cmd line args
if ( $landscape ) {
## Set up landscape defaults and maxima
$layout = 'landscape';
## Set default lines per page if necessary
if ( ! $lpp ) { $lpp = 45; } # Landscape default lines per page
## If left margin not specified, default to 1/2" or 36 points
if ( ! $left ) { $left = 36; } # Default left margin
## Left margin shouldn't be more than 10.5" (756 points) from left edge of page
if ( ! $left > 756 ) {
$left = 756; # Landscape max left margin (in points)
} # if $left greater than 756 points
## For top margin, need to calculate number of points from top of page
## Example, 1/2" margin is 36 points from top of page
## Top of page is 612 points, 1/2" down is 576 points (612 - 36 = 576)
if ( ! $top ) {
$top = 612 - 36; # Calculate 36 pts (1/2") from top of page
} else {
$top = 612 - $top; # Calculate $top pts from top of page
} # if top margin not specified
} else {
## Set up portrait defaults and maxima
## Set default lines per page if necessary
if ( ! $lpp ) { $lpp = 60; } # Landscape default lines per page
## If left margin not specified, default to 1/2" or 36 points
if ( ! $left ) { $left = 36; } # Default left margin
## Left margin shouldn't be more than 8" (576 points) from left edge of page
if ( ! $left > 576 ) {
$left = 576; # Landscape max left margin (in points)
} # if $left greater than 576 points
## For top margin, need to calculate number of points from top of page
## Example, 1/2" margin is 36 points from top of page
## Top of page is 792 points, 1/2" down is 756 points (792 - 36 = 756)
if ( ! $top ) {
$top = 792 - 36; # Calculate 36pts (1/2") from top of page
} else {
$top = 792 - $top; # Calculate $top pts from top of page
} # if top margin not specified
} # if landscape or portrait
# Set max, min spacing
if ( $spacing > 720 ) { $spacing = 720; } # why would anyone want this much spacing?
if ( $spacing < 1 ) { $spacing = 1; } # That's awfully crammed together...
foreach $file ( @FILES ) {
print "Processing $file...\n";
my ($name,$dir,$suf) = fileparse($file,qr/\.[^.]*/);
if ( $suf =~ m/txt2pdf|txt/) {
# replace .txt or .txt2pdf with .pdf
$outfile = $destpath . $name . '.pdf';
} else {
# just append .pdf to end of filename
$outfile = $destpath . $name . $suf . '.pdf';
} # if suffix is '.txt' or '.txt2pdf'
$pdf = PDF::API2::Lite->new;
&newpage; # create first page in PDF document
open (FILEIN,"$file") or die "$file - $!\n";
while(<FILEIN>) {
#chomp;
# chomp is insufficient when dealing with EOL from different systems
# this little regex will make things a bit easier
s/(\r)|(\n)//g;
if (m/\x0C/ || $linecount >= $lpp) { # found page break
&newpage;
next;
} # if
$pdf->text($_);
$pdf->nl;
$linecount++;
} # while(<FILEIN>)
$pdf->textend;
close(FILEIN);
$pdf->saveas($outfile);
} # foreach $file (@FILES)
sub newpage() {
if ($layout =~ m/l/i) { $pdf->page(792,612);}
else { $pdf->page(612,792); }
if ( $bold ) { $font = $pdf->corefont('CourierBold');}
else {$font = $pdf->corefont('Courier');}
$pdf->textstart;
$pdf->textlead($spacing);
$pdf->transform(-translate => [$left,$top]);
$pdf->textfont($font,$fontsize);
$linecount = 1;
}
sub usage() {
print << 'END_OF_USAGE'
MC's Text to PDF converter (very cheesy, but useful nonetheless)
Usage:
txt2pdf [options] <source file name>
Options:
--lpp=## specify number of lines per page
Note: portrait/landscape, margins and font size all affect the
placement of text on a page. You may need to experiment
--left=## specify left margin in points. 72 points = 1 inch
--top=## specify top margin in points. 36 points = .5 inch
-h, --help This help page
--size=## Set font size; default is 7.25
--spacing=# Set the spacing between lines; default is 8
-b, -B Set bold type to on; default is not bold
-l, -L Set doc to landscape; default is portrait
Special thanks to Alfred Reibenschuh for such a cool Perl module!
Also, many thanks to the PDF::API2 community for such great ideas.
END_OF_USAGE
}
__END__