texinfo-commits
[Top][All Lists]
Advanced

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

texinfo/tp Texinfo/Convert/Info.pm Texinfo/Conv...


From: Patrice Dumas
Subject: texinfo/tp Texinfo/Convert/Info.pm Texinfo/Conv...
Date: Thu, 20 Jan 2011 00:38:32 +0000

CVSROOT:        /sources/texinfo
Module name:    texinfo
Changes by:     Patrice Dumas <pertusus>        11/01/20 00:38:32

Modified files:
        tp/Texinfo/Convert: Info.pm Plaintext.pm 
        tp/t           : test_count.t 
        tp/t/results/def: all_commands_delimiters_printindex.pl 
                          all_commands_printindex.pl 

Log message:
        Count lines and bytes while walking on the tree.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Info.pm?cvsroot=texinfo&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/Texinfo/Convert/Plaintext.pm?cvsroot=texinfo&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/test_count.t?cvsroot=texinfo&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/def/all_commands_delimiters_printindex.pl?cvsroot=texinfo&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/texinfo/tp/t/results/def/all_commands_printindex.pl?cvsroot=texinfo&r1=1.2&r2=1.3

Patches:
Index: Texinfo/Convert/Info.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Info.pm,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- Texinfo/Convert/Info.pm     17 Jan 2011 00:57:23 -0000      1.13
+++ Texinfo/Convert/Info.pm     20 Jan 2011 00:38:31 -0000      1.14
@@ -56,7 +56,10 @@
 
   my $result = '';
 
+  push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0,
+                                     'locations' => []};
   my $header = $self->_info_header();
+  pop @{$self->{'count_context'}};
   my $header_bytes = $self->count_bytes($header);
   my $elements = Texinfo::Structuring::split_by_node($root);
 
@@ -78,15 +81,15 @@
     my $out_file_nr = 1;
     my @indirect_files;
     print $fh $header;
-    $self->{'file_bytes_count'} += $header_bytes;
-    my $first_node_bytes_count = $self->{'file_bytes_count'};
+    $self->{'count_context'}->[-1]->{'bytes'} += $header_bytes;
+    my $first_node_bytes_count = $header_bytes;
     my @nodes = @$elements;
     while (@nodes) {
       my $node = shift @nodes;
       my ($node_text) = $self->_convert_node($node);
       print $fh $node_text;
       if (defined($self->{'SPLIT_SIZE'}) 
-          and $self->{'file_bytes_count'} > 
+          and $self->{'count_context'}->[-1]->{'bytes'} > 
                   $out_file_nr * $self->{'SPLIT_SIZE'} and @nodes) {
         close ($fh);
         if ($out_file_nr == 1) {
@@ -112,9 +115,9 @@
            return undef;
         }
         print $fh $header;
-        $self->{'file_bytes_count'} += $header_bytes;
+        $self->{'count_context'}->[-1]->{'bytes'} += $header_bytes;
         push @indirect_files, [$self->{'output_filename'}.'-'.$out_file_nr,
-                               $self->{'file_bytes_count'}];
+                               $self->{'count_context'}->[-1]->{'bytes'}];
         #print STDERR join(' --> ', @{$indirect_files[-1]}) ."\n";
       }
       #$result .= $node_text;
@@ -139,7 +142,7 @@
     if ($out_file_nr > 1) {
       print $fh "(Indirect)\n";
     }
-    foreach my $label (@{$self->{'label_locations'}}) {
+    foreach my $label (@{$self->{'count_context'}->[-1]->{'locations'}}) {
       next unless ($label->{'root'});
       my $prefix = 'Ref';
       $prefix = 'Node' if ($label->{'root'}->{'cmdname'} eq 'node');
@@ -188,6 +191,7 @@
   my $output_basename = $output_file;
   $output_basename =~ s/^.*\///;
   $self->{'output_filename'} = $output_basename;
+
   # FIXME version/program
   my $text = "This is $output_basename, produced by makeinfo version 4.13 from 
$input_basename.";
   my $paragraph = Texinfo::Convert::Paragraph->new();
@@ -197,7 +201,7 @@
   $self->{'empty_lines_count'} = 1;
 
   if ($self->{'extra'} and $self->{'extra'}->{'copying'}) {
-    my ($copying) = $self->_convert({'contents' => 
+    my $copying = $self->_convert({'contents' => 
           $self->{'extra'}->{'copying'}->{'contents'}});
     $result .= $copying;
   }
@@ -211,7 +215,7 @@
         }
       } elsif ($command->{'cmdname'} eq 'direntry') {
         $result .= "START-INFO-DIR-ENTRY\n";
-        my ($direntry) = $self->_convert($command);
+        my $direntry = $self->_convert($command);
         $result .= $direntry;
         $result .= "END-INFO-DIR-ENTRY\n";
       }
@@ -233,47 +237,6 @@
   }
 }
 
-sub update_counts ($$$$$$)
-{
-  my $self = shift;
-  my $main_bytes_count = shift;
-  my $main_lines_count = shift;
-  my $main_locations = shift;
-  my $counts = shift;
-  my $locations = shift;
-  if ($locations) {
-    foreach my $location(@$locations) {
-      if (defined($location->{'lines'})) {
-        $location->{'lines'} += $$main_lines_count;
-      }
-      if (defined($location->{'bytes'})) {
-        $location->{'bytes'} += $$main_bytes_count;
-      }
-    }
-    push @{$main_locations}, @{$locations};
-  }
-  if ($counts) {
-    $$main_bytes_count += $counts->{'bytes'};
-    $$main_lines_count += $counts->{'lines'} if ($counts->{'lines'});
-  }
-}
-
-#sub _flush_paragraph($$)
-#{
-#  my $self = shift;
-#  my $text = shift;
-#
-#  my $index = -1;
-#  $index--
-#    while 
(!$flush_commands{$self->{'format_context'}->[$index]->{'cmdname'}});
-#  # nothing to do in case of flushleft
-#  if ($self->{'format_context'}->[$index]->{'cmdname'} eq 'flushleft') {
-#    return $text;
-#  }
-#  return _align_lines($text, $self->{'format_context'}->[$index]->{'max'},
-#                          'right');
-#}
-
 sub _contents($$$)
 {
   my $self = shift;
@@ -314,16 +277,16 @@
 
   my $result = "\x{00}\x{08}[index\x{00}\x{08}]\n* Menu:\n\n";
 
-  my $lines_count = 3;
-  my $bytes_count = $self->count_bytes($result);
+  $self->_add_text_count($result);
+  $self->_add_lines_count(3);
 
   # first determine the line numbers for the spacing of their formatting
   my %line_nrs;
   my $max_index_line_nr_string_length = 0;
   foreach my $entry (@{$self->{'index_entries'}->{$index_name}}) {
     my $line_nr;
-    if (defined ($self->{'index_entries_line_location'}->{$entry})) {
-      $line_nr = $self->{'index_entries_line_location'}->{$entry}->{'lines'};
+    if (defined 
($self->{'index_entries_line_location'}->{$entry->{'command'}})) {
+      $line_nr = 
$self->{'index_entries_line_location'}->{$entry->{'command'}}->{'lines'};
     }
     if (!defined($entry->{'node'})) {
       $line_nr = 0;
@@ -350,8 +313,7 @@
     my $entry_tree = {'contents' => $entry->{'content'}};
     $entry_tree->{'type'} = 'code' if ($in_code);
     my $entry_text = '';
-    $self->advance_count_text(\$entry_text, \$bytes_count, undef,
-           undef, 0, $self->convert_line($entry_tree, {'indent' => 0}));
+    $entry_text .= $self->convert_line($entry_tree, {'indent' => 0});
 
     my $entry_nr = '';
     if (!defined($entry_counts{$entry_text})) {
@@ -361,13 +323,13 @@
       $entry_nr = ' <'.$entry_counts{$entry_text}.'>';
     }
     my $entry_line = "* $entry_text${entry_nr}: ";
-    $bytes_count += $self->count_bytes("* ${entry_nr}: ");
+    $self->_add_text_count($entry_line);
     
     my $line_width = Texinfo::Convert::Unicode::string_width($entry_line);
     if ($line_width < $index_length_to_node) {
       my $spaces = ' ' x ($index_length_to_node - $line_width);
       $entry_line .= $spaces;
-      $bytes_count += $self->count_bytes($spaces);
+      $self->_add_text_count($spaces);
     }
     my $node_text;
     if (!defined($entry->{'node'})) {
@@ -376,10 +338,9 @@
       $node_text = {'type' => 'code',
                 'contents' => $entry->{'node'}->{'extra'}->{'node_content'}};
     }
-    $self->advance_count_text(\$entry_line, \$bytes_count, undef,
-           undef, 0, $self->convert_line($node_text));
+    $entry_line .= $self->convert_line($node_text);
     $entry_line .= '.';
-    $bytes_count += $self->count_bytes('.');
+    $self->_add_text_count('.');
 
     $result .= $entry_line;
 
@@ -391,22 +352,22 @@
     if ($line_width + $line_part_width +1 > $self->{'fillcolumn'}) {
       $line_part = "\n" . ' ' x ($self->{'fillcolumn'} - $line_part_width) 
            . "$line_part\n";
-      $lines_count++;
+      $self->_add_lines_count(1);
     } else { 
       $line_part 
         = ' ' x ($self->{'fillcolumn'} - $line_part_width - $line_width)
            . "$line_part\n";
     }
-    $lines_count++;
+    $self->_add_lines_count(1);
+    $self->_add_text_count($line_part);
     $result .= $line_part;
-    $bytes_count += $self->count_bytes($line_part);
   }
 
   $result .= "\n"; 
-  $lines_count++;
-  $bytes_count += $self->count_bytes("\n");
+  $self->_add_text_count("\n");
+  $self->_add_lines_count(1);
   
-  return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count});
+  return $result;
 }
 
 
