# Copyright (C) 1998-09 Stephane Galland # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. =pod =head1 NAME Bib2HTML::Generator::Theme - A theme for the HTML generator =head1 SYNOPSYS use Bib2HTML::Generator::Theme ; my $gen = Bib2HTML::Generator::Theme->new( generator, bib2html, target, title, lang ) ; =head1 DESCRIPTION Bib2HTML::Generator::Theme is a Perl module, which proposes a documentation theme for the HTML generator of bib2html. =head1 GETTING STARTED =head2 Initialization To start a generator script, say something like this: use Bib2HTML::Generator::Theme; my $gen = Bib2HTML::Generator::Theme->new( $generator, { 'VERSION' => '0.11' }, './bib_output', 'Title', $lang ) ; ...or something similar. Acceptable parameters to the constructor are: =over =item * parent (object ref) is a reference to the current HTML generator. =item * bib2html (hash) contains some data about bib2html. =item * target (string) The directory in which the documentation must be put. =item * title (string) is the title of the documentation. =item * lang (object ref) is a reference to the language object. =back =head1 METHOD DESCRIPTIONS This section contains only the methods in Theme.pm itself. =over =cut package Bib2HTML::Generator::Theme; @ISA = ('Exporter'); @EXPORT = qw(); @EXPORT_OK = qw(); use strict; use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION); use Exporter; use Carp ; use File::Spec ; use Bib2HTML::General::Verbose ; use Bib2HTML::General::Error ; use Bib2HTML::General::HTML ; use Bib2HTML::General::Misc ; use Bib2HTML::Generator::FileWriter ; use Bib2HTML::Generator::StdOutWriter ; #------------------------------------------------------ # # Global vars # #------------------------------------------------------ # Version number of theme my $VERSION = "2.0" ; #------------------------------------------------------ # # Constructor # #------------------------------------------------------ sub new($$$$$) : method { my $proto = shift; my $class = ref($proto) || $proto; my $self = { 'PARENT' => $_[0] || confess( 'you must supply the parent object' ), 'BIB2HTML' => $_[1] || '', 'TARGET_DIR' => $_[2] || confess( 'you must supply the target directory' ), 'TITLE' => $_[3] || '', 'LANG' => $_[4] || confess( 'you must supply the language object' ), } ; my $simpleclass = $class; if ($class =~ /^.*::(.+?)$/) { $simpleclass = "$1"; } # Register lang files if ($self->{'LANG'}) { $self->{'LANG'}->registerLang("Theme.$simpleclass"); } bless( $self, $class ); return $self; } =pod =item * copy_files() Copies some files from the bib2html distribution directly inside the HTML documentation tree. =cut sub copy_files() : method { my $self = shift ; } =pod =item * get_stream_writer() Replies the instance of the output stream writer. =cut sub get_stream_writer() : method { my $self = shift ; if (!$self->{'STREAM_WRITER'}) { $self->{'STREAM_WRITER'} = new Bib2HTML::Generator::FileWriter->new(); } return $self->{'STREAM_WRITER'}; } =pod =item * set_stream_writer($) Set the instance of the output stream writer. Replies the old writer. Takes 1 arg: =over =item * writer (ref to Bib2HTML::Generator::Writer) is the instance of the writer. =back =cut sub set_stream_writer($) : method { my $self = shift ; my $writer = shift; my $old_writer = $self->{'STREAM_WRITER'}; $self->{'STREAM_WRITER'} = $writer; return $old_writer; } #------------------------------------------------------ # # Filename API # #------------------------------------------------------ =pod =item * ext_href() Replies a hyperlink according to the parameters Takes 3 args: =over =item * section (string) is the id of the section. =item * label (string) is the label of the hyperlink =item * rootdir (string) is the path to the root directory. =back =cut sub ext_href($$$) : method { my $self = shift ; my $section = shift || confess( 'you must supply the section id' ) ; my $label = shift || '' ; my $rootdir = shift || confess( 'you must supply the root directory' ) ; return $self->href( htmlcatfile($rootdir,$self->filename($section,@_)), $label, $self->browserframe($section) ) ; } =pod =item * ext_wt_href() Replies a hyperlink according to the parameters (without target) Takes 3 args: =over =item * section (string) is the id of the section. =item * label (string) is the label of the hyperlink =item * rootdir (string) is the path to the root directory. =back =cut sub ext_wt_href($$$) : method { my $self = shift ; my $section = shift || confess( 'you must supply the section id' ) ; my $label = shift || '' ; my $rootdir = shift || confess( 'you must supply the root directory' ) ; return $self->href( htmlcatfile($rootdir,$self->filename($section,@_)), $label ) ; } =pod =item * filename() Replies the filename of the specified section. Takes 1 arg: =over =item * section (string) is the name of the section. =back =cut sub filename : method { my $self = shift ; return $self->{'PARENT'}->filename(@_) ; } =pod =item * browserframe() Replies the frame used for the specified section. Takes 1 arg: =over =item * section (string) is the name of the section. =back =cut sub browserframe : method { my $self = shift ; return $self->{'PARENT'}->browserframe(@_) ; } #------------------------------------------------------ # # Page API # #------------------------------------------------------ =pod =item * get_copyright() Replies a string that represents the copyright of this translator. =over =item * rootdir (string) is the path to the root directory =back =cut sub get_copyright($) : method { my $self = shift ; my $rootdir = $_[0] ; return join( '', $self->par( $self->small( $self->href( $self->{'BIB2HTML'}{'BUG_URL'}, $self->{'LANG'}->get( 'I18N_LANG_SUBMIT_BUG'), "_top" ) ) ), $self->par( $self->small( $self->{'LANG'}->get( 'I18N_LANG_BIB2HTML_COPYRIGHT', $self->href( $self->{'BIB2HTML'}{'URL'}, "bib2html ".$self->{'BIB2HTML'}{'VERSION'}, "_top" ), $self->href( "mailto:".$self->{'BIB2HTML'}{'AUTHOR_EMAIL'}, $self->{'BIB2HTML'}{'AUTHOR'} ), $self->href( "http://www.gnu.org/copyleft/gpl.html", "GNU General Public License", "_top" ) ) ) ) ) ; } =pod =item * get_html_index() Replies the content of the main index.html Takes 1 arg: =over =item * rootdir (string) is the path to the root directory. =back =cut sub get_html_index($) { my $self = shift ; my $rootdir = $_[0] || confess( 'you must supply the root directory' ) ; return join( '', "\n", "\n", "filename('overview-frame')), "\" name=\"", $self->browserframe('overview-frame'), "\">\nfilename('allelements')), "\" name=\"", $self->browserframe('allelements'), "\">\n\nfilename('overview-summary')), "\" name=\"", $self->browserframe('overview-summary'), "\">\n\n", $self->{'LANG'}->get('I18N_LANG_NO_FRAME_ALERT', $self->filename('overview-summary'), ''), "\n", "\n" ) ; } =pod =item * create_html_page() Creates an HTML page without a . Takes 3 args: =over =item * filename (string) is the name of the file in which the page must be created. =item * content (string) is the content of the page. =item * title (string) is the title of the page. =item * rootdir (string) is the path to the root directory. =item * frameset (boolean) must be true if the generated page must respect the w3c frameset definition, otherwhise it will respect the w3c transitional definition =back =cut sub create_html_page($$$$$) : method { my $self = shift ; my $rootdir = $_[3] || confess( 'you must supply the root directory' ) ; confess( 'you must supply the filename' ) unless $_[0] ; my $filename = File::Spec->catfile( $self->{'TARGET_DIR'}, htmlpath($_[0]) ) ; Bib2HTML::General::Verbose::two( "Writing $filename..." ) ; my $writer = $self->get_stream_writer(); $writer->openstream("$filename") or Bib2HTML::General::Error::syserr( "$filename: $!\n" ); my $header ; if ( $_[4] ) { $header = "" ; } else { $header = "" ; } $writer->out(join( '', $header, "\n\n\n\n", "\n\n", $_[2] || '', "\n", "\n", $self->get_html_header($rootdir), "\n", $_[1] || '', "" ) ) ; $writer->closestream() ; } =pod =item * get_html_encoding() Replies the HTML encoding of each page (by default ISO-8859-1). =cut sub get_html_encoding() : method { my $self = shift ; return $self->{'html_encoding'} || "ISO-8859-1" ; } =pod =item * set_html_encoding($) Set the HTML encoding of each page Takes 1 arg: =over =item * encoding (string) is the new encoding =back =cut sub set_html_encoding($) : method { my $self = shift ; my $encoding = shift; $self->{'html_encoding'} = $encoding if ($encoding) ; } =pod =item * get_html_header() Replies the HTML header of each page. Takes 1 arg: =over =item * rootdir (string) is the path to the root directory =back =cut sub get_html_header($) : method { my $self = shift ; return '' ; } =pod =item * create_html_body_page() Creates an HTML page with a . Takes 3 args: =over =item * filename (string) is the name of the file in which the page must be created. =item * content (string) is the content of the page. =item * title (string) is the title of the page. =item * rootdir (string) is the path to the root directory. =back =cut sub create_html_body_page($$$$@) : method { my $self = shift ; my $filename = shift ; my $content = shift ; my $title = shift ; my $rootdir = shift || confess( "the rootdir must be supplied" ) ; $content = join( '', "{'BACKGROUND_COLOR'} ? " BGCOLOR=\"" . $self->{'BACKGROUND_COLOR'} . "\"" : '' ), ">\n", $content ) ; my $small ; if ((@_)&&("$_[0]" eq 'small')) { shift @_ ; $small = 1 ; } $self->mergeValidHTMLIcons($content,$rootdir,$small,@_) ; $content .= "\n\n", $self->create_html_page( "$filename", "$content", "$title", "$rootdir", 0 ) ; } =pod =item * getMyValidHTML() Replies the list of W3C protocols for which this theme was validated. You must override this method. =cut sub getMyValidHTML() { my $self = shift ; return () ; } sub mergeValidHTMLIcons($$$@) { my $self = shift ; if (int(@_)>3) { # # A protocol is displayed as supported only if # the generator AND the theme support it, or # if the protocol was CSS and was supported # by the theme only (We assume that the generators # does not use any CSS syntax) # my @themevalid = $self->getMyValidHTML() ; my @valid = () ; for(my $i=3; $i\n" ; } =pod =item * title() Formats a page title Takes 2 args: =over =item * text (string) =item * text_before (optional boolean) indicates if some text are before this title =back =cut sub title($) { my $self = shift ; my $text = $_[0] || confess( 'you must specify the text' ) ; return ($_[1] ? $self->partseparator() : '') . "

