texinfo-commits
[Top][All Lists]
Advanced

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

[7480] split out tree transformations to new module Transformations.pm


From: gavinsmith0123
Subject: [7480] split out tree transformations to new module Transformations.pm
Date: Sun, 30 Oct 2016 15:53:20 +0000 (UTC)

Revision: 7480
          http://svn.sv.gnu.org/viewvc/?view=rev&root=texinfo&revision=7480
Author:   gavin
Date:     2016-10-30 15:53:19 +0000 (Sun, 30 Oct 2016)
Log Message:
-----------
split out tree transformations to new module Transformations.pm

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/tp/Makefile.am
    trunk/tp/Texinfo/Structuring.pm
    trunk/tp/t/automatic_menus.t
    trunk/tp/t/automatic_nodes.t
    trunk/tp/t/do_master_menu.t
    trunk/tp/t/reference_to_text_in_tree.t
    trunk/tp/t/test_fill_gaps_in_sectioning.t
    trunk/tp/t/test_utils.pl
    trunk/tp/texi2any.pl

Added Paths:
-----------
    trunk/tp/Texinfo/Transformations.pm

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog     2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/ChangeLog     2016-10-30 15:53:19 UTC (rev 7480)
@@ -1,5 +1,20 @@
 2016-10-30  Gavin Smith  <address@hidden>
 
+       * tp/Texinfo/Structuring.pm,
+       * tp/Texinfo/Transformations.pm
+       (fill_gaps_in_sectioning, insert_nodes_for_sectioning_commands)
+       (add_node_menu_if_missing, complete_node_menu)
+       (complete_tree_nodes_menus, new_master_menu, regenerate_master_menu)
+       (menu_to_simple_menu, set_menus_to_simple_menu): Move some 
+       less-used functions out into a new file, Transformations.pm.
+
+       * tp/Texinfo/Structuring.pm,
+       (_new_block_command, new_block_command): Rename.
+       (_new_node_menu_entry, new_node_menu_entry): Rename.
+       (add_missing_menus): Remove, as it isn't used anywhere.
+
+2016-10-30  Gavin Smith  <address@hidden>
+
        * tp/Texinfo/Structuring.pm (nodes_tree): Use a hash reference
        that is inside a variable for brevity.
 

Modified: trunk/tp/Makefile.am
===================================================================
--- trunk/tp/Makefile.am        2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/Makefile.am        2016-10-30 15:53:19 UTC (rev 7480)
@@ -71,6 +71,7 @@
  Texinfo/Common.pm \
  Texinfo/Encoding.pm \
  Texinfo/Structuring.pm \
+ Texinfo/Transformations.pm \
  Texinfo/Documentlanguages.pm
 
 dist_noinst_DATA = \

Modified: trunk/tp/Texinfo/Structuring.pm
===================================================================
--- trunk/tp/Texinfo/Structuring.pm     2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/Texinfo/Structuring.pm     2016-10-30 15:53:19 UTC (rev 7480)
@@ -50,20 +50,13 @@
 # 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
   elements_file_directions
-  insert_nodes_for_sectioning_commands
   merge_indices
-  new_master_menu
   nodes_tree
   number_floats
-  menu_to_simple_menu
-  regenerate_master_menu
   sectioning_structure
-  set_menus_to_simple_menu
   sort_indices
   sort_indices_by_letter
   split_by_node
@@ -306,120 +299,6 @@
 }
 
 
-# Add raise/lowersections to be back at the normal level
-sub _correct_level($$;$)
-{
-  my $section = shift;
-  my $parent = shift;
-  my $modifier = shift;
-  $modifier = 1 if (!defined($modifier));
-
-  my @result;
-  if ($section->{'extra'} and $section->{'extra'}->{'sections_level'}) {
-    my $level_to_remove = $modifier * $section->{'extra'}->{'sections_level'};
-    my $command;
-    if ($level_to_remove < 0) {
-      $command = 'raisesection';
-    } else {
-      $command = 'lowersection';
-    }
-    my $remaining_level = abs($level_to_remove);
-    while ($remaining_level) {
-      push @result, {'cmdname' => $command,
-                     'parent' => $parent};
-      push @result, {'type' => 'empty_line', 'text' => "\n",
-                     'parent' => $parent};
-      $remaining_level--;
-    }
-  }
-  return @result;
-}
-
-sub fill_gaps_in_sectioning($)
-{
-  my $root = shift;
-  if (!$root->{'type'} or $root->{'type'} ne 'document_root'
-      or !$root->{'contents'}) {
-    return undef;
-  }
-  my @sections_list;
-  foreach my $content (@{$root->{'contents'}}) {
-    if ($content->{'cmdname'} and $content->{'cmdname'} ne 'node'
-        and $content->{'cmdname'} ne 'bye') {
-      push @sections_list, $content;
-    }
-  }
-
-  return (undef, undef) if (!scalar(@sections_list));
-
-  my @added_sections;
-  my @contents;
-  my $previous_section;
-  foreach my $content(@{$root->{'contents'}}) {
-    push @contents, $content;
-    if (address@hidden or $sections_list[0] ne $content) {
-      next;
-    }
-    my $current_section = shift @sections_list;
-    my $current_section_level = $current_section->{'level'};
-    my $next_section = $sections_list[0];
-    
-    if (defined($next_section)) {
-      my $next_section_level = $next_section->{'level'};
-      if ($next_section_level - $current_section_level > 1) {
-        my @correct_level_offset_commands = _correct_level($next_section,
-                                                          $contents[-1]);
-        if (@correct_level_offset_commands) {
-          push @{$contents[-1]->{'contents'}}, @correct_level_offset_commands;
-        }
-        #print STDERR "* $current_section_level 
"._print_root_command_texi($current_section)."\n";
-        #print STDERR "  $next_section_level 
"._print_root_command_texi($next_section)."\n";
-        while ($next_section_level - $current_section_level > 1) {
-          $current_section_level++;
-          my $new_section = {'cmdname' =>
-            
$Texinfo::Common::level_to_structuring_command{'unnumbered'}->[$current_section_level],
-            'parent' => $root,
-          };
-          $new_section->{'contents'} = [{'type' => 'empty_line', 
-                                         'text' => "\n",
-                                         'parent' => $new_section}];
-          $new_section->{'args'} = [{'type' => 'misc_line_arg',
-                                     'parent' => $new_section}];
-          $new_section->{'args'}->[0]->{'contents'} = [
-             {'type' => 'empty_spaces_after_command',
-              'text' => " ",
-              'extra' => {'command' => $new_section},
-              'parent' => $new_section->{'args'}->[0]
-             },
-             {'cmdname' => 'asis',
-              'parent' => $new_section->{'args'}->[0]
-             },
-             {'type' => 'spaces_at_end',
-              'text' => "\n",
-              'parent' => $new_section->{'args'}->[0]
-             }];
-          $new_section->{'args'}->[0]->{'contents'}->[1]->{'args'}
-             = [{'type' => 'brace_command_arg',
-                 'contents' => [],
-                 'parent' => $new_section->{'args'}->[0]->{'contents'}->[1]}];
-          my @misc_contents = @{$new_section->{'args'}->[0]->{'contents'}};
-          Texinfo::Common::trim_spaces_comment_from_content(address@hidden);
-          $new_section->{'extra'}->{'misc_content'} = address@hidden;
-          push @contents, $new_section;
-          push @added_sections, $new_section;
-          #print STDERR "  -> "._print_root_command_texi($new_section)."\n";
-        }
-        my @set_level_offset_commands = _correct_level($next_section,
-                                                       $contents[-1], -1);
-        if (@set_level_offset_commands) {
-          push @{$contents[-1]->{'contents'}}, @set_level_offset_commands;
-        }
-      }
-    }
-  }
-  return (address@hidden, address@hidden);
-}
-
 sub warn_non_empty_parts($)
 {
   my $self = shift;
@@ -1331,214 +1210,6 @@
   }
 }
 
