The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Pod::HtmlEasy - Generate personalized HTML from PODs.

VERSION

This documentation refers to Pod::HtmlEasy version 0.0911.

DESCRIPTION

The purpose of this module is to generate HTML data from POD in a easy and personalized mode.

By default the HTML generated is similar to the CPAN site style for module documentation.

SYNOPSIS

Simple usage:

  my $podhtml = Pod::HtmlEasy->new() ;

  my $html = $podhtml->pod2html( 'test.pod' ) ;

  print "$html\n" ;

Complete usage:

  use Pod::HtmlEasy ;

  Create the object and set local events subs:

  Note that these are all the events, and examples of how to implement 
  them. All of these events are, of course, already implemented, so if
  the actions provided are adequate, no local subs are required.

  The actual implementation of on_head1 is somewhat more complex, to
  provide for the detection of the module title and insertion of the
  uparrow.

  my $podhtml = Pod::HtmlEasy->new (

  on_B         => sub {
                    my ( $this , $txt ) = @_ ;
                    return "<b>$txt</b>" ;
                  } ,

  on_C         => sub {
                    my ( $this , $txt ) = @_ ;
                    return "<font face='Courier New'>$txt</font>" ;
                  } ,

  on_E         => sub {
                    my ( $this , $txt ) = @_ ;
                    $txt =~ s{^&}{}smx;
                    $txt =~ s{;$}{}smx;
                    $txt = qq{#$txt} if $txt =~ /^\d+$/ ;
                    return qq{\0&$txt;};
                  } ,

  on_F         => sub {
                    my ( $this , $txt ) = @_ ;
                    return "<b><i>$txt</i></b>" ;
                  } ,

  on_I         => sub {
                    my ( $this , $txt ) = @_ ;
                    return "<i>$txt</i>" ;
                  } ,

  on_L         => sub {
                    my ( $this , $L , $text, $page , $section, $type ) = @_ ;
                    if   ( $type eq 'pod' ) {
                      $section = defined $section ? "#$section" : ''; 
                      $page = '' unless defined $page; 
                      return "<i><a href='http://search.cpan.org/perldoc?$page$section'>$text</a></i>" ;
                    }
                    elsif( $type eq 'man' ) { return "<i>$text</i>" ;}
                    elsif( $type eq 'url' ) { return "<a href='$page' target='_blank'>$text</a>" ;}
                  } ,

  on_S         => sub {
                    my ( $this , $txt ) = @_ ;
                    $txt =~ s/\n/ /gs ;
                    return $txt ;
                  } ,

  on_X         => sub { return '' ; } ,

  on_Z         => sub { return '' ; } ,

  on_back      => sub {
                    my $this = shift ;
                    return "</ul>$NL" ;
                  } ,

  on_begin     => sub {
                    my $this = shift ;
                    my ( $txt , $a_name ) = @_ ;
                    $this->{IN_BEGIN} = 1;
                    return '';
                  } ,

  on_error     => sub {
                    my ( $this , $txt ) = @_ ;
                    return qq{<!-- POD_ERROR: $txt -->} ;
                  } ,

  on_end       => sub { 
                    my $this = shift ;
                    my ( $txt , $a_name ) = @_ ;
                    delete $this->{IN_BEGIN};
                    return '';
                  } ,

  on_for       => sub { return '' ;} ,

  on_head1     => sub {
                    my ( $this , $txt , $a_name ) = @_ ;
                    return qq{<a name='$a_name'></a><h1>$txt</h1>$NL$NL} ;
                  } ,

  on_head2     => sub {
                    my ( $this , $txt , $a_name ) = @_ ;
                    return qq{<a name='$a_name'></a><h2>$txt</h2>$NL$NL} ;
                  } ,

  on_head3     => sub {
                    my ( $this , $txt , $a_name ) = @_ ;
                    return qq{<a name='$a_name'></a><h3>$txt</h3>$NL$NL} ;
                  } ,

  on_head4     => sub {
                    my ( $this , $txt , $a_name ) = @_ ;
                    return qq{<a name='$a_name'></a><h4>$txt</h4>$NL$NL} ;
                  } ,

  on_include   => sub {
                    my ( $this , $file ) = @_ ;
                    return qq{./$file} ;
                  } ,

  on_item      => sub {
                    my ( $this , $txt ) = @_ ;
                    return qq{<li>$txt</li>$NL} ;
                  } ,

  on_index_node_start => sub {
                    my ( $this , $txt , $a_name , $has_children ) = @_ ;
                    my $ret = qq{<li><a href='#$a_name'>$txt</a>$NL} ;
                    $ret .= q{$NL<ul>$NL} if $has_children ;
                    return $ret ;
                  } ,

  on_index_node_end => sub {
                    my $this = shift ;
                    my ( $txt , $a_name , $has_children ) = @_ ;
                    my $ret = $has_children ? q{</ul>} : $EMPTY ;
                    return $ret ;
                  } ,

  on_over      => sub {
                    my ( $this , $level ) = @_ ;
                    return qq{<ul>$NL? ;
                  } ,

  on_textblock => sub {
                    my ( $this , $txt ) = @_ ;
                    return if exists $this->{IN_BEGIN};
                    return qq{<p>$txt</p>$NL} ;
                  } ,

  on_uri       => sub {
                    my ( $this , $uri ) = @_ ;
                    return qq{<a href='$uri' target='_blank'>$uri</a>{ ;
                  } ,

  on_verbatim  => sub {
                    my ( $this , $txt ) = @_ ;
            $txt =~ s{(\A$NL)*(\A$NL)\z}{}gsmx;
                    return '' unless length $txt;
                    return qq{<pre>$txt</pre>$NL} ;
                  } ,
  ) ;

  ## Convert to HTML:

  my $html = $podhtml->pod2html('test.pod' ,
                                'test.html' ,
                                title => 'POD::Test' ,
                                body  => { bgcolor => '#CCCCCC' } ,
                                css   => 'test.css' ,
                               ) ;

SUBROUTINES/METHODS

new ( %EVENTS_SUBS )

By default the object has it own sub to handler the events.

But if you want to personalize/overwrite them you can set the keys in the initialization:

(For examples of how to implement the event subs see USAGE above).

on_B ( $txt )

When B<...> is found. (bold text).

on_C ( $txt )

When C<...> is found. (code text).

on_E ( $txt )

When E<...> is found. (a character escape).

on_I ( $txt )

When I<...> is found. (italic text).

on_L ( $L , $text, $page, $section, $type )

When L<...> is found. (Link).

$L

The link content. This is what is parsed to generate the other variables.

$text

The link text.

$page

The page of the link. Can be an URI, pack::age, or some other reference.

$section

The section of the $page.

$type

The type of the link: pod, man, url.

on_F ( $txt )

When F<...> is found. (used for filenames).

on_S ( $txt )

When S<...> is found. (text contains non-breaking spaces).

on_X ( $txt )

When X<...> is found. (a null (zero-effect) formatting code).

on_Z ( $txt )

When Z<...> is found. (a null (zero-effect) formatting code).

on_back

When =back is found.

on_begin

When =begin is found.

By default everything from '=begin' to '=end' is ignored.

on_error ( $txt )

Called on POD syntax error occurrence.

on_head1 ( $txt , $a_name )

When =head1 is found.

$txt

The text of the command.

$a_name

The text of the command filtered to be used as <a name="$a_name"</a>>.

on_head2 ( $txt , $a_name )

When =head2 is found. See on_head1.

on_head3 ( $txt , $a_name )

When =head3 is found. See on_head1.

on_head4 ( $txt , $a_name )

When =head4 is found. See on_head1.

on_for

When =for is found.

By default '=for' is ignored.

on_item ( $txt )

When =item foo is found.

on_end

When =end is found. See '=begin' above.

on_include ( $file )

When =include is found. Should be used only to handle the localtion of the $file.

on_index_node_start ( $txt , $a_name , $has_children )

Called to build the INDEX. This is called when a node is start. $has_children can be used to know if the node has childs (sub-nodes).

on_index_node_end ( $txt , $a_name , $has_children )

Called to build the INDEX. This is called when a node ends. $has_children can be used to know if the node has childs (sub-nodes).

on_over ( $level )

When =over X is found.

on_textblock ( $txt )

When normal text blocks are found.

on_uri ( $uri )

When an URI (URL, E-MAIL, etc...) is found.

on_verbatim ( $txt )

When VERBATIM data is found, trailing empty lines are deleted.

Note: This interface was previously called "on_verbatin". That interface has been retained for backwards compatibility.

pod2html ( POD_FILE|POD_DATA|FILEHANDLE, HTML_FILE, %OPTIONS )

Convert a POD to HTML. Returns the HTML data generated, as a string or as a list, according to context.

POD_FILE|POD_DATA|GLOB

The POD file (file path), data (SCALAR) or FILEHANDLE (GLOB, opened).

HTML_FILE (optional)

The output HTML file path or FILEHANDLE.

%OPTIONS (optional)
basic_entities

Deprecated.

body

The body values.

Examples:

  body => q`alink="#FF0000" bgcolor="#FFFFFF" link="#000000" text="#000000" vlink="#000066"` ,

  ## Or:

  body => { bgcolor => "#CCCCCC" , link => "#0000FF" } , ## This will overwrite only this 2 values,

Default: alink="#FF0000" bgcolor="#FFFFFF" link="#000000" text="#000000" vlink="#000066"

common_entities

Deprecated.

css

Can be a css file HREF or the css data.

Examples:

  css => 'test.css',

  ## Or:

  css => q`
    BODY {
      background: white;
      color: black;
      font-family: arial,sans-serif;
      margin: 0;
      padding: 1ex;
    }
    TABLE {
      border-collapse: collapse;
      border-spacing: 0;
      border-width: 0;
      color: inherit;
    }
  ` ,
index

Set the index data. If not set the index will be generated automatically, calling the event subs on_index_node_start and on_index_node_end

index_item

If set, items will be added in the index.

no_css

If set do not use css.

no_index

If set, do not build and insert the index.

no_generator

If set, the meta GENERATOR tag won't be added.

only_content

If set only generate the HTML content (between <body>...</body>).

parserwarn

The backend we use is Pod::Parser. This module generates warnings when it detects badly-formed POD. Regretably, it also generates warnings about multiple blank lines, which can be annoying. Thus, it's disabled by default.

title

The title of the HTML. Default: content of the first =head1 NAME, or, failing that the file path

top

Set TOP data. The HTML _top will be added just before the index. If there is a value associated with -top (as in -top uArr) That value will be added to to the head1 text. The value should be either a literal character, a representation of a extended HTML character, (as in uArr) or an existing file.

Utility Functions

default_css

Returns the default CSS.

pm_version ( pod2html )

Return the version of a Perl module file or undef. This is extracted from a statement that looks like "VERSION = 5.0008"

pm_package ( pod2html )

Return the package name of a Perl module file or undef.

pm_name ( pod2html )

Returns what follows the first instance of =head1 NAME description or undef.

pm_package_version_name ( pod2html )

Returns a list: ( pm_package, pm_version, pm_name )

CHARACTER SET

In compliance with HTML 4.01 specification, Pod::HtmlEasy supports the ISO 8859-1 character set (also known as Latin-1). In essence, this means that the full 8-bit character set is supported.

HTML provides an escape mechanism that allows characters to be specified by name; this kind of specification is called an entity.

Some characters must be converted to entities to avoid confusing user agents. This happens automagically. These characters are: &, <, >, "

HTML (via its relationship with SGML) supports a large number of characters that are outside the set supported by ISO 8859-1. These can be specified in the text by using the E&ls;...&gt; construct. These encodings are defined by ISO 10646, which is semi-informally known as UNICODE. http://www.unicode.org/Public/5.0.0/ucd/UCD.html. For example, the "heart" symbol E&l;dhearts&gt;. These are listed in section 24.3.1, The list of characters of the HTML 4.01 specification.

EMBEDDED URIs

Pod::HtmlEasy scans text (but not verbatim text!) for embedded URIs, such as http://foo.bar.com that are not embedded in L&ls;...&gt. Schemes detected are http, https, file and ftp. References of the form foo@bar.com are treated as mailto references and are translated accordingly.

Previous versions handled a more extensive list of URIs. It was thought that the overhead for processing these other schemes was not justified by their utility.

EXTENDING POD

You can extend POD defining non-standard events.

For example, to enable the command "=hr":

  my $podhtml = Pod::HtmlEasy->new(
  on_hr => sub {
            my ( $this , $txt ) = @_ ;
            return "<hr>" ;
           }
  ) ;

To define a new formatting code, do the same thing, but the code must be a single letter.

So, to enable "G<...>":

  my $podhtml = Pod::HtmlEasy->new(
  on_G => sub {
            my ( $this , $txt ) = @_ ;
            return "<img src='$txt' border=0>" ;
          }
  ) ;

DEPENDENCIES

This script requires the following modules:

 L<Pod::HtmlEasy::Parser>
 L<Pod::HtmlEasy::TiehHandler>

 L< Carp>
 L< English>
 L< File::Slurp>
 L< Readonly>
 L< Regexp::Common>
 L< Switch>

DEFAULT CSS

This is the default CSS added to the HTML.

** If you will set your own CSS use this as base.

  BODY {
    background: white;
    color: black;
    font-family: arial,sans-serif;
    margin: 0;
    padding: 1ex;
  }
  TABLE {
    border-collapse: collapse;
    border-spacing: 0;
    border-width: 0;
    color: inherit;
  }
  IMG { border: 0; }
  FORM { margin: 0; }
  input { margin: 2px; }
  A.fred {
    text-decoration: none;
  }
  A:link, A:visited {
    background: transparent;
    color: #006699;
  }
  TD {
    margin: 0;
    padding: 0;
  }
  DIV {
    border-width: 0;
  }
  DT {
    margin-top: 1em;
  }
  TH {
    background: #bbbbbb;
    color: inherit;
    padding: 0.4ex 1ex;
    text-align: left;
  }
  TH A:link, TH A:visited {
    background: transparent;
    color: black;
  }
  A.m:link, A.m:visited {
    background: #006699;
    color: white;
    font: bold 10pt Arial,Helvetica,sans-serif;
    text-decoration: none;
  }
  A.o:link, A.o:visited {
    background: #006699;
    color: #ccffcc;
    font: bold 10pt Arial,Helvetica,sans-serif;
    text-decoration: none;
  }
  A.o:hover {
    background: transparent;
    color: #ff6600;
    text-decoration: underline;
  }
  A.m:hover {
    background: transparent;
    color: #ff6600;
    text-decoration: underline;
  }
  table.dlsip     {
    background: #dddddd;
    border: 0.4ex solid #dddddd;
  }
  .pod PRE     {
    background: #eeeeee;
    border: 1px solid #888888;
    color: black;
    padding-top: 1em;
    white-space: pre;
  }
  .pod H1      {
    background: transparent;
    color: #006699;
    font-size: large;
  }
  .pod H2      {
    background: transparent;
    color: #006699;
    font-size: medium;
  }
  .pod IMG     {
    vertical-align: top;
  }
  .pod .toc A  {
    text-decoration: none;
  }
  .pod .toc LI {
    line-height: 1.2em;
    list-style-type: none;
  }

DIAGNOSTICS

option key is not supported

You've used (mis-spelled?) an unrecognized option.

"basic_entities" is deprecated

Like it says.

"common_entities" is deprecated

Like it says.

No file file

We couldn't find that (input) file.

pm_whatever must be referenced through Pod::HtmlEasy

The various pm_ functions are referenced through the module.

The maintainer would appreciate hearing about any messages other than those that result from the use warnings specified for each module. .

HtmlEasy uses Pod::Parser, which may produce error messages concerning malformed HTML.

SEE ALSO

Pod::Parser perlpod.

CONFIGURATION AND ENVIRONMENT

Neither is relevant.

INCOMPATIBILITIES

None are known.

BUGS AND LIMITATIONS

Please report problems at RT: http://rt.cpan.org/Public/Bug/Report.html?Queue=Pod-HtmlEasy

AUTHOR

Graciliano M. P. <gm@virtuasites.com.br>

I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P

Thanks to Ivan Tubert-Brohman <itub@cpan.org> that suggested to add the basic_entities and common_entities options and for tests.

MAINTENANCE

Updates for version 0.0803 and subsequent by Geoffrey Leach <gleach@cpan.org>

LICENSE AND COPYRIGHT

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.