$text

\n\n" ; } =pod =item * subtitle() Formats a page subtitle Takes 1 arg: =over =item * text (string) =item * text_before (optional boolean) indicates if some text are before this title =back =cut sub subtitle($) { my $self = shift ; my $text = $_[0] || '' ; if ( ! $text ) { Bib2HTML::General::Error::syswarm( 'a title was expected' ) ; } return ($_[1] ? "
\n" : ''). "

$text

\n" ; } =pod =item * strong() Formats a keyword Takes 2 args: =over =item * text (string) =back =cut sub strong($) { my $self = shift ; my $text = $_[0] || confess( 'you must specify the text' ) ; return "$text" ; } =pod =item * entry_title() Formats the title of an BibTeX entry. Takes 1 arg: =over =item * text (string) =back =cut sub entry_title($) { my $self = shift ; my $title = $_[0] || '' ; if ( ! $title ) { Bib2HTML::General::Error::syswarm( 'a title was expected' ) ; } return join( '', """, $title, """ ) ; } =pod =item * format_date() Formats a date. Takes 2 args: =over =item * month (string) =item * year (string) =back =cut sub format_date($$) { my $self = shift ; my $month = $_[0] || '' ; my $year = $_[1] || confess( 'you must supply the year' ) ; return ($month?"$month ":"")."$year" ; } =pod =item * href() Replies a hyperlink. Takes 3 args: =over =item * url (string) is the URL to link to =item * label (string) is the label of the hyperlink =item * target (optional string) is the frame target. =back =cut sub href($$) { my $self = shift ; my $url = $_[0] || confess( 'you must specify the URL' ) ; my $label = $_[1] ; return '' unless ($label) ; return join( '', "", $label, "" ) ; } =pod =item * small() Replies a text with a small size. Takes 1 arg: =over =item * text (string) =back =cut sub small($) { my $self = shift ; my $text = $_[0] || '' ; return join( '', "", $text, "\n" ) ; } =pod =item * tiny() Replies a text with a tiny size. Takes 1 arg: =over =item * text (string) =back =cut sub tiny($) { my $self = shift ; my $text = $_[0] || '' ; return join( '', "", $text, "\n" ) ; } =pod =item * par() Replies a paragraph. Takes 1 arg: =over =item * text (string) =back =cut sub par($) { my $self = shift ; my $text = $_[0] || '' ; return join( '', "

", $text, "

\n" ) ; } =pod =item * get_tree_node() Replues the HTML string for the specified tree. a list. Takes 2 args: =over =item * node (string) is the string that is the root of the tree. =item * subs (string) is an HTML string that describes the children. =item * rootdir (string) is the path to the root directory. =back =cut sub get_tree_node($$$) { my $self = shift ; my $text = $_[0] || '' ; my $sub = $_[1] || '' ; $sub = "
    $sub
" ; if ( $text ) { return "
  • ".$text.$sub."
  • \n" ; } else { return "$sub\n" ; } } =pod =item * get_tree_leaf() Replies a line of a tree which will be displayed inside a list. Takes 1 args: =over =item * node (string) is the string that is the root of the tree. =item * rootdir (string) is the path to the root directory. =back =cut sub get_tree_leaf($$) { my $self = shift ; my $text = $_[0] || '' ; return join( '', "
  • ", $text, "
  • \n" ) ; } =pod =item * get_tree() Creates a tree. Takes 2 or 3 args: =over =item * tree (hash) is the tree =item * rootdir (string) is the path to the root directory =item * root label (optional string) is the label of the root node =back =cut sub get_tree($$;$) : method { my $self = shift ; my $tree = $_[0] || confess( "you must supply the tree" ) ; my $rootdir = $_[1] || confess( 'you must supply the root directory' ) ; my $content = $self->__get_default_tree__($tree,$rootdir) ; if ( $content ) { return "
      $content
    \n" ; } else { return "$content" ; } } sub __get_default_tree__($$) { my $self = shift ; my $tree = $_[0] || confess( "you must supply the tree" ) ; my $rootdir = $_[1] || confess( 'you must supply the root directory' ) ; my $content = '' ; my @c = keys %{$tree}; @c = sortbyletters(@c); foreach my $children (@c) { if ( isemptyhash($tree->{"$children"}) ) { # leaf $content .= $self->get_tree_leaf("$children",$rootdir) ; } else { # node my $sub = $self->__get_default_tree__($tree->{"$children"},$rootdir) ; $content .= $self->get_tree_node("$children",$sub,$rootdir) ; } } return $content ; } =pod =item * get_navigation_bar() Replies the navigation bar. Takes 3 args: =over =item * url (string) is the url of the generated page. =item * params (hash ref) is a set of parameters used to generate the bar. =item * root (string) is the root directory for the generated documentation. =back =cut sub get_navigation_bar($$$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } =pod =item * section() Replies a section Takes 3 args: =over =item * title (string) is the title of the new section. =item * content (string) is the content of the new section =item * root (string) is the root directory for the generated documentation. =back =cut sub section($$$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } #------------------------------------------------------ # # Array API # #------------------------------------------------------ =pod =item * build_onecolumn_array() Replies an one-column array. Takes 2 args: =over =item * title (string) is the title of the array =item * cells (array ref) is the content of the returned cells. =back =cut sub build_onecolumn_array($$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } =pod =item * build_twocolumn_array() Replies an two-column array. Takes 2 args: =over =item * title (string) is the title of the array =item * cells (array ref) is the content of the returned cells. =back =cut sub build_twocolumn_array($$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } =pod =item * build_small_array() Replies an small one-column array. Takes 2 args: =over =item * title (string) is the title of the array =item * cells (array ref) is the content of the returned cells. =back =cut sub build_small_array($$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } =pod =item * build_tiny_array() Replies a tiny one-column array. Takes 2 args: =over =item * title (string) is the title of the array =item * cells (array ref) is the content of the returned cells. =back =cut sub build_tiny_array($$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } =pod =item * build_threecolumn_array() Replies an two-column array. Takes 3 args: =over =item * title (string) is the title of the array =item * cells (array ref) is the content of the returned cells. =item * anchor (string) is the name of the anchor. =back =cut sub build_threecolumn_array($$$) : method { my $self = shift ; confess( 'you must overwrite this method' ) ; } #------------------------------------------------------ # # Index API # #------------------------------------------------------ =pod =item * format_index_page() Replies a formatted page for the index. Takes 3 args: =over =item * letterlist (string) is the list of letters of the index. =item * letter (string) is the current letter. =item * content (array ref) is the content of the page. =back =cut sub format_index_page($$$) : method { my $self = shift ; my $letterlist = $_[0] || '' ; my $letter = notempty( $_[1], 'you must supply the index letter for this page' ) ; my $content = join( '', ( $letterlist ? $letterlist.$self->partseparator() : '' ), "

    ", uc($letter), "

    \n", "
    " ) ; my $previouslabel = '' ; my @currententry = () ; foreach my $entry (@{$_[2]}) { if ( "$previouslabel" eq $entry->{'label'} ) { # Caching this entry for futher display push @currententry, $entry ; } else { # Generate the page content $self->__generate_index_entry(\@currententry,$content,$entry); } $previouslabel = $entry->{'label'} ; } if ( @currententry ) { $self->__generate_index_entry(\@currententry,$content); } $content .= join( '', "
    ", ( $letterlist ? $self->partseparator().$letterlist : '' ) ) ; return $content ; } sub __generate_index_entry($$;$) { my $self = shift ; # Generates the previous entries if ( @{$_[0]} == 1 ) { $_[1] .= join( '', "
    ", $self->href( $_[0]->[0]{'url'}, $_[0]->[0]{'label'} ), ( $_[0]->[0]{'short_comment'} ? " - ".$_[0]->[0]{'short_comment'} : '' ), "
    ", $_[0]->[0]{'comment'}, " 
    \n" ) ; } elsif ( @{$_[0]} > 1 ) { $_[1] .= join( '', "
    ", $_[0]->[0]{'label'}, "
      " ) ; foreach my $entry_to_display (@{$_[0]}) { $_[1] .= join( '', "
    • ", $entry_to_display->{'comment'}, $self->href( $entry_to_display->{'url'}, "\"\"" ), "
    • \n" ) ; } $_[1] .= "
    \n" ; } # Prepare the caching for this entry if ( $_[2] ) { @{$_[0]} = ( $_[2] ) ; } } #------------------------------------------------------ # # Filename API # #------------------------------------------------------ =pod =item * get_math_start_tag() Replies the HTML balise which starts the math mode. =cut sub get_math_start_tag() : method { my $self = shift ; return "" ; } =pod =item * get_math_stop_tag() Replies the HTML balise which stops the math mode. =cut sub get_math_stop_tag() : method { my $self = shift ; return "" ; } 1; __END__ =back =head1 COPYRIGHT (c) Copyright 1998-09 Stéphane Galland , under GPL. =head1 AUTHORS =over =item * Conceived and initially developed by Stéphane Galland Egalland@arakhne.orgE. =back =head1 SEE ALSO bib2html.pl