-sub _reference_to_arg($$$)
-{
-  my $self = shift;
-  my $type = shift;
-  my $current = shift;
-
-  if ($current->{'cmdname'} and 
-      $Texinfo::Common::ref_commands{$current->{'cmdname'}}
-      and $current->{'extra'} 
-      and $current->{'extra'}->{'brace_command_contents'}) {
-    my @args_try_order;
-    if ($current->{'cmdname'} eq 'inforef') {
-      @args_try_order = (0, 1, 2);
-    } else {
-      @args_try_order = (0, 1, 2, 4, 3);
-    }
-    foreach my $index (@args_try_order) {
-      if (defined($current->{'args'}->[$index]) 
-          and 
defined($current->{'extra'}->{'brace_command_contents'}->[$index])) {
-        # This a double checking that there is some content.
-        # Not sure that it is useful.
-        my $text = 
Texinfo::Convert::Text::convert($current->{'args'}->[$index]);
-        if (defined($text) and $text =~ /\S/) {
-          my $result = {'contents' => 
-                $current->{'extra'}->{'brace_command_contents'}->[$index],
-                        'parent' => $current->{'parent'}};
-          return ($result);
-        }
-      }
-    }
-    return {'text' => '', 'parent' => $current->{'parent'}};
-  } else {
-    return ($current);
-  }
-}
-
-sub reference_to_arg_in_tree($$)
-{
-  my $self = shift;
-  my $tree = shift;
-  return Texinfo::Common::modify_tree($self, $tree, \&_reference_to_arg);
-}
-
-# prepare a new node and register it
-sub _new_node($$)
-{
-  my $self = shift;
-  my $node_tree = shift;
-
-  $node_tree = Texinfo::Common::protect_comma_in_tree($node_tree);
-  $node_tree->{'contents'} 
-     = Texinfo::Common::protect_first_parenthesis($node_tree->{'contents'});
-  $node_tree = reference_to_arg_in_tree($self, $node_tree);
-
-  my $empty_node = 0;
-  if (!$node_tree->{'contents'} 
-      or !scalar(@{$node_tree->{'contents'}})) {
-    $node_tree->{'contents'} = [{'text' => ''}];
-    $empty_node = 1;
-  }
-
-  unless (($node_tree->{'contents'}->[-1]->{'cmdname'}
-       and ($node_tree->{'contents'}->[-1]->{'cmdname'} eq 'c'
-            or $node_tree->{'contents'}->[-1]->{'cmdname'} eq 'comment'))
-      or (defined($node_tree->{'contents'}->[-1]->{'text'})
-          and $node_tree->{'contents'}->[-1]->{'text'} =~ /\n/)) {
-    push @{$node_tree->{'contents'}}, 
-           {'type' => 'spaces_at_end', 'text' => "\n"};
-  }
-
-  my $appended_number = 0 +$empty_node;
-  my ($node, $parsed_node);
-
-  while (!defined($node) 
-         or ($self->{'labels'} 
-            and $self->{'labels'}->{$parsed_node->{'normalized'}})) {
-    $node = {'cmdname' => 'node', 'args' => [{}]};
-    my $node_arg = $node->{'args'}->[0];
-    $node_arg->{'parent'} = $node;
-    @{$node_arg->{'contents'}} = (
-       {'extra' => {'command' => $node},
-        'text' => ' ',
-        'type' => 'empty_spaces_after_command'},
-        @{$node_tree->{'contents'}});
-    if ($appended_number) {
-      splice (@{$node_arg->{'contents'}}, -1, 0,
-                  {'text' => " $appended_number"});
-    }
-    foreach my $content (@{$node_arg->{'contents'}}) {
-      $content->{'parent'} = $node_arg;
-    }
-    $parsed_node = Texinfo::Parser::_parse_node_manual($node_arg);
-    if (!defined($parsed_node) or !$parsed_node->{'node_content'}
-        or $parsed_node->{'normalized'} !~ /[^-]/) {
-      if ($appended_number) {
-        return undef;
-      } else {
-        $node = undef;
-      }
-    }
-    $appended_number++;
-  }
-
-  push @{$node->{'extra'}->{'nodes_manuals'}}, $parsed_node;
-  if (!Texinfo::Parser::_register_label($self, $node, $parsed_node, undef)) {
-    print STDERR "BUG: node unique, register failed:  
$parsed_node->{'normalized'}\n";
-  }
-  push @{$self->{'nodes'}}, $node;
-  return $node;
-}
-
-# reassociate a tree element to the new node, from previous node
-sub _reassociate_to_node($$$$)
-{
-  my $self = shift;
-  my $type = shift;
-  my $current = shift;
-  my $nodes = shift;
-  my ($new_node, $previous_node) = @{$nodes};
-
-  if ($current->{'cmdname'} and $current->{'cmdname'} eq 'menu') {
-    if ($previous_node) {
-      if (!$previous_node->{'menus'} or address@hidden>{'menus'}}
-           or !grep {$current eq $_} @{$previous_node->{'menus'}}) {
-        print STDERR "Bug: menu $current not in previous node 
$previous_node\n";
-      } else {
-        @{$previous_node->{'menus'}} = grep {$_ ne $current} 
@{$previous_node->{'menus'}};
-        delete $previous_node->{'menus'} if !(@{$previous_node->{'menus'}});
-      }
-    } else {
-      my $info = $self->global_informations();
-      if (!$info or !$info->{'unassociated_menus'} 
-          or address@hidden>{'unassociated_menus'}}
-          or !grep {$current eq $_} @{$info->{'unassociated_menus'}}) {
-        print STDERR "Bug: menu $current not in unassociated menus\n";
-      } else {
-        @{$info->{'unassociated_menus'}} 
-          = grep {$_ ne $current} @{$info->{'unassociated_menus'}};
-        delete $info->{'unassociated_menus'} if 
!(@{$info->{'unassociated_menus'}});
-      }
-    }
-    push @{$new_node->{'menus'}}, $current;
-  } elsif ($current->{'extra'} and $current->{'extra'}->{'index_entry'}) {
-    if ($previous_node 
-        and (!$current->{'extra'}->{'index_entry'}->{'node'}
-             or $current->{'extra'}->{'index_entry'}->{'node'} ne 
$previous_node)) {
-      print STDERR "Bug: index entry $current (".
-        Texinfo::Convert::Texinfo::convert ({'contents' => 
$current->{'extra'}->{'index_entry'}->{'content'}})
-         .") not in previous node $previous_node\n";
-      print STDERR "  previous node: 
"._print_root_command_texi($previous_node)."\n";
-      if ($current->{'extra'}->{'index_entry'}->{'node'}) {
-        print STDERR "  current node: ".
-         
_print_root_command_texi($current->{'extra'}->{'index_entry'}->{'node'})."\n";
-      } else {
-        print STDERR "  current node not set\n";
-      }
-    }
-    $current->{'extra'}->{'index_entry'}->{'node'} = $new_node;
-  }
-  return ($current);
-}
-
-sub insert_nodes_for_sectioning_commands($$)
-{
-  my $self = shift;
-  my $root = shift;
-  if (!$root->{'type'} or $root->{'type'} ne 'document_root'
-      or !$root->{'contents'}) {
-    return (undef, undef);
-  }
-  my @added_nodes;
-  my @contents;
-  my $previous_node;
-  foreach my $content (@{$root->{'contents'}}) {
-    if ($content->{'cmdname'} and $content->{'cmdname'} ne 'node'
-        and $content->{'cmdname'} ne 'bye'
-        and $content->{'cmdname'} ne 'part'
-        and not ($content->{'extra'} 
-                 and $content->{'extra'}->{'associated_node'})) {
-      my $new_node_tree;
-      if ($content->{'cmdname'} eq 'top') {
-        $new_node_tree = {'contents' => [{'text' => 'Top'}]};
-      } else {
-        $new_node_tree = Texinfo::Common::copy_tree({'contents' 
-          => $content->{'extra'}->{'misc_content'}});
-      }
-      my $new_node = _new_node($self, $new_node_tree);
-      if (defined($new_node)) {
-        push @contents, $new_node;
-        push @added_nodes, $new_node;
-        $new_node->{'extra'}->{'associated_section'} = $content;
-        $content->{'extra'}->{'associated_node'} = $new_node;
-        $new_node->{'parent'} = $content->{'parent'};
-        # reassociate index entries and menus
-        Texinfo::Common::modify_tree($self, $content, \&_reassociate_to_node,
-                                     [$new_node, $previous_node]);
-      }
-    }
-    # check normalized to avoid erroneous nodes, such as duplicates
-    $previous_node = $content 
-      if ($content->{'cmdname'} 
-          and $content->{'cmdname'} eq 'node'
-          and $content->{'extra'}->{'normalized'});
-    push @contents, $content;
-  }
-  return (address@hidden, address@hidden);
-}
-
 sub _copy_contents($)
 {
   my $contents = shift;
@@ -1550,7 +1221,7 @@
   return $copy->{'contents'};
 }
 
-sub _new_node_menu_entry($$)
+sub new_node_menu_entry($$)
 {
   my $self = shift;
   my $node_contents = shift;
@@ -1587,7 +1258,7 @@
   return $entry;
 }
 
