2013-12-17 PDF Button

I’m experimenting with a PDF button for this website. In the past, I suggested Print Friendly & PDF. Yesterday I learned about wkhtmltopdf, which does the same thing without depending on a remote service and their ad revenue. On a typical Debian host, you need to apt-get install wkhtmltopdf. This installs a binary and all the required libraries. The problem is that this version needs an X11 server in order to work, which you don’t have when using it on your website. In addition to a regular installation, you need to install a statically compiled binary which has been compiled with a patched version of Qt and no longer requires an X11 server.

In your Oddmuse config file:

$Action{pdf} = \&DoPdf;
push(@KnownLocks, 'pdf');

sub DoPdf {
  my $id = shift;
  local $StyleSheet = 'https://alexschroeder.ch/alex-2012.css';
  my $html = PageHtml($id);
  my $source = "$TempDir/document.html";
  my $status = '500 INTERNAL SERVER ERROR';
  open(HTML, '>:utf8', $source)
    or ReportError("Cannot write $source: $!", $status);
  # see GetHeader
  print HTML GetHtmlHeader(NormalToFree($id), $id);
  print HTML $q->start_div({-class=>'header'});
  print HTML $q->h1({-style=>'font-size: x-large'}, GetPageLink($id));
  print HTML $q->end_div(); # header
  print HTML $q->start_div({-class=>'wrapper'});
  # get rid of letter-spacing
  my $sperrung = '<em style="font-style: normal; letter-spacing: 0.125em; padding-left: 0.125em;">';
  $html =~ s/$sperrung/<em>/g;
  my $newthought = '<em style="font-style: normal; font-variant:small-caps; letter-spacing: 0.125em;">';
  $html =~ s/$newthought/<em style="font-style: normal; font-variant:small-caps">/g;
  print HTML $html;
  # see PrintFooter
  print HTML $q->end_div(); # wrapper
  print HTML $q->start_div({-style=>'font-size: smaller; '});
  print HTML $q->hr();
  print HTML $FooterNote;
  # see DoContrib
  SetParam('rcidonly', $id);
  SetParam('all', 1);
  my %contrib = ();
  for my $line (GetRcLines(1)) {
    my ($ts, $pagename, $minor, $summary, $host, $username) = @$line;
    $contrib{$username}++ if $username;
  print HTML $q->p(Ts('Authors: %s',
                      join(', ', map { GetPageLink($_) }
                           sort(keys %contrib))));
  print HTML $q->end_div(); # footer
  print HTML $q->end_html;
  print HTML "\n";
  my $target = "$TempDir/document.pdf";
  my $error = `/home/alex/bin/wkhtmltopdf --print-media-type --quiet '$source' '$target'`;
  ReportError("The conversion of HTML to PDF failed", $status) if $error;
  open(PDF, '<:raw', $target) or ReportError("Cannot read $target: $!", $status);
  local $/ = undef;
  my $pdf = <PDF>;
  ReportError("$target is empty", $status) unless $pdf;
  binmode(STDOUT, ':raw');
  print GetHttpHeader('application/pdf');
  print $pdf;

sub PrintMyContent {
  my $id = UrlEncode(shift);
  if ($id and $IndexHash{$id}) {
print qq{
<form action="$FullUrl"><p>
<input type="hidden" name="action" value="pdf" />
<input type="hidden" name="id" value="$id" />
<input type="submit" value="PDF" />

Let me know if it works for you while I try to figure out whether I need this at all. The position of the PDF button at the very bottom of the page is probably less than ideal.

As you can tell, the markup using increased Wikipedia:letter-spacing is messing it all up, which is why I had to fix it.



Hi Alex, Long time ago, I wondered about to include a patch like this for my wiki, but eventually most browsers have an utility like this, and others like breadcrumbs, etc.. Is there any advantage?. Thanks.

JuanmaMP 2013-12-19 08:52 UTC

On my Mac, I don’t need it. Printing to PDF is simple. On Windows, however, I need to install a software PDF printer if I want to do this. Just recently my sister asked me for help converting a Word document she had written. She didn’t manage the installation of the PDF printer software. That reminded me of the fact that for some users, a PDF button might still be necessary. I personally don’t like the “save as HTML” feature of most browsers because it results in HTML + a directory of CSS files, images, ads, scripts, and so on. PDF feels “safe”.

AlexSchroeder 2013-12-19 09:03 UTC

Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy Policy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.