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.