NAME

PPI::HTML::CodeFolder - PPI::HTML Subclass providing code folding and compression

SYNOPSIS

    use strict;
    use File::Slurp ();
    use PPI;
    use PPI::HTML::CodeFolder;
    use CSS::Tiny;
    #
    # Get the file
    #
    my $file = shift @ARGV;
    $file    or die "File '$file' not provided";
    -f $file or die "File '$file' does not exist";
    #
    # Determine the output file
    #
    my $output = shift(@ARGV) || $file . '.html';
    my $foldjs = $output;
    $foldjs=~s/\.html/\.js/;
    my $foldcss = $output;
    $foldcss=~s/\.html/\.css/;
    #
    #    PPI the file
    #
    my $Document = PPI::Document->new( $file )
        or die "File '$file' could not be loaded as a document";
    #
    #    define our classname abbreviations
    #
    my %classabvs = qw(
    arrayindex ai
    backtick bt
    cast cs
    comment ct
    core co
    data dt
    double db
    end en
    heredoc hd
    heredoc_content hc
    heredoc_terminator ht
    interpolate ip
    keyword kw
    label lb
    line_number ln
    literal ll
    magic mg
    match mt
    number nm
    operator op
    pod pd
    pragma pg
    prototype pt
    readline rl
    regex re
    regexp re
    separator sp
    single sg
    structure st
    substitute su
    symbol sy
    transliterate tl
    word wd
    words wd
    );
    #
    #    define colors for the full classnames
    #
    my %tagcolors = (
    cast => '#339999',
    comment => '#008080',
    core => '#FF0000',
    double => '#999999',
    interpolate => '#999999',
    keyword => '#0000FF',
    line_number => '#666666',
    literal => '#999999',
    magic => '#0099FF',
    match => '#9900FF',
    number => '#990000',
    operator => '#DD7700',
    pod => '#008080',
    pragma => '#990000',
    regex => '#9900FF',
    single => '#999999',
    substitute => '#9900FF',
    transliterate => '#9900FF',
    word => '#999999',
    );
    #
    # Create the PPI::HTML::CodeFolder object
    #
    my $html = PPI::HTML::CodeFolder->new(
        line_numbers => 1,
        page         => 1,
        colors       => \%tagcolors,
        fold          => {
            POD           => 1,
            Comments      => 1,
            Imports       => 1,
            Foldtips      => 1,
            Abbreviate    => \%tagabvs,
            Javascript    => $foldjs,
            Stylesheet    => $foldcss,
            },
        )
        or die "Failed to create HTML syntax highlighter";
    #
    #    collect stylesheet and javascript; we'll server those
    #    separately
    #
    File::Slurp::write_file( $foldjs, $html->fold_javascript());
    File::Slurp::write_file( $foldcss, $html->fold_css());
    #
    # Process the file
    #
    my $content = $html->html( $Document )
        or die "Failed to generate HTML";

    File::Slurp::write_file( $output, $content );

DESCRIPTION

A subclass of PPI::HTML that attempts to compress the generated output by

The amount of compression that can be achieved varies signficantly, depending on the size and nature of the source code. Gregarious modules with lots of commentary and POD can be significantly reduced (assuming foldtips are disabled); E.g., some simple benchmarks using perl5db.pl (on WinXP, Perl 5.8.6):

                 Original Source:   323,204
                PPI::HTML Output: 1,008,919
    PPI::HTML::CodeFolder Output:
                   (w/ foldtips):   678,981
                  (wo/ foldtips):   475,022

As always, YMMV.

Samples

Folded version of CodeFolder.pm
Folded version of perl5db.pl (disabled due to download size)
CAUTION: Firefox (tested versions 1.5 on WinXP, 2.0 on OS X) has serious performance issues with the perl5db.pl output! Both IE6 and Safari (2.0.4) handled it reasonably well.

METHODS

$ppicf = PPI::HTML::CodeFolder->new( %args )

Same as the PPI::HTML constructor, with the addition of a fold parameter, which specifies a hashref of folding properties. If not specified, a default folding is applied (see individual fold properties below for default behavior). In addition, the PPI::HTML page property is always enabled.

NOTE that using the css parameter is strongly discouraged, as the folding alignment and tooltips are very sensitive to stylesheet changes. Instead, use the fold Stylesheet option (see below) to export the CSS to an external file, and directly edit it.

Folding properties include:

Abbreviate => \%abbreviations | $boolean

Specifies a mapping of standard PPI::HTML class names to an alternate (presumably abbreviated) version. If a 'true' scalar is specified, enables abbreviation using the default mapping; if a 'false' scalar is specified, disables abbreviation. Default is to abbreviate.

The default abbreviation map is

    arrayindex         => ai
    backtick           => bt
    cast               => cs
    comment            => ct
    core               => co
    data               => dt
    double             => db
    end                => en
    heredoc            => hd
    heredoc_content    => hc
    heredoc_terminator => ht
    interpolate        => ip
    keyword            => kw
    label              => lb
    line_number        => ln
    literal            => ll
    magic              => mg
    match              => mt
    number             => nm
    operator           => op
    pod                => pd
    pragma             => pg
    prototype          => pt
    readline           => rl
    regex              => re
    regexp             => re
    separator          => sp
    single             => sg
    structure          => st
    substitute         => su
    symbol             => sy
    transliterate      => tl
    word               => wd
    words              => wd

Abbreviation helps compression due to the large number of <span> tags with class specifications in the output.

NOTE: any colormap provided to the constructor (via the color|colour parameter) must use the full classname, not the abbreviated name.

Comments => $boolean

If a true value, comment lines are included in folding. Comment lines include only a comments and whitespace. Default is to include comment lines.

Foldtips => $boolean

If a true value, the replacement for the folded source is a hyperlink to a tooltip which will popup a small window with the folded source when the mouse hovers over the link. Default is false.

Imports => $boolean

If a true value, 'use' statements are included in folding. All statements which begin with 'use', including various pragmas, will be folded. Default is false.

Javascript => $filename

Causes the foldtip javascript to be linked by referencing the specified $filename, rather than embedded in the output HTML. Default is embedded; ignored if Foldtips is false.

MinFoldLines => $number

Specifies the minimum number of consecutive foldable lines required to actually apply folding. Default is 4. E.g., a value of 4 means that 3 consecutive comment lines, followed by valid statement, will not be folded.

POD => $boolean

If a true value, POD lines are included in folding. Default is to include POD lines.

Stylesheet => $filename

Causes color and foldtip CSS to be linked by referencing the specified $filename, rather than embedded in the output HTML. Default is embedded.

$javascript = $html->fold_javascript()

Returns the Javascript required for foldtips as a string.

$css = $html->fold_css()

Returns the CSS required for the generated HTML as a string.

NOTES

SEE ALSO

PPI

PPI::HTML

TO DO

AUTHOR, COPYRIGHT, & LICENSE

Copyright(C) 2007, Dean Arnold, Presicient Corp., USA. All rights reserved.

Permission is granted to use this software under the terms of the Perl Artistic License.