A mistake in a @menu block can produce many errors that are hard to
understand.  For example, one missing menu entry:

@menu
* One::
* Three::
@end menu

instead of

@menu
* One::
* Two::
* Three::
@end menu

produces 5 separate errors:

test.texi:13: warning: node next pointer for `One' is `Two' but next is `Three' 
in menu
test.texi:16: warning: node next for `Two' is `Three' in sectioning but not in 
menu
test.texi:16: warning: node prev for `Two' is `One' in sectioning but not in 
menu
test.texi:16: warning: node up for `Two' is `Capitulum' in sectioning but not 
in menu
test.texi:5: warning: node `Capitulum' lacks menu item for `Two' despite being 
its Up target
test.texi:20: warning: node prev pointer for `Three' is `Two' but prev is `One' 
in menu

This can be overwhelming for the user.

As you may remember, in a previous Texinfo release (6.8) we disabled
such warnings, but reenabled them in 7.2 due to users being unhappy about
malformed files going undetected.

Test file:

----------
\input texinfo

@node Capitulum
@chapter Main chapter

@menu
* One::
* Three::
@end menu

@node One
@section Oniddly Twodly

@node Two
@section Fffffffffff

@node Three
@section Fourtly Portly


@bye
----------

Fortunately, the issuance of these errors appears to be limited to one
function, in Texinfo/Structuring.pm ('complete_node_tree_with_menus').

I think it should be possible to reduce these errors, to only report once
about common problems.  For example, these are basically the same error:

test.texi:13: warning: node next pointer for `One' is `Two' but next is `Three' 
in menu
test.texi:20: warning: node prev pointer for `Three' is `Two' but prev is `One' 
in menu

The error is when comparing the list of sections under the chapter,
and the list of sections in the menu, one of the sections is missing in
the menu.

There would be similar groups of errors for other single mistakes such
as moving a section from one chapter to another, or reordering sections
within a chapter.

'complete_node_tree_with_menus' is not an easy function to read.
This function, as it is named (complete_node_tree_with_menus) uses
"menu directions" to complete any gaps in node directions, but it also
warns on any mismatches between node directions and menu directions.

What I would like to change, as a preliminary step before trying to
find better ways of reporting on problems with the node structure,
is to completely separate:

* Structure checking and warning code
* Code altering the structure.

It makes it very hard to understand and modify the code when the code
modifying the structure is also reporting on faults with the structure.

It could be possible to write completely new code just checking for
faults, which doesn't rely on "menu directions" at all.  (It may not be
clear to the user what "menu directions" are as these are an abstraction
created internally by texi2any.)  For example, we could record structural
flaws that involve groups of nodes, and then output all the warnings in
one go, rather than reporting the warnings node-by-node.

The code shown as removed in the following diff is purely for issuing warning
messages:

diff --git a/tta/perl/Texinfo/Structuring.pm b/tta/perl/Texinfo/Structuring.pm
index d029fcd322..04ec756e34 100644
--- a/tta/perl/Texinfo/Structuring.pm
+++ b/tta/perl/Texinfo/Structuring.pm
@@ -799,52 +799,6 @@ sub complete_node_tree_with_menus($)
             next;
           }
           my $section_relations = $node_relations->{'associated_section'};
-          if ($section_relations
-              and $customization_information->get_conf(
-                                             'CHECK_NORMAL_MENU_STRUCTURE')) {
-            # Check consistency with section and menu structure
-            my $direction_relation = $section_relations;
-
-            # Prefer the section associated with a @part for node directions.
-            if ($section_relations->{'part_associated_section'}) {
-              $direction_relation
-                = $section_relations->{'part_associated_section'};
-            }
-            my $direction_associated_node
-              = _section_direction_associated_node($direction_relation,
-                                                   $direction);
-            if ($direction_associated_node) {
-              my $section_directions
-                = $direction_relation->{'section_directions'};
-
-              my $menus;
-              if ($section_directions
-                  and $section_directions->{'up'}) {
-                my $up_relations = $section_directions->{'up'};
-                my $up_sec = $up_relations->{'element'};
-
-                if ($up_relations->{'associated_node'}) {
-                  my $up_node_relations = $up_relations->{'associated_node'};
-                  if ($up_node_relations->{'menus'}
-                      and scalar(@{$up_node_relations->{'menus'}})) {
-                    $menus = $up_node_relations->{'menus'};
-                  }
-                }
-              }
-
-              if ($menus
-                  and (!$menu_directions
-                       or !$menu_directions->{$direction})) {
-                $registrar->line_warn(
-           sprintf(__("node %s for `%s' is `%s' in sectioning but not in 
menu"),
-                          $direction,
-                          target_element_to_texi_label($node),
-         
target_element_to_texi_label($direction_associated_node->{'element'})),
-                                      $node->{'source_info'}, 0,
-                               $customization_information->get_conf('DEBUG'));
-              }
-            }
-          }
           # Direction was not set with sections, use menus.  This allows
           # using only automatic direction for manuals without sectioning
           # commands but with explicit menus.
@@ -853,18 +807,6 @@ sub complete_node_tree_with_menus($)
               and $menu_directions->{$direction}
               and !$menu_directions->{$direction}
                                           ->{'extra'}->{'manual_content'}) {
-            if ($customization_information->get_conf(
-                                               'CHECK_NORMAL_MENU_STRUCTURE')
-                and $section_relations) {
-              $registrar->line_warn(
-          sprintf(__("node `%s' is %s for `%s' in menu but not in sectioning"),
-                target_element_to_texi_label(
-                         $menu_directions->{$direction}),
-                                   $direction,
-                                 target_element_to_texi_label($node)),
-                                    $node->{'source_info'}, 0,
-                            $customization_information->get_conf('DEBUG'));
-            }
             $node_relations->{'node_directions'} = {}
                if (!$node_relations->{'node_directions'});
             $node_relations->{'node_directions'}->{$direction}

Without this warning code present, it is possible to read and make sense
of the remaining code.

Does it sound like a good idea to separate the warning code from the
code updating the structure?  If we could do this, I feel like I would
have a good chance of being able to write structure-checking code that
didn't produce so many warnings.

The focus would be on reporting problems with menus, with the assumption
that the error is in the menus (user forgot to update the menus or didn't
update them correctly) and not the sectioning structure inferred from
the order of nodes in the input file.


Reply via email to