I created a key in Windows registry to have an option on every folder which allows me to simply right click, choose the right option and have a PDF made, either from JPGS, or PNGs, or TIFs.
My registry key is as follows:
'"C:\strawberry\perl\bin\perl.exe" "C:\Users\michal\Documents\createpdf790024円.pl" "%1"'.
The code, thanks to suggestions and some major modifications by Matt Jacob works. Dealing with paths with spaces is done by:
my $folder = $ARGV[0];
$folder =~ s|\\|/|g;
$folder =~ s|/$||;
To read files I have came up with this: my @files = <"$folder/*">;
As I am a Perl newbie, I would like to see if this is correct. It works on my system.
The whole script is as follows:
#!/usr/bin/perl
use PDF::API2;
use strict;
use warnings;
my $folder = $ARGV[0];
$folder =~ s|\\|/|g;
$folder =~ s|/$||;
my $pdf_file = $folder . '.pdf';
die "Not a folder!\n" unless -d $folder;
die "There's already a pdf of that name!\n" if -f $pdf_file;
my $pdf = PDF::API2->new;
my %dispatch = (
jpg => sub { $pdf->image_jpeg(@_) },
png => sub { $pdf->image_png(@_) },
tif => sub { $pdf->image_tiff(@_) },
);
my @files = <"$folder/*">;
for my $ext (sort(keys(%dispatch))) {
my $count;
for my $file (@files) {
next unless $file =~ /\.$ext$/;
my $image = $dispatch{$ext}->($file);
my $page = $pdf->page;
$page->mediabox(0, 0, $image->width, $image->height);
$page->trimbox(0, 0, $image->width, $image->height);
my $gfx = $page->gfx;
$gfx->image($image, 0, 0);
$count++;
}
last if $count;
}
if ($pdf->pages) {
$pdf->saveas($pdf_file);
}
1 Answer 1
I think it's fine, although my preference would be readdir
over glob
. (I know someone made the exact opposite suggestion on your original post, and that's alright.) I can't really articulate why, but I've never liked glob
very much---I guess it just seems too magical to me. Some people would argue "why write three lines of code when you can write one?" or "readdir
isn't good because you have to filter out dots" or "readdir
isn't good because you have to remember to prepend the directory". OK, so put a tiny wrapper around it in your standard library or use read_dir
from File::Slurp. Anyway, moving on...
I did want to comment on your comment:
Dealing with paths with spaces is done by:
my $folder = $ARGV[0]; $folder =~ s|\\|/|g; $folder =~ s|/$||;
That code doesn't actually do anything related to handling paths with spaces. All it does is take the first command line argument to your script, replacing backslashes with forward slashes and stripping off the trailing slash. It's also unnecessary, since Perl on Windows can deal with either forward or backward slashes in paths. I would also assume that Windows is not giving you a directory path with a trailing slash on it, but I don't have access to a Windows box to confirm that.
Since you are on Windows, the shebang/hashbang line is redundant and can be removed:
#!/usr/bin/perl
Other than that, I think the rest of the code looks pretty good, but I guess it would be strange if I didn't think so, considering that I wrote some of it. When it comes to glob
vs. readdir
, it's mostly a matter of personal preference, although there's a good thread on Stack Overflow that examines the differences. Read it for yourself and see what you think.
-
\$\begingroup\$ Welcome to Code Review! Good job on your first answer \$\endgroup\$SirPython– SirPython2015年12月21日 21:25:59 +00:00Commented Dec 21, 2015 at 21:25
-
\$\begingroup\$ @Matt Jacob Thanks for this. If I understand you correctly
$folder =~ s|\\|/|g; $folder =~ s|/$||;
can be removed andmy $folder = $ARGV[0];
is fine. I removed the above lines (exceptmy $folder = $ARGV[0];
) and everything works flawlessly. \$\endgroup\$menteith– menteith2015年12月22日 12:35:50 +00:00Commented Dec 22, 2015 at 12:35 -
\$\begingroup\$ I would encourage people to use either
Path::Tiny
orFile::Slurper
for slurping now. File::Slurp is buggy and slow \$\endgroup\$Kent Fredric– Kent Fredric2016年02月14日 08:24:36 +00:00Commented Feb 14, 2016 at 8:24