@@ -416,42 +377,38 @@
   my $self = shift;
   my $node = shift;
 
-  my $bytes_count = 0;
-
   # May happen when only converting a fragment
   my $output_filename = $self->{'output_filename'};
   $output_filename = '' if (!defined($self->{'output_filename'}));
 
   my $result = "\x{1F}\nFile: $output_filename,  Node: ";
-  $bytes_count += $self->count_bytes($result);
-  $self->advance_count_text(\$result, \$bytes_count, undef,
-               undef, 0, $self->convert_line({'type' => 'code', 
-                           'contents' => $node->{'extra'}->{'node_content'}}));
+  $self->_add_text_count($result);
+  $result .= $self->convert_line({'type' => 'code',
+                           'contents' => $node->{'extra'}->{'node_content'}});
   foreach my $direction(@directions) {
     if ($node->{'node_'.lc($direction)}) {
       my $node_direction = $node->{'node_'.lc($direction)};
       my $text = ",  $direction: ";
-      $bytes_count += $self->count_bytes($text);
+      $self->_add_text_count($text);
       $result .= $text;
       if ($node_direction->{'extra'}->{'manual_content'}) {
-        $self->advance_count_text(\$result, \$bytes_count, undef,
-                undef, 0, $self->convert_line({'type' => 'code',
+        $result .= $self->convert_line({'type' => 'code',
                           'contents' => [{'text' => '('},
                              @{$node_direction->{'extra'}->{'manual_content'}},
-                                          {'text' => ')'}]}));
+                                          {'text' => ')'}]});
       }
       if ($node_direction->{'extra'}->{'node_content'}) {
-        $self->advance_count_text(\$result, \$bytes_count, undef,
-               undef, 0, $self->convert_line({'type' => 'code', 
-                 'contents' => $node_direction->{'extra'}->{'node_content'}}));
+        $result .= $self->convert_line({'type' => 'code',
+                 'contents' => $node_direction->{'extra'}->{'node_content'}});
       }
     }
   }
   $result .="\n\n";
-  $bytes_count += $self->count_bytes("\n\n");
+  $self->_add_text_count("\n\n");
+  $self->_add_location($node);
+  $self->{'count_context'}->[-1]->{'lines'} = 3;
 
-  return ($result, {'bytes' => $bytes_count, 'lines' => 3}, 
-          [{'bytes' => 0, 'root' => $node}]);
+  return $result;
 }
 
 my @image_files_extensions = ('png', 'jpg');

Index: Texinfo/Convert/Plaintext.pm
===================================================================
RCS file: /sources/texinfo/texinfo/tp/Texinfo/Convert/Plaintext.pm,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- Texinfo/Convert/Plaintext.pm        17 Jan 2011 00:57:23 -0000      1.52
+++ Texinfo/Convert/Plaintext.pm        20 Jan 2011 00:38:32 -0000      1.53
@@ -241,7 +241,7 @@
   'OUTFILE'              => undef,
   'documentlanguage'     => undef,
   'NUMBER_FOOTNOTES'     => 1,
-  'file_bytes_count'     => 0,
+  'empty_lines_count'    => 0,
   'SPLIT_SIZE'           => 300000,
   'expanded_formats'     => undef,
   'include_directories'  => undef,
@@ -382,6 +382,8 @@
   $converter->{'context'} = [];
   $converter->{'format_context'} = [];
   $converter->push_top_formatter('_Root_context');
+  push @{$converter->{'count_context'}}, {'lines' => 0, 'bytes' => 0,
+                                     'locations' => []};
 
   %{$converter->{'ignored_types'}} = %ignored_types;
   %{$converter->{'ignored_commands'}} = %ignored_commands;
@@ -412,28 +414,20 @@
   my $lines_count = 0;
   my $locations = [];
 
-  $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-         $locations, 0, $self->_convert($node));
+  print STDERR "NEW NODE\n" if ($self->{'DEBUG'});
+  die "Too much count_context\n" if (scalar(@{$self->{'count_context'}}) != 1);
 
-  $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-         $locations, 0, $self->_footnotes($node));
+  $self->{'count_context'}->[-1]->{'lines'} = 0;
+  $result .= $self->_convert($node);
 
-  foreach my $location (@{$locations}) {
-    if (defined($location->{'bytes'})) {
-      $location->{'bytes'} += $self->{'file_bytes_count'};
-      push @{$self->{'label_locations'}}, $location;
-      print STDERR "LOCATION $location anchor bytes $location->{'bytes'}\n"
-        if ($self->{'DEBUG'});
-    }
-    if (defined($location->{'lines'} and $location->{'index_entry'})) {
-      print STDERR "LOCATION $location idx $location->{'index_entry'} lines 
$location->{'lines'}\n"
-        if ($self->{'DEBUG'});
-      $self->{'index_entries_line_location'}->{$location->{'index_entry'}} = 
$location;
-    }
-  }
-  $self->{'file_bytes_count'} += $bytes_count;
-  # FIXME return $locations?
-  return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count});
+  print STDERR "END NODE 
($self->{'count_context'}->[-1]->{'lines'},$self->{'count_context'}->[-1]->{'bytes'})\n"
 if ($self->{'DEBUG'});
+
+  $result .= $self->_footnotes($node);
+
+  print STDERR "AFTER FOOTNOTES 
($self->{'count_context'}->[-1]->{'lines'},$self->{'count_context'}->[-1]->{'bytes'})\n"
 if ($self->{'DEBUG'});
+
+  return $result;
+  #return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count});
 }
 
 sub convert($$)
@@ -445,12 +439,12 @@
 
   my $elements = Texinfo::Structuring::split_by_node($root);
   if (!defined($elements)) {
-    ($result) = $self->_convert($root);
-    my ($footnotes) = $self->_footnotes();
+    $result = $self->_convert($root);
+    my $footnotes = $self->_footnotes();
     $result .= $footnotes;
   } else {
     foreach my $node (@$elements) {
-      my ($node_text) = $self->_convert_node($node);
+      my $node_text = $self->_convert_node($node);
       $result .= $node_text;
     }
   }
@@ -576,11 +570,10 @@
   my $conf = shift;
   my $container = $self->new_formatter('line', $conf);
   push @{$self->{'formatters'}}, $container;
-  my ($text, $counts, $new_locations) = $self->_convert($converted);
-  my $end = $container->{'container'}->end();
-  $counts->{'bytes'} += $self->count_bytes($end);
+  my $text = $self->_convert($converted);
+  $text .= $self->_count_added_end($container->{'container'});
   pop @{$self->{'formatters'}};
-  return ($text.$end, $counts, $new_locations);
+  return $text;
 }
 
 sub convert_unfilled($$;$)
@@ -591,8 +584,8 @@
   my $container = $self->new_formatter('unfilled', $conf);
   $container->{'code'} = 1;
   push @{$self->{'formatters'}}, $container;
