texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Wed, 22 Nov 2023 16:10:33 -0500 (EST)

branch: master
commit 1b0c07978385fef922d83f677cbfc390f81564f7
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Nov 22 22:09:16 2023 +0100

    * tp/Texinfo/Convert/HTML.pm (_convert_special_unit_type): rename
    element as output_unit.
    
    * tp/Texinfo/XS/convert/convert_html.c (enum
    count_elements_in_filename_type, count_elements_in_filename):
    implement count_elements_in_filename.
    
    * tp/Texinfo/Convert/HTML.pm (_XS_converter_initialize)
    (converter_initialize), tp/Texinfo/XS/convert/ConvertXS.xs
    (html_converter_initialize_sv),
    tp/Texinfo/XS/convert/get_html_perl_info.c
    (html_converter_initialize_sv): get special_unit_body formatting
    references from perl.
    
    * tp/Texinfo/XS/convert/convert_html.c
    (OUTPUT_UNIT_INTERNAL_CONVERSION, output_unit_conversion_external)
    (special_unit_body_formatting_external)
    (register_output_unit_conversion_function)
    (register_special_unit_body_formatting_function)
    (html_converter_initialize, convert_output_unit),
    tp/Texinfo/XS/main/converter_types.h (OUTPUT_UNIT_CONVERSION_FUNCTION)
    (SPECIAL_UNIT_BODY_FORMATTING, CONVERTER): add special unit
    body formatting function setup and the possibilty to convert output
    unit using a C function.
    
    * tp/Texinfo/XS/convert/convert_html.c (convert_special_unit_type),
    tp/Texinfo/XS/convert/call_html_perl_function.c
    (call_formatting_function_format_navigation_header)
    (call_special_unit_body_formatting),
    tp/Texinfo/XS/convert/get_html_perl_info.c
    (html_get_button_specification_list),
    tp/Texinfo/XS/main/converter_types.h (enum button_specification_type)
    (enum button_information_type, BUTTON_SPECIFICATION_INFO)
    (BUTTON_SPECIFICATION, BUTTON_SPECIFICATION_LIST),
    tp/Texinfo/XS/main/document_types.h,
    tp/maintain/regenerate_C_options_info.pl: add preliminary types for
    buttons specifications, declare struct OPTIONS in document_types.h and
    converter_types.h to avoid an interdependency between those files and
    included files and options_types.h. Get buttons specifications from
    perl. Add functions to call format_navigation_header and special unit
    body formatting from C.
    Incomplete implementation of convert_special_unit_type.
---
 ChangeLog                                       |  45 +++++
 tp/Texinfo/Convert/HTML.pm                      |  23 +--
 tp/Texinfo/XS/convert/ConvertXS.xs              |   2 +-
 tp/Texinfo/XS/convert/build_html_perl_state.h   |   1 +
 tp/Texinfo/XS/convert/call_html_perl_function.c | 133 ++++++++++++++
 tp/Texinfo/XS/convert/call_html_perl_function.h |   9 +
 tp/Texinfo/XS/convert/convert_html.c            | 225 ++++++++++++++++++++++--
 tp/Texinfo/XS/convert/get_html_perl_info.c      |  44 ++++-
 tp/Texinfo/XS/convert/get_html_perl_info.h      |   6 +-
 tp/Texinfo/XS/main/converter_types.h            |  87 ++++++++-
 tp/Texinfo/XS/main/document_types.h             |   8 +-
 tp/Texinfo/options_data.txt                     |  16 +-
 tp/maintain/regenerate_C_options_info.pl        |  35 +++-
 13 files changed, 588 insertions(+), 46 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b70a684f15..b4198cd401 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,51 @@
        configure.ac and propagate to Makefile.am, so it is more clear what
        "archlibexp" and "privlibexp" from the Perl conf are being used for.
 
+2023-11-22  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/HTML.pm (_convert_special_unit_type): rename
+       element as output_unit.
+
+       * tp/Texinfo/XS/convert/convert_html.c (enum
+       count_elements_in_filename_type, count_elements_in_filename):
+       implement count_elements_in_filename.
+
+       * tp/Texinfo/Convert/HTML.pm (_XS_converter_initialize)
+       (converter_initialize), tp/Texinfo/XS/convert/ConvertXS.xs
+       (html_converter_initialize_sv),
+       tp/Texinfo/XS/convert/get_html_perl_info.c
+       (html_converter_initialize_sv): get special_unit_body formatting
+       references from perl.
+
+       * tp/Texinfo/XS/convert/convert_html.c
+       (OUTPUT_UNIT_INTERNAL_CONVERSION, output_unit_conversion_external)
+       (special_unit_body_formatting_external)
+       (register_output_unit_conversion_function)
+       (register_special_unit_body_formatting_function)
+       (html_converter_initialize, convert_output_unit),
+       tp/Texinfo/XS/main/converter_types.h (OUTPUT_UNIT_CONVERSION_FUNCTION)
+       (SPECIAL_UNIT_BODY_FORMATTING, CONVERTER): add special unit
+       body formatting function setup and the possibilty to convert output
+       unit using a C function.  
+
+       * tp/Texinfo/XS/convert/convert_html.c (convert_special_unit_type),
+       tp/Texinfo/XS/convert/call_html_perl_function.c
+       (call_formatting_function_format_navigation_header)
+       (call_special_unit_body_formatting),
+       tp/Texinfo/XS/convert/get_html_perl_info.c
+       (html_get_button_specification_list),
+       tp/Texinfo/XS/main/converter_types.h (enum button_specification_type)
+       (enum button_information_type, BUTTON_SPECIFICATION_INFO)
+       (BUTTON_SPECIFICATION, BUTTON_SPECIFICATION_LIST),
+       tp/Texinfo/XS/main/document_types.h,
+       tp/maintain/regenerate_C_options_info.pl: add preliminary types for
+       buttons specifications, declare struct OPTIONS in document_types.h and
+       converter_types.h to avoid an interdependency between those files and
+       included files and options_types.h. Get buttons specifications from
+       perl. Add functions to call format_navigation_header and special unit
+       body formatting from C.
+       Incomplete implementation of convert_special_unit_type.
+
 2023-11-22  Patrice Dumas  <pertusus@free.fr>
 
        * tp/maintain/setup_converters_code_tables.pl: set ENV{'TEXINFO_XS'} =
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index 8e59f103d0..0c378c4d6f 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -7379,12 +7379,12 @@ sub _default_format_title_titlepage($)
   return $result;
 }
 
