package Safari::Edit::p4 ; =head1 Safari::Edit::p4 - add banners, menus to Safari output for p4 archives =head1 DESCRIPTION This module can be used by saf_http_out to alter the contents of a page before it is sent to a browser. This is used to add a banner and menus to text and html pages. =cut use strict ; use File::Basename ; use HTML::Entities qw( encode_entities ) ; use vars qw( @options ) ; # # Allow extra command line options to be passed in. # @::option_specs = ( @::option_specs, 'title=s', ) ; # # edit() gets called by saf_http_out according to the settings in it's # configuration file. It may change any of the options (like file-type) # or any headers or the contents. # # $options is a ref to a hash containing command line options # $headers is a ref to an array of strings containing header lines in # the order they are to be printed, like "Content-type: text/html". # $contents is a ref to a scalar containing the entire contents of the file # to be modified. # sub edit { my ( $options, $headers, $contents ) = @_ ; my $file_type = $options->{'file-type'} ; my $mime_type = $options->{'mime-type'} ; my $source_file_type = $options->{'source-file-type'} ; my $source_mime_type = $options->{'source-mime-type'} ; return unless $mime_type eq 'text/html' ; my $title = ( exists $options->{'title'} && $options->{'title'} ) || '' ; my $project = $ENV{SAF_PROJECT} ; my $up_to_project = $ENV{SAF_UP_TO_PROJECT} ; my $up_to_rev = $ENV{SAF_UP_TO_REV} ; my $up_to_filter = $ENV{SAF_UP_TO_FILTER} ; my $rev = $ENV{SAF_REV} ; my $filter = $ENV{SAF_FILTER} ; my $file = $ENV{SAF_FILE} ; $rev =~ s/^_/#/ ; $title = "$file" if ( length( $title ) == 0 ) ; $title = encode_entities( $title ) . "
" ; my $locator = locator( $up_to_project, $project, $rev, $filter ) ; my $project_menu = project_menu( $source_file_type, $source_mime_type, $up_to_project, $up_to_filter, $filter, $file, $project ) ; my $filter_menu = filter_menu( $source_file_type, $source_mime_type, $up_to_rev, $filter, $file ) ; my $tool_menu = tool_menu( $source_file_type, $source_mime_type, $filter, $file ) ; my $file_date = localtime ; # # Set up sections to insert # my $header = qq{
$locator $title
$project_menu$filter_menu$tool_menu } ; my $footer = qq{
This page generated by Safari at $file_date
} ; # # insert them # $$contents = "$header$$contents" unless $$contents =~ s@()@$header@ims ; $$contents .= $footer unless $$contents =~ s@()@$footer$1@ims ; return 1 ; } ############################################################################# sub locator { my ( $up_to_project, $project, $rev, $filter ) = @_ ; my $rev_anchor ; $project = encode_entities( $project ) ; $filter = encode_entities( $filter ) ; for ($rev) { my ( $stripped ) = /^@(.*)/ ; my $enc_rev = encode_entities( $_ ) ; $rev_anchor = /^@\d+$/ ? qq{$enc_rev} : /^#head$/ ? qq{$enc_rev} : /^@[^\d].*$/ ? qq{$enc_rev} : $enc_rev ; } # my $prev_change_anchor = "<" ; # my $next_change_anchor = ">" ; return qq{
PROJ: $project
REV: $rev_anchor
FILT: $filter
} ; } sub project_menu { my ( $file_type, $mime_type, $up_to_project, $up_to_filter, $filter, $file, $project ) =@_ ; my $project_url = "$up_to_filter" ; my $basename = basename( $file ) ; # # If we're browsing a file, then 'up' means go to our current directory, # otherwise it means '..', unless we're at the top of this filter. # my $up_url = ( $file =~ m@./$@ ) ? '../' : '' ; my $query_string = $ENV{QUERY_STRING} ; $query_string =~ s/force=yes&?//g ; $query_string =~ s/&force=yes//g ; $query_string =~ s/project=[^&]+&?//g ; $query_string =~ s/&project=[^&]//g ; # # We don't bother setting project= here because it's picked up out of # $script_uri. Of course, this needs to change... # my $reload_url = "$basename?force=yes&$query_string" ; my $project_anchor = "top" ; my $up_anchor = length( $up_to_filter ) ? "up" : "up" ; my $rebuild_anchor = "rebuild" ; my @reports = qw( changes labels ) ; for ( @reports ) { unless ( $_ eq $filter ) { my $url = $_ ; $url = "${up_to_project}_head/$_/index.html" ; $_ =~ s/ / / ; $_ = "$_" ; } } return build_menu( 'PROJECT', $project_anchor, $up_anchor, @reports, $rebuild_anchor, ) ; } sub filter_menu() { my ( $file_type, $mime_type, $up_to_rev, $filter, $file ) = @_ ; return '' if $file !~ m@[^/]$@ || grep( /^(changes|labels)$/, $filter ) ; my @filters = qw( Default ChLines NoMenus None pretty plain ) ; unshift( @filters, 'POD' ) if grep{ $_ eq $file_type } qw( perl ) ; @filters = sort { lc($a) cmp lc($b) } @filters ; for ( @filters ) { # unless ( $_ eq $filter ) { my $url = "$up_to_rev$_/$file" ; $_ =~ s/ / / ; $_ = "$_" ; # } # else { # $_ =~ s/ / / ; # } } return build_menu( 'FILTERS', @filters ) ; } sub tool_menu() { my ( $file_type, $mime_type, $filter, $file ) = @_ ; return '
' if $file !~ m@[^/]$@ || grep( /^(changes|labels)$/, $filter ) ; my @tools = qw( Download wc /_head/filelog ) ; unshift( @tools, 'gcclint' ) if grep { $_ eq $file_type } qw( c c++ ) ; @tools = sort { lc($a) cmp lc($b) } @tools ; my $basename = basename( $file ) ; # # 'tools' should not change the current filter. So, tools are launched # using a QUERY_STRING targets= entry which overrides the PATH_INFO # section when the make is done. This allows PATH_INFO to be unchanged # and the tool to be run instead. # for ( @tools ) { unless ( $_ eq $filter ) { my $url = $_ ; $url =~ s/ /_/ig ; if ( substr( $url, 0, 1 ) eq '/' ) { my ( $new_rev, $new_filter ) = m@/([^/]*)/(.*)@ ; $url = "$basename?rev=$new_rev&filter=$new_filter" ; } else { $url = "$basename?filter=$url" } $_ =~ s@^/[^/]*/@@ ; $_ =~ s/ / / ; $_ = "$_" ; } } return build_menu( 'TOOLS', @tools ) ; } sub build_menu { my $name = shift ; $name = qq{$name} ; return join( "
\n     ", $name, @_) . "

\n"; }