PPI-HTML-CodeFolder

 view release on metacpan or  search on metacpan

lib/PPI/HTML/CodeFolder.pm  view on Meta::CPAN

        or return undef;

	$outfile = (ref $src) ? '' : "$src.html"
		unless $outfile;
	$script ||= $src 
		unless ref $src || (substr($src, -3) eq '.pm');
#
#	expand tabs as needed (we use 4 space tabs)
#	have to adjust some spans that confuse tab processing
#
	my @lns = split /\n/, $html;
	my $tabsz = $self->{fold}{Tabs};
	foreach my $line (@lns) {
		next if $line=~s/^\s*$//;
		next unless $line=~tr/\t//;
		my $offs = 0;
		my $pad;
#
#	scan for and replace tabs; adjust positions
#	of extracted tags as needed
#
		pos($line) = 0;
		while ($line=~/\G.*?((<[^>]+>)|\t)/gc) {
			$offs += length($2),
			next
				unless ($1 eq "\t");

			$pad = $tabsz - ($-[1] - $offs) % $tabsz;
			substr($line, $-[1], 1, ' ' x $pad);
			pos($line) = $-[1] + $pad - 1;
		}
	}
	$html = join("\n", @lns);

    delete $self->{colors} unless $orig_colors;

    my $opts = $self->{fold};
#
#    extract stylesheet and replace with abbreviated version
#
	my $style = $opts->{Stylesheet} ?
        "<link type='text/css' rel='stylesheet' href='" . 
        	_pathAdjust($outfile, $opts->{Stylesheet}) . "' />" :
        $self->foldCSS();

    $style .= $opts->{Javascript} ?
        "\n<script type='text/javascript' src='" .
        	_pathAdjust($outfile, $opts->{Javascript}) . "'></script>\n" :
        "\n<script type='text/javascript'>\n$ftjs\n</script>\n"
        if $opts->{Expandable};
#
#   original html may have no style, so we've got to add OR replace
#
    $html=~s|</head>|$style</head>|s
        unless ($html=~s|<style type="text/css">.+</style>|$style|s);
#
#	force spans to end before line endings
#
	$html=~s!(<br>\s*)</span>!</span>$1!g;
#
#	split multiline comments into 2 spans: 1st line (in case its midline)
#	and the remainder; note that the prior substitution avoids
#	doing this to single line comments
#
	$html=~s/(?!<br>\s+)(<span class=['"]comment['"]>[^<]+)<br>\n/$1<\/span><br>\n<span class="comment">/g;
#
# keep folded fragments here for later insertion
# as fold DIVs; key is starting line number,
# value is [ number of lines, text ]
#
    my %folddivs = ( 1 => [ 0, '', 0, 0 ]);
#
#    count <br> tags, and looks for any of
#    comment, pod, or use/require keyword (depending on the options);
#    keeps track of start and end position of foldable segments
#
    my $lineno = 1;
    my $lastfold = 1;

	$html=~s/<br>\n/<br>/g;
#
#   now process remainder
#
	study $html;
    pos($html) = 0;
    $html=~/^.*?(<body[^>]+><pre>)/s;
	my $startpos = $+[1];
#
#	map linebreak positions to line numbers
#
	my @lnmap = (0, $startpos);
	push @lnmap, $+[1]
	    while ($html=~/\G.*?(<br>)/gcs);
#
#	now scan for foldables
#
	pos($html) = $startpos;
	my @folds = _extractFolds(\$html, $startpos, \@lnmap, $opts);
#
#	trim small folds;
#   since its used frequently, create a sorted list of the fold DIV lines;
#	isolate positions of folds and extract folded content
#
	my $ln = 0;
	my @ftsorted = ();
	foreach (@folds) {
		if ($_->[1] - $_->[0] + 1 >= $opts->{MinFoldLines}) {
			$folddivs{$_->[0]} = [ $_->[1], substr($html, $lnmap[$_->[0]], $lnmap[$_->[1] + 1] - $lnmap[$_->[0]]), 
				$lnmap[$_->[0]], $lnmap[$_->[1] + 1] ];
			push @ftsorted, $_->[0];
		}
		elsif ($self->{_verbose}) {
#			print "*** skipping section at line $_->[0]to $_->[1]\n";
#			print substr($html, $lnmap[$_->[0]], $lnmap[$_->[1] + 1] - $lnmap[$_->[0]]), "\n";
		}
	}
#
#    now remove the folded lines; we work from bottom to top since
#    we're changing the HTML as we go, which would invalidate the
#    positional elements we've kept. If fold expansion is enabled, we replace
#    w/ a hyperlink; otherwise we replace with a simple indication of the fold



( run in 1.132 second using v1.01-cache-2.11-cpan-71847e10f99 )