-sub _new_block_command($$$)
+sub new_block_command($$$)
 {
   my $block_contents = shift;
   my $parent = shift;
@@ -1642,340 +1313,18 @@
 
   my @pending;
   for my $child (@node_childs) {
-    my $entry = _new_node_menu_entry($self, 
+    my $entry = new_node_menu_entry($self, 
                                      $child->{'extra'}->{'node_content'});
     push @pending, $entry;
   }
 
   my $section = $node->{'extra'}->{'associated_section'};
-  my $current_menu = _new_block_command (address@hidden, $section, 'menu');
+  my $current_menu = new_block_command (address@hidden, $section, 'menu');
 
   return $current_menu;
 }
 
 
-sub add_node_menu_if_missing($$)
-{
-  my $self = shift;
-  my $node = shift;
-
-  if ($node->{'menus'} and @{$node->{'menus'}}) {
-    return;
-  }
-
-  my $current_menu = menu_of_node($self, $node);
-  if (!$current_menu) {
-    return;
-  }
-
-  my $section = $node->{'extra'}->{'associated_section'};
-  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;
-  my $node = shift;
-
-  my @node_childs;
-  if ($node->{'extra'}->{'associated_section'}->{'section_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'};
-      }
-    }
-  }
-  # Special case for @top.  Gather all the children of the @part following
-  # @top.
-  if ($node->{'extra'}->{'associated_section'}->{'cmdname'} eq 'top') {
-    my $current = $node->{'extra'}->{'associated_section'};
-    while ($current->{'section_next'}) {
-      $current = $current->{'section_next'};
-      if ($current->{'cmdname'} and $current->{'cmdname'} eq 'part'
-          and $current->{'section_childs'}) {
-        foreach my $child (@{$current->{'section_childs'}}) {
-          if ($child->{'extra'} and $child->{'extra'}->{'associated_node'}) {
-            push @node_childs, $child->{'extra'}->{'associated_node'};
-          }
-        }
-      } elsif ($current->{'extra'}->{'associated_node'}) {
-        # for @appendix, and what follows, as it stops a @part, but is 
-        # not below @top
-        push @node_childs, $current->{'extra'}->{'associated_node'};
-      }
-    }
-  }
-  if (scalar(@node_childs)) {
-    my %existing_entries;
-    if ($node->{'menus'} and @{$node->{'menus'}}) {
-      foreach my $menu (@{$node->{'menus'}}) {
-        foreach my $entry (@{$menu->{'contents'}}) {
-          if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
-            my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
-            if (! $entry_node->{'manual_content'}
-                and defined($entry_node->{'normalized'})) {
-              $existing_entries{$entry_node->{'normalized'}} 
-                = [$menu, $entry];
-            }
-          }
-        }
-      }
-    }
-    #print STDERR join('|', keys(%existing_entries))."\n";
-    my @pending;
-    my $current_menu;
-    foreach my $node_entry (@node_childs) {
-      if ($existing_entries{$node_entry->{'extra'}->{'normalized'}}) {
-        my $entry;
-        ($current_menu, $entry) 
-         = @{$existing_entries{$node_entry->{'extra'}->{'normalized'}}};
-        if (@pending) {
-          my $index;
-          for ($index = 0; $index < scalar(@{$current_menu->{'contents'}}); 
$index++) {
-            #print STDERR "$index, 
".scalar(@{$current_menu->{'contents'}})."\n";
-            last if ($current_menu->{'contents'}->[$index] eq $entry);
-          }
-          splice (@{$current_menu->{'contents'}}, $index, 0, @pending);
-          foreach my $entry (@pending) {
-            $entry->{'parent'} = $current_menu;
-          }
-          @pending = ();
-        }
-      } else {
-        my $entry = _new_node_menu_entry($self, 
-                              $node_entry->{'extra'}->{'node_content'});
-        push @pending, $entry;
-      }
-    }
-    if (scalar(@pending)) {
-      if (!$current_menu) {
-        my $section = $node->{'extra'}->{'associated_section'};
-        $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;
-      } else {
-        foreach my $entry (@pending) {
-          $entry->{'parent'} = $current_menu;
-        }
-        my $end;
-        if ($current_menu->{'contents'}->[-1]->{'cmdname'}
-            and $current_menu->{'contents'}->[-1]->{'cmdname'} eq 'end') {
-          $end = pop @{$current_menu->{'contents'}};
-        }
-        push @{$current_menu->{'contents'}}, @pending;
-        push @{$current_menu->{'contents'}}, $end if ($end);
-      }
-    }
-  }
-}
-
-# 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;
-  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'}) {
-      complete_node_menu($self, $content);
-    }
-  }
-}
-
-sub _print_down_menus($$;$);
-sub _print_down_menus($$;$)
-{
-  my $self = shift;
-  my $node = shift;
-  my $labels = shift;
-  $labels = $self->labels_information() if (!defined($labels));
-
-  my @master_menu_contents;
-
-  if ($node->{'menus'} and scalar(@{$node->{'menus'}})) {
-    my @node_children;
-    foreach my $menu (@{$node->{'menus'}}) {
-      foreach my $entry (@{$menu->{'contents'}}) {
-        if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
-          push @master_menu_contents, Texinfo::Common::copy_tree($entry);
-          # gather node children to recusrsively print their menus
-          my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
-          if (! $entry_node->{'manual_content'}
-              and defined($entry_node->{'normalized'})) {
-            my $node = $labels->{$entry_node->{'normalized'}};
-            if (defined($node) and $node->{'extra'}) {
-              push @node_children, $node;
-            }
-          }
-        }
-      }
-    }
-    if (scalar(@master_menu_contents)) {
-      # Prepend node title
-      my $node_title_contents;
-      if ($node->{'extra'}->{'associated_section'}
-          and $node->{'extra'}->{'associated_section'}->{'extra'}
-          and 
$node->{'extra'}->{'associated_section'}->{'extra'}->{'misc_content'}) {
-        $node_title_contents
-          = 
_copy_contents($node->{'extra'}->{'associated_section'}->{'extra'}->{'misc_content'});
-      } else {
-        $node_title_contents = 
_copy_contents($node->{'extra'}->{'node_content'});
-      }
-      my $menu_comment = {'type' => 'menu_comment'};
-      $menu_comment->{'contents'}->[0] = {'type' => 'preformatted',
-                                          'parent' => $menu_comment};
-    
-      $menu_comment->{'contents'}->[0]->{'contents'}
-        = [{'text' => "\n", 'type' => 'empty_line'}, @$node_title_contents,
-           {'text' => "\n", 'type' => 'empty_line'},
-           {'text' => "\n", 'type' => 'empty_line'}];
-      foreach my $content (@{$menu_comment->{'contents'}->[0]->{'contents'}}) {
-        $content->{'parent'} = $menu_comment->{'contents'}->[0];
-      }
-      unshift @master_menu_contents, $menu_comment;
-
-      # now recurse in the children
-      foreach my $child (@node_children) {
-        push @master_menu_contents, _print_down_menus($self, $child, $labels);
-      }
-    }
-  }
-  return @master_menu_contents;
-}
-
-sub new_master_menu($;$)
-{
-  my $self = shift;
-  my $labels = shift;
-  $labels = $self->labels_information() if (!defined($labels));
-  my $node = $labels->{'Top'};
-  return undef if (!defined($node));
-
-  my @master_menu_contents;
-  if ($node->{'menus'} and scalar(@{$node->{'menus'}})) {
-    foreach my $menu (@{$node->{'menus'}}) {
-      foreach my $entry (@{$menu->{'contents'}}) {
-        if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
-          my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
-          if (! $entry_node->{'manual_content'}
-              and defined($entry_node->{'normalized'})) {
-            my $node = $labels->{$entry_node->{'normalized'}};
-            if (defined($node) and $node->{'extra'}) {
-              push @master_menu_contents, _print_down_menus($self, 
-                                                            $node, $labels);
-            }
-          }
-        }
-      }
-    }
-  }
-  if (scalar(@master_menu_contents)) {
-    my $first_preformatted = $master_menu_contents[0]->{'contents'}->[0];
-    my $master_menu_title = $self->gdt(' --- The Detailed Node Listing ---');
-    my @master_menu_title_contents;
-    foreach my $content (@{$master_menu_title->{'contents'}}, {'text' => 
"\n"}) {
-      $content->{'parent'} = $first_preformatted;
-      push @master_menu_title_contents, $content;
-    }
-    unshift @{$first_preformatted->{'contents'}}, @master_menu_title_contents;
-    return _new_block_command(address@hidden, undef, 'detailmenu');
-  } else {
-    return undef;
-  }
-}
-
-sub regenerate_master_menu($;$)
-{
-  my $self = shift;
-  my $labels = shift;
-  $labels = $self->labels_information() if (!defined($labels));
-  my $top_node = $labels->{'Top'};
-  return undef if (!defined($top_node));
-
-  my $new_master_menu = new_master_menu($self, $labels);
-  return undef if (!defined($new_master_menu) or !$top_node->{'menus'}
-                   or !scalar(@{$top_node->{'menus'}}));
-
-  foreach my $menu (@{$top_node->{'menus'}}) {
-    my $detailmenu_index = 0;
-    foreach my $entry (@{$menu->{'contents'}}) {
-      if ($entry->{'cmdname'} and $entry->{'cmdname'} eq 'detailmenu') {
-        # replace existing detailmenu by the master menu
-        $new_master_menu->{'parent'} = $menu;
-        splice (@{$menu->{'contents'}}, $detailmenu_index, 1, 
-                $new_master_menu);
-        return 1;
-      }
-      $detailmenu_index++;
-    }
-  }
-
-  my $last_menu = $top_node->{'menus'}->[-1];
-  my $index = scalar(@{$last_menu->{'contents'}});
-  if ($index
-      and $last_menu->{'contents'}->[$index-1]->{'cmdname'}
-      and $last_menu->{'contents'}->[$index-1]->{'cmdname'} eq 'end') {
-    $index --;
-  }
-  $new_master_menu->{'parent'} = $last_menu;
-  if ($index
-      and $last_menu->{'contents'}->[$index-1]->{'type'}
-      and $last_menu->{'contents'}->[$index-1]->{'type'} eq 'menu_comment'
-      and $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]->{'type'}
-      and $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]->{'type'}
-             eq 'preformatted') {
-    my $empty_line = {'type' => 'empty_line', 'text' => "\n", 'parent' =>
-               $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]};
-    push @{$last_menu->{'contents'}->[$index-1]->{'contents'}}, $empty_line;
-  } elsif ($index
-           and $last_menu->{'contents'}->[$index-1]->{'type'}
-           and $last_menu->{'contents'}->[$index-1]->{'type'} eq 'menu_entry') 
{
-    my $menu_comment = {'type' => 'menu_comment', 'parent' => $last_menu};
-    splice (@{$last_menu->{'contents'}}, $index, 0, $menu_comment);
-    $index++;
-    my $preformatted = {'type' => 'preformatted', 'parent' => $menu_comment};
-    push @{$menu_comment->{'contents'}}, $preformatted;
-    my $empty_line = {'type' => 'after_description_line', 'text' => "\n",
-                      'parent' => $preformatted};
-    push @{$preformatted->{'contents'}}, $empty_line;
-  }
-  splice (@{$last_menu->{'contents'}}, $index, 0, $new_master_menu);
-
-  return 1;
-}
-
 sub _sort_string($$)
 {
   my $a = shift;
@@ -2113,89 +1462,7 @@
   return $merged_index_entries;
 }
 
-# modify the menu tree to put description and menu comment content
-# together directly in the menu.  Put the menu_entry in a preformatted.
-# last merge preformatted.
-sub menu_to_simple_menu($);
 
