ServDoc_html - turn output of ServDoc modules in a readable html-page
$Id: ServDoc_html,v 1.17 2004/02/17 09:51:09 uherbst Exp $
ServDoc_html [-h|help] [-v|version] [--debug HTML,intensity]
ServDoc_html reads the collected output from different ServDoc modules from STDIN and tries to put that in a readable HTML Format with table of contents.
Every Headline in the input becomes a HTML-Headline.
Before and after the HTML-text, two file named ``header.html'' and ``footer.html'' (in the html-subdirectory) will be included.
``%h'' in the header file will be substituted with the hostname (eg. in the HTML-title).
The debug feature for that module is named ``HTML''.
Ulrich Herbst <Ulrich.Herbst@gmx.de>
#!/usr/bin/perl
#---------------------------------------------------------------------- # standard perl modules use strict; # print error about unknown variables ... use English; # long internal variable names; use FindBin; # In which directory is ServDoc itself ? # There has to be the module and the lib dir! use lib $FindBin::Bin. "/lib"; # Here are the ServDoc-perl-modules use Sys::Hostname; # our own perl modules use ServDoc; use ServDocOutput; use XML::Simple::PurePerl; #---------------------------------------------------------------------- my $options; $options->{Version} = '$Name: $'; # $Name r0-7b $ -> r0-7b $options->{Version} =~ s/\$//g; $options->{Version} =~ s/Name: r(.*) .*/$1/; #0-7b -> 0.7b $options->{Version} =~ s/-/./g; # If we haven't a $Name: $-Tag (because we haven't a CVS-Release): put # "nightly" as version $options->{Version} =~ s/^Name.*/nightly/; %{$options->{lang}->{en}} = ( toc => "Table of Contents", ); %{$options->{lang}->{de}} = ( toc => "Inhaltsverzeichnis", ); # We need the cmdline to call the modules with the same debug options. $options->{cmdline} = join " ", @ARGV; sub debug { ServDoc_debug( "HTML", $options, shift, shift ); } $options = &process_cmdline($options); debug( 9, "ServDoc_html is running" ); #---------------------------------------------------------------------- # Main # include header my $headerfile="$FindBin::Bin/html/header.html"; my $headerfile_lang = "$FindBin::Bin/html/header." . $options->{output_i18n} . ".html"; if (-e $headerfile_lang) { $headerfile=$headerfile_lang; } my $footerfile="$FindBin::Bin/html/footer.html"; my $footerfile_lang = "$FindBin::Bin/html/footer." . $options->{output_i18n} . ".html"; if (-e $footerfile_lang) { $footerfile=$footerfile_lang; } open( FILE, "< $headerfile" ) or die "can't open $headerfile: $!\n"; my $HOSTNAME = hostname(); # %h -> hostname # %r -> CVS-Release while (<FILE>) { s/%h/$HOSTNAME/g; s/%r/$options->{Version}/g; print; } close(FILE); my $html_output = ''; my $html_content = "<h1>" . i18n_mesg('toc') . "</h1>\n<ul>\n"; my @last_headings = (''); my $heading_count=0; # Inputs are on STDIN my $xmldata=join "",<STDIN>; my $xmltree=XMLin($xmldata,keyattr=>"",forcearray=>1,forcecontent=>1); for (my $i=0; $i<=$#{@{$xmltree->{SDitem}}}; $i++) { my $html_new_content = ''; my ($short_desc,$long_desc,$text,$tableref,@headings) = get_and_normalize_SDitem_data($xmltree->{SDitem}->[$i]); # Put & -> & ... in $text $text = html_encode($text); debug( 8, "---------------------------" ); my $heading_equal; for ( $heading_equal = 0 ; $heading_equal <= $#headings ; $heading_equal++ ) { if ( $last_headings[$heading_equal] ne $headings[$heading_equal] ) { last; } } debug( 8, "Actual Headings : " . join " .. ", @headings ); debug( 8, "Last Headings : " . join " .. ", @last_headings ); debug( 8, "Heading and previous are unequal from $heading_equal" ); # in $heading_equal is the number of the first unequal heading # between the new "@headings" and the headings from the last line; # Close all unused <ul>-Tags $html_new_content .= "</ul>\n" x ( $#last_headings - $heading_equal ); debug( 8, ( $#last_headings - $heading_equal ) . "<ul>'s closed" ); # Write new headings for ( my $x = $heading_equal ; $x < $#headings ; $x++ ) { my $hnr = ( $x > 5 ? 6 : $x + 1 ); $html_output .= "<h$hnr><a name=\"$headings[$x]_$heading_count\">" . "$headings[$x]</a></h$hnr>\n"; $html_new_content .= "<li><a href=\"#$headings[$x]_$heading_count\">$headings[$x]</a>\n" . "<ul>\n"; debug( 8, "<ul> opened ($headings[$x])" ); $heading_count++; } my $hnr .= ( $#headings > 5 ? 6 : $#headings + 1 ); $html_output .= "<h$hnr><a name=\"$headings[-1]_$heading_count\">" . "$headings[-1]</a></h$hnr>\n"; $html_output .= "$short_desc\n<p>$long_desc\n<p>"; # Are there tables to output ? if (ref($tableref) eq "ARRAY") { $html_output .= make_table($tableref->[0])."\n<hr>\n"; } $html_output .= "<pre>$text</pre>\n<hr>\n" if ($text); $html_new_content .= "<li><a href=\"#$headings[-1]_$heading_count\">$headings[-1]</a>\n"; $heading_count++; @last_headings=@headings; debug( 8, "New TOC entry: $html_new_content" ); $html_content .= $html_new_content; } # while (<>) for ( my $x = 0 ; $x <= $#last_headings ; $x++ ) { $html_content .= "</ul>\n"; } print $html_content; print "\n<hr>\n"; print $html_output; open( FILE, "< $footerfile" ) or die "can't open $footerfile: $!\n"; while (<FILE>) { s/%h/$HOSTNAME/g; print; } close(FILE); # Make HTML-Chars: # "<", ">" sub html_encode { my $text = shift; # It is important to translate & BEFORE the others (or the # translation will go wrong) $text =~ s/&/&/g; $text =~ s/</</g; $text =~ s/>/>/g; $text =~ s/"/"/g; return $text; } # make a HTML-Table: sub make_table { my $ref=shift; my $output = readfile("$FindBin::Bin/html/table_header.html"); my $tr; for ($tr=0; $tr<=$#{@{$ref->{'tr'}}};$tr++) { $output .=" <tr>"; my $td; for ($td=0; $td <=$#{@{$ref->{'tr'}->[$tr]->{th}}}; $td++) { $output .="<th>" . $ref->{'tr'}->[$tr]->{th}->[$td]->{content} . "</th>"; }; for ($td=0; $td <=$#{@{$ref->{'tr'}->[$tr]->{td}}}; $td++) { $output .="<td>" . $ref->{'tr'}->[$tr]->{td}->[$td]->{content} . "</td>"; }; $output .="</tr>\n"; }; # rows $output .= readfile("$FindBin::Bin/html/table_footer.html"); return $output; }