texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * doc/texi2any_api.texi (Customizing Footnotes),


From: Patrice Dumas
Subject: branch master updated: * doc/texi2any_api.texi (Customizing Footnotes), tp/Texinfo/Convert/HTML.pm (get_pending_footnotes) (_default_format_footnotes_sequence): have get_pending_footnotes return a reference on an array.
Date: Tue, 28 Nov 2023 18:52:26 -0500

This is an automated email from the git hooks/post-receive script.

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new e738b8ea1d * doc/texi2any_api.texi (Customizing Footnotes), 
tp/Texinfo/Convert/HTML.pm (get_pending_footnotes) 
(_default_format_footnotes_sequence): have get_pending_footnotes return a 
reference on an array.
e738b8ea1d is described below

commit e738b8ea1d5fce7b4b1ecf5dcbce95d6c3606841
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Nov 29 00:50:20 2023 +0100

    * doc/texi2any_api.texi (Customizing Footnotes),
    tp/Texinfo/Convert/HTML.pm (get_pending_footnotes)
    (_default_format_footnotes_sequence): have get_pending_footnotes
    return a reference on an array.
    
    * doc/texi2any_api.texi (Customizing Footnotes),
    tp/Texinfo/Convert/HTML.pm (_convert_footnote_command)
    (_default_format_footnotes_sequence, _convert_footnote_command):
    always pass the number of the footnote to register_footnote.
    
    * tp/Texinfo/Convert/HTML.pm (shared_conversion_state)
    (_initialize_output_state),
    tp/Texinfo/XS/convert/call_html_perl_function.c
    (get_shared_conversion_state, call_*),
    tp/Texinfo/XS/main/converter_types.h (HTML_SHARED_CONVERSION_STATE)
    (CONVERTER), tp/Texinfo/XS/main/extra.c (add_associated_info_integer):
    register in $self->{'shared_conversion_state_integers'} the conversion
    states that are integers.  Register in
    $self->{'shared_conversion_accessed_integers'} the integer conversion
    states that were accessed such that XS code can get their values.  Get
    the accessed integers at the end of call_* function by calling
    get_shared_conversion_state that add the integer to the C converter
    shared_conversion_state.
    
    * tp/Texinfo/Convert/HTML.pm (%XS_conversion_overrides),
    tp/Texinfo/XS/convert/ConvertXS.xs (html_register_footnote)
    (html_get_pending_footnotes),
    tp/Texinfo/XS/convert/build_html_perl_state.c
    (build_pending_footnotes), tp/Texinfo/XS/convert/convert_html.c
    (html_register_footnote, html_get_pending_footnotes)
    (destroy_pending_footnotes), tp/Texinfo/XS/main/converter_types.h
    (HTML_PENDING_FOOTNOTE, HTML_PENDING_FOOTNOTE_STACK, CONVERTER):
    implement register_footnote and get_pending_footnotes in C, add XS
    interface.
    
    * tp/Texinfo/Convert/HTML.pm (_convert_explained_command):
    rename element_explanation_contents shared_conversion_state as
    element_explanation_content. Avoid using contents separate from the
    associated element.
---
 ChangeLog                                       |  42 ++++++++++
 doc/texi2any_api.texi                           |  14 ++--
 tp/Texinfo/Convert/HTML.pm                      |  67 +++++++++++-----
 tp/Texinfo/XS/convert/ConvertXS.xs              | 102 ++++++++++++++++++++++--
 tp/Texinfo/XS/convert/build_html_perl_state.c   |  34 ++++++++
 tp/Texinfo/XS/convert/build_html_perl_state.h   |   2 +
 tp/Texinfo/XS/convert/call_html_perl_function.c |  85 ++++++++++++++++++++
 tp/Texinfo/XS/convert/convert_html.c            |  76 +++++++++++++++++-
 tp/Texinfo/XS/convert/convert_html.h            |   6 ++
 tp/Texinfo/XS/main/converter_types.h            |  32 ++++++++
 tp/Texinfo/XS/main/extra.c                      |   7 ++
 tp/Texinfo/XS/main/extra.h                      |   1 +
 12 files changed, 431 insertions(+), 37 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 149989e5d1..e5d8b7676d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2023-11-28  Patrice Dumas  <pertusus@free.fr>