-  my ($result) = $self->_convert($converted);
-  $result .= $container->{'container'}->end();
+  my $result = $self->_convert($converted);
+  $result .= $self->_count_added_end($container->{'container'});
   pop @{$self->{'formatters'}};
   return $result;
 }
@@ -636,52 +629,95 @@
   }
 }
 
-sub update_counts ($$$$$$)
+sub _add_text_count($$)
 {
   my $self = shift;
-  my $main_bytes_count = shift;
-  my $main_lines_count = shift;
-  my $main_locations = shift;
-  my $counts = shift;
-  my $locations = shift;
-  if ($locations) {
-    foreach my $location(@$locations) {
-      if (defined($location->{'lines'})) {
-        $location->{'lines'} += $$main_lines_count;
-      }
-      if (defined($location->{'bytes'})) {
-        $location->{'bytes'} += $$main_bytes_count;
-      }
-    }
-    push @{$main_locations}, @{$locations};
-  }
-  if ($counts) {
-    $$main_bytes_count += $counts->{'bytes'};
-    $$main_lines_count += $counts->{'lines'} if ($counts->{'lines'});
+  my $text = shift;
+  $self->{'count_context'}->[-1]->{'bytes'} += $self->count_bytes($text);
+}
+
+sub _add_lines_count($$)
+{
+  my $self = shift;
+  my $lines_count = shift;
+  $self->{'count_context'}->[-1]->{'lines'} += $lines_count;
+}
+
+sub _add_location($$)
+{
+  my $self = shift;
+  my $root = shift;
+  my $location = { 'lines' => $self->{'count_context'}->[-1]->{'lines'} };
+  push @{$self->{'count_context'}->[-1]->{'locations'}}, $location;
+  if (!($root->{'extra'} and $root->{'extra'}->{'index_entry'})) {
+    $location->{'bytes'}
+      = $self->{'count_context'}->[-1]->{'bytes'};
+    $location->{'root'} = $root;
+  } else {
+    $location->{'index_entry'} = $root;
   }
+  return $location;
+}
+
+sub _count_added_text($$$)
+{
+  my $self = shift;
+  my $container = shift;
+  my $text = shift;
+
+  my $line_counter_before = $container->{'lines_counter'};
+  my $result = $container->add_text($text);
+  $self->_add_lines_count($container->{'lines_counter'} - 
$line_counter_before);
+  $self->_add_text_count($result);
+  return $result;
+}
+
+sub _count_added_next($$$;$$)
+{
+  my $self = shift;
+  my $container = shift;
+  my $text = shift;
+  my $word = shift;
+  my $space = shift;
+
+  my $line_counter_before = $container->{'lines_counter'};
+  my $result = $container->add_next($text, $word, $space);
+  $self->_add_lines_count($container->{'lines_counter'} - 
$line_counter_before);
+  $self->_add_text_count($result);
+  return $result;
+}
+
+sub _count_added_end($$$)
+{
+  my $self = shift;
+  my $container = shift;
+
+  my $line_counter_before = $container->{'lines_counter'};
+  my $end = $container->end();
+  $self->_add_lines_count($container->{'lines_counter'} - 
$line_counter_before);
+  $self->_add_text_count($end);
+  return $end;
 }
 
+
 my $footnote_indent = 3;
 sub _footnotes($$)
 {
   my $self = shift;
   my $element = shift;
 
-  my $bytes_count = 0;
-  my $lines_count = 0;
-  my $locations = [];
   my $result = '';
   if (scalar(@{$self->{'pending_footnotes'}})) {
     unless ($self->{'empty_lines_count'}) {
       $result .= "\n";
-      $bytes_count += $self->count_bytes("\n");
-      $lines_count++;
+      $self->_add_text_count("\n");
+      $self->_add_lines_count(1);
     }
     if ($self->{'footnotestyle'} eq 'end' or !defined($element)) {
       my $footnotes_header = "   ---------- Footnotes ----------\n\n";
       $result .= $footnotes_header;
-      $bytes_count += $self->count_bytes($footnotes_header);
-      $lines_count += 2;
+      $self->_add_text_count($footnotes_header);
+      $self->_add_lines_count(2);
     } else {
 
       my $footnotes_node = {
@@ -691,19 +727,17 @@
              address@hidden>{'extra'}->{'node'}->{'extra'}->{'node_content'}},
                                      {'text' => '-Footnotes'}]}
       };
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_node($footnotes_node));
+      $result .= $self->_node($footnotes_node);
+      $self->{'count_context'}->[-1]->{'lines'} = 0;
     }
     while (@{$self->{'pending_footnotes'}}) {
       my $footnote = shift (@{$self->{'pending_footnotes'}});
 
-      push @$locations, {'bytes' => $bytes_count, 
-           'root' => {'cmdname' => 'anchor',
+      $self->_add_location({'cmdname' => 'anchor',
                       'extra' => {'node_content' => 
                
address@hidden>{'extra'}->{'node'}->{'extra'}->{'node_content'}},
                               {'text' => "-Footnote-$footnote->{'number'}"}]}
-                     }
-        } if ($element);
+                     }) if ($element);
       # this pushes on 'context', 'format_context' and 'formatters'
       $self->push_top_formatter('footnote');
       my $footnote_text = ' ' x $footnote_indent 
@@ -711,15 +745,13 @@
       $result .= $footnote_text;
       $self->{'format_context'}->[-1]->{'counter'} += 
          Texinfo::Convert::Unicode::string_width($footnote_text);
-      $bytes_count += $self->count_bytes($footnote_text);
+      $self->_add_text_count($footnote_text);
 
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, 
-               $self->_convert($footnote->{'root'}->{'args'}->[0]));      
+      $result .= $self->_convert($footnote->{'root'}->{'args'}->[0]); 
       unless ($self->{'empty_lines_count'}) {
         $result .= "\n";
-        $bytes_count += $self->count_bytes("\n");
-        $lines_count++;
+        $self->_add_text_count("\n");
+        $self->_add_lines_count(1);
         $self->{'empty_lines_count'} = 1;
       }
       
@@ -730,8 +762,29 @@
   }
   $self->{'footnote_index'} = 0;
 