-# Function for converting special elements
+# Function for converting special output units
 sub _convert_special_unit_type($$$$)
 {
   my $self = shift;
   my $type = shift;
-  my $element = shift;
+  my $output_unit = shift;
   my $content = shift;
 
   $content = '' if (!defined($content));
@@ -7395,13 +7395,13 @@ sub _convert_special_unit_type($$$$)
 
   my $result = '';
 
-  my $special_unit_variety = $element->{'special_unit_variety'};
+  my $special_unit_variety = $output_unit->{'special_unit_variety'};
   my $closed_strings = $self->close_registered_sections_level(0);
   $result .= join('', @{$closed_strings});
 
   my $special_unit_body
     .= &{$self->special_unit_body_formatting($special_unit_variety)}($self,
-                                          $special_unit_variety, $element);
+                                      $special_unit_variety, $output_unit);
 
   # This may happen with footnotes in regions that are not expanded,
   # like @copying or @titlepage
@@ -7409,7 +7409,7 @@ sub _convert_special_unit_type($$$$)
     return '';
   }
 
-  my $unit_command = $element->{'unit_command'};
+  my $unit_command = $output_unit->{'unit_command'};
 
   my $id = $self->command_id($unit_command);
   my $class_base
@@ -7422,7 +7422,7 @@ sub _convert_special_unit_type($$$$)
   if ($self->get_conf('HEADERS')
       # first in page
       or $self->count_elements_in_filename('current',
-                  $element->{'unit_filename'}) == 1) {
+                  $output_unit->{'unit_filename'}) == 1) {
     $result .= &{$self->formatting_function('format_navigation_header')}($self,
                      $self->get_conf('MISC_BUTTONS'), undef, $unit_command);
   }
@@ -7436,8 +7436,8 @@ sub _convert_special_unit_type($$$$)
 
 
   $result .= $special_unit_body . '</div>';
-  $result .= &{$self->formatting_function('format_element_footer')}($self, 
$type,
-                                               $element, $content, 
$unit_command);
+  $result .= &{$self->formatting_function('format_element_footer')}($self,
+                                 $type, $output_unit, $content, $unit_command);
   return $result;
 }
 
@@ -7497,7 +7497,7 @@ sub _convert_unit_type($$$$)
 
 $default_output_units_conversion{'unit'} = \&_convert_unit_type;
 
-# for output units and special elements
+# for output units, both normal and special
 sub _default_format_element_footer($$$$;$)
 {
   my $self = shift;
@@ -8058,7 +8058,7 @@ my %special_characters = (
   'non_breaking_space' => [undef, '00A0'],
 );
 
-sub _XS_converter_initialize($$$$$$$$$$)
+sub _XS_converter_initialize($$$$$$$$$$$)
 {
 }
 
@@ -8560,7 +8560,8 @@ sub converter_initialize($)
                              \%default_types_open,
                              \%default_types_conversion,
                              \%default_css_string_types_conversion,
-                             \%default_output_units_conversion);
+                             \%default_output_units_conversion,
+                             \%defaults_format_special_unit_body_contents);
     delete $self->{'sorted_special_unit_varieties'};
     delete $self->{'simplified_special_unit_info'};
   }
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 63941151f9..5a31e49e3a 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -195,7 +195,7 @@ void
 html_format_init ()
 
 int
-html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_css_string_commands_conversion, SV *default_types_open, SV 
*default_types_conversion, SV *default_css_string_types_conversion, SV 
*default_output_units_conversion)
+html_converter_initialize_sv (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_css_string_commands_conversion, SV *default_types_open, SV 
*default_types_conversion, SV *default_css_string_types_conversion, SV 
*default_output_units_conversion, SV *default_special_unit_body)
 
 void
 html_initialize_output_state (SV *converter_in, char *context)
diff --git a/tp/Texinfo/XS/convert/build_html_perl_state.h 
b/tp/Texinfo/XS/convert/build_html_perl_state.h
index 09800f5358..99f75c01ab 100644
--- a/tp/Texinfo/XS/convert/build_html_perl_state.h
+++ b/tp/Texinfo/XS/convert/build_html_perl_state.h
@@ -35,4 +35,5 @@ SV *build_html_formatting_state (CONVERTER *converter, 
unsigned long flags);
 SV *build_html_command_formatted_args
            (const HTML_ARGS_FORMATTED *args_formatted);
 SV *build_replaced_substrings (NAMED_STRING_ELEMENT_LIST *replaced_substrings);