+
+       * doc/texi2any_api.texi (Customizing Footnotes),
+       tp/Texinfo/Convert/HTML.pm (get_pending_footnotes)
+       (_default_format_footnotes_sequence): have get_pending_footnotes
+       return a reference on an array.
+
+       * doc/texi2any_api.texi (Customizing Footnotes),
+       tp/Texinfo/Convert/HTML.pm (_convert_footnote_command)
+       (_default_format_footnotes_sequence, _convert_footnote_command):
+       always pass the number of the footnote to register_footnote.
+
+       * tp/Texinfo/Convert/HTML.pm (shared_conversion_state)
+       (_initialize_output_state),
+       tp/Texinfo/XS/convert/call_html_perl_function.c
+       (get_shared_conversion_state, call_*),
+       tp/Texinfo/XS/main/converter_types.h (HTML_SHARED_CONVERSION_STATE)
+       (CONVERTER), tp/Texinfo/XS/main/extra.c (add_associated_info_integer):
+       register in $self->{'shared_conversion_state_integers'} the conversion
+       states that are integers.  Register in
+       $self->{'shared_conversion_accessed_integers'} the integer conversion
+       states that were accessed such that XS code can get their values.  Get
+       the accessed integers at the end of call_* function by calling
+       get_shared_conversion_state that add the integer to the C converter
+       shared_conversion_state.
+
+       * tp/Texinfo/Convert/HTML.pm (%XS_conversion_overrides),
+       tp/Texinfo/XS/convert/ConvertXS.xs (html_register_footnote)
+       (html_get_pending_footnotes),
+       tp/Texinfo/XS/convert/build_html_perl_state.c
+       (build_pending_footnotes), tp/Texinfo/XS/convert/convert_html.c
+       (html_register_footnote, html_get_pending_footnotes)
+       (destroy_pending_footnotes), tp/Texinfo/XS/main/converter_types.h
+       (HTML_PENDING_FOOTNOTE, HTML_PENDING_FOOTNOTE_STACK, CONVERTER):
+       implement register_footnote and get_pending_footnotes in C, add XS
+       interface.
+
+       * tp/Texinfo/Convert/HTML.pm (_convert_explained_command):
+       rename element_explanation_contents shared_conversion_state as
+       element_explanation_content. Avoid using contents separate from the
+       associated element.
+
 2023-11-28  Gavin Smith <gavinsmith0123@gmail.com>
 
        * tp/Texinfo/ParserNonXS.pm (%parser_state_configuration):
diff --git a/doc/texi2any_api.texi b/doc/texi2any_api.texi
index 2051f0b7a9..f12f049f12 100644
--- a/doc/texi2any_api.texi
+++ b/doc/texi2any_api.texi
@@ -3724,8 +3724,8 @@ functions formatting their argument elsewhere, two 
functions are available:
 @var{\%element} is the footnote texinfo tree element. @var{$footnote_id} is the
 identifier for the location where the footnote arguments are expanded.
 @var{$foot_in_doc_id} is the identifier for the location where the footnote
-appears in the document.  @var{$number_in_doc} is the symbol used to format the
-footnote in the document.  @var{$footnote_location_filename} is the filename of
+appears in the document.  @var{$number_in_doc} is the number of the footnote
+in the document.  @var{$footnote_location_filename} is the filename of
 the output unit of the footnote in the document. If the footnote appears
 in a region that is expanded multiple times, the information on the expansion
 is @var{$multi_expanded_region} (@pxref{Dynamic Converter Formatting
@@ -3737,11 +3737,11 @@ Information}).
 also call @code{command_href} to link to the location where the footnote
 text will be expanded (@pxref{Target Commands Links@comma{} Texts and 
Associated Commands}).
 
-@deftypefun {@var{@@pending_footnotes_information} =} 
@var{$converter}->get_pending_footnotes ()
-Returns in @var{@@pending_footnotes_information} the information gathered
-in @code{register_footnote}.  Each of the array element in 
@var{@@pending_footnotes_information}
-is an array reference containing the arguments of @code{register_footnote}
-in the same order.
+@deftypefun {@var{\@@pending_footnotes_information} =} 
@var{$converter}->get_pending_footnotes ()
+Returns in @var{\@@pending_footnotes_information} the information gathered
+in @code{register_footnote}.  Each of the array reference
+element in @var{\@@pending_footnotes_information} is an array reference
+containing the arguments of @code{register_footnote} in the same order.
 @end deftypefun
 
 The formatting of footnotes content is done by the
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index 9899780167..711bb357a9 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -130,6 +130,10 @@ my %XS_conversion_overrides = (
    => "Texinfo::Convert::ConvertXS::html_attribute_class",
   "Texinfo::Convert::HTML::html_get_css_elements_classes"
    => "Texinfo::Convert::ConvertXS::html_get_css_elements_classes",
+  "Texinfo::Convert::HTML::register_footnote",
+   => "Texinfo::Convert::ConvertXS::html_register_footnote",
+  "Texinfo::Convert::HTML::get_pending_footnotes",
+   => "Texinfo::Convert::ConvertXS::html_get_pending_footnotes",
   "Texinfo::Convert::HTML::_XS_get_index_entries_sorted_by_letter"
    => "Texinfo::Convert::ConvertXS::get_index_entries_sorted_by_letter",
   "Texinfo::Convert::HTML::_XS_html_merge_index_entries"
@@ -1787,12 +1791,19 @@ sub shared_conversion_state($$;$)
   my $initialization_value = shift;
 
   if (not defined($self->{'shared_conversion_state'}->{$state_name})) {
+    if ($initialization_value =~ /^\d+$/) {
+      $self->{'shared_conversion_state_integers'}->{$state_name} = 1;
+    }
     if (not ref($initialization_value)) {
       $self->{'shared_conversion_state'}->{$state_name} = 
\$initialization_value;
     } else {
       $self->{'shared_conversion_state'}->{$state_name} = 
$initialization_value;
     }
   }
+  # set for XS code to notify that value may have changed
+  if ($self->{'shared_conversion_state_integers'}->{$state_name}) {
+    $self->{'shared_conversion_accessed_integers'}->{$state_name} = 1;
+  }
   return $self->{'shared_conversion_state'}->{$state_name};
 }
 