-  return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count}, 
-          $locations);
+  return $result;
+}
+
+sub in_flushright($)
+{
+  my $self = shift;
+  my $index = -1;
+  $index--
+    while (!$flush_commands{$self->{'format_context'}->[$index]->{'cmdname'}});
+  if ($self->{'format_context'}->[$index]->{'cmdname'} eq 'flushright') {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+sub flushright_index ($)
+{
+  my $self = shift;
+  my $index = -1;
+  $index--
+    while (!$flush_commands{$self->{'format_context'}->[$index]->{'cmdname'}});
+  return $index;
 }
 
 sub _align_lines($$$$$)
@@ -814,8 +867,10 @@
   # FIXME return bytes count? lines count?
   my $result = '';
   while ($section and $section ne $section_root) {
+    push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0};
     my ($section_title) = $self->convert_line({'contents'
                 => $section->{'extra'}->{'misc_content'}});
+    pop @{$self->{'count_context'}};
     my $text = Texinfo::Convert::Text::numbered_heading($section, 
                             $section_title, $self->{'NUMBER_SECTIONS'})."\n";
     $result .= (' ' x (2*($section->{'level'} - ($root_level+1)))) . $text;
@@ -844,8 +899,9 @@
 
   if ($menu_command->{'cmdname'} eq 'menu') {
     my $result = "* Menu:\n\n";
-    return ($result, {'bytes' => $self->count_bytes($result),
-                      'lines' => 2});
+    $self->_add_text_count($result);
+    $self->_add_lines_count(2);
+    return $result;
   } else {
     return '';
   }
@@ -855,13 +911,14 @@
 {
   my $self = shift;
   my $printindex = shift;
-  return '';
+  return ('');
 }
 
 sub _node($$)
 {
   my $self = shift;
   my $node = shift;
+
   return '';
 }
 
@@ -871,42 +928,27 @@
   my $anchor = shift;
 
   # 'lines_count' is in fact only needed when in @flush and @multitable
-  my $locations = 
-   [ {'lines' => $self->{'formatters'}->[-1]->{'container'}->{'lines_counter'},
-      'bytes' => 0, 'root' => $anchor} ];
-  return ('', undef, $locations);
+  $self->_add_location($anchor);
+  return '';
 }
 
 my $listoffloat_entry_length = 41;
 my $listoffloat_append = '...';
 
-sub advance_count_text ($$$$$$@)
+sub ensure_end_of_line($$)
 {
   my $self = shift;
-  my $result = shift;
-  my $bytes_count = shift;
-  my $lines_count = shift;
-  my $locations = shift;
-  my $ensure_end_line = shift;
-  
   my $text = shift;
-  my $counts = shift;
-  my $new_locations = shift;
-
-  $self->update_counts($bytes_count, $lines_count, $locations,
-                                $counts, $new_locations);
-  $$result .= $text;
-  if ($ensure_end_line) {
-    my $chomped = chomp ($$result);
+  my $chomped = chomp ($text);
     if ($chomped) {
-      $$bytes_count -= $self->count_bytes($chomped);
-      $$lines_count--;
-    }
-    $self->{'empty_lines_count'} = 0 unless ($$result eq '');
-    $$result .= "\n";
-    $$lines_count++;
-    $$bytes_count += $self->count_bytes("\n");
+    $self->{'count_context'}->[-1]->{'bytes'} -= $self->count_bytes($chomped);
+    $self->{'count_context'}->[-1]->{'lines'} -= 1;
   }
+  $self->{'empty_lines_count'} = 0 unless ($text eq '');
+  $text .= "\n";
+  $self->_add_text_count("\n");
+  $self->_add_lines_count(1);
+  return $text;
 }
 
 sub _image_text($$$)
@@ -991,9 +1033,11 @@
   my $formatter = $self->{'formatters'}->[-1];
   #}
   if ($self->{'DEBUG'}) {
+    my $is_top_formatter = 0;
+    $is_top_formatter = 1 if ($formatter->{'_top_formatter'});
     my $empty_lines_count = '';
     $empty_lines_count = $self->{'empty_lines_count'} if 
defined($self->{'empty_lines_count'});
-    print STDERR "ROOT 
(@{$self->{'context'}}|@{$self->{'format_context'}},$empty_lines_count)";
+    print STDERR "ROOT 
(@{$self->{'context'}}|@{$self->{'format_context'}},$empty_lines_count|$is_top_formatter)";
     print STDERR " format_context: 
$self->{'format_context'}->[-1]->{'cmdname'}, 
$self->{'format_context'}->[-1]->{'paragraph_count'}, 
$self->{'format_context'}->[-1]->{'indent_level'}, "
       .(defined($self->{'format_context'}->[-1]->{'counter'}) ? "counter: 
$self->{'format_context'}->[-1]->{'counter'}, " : '') 
        ."max: $self->{'format_context'}->[-1]->{'max'}\n";
@@ -1019,19 +1063,17 @@
     return '';
   }
   my $result = '';
-  my $bytes_count = 0;
-  my $lines_count = 0;
-  my $locations = [];
 
 
   if (defined($root->{'text'})) {
     if (!$formatter->{'_top_formatter'}) {
-      $result = $formatter->{'container'}->add_text(
+      $result = $self->_count_added_text($formatter->{'container'}, 
                       $self->_process_text($root, $formatter));
-      return ($result, {'bytes' => $self->count_bytes($result)});
+      return $result;
     # the following is only possible if paragraphindent is set to asis
     } elsif ($root->{'type'} and $root->{'type'} eq 
'empty_spaces_before_paragraph') {
-      return ($root->{'text'}, {'bytes' => 
$self->count_bytes($root->{'text'})});
+      $self->_add_text_count($root->{'text'});
+      return $root->{'text'};
     # ignore text outside of any format, but warn if ignored text not empty
     } elsif ($root->{'text'} =~ /\S/) {
       warn "BUG: ignored text not empty `$root->{'text'}'\n";
@@ -1054,33 +1096,40 @@
         $formatter->{'container'}->inhibit_end_sentence();
         return '';
       } elsif ($command eq '*') {
+        my $line_counter_before = $formatter->{'container'}->{'lines_counter'};
         $result = $formatter->{'container'}->add_pending_word();
         $result .= $formatter->{'container'}->end_line();
+        $self->_add_lines_count($formatter->{'container'}->{'lines_counter'} - 
$line_counter_before);
+        $self->_add_text_count($result);
       } elsif ($command eq '.' or $command eq '?' or $command eq '!') {
-        $result .= $formatter->{'container'}->add_next($command, undef, 1),
+        $result .= $self->_count_added_next($formatter->{'container'}, 
+                                            $command, undef, 1);
       } elsif ($command eq ' ' or $command eq "\n" or $command eq "\t") {
-        $result .= 
$formatter->{'container'}->add_next($text_no_brace_commands{$root->{'cmdname'}});
+        $result .= $self->_count_added_next($formatter->{'container'}, 
+                                            $text_no_brace_commands{$command});
       } else {
-        $result .= 
$formatter->{'container'}->add_text($text_no_brace_commands{$root->{'cmdname'}});
+        $result .= $self->_count_added_text($formatter->{'container'}, 
+                                            $text_no_brace_commands{$command});
       }
-      return ($result, {'bytes' => $self->count_bytes($result)});
+      return $result;
     } elsif (defined($text_brace_no_arg_commands{$root->{'cmdname'}})) {
       my $text = Texinfo::Convert::Text::brace_no_arg_command($root, 
                                                     $self->{'encoding'});
       if ($command eq 'enddots') {
-        $result .= $formatter->{'container'}->add_next($text, undef, 1),
+        $result .= $self->_count_added_next($formatter->{'container'},
+                                             $text, undef, 1);
       } else {
-        $result .= $formatter->{'container'}->add_text($text);
+        $result .= $self->_count_added_text($formatter->{'container'}, $text); 
         if ($command eq 'dots') {
           $formatter->{'container'}->inhibit_end_sentence();
         }
       }
-      return ($result, {'bytes' => $self->count_bytes($result)});
+      return $result;
     # commands with braces
     } elsif ($accent_commands{$root->{'cmdname'}}) {
-      $result .= $formatter->{'container'}->add_text(
+      $result .= $self->_count_added_text($formatter->{'container'},
           Texinfo::Convert::Text::text_accents($root, $self->{'encoding'}));
-      return ($result, {'bytes' => $self->count_bytes($result)});
+      return $result;
     } elsif ($style_map{$command}) {
       if ($code_style_commands{$command}) {
         $formatter->{'code'}++;
@@ -1094,16 +1143,14 @@
         $formatter->{'container'}->set_space_protection(1,1)
           if ($formatter->{'w'} == 1);
       }
-      $result = $formatter->{'container'}->add_text($style_map{$command}->[0]);
-      $bytes_count += $self->count_bytes($result);
+      $result = $self->_count_added_text($formatter->{'container'},
+                         $style_map{$command}->[0]);
       if ($root->{'args'}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count, 
-               $locations, 0, $self->_convert($root->{'args'}->[0]));
+        $result .= $self->_convert($root->{'args'}->[0]);
 
       }
-      my $end = $formatter->{'container'}->add_text($style_map{$command}->[1]);
-      $result .= $end;
-      $bytes_count += $self->count_bytes($end);
+      $result .= $self->_count_added_text($formatter->{'container'},
+                       $style_map{$command}->[1]);
       if ($command eq 'w') {
         $formatter->{'w'}--;
         $formatter->{'container'}->set_space_protection(0,0)
@@ -1118,12 +1165,12 @@
           undef, undef, $frenchspacing);
       }
       $formatter->{'upper_case'}-- if ($upper_case_commands{$command});
-      return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count},
-          $locations);
+      return $result;
     } elsif ($root->{'cmdname'} eq 'image') {
       # FIXME count lines
       $result = $self->_image($root);
-      return ($result, {'bytes' => $self->count_bytes($result)});
+      $self->_add_text_count($result);
+      return $result;
     } elsif ($root->{'cmdname'} eq 'email') {
       # nothing is output for email, instead the command is substituted.
       my @email_contents;
@@ -1194,14 +1241,15 @@
       push @{$self->{'pending_footnotes'}}, {'root' => $root, 
                                              'number' => $footnote_number}
           unless ($multiple_pass);
-      return $formatter->{'container'}->add_text("($footnote_number)");
+      return $self->_count_added_text($formatter->{'container'},
+                                            "($footnote_number)");
     } elsif ($command eq 'anchor') {
+      my $line_counter_before = $formatter->{'container'}->{'lines_counter'};
       $result = $formatter->{'container'}->add_pending_word();
-      $bytes_count += $self->count_bytes($result);
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_anchor($root));
-      return ($result, {'bytes' => $bytes_count, 'lines' => $lines_count},
-          $locations);
+      $self->_add_lines_count($formatter->{'container'}->{'lines_counter'} - 
$line_counter_before);
+      $self->_add_text_count($result);
+      $result .= $self->_anchor($root);
+      return $result;
     } elsif ($ref_commands{$command}) {
       # FIXME if it a reference to a float with a label, $arg[1] should 
       # be set to '$type $number' or '$number' if there is no type.
@@ -1278,19 +1326,20 @@
     } elsif ($command eq 'math') {
       push @{$self->{'context'}}, 'math';
       if ($root->{'args'}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_convert($root->{'args'}->[0]));
+        $result .= $self->_convert($root->{'args'}->[0]);
       }
       pop @{$self->{'context'}};
