Index: NEWS =================================================================== --- NEWS (revision 6381) +++ NEWS (working copy) @@ -22,6 +22,10 @@ one of the relevant sections: http://www.gnu.org/software/texinfo/manual/texinfo/html_node/Document-Permissions.html ------------------------------------------------------------------------------- +* Language: + . @menu is now optional in nodes. For Info output, makeinfo will + automatically create a menu for nodes lacking one given explicitly. + 6.0 (26 June 2015) * Language: Index: tp/texi2any.pl =================================================================== --- tp/texi2any.pl (revision 6381) +++ tp/texi2any.pl (working copy) @@ -1302,7 +1302,10 @@ while(@input_files) { if ($tree_transformations{'complete_tree_nodes_menus'}) { Texinfo::Structuring::complete_tree_nodes_menus($parser, $tree); + } else { + Texinfo::Structuring::add_missing_menus($parser, $tree); } + if ($tree_transformations{'indent_menu_descriptions'}) { Texinfo::Convert::Plaintext::indent_menu_descriptions(undef, $parser); } Index: tp/Texinfo/Structuring.pm =================================================================== --- tp/Texinfo/Structuring.pm (revision 6381) +++ tp/Texinfo/Structuring.pm (working copy) @@ -43,6 +43,7 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPO # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. %EXPORT_TAGS = ( 'all' => [ qw( + add_missing_menus associate_internal_references complete_tree_nodes_menus elements_directions @@ -1683,6 +1684,40 @@ sub _new_block_command($$$) return $new_block; } +sub add_node_menu_if_missing($$) +{ + my $self = shift; + my $node = shift; + + if (!$node->{'extra'}->{'associated_section'}->{'section_childs'} + or $node->{'menus'} and @{$node->{'menus'}}) { + return; + } + + my @node_childs; + foreach my $child (@{$node->{'extra'}->{'associated_section'}->{'section_childs'}}) { + if ($child->{'extra'} and $child->{'extra'}->{'associated_node'}) { + push @node_childs, $child->{'extra'}->{'associated_node'}; + } + } + + my @pending; + for my $child (@node_childs) { + my $entry = _new_node_menu_entry($self, + $child->{'extra'}->{'node_content'}); + push @pending, $entry; + } + + # Add a menu to this node + my $section = $node->{'extra'}->{'associated_section'}; + my $current_menu = _new_block_command (address@hidden, $section, 'menu'); + push @{$section->{'contents'}}, $current_menu; + push @{$section->{'contents'}}, {'type' => 'empty_line', + 'text' => "\n", + 'parent' => $section}; + push @{$node->{'menus'}}, $current_menu; +} + sub complete_node_menu($$) { my $self = shift; @@ -1784,6 +1819,25 @@ sub complete_node_menu($$) } # This should be called after sectioning_structure +sub add_missing_menus($$) +{ + my $self = shift; + my $root = shift; + if (!$root->{'type'} or $root->{'type'} ne 'document_root' + or !$root->{'contents'}) { + return undef; + } + foreach my $content (@{$root->{'contents'}}) { + if ($content->{'cmdname'} and $content->{'cmdname'} eq 'node' + and (scalar(@{$content->{'extra'}->{'nodes_manuals'}}) == 1) + and $content->{'extra'} + and $content->{'extra'}->{'associated_section'}) { + add_node_menu_if_missing($self, $content); + } + } +} + +# This should be called after sectioning_structure sub complete_tree_nodes_menus($$) { my $self = shift;