@@ -1814,7 +1825,7 @@ sub get_pending_footnotes($)
 
   my @result = @{$self->{'pending_footnotes'}};
   @{$self->{'pending_footnotes'}} = ();
-  return @result;
+  return \@result;
 }
 
 
@@ -3177,15 +3188,16 @@ sub _convert_explained_command($$$$)
   my $normalized_type = '';
   if ($command->{'args'}->[0]
       and $command->{'args'}->[0]->{'contents'}) {
-    $normalized_type = 
Texinfo::Convert::NodeNameNormalization::convert_to_identifier(
-          {'contents' => $command->{'args'}->[0]->{'contents'}});
+    $normalized_type
+       = Texinfo::Convert::NodeNameNormalization::convert_to_identifier(
+                                   $command->{'args'}->[0]);
   }
 
   my $explained_commands
     = $self->shared_conversion_state('explained_commands', {});
   $explained_commands->{$cmdname} = {} if (!$explained_commands->{$cmdname});
-  my $element_explanation_contents
-    = $self->shared_conversion_state('element_explanation_contents', {});
+  my $element_explanation_content
+    = $self->shared_conversion_state('element_explanation_content', {});
   if ($args and $args->[1] and defined($args->[1]->{'string'})
                  and $args->[1]->{'string'} =~ /\S/) {
     $with_explanation = 1;
@@ -3197,28 +3209,29 @@ sub _convert_explained_command($$$$)
     $explanation_result = $self->convert_tree($args->[1]->{'tree'},
                                               "convert $cmdname explanation");
     $explained_commands->{$cmdname}->{$normalized_type} =
-       $command->{'args'}->[1]->{'contents'};
-  } elsif ($element_explanation_contents->{$command}) {
+                                          $command->{'args'}->[1];
+  } elsif ($element_explanation_content->{$command}) {
     # if an acronym element is formatted more than once, this ensures that
     # only the first explanation (including a lack of explanation) is reused.
     # Note that this means that acronyms converted first on a sectioning
     # command line for a direction text may not get the explanation
     # from acronyms appearing later on in the document but before
     # the sectioning command.
-    if (@{$element_explanation_contents->{$command}}) {
+    if ($element_explanation_content->{$command}->{'contents'}
+     and scalar(@{$element_explanation_content->{$command}->{'contents'}})) {
       $explanation_string = $self->convert_tree_new_formatting_context(
         {'type' => '_string',
-         'contents' => $element_explanation_contents->{$command}},
+         'contents' => [$element_explanation_content->{$command}]},
         $cmdname, $cmdname);
     }
   } elsif ($explained_commands->{$cmdname}->{$normalized_type}) {
     $explanation_string = $self->convert_tree_new_formatting_context(
                       {'type' => '_string',
-                       'contents' => $explained_commands
-                                     ->{$cmdname}->{$normalized_type}},
+                       'contents' => [$explained_commands
+                                     ->{$cmdname}->{$normalized_type}]},
                                                    $cmdname, $cmdname);
 