-      return ($result, {'lines' => $lines_count, 'bytes' => $bytes_count},
-             $locations);
+      return $result;
     } elsif ($command eq 'titlefont') {
+      push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0};
       ($result) = $self->convert_line ($root->{'args'}->[0]);
+      pop @{$self->{'count_context'}};
       $result = Texinfo::Convert::Text::heading({'level' => 0, 
            'cmdname' => 'titlefont'}, $result, $self->{'NUMBER_SECTIONS'});
       $self->{'empty_lines_count'} = 0 unless ($result eq '');
-      return ($result, {'bytes' => $self->count_bytes($result),
-                       'lines' => 2});
+      $self->_add_text_count($result);
+      $self->_add_lines_count(2);
+      return $result;
     } elsif ($command eq 'value') {
       my $expansion = $self->gdt('@{No value for `{value}\'@}', 
                                     {'value' => $root->{'type'}});
@@ -1330,15 +1379,13 @@
           my $prepended = $self->gdt('@b{{quotation_arg}:} ', 
              {'quotation_arg' => 
$root->{'extra'}->{'block_command_line_contents'}->[0]});
           #print STDERR Data::Dumper->Dump([$prepended]);
-          $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-              $locations, 0, $self->convert_line($prepended));
+          $result .= $self->convert_line($prepended);
           $self->{'format_context'}->[-1]->{'counter'} += 
              Texinfo::Convert::Unicode::string_width($result);
           $self->{'empty_lines_count'} = 0 unless ($result eq '');
         }
       } elsif ($menu_commands{$root->{'cmdname'}}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-            $locations, 0, $self->_menu($root));
+        $result .= $self->_menu($root);
       } elsif ($root->{'cmdname'} eq 'multitable') {
         my $columnsize;
         if ($root->{'extra'}->{'columnfractions'}) {
@@ -1347,8 +1394,10 @@
           }
         } elsif ($root->{'extra'}->{'prototypes'}) {
           foreach my $prototype (@{$root->{'extra'}->{'prototypes'}}) {
+            push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0};
             my ($formatted_prototype) = $self->convert_line($prototype, 
                                                         {'indent_length' => 
0});
+            pop @{$self->{'count_context'}};
             print STDERR " MULTITABLE_PROTO {$formatted_prototype}\n" 
               if ($self->{'DEBUG'});
             push @$columnsize, 
@@ -1359,12 +1408,10 @@
         $self->{'format_context'}->[-1]->{'columns_size'} = $columnsize;
       } elsif ($root->{'cmdname'} eq 'float' and $root->{'extra'}
                and $root->{'extra'}->{'normalized'}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_anchor($root));
+        $result .= $self->_anchor($root);
       }
     } elsif ($root->{'cmdname'} eq 'node') {
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_node($root));
+      $result .= $self->_node($root);
       $self->{'format_context'}->[-1]->{'paragraph_count'} = 0;
     } elsif ($sectioning_commands{$root->{'cmdname'}}) {
       if ($self->{'setcontentsaftertitlepage'} 
@@ -1373,7 +1420,8 @@
                               'contents') ."\n";
         $self->{'empty_lines_count'} = 0;
         $self->{'setcontentsaftertitlepage'} = 0;
-        $bytes_count += $self->count_bytes($contents);
+        $self->_add_text_count($contents);
+        
         $result .= $contents;
       } 
       if ($self->{'setshortcontentsaftertitlepage'} 
@@ -1382,18 +1430,20 @@
                               'shortcontents')."\n";
         $self->{'empty_lines_count'} = 0;
         $self->{'setshortcontentsaftertitlepage'} = 0;
-        $bytes_count += $self->count_bytes($contents);
+        $self->_add_text_count($contents);
         $result .= $contents;
       }
       if ($root->{'args'}) {
+        push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0};
         my ($heading) = $self->convert_line($root->{'args'}->[0]);
+        pop @{$self->{'count_context'}};
         my $heading_underlined = 
              Texinfo::Convert::Text::heading ($root, $heading, 
                                               $self->{'NUMBER_SECTIONS'});
         $self->{'empty_lines_count'} = 0 unless ($heading_underlined eq '');
-        $bytes_count += $self->count_bytes($heading_underlined);
+        $self->_add_text_count($heading_underlined);
         # FIXME address@hidden and @c?
-        $lines_count += 2;
+        $self->_add_lines_count(2);
         $result .= $heading_underlined;
       }
       $self->{'format_context'}->[-1]->{'paragraph_count'} = 0;
@@ -1406,10 +1456,11 @@
                             'contents' => $contents}]
         }];
       }
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 1, $self->convert_line({'contents' => $contents},
+      $result = $self->convert_line({'contents' => $contents},
                   {'indent_level' 
-                    => $self->{'format_context'}->[-1]->{'indent_level'} -1}));
+                    => $self->{'format_context'}->[-1]->{'indent_level'} -1});
+      $result = $self->ensure_end_of_line($result);
+      
     } elsif ($root->{'cmdname'} eq 'item' and $root->{'parent'}->{'cmdname'}
              and $item_container_commands{$root->{'parent'}->{'cmdname'}}) {
       $self->{'format_context'}->[-1]->{'paragraph_count'} = 0;
@@ -1420,21 +1471,19 @@
                  + 
$item_indent_format_length{$root->{'parent'}->{'cmdname'}}});
       push @{$self->{'formatters'}}, $line;
       if ($root->{'parent'}->{'cmdname'} eq 'enumerate') {
-        $result = 
$line->{'container'}->add_next(Texinfo::Convert::Text::enumerate_item_representation(
+        $result = $self->_count_added_next($line->{'container'},
+          Texinfo::Convert::Text::enumerate_item_representation(
           $root->{'parent'}->{'extra'}->{'enumerate_specification'},
           $root->{'extra'}->{'item_number'}) . '. ');
       } else {
         # FIXME convert_line and no array of contents?
-        my ($item_line) = $self->_convert(
+        $result = $self->_convert(
           {'contents' => 
              
address@hidden>{'parent'}->{'extra'}->{'block_command_line_contents'}->[0]},
               { 'text' => ' ' }]
           });
-        $result = $item_line;
       }
-      $result .= $line->{'container'}->end();
-      $bytes_count += $self->count_bytes($result);
-      $lines_count += 1;
+      $result .= $self->_count_added_end($line->{'container'});
       print STDERR "  
$root->{'parent'}->{'cmdname'}($root->{'extra'}->{'item_number'}) -> 
|$result|\n" 
          if ($self->{'DEBUG'});
       pop @{$self->{'formatters'}};
@@ -1455,6 +1504,8 @@
              'paragraph_count' => 0,
              'indent_level' => 0,
              'max' => $cell_width - 2 };