-sub menu_to_simple_menu($)
-{
-  my $menu = shift;
-  
-  my @contents;
-  foreach my $content (@{$menu->{'contents'}}) {
-    if ($content->{'type'} and $content->{'type'} eq 'menu_comment') {
-      push @contents, @{$content->{'contents'}};
-    } elsif ($content->{'type'} and $content->{'type'} eq 'menu_entry') {
-      my $preformatted = {'type' => 'preformatted', 'contents' => [$content]};
-      push @contents, $preformatted;
-      $content->{'parent'} = $preformatted;
-
-      my $in_description;
-      my @args = @{$content->{'args'}};
-      @{$content->{'args'}} = ();
-      while (@args) {
-        if ($args[0]->{'type'} and $args[0]->{'type'} eq 
'menu_entry_description') {
-          my $description = shift @args;
-          push @contents, @{$description->{'contents'}};
-          push @contents, @args;
-          last;
-        } else {
-          my $arg = shift @args;
-          push @{$content->{'args'}}, $arg;
-        }
-      }
-    } elsif ($content->{'cmdname'}
-             and $Texinfo::Common::menu_commands{$content->{'cmdname'}}) {
-      menu_to_simple_menu($content);
-      push @contents, $content;
-    } else {
-      push @contents, $content;
-    }
-  }
-  
-  # reset parent, put in menu and merge preformatted.
-  @{$menu->{'contents'}} = ();
-  my $current_preformatted;
-  foreach my $content (@contents) {
-    $content->{'parent'} = $menu;
-    if ($content->{'type'} and $content->{'type'} eq 'preformatted') {
-      if (!defined($current_preformatted)) {
-        $current_preformatted = $content;
-        push @{$menu->{'contents'}}, $content;
-      } else {
-        foreach my $preformatted_content (@{$content->{'contents'}}) {
-          push @{$current_preformatted->{'contents'}}, $preformatted_content;
-          $preformatted_content->{'parent'} = $current_preformatted;
-        }
-      }
-    } else {
-      $current_preformatted = undef;
-      push @{$menu->{'contents'}}, $content;
-    }
-  }
-}
-
-sub set_menus_to_simple_menu($)
-{
-  my $self = shift;
-
-  if ($self->{'info'} and $self->{'info'}->{'unassociated_menus'}) {
-    foreach my $menu (@{$self->{'info'}->{'unassociated_menus'}}) {
-      menu_to_simple_menu($menu);
-    }
-  }
-  if ($self->{'nodes'} and @{$self->{'nodes'}}) {
-    foreach my $node (@{$self->{'nodes'}}) {
-      if ($node->{'menus'}) {
-        foreach my $menu (@{$node->{'menus'}}) {
-          menu_to_simple_menu($menu);
-        }
-      }
-    }
-  }
-}
-
 1;
 
 __END__
@@ -2206,7 +1473,7 @@
 
 =head1 NAME
 
-Texinfo::Structuring - informations and transformations in Texinfo::Parser tree
+Texinfo::Structuring - information on Texinfo::Parser tree
 
 =head1 SYNOPSIS
 
@@ -2543,53 +1810,6 @@
 When simply sorting, the array of the sorted indes entries is associated
 with the index name.
 
-=item ($root_content, $added_sections) = fill_gaps_in_sectioning ($root)
-
-This function adds empty C<@unnumbered> and similar commands in a tree
-to fill gaps in sectioning.  This may be used, for example, when converting 
-from a format that can handle gaps in sectioning.  I<$root> is the tree
-root.  An array reference is returned, containing the root contents
-with added sectioning commands, as well as an array reference containing 
-the added sectioning commands.
-
-If the sectioning commands are lowered or raised (with C<@raisesections>,
-C<@lowersection>) the tree may be modified with C<@raisesections> or
-C<@lowersection> added to some tree elements.
-
-=item menu_to_simple_menu ($menu)
-
-=item set_menus_to_simple_menu ($parser)
-
-C<menu_to_simple_menu> transforms the tree of a menu tree element.  
-C<set_menus_to_simple_menu> calls C<menu_to_simple_menu> for all the
-menus of the document.
-
-A simple menu has no I<menu_comment>, I<menu_entry> or 
I<menu_entry_description>
-container anymore, their content are merged directly in the menu in 
-I<preformatted> container.
-
-=item ($root_content, $added_nodes) = insert_nodes_for_sectioning_commands 
($parser, $tree)
-
-Insert nodes for sectioning commands without node in C<$tree>.
-An array reference is returned, containing the root contents
-with added nodes, as well as an array reference containing the 
-added nodes.
-
-=item complete_tree_nodes_menus ($parser, $tree)
-
-Add menu entries or whole menus for nodes associated with sections,
-based on the sectioning tree.  This function should therefore be
-called after L<sectioning_structure>.
-
-=item $detailmenu = new_master_menu ($parser)
-
-Returns a detailmenu tree element formatted as a master node.
-
-=item regenerate_master_menu ($parser)
-
-Regenerate the Top node master menu, replacing the first detailmenu
-in Top node menus or appending at the end of the Top node menu.
-
 =back
 
 =head1 SEE ALSO

