bug-texinfo
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: footer navigation headers


From: Patrice Dumas
Subject: Re: footer navigation headers
Date: Sat, 20 Feb 2021 01:31:45 +0100

On Thu, Feb 18, 2021 at 08:03:22AM -0800, Per Bothner wrote:
> I think this link shows a good default output (with no configuration 
> settings),
> assuming --split=section (and of course some non-default css):
> 
> http://per.bothner.com/tmp/DomTerm-txjs/Wire-byte-protocol.html
> <
> There is a navigation header for each node, and a single navigation footer.
> 
> You can remove excess headers with CSS:
> div.section div.header { display: none }
> div.subsection div.header { display: none }
> div.subsubsection div.header { display: none }
> 
> and the result is reasonable.
> 
> The way I did it (see attached patch) is probably not the right one.
> Things will probably misbehave for certain configuration settings.
> WORDS_IN_PAGE is disabled, for one.  (Though I don't think we should be 
> obliged
> to support every existing configuration setting in the same way as before.
> It's ok to remove some little-used settings, especially if they no longer 
> make sense.)

This was something introduced for the singular manual.  This is actually
the use case that required the most of customization and is still used
to test for many customization options.

> For what it's worth, what I tried was to split _default_format_element_footer
> into two parts:
> 
> (1) _default_format_element_footer is called at the end of each node,
> as before.  It emits rules, footnotes, but no navigation buttons.
> 
> (2) _default_format_element_footer is emitted at the end of each page.
> It emits navigation buttons.  It is actually called in 
> _convert_heading_command
> at the top of the page, which is why WORDS_IN_PAGE is ignored, but that
> could be changed with some more complicated logic.

I must be missing something, as I can't see how it could work to output
the footer at the top of the page?

It may make sense, however, to have two separate functions, one called at the
end of each element and one called at the end of file, but before
format_end_file, to separate some customization of the end of file, and
some customization of something that is associated to the element.

I think that the reason why it isn't that way is to handle the
"intermediary" case in which there is a transition that warrants a
special formatting, but it is not yet the end of the file.  For instance
this is what happens when not split and transitioning from the normal
elements to special elements (that are not output in every case, that
corresponds more to texi2html styme).

> 
> -- 
>       --Per Bothner
> per@bothner.com   http://per.bothner.com/

> diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
> index 098b3c3c30..bdfdacbc34 100644
> --- a/tp/Texinfo/Convert/HTML.pm
> +++ b/tp/Texinfo/Convert/HTML.pm
> @@ -2456,11 +2456,31 @@ sub _convert_heading_command($$$$$)
>    }
>  
>    my $element_id = $self->command_id($command);
> +  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'};
> +  }
> +  my $element_header;
> +  my $page_footer;
> +  if ($element) {
> +    $element_header = &{$self->{'format_element_header'}}($self, $cmdname,
> +                                            $command, $element);
> +    $page_footer = &{$self->{'format_page_footer'}}($self, $command);
> +  }
> +
>    my $section = $command->{'extra'}->{'associated_section'};
>    if ($cmdname eq 'node' and $section) {
>      my $level = $section->{'level'};
>      $result .= join('', $self->close_registered_sections_level($level));
> -    $self->register_opened_section_level($level, "</div>\n");
> +    my $close =
> +        "</div>\n";
> +    if ($page_footer and scalar(@{$self->{'pending_closes'}}) == 0) {
> +        $close = $page_footer . $close;
> +    }
> +    $self->register_opened_section_level($level, $close);
>  
>      $result .= '<div class="' . $section->{'cmdname'} . '"';
>  
> @@ -2475,16 +2495,8 @@ sub _convert_heading_command($$$$$)
>    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);
> +    $result .= $element_header;
>    }
>  
>    my $heading_level;
> @@ -4767,7 +4779,7 @@ sub _default_format_element_footer($$$$)
>    my $type = shift;
>    my $element = shift;
>    my $content = shift;
> -
> + 
>    my $result = '';
>    my $is_top = $self->element_is_top($element);
>    my $next_is_top = ($element->{'element_next'} 
> @@ -4796,34 +4808,15 @@ sub _default_format_element_footer($$$$)
>    }
>  
>    my $rule = '';
> -  my $buttons;
> -  my $maybe_in_page;
> +  my $maybe_in_page = 1;
>    if (($is_top or $is_special)
>        and ($self->get_conf('SPLIT') or !$self->get_conf('MONOLITHIC'))
>        and ($end_page 
>           and ($self->get_conf('HEADERS') 
>                or ($self->get_conf('SPLIT') and $self->get_conf('SPLIT') ne 
> 'node')))) {
> -    if ($is_top) {
> -      $buttons = $self->get_conf('TOP_BUTTONS');
> -    } else {
> -      $buttons = $self->get_conf('MISC_BUTTONS');
> -    }
>    } elsif ($end_page and $self->get_conf('SPLIT') eq 'section') {
> -    $buttons = $self->get_conf('SECTION_FOOTER_BUTTONS');
>    } elsif ($end_page and $self->get_conf('SPLIT') eq 'chapter') {
> -    $buttons = $self->get_conf('CHAPTER_BUTTONS');
>    } elsif ($self->get_conf('SPLIT') eq 'node') {
> -    if ($self->get_conf('HEADERS')) {
> -      my $no_footer_word_count;
> -      if ($self->get_conf('WORDS_IN_PAGE')) {
> -        my @cnt = split(/\W*\s+\W*/, $content);
> -        if (scalar(@cnt) < $self->get_conf('WORDS_IN_PAGE')) {
> -          $no_footer_word_count = 1;
> -        }
> -      }
> -      $buttons = $self->get_conf('NODE_FOOTER_BUTTONS')
> -         unless ($no_footer_word_count);
> -    }
>    } else {
>      $maybe_in_page = 1;
>    }
> @@ -4849,11 +4842,78 @@ sub _default_format_element_footer($$$$)
>      $result .= &{$self->{'format_footnotes_text'}}($self);
>    }
>    if (!$self->get_conf('PROGRAM_NAME_IN_FOOTER') 
> -      and !$buttons and !$maybe_in_page) {
> +      and !$maybe_in_page) {
>      # no rule in that case
>    } else {
>      $result .= "$rule\n" if ($rule);
>    }
> +  
> +  return $result;
> +}
> +sub _default_format_page_footer($$)
> +{
> +  my $self = shift;
> +  my $element = shift;
> +
> +  my $result = '';
> +  my $is_top = $self->element_is_top($element);
> +  my $next_is_top = ($element->{'element_next'} 
> +                     and $self->element_is_top($element->{'element_next'}));
> +  my $next_is_special = (defined($element->{'element_next'})
> +    and $element->{'element_next'}->{'extra'}->{'special_element'});
> +  # no 'parent' defined happens if there are no pages, and there are 
> elements 
> +  # which should only happen when called with $self->{'output_file'} 
> +  # set to ''.
> +  my $end_page = (!$element->{'element_next'}
> +       or (defined($element->{'filename'}) 
> +           and $element->{'filename'} ne 
> $element->{'element_next'}->{'filename'}
> +           and $self->{'file_counters'}->{$element->{'filename'}} == 1));
> +  #my $end_page = (!$element->{'element_next'}
> +  #     or (defined($element->{'parent'}) 
> +  #         and $element->{'parent'} ne 
> $element->{'element_next'}->{'parent'}));
> +  my $is_special = $element->{'extra'}->{'special_element'};
> +
> +  if (($end_page or $next_is_top or $next_is_special or $is_top)
> +       and $self->get_conf('VERTICAL_HEAD_NAVIGATION')
> +       and ($self->get_conf('SPLIT') ne 'node' 
> +            or $self->get_conf('HEADERS') or $is_special or $is_top)) {
> +   $result .= "</td>
> +</tr>
> +</table>"."\n";
> +  }
> +
> +  my $buttons;
> +  my $maybe_in_page;
> +  if (($is_top or $is_special)
> +      and ($self->get_conf('SPLIT') or !$self->get_conf('MONOLITHIC'))
> +      and ($end_page 
> +         and ($self->get_conf('HEADERS') 
> +              or ($self->get_conf('SPLIT') and $self->get_conf('SPLIT') ne 
> 'node')))) {
> +    if ($is_top) {
> +      $buttons = $self->get_conf('TOP_BUTTONS');
> +    } else {
> +      $buttons = $self->get_conf('MISC_BUTTONS');
> +    }
> +  } elsif ($end_page and $self->get_conf('SPLIT') eq 'section') {
> +    $buttons = $self->get_conf('SECTION_FOOTER_BUTTONS');
> +  } elsif ($end_page and $self->get_conf('SPLIT') eq 'chapter') {
> +    $buttons = $self->get_conf('CHAPTER_BUTTONS');
> +  } elsif ($self->get_conf('SPLIT') eq 'node') {
> +    if ($self->get_conf('HEADERS')) {
> +      $buttons = $self->get_conf('NODE_FOOTER_BUTTONS');
> +    }
> +  } else {
> +    $maybe_in_page = 1;
> +  }
> +
> +  # FIXME the following condition is almost a duplication of end_page 
> +  # except that the file counter needs not be 1
> +  if ((!$element->{'element_next'}
> +       or (defined($element->{'filename'})
> +           and $element->{'filename'} ne 
> $element->{'element_next'}->{'filename'}))
> +      and $self->get_conf('footnotestyle') eq 'end') {
> +    $result .= &{$self->{'format_footnotes_text'}}($self);
> +  }
>    if ($buttons) {
>      $result .= &{$self->{'format_navigation_header_panel'}}($self, $buttons,
>                                                       undef, $element);
> @@ -4895,6 +4955,7 @@ my %default_formatting_references = (
>       'format_navigation_header_panel' => 
> \&_default_format_navigation_header_panel, 
>       'format_element_header' => \&_default_format_element_header,
>       'format_element_footer' => \&_default_format_element_footer,
> +     'format_page_footer' => \&_default_format_page_footer,
>       'format_button' => \&_default_format_button, 
>       'format_button_icon_img' => \&_default_format_button_icon_img, 
>       'format_contents' => \&_default_format_contents,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]