help-texinfo
[Top][All Lists]
Advanced

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

Re: Relating multiple index entries to one table item


From: Gavin Smith
Subject: Re: Relating multiple index entries to one table item
Date: Mon, 21 Nov 2022 20:49:34 +0000

On Mon, Nov 21, 2022 at 06:43:20PM +0000, Gavin Smith wrote:
> Hence, I think our starting point is to make mixed @item/@itemx/@?index
> work appropriately, associating index commands that immediately follow
> @item commands with them.  I think it might be better in a case like
> 
> @table @gcctabopt
> @item -Wpedantic
> @itemx -pedantic
> @opindex pedantic
> @opindex Wpedantic
> @opindex Wno-pedantic
> 
> to find some way to make all index entries link to the top @item

My current work is at the bottom of the email.  This will need more testing
and also implementing in the XS parser, so it will take me at least few days to
finish.

The idea is to put the index entries in the 'table_term' element rather
than 'table_item', and in the transformation in Texinfo::Common,
to reorder inside table_term to put index entries first, taking the
first index entry that occurs as the copiable anchor.  So

@table @asis
@item -Wpedantic
@itemx -pedantic
@vindex pedantic
@vindex Wpedantic
@vindex Wno-pedantic
aaaaa

bbb
@end table

produces

<dl class="table">
<a class="index-entry-id" id="index-Wpedantic"></a>
<a class="index-entry-id" id="index-Wno_002dpedantic"></a>
<dt id='index-pedantic'><span>-Wpedantic<a class="copiable-link" href='#index-pe
dantic'> &para;</a></span></dt>
<dt>-pedantic</dt>
<dd><p>aaaaa
</p>
<p>bbb
</p></dd>
</dl>

Does this seem ok?

diff --git a/tp/Texinfo/Common.pm b/tp/Texinfo/Common.pm
index 607b61d5ca..e57a0aa96c 100644
--- a/tp/Texinfo/Common.pm
+++ b/tp/Texinfo/Common.pm
@@ -2177,6 +2177,7 @@ sub move_index_entries_after_items_in_tree($)
   return modify_tree($tree, \&_move_index_entries_after_items);
 }
 
+# todo: rename
 sub _relate_index_entry_to_table_entry($)
 {
   my $current = shift; # table_entry
@@ -2204,15 +2205,27 @@ sub _relate_index_entry_to_table_entry($)
 
   return if !$table_term or !$table_item or !$item;
 
-  if ($table_item->{'contents'}
-    and $table_item->{'contents'}->[0]
-    and $table_item->{'contents'}->[0]->{'type'}
-    and $table_item->{'contents'}->[0]->{'type'} eq 'index_entry_command') {
-      my $index_command = shift @{$table_item->{'contents'}};
-      delete $index_command->{'parent'};
-      $item->{'extra'}->{'index_entry'}
-        = $index_command->{'extra'}->{'index_entry'};
-      $item->{'extra'}->{'index_entry'}->{'entry_element'} = $item;
+  my $index_command;
+  my @old_contents = @{$table_term->{'contents'}};
+  my (@index_children, @non_index_children);
+  for my $element (@old_contents) {
+    if ($element->{'type'} and $element->{'type'} eq 'index_entry_command') {
+      push @index_children, $element;
+    } else {
+      push @non_index_children, $element;
+    }
+  }
+  if (@index_children) {
+    $index_command = shift @index_children;
+  }
+
+  @{$table_term->{'contents'}} = (@index_children, @non_index_children);
+
+  if (defined($index_command)) {
+    delete $index_command->{'parent'};
+    $item->{'extra'}->{'index_entry'}
+      = $index_command->{'extra'}->{'index_entry'};
+    $item->{'extra'}->{'index_entry'}->{'entry_element'} = $item;
   }
 }
 
diff --git a/tp/Texinfo/ParserNonXS.pm b/tp/Texinfo/ParserNonXS.pm
index e05754f448..8e29992e1d 100644
--- a/tp/Texinfo/ParserNonXS.pm
+++ b/tp/Texinfo/ParserNonXS.pm
@@ -1567,19 +1567,26 @@ sub _gather_previous_item($$;$$)
   # remove everything that is not an @item/@itemx or before_item to
   # put it in the table_item/inter_item
   my $contents_count = scalar(@{$current->{'contents'}});
-  my $item_idx;
+  my $splice_idx;
   for (my $i = $contents_count - 1; $i >= 0; $i--) {
     if ($current->{'contents'}->[$i]->{'cmdname'}
         and ($current->{'contents'}->[$i]->{'cmdname'} eq 'item'
              or ($current->{'contents'}->[$i]->{'cmdname'} eq 'itemx'))) {
-      $item_idx = $i;
+      $splice_idx = $i;
       last;
     }
   }
-  $item_idx = -1 if !defined($item_idx);
+  $splice_idx = -1 if !defined($splice_idx);
+
+  # move forward past any index entries
+  for ($splice_idx++; $splice_idx < $contents_count; $splice_idx++) {
+    my $child = $current->{'contents'}->[$splice_idx];
+    last if (!$child->{'type'} or $child->{'type'} ne 'index_entry_command');
+  }
 
   my $new_contents = [];
-  @{$new_contents} = splice @{$current->{'contents'}}, $item_idx + 1;
+  @{$new_contents} = splice @{$current->{'contents'}}, $splice_idx;
+
   my $table_after_terms = {'type' => $type,
                            'contents' => $new_contents};
   for my $child (@{$new_contents}) {
@@ -1609,11 +1616,12 @@ sub _gather_previous_item($$;$$)
         $item_content->{'parent'} = $table_term;
         unshift @{$table_term->{'contents'}}, $item_content;
         # debug
-        if (! (($item_content->{'cmdname'}
-                and ($item_content->{'cmdname'} eq 'itemx'
-                    or $item_content->{'cmdname'} eq 'item'))
-               or ($item_content->{'type'}
-                   and $item_content->{'type'} eq 'inter_item'))) {
+        if (!(($item_content->{'cmdname'}
+               and ($item_content->{'cmdname'} eq 'itemx'
+                   or $item_content->{'cmdname'} eq 'item'))
+              or ($item_content->{'type'}
+                  and ($item_content->{'type'} eq 'inter_item'
+                   or $item_content->{'type'} eq 'index_entry_command')))) {
           $self->_bug_message("wrong element in table term", $source_info,
                               $item_content);
         }





reply via email to

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