Previewing POD before shipping

I always find typos after I ship to CPAN.

There is something about reading my docs in nicely-formatted HTML on a web site that makes my mistakes jump out at me. And then I feel stupid for not having caught it earlier.

I used to use the search.cpan.org pod renderer to preview my POD, but I stopped after a while, probably when I stopped using search.cpan.org for everything else as well.

What I really wanted was something local, quick and pretty. So I ripped off a bit of what MetaCPAN was doing to render POD and came up with my own utility program: podpreview.

$ podpreview path/to/whatever.pm

That renders the POD from the file into HTML with an embedded stylesheet, saves it in a temporary file and opens up that file in my browser. There I can happily proofread and find my typos before shipping.

If you'd like to try it out and adapt it to your own style, here it is:

#!/usr/bin/env perl
use v5.10;
use strict;
use warnings;
use Browser::Open qw/open_browser/;
use Path::Tiny;
use Pod::Simple::XHTML;

my $file = shift @ARGV
  or die "Usage: $0 <file>";
$file = path($file);

my $psx = Pod::Simple::XHTML->new;
$psx->output_string( \my $html );
$psx->html_charset('UTF-8');
$psx->html_encode_chars('&<>">');
$psx->perldoc_url_prefix("https://metacpan.org/module/");
$psx->html_header( my_header() );
$psx->html_footer( my_footer() );
$psx->parse_string_document( $file->slurp_utf8 );

my $temp = path( $ENV{TMPDIR}, 'podpreview', $file->relative . '.html' );
$temp->touchpath;
$temp->spew_utf8($html);
open_browser("file:///$temp");

sub my_css {
    return <<'CSS';
body { background: snow; font-family: sans-serif; }
div#main { width: 70%; margin: 5% auto; }
h1 { font-size: 1.5em; margin: .83em 0 }
h2 { font-size: 1.17em; margin: 1em 0 }
h3 { margin: 1.33em 0 }
h4 { font-size: .83em; line-height: 1.17em; margin: 1.67em 0 }
h5 { font-size: .67em; margin: 2.33em 0 }
h1, h2, h3, h4, h5 { font-weight: bolder; color: #36c }
a:link { color: #36c }
code { font-size: 1.2em }
CSS
}

sub my_header {
    my $css = my_css();
    return <<"HEADER";
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
$css
</style>
</head>
<body>
<div id="main">
HEADER
}

sub my_footer {
    return <<'FOOTER';
</div>
</body>
</head>
FOOTER
}
This entry was posted in perl programming and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

10 Comments

  1. Posted September 13, 2013 at 4:05 am | Permalink

    That's nice. I wrote pod2cpanhtml for similar reasons.

  2. Posted September 13, 2013 at 4:18 am | Permalink

    Nice, thanks. Like you I prefer to read the rendered HTML so I know I'll find this useful. Just one small thing, I didn't have TMPDIR set in my environment (Linux, Ubuntu) and so line 22 bombed out. I just replaced it with '/tmp'.

    • ggl
      Posted September 14, 2013 at 3:03 am | Permalink

      Ubuntu here too.

      my $temp = $ENV{TMPDIR}
      ? path( $ENV{TMPDIR}, 'podpreview', $file->relative . '.html' )
      : path( '/tmp', 'podpreview', $file->relative . '.html' );

      (should probably look better with an if though)

  3. Ether
    Posted September 13, 2013 at 12:45 pm | Permalink

    Also check out: https://metacpan.org/module/Dist::Zilla::App::Command::podpreview

    • Posted September 13, 2013 at 12:57 pm | Permalink

      I didn't know that existed. Thanks. It's a bit too simple for my taste, though.

  4. Ivan Wills
    Posted September 24, 2013 at 4:57 pm | Permalink

    I wrote docperl for similar reasons although it hasn't seen much love in the last cople of years (I have been meaning to port it to Catalyst or Dancer).

  5. Posted September 30, 2013 at 1:17 pm | Permalink

    Does it handle links though? I find I can deal with the typos fairly well without seeing the final result, but one never knows how the links are going to come out until you see the final result ... If the converter could show me the links, though, that would be immensely helpful. Doing only the internal links would be helpful enough, but links to other modules (and sections within other modules) would be _really_ nice. I suppose you'd have to specify whether you wanted to simulate a search.cpan.org or a metacpan.org, but that part seems easy enough. Beyond that, I wouldn't know how tough it is though.

    • Posted September 30, 2013 at 2:13 pm | Permalink

      It does. The "perldoc_url_prefix" option controls where pod links resolve.

  6. Ether
    Posted September 30, 2013 at 1:55 pm | Permalink

    > Does it handle links though? I find I can deal with the typos fairly well without seeing the final result, but one never knows how the links are going to come out until you see the final result ...

    I use the markdown version for this (as well as tests like what Dist::Zilla::Plugin::Test::Pod::No404s generates) - \(link) is pretty readable as raw text.

  7. Ether
    Posted September 30, 2013 at 1:56 pm | Permalink

    I meant to say open-bracket text close-bracket open-paren link close-paren (shakes fist at markup languages) :)

© 2009-2014 David Golden All Rights Reserved