#!/pro/bin/perl use 5.14.1; use warnings; sub usage { my $err = shift and select STDERR; say "usage: pod2pdf [--output=file.pdf] [input]"; exit $err; } # usage use Getopt::Long qw(:config bundling); my $opt_o; my $opt_t; my $opt_c; GetOptions ( "help|?" => sub { usage (0); }, "o|output=s" => \$opt_o, "t|title=s" => \$opt_t, "c|css=s" => \$opt_c, ) or usage (1); use Pod::Html; use File::Temp qw( tempdir ); # Pod::Html doesn't support piped output :( :( use HTML::TreeBuilder; my $td = tempdir (CLEANUP => 1); my %tf = map { $_ => "$td/pod2pdf.$_" } "html", "pdf"; my $html; { pod2html "--outfile=$tf{html}", @ARGV; # Cleanup leftover junk from Pod::Html :( -f $_ && unlink $_ for map { "$_/pod2htmd.tmp" } ".", $ENV{TMPDIR} // "/tmp"; open my $fh, "<", $tf{html}; $html = join "" => <$fh>; close $fh; } my $css = join "" => ; if ($opt_c && open my $fh, "<", $opt_c) { $css = join "" => <$fh>; close $fh; } my $tree = HTML::TreeBuilder->new; $tree->parse_content ($html); foreach my $head ($tree->look_down (_tag => "head")) { my $style = HTML::Element->new ("style"); $style->attr (type => "text/css"); $style->push_content ($css); $head->push_content ($style); } my $pdf = do { open my $fh, ">", $tf{html} or die "$tf{html}: $!\n"; print $fh $tree->as_HTML (undef, " ", {}); close $fh; my @cmd = qw( wkhtmltopdf --quiet --load-error-handling ignore ); $opt_t and push @cmd, "--title", $opt_t; push @cmd, $tf{html}, $tf{pdf}; system @cmd; open $fh, "<", $tf{pdf} or die "$tf{pdf}: $!\n"; join "" => <$fh>; }; if ($opt_o) { open my $fh, ">", $opt_o or die "$opt_o: $!\n"; print $fh $pdf; close $fh; } else { print $pdf; } __END__ body, p, ul, ol, h1, h2, h3 { font-family: "DejaVu Sans", "Nimbus Sans L", Helvetica, sans-serif; } body { color: Black; background: White; } a:link { color: Purple; } a:visited { color: Maroon; } pre, tt, code { font-family: "DejaVu Sans Mono", "Liberation Mono", LettrGothic12BT, "Lucida Console", mono, monospace; } p, ul, ol { text-align: left; } h1 { color: Maroon; } h2 { color: Green; } h3 { color: Navy; }