+
 #endif
diff --git a/tp/Texinfo/XS/convert/call_html_perl_function.c 
b/tp/Texinfo/XS/convert/call_html_perl_function.c
index 2ff735d593..6c281c97aa 100644
--- a/tp/Texinfo/XS/convert/call_html_perl_function.c
+++ b/tp/Texinfo/XS/convert/call_html_perl_function.c
@@ -31,6 +31,7 @@
 #undef context
 
 #include "text.h"
+#include "converter_types.h"
 #include "utils.h"
 /* for newSVpv_utf8 build_texinfo_tree */
 #include "build_perl_info.h"
@@ -746,6 +747,70 @@ call_formatting_function_format_translate_message 
(CONVERTER *self,
   return result;
 }
 
+char *
+call_formatting_function_format_navigation_header (CONVERTER *self,
+                                  const BUTTON_SPECIFICATION_LIST *buttons,
+                                  const char *cmdname,
+                                  const ELEMENT *element)
+{
+  int count;
+  char *result = 0;
+  char *result_ret;
+  STRLEN len;
+  SV *result_sv;
+  SV *formatting_reference_sv;
+
+  dTHX;
+
+  if (!self->hv)
+    return 0;
+
+  formatting_reference_sv
+    = self->formatting_references[
+         FR_format_navigation_header].sv_reference;
+
+  if (self->modified_state)
+    {
+      build_html_formatting_state (self, self->modified_state);
+      self->modified_state = 0;
+    }
+
+  dSP;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  EXTEND(SP, 4);
+
+  PUSHs(sv_2mortal (newRV_inc (self->hv)));
+  PUSHs(sv_2mortal (newRV_inc (buttons->av)));
+  PUSHs(sv_2mortal (newSVpv (cmdname, 0)));
+  PUSHs(sv_2mortal (newRV_inc (element->hv)));
+  PUTBACK;
+
+  count = call_sv (formatting_reference_sv,
+                   G_SCALAR);
+
+  SPAGAIN;
+
+  if (count != 1)
+    croak("format_navigation_header should return 1 item\n");
+
+  result_sv = POPs;
+  result_ret = SvPVutf8 (result_sv, len);
+  result = strdup (result_ret);
+
+  PUTBACK;
+
+  FREETMPS;
+  LEAVE;
+
+  return result;
+}
+
+
+
 
 
 void
@@ -1093,4 +1158,72 @@ call_output_units_conversion (CONVERTER *self,
   LEAVE;
 }
 
+void
+call_special_unit_body_formatting (CONVERTER *self,
+                              const size_t special_unit_number,
+                              const char *special_unit_variety,
+                              const OUTPUT_UNIT *output_unit,
+                              TEXT *result)
+{
+  int count;
+  char *result_ret;
+  STRLEN len;
+  SV *result_sv;
+  SV *formatting_reference_sv;
+
+  dTHX;
+
+  if (!self->hv)
+    return;
+
+  if (self->tree_to_build)
+    {
+      build_texinfo_tree (self->tree_to_build);
+      self->tree_to_build = 0;
+    }
+
+  formatting_reference_sv
+     = self->special_unit_body[special_unit_number -1].sv_reference;
+
+  if (self->modified_state)
+    {
+      build_html_formatting_state (self, self->modified_state);
+      self->modified_state = 0;
+    }
+
+  dSP;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  EXTEND(SP, 4);
+
+  PUSHs(sv_2mortal (newRV_inc (self->hv)));
+  PUSHs(sv_2mortal (newSVpv (special_unit_variety, 0)));
+  PUSHs(sv_2mortal (newRV_inc (output_unit->hv)));
+  PUTBACK;
+
+  count = call_sv (formatting_reference_sv,
+                   G_SCALAR);
+
+  SPAGAIN;
+
+  if (count != 1)
+    croak("special_unit_body_formatting should return 1 item\n");
+
+
+  result_sv = POPs;
+  /* it is encoded using non strict encoding, so the UTF-8 could be invalid.
+     It could be possible to add a wrapper in perl that encode to UTF-8,
+     but probably not worth it */
+  result_ret = SvPVutf8 (result_sv, len);
+  text_append (result, result_ret);
+
+  PUTBACK;
+
+  FREETMPS;
+  LEAVE;
+}
+
 