+      push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0,
+                                                   'locations' => []};
       if ($self->{'context'}->[-1] eq 'preformatted') {
         $preformatted = $self->new_formatter('unfilled');
         push @{$self->{'formatters'}}, $preformatted;
@@ -1463,28 +1514,32 @@
       $cell = 1;
     } elsif ($root->{'cmdname'} eq 'center') {
       #my ($counts, $new_locations);
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 1,
-               $self->convert_line (
+      push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0, 
+                                                   'locations' => []};
+      $result = $self->convert_line (
                        {'contents' => $root->{'extra'}->{'misc_content'}},
-                       {'indent_length' => 0}));
+                       {'indent_length' => 0});
+      $result = $self->ensure_end_of_line($result);
+      my $counts = pop @{$self->{'count_context'}};
+
+      my $bytes_count;
       ($result, $bytes_count) 
          = $self->_align_lines ($result, 
-             $self->{'format_context'}->[-1]->{'max'}, 'center', $locations);
+             $self->{'format_context'}->[-1]->{'max'}, 'center', 
+             $counts->{'locations'});
+      $self->{'count_context'}->[-1]->{'bytes'} += $bytes_count;
+      $self->{'count_context'}->[-1]->{'lines'} += $counts->{'lines'};
       $self->{'empty_lines_count'} = 0 unless ($result eq '');
       $self->{'format_context'}->[-1]->{'paragraph_count'}++;
-      return ($result, {'bytes' => $bytes_count, 
-                        'lines' => $lines_count}, $locations);
+      push @{$self->{'count_context'}->[-1]->{'locations'}}, 
+                       @{$counts->{'locations'}};
+      return $result;
     } elsif ($root->{'cmdname'} eq 'exdent') {
-      
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 1, $self->convert_line (
-        {'contents' => $root->{'extra'}->{'misc_content'}},
+      $result = $self->convert_line ({'contents' => 
$root->{'extra'}->{'misc_content'}},
         {'indent_level' 
-          => $self->{'format_context'}->[-1]->{'indent_level'} -1}));
-
-      return ($result, {'bytes' => $bytes_count, 
-                        'lines' => $lines_count}, $locations);
+          => $self->{'format_context'}->[-1]->{'indent_level'} -1});
+      $result = $self->ensure_end_of_line ($result);
+      return $result;
     } elsif ($root->{'cmdname'} eq 'verbatiminclude') {
       my $expansion = $self->Texinfo::Parser::expand_verbatiminclude($root);
       unshift @{$self->{'current_contents'}->[-1]}, $expansion
@@ -1497,17 +1552,16 @@
       }
       return '';
     } elsif ($root->{'cmdname'} eq 'printindex') {
-       $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_printindex($root));
-      return ($result, {'bytes' => $bytes_count, 'lines' => $lines_count},
-          $locations);
-
+      $result = $self->_printindex($root);
+      return $result;
     } elsif ($root->{'cmdname'} eq 'listoffloats') {
       if ($root->{'extra'} and $root->{'extra'}->{'type'}
           and defined($root->{'extra'}->{'type'}->{'normalized'}) 
           and $self->{'floats'} 
           and $self->{'floats'}->{$root->{'extra'}->{'type'}->{'normalized'}}
           and 
@{$self->{'floats'}->{$root->{'extra'}->{'type'}->{'normalized'}}}) {
+        push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0};
+        my $lines_count = 0;
         $result .= "\n" if (!$self->{'empty_lines_count'});
         $result .= "* Menu:\n\n";
         foreach my $float 
(@{$self->{'floats'}->{$root->{'extra'}->{'type'}->{'normalized'}}}) {
@@ -1567,27 +1621,30 @@
         }
         $result .= "\n";
         $lines_count++;
+        $self->_add_lines_count($lines_count);
         $self->{'empty_lines_count'} = 1;
+        pop @{$self->{'count_context'}};
       }
       $self->{'format_context'}->[-1]->{'paragraph_count'}++;
-      return ($result, {'bytes' => $self->count_bytes($result), 
-                        'lines' => $lines_count});
+      $self->_add_text_count($result);
+      return $result;
     } elsif ($root->{'cmdname'} eq 'sp') {
       if ($root->{'extra'}->{'misc_args'}->[0]) {
         # this useless copy avoids perl changing the type to integer!
         my $sp_nr = $root->{'extra'}->{'misc_args'}->[0];
         $result = "\n" x $sp_nr;
+        $self->_add_text_count($result);
         $self->{'empty_lines_count'} += $sp_nr;
-        $lines_count += $sp_nr;
+        $self->_add_lines_count($sp_nr);
       }
-      return ($result, {'lines' => $self->count_bytes($result), 
-                        'bytes' => $bytes_count});
+      return $result;
     } elsif ($root->{'cmdname'} eq 'contents') {
       if (!defined($self->{'setcontentsaftertitlepage'})
            and $self->{'structuring'}
            and $self->{'structuring'}->{'sectioning_root'}) {
         $result = 
$self->_contents($self->{'structuring'}->{'sectioning_root'}, 
                               'contents');
+        $self->_add_text_count($result);
       }
       return $result;
     } elsif ($root->{'cmdname'} eq 'shortcontents' 
@@ -1597,6 +1654,7 @@
             and $self->{'structuring'}->{'sectioning_root'}) {
         $result = 
$self->_contents($self->{'structuring'}->{'sectioning_root'}, 
                               'shortcontents');
+        $self->_add_text_count($result);
       }
       return $result;
     # all the @-commands that have an information for the formatting, like
@@ -1615,10 +1673,9 @@
     
   }
   if ($root->{'extra'} and $root->{'extra'}->{'index_entry'}) {
-    push @{$locations}, {'lines' => $lines_count
-            + $self->{'formatters'}->[-1]->{'container'}->{'lines_counter'}, 
-                         'index_entry' => $root};
-    print STDERR "INDEX ENTRY lines_count $locations->[-1]->{'lines'}, 
index_entry $locations->[-1]->{'index_entry'}\n" 
+    my $location = $self->_add_location($root);
+    $self->{'index_entries_line_location'}->{$root} = $location;
+    print STDERR "INDEX ENTRY lines_count $location->{'lines'}, index_entry 
$location->{'index_entry'}\n" 
        if ($self->{'DEBUG'});
   }
 
@@ -1639,6 +1696,10 @@
       $paragraph = $self->new_formatter('paragraph', $conf);
       push @{$self->{'formatters'}}, $paragraph;
       $self->{'format_context'}->[-1]->{'paragraph_count'}++;
+      if ($self->{'context'}->[-1] eq 'flush' and $self->in_flushright()) {
+        push @{$self->{'count_context'}}, {'lines' => 0, 'bytes' => 0,
+                                                   'locations' => []};
+      }
     } elsif ($root->{'type'} eq 'empty_line') {
       print STDERR "EMPTY_LINE ($self->{'empty_lines_count'})\n"
         if ($self->{'DEBUG'});
@@ -1647,8 +1708,9 @@
       if ($self->{'empty_lines_count'} <= 1
           or $self->{'context'}->[-1] eq 'preformatted') {
         $result = "\n";
-        $lines_count = 1;
-        return ("\n", {'bytes' => $self->count_bytes("\n"), 'lines'=> 1});
+        $self->_add_text_count($result);
+        $self->_add_lines_count(1);
+        return $result;
       } else {
         return '';
       }
@@ -1686,24 +1748,19 @@
            'indent_length_next' => 
(1+$self->{'format_context'}->[-1]->{'indent_level'})*$indent_length});
         push @{$self->{'formatters'}}, $def_paragraph;
 
-        $result .= $def_paragraph->{'container'}->add_next(" -- ");
-        my ($def_body) = $self->_convert({'type' => 'code', 'contents' => 
address@hidden);
-        $result .= $def_body;
-        $result .= $def_paragraph->{'container'}->end();
+        $result .= $self->_count_added_next($def_paragraph->{'container'}, " 
-- ");
+        $result .= $self->_convert({'type' => 'code', 'contents' => 
address@hidden);
+        $result .= $self->_count_added_end($def_paragraph->{'container'});
 
         pop @{$self->{'formatters'}};
         $self->{'empty_lines_count'} = 0;
         print STDERR "     --> $result" if ($self->{'DEBUG'});
       }
     } elsif ($root->{'type'} eq 'menu_entry') {
-      # an end of line is ensured for the last argument.
-      my $index = 0;
-      my $args_nr = scalar(@{$root->{'args'}});
       foreach my $arg (@{$root->{'args'}}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, ($index >= $args_nr -1), $self->_convert($arg));
-        $index++;
+        $result .= $self->_convert($arg);
       }
+      $result = $self->ensure_end_of_line($result);
     } elsif ($root->{'type'} eq 'frenchspacing') {
       push @{$formatter->{'frenchspacing_stack'}}, 'on';
       $formatter->{'container'}->set_space_protection(undef,
@@ -1715,7 +1772,7 @@
         undef,undef,1);
     } elsif ($root->{'type'} eq 'bracketed') {
       #and $self->{'context'}->[-1] eq 'math') {
-      $result .= $formatter->{'container'}->add_text('{');
+      $result .= $self->_count_added_text($formatter->{'container'}, '{');
     }
   }
 
