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, 6 Dec 2023 15:25:40 -0500 (EST)

branch: master
commit d6d18fe56eb85722ff42eb0e24c2868802b8813d
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Wed Dec 6 21:25:25 2023 +0100

    * tp/Texinfo/Convert/HTML.pm (_default_format_navigation_panel):
    ignore leading space button also if the button specificatio is a
    reference on an array.
    
    * tp/Texinfo/XS/main/tree_types.h (HTML_GLOBAL_DIRECTIONS_LIST)
    (enum global_unit_direction), tp/Texinfo/XS/main/utils.h: move
    HTML_GLOBAL_DIRECTIONS_LIST to tree_types.h.
    
    * tp/Texinfo/XS/main/api_to_perl.c (unregister_perl_button),
    tp/Texinfo/XS/main/converter_types.h (enum button_unit_direction)
    (BUTTON_SPECIFICATION_INFO, BUTTON_SPECIFICATION),
    tp/Texinfo/XS/main/get_perl_info.c (get_sv_options, copy_sv_options)
    (converter_initialize, set_output_converter_sv)
    (html_get_direction_index, html_get_button_specification_list),
    tp/Texinfo/XS/main/utils.c (html_button_direction_names)
    (html_free_button_specification_list),
    tp/maintain/regenerate_C_options_info.pl: get perl buttons information
    into C with html_get_direction_index and
    html_get_button_specification_list, add
    html_free_button_specification_list to free that information.  Add a
    converter argument to *_sv_options to obtain the special output units
    direction strings.  Update callers.
    
    * tp/Texinfo/XS/convert/call_html_perl_function.c
    (call_formatting_function_format_button),
    tp/Texinfo/XS/convert/convert_html.c
    (html_global_unit_direction_names, format_button)
    (html_default_format_navigation_panel, format_navigation_panel),
    tp/Texinfo/XS/main/converter_types.h (FORMATTED_BUTTON_INFO):
    add call_formatting_function_format_button, implement
    format_navigation_panel in C.
    
    * tp/Texinfo/XS/convert/call_html_perl_function.c: add const.
---
 ChangeLog                                       |  36 ++++++
 tp/Texinfo/Convert/HTML.pm                      |  10 +-
 tp/Texinfo/XS/convert/ConvertXS.xs              |   2 +-
 tp/Texinfo/XS/convert/call_html_perl_function.c | 117 +++++++++++++++++---
 tp/Texinfo/XS/convert/call_html_perl_function.h |  32 +++---
 tp/Texinfo/XS/convert/convert_html.c            | 140 +++++++++++++++++++++++-
 tp/Texinfo/XS/main/DocumentXS.xs                |   4 +-
 tp/Texinfo/XS/main/api_to_perl.c                |   9 ++
 tp/Texinfo/XS/main/api_to_perl.h                |   2 +
 tp/Texinfo/XS/main/converter_types.h            |  52 +++++++--
 tp/Texinfo/XS/main/get_perl_info.c              | 135 ++++++++++++++++++++---
 tp/Texinfo/XS/main/get_perl_info.h              |   5 +-
 tp/Texinfo/XS/main/tree_types.h                 |  20 ++++
 tp/Texinfo/XS/main/utils.c                      |  38 +++++++
 tp/Texinfo/XS/main/utils.h                      |  29 +----
 tp/maintain/regenerate_C_options_info.pl        |  21 +++-
 16 files changed, 561 insertions(+), 91 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0ee8b5aea4..26a2dba8c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2023-12-06  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/HTML.pm (_default_format_navigation_panel):
+       ignore leading space button also if the button specificatio is a
+       reference on an array.
+
+       * tp/Texinfo/XS/main/tree_types.h (HTML_GLOBAL_DIRECTIONS_LIST)
+       (enum global_unit_direction), tp/Texinfo/XS/main/utils.h: move
+       HTML_GLOBAL_DIRECTIONS_LIST to tree_types.h.
+
+       * tp/Texinfo/XS/main/api_to_perl.c (unregister_perl_button),
+       tp/Texinfo/XS/main/converter_types.h (enum button_unit_direction)
+       (BUTTON_SPECIFICATION_INFO, BUTTON_SPECIFICATION),
+       tp/Texinfo/XS/main/get_perl_info.c (get_sv_options, copy_sv_options)
+       (converter_initialize, set_output_converter_sv)
+       (html_get_direction_index, html_get_button_specification_list),
+       tp/Texinfo/XS/main/utils.c (html_button_direction_names)
+       (html_free_button_specification_list),
+       tp/maintain/regenerate_C_options_info.pl: get perl buttons information
+       into C with html_get_direction_index and
+       html_get_button_specification_list, add
+       html_free_button_specification_list to free that information.  Add a
+       converter argument to *_sv_options to obtain the special output units
+       direction strings.  Update callers.
+
+       * tp/Texinfo/XS/convert/call_html_perl_function.c
+       (call_formatting_function_format_button),
+       tp/Texinfo/XS/convert/convert_html.c
+       (html_global_unit_direction_names, format_button)
+       (html_default_format_navigation_panel, format_navigation_panel),
+       tp/Texinfo/XS/main/converter_types.h (FORMATTED_BUTTON_INFO):
+       add call_formatting_function_format_button, implement
+       format_navigation_panel in C.
+
+       * tp/Texinfo/XS/convert/call_html_perl_function.c: add const.
+
 2023-12-05  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/XS/convert/convert_html.c
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index fb43cdcbeb..d256061a2c 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -4154,10 +4154,12 @@ sub _default_format_navigation_panel($$$$;$)
       $direction = $button->[0];
     } elsif (defined($button) and ref($button) eq '') {
       $direction = $button;
-      # if the first button is an empty button, pass
-      if ($direction eq ' ' and $nr_of_buttons_shown == 0) {
-        next;
-      }
+    }
+    # if the first button is an empty button, pass
+    # FIXME check if documented, if not, document
+    if (defined($direction)
+        and $direction eq ' ' and $nr_of_buttons_shown == 0) {
+      next;
     }
 
     my ($active, $passive, $need_delimiter)
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index e5e50afad1..3c43a1838f 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -1093,7 +1093,7 @@ html_translate_names (SV *converter_in)
              free (self->conf);
 
              self->conf
