# A style that tries to be analogous with a book, in HTML. # # This file is in the public domain. Thus it may easily be used as an # example for further customizations. # # Originally written by Patrice Dumas in 2004. # Modified in 2007, 2008. # # This style is based on the scriptbasic style. use strict; use vars qw($element_file_name); set_from_init_file('contents', 1); set_from_init_file('INLINE_CONTENTS', 1); set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1); my @book_buttons = ('Back', 'Forward', ' ', 'Contents', 'Index', 'About'); foreach my $buttons ('SECTION_BUTTONS', 'CHAPTER_BUTTONS', 'TOP_BUTTONS') { set_from_init_file($buttons, \@book_buttons); } my @book_footer_buttons = ('Contents', 'Index', 'About'); foreach my $buttons ('MISC_BUTTONS', 'SECTION_FOOTER_BUTTONS') { set_from_init_file($buttons, \@book_footer_buttons); } set_from_init_file('NODE_FOOTER_BUTTONS', ['Back', 'Forward']); set_from_init_file('LINKS_BUTTONS', ['Top', 'Index', 'Contents', 'About', 'Up', 'NextFile', 'PrevFile']); set_from_init_file('WORDS_IN_PAGE', undef); set_from_init_file('SHOW_MENU', 0); set_from_init_file('USE_NODES', undef); set_from_init_file('BIG_RULE', '
'); my ($book_previous_default_filename, $book_previous_file_name, $book_unumbered_nr); sub book_init($) { my $converter = shift; $book_previous_default_filename = undef; $book_previous_file_name = undef; $book_unumbered_nr = 0; return 1; } texinfo_register_handler('init', \&book_init); my $NO_BULLET_LIST_CLASS = 'no-bullet'; sub book_print_up_toc($$) { my $converter = shift; my $command = shift; my $result = ''; my $current_command = $command; my @up_commands; while (defined($current_command->{'section_up'}) and ($current_command->{'section_up'} ne $current_command) and defined($current_command->{'section_up'}->{'cmdname'})) { unshift (@up_commands, $current_command->{'section_up'}); $current_command = $current_command->{'section_up'}; } # this happens for example for top element return '' if !(@up_commands); #print $fh "\n"; } $result .= "\n"; return $result; } sub book_navigation_header($$$$) { my $self = shift; my $buttons = shift; my $cmdname = shift; my $command = shift; my $element = $command->{'parent'}; if ($element and $element->{'extra'}->{'section'} and ($element->{'contents'}->[0] eq $command or (!$element->{'contents'}->[0]->{'cmdname'} and $element->{'contents'}->[1] eq $command)) and defined($element->{'filename'}) and $self->{'counter_in_file'}->{$element->{'filename'}} == 1) { return book_print_up_toc($self, $element->{'extra'}->{'section'}) . &{$self->default_formatting_function('navigation_header')}($self, $buttons, $cmdname, $command); } else { return &{$self->default_formatting_function('navigation_header')}($self, $buttons, $cmdname, $command); } } texinfo_register_formatting_function('navigation_header', \&book_navigation_header); sub book_print_sub_toc($$$); sub book_print_sub_toc($$$) { my $converter = shift; my $parent_command = shift; my $command = shift; my $result = ''; my $content_href = $converter->command_href($command); my $heading = $converter->command_text($command); if ($content_href) { $result .= "
  • "."$heading" . "
  • \n"; } #print STDERR "SUB_TOC $element->{'text'}\n"; #sleep 1; if ($command->{'section_childs'} and @{$command->{'section_childs'}}) { #print STDERR "SUB_TOC child $element->{'child'}->{'text'}\n"; $result .= '
  • '.$converter->_attribute_class('ul',$NO_BULLET_LIST_CLASS) .">\n". book_print_sub_toc($converter, $parent_command, $command->{'section_childs'}->[0]) ."
  • \n"; } if (exists($command->{'section_next'})) { #print STDERR "SUB_TOC next($element->{'text'}) $element->{'next'}->{'text'}\n"; $result .= book_print_sub_toc($converter, $parent_command, $command->{'section_next'}); } return $result; } sub book_convert_heading_command($$$$$) { my $self = shift; my $cmdname = shift; my $command = shift; my $args = shift; my $content = shift; my $result = ''; # not clear that it may really happen if ($self->in_string) { $result .= $self->command_string($command) ."\n" if ($cmdname ne 'node'); $result .= $content if (defined($content)); return $result; } my $element_id = $self->command_id($command); $result .= "\n" if (defined($element_id) and $element_id ne ''); print STDERR "Process $command " .Texinfo::Structuring::_print_root_command_texi($command)."\n" if ($self->get_conf('DEBUG')); my $element; if ($Texinfo::Common::root_commands{$command->{'cmdname'}} and $command->{'parent'} and $command->{'parent'}->{'type'} and $command->{'parent'}->{'type'} eq 'element') { $element = $command->{'parent'}; } if ($element) { $result .= &{$self->{'format_element_header'}}($self, $cmdname, $command, $element); } my $heading_level; # FIXME this is done as in texi2html: node is used as heading if there # is nothing else. Is it right? if ($cmdname eq 'node') { if (!$element or (!$element->{'extra'}->{'section'} and $element->{'extra'}->{'node'} and $element->{'extra'}->{'node'} eq $command # bogus node may not have been normalized and defined($command->{'extra'}->{'normalized'}))) { if ($command->{'extra'}->{'normalized'} eq 'Top') { $heading_level = 0; } else { $heading_level = 3; } } } else { $heading_level = $command->{'level'}; } my $heading = $self->command_text($command); # $heading not defined may happen if the command is a @node, for example # if there is an error in the node. if (defined($heading) and $heading ne '' and defined($heading_level)) { if ($self->get_conf('TOC_LINKS') and $Texinfo::Common::root_commands{$cmdname} and $Texinfo::Common::sectioning_commands{$cmdname}) { my $content_href = $self->command_contents_href($command, 'contents', $self->{'current_filename'}); if ($content_href) { $heading = "$heading"; } } if ($self->in_preformatted()) { $result .= ''.$heading.''."\n"; } else { # if the level was changed, set the command name right if ($cmdname ne 'node' and $heading_level ne $Texinfo::Common::command_structuring_level{$cmdname}) { $cmdname = $Texinfo::Common::level_to_structuring_command{$cmdname}->[$heading_level]; } $result .= &{$self->{'format_heading_text'}}($self, $cmdname, $heading, $heading_level, $command); } } if ($command->{'section_childs'} and @{$command->{'section_childs'}} and $cmdname ne 'top') { $result .= $self->_attribute_class('ul', $NO_BULLET_LIST_CLASS).">\n"; $result .= book_print_sub_toc($self, $command, $command->{'section_childs'}->[0]); $result .= "\n"; } $result .= $content if (defined($content)); return $result; } foreach my $command (keys(%Texinfo::Common::sectioning_commands), 'node') { texinfo_register_command_formatting($command, \&book_convert_heading_command); } sub book_element_file_name($$$) { my $converter = shift; my $element = shift; my $filename = shift; return undef if ($converter->get_conf('NODE_FILENAMES') or !$converter->get_conf('SPLIT')); if (defined($book_previous_default_filename) and ($filename eq $book_previous_default_filename)) { return $book_previous_file_name; } my $prefix = $converter->{'document_name'}; my $new_file_name; my $command = $element->{'extra'}->{'section'}; return undef unless ($command); if ($converter->element_is_top($element)) { $new_file_name = "${prefix}_top.html"; } elsif (defined($command->{'number'}) and ($command->{'number'} ne '')) { my $number = $command->{'number'}; $number .= '.' unless ($number =~ /\.$/); $new_file_name = "${prefix}_$number" . 'html'; } else { $book_unumbered_nr++; $new_file_name = "${prefix}_U." . $book_unumbered_nr . '.html'; } $book_previous_default_filename = $filename; $book_previous_file_name = $new_file_name; return $new_file_name; } $element_file_name = \&book_element_file_name; 1;