@@ -1724,11 +1781,9 @@
     push @{$self->{'current_contents'}}, address@hidden;
     while (@contents) {
       my $content = shift @contents;
-      my ($text, $counts, $new_locations)
-       = $self->_convert($content);
-      $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-             $locations, 0, $text, $counts, $new_locations);
+      my $text = $self->_convert($content);
       $self->{'empty_lines_count'} = 0 if ($preformatted and $text ne '');
+      $result .= $text;
     }
     pop @{$self->{'current_contents'}};
   }
@@ -1749,7 +1804,7 @@
       $formatter->{'container'}->set_space_protection(undef,
         undef, undef, $frenchspacing);
     } elsif ($root->{'type'} eq 'bracketed') {
-      $result .= $formatter->{'container'}->add_text('}');
+      $result .= $self->_count_added_text($formatter->{'container'}, '}');
     } elsif ($root->{'type'} eq 'row') {
       my @cell_beginnings;
       my @cell_lines;
@@ -1788,7 +1843,7 @@
       
       # this is used to keep track of the last cell with content.
       my $max_cell = scalar(@{$self->{'format_context'}->[-1]->{'row'}});
-      $bytes_count = 0;
+      my $bytes_count = 0;
       for (my $line_idx = 0; $line_idx < $max_lines; $line_idx++) {
         my $line_width = $indent_len;
         my $line = '';
@@ -1851,20 +1906,17 @@
     }
   }
   if ($paragraph) {
-    my $end = $paragraph->{'container'}->end();
-    $result .= $end;
-    $bytes_count += $self->count_bytes($end);
-    $lines_count += $paragraph->{'container'}->{'lines_counter'};
-    if ($self->{'context'}->[-1] eq 'flush') {
-      my $index = -1;
-      $index--
-        while 
(!$flush_commands{$self->{'format_context'}->[$index]->{'cmdname'}});
-      # nothing to do in case of flushleft
-      if ($self->{'format_context'}->[$index]->{'cmdname'} eq 'flushright') {
+    $result .= $self->_count_added_end($paragraph->{'container'});
+    if ($self->{'context'}->[-1] eq 'flush' and $self->in_flushright()) {
+      my $counts = pop @{$self->{'count_context'}};
+      my $bytes_count;
         ($result, $bytes_count) = $self->_align_lines($result, 
-                        $self->{'format_context'}->[$index]->{'max'},
-                        'right', $locations);
-      }
+                      
$self->{'format_context'}->[$self->flushright_index]->{'max'},
+                      'right', $counts->{'locations'});
+      $self->{'count_context'}->[-1]->{'bytes'} += $bytes_count;
+      $self->{'count_context'}->[-1]->{'lines'} += $counts->{'lines'};
+      push @{$self->{'count_context'}->[-1]->{'locations'}},
+                       @{$counts->{'locations'}};
     }
     pop @{$self->{'formatters'}};
     delete $self->{'format_context'}->[-1]->{'counter'};
@@ -1930,30 +1982,26 @@
             $prepended = $self->gdt("{float_number}\n",
                  {'float_number' => $root->{'number'}});
           }
-          $lines_count++;
         }
         if ($prepended) {
           #print STDERR "PREPENDED ".Data::Dumper->Dump([$prepended]);
-          my ($float_number) = $self->convert_line ($prepended);
+          my $float_number = $self->convert_line ($prepended);
           $result .= $float_number;
-          $bytes_count += $self->count_bytes($float_number);
           $self->{'format_context'}->[-1]->{'counter'} += 
             Texinfo::Convert::Unicode::string_width($float_number);
         }
         if ($caption) {
           # FIXME not sure it is right.
           $self->{'format_context'}->[-1]->{'paragraph_count'} = 0;
-          $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-               $locations, 0, $self->_convert($caption->{'args'}->[0]));
+          $result .= $self->_convert($caption->{'args'}->[0]);
         }
       }
     } elsif ($root->{'cmdname'} eq 'quotation' and $root->{'extra'} 
              and $root->{'extra'}->{'authors'}) {
       foreach my $author (@{$root->{'extra'}->{'authors'}}) {
-        $self->advance_count_text(\$result, \$bytes_count, \$lines_count,
-             $locations, 0, $self->_convert(
+        $result .= $self->_convert(
                  $self->gdt("address@hidden --- address@hidden",
-                    {'author' => $author->{'extra'}->{'misc_content'}})));
+                    {'author' => $author->{'extra'}->{'misc_content'}}));
       }
     }
     if ($advance_paragraph_count_commands{$root->{'cmdname'}}) {
@@ -1961,8 +2009,7 @@
     }
   }
   if ($preformatted) {
-    $result .= $preformatted->{'container'}->end();
-    # FIXME get lines count?
+    $result .= $self->_count_added_end($preformatted->{'container'});
     pop @{$self->{'formatters'}};
   }
 
@@ -1976,13 +2023,14 @@
     if ($root->{'cmdname'} and $format_context_commands{$root->{'cmdname'}}
         or $cell);
   if ($cell) {
+    # FIXME
     push @{$self->{'format_context'}->[-1]->{'row'}}, $result;
-    push @{$self->{'format_context'}->[-1]->{'locations'}}, $locations;
+    #push @{$self->{'format_context'}->[-1]->{'locations'}}, $locations;
+    pop @{$self->{'count_context'}};
     $result = '';
   }
 
-  return ($result, {'bytes' => $bytes_count, 'lines' => $lines_count},
-          $locations);
+  return $result;
 }
 
 1;

Index: t/test_count.t
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/test_count.t,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- t/test_count.t      16 Jan 2011 10:04:49 -0000      1.1
+++ t/test_count.t      20 Jan 2011 00:38:32 -0000      1.2
@@ -28,33 +28,34 @@
   my $self = shift;
   my $root = shift;
 
-  my ($text, $counts, $locations) =
+  my $text =
     Texinfo::Convert::Plaintext::_convert($self, $root);
   my $string = '';
   $string .= '@'.$root->{'cmdname'} if ($root->{'cmdname'});
   $string .= ":$root->{'type'}" if ($root->{'type'});
   $string .= ":text" if (defined($root->{'text'}));
-  if ($counts) {
-    if (defined($counts->{'bytes'})) {
-      $string .= ", b $counts->{'bytes'}";
-    }
-    if (defined($counts->{'lines'})) {
-      $string .= ", l $counts->{'lines'}";
-    }
-    if ($locations) {
-      foreach my $location (@$locations) {
-        $string .= "|";
-        if (defined($location->{'lines'})) {
-          $string .= " l $location->{'lines'}";
-        }
-        if (defined($location->{'bytes'})) {
-          $string .= " b $location->{'bytes'}";
-        }
-      }
-    }
-  }
+  #if ($counts) {
+  #  if (defined($counts->{'bytes'})) {
+  #    $string .= ", b $counts->{'bytes'}";
+  #  }
+  #  if (defined($counts->{'lines'})) {
+  #    $string .= ", l $counts->{'lines'}";
+  #  }
+  #  if ($locations) {
+  #    foreach my $location (@$locations) {
+  #      $string .= "|";
+  #      if (defined($location->{'lines'})) {
+  #        $string .= " l $location->{'lines'}";
+  #      }
+  #      if (defined($location->{'bytes'})) {
+  #        $string .= " b $location->{'bytes'}";
+  #      }
+  #    }
+  #  }
+  #}
   #print STDERR "$string\n";
-  return ($text, $counts, $locations);
+  #return ($text, $counts, $locations);
+  return $text;
 }
 
 }

Index: t/results/def/all_commands_delimiters_printindex.pl
===================================================================
RCS file: 
/sources/texinfo/texinfo/tp/t/results/def/all_commands_delimiters_printindex.pl,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- t/results/def/all_commands_delimiters_printindex.pl 17 Jan 2011 00:57:23 
-0000      1.2
+++ t/results/def/all_commands_delimiters_printindex.pl 20 Jan 2011 00:38:32 
-0000      1.3
@@ -12617,38 +12617,38 @@
 [index]
 * Menu:
 