-              = copy_sv_options (*converter_options_sv);
+              = copy_sv_options (*converter_options_sv, self);
            }
 
          html_translate_names (self);
diff --git a/tp/Texinfo/XS/convert/call_html_perl_function.c 
b/tp/Texinfo/XS/convert/call_html_perl_function.c
index 64fa95a9f0..93a6526742 100644
--- a/tp/Texinfo/XS/convert/call_html_perl_function.c
+++ b/tp/Texinfo/XS/convert/call_html_perl_function.c
@@ -110,8 +110,8 @@ get_shared_conversion_state (CONVERTER *self)
 
 TARGET_FILENAME *
 call_file_id_setting_special_unit_target_file_name (CONVERTER *self,
-                                      OUTPUT_UNIT *special_unit, char *target,
-                                                    char *default_filename)
+                         const OUTPUT_UNIT *special_unit, const char *target,
+                                                const char *default_filename)
 {
   SV **file_id_setting_sv;
 
@@ -192,8 +192,8 @@ call_file_id_setting_special_unit_target_file_name 
(CONVERTER *self,
 
 char *
 call_file_id_setting_label_target_name (CONVERTER *self,
-                       char *normalized, const ELEMENT *label_element, char 
*target,
-                       int *called)
+                const char *normalized, const ELEMENT *label_element,
+                const char *target, int *called)
 {
   SV **file_id_setting_sv;
 
@@ -266,8 +266,8 @@ call_file_id_setting_label_target_name (CONVERTER *self,
 
 char *
 call_file_id_setting_node_file_name (CONVERTER *self,
-                       const ELEMENT *target_element, char *node_filename,
-                       int *called)
+                   const ELEMENT *target_element, const char *node_filename,
+                   int *called)
 {
   SV **file_id_setting_sv;
 
@@ -343,9 +343,9 @@ call_file_id_setting_node_file_name (CONVERTER *self,
 
 TARGET_CONTENTS_FILENAME *
 call_file_id_setting_sectioning_command_target_name (CONVERTER *self,
-                      const ELEMENT *command, char *target,
-                      char *target_contents,
-                      char *target_shortcontents, char *filename)
+                      const ELEMENT *command, const char *target,
+                      const char *target_contents,
+                      const char *target_shortcontents, const char *filename)
 {
   SV **file_id_setting_sv;
 
@@ -431,8 +431,9 @@ call_file_id_setting_sectioning_command_target_name 
(CONVERTER *self,
 }
 
 FILE_NAME_PATH *
-call_file_id_setting_unit_file_name (CONVERTER *self, OUTPUT_UNIT *output_unit,
-                                     char *filename, char *filepath)
+call_file_id_setting_unit_file_name (CONVERTER *self,
+                                 const OUTPUT_UNIT *output_unit,
+                                 const char *filename, const char *filepath)
 {
   SV **file_id_setting_sv;
 
@@ -926,8 +927,8 @@ call_formatting_function_format_footnotes_sequence 
(CONVERTER *self)
 }
 
 char *
-call_formatting_function_format_end_file (CONVERTER *self, char *filename,
-                                          const OUTPUT_UNIT *output_unit)
+call_formatting_function_format_end_file (CONVERTER *self,
+                    const char *filename, const OUTPUT_UNIT *output_unit)
 {
   int count;
   char *result;
@@ -992,7 +993,8 @@ call_formatting_function_format_end_file (CONVERTER *self, 
char *filename,
 }
 
 char *
-call_formatting_function_format_begin_file (CONVERTER *self, char *filename,
+call_formatting_function_format_begin_file (CONVERTER *self,
+                                            const char *filename,
                                             const OUTPUT_UNIT *output_unit)
 {
   int count;
@@ -1123,6 +1125,93 @@ call_formatting_function_format_translate_message 
(CONVERTER *self,
   return result;
 }
 
+FORMATTED_BUTTON_INFO *
+call_formatting_function_format_button (CONVERTER *self,
+                                  const BUTTON_SPECIFICATION *button,
+                                  const ELEMENT *element)
+{
+  int count;
+  SV *need_delimiter_sv;
+  SV *passive_sv;
+  SV *active_sv;
+  SV *formatting_reference_sv;
+
+  dTHX;
+
+  if (!self->hv)
+    return 0;
+
+  formatting_reference_sv
+    = self->formatting_references[
+         FR_format_button].sv_reference;
+
+  if (self->modified_state)
+    {
+      build_html_formatting_state (self, self->modified_state);
+      self->modified_state = 0;
+    }
+
+  build_tree_to_build (&self->tree_to_build);
+
+  FORMATTED_BUTTON_INFO *result
+   = (FORMATTED_BUTTON_INFO *) malloc (sizeof (FORMATTED_BUTTON_INFO));
+  memset (result, 0, sizeof (FORMATTED_BUTTON_INFO));
+
+  dSP;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  EXTEND(SP, 3);
+
+  SvREFCNT_inc (button->sv);
+
+  PUSHs(sv_2mortal (newRV_inc (self->hv)));
+  PUSHs(sv_2mortal (button->sv));
+  PUSHs(sv_2mortal (newRV_inc (element->hv)));
+  PUTBACK;
+
+  count = call_sv (formatting_reference_sv,
+                   G_ARRAY);
+
+  SPAGAIN;
+
+  if (count != 3)
+    croak("format_button should return 3 items\n");
+
+  need_delimiter_sv = POPs;
+  if (SvOK (need_delimiter_sv))
+    {
+      result->need_delimiter = SvIV (need_delimiter_sv);
+    }
+
+  passive_sv = POPs;
+  if (SvOK (passive_sv))
+    {
+      STRLEN len;
+      char *passive_ret = SvPV (passive_sv, len);
+      result->passive = strdup (passive_ret);
+    }
+
+  active_sv = POPs;
+  if (SvOK (active_sv))
+    {
+      STRLEN len;
+      char *active_ret = SvPV (active_sv, len);
+      result->active = strdup (active_ret);
+    }
+
+  PUTBACK;
+
+  FREETMPS;
+  LEAVE;
+
+  get_shared_conversion_state (self);
+
+  return result;
+}
+
 char *
 call_formatting_function_format_navigation_panel (CONVERTER *self,
                                   const BUTTON_SPECIFICATION_LIST *buttons,
diff --git a/tp/Texinfo/XS/convert/call_html_perl_function.h 
b/tp/Texinfo/XS/convert/call_html_perl_function.h
index 52b3277ff4..0f04fb3bc1 100644
--- a/tp/Texinfo/XS/convert/call_html_perl_function.h
+++ b/tp/Texinfo/XS/convert/call_html_perl_function.h
@@ -26,23 +26,24 @@ typedef struct TARGET_CONTENTS_FILENAME {
     char *target_shortcontents;
 } TARGET_CONTENTS_FILENAME;
 
-TARGET_FILENAME *call_file_id_setting_special_unit_target_file_name (
-                     CONVERTER *self, OUTPUT_UNIT *special_unit, char *target,
-                                                      char *default_filename);
+TARGET_FILENAME *call_file_id_setting_special_unit_target_file_name
+                            (CONVERTER *self,
+                          const OUTPUT_UNIT *special_unit, const char *target,
+                                                 const char *default_filename);
 char *call_file_id_setting_label_target_name (CONVERTER *self,
-                       char *normalized, const ELEMENT *label_element,
-                       char *target, int *called);
+                       const char *normalized, const ELEMENT *label_element,
+                       const char *target, int *called);
 char *call_file_id_setting_node_file_name (CONVERTER *self,
-                       const ELEMENT *target_element, char *node_filename,
-                       int *called);
+                     const ELEMENT *target_element, const char *node_filename,
+                     int *called);
 TARGET_CONTENTS_FILENAME * call_file_id_setting_sectioning_command_target_name
                      (CONVERTER *self,
-                      const ELEMENT *command, char *target,
-                      char *target_contents,
-                      char *target_shortcontents, char *filename);
+                      const ELEMENT *command, const char *target,
+                      const char *target_contents,
+                      const char *target_shortcontents, const char *filename);
 FILE_NAME_PATH *call_file_id_setting_unit_file_name (CONVERTER *self,
-                                                     OUTPUT_UNIT *output_unit,
-                                               char *filename, char *filepath);
+                                  const OUTPUT_UNIT *output_unit,
+                                  const char *filename, const char *filepath);
 TARGET_DIRECTORY_FILENAME *call_file_id_setting_external_target_split_name
                     (CONVERTER *self,
                      const char *normalized, const ELEMENT *element,
@@ -59,11 +60,14 @@ char *call_formatting_function_format_protect_text 
(CONVERTER *self,
 char *call_formatting_function_format_footnotes_sequence (CONVERTER *self);
 char *call_formatting_function_format_footnotes_segment (CONVERTER *self);
 char *call_formatting_function_format_end_file (CONVERTER *self,
-                                                char *filename,
+                                         const char *filename,
                                          const OUTPUT_UNIT *output_unit);
 char *call_formatting_function_format_begin_file (CONVERTER *self,
-                                                 char *filename,
+                                         const char *filename,
                                          const OUTPUT_UNIT *output_unit);
+FORMATTED_BUTTON_INFO *call_formatting_function_format_button (CONVERTER *self,
+                                  const BUTTON_SPECIFICATION *button,
+                                  const ELEMENT *element);
 char *call_formatting_function_format_navigation_panel (CONVERTER *self,
                                   const BUTTON_SPECIFICATION_LIST *buttons,
                                   const char *cmdname, const ELEMENT *element,
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index 8367aad1a8..f3817fa48e 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -107,6 +107,7 @@ char *html_global_unit_direction_names[] = {
   #define hgdt_name(name) #name,
    HTML_GLOBAL_DIRECTIONS_LIST
   #undef hgdt_name
+   " ",
 };
 
 char *html_conversion_context_type_names[] = {
@@ -4690,13 +4691,149 @@ convert_text (CONVERTER *self, const enum element_type 
type,
     free (content_used);
 }
 
+FORMATTED_BUTTON_INFO *
+format_button (CONVERTER *self,
+               const BUTTON_SPECIFICATION *button,
+               const ELEMENT *element)
+{
+/*
+  if (self->formatting_references[FR_format_button].status
+                                             == FRS_status_default_set)
+    {
+      html_default_format_button (self, button, element, result);
+    }
+  else
+*/
+    {
+      return call_formatting_function_format_button (self, button, element);
+    }
+}
+
+void
+html_default_format_navigation_panel (CONVERTER *self,
+                         const BUTTON_SPECIFICATION_LIST *buttons,
+                         const char *cmdname, const ELEMENT *element,
+                         int vertical, TEXT *result)
+{
+  int i;
+  /* do the buttons first in case they are formatteed as an empty string */
+  int nr_of_buttons_shown = 0;
+  TEXT result_buttons;
+  char *attribute_class;
+  STRING_LIST *classes;
+
+  text_init (&result_buttons);
+  text_append (&result_buttons, "");
+
+  for (i = 0; i < buttons->number; i++)
+    {
+      const BUTTON_SPECIFICATION *button = &buttons->list[i];
+      FORMATTED_BUTTON_INFO *button_info;
+      char *active = 0;
+      char *passive = 0;
+      int need_delimiter = 0;
+      int direction = -1;
+      if (button->type == BST_direction_info)
+        direction = button->button_info->direction;
+      else if (button->type == BST_direction)
+        direction = button->direction;
+
+      if (direction >= 0 && direction == D_button_space
+          && nr_of_buttons_shown == 0)
+        continue;
+
+      button_info = format_button (self, button, element);
+
+      if (button_info)
+        {
+          need_delimiter = button_info->need_delimiter;
+          active = button_info->active;
+          passive = button_info->passive;
+          free (button_info);
+        }
+
+      if (self->conf->HEADER_IN_TABLE > 0)
+        {
+          if (vertical)
+            text_append_n (&result_buttons, "<tr>\n", 5);
+          text_append_n (&result_buttons, "<td>", 4);
+
+          if (active)
+            text_append (&result_buttons, active);
+          else if (passive)
+            text_append (&result_buttons, passive);
+
+          text_append_n (&result_buttons, "</td>\n", 6);
+          if (vertical)
+            text_append_n (&result_buttons, "</tr>\n", 6);
+
+          nr_of_buttons_shown++;
+        }
+      else if (active)
+        { /* only active buttons are print out when not in table */
+          if (need_delimiter && nr_of_buttons_shown > 0)
+            text_append_n (&result_buttons, ", ", 2);
+
+          text_append (&result_buttons, active);
+
+          nr_of_buttons_shown++;
+        }
+
+      free (active);
+      free (passive);
+    }
+
+  classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+  memset (classes, 0, sizeof (STRING_LIST));
+
+  add_string ("nav-panel", classes);
+
+  if (self->conf->HEADER_IN_TABLE > 0)
+    {
+      attribute_class = html_attribute_class (self, "table", classes);
+      text_append (result, attribute_class);
+      text_append (result,
+                   " cellpadding=\"1\" cellspacing=\"1\" border=\"0\">\n");
+      free (attribute_class);
+
+      if (!vertical)
+        text_append_n (result, "<tr>", 4);
+    }
+  else
+    {
+      attribute_class = html_attribute_class (self, "div", classes);
+      text_append (result, attribute_class);
+      text_append_n (result, ">\n", 2);
+      free (attribute_class);
+
+      if (result_buttons.end > 0)
+        text_append_n (result, "<p>\n", 4);
+    }
+  destroy_strings_list (classes);
+
+  text_append (result, result_buttons.text);
+
+  if (self->conf->HEADER_IN_TABLE > 0)
+    {
+      if (!vertical)
+        text_append_n (result, "</tr>", 5);
+      text_append_n (result, "</table>\n", 9);
+    }
+  else
+    {
+      if (result_buttons.end > 0)
+        text_append_n (result, "</p>\n", 5);
+
+      text_append_n (result, "</div>\n", 7);
+    }
+}
+
 void
 format_navigation_panel (CONVERTER *self,
                          const BUTTON_SPECIFICATION_LIST *buttons,
                          const char *cmdname, const ELEMENT *element,
                          int vertical, TEXT *result)
 {
-/*
   if (self->formatting_references[FR_format_navigation_panel].status
                                              == FRS_status_default_set)
     {
@@ -4704,7 +4841,6 @@ format_navigation_panel (CONVERTER *self,
                                             element, vertical, result);
     }
   else
-*/
     {
       char *navigation_panel
         = call_formatting_function_format_navigation_panel (self,
diff --git a/tp/Texinfo/XS/main/DocumentXS.xs b/tp/Texinfo/XS/main/DocumentXS.xs
index cccd93776f..4f3a936059 100644
--- a/tp/Texinfo/XS/main/DocumentXS.xs
+++ b/tp/Texinfo/XS/main/DocumentXS.xs
@@ -172,7 +172,7 @@ set_document_options (SV *sv_options_in, SV *document_in)
                                              "set_document_options");
         if (document)
           {
-            OPTIONS *options = copy_sv_options (sv_options_in);
+            OPTIONS *options = copy_sv_options (sv_options_in, 0);
             register_document_options (document, options);
           }
 
@@ -208,7 +208,7 @@ gdt (SV *options_in, string, ...)
       CODE:
          if (SvOK(options_in))
            {
-             options = copy_sv_options (options_in);
+             options = copy_sv_options (options_in, 0);
            }
         if (items > 4 && SvOK(ST(4)))
            in_lang = (char *)SvPVutf8_nolen(ST(4));
diff --git a/tp/Texinfo/XS/main/api_to_perl.c b/tp/Texinfo/XS/main/api_to_perl.c
index a0e9eb4344..2f1e2c0298 100644
--- a/tp/Texinfo/XS/main/api_to_perl.c
+++ b/tp/Texinfo/XS/main/api_to_perl.c
@@ -31,6 +31,7 @@
 #undef context
 
 #include "tree_types.h"
+#include "converter_types.h"
 
 /* to be called when a tree element is destroyed, to remove the reference
    of the association with the C tree */
@@ -46,6 +47,14 @@ unregister_perl_tree_element (ELEMENT *e)
     }
 }
 
+void
+unregister_perl_button (BUTTON_SPECIFICATION *button)
+{
+  dTHX;
+
+  SvREFCNT_dec (button->sv);
+}
+
 void
 call_switch_to_global_locale (void)
 {
diff --git a/tp/Texinfo/XS/main/api_to_perl.h b/tp/Texinfo/XS/main/api_to_perl.h
index 3bd15e6943..7b701e7076 100644
--- a/tp/Texinfo/XS/main/api_to_perl.h
+++ b/tp/Texinfo/XS/main/api_to_perl.h
@@ -3,8 +3,10 @@
 #define TREE_PERL_API_H
 
 #include "tree_types.h"
+#include "converter_types.h"
 
 void unregister_perl_tree_element (ELEMENT *e);
+void unregister_perl_button (BUTTON_SPECIFICATION *button);
 
 void call_switch_to_global_locale (void);
 void call_sync_locale (void);
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index 02f1e81b6d..f4d2c0b54a 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -153,6 +153,7 @@ enum html_argument_formatting_type {
    #undef html_aft_type
 };
 
+/* TODO move to convert_html.c? */
 enum html_special_character {
    SC_paragraph_symbol,
    SC_left_quote,
@@ -727,6 +728,24 @@ typedef struct TRANSLATED_SUI_ASSOCIATION {
 
 /* FIXME move somewhere else? */
 
+/* button directions are not often used as enum, but it can be useful
+   sometime to have an enum name for a direction */
+/* special units are put after these fixed types, they are dynamically
+   determined from perl input */
+enum button_unit_direction {
+  #define hgdt_name(name) D_button_ ## name,
+   HTML_GLOBAL_DIRECTIONS_LIST
+  #undef hgdt_name
+   D_button_space,
+  #define rud_type(name) D_button_ ## name,
+   RUD_DIRECTIONS_TYPES_LIST
+   RUD_FILE_DIRECTIONS_TYPES
+  #undef rud_type
+  #define rud_type(name) D_button_FirstInFile## name,
+   RUD_DIRECTIONS_TYPES_LIST
+  #undef rud_type
+};
+
 enum button_specification_type {
   BST_direction,
   BST_function,
@@ -741,33 +760,48 @@ enum button_information_type {
 };
 
 typedef struct BUTTON_SPECIFICATION_INFO {
-    char *direction; /* or direction enum/index? need both global and relative 
*/
+     /* both global and relative directions index */
+    int direction;
     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? */
+      void *sv_reference; /* BIT_function */
+      void *sv_string; /* BIT_string */
+     /* both global and relative directions index */
+      int direction_information_type; /* BIT_direction_information_type
+            text string in perl, element direction information type */
     };
 } BUTTON_SPECIFICATION_INFO;
 
 typedef struct BUTTON_SPECIFICATION {
+    void *sv; /* reference to perl data that can be used instead of
+                 the C data */
+
     enum button_specification_type type;
     union {
-      char *string; /* or direction enum/index? need both global and relative 
*/
+     /* both global and relative directions index */
+      int direction; /* BST_direction, string with an element direction */
   /* 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;
+      void *sv_reference; /* BST_function */
+      void *sv_string; /* BST_string scalar reference */
+      BUTTON_SPECIFICATION_INFO *button_info; /* BST_direction_info 
+                                              array reference of length 2 */
     };
 } BUTTON_SPECIFICATION;
 
 typedef struct BUTTON_SPECIFICATION_LIST {
-    void *av; /* reference to perl data */
+    void *av; /* reference to perl data that can be used instead of 
+                 the list */
     size_t number;
     BUTTON_SPECIFICATION *list;
 } BUTTON_SPECIFICATION_LIST;
 
+typedef struct FORMATTED_BUTTON_INFO {
+    char *active;
+    char *passive;
+    int need_delimiter;
+} FORMATTED_BUTTON_INFO;
+
 #endif
diff --git a/tp/Texinfo/XS/main/get_perl_info.c 
b/tp/Texinfo/XS/main/get_perl_info.c
index 6b08197c1a..6dbd57d23d 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -39,6 +39,8 @@ FIXME add an initialization of translations?
 */
 
 #include "options_types.h"
+#include "document_types.h"
+#include "converter_types.h"
 #include "utils.h"
 #include "builtin_commands.h"
 #include "document.h"
@@ -195,7 +197,7 @@ add_svav_to_string_list (SV *sv, STRING_LIST *string_list, 
enum sv_string_type t
 #include "options_get_perl.c"
 
 void
-get_sv_options (SV *sv, OPTIONS *options)
+get_sv_options (SV *sv, OPTIONS *options, CONVERTER *converter)
 {
   I32 hv_number;
   I32 i;
@@ -212,17 +214,17 @@ get_sv_options (SV *sv, OPTIONS *options)
       SV *value = hv_iternextsv(hv, &key, &retlen);
       if (value && SvOK (value))
         {
-          get_sv_option (options, key, value);
+          get_sv_option (options, key, value, converter);
         }
     }
 }
 
 
 OPTIONS *
-copy_sv_options (SV *sv_in)
+copy_sv_options (SV *sv_in, CONVERTER *converter)
 {
   OPTIONS *options = new_options ();
-  get_sv_options (sv_in, options);
+  get_sv_options (sv_in, options, converter);
   return options;
 }
 
@@ -363,7 +365,7 @@ converter_initialize (SV *converter_sv, CONVERTER 
*converter)
   if (conf_sv && SvOK (*conf_sv))
     {
       converter->conf
-         = copy_sv_options (*conf_sv);
+         = copy_sv_options (*conf_sv, converter);
     }
 
   FETCH(converter_init_conf)
@@ -371,7 +373,7 @@ converter_initialize (SV *converter_sv, CONVERTER 
*converter)
   if (converter_init_conf_sv && SvOK (*converter_init_conf_sv))
     {
       converter->init_conf
-         = copy_sv_options (*converter_init_conf_sv);
+         = copy_sv_options (*converter_init_conf_sv, converter);
     }
 
   FETCH(output_format)
@@ -411,7 +413,7 @@ set_output_converter_sv (SV *sv_in, char *warn_string)
       free (converter->conf);
 
       converter->conf
-         = copy_sv_options (*conf_sv);
+         = copy_sv_options (*conf_sv, converter);
     }
 
   FETCH(output_init_conf)
@@ -423,7 +425,7 @@ set_output_converter_sv (SV *sv_in, char *warn_string)
       free (converter->init_conf);
 
       converter->init_conf
-         = copy_sv_options (*output_init_conf_sv);
+         = copy_sv_options (*output_init_conf_sv, converter);
     }
 
   return converter;
@@ -564,7 +566,7 @@ get_sv_index_entries_sorted_by_letter (INDEX **index_names,
             = &index_index_letters->letter_entries[i];
           if (letter_entries_sv)
             {
-              int k;
+              SSize_t k;
               char *letter_string;
               SSize_t entries_nr;
               AV *entries_av;
@@ -664,7 +666,7 @@ void
 set_conf (CONVERTER *converter, const char *conf, SV *value)
 {
   if (converter->conf)
-    get_sv_option (converter->conf, conf, value);
+    get_sv_option (converter->conf, conf, value, converter);
    /* Too early to have options set
   else
     fprintf (stderr, "HHH no converter conf %s\n", conf);
@@ -720,7 +722,7 @@ copy_sv_options_for_convert_text (SV *sv_in)
   if (other_converter_options_sv)
     {
       text_options->other_converter_options
-         = copy_sv_options (*other_converter_options_sv);
+         = copy_sv_options (*other_converter_options_sv, 0);
     }
 
   self_converter_options_sv = hv_fetch (hv_in, "self_converter_options",
@@ -729,26 +731,129 @@ copy_sv_options_for_convert_text (SV *sv_in)
   if (self_converter_options_sv)
     {
       text_options->self_converter_options
-         = copy_sv_options (*self_converter_options_sv);
+         = copy_sv_options (*self_converter_options_sv, 0);
     }
 
   return text_options;
 }
 
+int
+html_get_direction_index (CONVERTER *converter, const char *direction)
+{
+  int i;
+  int idx;
+  for (i = 0; i < D_button_FirstInFileNodeUp +1; i++)
+    {
+      if (!strcmp (direction, html_button_direction_names[i]))
+        return i;
+    }
+  idx = D_button_FirstInFileNodeUp +1;
+  if (converter)
+    {
+      for (i = 0; i < converter->special_unit_varieties.number; i++)
+        {
+          if (!strcmp(direction,
+                  converter->special_unit_info[SUI_type_direction][i]))
+            return idx;
+          idx++;
+        }
+    }
+  return -1;
+}
+
 /* HTML specific, but needs to be there for options_get_perl.c */
 BUTTON_SPECIFICATION_LIST *
-html_get_button_specification_list (SV *buttons_sv)
+html_get_button_specification_list (CONVERTER *converter, SV *buttons_sv)
 {
   BUTTON_SPECIFICATION_LIST *result;
+  AV *buttons_av;
+  SSize_t buttons_nr;
+  SSize_t i;
 
   dTHX;
 
   result = (BUTTON_SPECIFICATION_LIST *)
             malloc (sizeof (BUTTON_SPECIFICATION_LIST));
 
-  result->av = (AV *)SvRV (buttons_sv);
+  buttons_av = (AV *)SvRV (buttons_sv);
+  /* TODO increase ref count of result->av? */
+  result->av = buttons_av;
+
+  buttons_nr = av_top_index (buttons_av) +1;
+
+  result->number = (size_t) buttons_nr;
+  result->list = (BUTTON_SPECIFICATION *)
+    malloc (result->number * sizeof (BUTTON_SPECIFICATION));
+  memset (result->list, 0, result->number * sizeof (BUTTON_SPECIFICATION));
+ 
+  for (i = 0; i < buttons_nr; i++)
+    {
+      SV** button_sv = av_fetch (buttons_av, i, 0);
+      BUTTON_SPECIFICATION *button = &result->list[i];
+
+      button->sv = *button_sv;
+      SvREFCNT_inc (button->sv);
+
+      if (SvROK (*button_sv))
+        {
+          if (SvTYPE (SvRV(*button_sv)) == SVt_PVCV) /* CODE */
+            {
+              button->type = BST_function;
+              button->sv_reference = *button_sv;
+            }
+          else if (SvTYPE (SvRV(*button_sv)) == SVt_PVAV)
+            {
+              AV *button_spec_info_av = (AV *) SvRV(*button_sv);
+              SV **direction_sv = av_fetch (button_spec_info_av, 0, 0);
+              SV **button_spec_info_type
+                 = av_fetch (button_spec_info_av, 1, 0);
+
+              BUTTON_SPECIFICATION_INFO *button_spec
+                = (BUTTON_SPECIFICATION_INFO *)
+                   malloc (sizeof (BUTTON_SPECIFICATION_INFO));
+              memset (button_spec, 0, sizeof (BUTTON_SPECIFICATION_INFO));
 
-  /* TODO do C structures to be able to call C functions */
+              button->type = BST_direction_info;
+              button->button_info = button_spec;
+
+              button_spec->direction
+                = html_get_direction_index (converter,
+                                            SvPVutf8_nolen (*direction_sv));
+
+              if (SvROK (*button_spec_info_type))
+                {
+                  if (SvTYPE (SvRV(*button_spec_info_type)) == SVt_PVCV) /* 
CODE */
+                    {
+                      button_spec->type = BIT_function;
+                      button_spec->sv_reference = *button_spec_info_type;
+                    }
+                  else
+                    {
+                      button_spec->type = BIT_string;
+                      button_spec->sv_string = *button_spec_info_type;
+                    }
+                }
+              else
+                {
+                  button_spec->type = BIT_direction_information_type;
+                  button_spec->direction_information_type
+                   = html_get_direction_index (converter,
+                                 SvPVutf8_nolen (*button_spec_info_type));
+                }
+            }
+          else
+            {
+              button->type = BST_string;
+              button->sv_string = *button_sv;
+            }
+        }
+      else
+        {
+          button->type = BST_direction;
+          button->direction = html_get_direction_index (converter,
+                                              SvPVutf8_nolen (*button_sv));
+        }
+    }
 
   return result;
 }
diff --git a/tp/Texinfo/XS/main/get_perl_info.h 
b/tp/Texinfo/XS/main/get_perl_info.h
index 24b67ac2db..23470848ca 100644
--- a/tp/Texinfo/XS/main/get_perl_info.h
+++ b/tp/Texinfo/XS/main/get_perl_info.h
@@ -26,7 +26,7 @@ int get_sv_output_units_descriptor (SV *output_units_in, char 
*warn_string);
 void add_svav_to_string_list (SV *sv, STRING_LIST *string_list,
                               enum sv_string_type type);
 
-OPTIONS *copy_sv_options (SV *sv_in);
+OPTIONS *copy_sv_options (SV *sv_in, CONVERTER *converter);
 void set_conf (CONVERTER *converter, const char *conf, SV *value);
 
 CONVERTER *set_output_converter_sv (SV *sv_in, char *warn_string);
@@ -39,6 +39,7 @@ INDEX_SORTED_BY_LETTER *get_sv_index_entries_sorted_by_letter
 
 TEXT_OPTIONS *copy_sv_options_for_convert_text (SV *sv_in);
 
-BUTTON_SPECIFICATION_LIST *html_get_button_specification_list (SV *buttons_sv);
+BUTTON_SPECIFICATION_LIST *html_get_button_specification_list
+                                (CONVERTER *converter, SV *buttons_sv);
 
 #endif
diff --git a/tp/Texinfo/XS/main/tree_types.h b/tp/Texinfo/XS/main/tree_types.h
index 0577a36046..819450d753 100644
--- a/tp/Texinfo/XS/main/tree_types.h
+++ b/tp/Texinfo/XS/main/tree_types.h
@@ -75,6 +75,26 @@ enum output_unit_type {
    OU_special_unit,
 };
 
+/* see Texinfo::HTML _prepare_output_units_global_targets
+
+   NOTE the special output units direction names
+   are obtained dynamically from the perl input and stored in
+   special_unit_info and put later on in
+   special_units_direction_name
+ */
+#define HTML_GLOBAL_DIRECTIONS_LIST \
+   hgdt_name(First) \
+   hgdt_name(Top) \
+   hgdt_name(Index) \
+   hgdt_name(Last)
+
+enum global_unit_direction {
+  #define hgdt_name(name) D_ ## name,
+   HTML_GLOBAL_DIRECTIONS_LIST
+  #undef hgdt_name
+   D_Space,
+};
+
 /* relative output unit directions */
 #define RUD_DIRECTIONS_TYPES_LIST \
    rud_type(This) \
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 48f64da00f..f2a7943a91 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -40,6 +40,7 @@
 #include "errors.h"
 #include "debug.h"
 #include "builtin_commands.h"
+#include "api_to_perl.h"
 #include "utils.h"
 
 #include "options_init_free.c"
@@ -85,6 +86,22 @@ EXPANDED_FORMAT expanded_formats[] = {
     "latex", 0,
 };
 
+/* special output units global directions are not there, they are
+   determined from perl dynamically */
+const char *html_button_direction_names[] = {
+  #define hgdt_name(name) #name,
+   HTML_GLOBAL_DIRECTIONS_LIST
+  #undef hgdt_name
+   " ",
+  #define rud_type(name) #name,
+   RUD_DIRECTIONS_TYPES_LIST
+   RUD_FILE_DIRECTIONS_TYPES
+  #undef rud_type
+  #define rud_type(name) "FirstInFile" #name,
+   RUD_DIRECTIONS_TYPES_LIST
+  #undef rud_type
+};
+
 /* wrapper for asprintf */
 int
 xasprintf (char **ptr, const char *template, ...)
@@ -1267,3 +1284,24 @@ enumerate_item_representation (char *specification, int 
number)
   return result.text;
 }
 
+void
+html_free_button_specification_list (BUTTON_SPECIFICATION_LIST *buttons)
+{
+  if (!buttons)
+    return;
+
+  if (buttons->number > 0)
+    {
+      size_t i;
+      for (i = 0; i < buttons->number; i++)
+        {
+          BUTTON_SPECIFICATION *button = &buttons->list[i];
+          if (button->type == BST_direction_info)
+            free (button->button_info);
+          unregister_perl_button (button);
+        }
+    }
+  free (buttons->list);
+  free (buttons);
+}
+
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index bc556122cd..a9349a4903 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -40,6 +40,8 @@ extern const char *output_unit_type_names[];
 
 extern const char *command_location_names[];
 
+extern const char *html_button_direction_names[];
+
 typedef struct {
     char *encoding_name;
     iconv_t iconv;
@@ -98,30 +100,7 @@ typedef struct COMMAND_OPTION_VALUE {
 
 extern const enum command_id small_block_associated_command[][2];
 
-/* CONVERTER and associated types needed for set_global_document_command */
-/* see Texinfo::HTML _prepare_output_units_global_targets
-
-   NOTE the special output units names are not actually used, the
-   special output units direction names are obtained from the perl input
-   and stored in special_unit_info and put later on in
-   special_units_direction_name
- */
-#define HTML_GLOBAL_DIRECTIONS_LIST \
-   hgdt_name(First) \
-   hgdt_name(Top) \
-   hgdt_name(Index) \
-   hgdt_name(Last) \
-   hgdt_name(About) \
-   hgdt_name(Contents) \
-   hgdt_name(Overview) \
-   hgdt_name(Footnotes)
-
-enum global_unit_direction {
-  #define hgdt_name(name) D_ ## name,
-   HTML_GLOBAL_DIRECTIONS_LIST
-  #undef hgdt_name
-};
-
+/* enum needed for set_global_document_command */
 enum command_location {
    CL_before,
    CL_last,
@@ -254,4 +233,6 @@ ELEMENT *set_global_document_command (GLOBAL_COMMANDS 
*global_commands,
                              enum command_location command_location);
 ELEMENT_LIST *get_cmd_global_multi_command (GLOBAL_COMMANDS 
*global_commands_ref,
                                       enum command_id cmd);
+
+void html_free_button_specification_list (BUTTON_SPECIFICATION_LIST *buttons);
 #endif
diff --git a/tp/maintain/regenerate_C_options_info.pl 
b/tp/maintain/regenerate_C_options_info.pl
index 4e081e9ae7..4b4e517779 100755
--- a/tp/maintain/regenerate_C_options_info.pl
+++ b/tp/maintain/regenerate_C_options_info.pl
@@ -130,6 +130,12 @@ close(HEADER);
 open (CODE, ">$code_file") or die "Open $code_file: $!\n";
 print CODE "/* Automatically generated from $0 */\n\n";
 
+print CODE '#include <stdlib.h>'."\n\n";
+
+print CODE '#include "options_types.h"'."\n";
+print CODE '#include "converter_types.h"'."\n";
+print CODE '#include "utils.h"'."\n\n";
+
 print CODE "void\ninitialize_options (OPTIONS *options)\n{\n";
 
 foreach my $category (sort(keys(%option_categories))) {
@@ -156,8 +162,10 @@ 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 *' or $type eq 'BUTTON_SPECIFICATION_LIST *') {
+    } elsif ($type eq 'char *') {
       print CODE " free (options->$option);\n";
+    } elsif ($type eq 'BUTTON_SPECIFICATION_LIST *') {
+      print GET "  html_free_button_specification_list (options->$option);\n";
     }
   }
 }
@@ -272,10 +280,12 @@ print GET '
 print GET '#include <string.h>'."\n\n";
 
 print GET '#include "options_types.h"'."\n";
+print GET '#include "converter_types.h"'."\n";
+print GET '#include "utils.h"'."\n";
 print GET '#include "get_perl_info.h"'."\n\n";
 
 print GET 'void
-get_sv_option (OPTIONS *options, const char *key, SV *value)
+get_sv_option (OPTIONS *options, const char *key, SV *value, CONVERTER 
*converter)
 {
   dTHX;
 
@@ -316,8 +326,11 @@ foreach my $category (sort(keys(%option_categories))) {
         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";
+      print GET "    {\n";
+      print GET "      html_free_button_specification_list 
(options->$option);\n";
+      print GET "      options->$option = "
+                        ."html_get_button_specification_list (converter, 
value);\n";
+      print GET "    }\n";
     } else {
       print GET "    {}\n";
     }



reply via email to

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