PPI::HTML::CodeFolder - PPI::HTML Subclass providing code folding and compression
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 );
A subclass of PPI::HTML that attempts to compress the generated output by
<span> classnames<span>'s to a single table column with a single class, with the source body contained in the 2nd table column.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.
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:
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.
If a true value, comment lines are included in folding. Comment lines include only a comments and whitespace. Default is to include comment lines.
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.
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.
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.
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.
If a true value, POD lines are included in folding. Default is to include POD lines.
Causes color and foldtip CSS to be linked by referencing the specified $filename, rather than embedded in the output HTML. Default is embedded.
Returns the Javascript required for foldtips as a string.
Returns the CSS required for the generated HTML as a string.
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.