-* )expose on )Window:                    Top.                   (line 4)
-* )expose on )Window <1>:                Top.                   (line 4)
-* ,expose on ,Window:                    Top.                   (line 4)
-* ,expose on ,Window <1>:                Top.                   (line 4)
-* ;expose on ;Window:                    Top.                   (line 4)
-* ;expose on ;Window <1>:                Top.                   (line 4)
-* `A2\':                                  Top.                   (line 4)
-* A2:                                    Top.                   (line 4)
-* `A3\':                                  Top.                   (line 4)
-* A3:                                    Top.                   (line 4)
-* `A3\' on `A2\':                          Top.                   (line 4)
-* A3 on A2:                              Top.                   (line 4)
-* `A4\' on `A2\':                          Top.                   (line 4)
-* A4 on A2:                              Top.                   (line 4)
-* apply:                                 Top.                   (line 4)
-* e)xpose on W)indow:                    Top.                   (line 4)
-* e)xpose on W)indow <1>:                Top.                   (line 4)
-* e,xpose on W,indow:                    Top.                   (line 4)
-* e,xpose on W,indow <1>:                Top.                   (line 4)
-* e;xpose on W;indow:                    Top.                   (line 4)
-* e;xpose on W;indow <1>:                Top.                   (line 4)
-* expose on `com\':                       Top.                   (line 4)
-* expose on W,indow:                     Top.                   (line 4)
-* expose on Window:                      Top.                   (line 4)
-* expose on windows:                     Top.                   (line 4)
-* foobar:                                Top.                   (line 4)
-* foobar <1>:                            Top.                   (line 4)
-* foobug:                                Top.                   (line 4)
-* FORWARD--CHAR:                         Top.                   (line 4)
-* fun_name:                              Top.                   (line 4)
-* fun_name1:                             Top.                   (line 4)
-* push:                                  Top.                   (line 4)
+* )expose on )Window:                    Top.                 (line  47)
+* )expose on )Window <1>:                Top.                 (line  51)
+* ,expose on ,Window:                    Top.                 (line  39)
+* ,expose on ,Window <1>:                Top.                 (line  43)
+* ;expose on ;Window:                    Top.                 (line  55)
+* ;expose on ;Window <1>:                Top.                 (line  59)
+* `A2\':                                  Top.                 (line  67)
+* A2:                                    Top.                 (line  65)
+* `A3\':                                  Top.                 (line  75)
+* A3:                                    Top.                 (line  73)
+* `A3\' on `A2\':                          Top.                 (line  95)
+* A3 on A2:                              Top.                 (line  93)
+* `A4\' on `A2\':                          Top.                 (line  99)
+* A4 on A2:                              Top.                 (line  97)
+* apply:                                 Top.                 (line  63)
+* e)xpose on W)indow:                    Top.                 (line  49)
+* e)xpose on W)indow <1>:                Top.                 (line  45)
+* e,xpose on W,indow:                    Top.                 (line  41)
+* e,xpose on W,indow <1>:                Top.                 (line  37)
+* e;xpose on W;indow:                    Top.                 (line  57)
+* e;xpose on W;indow <1>:                Top.                 (line  53)
+* expose on `com\':                       Top.                 (line  61)
+* expose on W,indow:                     Top.                 (line  32)
+* expose on Window:                      Top.                 (line  35)
+* expose on windows:                     Top.                 (line  29)
+* foobar:                                Top.                 (line  10)
+* foobar <1>:                            Top.                 (line   8)
+* foobug:                                Top.                 (line  15)
+* FORWARD--CHAR:                         Top.                 (line   3)
+* fun_name:                              Top.                 (line 101)
+* fun_name1:                             Top.                 (line 103)
+* push:                                  Top.                 (line  17)
 
 
 Types
@@ -12656,10 +12656,10 @@
 [index]
 * Menu:
 
-* `A2\':                                  Top.                   (line 4)
-* `A2\' <1>:                              Top.                   (line 4)
-* A2:                                    Top.                   (line 4)
-* pair:                                  Top.                   (line 4)
+* `A2\':                                  Top.                  (line 87)
+* `A2\' <1>:                              Top.                  (line 83)
+* A2:                                    Top.                  (line 81)
+* pair:                                  Top.                  (line 22)
 
 
 Variables
@@ -12667,17 +12667,17 @@
 [index]
 * Menu:
 
-* `A2\':                                  Top.                   (line 4)
-* A2:                                    Top.                   (line 4)
-* A3:                                    Top.                   (line 4)
-* `A3\':                                  Top.                   (line 4)
-* A3 <1>:                                Top.                   (line 4)
-* A4 of A2:                              Top.                   (line 4)
-* `A4\' of `A2\':                          Top.                   (line 4)
-* border-pattern:                        Top.                   (line 4)
-* border-pattern of Window:              Top.                   (line 4)
-* enable:                                Top.                   (line 4)
-* fill-column:                           Top.                   (line 4)
+* `A2\':                                  Top.                  (line 71)
+* A2:                                    Top.                  (line 69)
+* A3:                                    Top.                  (line 85)
+* `A3\':                                  Top.                  (line 79)
+* A3 <1>:                                Top.                  (line 77)
+* A4 of A2:                              Top.                  (line 89)
+* `A4\' of `A2\':                          Top.                  (line 91)
+* border-pattern:                        Top.                  (line 25)
+* border-pattern of Window:              Top.                  (line 27)
+* enable:                                Top.                  (line 20)
+* fill-column:                           Top.                  (line  6)
 
 ';
 

Index: t/results/def/all_commands_printindex.pl
===================================================================
RCS file: /sources/texinfo/texinfo/tp/t/results/def/all_commands_printindex.pl,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- t/results/def/all_commands_printindex.pl    17 Jan 2011 00:57:24 -0000      
1.2
+++ t/results/def/all_commands_printindex.pl    20 Jan 2011 00:38:32 -0000      
1.3
@@ -2942,15 +2942,15 @@
 [index]
 * Menu:
 
-* d--efmac_name:                         Top.                   (line 4)
-* d--efmethod_name on c--lass:           Top.                   (line 4)
-* d--efop_name on c--lass:               Top.                   (line 4)
-* d--efspec_name:                        Top.                   (line 4)
-* d--eftypefn_name:                      Top.                   (line 4)
-* d--eftypefun_name:                     Top.                   (line 4)
-* d--eftypemethod_name on c--lass:       Top.                   (line 4)
-* d--eftypeop_name on c--lass:           Top.                   (line 4)
-* d--efun_name:                          Top.                   (line 4)
+* d--efmac_name:                         Top.                  (line 27)
+* d--efmethod_name on c--lass:           Top.                  (line 51)
+* d--efop_name on c--lass:               Top.                  (line 18)
+* d--efspec_name:                        Top.                  (line 30)
+* d--eftypefn_name:                      Top.                  (line  6)
+* d--eftypefun_name:                     Top.                  (line 39)
+* d--eftypemethod_name on c--lass:       Top.                  (line 54)
+* d--eftypeop_name on c--lass:           Top.                  (line  9)
+* d--efun_name:                          Top.                  (line 24)
 
 
 Types
@@ -2958,7 +2958,7 @@
 [index]
 * Menu:
 
-* d--eftp_name:                          Top.                   (line 4)
+* d--eftp_name:                          Top.                  (line 21)
 
 
 Variables
@@ -2966,14 +2966,14 @@
 [index]
 * Menu:
 
-* d--efcv_name:                          Top.                   (line 4)
-* d--efivar_name of c--lass:             Top.                   (line 4)
-* d--efopt_name:                         Top.                   (line 4)
-* d--eftypeivar_name of c--lass:         Top.                   (line 4)
-* d--eftypevar_name:                     Top.                   (line 4)
-* d--eftypevr_name:                      Top.                   (line 4)
-* d--efvar_name:                         Top.                   (line 4)
-* d--efvr_name:                          Top.                   (line 4)
+* d--efcv_name:                          Top.                  (line 15)
+* d--efivar_name of c--lass:             Top.                  (line 45)
+* d--efopt_name:                         Top.                  (line 36)
+* d--eftypeivar_name of c--lass:         Top.                  (line 48)
+* d--eftypevar_name:                     Top.                  (line 42)
+* d--eftypevr_name:                      Top.                  (line 12)
+* d--efvar_name:                         Top.                  (line 33)
+* d--efvr_name:                          Top.                  (line  3)
 
 ';
 



reply via email to

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