package Pod::HTML; =head1 NAME Pod::HTML - Translate POD into HTML file =head1 SYNOPSIS use Pod::HTML; =head1 DESCRIPTION =cut package Pod::HTML; sub import {} use Pod::Simplify; use HTML::AsSubs; use HTML::Element; use HTML::Entities; =item findindex REF, PATH, [PATH, ...] Find the index. =cut sub findindex { my(@a) = @_; shift @a; my(@look) = map(join("/",@$_),@a); my($match)=0; foreach(@look) { if($match = $idx{$_}) { last; } } $match; } =item flowed ARRAY Translate the array of annotations into HTML. Recurses over contained arrays. For now, leave a tag ("{t}") for each type "t" to show the translation rule for ambiguous constructs. =cut sub flowed { my(@out); # contains pieces of HTML::Element foreach $i (@_) { if(ref $i eq "ARRAY") { my(@i) = (@$i); my($c) = shift @i; if($c eq "B") { # Bold push(@out, b(flowed(@i))); } elsif($c eq "I") { # italic push(@out, i(flowed(@i))); } elsif($c eq "V") { # Variable push(@out, "``", code({'type'=>'v'}, flowed(@i)), "''"); } elsif($c eq "P") { # Procedure push(@out, i({'type'=>'p'}, flowed(@i))); } elsif($c eq "F") { # Filename push(@out, em({'type'=>'f'}, flowed(@i))); } elsif($c eq "S") { # Switch push(@out, b({'type'=>'s'}, flowed(@i))); } elsif($c eq "C") { # Code push(@out, code(flowed(@i))); } elsif($c eq "R") { # Reference my($id) = findindex(@i); my(@annotated) = flowed(@{$i[0]}); if ( $id ) { push(@out, a({'href'=>($id->[2] ne "foo" ? $id->[2] : "")."#".$id->[0]}, @annotated)); } else { push(@out, @annotated); } } elsif($c eq "X") { # Index my($id) = findindex(@i); push(@out, a({'name'=>$id->[0]}, flowed(@{$i[0]}))); } elsif($c eq "E") { # Escape my($v) = "&".$i[0].";"; decode_entities($v); push(@out, $v); } else { push(@out, "{$c:", flowed(@i),"}"); } } else { # Simple text reference push(@out, &simpleText($i)); } } return @out; } =item simpleText TEXT Pick off the initial characters of the text, and apply an outstanding index item to them. The deferred index is in array @waitingindex. Also, translate special characters. Return either a text item or an array. =cut sub simpleText { my($i) = @_; my(@out); while(@waitingindex and length($i)) { my($c) = substr($i,0,1); push(@out, a({'name'=>(shift @waitingindex)}, $c)); substr($i,0,1)=""; } if ( @out ) { return (@out, $i); } return $i; } @listtype=(); $idx=0; sub doindex { foreach (@_) { if(ref $_ eq "ARRAY") { my(@i) = @$_; my($i) = shift @i; if( $i eq "X") { shift @i; # discard printable block $idx++; $name = join("/",@{$i[0]}); $name =~ s/([^A-Za-z0-9_])/ "%".sprintf("%.2X",ord($1)) /ge; foreach (@i) { $idx{join("/",@$_)} = [$name,$idx,"perlvar.pod"]; } #print "Index: ",Simplify::dumpout([@i]),"\n"; } else { doindex(@i); } } } } sub dump1 { my($par,$line,$pos,$cmd,$var1,$var2) = @_; # Save the parsed data for later processing push(@results,@_); if( $cmd =~ /^(item|head|flow|index)$/) { doindex(@$var2); } } =item comment COMMENTS Create a comment HTML element. Currently, will not be printed in normal HTML display. =cut sub comment { my $cmt = new HTML::Element 'comment'; $cmt->push_content(@_); return $cmt; } @formatStack = (); sub Format { my($par,$line,$pos,$cmd,$var1,$var2) = @_; #print "cmd = $cmd\n"; if( $cmd eq "begin" ) { if($var1 eq "list") { my $f; if($var2 eq "bullet") { $f = ul(); } elsif($var2 eq "number") { $f = ol(); } else { $f = dl(); } $formatted->push_content($f); push(@formatStack, $formatted); $formatted = $f; } elsif($var1 eq "pod") { $documentTitle = title(); $documentTitle->push_content($var2->[0]); $documentHead = head($documentTitle); $documentBody = body(); $document = html($documentBody); # $formatted retains the element pointer $formatted = $documentBody; @formatStack = (); } } elsif( $cmd eq "end" ) { if($var1 eq "list") { $formatted = pop(@formatStack); } elsif($var1 eq "pod") { print $document->as_HTML(); } } elsif( $cmd eq "item") { # print "v=".Simplify::dumpout($var2)."\n"; if($var1->[0] eq "bullet" or $var1->[0] eq "number") { $formatted->push_content(li(flowed(@$var2))); } else { $formatted->push_content(dt(strong(flowed(@$var2)))); push(@formatStack, $formatted); $f = dd(); $formatted->push_content($f); $formatted = $f; } } elsif( $cmd eq "head") { my($head) = new HTML::Element "h".$var1; $head->push_content(flowed(@$var2)); if ( $var1 < 2 ) { $formatted->push_content(hr()); } $formatted->push_content($head); } elsif( $cmd eq "verb") { $var1 =~ s/^/ /gm; my $pre = pre(simpleText($var1)); $formatted->push_content($pre); } elsif( $cmd eq "flow") { @f = flowed(@$var2); if ( $formatted->tag eq 'dd' ) { # First element of definition. # Don't use a paragraph here $formatted->push_content(@f); } else { $formatted->push_content(p(@f)); } } elsif( $cmd eq "comment" ) { $var1 =~ s/--/- -/g; $var1 =~ s//gt/g; $formatted->push_content(comment($var1)); } elsif( $cmd eq "index") { push(@waitingindex,map(join("/",@$_),@{$var2->[0]})); } } #$x->parse_from_file_by_name("newvar.pod",\&dump1); #$x->parse_from_file_by_name($ARGV[0] || "newfunc.pod",\&dump2); #write index #foreach (sort keys %idx) { # print join(" ",$_,@{$idx{$_}}),"\n"; #} #dump2(@_) while(@_=splice(@results,0,6)); 1;