diff --git a/tp/Texinfo/XS/convert/call_html_perl_function.h 
b/tp/Texinfo/XS/convert/call_html_perl_function.h
index 5d195a1104..b1a82a437c 100644
--- a/tp/Texinfo/XS/convert/call_html_perl_function.h
+++ b/tp/Texinfo/XS/convert/call_html_perl_function.h
@@ -46,6 +46,10 @@ char *call_formatting_function_format_end_file (CONVERTER 
*self,
 char *call_formatting_function_format_begin_file (CONVERTER *self,
                                                  char *filename,
                                          const OUTPUT_UNIT *output_unit);
+char *call_formatting_function_format_navigation_header (CONVERTER *self,
+                                  const BUTTON_SPECIFICATION_LIST *buttons,
+                                  const char *cmdname,
+                                  const ELEMENT *element);
 
 void call_types_conversion (CONVERTER *self, const enum element_type type,
                        const FORMATTING_REFERENCE *formatting_reference,
@@ -64,6 +68,11 @@ void call_output_units_conversion (CONVERTER *self,
                                const enum output_unit_type unit_type,
                         const OUTPUT_UNIT *output_unit, const char *content,
                         TEXT *result);
+void call_special_unit_body_formatting (CONVERTER *self,
+                              const size_t special_unit_number,
+                              const char *special_unit_variety,
+                              const OUTPUT_UNIT *output_unit,
+                              TEXT *result);
 
 char *call_formatting_function_format_translate_message (CONVERTER *self,
                                   const char *message, const char *lang,
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index c29318ac5b..4217cc4567 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -47,6 +47,11 @@
 #include "unicode.h"
 #include "convert_html.h"
 
+enum count_elements_in_filename_type {
+  CEFT_total,
+  CEFT_remaining,
+  CEFT_current,
+};
 
 typedef struct ROOT_AND_UNIT {
     const OUTPUT_UNIT *output_unit;
@@ -65,6 +70,14 @@ typedef struct TYPE_INTERNAL_CONVERSION {
                               TEXT *result);
 } TYPE_INTERNAL_CONVERSION;
 
+typedef struct OUTPUT_UNIT_INTERNAL_CONVERSION {
+    enum output_unit_type type;
+    void (* output_unit_conversion) (CONVERTER *self,
+                        const enum output_unit_type unit_type,
+                        const OUTPUT_UNIT *output_unit, const char *content,
+                        TEXT *result);
+} OUTPUT_UNIT_INTERNAL_CONVERSION;
+
 char *html_global_unit_direction_names[] = {
   #define hgdt_name(name) #name,
    HTML_GLOBAL_DIRECTIONS_LIST
@@ -557,6 +570,23 @@ in_verbatim (CONVERTER *self)
   return top_document_ctx->verbatim_ctx;
 }
 
+size_t
+count_elements_in_filename (CONVERTER *self,
+                 enum count_elements_in_filename_type type,
+                 size_t file_number)
+{
+  size_t i = file_number - 1;
+  FILE_NAME_PATH_COUNTER *file_counter
+            = &self->output_unit_files.list[i];
+
+  if (type == CEFT_total)
+    return file_counter->elements_in_file_count;
+  else if (type == CEFT_remaining)
+    return file_counter->counter;
+  else /* if (type == CEFT_current) */
+    return file_counter->elements_in_file_count - file_counter->counter;
+}
+
 ELEMENT *
 special_unit_info_tree (CONVERTER *self, enum special_unit_info_tree type,
                         char *special_unit_variety)
@@ -3056,6 +3086,95 @@ static TYPE_INTERNAL_CONVERSION 
types_internal_conversion_table[] = {
   {0, 0},
 };
 
+void
+convert_special_unit_type (CONVERTER *self,
+                        const enum output_unit_type unit_type,
+                        const OUTPUT_UNIT *output_unit, const char *content,
+                        TEXT *result)
+{
+  size_t number;
+  TEXT special_unit_body;
+  ELEMENT *unit_command;
+  char *id;
+  char *class_base;
+  char *attribute_class;
+  char *class;
+  STRING_LIST *classes;
+
+  char *special_unit_variety;
+  STRING_LIST *closed_strings;
+  size_t file_index;
+
+  if (in_string (self))
+    return;
+
+  special_unit_variety = output_unit->special_unit_variety;
+  number = find_string (&self->special_unit_varieties,
+                        special_unit_variety);
+
+  closed_strings = html_close_registered_sections_level (self, 0);
+
+  if (closed_strings->number)
+    {
+      int i;
+      for (i = 0; i < closed_strings->number; i++)
+        {
+          text_append (result, closed_strings->list[i]);
+        }
+    }
+  text_init (&special_unit_body);
+  text_append (&special_unit_body, "");
+
+  (*self->special_unit_body_formatting[number -1].special_unit_body_formatting)
+         (self, number, special_unit_variety, output_unit, &special_unit_body);
+
+  /* This may happen with footnotes in regions that are not expanded,
+     like @copying or @titlepage */
+  if (special_unit_body.end == 0)
+    return;
+
+  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+  memset (classes, 0, sizeof (STRING_LIST));
+
+  unit_command = output_unit->unit_command;
+  id = html_command_id (self, unit_command);
+  class_base = special_unit_info (self, SUI_type_class,
+                                  special_unit_variety);
+  xasprintf (&class, "element-%s", class_base);
+
+  add_string (class, classes);
+  free (class);
+  attribute_class = html_attribute_class (self, "div", classes);
+  destroy_strings_list (classes);
+
+  text_append (result, attribute_class);
+  free (attribute_class);
+
+  if (id && strlen (id))
+    text_printf (result, " id=\"%s\"", id);
+  text_append (result, ">\n");
+
+  file_index = self->special_unit_file_indices[output_unit->index];
+  if (self->conf->HEADERS > 0
+      /* first in page */
+ || (count_elements_in_filename (self, CEFT_current, file_index +1) == 1))
+    {
+      char *navigation_header =
+        call_formatting_function_format_navigation_header (self,
+                             self->conf->MISC_BUTTONS, 0, unit_command);
+      text_append (result, navigation_header);
+      free (navigation_header);
+    }
+  /* TODO */
+}
+
+static OUTPUT_UNIT_INTERNAL_CONVERSION 
output_units_internal_conversion_table[] = {
+   /*
+  {OU_special_unit, &convert_special_unit_type},
+    */
+  {0, 0},
+};
+
 static void
 command_conversion_external (CONVERTER *self, const enum command_id cmd,
                     const ELEMENT *element,
@@ -3113,6 +3232,30 @@ type_open (CONVERTER *self, enum element_type type, 
const ELEMENT *element,
     call_types_open (self, type, element, result);
 }
 
+static void
+output_unit_conversion_external (CONVERTER *self,
+                        const enum output_unit_type unit_type,
+                        const OUTPUT_UNIT *output_unit, const char *content,
+                        TEXT *result)
+{
+  if (self->output_units_conversion[unit_type].status > 0)
+    call_output_units_conversion (self, unit_type, output_unit, content,
+                                  result);
+}
+
+static void
+special_unit_body_formatting_external (CONVERTER *self,
+                               const size_t special_unit_number,
+                               const char *special_unit_variety,
+                               const OUTPUT_UNIT *output_unit,
+                               TEXT *result)
+{
+  if (self->special_unit_body[special_unit_number -1].status > 0)
+    call_special_unit_body_formatting (self, special_unit_number,
+                                       special_unit_variety,
+                                       output_unit, result);
+}
+
 static void
 push_html_formatting_context (HTML_FORMATTING_CONTEXT_STACK *stack,
                               char *context_name)
@@ -3338,6 +3481,41 @@ register_command_conversion_function 
(COMMAND_CONVERSION_FUNCTION *result,
     }
 }
 
+void
+register_output_unit_conversion_function
+                                  (OUTPUT_UNIT_CONVERSION_FUNCTION *result,
+                                   enum output_unit_type type,
+                                   FORMATTING_REFERENCE *formatting_reference)
+{
+  if (formatting_reference->status > 0)
+    {
+      result->status = formatting_reference->status;
+      if (formatting_reference->status != FRS_status_ignored)
+        {
+          result->output_unit_conversion = &output_unit_conversion_external;
+          result->formatting_reference = formatting_reference;
+        }
+    }
+}
+
+void
+register_special_unit_body_formatting_function
+                                  (SPECIAL_UNIT_BODY_FORMATTING *result,
+                                   const char *special_unit_variety,
+                                   FORMATTING_REFERENCE *formatting_reference)
+{
+  if (formatting_reference->status > 0)
+    {
+      result->status = formatting_reference->status;
+      if (formatting_reference->status != FRS_status_ignored)
+        {
+          result->special_unit_body_formatting
+               = &special_unit_body_formatting_external;
+          result->formatting_reference = formatting_reference;
+        }
+    }
+}
+
 /* most of the initialization is done by html_converter_initialize_sv
    in get_perl_info, the initialization that do not require information
    directly from perl data is done here.  This is called after information
@@ -3457,6 +3635,38 @@ html_converter_initialize (CONVERTER *self)
              &self->css_string_commands_conversion[i]);
     }
 
+  for (i = 0; i < OU_special_unit+1; i++)
+    {
+      register_output_unit_conversion_function
+                                  (&self->output_unit_conversion_function[i],
+                                        i, &self->output_units_conversion[i]);
+    }
+
+  for (i = 0;
+     output_units_internal_conversion_table[i].output_unit_conversion; i++)
+    {
+      enum output_unit_type type
+           = output_units_internal_conversion_table[i].type;
+      OUTPUT_UNIT_CONVERSION_FUNCTION *output_unit_conversion
+         = &self->output_unit_conversion_function[type];
+      if (output_unit_conversion->status == FRS_status_default_set)
+        {
+          output_unit_conversion->formatting_reference = 0;
+          output_unit_conversion->status = FRS_status_internal;
+          output_unit_conversion->output_unit_conversion
+           = output_units_internal_conversion_table[i].output_unit_conversion;
+        }
+    }
+
+  self->special_unit_body_formatting = (SPECIAL_UNIT_BODY_FORMATTING *)
+   malloc (nr_special_units * sizeof (SPECIAL_UNIT_BODY_FORMATTING));
+
+  for (i = 0; i < nr_special_units; i++)
+    {
+      register_special_unit_body_formatting_function
+                                  (&self->special_unit_body_formatting[i],
+          self->special_unit_varieties.list[i], &self->special_unit_body[i]);
+    }
 }
 
 /* called in the end of html_converter_prepare_output_sv */
@@ -4936,18 +5146,6 @@ convert_to_html_internal (CONVERTER *self, const ELEMENT 
*element,
 }
 #undef ADD
 
-static void
-output_unit_conversion (CONVERTER *self, const enum output_unit_type unit_type,
-                        const OUTPUT_UNIT *output_unit, const char *content,
-                        TEXT *result)
-{
-  /* TODO call a C function if status is FRS_status_default_set
-     maybe putting function references in an array */
-  if (self->output_units_conversion[unit_type].status > 0)
-    call_output_units_conversion (self, unit_type, output_unit, content,
-                                  result);
-}
-
 void
 convert_output_unit (CONVERTER *self, const OUTPUT_UNIT *output_unit,
                      char *explanation, TEXT *result)
@@ -5000,7 +5198,8 @@ convert_output_unit (CONVERTER *self, const OUTPUT_UNIT 
*output_unit,
 
   if (self->output_units_conversion[unit_type].status)
     {
-      output_unit_conversion (self, unit_type, output_unit,
+  (*(self->output_unit_conversion_function[unit_type].output_unit_conversion))
+                             (self, unit_type, output_unit,
                               content_formatted.text, result);
     }
    else
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.c 
b/tp/Texinfo/XS/convert/get_html_perl_info.c
index d85dec558b..11ed594d98 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.c
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.c
@@ -126,7 +126,8 @@ html_converter_initialize_sv (SV *converter_sv,
                               SV *default_types_open,
                               SV *default_types_conversion,
                               SV *default_css_string_types_conversion,
-                              SV *default_output_units_conversion)
+                              SV *default_output_units_conversion,
+                              SV *default_special_unit_body)
 {
   int i;
   HV *converter_hv;
@@ -363,9 +364,13 @@ html_converter_initialize_sv (SV *converter_sv,
 
   if (sorted_special_unit_varieties_sv)
     {
+      int i;
       enum special_unit_info_type j;
       SV **special_unit_info_sv;
       HV *special_unit_info_hv;
+      SV **special_unit_body_sv;
+      HV *special_unit_body_hv;
+      HV *default_special_unit_body_hv;
 
       STRING_LIST *special_unit_varieties = &converter->special_unit_varieties;
       if (sorted_special_unit_varieties_sv)
@@ -423,6 +428,26 @@ html_converter_initialize_sv (SV *converter_sv,
                 }
             }
         }
+
+      converter->special_unit_body = (FORMATTING_REFERENCE *)
+       malloc (special_unit_varieties->number * sizeof (FORMATTING_REFERENCE));
+      memset (converter->special_unit_body, 0,
+              special_unit_varieties->number * sizeof (FORMATTING_REFERENCE));
+
+      FETCH(special_unit_body)
+      special_unit_body_hv = (HV *)SvRV (*special_unit_body_sv);
+      default_special_unit_body_hv = (HV *)SvRV (default_special_unit_body);
+
+      for (i = 0; i < special_unit_varieties->number; i++)
+        {
+          char *variety_name = special_unit_varieties->list[i];
+          FORMATTING_REFERENCE *special_unit_body_formatting_reference
+            = &converter->special_unit_body[i];
+          register_formatting_reference_with_default ("special_unit_body",
+            special_unit_body_formatting_reference, variety_name,
+            default_special_unit_body_hv,
+            special_unit_body_hv);
+        }
     }
 
   FETCH(code_types)
@@ -800,3 +825,20 @@ html_converter_prepare_output_sv (SV *converter_sv, 
CONVERTER *converter)
 
 #undef FETCH
 
+BUTTON_SPECIFICATION_LIST *
+html_get_button_specification_list (SV *buttons_sv)
+{
+  BUTTON_SPECIFICATION_LIST *result;
+
+  dTHX;
+
+  result = (BUTTON_SPECIFICATION_LIST *)
+            malloc (sizeof (BUTTON_SPECIFICATION_LIST));
+
+  result->av = (AV *)SvRV (buttons_sv);
+
+  /* TODO do C structures to be able to call C functions */
+
+  return result;
+}
+
diff --git a/tp/Texinfo/XS/convert/get_html_perl_info.h 
b/tp/Texinfo/XS/convert/get_html_perl_info.h
index 5340fb8cc7..4ce8056425 100644
--- a/tp/Texinfo/XS/convert/get_html_perl_info.h
+++ b/tp/Texinfo/XS/convert/get_html_perl_info.h
@@ -14,7 +14,11 @@ int html_converter_initialize_sv (SV *converter_sv,
                                   SV *default_types_open,
                                   SV *default_types_conversion,
                                   SV *default_css_string_types_conversion,
-                                  SV *default_output_units_conversion);
+                                  SV *default_output_units_conversion,
+                                  SV *default_special_unit_body);
 
 void html_converter_prepare_output_sv (SV *converter_sv, CONVERTER *converter);
+
+BUTTON_SPECIFICATION_LIST *html_get_button_specification_list (SV *buttons_sv);
+
 #endif
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index c789414f90..fc3029f6ff 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -22,8 +22,13 @@
 
 #include "element_types.h"
 #include "tree_types.h"
-#include "options_types.h"
 #include "document_types.h"
+/*
+#include "options_types.h"
+ */
+
+/* for interdependency with options_types.h */
+struct OPTIONS;
 
 enum formatting_reference_status {
    FRS_status_none,
@@ -445,20 +450,46 @@ typedef struct COMMAND_CONVERSION_FUNCTION {
                                  const char *content, TEXT *result);
 } COMMAND_CONVERSION_FUNCTION;
 
+typedef struct OUTPUT_UNIT_CONVERSION_FUNCTION {
+    enum formatting_reference_status status;
+    /* points to the perl formatting reference if it is used for
+       conversion */
+    FORMATTING_REFERENCE *formatting_reference;
+    /* the function used for conversion, either a function that calls
+       the perl function in formatting_reference, or another C function */
+    void (* output_unit_conversion) (struct CONVERTER *self,
+                        const enum output_unit_type unit_type,
+                        const OUTPUT_UNIT *output_unit, const char *content,
+                        TEXT *result);
+} OUTPUT_UNIT_CONVERSION_FUNCTION;
+
+typedef struct SPECIAL_UNIT_BODY_FORMATTING {
+    enum formatting_reference_status status;
+    /* points to the perl formatting reference if it is used for
+       conversion */
+    FORMATTING_REFERENCE *formatting_reference;
+    /* the function used for conversion, either a function that calls
+       the perl function in formatting_reference, or another C function */
+    void (* special_unit_body_formatting) (struct CONVERTER *self,
+            const size_t special_unit_number, const char *special_unit_variety,
+            const OUTPUT_UNIT *output_unit,
+            TEXT *result);
+} SPECIAL_UNIT_BODY_FORMATTING;
+
 typedef struct CONVERTER {
     int converter_descriptor;
   /* perl converter. This should be HV *hv,
      but we don't want to include the Perl headers everywhere; */
     void *hv;
 
-    OPTIONS *conf;
-    OPTIONS *init_conf;
+    struct OPTIONS *conf;
+    struct OPTIONS *init_conf;
     EXPANDED_FORMAT *expanded_formats;
     TRANSLATED_COMMAND *translated_commands;
 
     ERROR_MESSAGE_LIST error_messages;
 
-    struct DOCUMENT *document;
+    DOCUMENT *document;
     MERGED_INDEX *index_entries;
     INDEX_SORTED_BY_LETTER *index_entries_by_letter;
     int document_units_descriptor;
@@ -495,12 +526,15 @@ typedef struct CONVERTER {
     FORMATTING_REFERENCE types_conversion[TXI_TREE_TYPES_NUMBER];
     FORMATTING_REFERENCE css_string_types_conversion[TXI_TREE_TYPES_NUMBER];
     FORMATTING_REFERENCE output_units_conversion[OU_special_unit+1];
+    FORMATTING_REFERENCE *special_unit_body;
     STRING_LIST special_unit_varieties;
     char **special_unit_info[SUI_type_heading+1];
     TYPE_CONVERSION_FUNCTION type_conversion_function[TXI_TREE_TYPES_NUMBER];
     TYPE_CONVERSION_FUNCTION 
css_string_type_conversion_function[TXI_TREE_TYPES_NUMBER];
     COMMAND_CONVERSION_FUNCTION 
command_conversion_function[BUILTIN_CMD_NUMBER];
     COMMAND_CONVERSION_FUNCTION 
css_string_command_conversion_function[BUILTIN_CMD_NUMBER];
+    OUTPUT_UNIT_CONVERSION_FUNCTION 
output_unit_conversion_function[OU_special_unit+1];
+    SPECIAL_UNIT_BODY_FORMATTING *special_unit_body_formatting;
     /* set for a converter, modified in a document */
     HTML_COMMAND_CONVERSION 
html_command_conversion[BUILTIN_CMD_NUMBER][HCC_type_css_string+1];
 
@@ -561,4 +595,49 @@ typedef struct TRANSLATED_SUI_ASSOCIATION {
     enum special_unit_info_type string_type;
 } TRANSLATED_SUI_ASSOCIATION;
 
+/* FIXME move somewhere else? */
+
+enum button_specification_type {
+  BST_direction,
+  BST_function,
+  BST_string,
+  BST_direction_info,
+};
+
+enum button_information_type {
+  BIT_string,
+  BIT_function,
+  BIT_direction_information_type,
+};
+
+typedef struct BUTTON_SPECIFICATION_INFO {
+    char *direction; /* or direction enum/index? need both global and relative 
*/
+    enum button_information_type type;
+    union {
+  /* perl references. This should be SV *sv_*,
+     but we don't want to include the Perl headers everywhere; */
+      void *sv_reference;
+      void *sv_string;
+      int direction_information_type; /* TODO should be an enum? */
+    };
+} BUTTON_SPECIFICATION_INFO;
+
+typedef struct BUTTON_SPECIFICATION {
+    enum button_specification_type type;
+    union {
+      char *string; /* or direction enum/index? need both global and relative 
*/
+  /* perl references. This should be SV *sv_*,
+     but we don't want to include the Perl headers everywhere; */
+      void *sv_reference;
+      void *sv_string;
+      BUTTON_SPECIFICATION_INFO *button_info;
+    };
+} BUTTON_SPECIFICATION;
+
+typedef struct BUTTON_SPECIFICATION_LIST {
+    void *av; /* reference to perl data */
+    size_t number;
+    BUTTON_SPECIFICATION *list;
+} BUTTON_SPECIFICATION_LIST;
+
 #endif
diff --git a/tp/Texinfo/XS/main/document_types.h 
b/tp/Texinfo/XS/main/document_types.h
index 350c634298..f25a01762d 100644
--- a/tp/Texinfo/XS/main/document_types.h
+++ b/tp/Texinfo/XS/main/document_types.h
@@ -20,9 +20,15 @@
 #include <stddef.h>
 
 #include "tree_types.h"
+/*
 #include "options_types.h"
+ */
 #include "global_commands_types.h"
 
+/* to avoid interdependency with options_types.h, including for
+   other include files */
+struct OPTIONS;
+
 enum error_type { MSG_error, MSG_warning,
                   MSG_document_error, MSG_document_warning };
 
@@ -65,7 +71,7 @@ typedef struct DOCUMENT {
     ELEMENT_LIST *nodes_list;
     ELEMENT_LIST *sections_list;
     ERROR_MESSAGE_LIST *error_messages;
-    OPTIONS *options; /* for options used in structuring */
+    struct OPTIONS *options; /* for options used in structuring */
 } DOCUMENT;
 
 /* not in document, but used in parser */
diff --git a/tp/Texinfo/options_data.txt b/tp/Texinfo/options_data.txt
index 4d84e40b04..aa78235617 100644
--- a/tp/Texinfo/options_data.txt
+++ b/tp/Texinfo/options_data.txt
@@ -321,14 +321,14 @@ XREF_USE_NODE_NAME_ARG             
converter_customization undef   int
 
 
 # Not strings
-LINKS_BUTTONS                      converter_other undef   BUTTONS *
-TOP_BUTTONS                        converter_other undef   BUTTONS *
-SECTION_BUTTONS                    converter_other undef   BUTTONS *
-CHAPTER_FOOTER_BUTTONS             converter_other undef   BUTTONS *
-SECTION_FOOTER_BUTTONS             converter_other undef   BUTTONS *
-NODE_FOOTER_BUTTONS                converter_other undef   BUTTONS *
-MISC_BUTTONS                       converter_other undef   BUTTONS *
-CHAPTER_BUTTONS                    converter_other undef   BUTTONS *
+LINKS_BUTTONS                      converter_other undef   
BUTTON_SPECIFICATION_LIST *
+TOP_BUTTONS                        converter_other undef   
BUTTON_SPECIFICATION_LIST *
+SECTION_BUTTONS                    converter_other undef   
BUTTON_SPECIFICATION_LIST *
+CHAPTER_FOOTER_BUTTONS             converter_other undef   
BUTTON_SPECIFICATION_LIST *
+SECTION_FOOTER_BUTTONS             converter_other undef   
BUTTON_SPECIFICATION_LIST *
+NODE_FOOTER_BUTTONS                converter_other undef   
BUTTON_SPECIFICATION_LIST *
+MISC_BUTTONS                       converter_other undef   
BUTTON_SPECIFICATION_LIST *
+CHAPTER_BUTTONS                    converter_other undef   
BUTTON_SPECIFICATION_LIST *
 ACTIVE_ICONS                       converter_other undef   ICONS *
 PASSIVE_ICONS                      converter_other undef   ICONS *
 
diff --git a/tp/maintain/regenerate_C_options_info.pl 
b/tp/maintain/regenerate_C_options_info.pl
index f82810023e..753a5ed4ab 100755
--- a/tp/maintain/regenerate_C_options_info.pl
+++ b/tp/maintain/regenerate_C_options_info.pl
@@ -101,13 +101,11 @@ print HEADER "/* Automatically generated from $0 */\n\n";
 
 print HEADER "#ifndef OPTIONS_TYPE_H\n#define OPTIONS_TYPE_H\n\n";
 
-print HEADER "#include \"tree_types.h\"\n\n";
+print HEADER "#include \"tree_types.h\"\n";
+print HEADER "#include \"converter_types.h\"\n\n";
 
 print HEADER '
 /* temporary */
-typedef struct {
-} BUTTONS;
-
 typedef struct {
 } ICONS;
 
@@ -158,7 +156,7 @@ foreach my $category (sort(keys(%option_categories))) {
     my ($option, $value, $type) = @$option_info;
     if ($type eq 'STRING_LIST') {
       print CODE "  free_strings_list (&options->$option);\n";
-    } elsif ($type eq 'char *') {
+    } elsif ($type eq 'char *' or $type eq 'BUTTON_SPECIFICATION_LIST *') {
       print CODE " free (options->$option);\n";
     }
   }
@@ -253,7 +251,29 @@ close(CODE);
 open (GET, ">$get_file") or die "Open $get_file: $!\n";
 print GET "/* Automatically generated from $0 */\n\n";
 
-print GET '#include "get_perl_info.h"'."\n\n";
+print GET '
+/* Avoid namespace conflicts. */
+#define context perl_context
+
+#define PERL_NO_GET_CONTEXT
+#include "EXTERN.h"
+#include "perl.h"
+/* Avoid warnings about Perl headers redefining symbols that gnulib
+   redefined already. */
+#if defined _WIN32 && !defined __CYGWIN__
+  #undef free
+#endif
+#include "XSUB.h"
+
+#undef context
+
+';
+
+print GET '#include <string.h>'."\n\n";
+
+print GET '#include "options_types.h"'."\n";
+print GET '#include "get_perl_info.h"'."\n";
+print GET '#include "get_html_perl_info.h"'."\n\n";
 
 print GET 'void
 get_sv_option (OPTIONS *options, const char *key, SV *value)
@@ -296,6 +316,9 @@ foreach my $category (sort(keys(%option_categories))) {
       $dir_string_arg = 'svt_dir'
         if ($option eq 'INCLUDE_DIRECTORIES');
       print GET "    add_svav_to_string_list (value, &options->$option, 
$dir_string_arg);\n";
+    } elsif ($type eq 'BUTTON_SPECIFICATION_LIST *') {
+      print GET "    options->$option = "
+                        ."html_get_button_specification_list (value);\n";
     } else {
       print GET "    {}\n";
     }



reply via email to

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