Added: trunk/tp/Texinfo/Transformations.pm
===================================================================
--- trunk/tp/Texinfo/Transformations.pm                         (rev 0)
+++ trunk/tp/Texinfo/Transformations.pm 2016-10-30 15:53:19 UTC (rev 7480)
@@ -0,0 +1,825 @@
+# Transformations.pm: some transformations of the document tree
+#
+# Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation, 
+# Inc.
+# 
+# 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 3 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.  If not, see <http://www.gnu.org/licenses/>.
+# 
+# Original author: Patrice Dumas <address@hidden>
+# Parts (also from Patrice Dumas) come from texi2html.pl.
+
+package Texinfo::Transformations;
+
+use 5.00405;
+
+use strict;
+
+use Texinfo::Common;
+use Texinfo::Structuring;
+
+# Add raise/lowersections to be back at the normal level
+sub _correct_level($$;$)
+{
+  my $section = shift;
+  my $parent = shift;
+  my $modifier = shift;
+  $modifier = 1 if (!defined($modifier));
+
+  my @result;
+  if ($section->{'extra'} and $section->{'extra'}->{'sections_level'}) {
+    my $level_to_remove = $modifier * $section->{'extra'}->{'sections_level'};
+    my $command;
+    if ($level_to_remove < 0) {
+      $command = 'raisesection';
+    } else {
+      $command = 'lowersection';
+    }
+    my $remaining_level = abs($level_to_remove);
+    while ($remaining_level) {
+      push @result, {'cmdname' => $command,
+                     'parent' => $parent};
+      push @result, {'type' => 'empty_line', 'text' => "\n",
+                     'parent' => $parent};
+      $remaining_level--;
+    }
+  }
+  return @result;
+}
+
+sub fill_gaps_in_sectioning($)
+{
+  my $root = shift;
+  if (!$root->{'type'} or $root->{'type'} ne 'document_root'
+      or !$root->{'contents'}) {
+    return undef;
+  }
+  my @sections_list;
+  foreach my $content (@{$root->{'contents'}}) {
+    if ($content->{'cmdname'} and $content->{'cmdname'} ne 'node'
+        and $content->{'cmdname'} ne 'bye') {
+      push @sections_list, $content;
+    }
+  }
+
+  return (undef, undef) if (!scalar(@sections_list));
+
+  my @added_sections;
+  my @contents;
+  my $previous_section;
+  foreach my $content(@{$root->{'contents'}}) {
+    push @contents, $content;
+    if (address@hidden or $sections_list[0] ne $content) {
+      next;
+    }
+    my $current_section = shift @sections_list;
+    my $current_section_level = $current_section->{'level'};
+    my $next_section = $sections_list[0];
+    
+    if (defined($next_section)) {
+      my $next_section_level = $next_section->{'level'};
+      if ($next_section_level - $current_section_level > 1) {
+        my @correct_level_offset_commands = _correct_level($next_section,
+                                                          $contents[-1]);
+        if (@correct_level_offset_commands) {
+          push @{$contents[-1]->{'contents'}}, @correct_level_offset_commands;
+        }
+        #print STDERR "* $current_section_level 
"._print_root_command_texi($current_section)."\n";
+        #print STDERR "  $next_section_level 
"._print_root_command_texi($next_section)."\n";
+        while ($next_section_level - $current_section_level > 1) {
+          $current_section_level++;
+          my $new_section = {'cmdname' =>
+            
$Texinfo::Common::level_to_structuring_command{'unnumbered'}->[$current_section_level],
+            'parent' => $root,
+          };
+          $new_section->{'contents'} = [{'type' => 'empty_line', 
+                                         'text' => "\n",
+                                         'parent' => $new_section}];
+          $new_section->{'args'} = [{'type' => 'misc_line_arg',
+                                     'parent' => $new_section}];
+          $new_section->{'args'}->[0]->{'contents'} = [
+             {'type' => 'empty_spaces_after_command',
+              'text' => " ",
+              'extra' => {'command' => $new_section},
+              'parent' => $new_section->{'args'}->[0]
+             },
+             {'cmdname' => 'asis',
+              'parent' => $new_section->{'args'}->[0]
+             },
+             {'type' => 'spaces_at_end',
+              'text' => "\n",
+              'parent' => $new_section->{'args'}->[0]
+             }];
+          $new_section->{'args'}->[0]->{'contents'}->[1]->{'args'}
+             = [{'type' => 'brace_command_arg',
+                 'contents' => [],
+                 'parent' => $new_section->{'args'}->[0]->{'contents'}->[1]}];
+          my @misc_contents = @{$new_section->{'args'}->[0]->{'contents'}};
+          Texinfo::Common::trim_spaces_comment_from_content(address@hidden);
+          $new_section->{'extra'}->{'misc_content'} = address@hidden;
+          push @contents, $new_section;
+          push @added_sections, $new_section;
+          #print STDERR "  -> "._print_root_command_texi($new_section)."\n";
+        }
+        my @set_level_offset_commands = _correct_level($next_section,
+                                                       $contents[-1], -1);
+        if (@set_level_offset_commands) {
+          push @{$contents[-1]->{'contents'}}, @set_level_offset_commands;
+        }
+      }
+    }
+  }
+  return (address@hidden, address@hidden);
+}
+
+sub _reference_to_arg($$$)
+{
+  my $self = shift;
+  my $type = shift;
+  my $current = shift;
+
+  if ($current->{'cmdname'} and 
+      $Texinfo::Common::ref_commands{$current->{'cmdname'}}
+      and $current->{'extra'} 
+      and $current->{'extra'}->{'brace_command_contents'}) {
+    my @args_try_order;
+    if ($current->{'cmdname'} eq 'inforef') {
+      @args_try_order = (0, 1, 2);
+    } else {
+      @args_try_order = (0, 1, 2, 4, 3);
+    }
+    foreach my $index (@args_try_order) {
+      if (defined($current->{'args'}->[$index]) 
+          and 
defined($current->{'extra'}->{'brace_command_contents'}->[$index])) {
+        # This a double checking that there is some content.
+        # Not sure that it is useful.
+        my $text = 
Texinfo::Convert::Text::convert($current->{'args'}->[$index]);
+        if (defined($text) and $text =~ /\S/) {
+          my $result = {'contents' => 
+                $current->{'extra'}->{'brace_command_contents'}->[$index],
+                        'parent' => $current->{'parent'}};
+          return ($result);
+        }
+      }
+    }
+    return {'text' => '', 'parent' => $current->{'parent'}};
+  } else {
+    return ($current);
+  }
+}
+
+sub reference_to_arg_in_tree($$)
+{
+  my $self = shift;
+  my $tree = shift;
+  return Texinfo::Common::modify_tree($self, $tree, \&_reference_to_arg);
+}
+
+# prepare a new node and register it
+sub _new_node($$)
+{
+  my $self = shift;
+  my $node_tree = shift;
+
+  $node_tree = Texinfo::Common::protect_comma_in_tree($node_tree);
+  $node_tree->{'contents'} 
+     = Texinfo::Common::protect_first_parenthesis($node_tree->{'contents'});
+  $node_tree = reference_to_arg_in_tree($self, $node_tree);
+
+  my $empty_node = 0;
+  if (!$node_tree->{'contents'} 
+      or !scalar(@{$node_tree->{'contents'}})) {
+    $node_tree->{'contents'} = [{'text' => ''}];
+    $empty_node = 1;
+  }
+
+  unless (($node_tree->{'contents'}->[-1]->{'cmdname'}
+       and ($node_tree->{'contents'}->[-1]->{'cmdname'} eq 'c'
+            or $node_tree->{'contents'}->[-1]->{'cmdname'} eq 'comment'))
+      or (defined($node_tree->{'contents'}->[-1]->{'text'})
+          and $node_tree->{'contents'}->[-1]->{'text'} =~ /\n/)) {
+    push @{$node_tree->{'contents'}}, 
+           {'type' => 'spaces_at_end', 'text' => "\n"};
+  }
+
+  my $appended_number = 0 +$empty_node;
+  my ($node, $parsed_node);
+
+  while (!defined($node) 
+         or ($self->{'labels'} 
+            and $self->{'labels'}->{$parsed_node->{'normalized'}})) {
+    $node = {'cmdname' => 'node', 'args' => [{}]};
+    my $node_arg = $node->{'args'}->[0];
+    $node_arg->{'parent'} = $node;
+    @{$node_arg->{'contents'}} = (
+       {'extra' => {'command' => $node},
+        'text' => ' ',
+        'type' => 'empty_spaces_after_command'},
+        @{$node_tree->{'contents'}});
+    if ($appended_number) {
+      splice (@{$node_arg->{'contents'}}, -1, 0,
+                  {'text' => " $appended_number"});
+    }
+    foreach my $content (@{$node_arg->{'contents'}}) {
+      $content->{'parent'} = $node_arg;
+    }
+    $parsed_node = Texinfo::Parser::_parse_node_manual($node_arg);
+    if (!defined($parsed_node) or !$parsed_node->{'node_content'}
+        or $parsed_node->{'normalized'} !~ /[^-]/) {
+      if ($appended_number) {
+        return undef;
+      } else {
+        $node = undef;
+      }
+    }
+    $appended_number++;
+  }
+
+  push @{$node->{'extra'}->{'nodes_manuals'}}, $parsed_node;
+  if (!Texinfo::Parser::_register_label($self, $node, $parsed_node, undef)) {
+    print STDERR "BUG: node unique, register failed:  
$parsed_node->{'normalized'}\n";
+  }
+  push @{$self->{'nodes'}}, $node;
+  return $node;
+}
+
+# reassociate a tree element to the new node, from previous node
+sub _reassociate_to_node($$$$)
+{
+  my $self = shift;
+  my $type = shift;
+  my $current = shift;
+  my $nodes = shift;
+  my ($new_node, $previous_node) = @{$nodes};
+
+  if ($current->{'cmdname'} and $current->{'cmdname'} eq 'menu') {
+    if ($previous_node) {
+      if (!$previous_node->{'menus'} or address@hidden>{'menus'}}
+           or !grep {$current eq $_} @{$previous_node->{'menus'}}) {
+        print STDERR "Bug: menu $current not in previous node 
$previous_node\n";
+      } else {
+        @{$previous_node->{'menus'}} = grep {$_ ne $current} 
@{$previous_node->{'menus'}};
+        delete $previous_node->{'menus'} if !(@{$previous_node->{'menus'}});
+      }
+    } else {
+      my $info = $self->global_informations();
+      if (!$info or !$info->{'unassociated_menus'} 
+          or address@hidden>{'unassociated_menus'}}
+          or !grep {$current eq $_} @{$info->{'unassociated_menus'}}) {
+        print STDERR "Bug: menu $current not in unassociated menus\n";
+      } else {
+        @{$info->{'unassociated_menus'}} 
+          = grep {$_ ne $current} @{$info->{'unassociated_menus'}};
+        delete $info->{'unassociated_menus'} if 
!(@{$info->{'unassociated_menus'}});
+      }
+    }
+    push @{$new_node->{'menus'}}, $current;
+  } elsif ($current->{'extra'} and $current->{'extra'}->{'index_entry'}) {
+    if ($previous_node 
+        and (!$current->{'extra'}->{'index_entry'}->{'node'}
+             or $current->{'extra'}->{'index_entry'}->{'node'} ne 
$previous_node)) {
+      print STDERR "Bug: index entry $current (".
+        Texinfo::Convert::Texinfo::convert ({'contents' => 
$current->{'extra'}->{'index_entry'}->{'content'}})
+         .") not in previous node $previous_node\n";
+      print STDERR "  previous node: 
"._print_root_command_texi($previous_node)."\n";
+      if ($current->{'extra'}->{'index_entry'}->{'node'}) {
+        print STDERR "  current node: ".
+         
_print_root_command_texi($current->{'extra'}->{'index_entry'}->{'node'})."\n";
+      } else {
+        print STDERR "  current node not set\n";
+      }
+    }
+    $current->{'extra'}->{'index_entry'}->{'node'} = $new_node;
+  }
+  return ($current);
+}
+
+sub insert_nodes_for_sectioning_commands($$)
+{
+  my $self = shift;
+  my $root = shift;
+  if (!$root->{'type'} or $root->{'type'} ne 'document_root'
+      or !$root->{'contents'}) {
+    return (undef, undef);
+  }
+  my @added_nodes;
+  my @contents;
+  my $previous_node;
+  foreach my $content (@{$root->{'contents'}}) {
+    if ($content->{'cmdname'} and $content->{'cmdname'} ne 'node'
+        and $content->{'cmdname'} ne 'bye'
+        and $content->{'cmdname'} ne 'part'
+        and not ($content->{'extra'} 
+                 and $content->{'extra'}->{'associated_node'})) {
+      my $new_node_tree;
+      if ($content->{'cmdname'} eq 'top') {
+        $new_node_tree = {'contents' => [{'text' => 'Top'}]};
+      } else {
+        $new_node_tree = Texinfo::Common::copy_tree({'contents' 
+          => $content->{'extra'}->{'misc_content'}});
+      }
+      my $new_node = _new_node($self, $new_node_tree);
+      if (defined($new_node)) {
+        push @contents, $new_node;
+        push @added_nodes, $new_node;
+        $new_node->{'extra'}->{'associated_section'} = $content;
+        $content->{'extra'}->{'associated_node'} = $new_node;
+        $new_node->{'parent'} = $content->{'parent'};
+        # reassociate index entries and menus
+        Texinfo::Common::modify_tree($self, $content, \&_reassociate_to_node,
+                                     [$new_node, $previous_node]);
+      }
+    }
+    # check normalized to avoid erroneous nodes, such as duplicates
+    $previous_node = $content 
+      if ($content->{'cmdname'} 
+          and $content->{'cmdname'} eq 'node'
+          and $content->{'extra'}->{'normalized'});
+    push @contents, $content;
+  }
+  return (address@hidden, address@hidden);
+}
+
+sub complete_node_menu($$)
+{
+  my $self = shift;
+  my $node = shift;
+
+  my @node_childs;
+  if ($node->{'extra'}->{'associated_section'}->{'section_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'};
+      }
+    }
+  }
+  # Special case for @top.  Gather all the children of the @part following
+  # @top.
+  if ($node->{'extra'}->{'associated_section'}->{'cmdname'} eq 'top') {
+    my $current = $node->{'extra'}->{'associated_section'};
+    while ($current->{'section_next'}) {
+      $current = $current->{'section_next'};
+      if ($current->{'cmdname'} and $current->{'cmdname'} eq 'part'
+          and $current->{'section_childs'}) {
+        foreach my $child (@{$current->{'section_childs'}}) {
+          if ($child->{'extra'} and $child->{'extra'}->{'associated_node'}) {
+            push @node_childs, $child->{'extra'}->{'associated_node'};
+          }
+        }
+      } elsif ($current->{'extra'}->{'associated_node'}) {
+        # for @appendix, and what follows, as it stops a @part, but is 
+        # not below @top
+        push @node_childs, $current->{'extra'}->{'associated_node'};
+      }
+    }
+  }
+  if (scalar(@node_childs)) {
+    my %existing_entries;
+    if ($node->{'menus'} and @{$node->{'menus'}}) {
+      foreach my $menu (@{$node->{'menus'}}) {
+        foreach my $entry (@{$menu->{'contents'}}) {
+          if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
+            my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
+            if (! $entry_node->{'manual_content'}
+                and defined($entry_node->{'normalized'})) {
+              $existing_entries{$entry_node->{'normalized'}} 
+                = [$menu, $entry];
+            }
+          }
+        }
+      }
+    }
+    #print STDERR join('|', keys(%existing_entries))."\n";
+    my @pending;
+    my $current_menu;
+    foreach my $node_entry (@node_childs) {
+      if ($existing_entries{$node_entry->{'extra'}->{'normalized'}}) {
+        my $entry;
+        ($current_menu, $entry) 
+         = @{$existing_entries{$node_entry->{'extra'}->{'normalized'}}};
+        if (@pending) {
+          my $index;
+          for ($index = 0; $index < scalar(@{$current_menu->{'contents'}}); 
$index++) {
+            #print STDERR "$index, 
".scalar(@{$current_menu->{'contents'}})."\n";
+            last if ($current_menu->{'contents'}->[$index] eq $entry);
+          }
+          splice (@{$current_menu->{'contents'}}, $index, 0, @pending);
+          foreach my $entry (@pending) {
+            $entry->{'parent'} = $current_menu;
+          }
+          @pending = ();
+        }
+      } else {
+        my $entry = Texinfo::Structuring::new_node_menu_entry($self, 
+                              $node_entry->{'extra'}->{'node_content'});
+        push @pending, $entry;
+      }
+    }
+    if (scalar(@pending)) {
+      if (!$current_menu) {
+        my $section = $node->{'extra'}->{'associated_section'};
+        $current_menu =
+       Texinfo::Structuring::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;
+      } else {
+        foreach my $entry (@pending) {
+          $entry->{'parent'} = $current_menu;
+        }
+        my $end;
+        if ($current_menu->{'contents'}->[-1]->{'cmdname'}
+            and $current_menu->{'contents'}->[-1]->{'cmdname'} eq 'end') {
+          $end = pop @{$current_menu->{'contents'}};
+        }
+        push @{$current_menu->{'contents'}}, @pending;
+        push @{$current_menu->{'contents'}}, $end if ($end);
+      }
+    }
+  }
+}
+
+# This should be called after Texinfo::Structuring::sectioning_structure.
+sub complete_tree_nodes_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'}) {
+      complete_node_menu($self, $content);
+    }
+  }
+}
+
+sub _copy_contents($)
+{
+  my $contents = shift;
+  my $copy = Texinfo::Common::copy_tree({'contents' => $contents});
+  return $copy->{'contents'};
+}
+
+sub _print_down_menus($$;$);
+sub _print_down_menus($$;$)
+{
+  my $self = shift;
+  my $node = shift;
+  my $labels = shift;
+  $labels = $self->labels_information() if (!defined($labels));
+
+  my @master_menu_contents;
+
+  if ($node->{'menus'} and scalar(@{$node->{'menus'}})) {
+    my @node_children;
+    foreach my $menu (@{$node->{'menus'}}) {
+      foreach my $entry (@{$menu->{'contents'}}) {
+        if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
+          push @master_menu_contents, Texinfo::Common::copy_tree($entry);
+          # gather node children to recusrsively print their menus
+          my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
+          if (! $entry_node->{'manual_content'}
+              and defined($entry_node->{'normalized'})) {
+            my $node = $labels->{$entry_node->{'normalized'}};
+            if (defined($node) and $node->{'extra'}) {
+              push @node_children, $node;
+            }
+          }
+        }
+      }
+    }
+    if (scalar(@master_menu_contents)) {
+      # Prepend node title
+      my $node_title_contents;
+      if ($node->{'extra'}->{'associated_section'}
+          and $node->{'extra'}->{'associated_section'}->{'extra'}
+          and 
$node->{'extra'}->{'associated_section'}->{'extra'}->{'misc_content'}) {
+        $node_title_contents
+          = 
_copy_contents($node->{'extra'}->{'associated_section'}->{'extra'}->{'misc_content'});
+      } else {
+        $node_title_contents = 
_copy_contents($node->{'extra'}->{'node_content'});
+      }
+      my $menu_comment = {'type' => 'menu_comment'};
+      $menu_comment->{'contents'}->[0] = {'type' => 'preformatted',
+                                          'parent' => $menu_comment};
+    
+      $menu_comment->{'contents'}->[0]->{'contents'}
+        = [{'text' => "\n", 'type' => 'empty_line'}, @$node_title_contents,
+           {'text' => "\n", 'type' => 'empty_line'},
+           {'text' => "\n", 'type' => 'empty_line'}];
+      foreach my $content (@{$menu_comment->{'contents'}->[0]->{'contents'}}) {
+        $content->{'parent'} = $menu_comment->{'contents'}->[0];
+      }
+      unshift @master_menu_contents, $menu_comment;
+
+      # now recurse in the children
+      foreach my $child (@node_children) {
+        push @master_menu_contents, _print_down_menus($self, $child, $labels);
+      }
+    }
+  }
+  return @master_menu_contents;
+}
+
+sub new_master_menu($;$)
+{
+  my $self = shift;
+  my $labels = shift;
+  $labels = $self->labels_information() if (!defined($labels));
+  my $node = $labels->{'Top'};
+  return undef if (!defined($node));
+
+  my @master_menu_contents;
+  if ($node->{'menus'} and scalar(@{$node->{'menus'}})) {
+    foreach my $menu (@{$node->{'menus'}}) {
+      foreach my $entry (@{$menu->{'contents'}}) {
+        if ($entry->{'type'} and $entry->{'type'} eq 'menu_entry') {
+          my $entry_node = $entry->{'extra'}->{'menu_entry_node'};
+          if (! $entry_node->{'manual_content'}
+              and defined($entry_node->{'normalized'})) {
+            my $node = $labels->{$entry_node->{'normalized'}};
+            if (defined($node) and $node->{'extra'}) {
+              push @master_menu_contents, _print_down_menus($self, 
+                                                            $node, $labels);
+            }
+          }
+        }
+      }
+    }
+  }
+  if (scalar(@master_menu_contents)) {
+    my $first_preformatted = $master_menu_contents[0]->{'contents'}->[0];
+    my $master_menu_title = $self->gdt(' --- The Detailed Node Listing ---');
+    my @master_menu_title_contents;
+    foreach my $content (@{$master_menu_title->{'contents'}}, {'text' => 
"\n"}) {
+      $content->{'parent'} = $first_preformatted;
+      push @master_menu_title_contents, $content;
+    }
+    unshift @{$first_preformatted->{'contents'}}, @master_menu_title_contents;
+    return Texinfo::Structuring::new_block_command(address@hidden, undef, 
'detailmenu');
+  } else {
+    return undef;
+  }
+}
+
+sub regenerate_master_menu($;$)
+{
+  my $self = shift;
+  my $labels = shift;
+  $labels = $self->labels_information() if (!defined($labels));
+  my $top_node = $labels->{'Top'};
+  return undef if (!defined($top_node));
+
+  my $new_master_menu = new_master_menu($self, $labels);
+  return undef if (!defined($new_master_menu) or !$top_node->{'menus'}
+                   or !scalar(@{$top_node->{'menus'}}));
+
+  foreach my $menu (@{$top_node->{'menus'}}) {
+    my $detailmenu_index = 0;
+    foreach my $entry (@{$menu->{'contents'}}) {
+      if ($entry->{'cmdname'} and $entry->{'cmdname'} eq 'detailmenu') {
+        # replace existing detailmenu by the master menu
+        $new_master_menu->{'parent'} = $menu;
+        splice (@{$menu->{'contents'}}, $detailmenu_index, 1, 
+                $new_master_menu);
+        return 1;
+      }
+      $detailmenu_index++;
+    }
+  }
+
+  my $last_menu = $top_node->{'menus'}->[-1];
+  my $index = scalar(@{$last_menu->{'contents'}});
+  if ($index
+      and $last_menu->{'contents'}->[$index-1]->{'cmdname'}
+      and $last_menu->{'contents'}->[$index-1]->{'cmdname'} eq 'end') {
+    $index --;
+  }
+  $new_master_menu->{'parent'} = $last_menu;
+  if ($index
+      and $last_menu->{'contents'}->[$index-1]->{'type'}
+      and $last_menu->{'contents'}->[$index-1]->{'type'} eq 'menu_comment'
+      and $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]->{'type'}
+      and $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]->{'type'}
+             eq 'preformatted') {
+    my $empty_line = {'type' => 'empty_line', 'text' => "\n", 'parent' =>
+               $last_menu->{'contents'}->[$index-1]->{'contents'}->[-1]};
+    push @{$last_menu->{'contents'}->[$index-1]->{'contents'}}, $empty_line;
+  } elsif ($index
+           and $last_menu->{'contents'}->[$index-1]->{'type'}
+           and $last_menu->{'contents'}->[$index-1]->{'type'} eq 'menu_entry') 
{
+    my $menu_comment = {'type' => 'menu_comment', 'parent' => $last_menu};
+    splice (@{$last_menu->{'contents'}}, $index, 0, $menu_comment);
+    $index++;
+    my $preformatted = {'type' => 'preformatted', 'parent' => $menu_comment};
+    push @{$menu_comment->{'contents'}}, $preformatted;
+    my $empty_line = {'type' => 'after_description_line', 'text' => "\n",
+                      'parent' => $preformatted};
+    push @{$preformatted->{'contents'}}, $empty_line;
+  }
+  splice (@{$last_menu->{'contents'}}, $index, 0, $new_master_menu);
+
+  return 1;
+}
+
+# modify the menu tree to put description and menu comment content
+# together directly in the menu.  Put the menu_entry in a preformatted.
+# last merge preformatted.
+sub menu_to_simple_menu($);
+
+sub menu_to_simple_menu($)
+{
+  my $menu = shift;
+  
+  my @contents;
+  foreach my $content (@{$menu->{'contents'}}) {
+    if ($content->{'type'} and $content->{'type'} eq 'menu_comment') {
+      push @contents, @{$content->{'contents'}};
+    } elsif ($content->{'type'} and $content->{'type'} eq 'menu_entry') {
+      my $preformatted = {'type' => 'preformatted', 'contents' => [$content]};
+      push @contents, $preformatted;
+      $content->{'parent'} = $preformatted;
+
+      my $in_description;
+      my @args = @{$content->{'args'}};
+      @{$content->{'args'}} = ();
+      while (@args) {
+        if ($args[0]->{'type'} and $args[0]->{'type'} eq 
'menu_entry_description') {
+          my $description = shift @args;
+          push @contents, @{$description->{'contents'}};
+          push @contents, @args;
+          last;
+        } else {
+          my $arg = shift @args;
+          push @{$content->{'args'}}, $arg;
+        }
+      }
+    } elsif ($content->{'cmdname'}
+             and $Texinfo::Common::menu_commands{$content->{'cmdname'}}) {
+      menu_to_simple_menu($content);
+      push @contents, $content;
+    } else {
+      push @contents, $content;
+    }
+  }
+  
+  # reset parent, put in menu and merge preformatted.
+  @{$menu->{'contents'}} = ();
+  my $current_preformatted;
+  foreach my $content (@contents) {
+    $content->{'parent'} = $menu;
+    if ($content->{'type'} and $content->{'type'} eq 'preformatted') {
+      if (!defined($current_preformatted)) {
+        $current_preformatted = $content;
+        push @{$menu->{'contents'}}, $content;
+      } else {
+        foreach my $preformatted_content (@{$content->{'contents'}}) {
+          push @{$current_preformatted->{'contents'}}, $preformatted_content;
+          $preformatted_content->{'parent'} = $current_preformatted;
+        }
+      }
+    } else {
+      $current_preformatted = undef;
+      push @{$menu->{'contents'}}, $content;
+    }
+  }
+}
+
+sub set_menus_to_simple_menu($)
+{
+  my $self = shift;
+
+  if ($self->{'info'} and $self->{'info'}->{'unassociated_menus'}) {
+    foreach my $menu (@{$self->{'info'}->{'unassociated_menus'}}) {
+      menu_to_simple_menu($menu);
+    }
+  }
+  if ($self->{'nodes'} and @{$self->{'nodes'}}) {
+    foreach my $node (@{$self->{'nodes'}}) {
+      if ($node->{'menus'}) {
+        foreach my $menu (@{$node->{'menus'}}) {
+          menu_to_simple_menu($menu);
+        }
+      }
+    }
+  }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Texinfo::Transformations - transformations of Texinfo::Parser.pm tree
+
+=head1 SYNOPSIS
+
+  use Texinfo:Transformations;
+  
+  
+=head1 DESCRIPTION
+
+Includes miscellaneous methods C<set_menus_to_simple_menu> and
+C<menu_to_simple_menu> to change the menu texinfo tree, as well
+as C<insert_nodes_for_sectioning_commands> that adds nodes for 
+sectioning commands without nodes and C<complete_tree_nodes_menus>
+that completes the node menus based on the sectioning tree.
+
+
+
+=head1 METHODS
+
+No method is exported in the default case.
+
+Most of those function references takes a Texinfo::Parser object
+as argument, see L<Texinfo::Parser>.
+
+=over
+
+
+=item ($root_content, $added_sections) = fill_gaps_in_sectioning ($root)
+
+This function adds empty C<@unnumbered> and similar commands in a tree
+to fill gaps in sectioning.  This may be used, for example, when converting 
+from a format that can handle gaps in sectioning.  I<$root> is the tree
+root.  An array reference is returned, containing the root contents
+with added sectioning commands, as well as an array reference containing 
+the added sectioning commands.
+
+If the sectioning commands are lowered or raised (with C<@raisesections>,
+C<@lowersection>) the tree may be modified with C<@raisesections> or
+C<@lowersection> added to some tree elements.
+
+=item menu_to_simple_menu ($menu)
+
+=item set_menus_to_simple_menu ($parser)
+
+C<menu_to_simple_menu> transforms the tree of a menu tree element.  
+C<set_menus_to_simple_menu> calls C<menu_to_simple_menu> for all the
+menus of the document.
+
+A simple menu has no I<menu_comment>, I<menu_entry> or 
I<menu_entry_description>
+container anymore, their content are merged directly in the menu in 
+I<preformatted> container.
+
+=item ($root_content, $added_nodes) = insert_nodes_for_sectioning_commands 
($parser, $tree)
+
+Insert nodes for sectioning commands without node in C<$tree>.
+An array reference is returned, containing the root contents
+with added nodes, as well as an array reference containing the 
+added nodes.
+
+=item complete_tree_nodes_menus ($parser, $tree)
+
+Add menu entries or whole menus for nodes associated with sections,
+based on the sectioning tree.  This function should therefore be
+called after L<sectioning_structure>.
+
+=item $detailmenu = new_master_menu ($parser)
+
+Returns a detailmenu tree element formatted as a master node.
+
+=item regenerate_master_menu ($parser)
+
+Regenerate the Top node master menu, replacing the first detailmenu
+in Top node menus or appending at the end of the Top node menu.
+
+=back
+
+=head1 SEE ALSO
+
+L<Texinfo manual|http://www.gnu.org/s/texinfo/manual/texinfo/>, 
+L<Texinfo::Parser>.
+
+=head1 AUTHOR
+
+Patrice Dumas, E<lt>address@hidden<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2010, 2011, 2012 Free Software Foundation, Inc.
+
+This library 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 3 of the License,
+or (at your option) any later version.
+
+=cut

Modified: trunk/tp/t/automatic_menus.t
===================================================================
--- trunk/tp/t/automatic_menus.t        2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/t/automatic_menus.t        2016-10-30 15:53:19 UTC (rev 7480)
@@ -15,7 +15,7 @@
 use lib 'maintain/lib/libintl-perl/lib/';
 use lib 'maintain/lib/Text-Unidecode/lib/';
 use Texinfo::Parser qw(parse_texi_text);
-use Texinfo::Structuring;
+use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
 use Data::Dumper;
@@ -31,7 +31,7 @@
   my $parser = Texinfo::Parser::parser();
   my $tree = $parser->parse_texi_text($in);
   my $sectioning = $parser->Texinfo::Structuring::sectioning_structure($tree);
-  $parser->Texinfo::Structuring::complete_tree_nodes_menus($tree);
+  $parser->Texinfo::Transformations::complete_tree_nodes_menus($tree);
   my $texi_result = Texinfo::Convert::Texinfo::convert($tree);
 
   if (!defined($out)) {

Modified: trunk/tp/t/automatic_nodes.t
===================================================================
--- trunk/tp/t/automatic_nodes.t        2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/t/automatic_nodes.t        2016-10-30 15:53:19 UTC (rev 7480)
@@ -15,7 +15,7 @@
 use lib 'maintain/lib/libintl-perl/lib/';
 use lib 'maintain/lib/Text-Unidecode/lib/';
 use Texinfo::Parser qw(parse_texi_text);
-use Texinfo::Structuring;
+use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
 use Data::Dumper;
@@ -31,7 +31,7 @@
 
   my $parser = Texinfo::Parser::parser();
   my $line = $parser->parse_texi_line ($in);
-  my $node = Texinfo::Structuring::_new_node($parser, $line);
+  my $node = Texinfo::Transformations::_new_node($parser, $line);
   
   my ($texi_result, $normalized);
   if (defined($node)) {
@@ -72,7 +72,7 @@
 my $tree = $parser->parse_texi_text('@node a node
 ');
 my $line_tree = Texinfo::Parser::parse_texi_line (undef, 'a node');
-my $node = Texinfo::Structuring::_new_node($parser, $line_tree);
+my $node = Texinfo::Transformations::_new_node($parser, $line_tree);
 is ('@node a node 1
 ',  Texinfo::Convert::Texinfo::convert($node), 'duplicate node added');
 #print STDERR Texinfo::Convert::Texinfo::convert($node);
@@ -142,8 +142,7 @@
 
   $parser = Texinfo::Parser::parser();
   $tree = $parser->parse_texi_text ($sections_text);
-  my ($new_content, $added_nodes)
-   = Texinfo::Structuring::insert_nodes_for_sectioning_commands($parser, 
$tree);
+  my ($new_content, $added_nodes) = 
Texinfo::Transformations::insert_nodes_for_sectioning_commands($parser, $tree);
   $tree->{'contents'} = $new_content;
   my $result = Texinfo::Convert::Texinfo::convert($tree);
   is ($reference, $result, 'add nodes');
@@ -162,7 +161,7 @@
 @end menu
 ');
 ($new_content, $added_nodes)
-   = Texinfo::Structuring::insert_nodes_for_sectioning_commands($parser, 
$tree);
+   = Texinfo::Transformations::insert_nodes_for_sectioning_commands($parser, 
$tree);
 $tree->{'contents'} = $new_content;
 my ($index_names, $merged_indices) = $parser->indices_information();
 my $labels = $parser->labels_information();
@@ -192,7 +191,7 @@
 $tree = $parser->parse_texi_text ($text_duplicate_nodes);
 # In fact, here we also check that there is no debugging message...
 ($new_content, $added_nodes)
-   = Texinfo::Structuring::insert_nodes_for_sectioning_commands($parser, 
$tree);
+   = Texinfo::Transformations::insert_nodes_for_sectioning_commands($parser, 
$tree);
 ($index_names, $merged_indices) = $parser->indices_information();
 $labels = $parser->labels_information();
 is ($labels->{'SEE-ALSO'}, 
$index_names->{'cp'}->{'index_entries'}->[0]->{'node'},

Modified: trunk/tp/t/do_master_menu.t
===================================================================
--- trunk/tp/t/do_master_menu.t 2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/t/do_master_menu.t 2016-10-30 15:53:19 UTC (rev 7480)
@@ -15,7 +15,7 @@
 use lib 'maintain/lib/libintl-perl/lib/';
 use lib 'maintain/lib/Text-Unidecode/lib/';
 use Texinfo::Parser qw(parse_texi_text);
-use Texinfo::Structuring;
+use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
 use Data::Dumper;
@@ -130,7 +130,7 @@
 
 my $parser = Texinfo::Parser::parser();
 my $tree = $parser->parse_texi_text($in_detailmenu);
-my $master_menu = Texinfo::Structuring::new_master_menu($parser);
+my $master_menu = Texinfo::Transformations::new_master_menu($parser);
 my $out = Texinfo::Convert::Texinfo::convert($master_menu);
 
 my $reference = '@detailmenu
@@ -169,13 +169,13 @@
 
 $parser = Texinfo::Parser::parser();
 $tree = $parser->parse_texi_text($no_detailmenu);
-$master_menu = Texinfo::Structuring::new_master_menu($parser);
+$master_menu = Texinfo::Transformations::new_master_menu($parser);
 $out = Texinfo::Convert::Texinfo::convert($master_menu);
 is ($out, $reference, 'master menu no detailmenu');
 
 $parser = Texinfo::Parser::parser();
 $tree = $parser->parse_texi_text($in_detailmenu);
-Texinfo::Structuring::regenerate_master_menu($parser);
+Texinfo::Transformations::regenerate_master_menu($parser);
 $out = Texinfo::Convert::Texinfo::convert($tree);
 
 is ($out, _get_in($reference), 'regenerate with existing detailmenu');
@@ -184,7 +184,7 @@
 
 $parser = Texinfo::Parser::parser();
 $tree = $parser->parse_texi_text($no_detailmenu);
-Texinfo::Structuring::regenerate_master_menu($parser);
+Texinfo::Transformations::regenerate_master_menu($parser);
 $out = Texinfo::Convert::Texinfo::convert($tree);
 
 is ($out, _get_in('',"\n".$reference), 'regenerate with no detailmenu');

Modified: trunk/tp/t/reference_to_text_in_tree.t
===================================================================
--- trunk/tp/t/reference_to_text_in_tree.t      2016-10-30 10:53:00 UTC (rev 
7479)
+++ trunk/tp/t/reference_to_text_in_tree.t      2016-10-30 15:53:19 UTC (rev 
7480)
@@ -15,7 +15,7 @@
 use lib 'maintain/lib/libintl-perl/lib/';
 use lib 'maintain/lib/Text-Unidecode/lib/';
 use Texinfo::Parser qw(parse_texi_text);
-use Texinfo::Structuring;
+use Texinfo::Transformations;
 use Texinfo::Convert::Texinfo;
 
 ok(1);
@@ -30,7 +30,7 @@
   my $tree = parse_texi_text($parser, $in);
 
   my $corrected_tree 
-    = Texinfo::Structuring::reference_to_arg_in_tree($parser, $tree);
+    = Texinfo::Transformations::reference_to_arg_in_tree($parser, $tree);
   my $texi_result = Texinfo::Convert::Texinfo::convert($corrected_tree);
 
   if (!defined($out)) {

Modified: trunk/tp/t/test_fill_gaps_in_sectioning.t
===================================================================
--- trunk/tp/t/test_fill_gaps_in_sectioning.t   2016-10-30 10:53:00 UTC (rev 
7479)
+++ trunk/tp/t/test_fill_gaps_in_sectioning.t   2016-10-30 15:53:19 UTC (rev 
7480)
@@ -14,7 +14,7 @@
 use lib 'maintain/lib/Unicode-EastAsianWidth/lib/';
 use lib 'maintain/lib/libintl-perl/lib/';
 use lib 'maintain/lib/Text-Unidecode/lib/';
-use Texinfo::Structuring;
+use Texinfo::Transformations;
 use Texinfo::Parser qw(parse_texi_text);
 use Texinfo::Convert::Texinfo;
 
@@ -26,7 +26,7 @@
 
 my $section = $tree->{'contents'}->[1];
 my @correct_level_offset_commands 
-   = Texinfo::Structuring::_correct_level($section, $tree->{'contents'}->[0]);
+ = Texinfo::Transformations::_correct_level($section, 
$tree->{'contents'}->[0]);
 
 # 2 because there is also an empty line
 ok (scalar(@correct_level_offset_commands) == 2,"one lowersection");
@@ -39,7 +39,7 @@
 ');
 $section = $tree->{'contents'}->[1];
 @correct_level_offset_commands 
-   = Texinfo::Structuring::_correct_level($section, $tree->{'contents'}->[0], 
-1);
+   = Texinfo::Transformations::_correct_level($section, 
$tree->{'contents'}->[0], -1);
 ok (scalar(@correct_level_offset_commands) == 4,"two lowersection");
 ok ($correct_level_offset_commands[0]->{'cmdname'} eq 'lowersection' ,
     "command is lowersection");
@@ -51,7 +51,7 @@
   my $name = shift;
   my $tree = parse_texi_text(undef, $in);
   my ($corrected_content, $added_sections) 
-      = Texinfo::Structuring::fill_gaps_in_sectioning($tree);
+      = Texinfo::Transformations::fill_gaps_in_sectioning($tree);
   $tree->{'contents'} = $corrected_content;
   {
   local $Data::Dumper::Purity = 1;

Modified: trunk/tp/t/test_utils.pl
===================================================================
--- trunk/tp/t/test_utils.pl    2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/t/test_utils.pl    2016-10-30 15:53:19 UTC (rev 7480)
@@ -784,7 +784,8 @@
                                                      $index_names);
   }
   if ($parser_options->{'SIMPLE_MENU'}) {
-    $parser->Texinfo::Structuring::set_menus_to_simple_menu();
+    require Texinfo::Transformations;
+    $parser->Texinfo::Transformations::set_menus_to_simple_menu();
   }
 
   my $converted_text = Texinfo::Convert::Text::convert($result, {'TEST' => 1});

Modified: trunk/tp/texi2any.pl
===================================================================
--- trunk/tp/texi2any.pl        2016-10-30 10:53:00 UTC (rev 7479)
+++ trunk/tp/texi2any.pl        2016-10-30 15:53:19 UTC (rev 7480)
@@ -1070,6 +1070,7 @@
 
 require Texinfo::Parser;
 require Texinfo::Structuring;
+require Texinfo::Transformations;
 # Avoid loading these modules until down here to speed up the case
 # when they are not needed.
 
@@ -1234,7 +1235,7 @@
 
   if ($tree_transformations{'fill_gaps_in_sectioning'}) {
     my ($filled_contents, $added_sections) 
-      = Texinfo::Structuring::fill_gaps_in_sectioning($tree);
+      = Texinfo::Transformations::fill_gaps_in_sectioning($tree);
     if (!defined($filled_contents)) {
       document_warn(__("fill_gaps_in_sectioning transformation return no 
result. No section?"));
     } else {
@@ -1244,7 +1245,7 @@
   if ((get_conf('SIMPLE_MENU')
        and $formats_table{$format}->{'simple_menu'})
       or $tree_transformations{'simple_menus'}) {
-    $parser->Texinfo::Structuring::set_menus_to_simple_menu();
+    $parser->Texinfo::Transformations::set_menus_to_simple_menu();
   }
 
   if (defined(get_conf('MACRO_EXPAND')) and $file_number == 0) {
@@ -1287,7 +1288,7 @@
 
   if ($tree_transformations{'insert_nodes_for_sectioning_commands'}) {
     my ($modified_contents, $added_nodes)
-     = Texinfo::Structuring::insert_nodes_for_sectioning_commands($parser, 
$tree);
+     = Texinfo::Transformations::insert_nodes_for_sectioning_commands($parser, 
$tree);
     if (!defined($modified_contents)) {
       document_warn(__(
        "insert_nodes_for_sectioning_commands transformation return no result. 
No section?"));
@@ -1308,11 +1309,11 @@
   }
 
   if ($tree_transformations{'complete_tree_nodes_menus'}) {
-    Texinfo::Structuring::complete_tree_nodes_menus($parser, $tree);
+    Texinfo::Transformations::complete_tree_nodes_menus($parser, $tree);
   }
 
   if ($tree_transformations{'regenerate_master_menu'}) {
-    Texinfo::Structuring::regenerate_master_menu($parser);
+    Texinfo::Transformations::regenerate_master_menu($parser);
   }
 
   # this can be done for every format, since information is already gathered




reply via email to

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