-    $element_explanation_contents->{$command}
+    $element_explanation_content->{$command}
        = $explained_commands->{$cmdname}->{$normalized_type};
   } else {
     # Avoid ever giving an explanation for this element, even if an
@@ -3229,7 +3242,7 @@ sub _convert_explained_command($$$$)
     # @acronym within the explanation could end up referring to the
     # containing @acronym.
 
-    $element_explanation_contents->{$command} = [];
+    $element_explanation_content->{$command} = {};
   }
   my $result = '';
   if ($args and defined($args->[0])) {
@@ -3285,16 +3298,17 @@ sub _convert_footnote_command($$$$)
   my $command = shift;
   my $args = shift;
 
-  my $number_in_doc;
   my $foot_num = $self->shared_conversion_state('footnote_number', 0);
   ${$foot_num}++;
+  my $number_in_doc = $$foot_num;
+  my $footnote_mark;
   if ($self->get_conf('NUMBER_FOOTNOTES')) {
-    $number_in_doc = $$foot_num;
+    $footnote_mark = $number_in_doc;
   } else {
-    $number_in_doc = $self->get_conf('NO_NUMBER_FOOTNOTE_SYMBOL');
+    $footnote_mark = $self->get_conf('NO_NUMBER_FOOTNOTE_SYMBOL');
   }
 
-  return "($number_in_doc)" if ($self->in_string());
+  return "($footnote_mark)" if ($self->in_string());
 
   #print STDERR "FOOTNOTE $command\n";
   my $footid = $self->command_id($command);
@@ -3349,9 +3363,9 @@ sub _convert_footnote_command($$$$)
 
   my $footnote_number_text;
   if ($self->in_preformatted_context()) {
-    $footnote_number_text = "($number_in_doc)";
+    $footnote_number_text = "($footnote_mark)";
   } else {
-    $footnote_number_text = "<sup>$number_in_doc</sup>";
+    $footnote_number_text = "<sup>$footnote_mark</sup>";
   }
   return $self->html_attribute_class('a', [$cmdname])
     ." id=\"$docid\" href=\"$footnote_href\">$footnote_number_text</a>";
@@ -10746,9 +10760,9 @@ sub _default_format_footnotes_sequence($)
 {
   my $self = shift;
 
-  my @pending_footnotes = $self->get_pending_footnotes();
+  my $pending_footnotes = $self->get_pending_footnotes();
   my $result = '';
-  foreach my $pending_footnote_info_array (@pending_footnotes) {
+  foreach my $pending_footnote_info_array (@$pending_footnotes) {
     my ($command, $footid, $docid, $number_in_doc,
         $footnote_location_filename, $multi_expanded_region)
           = @$pending_footnote_info_array;
@@ -10770,8 +10784,15 @@ sub _default_format_footnotes_sequence($)
     chomp ($footnote_text);
     $footnote_text .= "\n";
 
+    my $footnote_mark;
+    if ($self->get_conf('NUMBER_FOOTNOTES')) {
+      $footnote_mark = $number_in_doc;
+    } else {
+      $footnote_mark = $self->get_conf('NO_NUMBER_FOOTNOTE_SYMBOL');
+    }
+
     $result .= $self->html_attribute_class('h5', ['footnote-body-heading']) . 
'>'.
-     "<a id=\"$footid\" 
href=\"$footnote_location_href\">($number_in_doc)</a></h5>\n"
+     "<a id=\"$footid\" 
href=\"$footnote_location_href\">($footnote_mark)</a></h5>\n"
      . $footnote_text;
   }
   return $result;
@@ -11067,6 +11088,8 @@ sub _initialize_output_state($$)
 
   # for diverse API used in conversion
   $self->{'shared_conversion_state'} = {};
+  $self->{'shared_conversion_state_integers'} = {};
+  $self->{'shared_conversion_accessed_integers'} = {};
 
   $self->{'associated_inline_content'} = {};
 
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 5a31e49e3a..952c0e563f 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -32,19 +32,20 @@
 
 #include "ppport.h"
 
-#include "get_perl_info.h"
-#include "build_perl_info.h"
-#include "build_html_perl_state.h"
+#include "builtin_commands.h"
 #include "convert_plain_texinfo.h"
 #include "convert_text.h"
 #include "convert_to_text.h"
-#include "builtin_commands.h"
+#include "convert_to_texinfo.h"
 #include "indices_in_conversion.h"
 #include "command_stack.h"
+#include "document.h"
+#include "get_perl_info.h"
+#include "build_perl_info.h"
+#include "build_html_perl_state.h"
 #include "converter.h"
 #include "convert_html.h"
 #include "get_html_perl_info.h"
-#include "document.h"
 
 MODULE = Texinfo::Convert::ConvertXS   PACKAGE = Texinfo::Convert::ConvertXS
 
@@ -421,6 +422,97 @@ html_get_css_elements_classes (SV *converter_in, ...)
     OUTPUT:
          RETVAL
 
+void
+html_register_footnote (SV *converter_in, SV *command, footid, docid, int 
number_in_doc, footnote_location_filename, ...)
+         char *footid = (char *)SvPVutf8_nolen($arg);
+         char *docid = (char *)SvPVutf8_nolen($arg);
+         char *footnote_location_filename = (char *)SvPVutf8_nolen($arg);
+      PROTOTYPE: $$$$$$$
+      PREINIT:
+         CONVERTER *self;
+         char *multi_expanded_region = 0;
+      CODE:
+         self = get_sv_converter (converter_in,
+                                  "html_register_footnote");
+         if (self)
+           {
+             /* find footnote in XS.  First use number_in_doc, if not
+                effective, do a linear search */
+             /* TODO if not found, could determine an offset with
+                     number_in_doc and reuse it. */
+             /* TODO another possibility would be to setup a sorted array
+                when setting up the footnotes targets and use bsearch,
+                although it is not clear that it would be more efficient */
+             ELEMENT *footnote = 0;
+             ELEMENT *current;
+             HV *command_hv = (HV *) SvRV (command);
+             ELEMENT_LIST *footnotes
+                = &self->document->global_commands->footnotes;
+             if (number_in_doc - 1 < footnotes->number)
+               {
+                 ELEMENT *current = footnotes->list[number_in_doc - 1];
+                 if (command_hv == current->hv)
+                   footnote = current;
+                   /*
+                 else
+                   fprintf (stderr,
+                            "REMARK: footnote %d %s not directly found\n", 
+                            number_in_doc, footid);
+                    */
+               }
+             if (!footnote)
+               {
+                 size_t i;
+                 for (i = 0; i < footnotes->number; i++)
+                   {
+                     current = footnotes->list[i];
+                     if (current->hv == command_hv)
+                       {
+                         footnote = current;
+                         break;
+                       }
+                   }
+               }
+             if (footnote)
+               {
+              /*
+                 fprintf (stderr, "FFF %s\n", convert_to_texinfo (footnote));
+               */
+                  if (items > 7 && SvOK(ST(7)))
+                    multi_expanded_region = SvPVutf8_nolen (ST(7));
+                  html_register_footnote (self, footnote, footid, docid,
+                              number_in_doc, footnote_location_filename,
+                                                  multi_expanded_region);
+               }
+             else
+               {
+                 fprintf (stderr, "ERROR: footnote not found\n");
+               }
+           }
+
+SV *
+html_get_pending_footnotes (SV *converter_in)
+      PREINIT:
+         CONVERTER *self;
+         AV *pending_footnotes_av;
+      CODE:
+         self = get_sv_converter (converter_in,
+                                  "html_register_footnote");
+         pending_footnotes_av = newAV ();
+         if (self)
+           {
+             HTML_PENDING_FOOTNOTE_STACK *stack
+              = html_get_pending_footnotes (self);
+
+             build_pending_footnotes (pending_footnotes_av, stack);
+
+             destroy_pending_footnotes (stack);
+           }
+         RETVAL = newRV_noinc ((SV *) pending_footnotes_av);
+    OUTPUT:
+         RETVAL
+
+
 
 void
 html_merge_index_entries (SV *converter_in)
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.c 
b/tp/Texinfo/XS/convert/build_html_perl_state.c
index d1077a29e2..495187a2a5 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.c
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.c
@@ -1148,3 +1148,37 @@ build_replaced_substrings (NAMED_STRING_ELEMENT_LIST 
*replaced_substrings)
   return newRV_noinc ((SV *) hv);
 }
 
+void
+build_pending_footnotes (AV *av, HTML_PENDING_FOOTNOTE_STACK *stack)
+{
+  dTHX;
+
+  if (stack->top > 0)
+    {
+      size_t i;
+      for (i = 0; i < stack->top; i++)
+        {
+          HTML_PENDING_FOOTNOTE *pending_footnote = stack->stack[i];
+
+          AV *pending_footnote_av = newAV ();
+          SV *sv = newRV_noinc ((SV *) pending_footnote_av);
+          av_push (av, sv);
+
+          av_push (pending_footnote_av,
+                   newRV_inc ((SV *) pending_footnote->command->hv));
+          av_push (pending_footnote_av,
+                   newSVpv_utf8 (pending_footnote->footid, 0));
+          av_push (pending_footnote_av,
+                   newSVpv_utf8 (pending_footnote->docid, 0));
+          av_push (pending_footnote_av,
+                   newSViv (pending_footnote->number_in_doc));
+          av_push (pending_footnote_av,
+           newSVpv_utf8 (pending_footnote->footnote_location_filename, 0));
+          if (pending_footnote->multi_expanded_region)
+            av_push (pending_footnote_av,
+                     newSVpv_utf8 (pending_footnote->multi_expanded_region, 
0));
+          else
+            av_push (pending_footnote_av, newSV (0));
+        }
+    }
+}
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.h 
b/tp/Texinfo/XS/convert/build_html_perl_state.h
index 99f75c01ab..6d144ce8d9 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.h
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.h
@@ -36,4 +36,6 @@ SV *build_html_command_formatted_args
            (const HTML_ARGS_FORMATTED *args_formatted);
 SV *build_replaced_substrings (NAMED_STRING_ELEMENT_LIST *replaced_substrings);
 
+void build_pending_footnotes (AV *av, HTML_PENDING_FOOTNOTE_STACK *stack);
+
 #endif
diff --git a/tp/Texinfo/XS/convert/call_html_perl_function.c 
b/tp/Texinfo/XS/convert/call_html_perl_function.c
index 229a76dca6..9be480c296 100644
--- a/tp/Texinfo/XS/convert/call_html_perl_function.c
+++ b/tp/Texinfo/XS/convert/call_html_perl_function.c
@@ -33,6 +33,8 @@
 #include "text.h"
 #include "converter_types.h"
 #include "utils.h"
+/* for add_associated_info_integer */
+#include "extra.h"
 /* for newSVpv_utf8 build_texinfo_tree */
 #include "build_perl_info.h"
 #include "build_html_perl_state.h"
@@ -52,6 +54,59 @@ build_tree_to_build (ELEMENT_LIST *tree_to_build)
     }
 }
 
