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; RequestLockDir('pdf'); 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"; close(HTML); 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>; close(PDF); ReportError("$target is empty", $status) unless $pdf; binmode(STDOUT, ':raw'); print GetHttpHeader('application/pdf'); print $pdf; ReleaseLockDir('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" /> </p></form> } } };
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.
#Oddmuse
(Please contact me if you want to remove your comment.)
⁂
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”.
– Alex Schroeder 2013-12-19 09:03 UTC