+/* in general we get information from perl by overriding functions setting
+   that information, but for shared_conversion the reference obtained
+   through a function call may be modified afterwards, so it is better to
+   set in perl information allowing to find which item may be modified and
+   get the information here when exiting from user-defined functions */
+void
+get_shared_conversion_state (CONVERTER *self)
+{
+  SV **shared_conversion_accessed_integers_sv;
+
+  dTHX;
+
+  shared_conversion_accessed_integers_sv = hv_fetch (self->hv,
+                       "shared_conversion_accessed_integers",
+                       strlen ("shared_conversion_accessed_integers"), 0);
+
+  if (shared_conversion_accessed_integers_sv)
+    {
+      SV **shared_conversion_state_sv;
+      I32 hv_number;
+      I32 i;
+
+      shared_conversion_state_sv = hv_fetch (self->hv,
+                       "shared_conversion_state",
+                       strlen ("shared_conversion_state"), 0);
+      HV *conversion_state_hv = (HV *) SvRV (*shared_conversion_state_sv);
+
+      HV *accessed_integers_v
+        = (HV *) SvRV (*shared_conversion_accessed_integers_sv);
+
+      hv_number = hv_iterinit (accessed_integers_v);
+
+      for (i = 0; i < hv_number; i++)
+        {
+          SV *ref_value_sv;
+          int value;
+          HE *next = hv_iternext (accessed_integers_v);
+          SV *selector_sv = hv_iterkeysv (next);
+          char *selector = (char *) SvPVutf8_nolen (selector_sv);
+
+          HE *conversion_state_he = hv_fetch_ent (conversion_state_hv,
+                                                  selector_sv, 0, 0);
+          ref_value_sv = HeVAL (conversion_state_he);
+          value = SvIV (SvRV (ref_value_sv));
+
+          add_associated_info_integer (&self->shared_conversion_state.integers,
+                                       selector, value);
+
+          hv_delete_ent (accessed_integers_v, selector_sv, 0, 0);
+        }
+    }
+}
+
 TARGET_FILENAME *
 call_file_id_setting_special_unit_target_file_name (CONVERTER *self,
                                       OUTPUT_UNIT *special_unit, char *target,
@@ -508,6 +563,8 @@ call_formatting_function_format_title_titlepage (CONVERTER 
*self)
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -564,6 +621,8 @@ call_formatting_function_format_footnotes_segment 
(CONVERTER *self)
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -620,6 +679,8 @@ call_formatting_function_format_footnotes_sequence 
(CONVERTER *self)
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -685,6 +746,8 @@ call_formatting_function_format_end_file (CONVERTER *self, 
char *filename,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -750,6 +813,8 @@ call_formatting_function_format_begin_file (CONVERTER 
*self, char *filename,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -814,6 +879,8 @@ call_formatting_function_format_translate_message 
(CONVERTER *self,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -878,6 +945,8 @@ call_formatting_function_format_navigation_header 
(CONVERTER *self,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -970,6 +1039,8 @@ call_formatting_function_format_heading_text (CONVERTER 
*self,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -1037,6 +1108,8 @@ call_formatting_function_format_element_footer (CONVERTER 
*self,
   FREETMPS;
   LEAVE;
 
+  get_shared_conversion_state (self);
+
   return result;
 }
 
@@ -1106,6 +1179,8 @@ call_types_conversion (CONVERTER *self, const enum 
element_type type,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 void
@@ -1165,6 +1240,8 @@ call_types_open (CONVERTER *self, const enum element_type 
type,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 void
@@ -1238,6 +1315,8 @@ call_commands_conversion (CONVERTER *self, const enum 
command_id cmd,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 void
@@ -1301,6 +1380,8 @@ call_commands_open (CONVERTER *self, const enum 
command_id cmd,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 void
@@ -1367,6 +1448,8 @@ call_output_units_conversion (CONVERTER *self,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 void
@@ -1431,6 +1514,8 @@ call_special_unit_body_formatting (CONVERTER *self,
 
   FREETMPS;
   LEAVE;
+
+  get_shared_conversion_state (self);
 }
 
 
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index 53f2340d6f..3ad00a902b 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -639,6 +639,76 @@ special_unit_info (CONVERTER *self, enum 
special_unit_info_type type,
   return self->special_unit_info[type][i];
 }
 
+void
+html_register_footnote (CONVERTER *self, const ELEMENT *command,
+     const char *footid, const char *docid, const int number_in_doc,
+     const char *footnote_location_filename, char *multi_expanded_region)
+{
+  HTML_PENDING_FOOTNOTE_STACK *stack;
+  HTML_PENDING_FOOTNOTE *pending_footnote;
+  KEY_PAIR *k = lookup_associated_info 
(&self->shared_conversion_state.integers,
+                                        "in_skipped_node_top");
+
+  if (k && k->integer == 1)
+    return;
+
+  stack = &self->pending_footnotes;
+
+  if (stack->top >= stack->space)
+    {
+      stack->stack
+        = realloc (stack->stack,
+                   (stack->space += 5) * sizeof (HTML_PENDING_FOOTNOTE *));
+    }
+  pending_footnote = (HTML_PENDING_FOOTNOTE *)
+                      malloc (sizeof (HTML_PENDING_FOOTNOTE));
+  stack->stack[stack->top] = pending_footnote;
+  stack->top++;
+
+  pending_footnote->command = command;
+  pending_footnote->footid = strdup (footid);
+  pending_footnote->docid = strdup (docid);
+  pending_footnote->number_in_doc = number_in_doc;
+  pending_footnote->footnote_location_filename
+       = strdup (footnote_location_filename);
+
+  if (multi_expanded_region)
+    pending_footnote->multi_expanded_region = strdup (multi_expanded_region);
+  else
+    pending_footnote->multi_expanded_region = 0;
+}
+
+HTML_PENDING_FOOTNOTE_STACK *
+html_get_pending_footnotes (CONVERTER *self)
+{
+  HTML_PENDING_FOOTNOTE_STACK *stack = (HTML_PENDING_FOOTNOTE_STACK *)
+     malloc (sizeof (HTML_PENDING_FOOTNOTE_STACK));
+
+  stack->top = self->pending_footnotes.top;
+  stack->space = self->pending_footnotes.space;
+  stack->stack = self->pending_footnotes.stack;
+
+  memset (&self->pending_footnotes, 0, sizeof (HTML_PENDING_FOOTNOTE_STACK));
+
+  return stack;
+}
+
+void
+destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack)
+{
+  int i;
+  for (i = 0; i < stack->top; i++)
+    {
+      free (stack->stack[i]->multi_expanded_region);
+      free (stack->stack[i]->footid);
+      free (stack->stack[i]->docid);
+      free (stack->stack[i]->footnote_location_filename);
+      free (stack->stack[i]);
+    }
+  free (stack->stack);
+  free (stack);
+}
+
 void
 html_register_opened_section_level (CONVERTER *self, int level,
                                     const char *close_string)
@@ -2173,10 +2243,10 @@ html_command_text (CONVERTER *self, ELEMENT *command,
 static int
 compare_page_name_number (const void *a, const void *b)
 {
-  const PAGE_NAME_NUMBER *css_a = (const PAGE_NAME_NUMBER *) a;
-  const PAGE_NAME_NUMBER *css_b = (const PAGE_NAME_NUMBER *) b;
+  const PAGE_NAME_NUMBER *pnn_a = (const PAGE_NAME_NUMBER *) a;
+  const PAGE_NAME_NUMBER *pnn_b = (const PAGE_NAME_NUMBER *) b;
 
-  return strcmp (css_a->page_name, css_b->page_name);
+  return strcmp (pnn_a->page_name, pnn_b->page_name);
 }
 
 size_t
diff --git a/tp/Texinfo/XS/convert/convert_html.h 
b/tp/Texinfo/XS/convert/convert_html.h
index 9194726a80..eda6156699 100644
--- a/tp/Texinfo/XS/convert/convert_html.h
+++ b/tp/Texinfo/XS/convert/convert_html.h
@@ -38,6 +38,12 @@ char *html_attribute_class (CONVERTER *self, const char 
*element,
 STRING_LIST *html_get_css_elements_classes (CONVERTER *self,
                                             const char *filename);
 
+void html_register_footnote (CONVERTER *self, const ELEMENT *command,
+     const char *footid, const char *docid, const int number_in_doc,
+     const char *footnote_location_filename, char *multi_expanded_region);
+HTML_PENDING_FOOTNOTE_STACK *html_get_pending_footnotes (CONVERTER *self);
+void destroy_pending_footnotes (HTML_PENDING_FOOTNOTE_STACK *stack);
+
 void html_merge_index_entries (CONVERTER *self);
 
 void html_prepare_conversion_units (CONVERTER *self,
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index b07e6d1fe3..34f0b69e44 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -231,6 +231,21 @@ typedef struct HTML_TARGET_LIST {
     HTML_TARGET *list;
 } HTML_TARGET_LIST;
 
+typedef struct HTML_SHARED_CONVERSION_STATE {
+    int explained_commands; /* explained_commands->{char $cmdname}->{char 
$normalized_type}
+                               = ELEMENT */
+    int element_explanation_content; /* element_explanation_content->{ELEMENT 
$command}
+                                = ELEMENT */
+    int footnote_id_numbers; /* footnote_id_numbers->{char $footid} = int */
+    /* probably not useful, directly use expanded formats in the converter 
+       needed in perl as expanded formats are accessed per format in the API
+    int expanded_format_raw;
+     */
+    int formatted_index_entries; /* formatted_index_entries->{INDEX_ENTRY 
$index_entry_ref} = 1, ++ */
+    int formatted_nodedescriptions; /* formatted_nodedescriptions->{ELEMENT 
$node_description} = 1, ++ */
+    ASSOCIATED_INFO integers;
+} HTML_SHARED_CONVERSION_STATE;
+
 typedef struct MERGED_INDEX {
     char *name;
     INDEX_ENTRY *index_entries;
@@ -480,6 +495,21 @@ typedef struct SPECIAL_UNIT_BODY_FORMATTING {
             TEXT *result);
 } SPECIAL_UNIT_BODY_FORMATTING;
 
+typedef struct HTML_PENDING_FOOTNOTE {
+    const ELEMENT *command;
+    char *footid;
+    char *docid;
+    int number_in_doc;
+    char *footnote_location_filename;
+    char *multi_expanded_region;
+} HTML_PENDING_FOOTNOTE;
+
+typedef struct HTML_PENDING_FOOTNOTE_STACK {
+    size_t top;
+    size_t space;
+    HTML_PENDING_FOOTNOTE **stack;
+} HTML_PENDING_FOOTNOTE_STACK;
+
 typedef struct CONVERTER {
     int converter_descriptor;
   /* perl converter. This should be HV *hv,
@@ -591,6 +621,8 @@ typedef struct CONVERTER {
     STRING_STACK pending_closes;
     CURRENT_FILE_INFO current_filename;
     ELEMENT_LIST referred_command_stack;
+    HTML_SHARED_CONVERSION_STATE shared_conversion_state;
+    HTML_PENDING_FOOTNOTE_STACK pending_footnotes;
     /* state common with perl converter, not transmitted to perl */
     int use_unicode_text;
 } CONVERTER;
diff --git a/tp/Texinfo/XS/main/extra.c b/tp/Texinfo/XS/main/extra.c
index 3aa47e7403..f5dd58407d 100644
--- a/tp/Texinfo/XS/main/extra.c
+++ b/tp/Texinfo/XS/main/extra.c
@@ -160,6 +160,13 @@ add_info_string_dup (ELEMENT *e, char *key, char *value)
   k->string = strdup (value);
 }
 
+void
+add_associated_info_integer (ASSOCIATED_INFO *a, char *key, int value)
+{
+  KEY_PAIR *k = get_associated_info_key (a, key, extra_integer);
+  k->integer = value;
+}
+
 void
 add_extra_integer (ELEMENT *e, char *key, long value)
 {
diff --git a/tp/Texinfo/XS/main/extra.h b/tp/Texinfo/XS/main/extra.h
index 22eeafc5d4..d8daa15c5a 100644
--- a/tp/Texinfo/XS/main/extra.h
+++ b/tp/Texinfo/XS/main/extra.h
@@ -32,6 +32,7 @@ void add_extra_integer (ELEMENT *e, char *key, long value);
 void add_info_string (ELEMENT *e, char *key, char *value);
 void add_info_string_dup (ELEMENT *e, char *key, char *value);
 void add_info_element_oot (ELEMENT *e, char *key, ELEMENT *value);
+void add_associated_info_integer (ASSOCIATED_INFO *a, char *key, int value);
 KEY_PAIR *lookup_extra (const ELEMENT *e, char *key);
 KEY_PAIR *lookup_info (const ELEMENT *e, char *key);
 ELEMENT *lookup_extra_element (const ELEMENT *e, char *key);



reply via email to

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