texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * tp/Texinfo/Convert/HTML.pm (_convert): make cod


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/Convert/HTML.pm (_convert): make code clearer and more efficient, avoid modifying @args_specification, rename $i as $content_idx.
Date: Mon, 23 Oct 2023 18:37:55 -0400

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 1fdbd59c28 * tp/Texinfo/Convert/HTML.pm (_convert): make code clearer 
and more efficient, avoid modifying @args_specification, rename $i as 
$content_idx.
1fdbd59c28 is described below

commit 1fdbd59c28653809bdbe973fba8707764b19a52d
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Tue Oct 24 00:37:55 2023 +0200

    * tp/Texinfo/Convert/HTML.pm (_convert): make code clearer and more
    efficient, avoid modifying @args_specification, rename $i as
    $content_idx.
    
    * tp/Texinfo/XS/main/builtin_commands.c (element_command_name)
    (element_builtin_cmd), tp/Texinfo/XS/main/command_data.awk: add
    to generated command_ids.h a define for BUILTIN_CMD_NUMBER, that
    replaces the builtin_cmd_number variable.
    
    * tp/Texinfo/XS/main/utils.c (item_line_parent),
    tp/Texinfo/XS/parsetexi/multitable.c: move item_line_parent from
    parsetexi/multitable.c to main/utils.c.
    
    * tp/Texinfo/Convert/Converter.pm (encode_converter_document),
    tp/Texinfo/Convert/HTML.pm (converter_initialize),
    tp/Texinfo/XS/main/get_perl_info.c
    (register_formatting_reference_with_default)
    (html_converter_initialize), tp/Texinfo/XS/main/utils.h (enum
    formatting_reference_status, FORMATTING_REFERENCE, CONVERTER):
    pass commands_open, commands_conversion, types_open and
    types_conversion to converter.  Add a status for FORMATTING_REFERENCE
    to simplify the use of FORMATTING_REFERENCE.
    
    * tp/Texinfo/XS/convert/convert_html.c (convert_to_html_internal):
    preliminary implementation.
---
 ChangeLog                                 |  28 +++
 tp/Texinfo/Convert/Converter.pm           |   3 +-
 tp/Texinfo/Convert/HTML.pm                |  40 ++--
 tp/Texinfo/XS/convert/ConvertXS.xs        |   2 +-
 tp/Texinfo/XS/convert/convert_html.c      | 301 +++++++++++++++++++++++++++++-
 tp/Texinfo/XS/main/builtin_commands.c     |   8 +-
 tp/Texinfo/XS/main/builtin_commands.h     |   1 -
 tp/Texinfo/XS/main/command_data.awk       |   3 +
 tp/Texinfo/XS/main/command_ids.h          |   1 +
 tp/Texinfo/XS/main/get_perl_info.c        | 169 ++++++++++++++---
 tp/Texinfo/XS/main/get_perl_info.h        |   6 +-
 tp/Texinfo/XS/main/utils.c                |  15 ++
 tp/Texinfo/XS/main/utils.h                |  20 +-
 tp/Texinfo/XS/parsetexi/handle_commands.c |   2 +-
 tp/Texinfo/XS/parsetexi/multitable.c      |  15 +-
 tp/Texinfo/XS/parsetexi/parser.c          |   2 +-
 tp/Texinfo/XS/parsetexi/parser.h          |   1 -
 17 files changed, 546 insertions(+), 71 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3a91d96661..a12dfcd600 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2023-10-23  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/Convert/HTML.pm (_convert): make code clearer and more
+       efficient, avoid modifying @args_specification, rename $i as
+       $content_idx.
+
+       * tp/Texinfo/XS/main/builtin_commands.c (element_command_name)
+       (element_builtin_cmd), tp/Texinfo/XS/main/command_data.awk: add
+       to generated command_ids.h a define for BUILTIN_CMD_NUMBER, that
+       replaces the builtin_cmd_number variable.
+
+       * tp/Texinfo/XS/main/utils.c (item_line_parent),
+       tp/Texinfo/XS/parsetexi/multitable.c: move item_line_parent from
+       parsetexi/multitable.c to main/utils.c.
+
+       * tp/Texinfo/Convert/Converter.pm (encode_converter_document),
+       tp/Texinfo/Convert/HTML.pm (converter_initialize),
+       tp/Texinfo/XS/main/get_perl_info.c
+       (register_formatting_reference_with_default)
+       (html_converter_initialize), tp/Texinfo/XS/main/utils.h (enum
+       formatting_reference_status, FORMATTING_REFERENCE, CONVERTER):
+       pass commands_open, commands_conversion, types_open and
+       types_conversion to converter.  Add a status for FORMATTING_REFERENCE
+       to simplify the use of FORMATTING_REFERENCE.
+
+       * tp/Texinfo/XS/convert/convert_html.c (convert_to_html_internal):
+       preliminary implementation.
+
 2023-10-23  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (output): set BODYTEXT early where
diff --git a/tp/Texinfo/Convert/Converter.pm b/tp/Texinfo/Convert/Converter.pm
index 6674ab72cb..c518b37ffb 100644
--- a/tp/Texinfo/Convert/Converter.pm
+++ b/tp/Texinfo/Convert/Converter.pm
@@ -442,7 +442,8 @@ sub encode_converter_document($)
                                       # and set converter_descriptor
                 'document_descriptor' => $self->{'document_descriptor'}};
 
-  foreach my $variable ('style_commands_formatting', 'formatting_function') {
+  foreach my $variable ('style_commands_formatting', 'formatting_function',
+     'types_open', 'types_conversion', 'commands_open', 'commands_conversion') 
{
     if ($self->{$variable}) {
       $result->{$variable} = $self->{$variable};
     }
diff --git a/tp/Texinfo/Convert/HTML.pm b/tp/Texinfo/Convert/HTML.pm
index 0b2c839633..09a5f4a2bd 100644
--- a/tp/Texinfo/Convert/HTML.pm
+++ b/tp/Texinfo/Convert/HTML.pm
@@ -7961,7 +7961,7 @@ my %special_characters = (
   'non_breaking_space' => [undef, '00A0'],
 );
 
-sub _XS_converter_initialize($$$)
+sub _XS_converter_initialize($$$$$$$)
 {
 }
 
@@ -8413,7 +8413,11 @@ sub converter_initialize($)
     my $encoded_converter = $self->encode_converter_document();
     _XS_converter_initialize($encoded_converter,
                              \%default_formatting_references,
-                             \%default_css_string_formatting_references);
+                             \%default_css_string_formatting_references,
+                             \%default_commands_open,
+                             \%default_commands_conversion,
+                             \%default_types_open,
+                             \%default_types_conversion);
   }
 
   return $self;
@@ -12047,21 +12051,18 @@ sub _convert($$;$)
             and exists($self->{'commands_conversion'}->{$element->{'cmdname'}})
             and 
!defined($self->{'commands_conversion'}->{$element->{'cmdname'}}))) {
     if ($debug) {
-      my $string = 'IGNORED';
-      $string .= " \@$element->{'cmdname'}" if ($element->{'cmdname'});
-      $string .= " $element->{'type'}" if ($element->{'type'});
-      print STDERR "$string\n";
+      print STDERR "IGNORED $command_type\n";
     }
     return '';
   }
 
   # Process text
   if (defined($element->{'text'})) {
+    my $result;
     # already converted to html, keep it as is
     if ($element->{'type'} and $element->{'type'} eq '_converted') {
-      return $element->{'text'};
-    }
-    if ($element->{'type'} and $element->{'type'} eq 'untranslated') {
+      $result = $element->{'text'};
+    } elsif ($element->{'type'} and $element->{'type'} eq 'untranslated') {
       my $translated;
       if ($element->{'extra'}
           and $element->{'extra'}->{'translation_context'}) {
@@ -12070,13 +12071,13 @@ sub _convert($$;$)
       } else {
         $translated = $self->gdt($element->{'text'});
       }
-      my $result = $self->_convert($translated, 'translated TEXT');
-      return $result;
-    }
-    my $result = &{$self->{'types_conversion'}->{'text'}} ($self,
+      $result = $self->_convert($translated, 'translated TEXT');
+    } else {
+      $result = &{$self->{'types_conversion'}->{'text'}} ($self,
                                                       $element->{'type'},
                                                       $element,
                                                       $element->{'text'});
+    }
     print STDERR "DO TEXT => `$result'\n" if $debug;
     return $result;
   }
@@ -12178,10 +12179,14 @@ sub _convert($$;$)
           my @args_specification;
           @args_specification = @{$default_commands_args{$command_name}}
             if (defined($default_commands_args{$command_name}));
+          my $spec_nr = scalar(@args_specification);
           my $arg_idx = -1;
           foreach my $arg (@{$element->{'args'}}) {
             $arg_idx++;
-            my $arg_spec = shift @args_specification;
+            my $arg_spec;
+            if ($arg_idx < $spec_nr) {
+              $arg_spec = $args_specification[$arg_idx];
+            }
             if ((!$arg->{'contents'} or !scalar(@{$arg->{'contents'}}))
                 # special case for @value argument
                 and !defined($arg->{'text'})) {
@@ -12379,10 +12384,11 @@ sub _convert($$;$)
   } elsif ($element->{'contents'}) {
     # this happens inside accents, for section/node names, for @images.
     my $content_formatted = '';
-    my $i = 0;
+    my $content_idx = 0;
     foreach my $content (@{$element->{'contents'}}) {
-      $content_formatted .= $self->_convert($content, "$command_type C[$i]");
-      $i++;
+      $content_formatted .= $self->_convert($content,
+                                            "$command_type C[$content_idx]");
+      $content_idx++;
     }
     print STDERR "UNNAMED HOLDER => `$content_formatted'\n" if $debug;
     return $content_formatted;
diff --git a/tp/Texinfo/XS/convert/ConvertXS.xs 
b/tp/Texinfo/XS/convert/ConvertXS.xs
index 81faf0b6b0..067b618550 100644
--- a/tp/Texinfo/XS/convert/ConvertXS.xs
+++ b/tp/Texinfo/XS/convert/ConvertXS.xs
@@ -94,7 +94,7 @@ text_convert_tree (text_options_in, tree_in, unused=0)
         RETVAL
 
 int
-html_converter_initialize (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references)
+html_converter_initialize (SV *converter_in, SV 
*default_formatting_references, SV *default_css_string_formatting_references, 
SV *default_commands_open, SV *default_commands_conversion, SV 
*default_types_open, SV *default_types_conversion)
 
 void
 html_initialize_output_state (SV *converter_in)
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index b00c2b8c63..a798433979 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -20,6 +20,7 @@
 
 #include "global_commands_types.h"
 #include "tree_types.h"
+#include "element_types.h"
 #include "tree.h"
 #include "builtin_commands.h"
 #include "utils.h"
@@ -42,6 +43,9 @@ typedef struct ROOT_AND_UNIT {
     ELEMENT *root;
 } ROOT_AND_UNIT;
 
+static void convert_to_html_internal (CONVERTER *self, ELEMENT *e,
+                                      TEXT *result, char *explanation);
+
 /*
  if OUTPUT_UNITS is defined, the first output unit is used if a proper
  top output unit is not found.
@@ -1264,7 +1268,7 @@ compare_index_name (const void *a, const void *b)
 {
   const INDEX **idx_a = (const INDEX **) a;
   const INDEX **idx_b = (const INDEX **) b;
- 
+
   return strcmp ((*idx_a)->name, (*idx_b)->name);
 }
 
@@ -2176,3 +2180,298 @@ html_convert_init (CONVERTER *self)
     = call_formatting_function_format_title_titlepage (self);
   self->title_titlepage = title_titlepage;
 }
+
+#define ADD(x) text_append (result, x)
+
+/* EXPLANATION is used for debugging */
+void
+convert_to_html_internal (CONVERTER *self, ELEMENT *element,
+                          TEXT *result, char *explanation)
+{
+  /* for debugging, for explanations */
+  TEXT command_type;
+  char *debug_str;
+  char *command_name = element_command_name (element);
+
+  text_init (&command_type);
+  if (command_name)
+    text_printf (&command_type, "@%s ", command_name);
+
+  if (element->type)
+    text_append (&command_type, element_type_names[element->type]);
+
+  if (self->conf->DEBUG > 0)
+    {
+      TEXT debug_str;
+      text_init (&debug_str);
+     /* TODO
+         my @contexts_names = map {defined($_->{'context_name'})
+                                 ? $_->{'context_name'}: 'UNDEF'}
+         @{$self->{'document_context'}->[-1]->{'formatting_context'}};
+    print STDERR "ELEMENT($explanation) (".join('|',@contexts_names)."), ->";
+       */
+      text_printf (&debug_str, "ELEMENT(%s) (), ->", explanation);
+      if (command_name)
+        text_printf (&debug_str, " cmd: %s,", command_name);
+      if (element->type)
+        text_printf (&debug_str, " type: %s",
+                     element_type_names[element->type]);
+      if (element->text.end > 0)
+        {
+          int allocated;
+          char *text = debug_protect_eol (element->text.text, &allocated);
+          text_printf (&debug_str, " text: %s", text);
+          if (allocated)
+            free (text);
+        }
+      text_append (&debug_str, "\n");
+      fprintf (stderr, debug_str.text);
+      free (debug_str.text);
+    }
+
+  if ((element->type
+       && self->types_conversion[element->type].status == FRS_status_ignored)
+      || (element->cmd
+          && self->commands_conversion[element->cmd].status
+               == FRS_status_ignored))
+    {
+      if (self->conf->DEBUG > 0)
+        {
+          fprintf (stderr, "IGNORED %s\n", command_type.text);
+        }
+    }
+
+  /* Process text */
+
+  if (element->text.space > 0)
+    {
+      char *result = 0;
+
+      if (self->conf->DEBUG > 0)
+        {
+          fprintf (stderr, "DO TEXT => `%s'\n", result);
+        }
+
+      return;
+    }
+
+  if (element->cmd
+      && (element->type != ET_def_line
+          && element->type != ET_definfoenclose_command
+          && element->type != ET_index_entry_command))
+    {
+      enum command_id cmd = element->cmd;
+      enum command_id data_cmd = cmd;
+      if (cmd == CM_item && item_line_parent (element))
+        data_cmd = CM_item_LINE;
+
+     /*
+    if ($root_commands{$command_name}) {
+      $self->{'current_root_command'} = $element;
+    }
+      */
+
+      if (self->commands_conversion[cmd].status)
+        {
+          int convert_to_latex = 0;
+          TEXT content_formatted;
+          /* ?? args_formatted = 0; */
+
+          /* */
+
+          if (element->contents.number > 0)
+            {
+              text_init (&content_formatted);
+
+              if (convert_to_latex)
+                {
+                  /* */
+                }
+              else
+                {
+                  int content_idx;
+                  text_append (&content_formatted, "");
+                  for (content_idx = 0; content_idx < element->contents.number;
+                       content_idx++)
+                    {
+                      ELEMENT *content = element->contents.list[content_idx];
+                      char *explanation;
+                      xasprintf (&explanation, "%s c[%d]", command_type.text,
+                                content_idx);
+                      convert_to_html_internal (self, content, 
&content_formatted,
+                                                explanation);
+                      free (explanation);
+                    }
+                }
+            }
+
+          if ((builtin_command_data[data_cmd].flags & CF_brace)
+              || (builtin_command_data[data_cmd].flags & CF_line
+                  && builtin_command_data[data_cmd].data == LINE_line)
+              || ((cmd == CM_item || cmd == CM_itemx)
+                  && element->parent->type == ET_table_term)
+              || (cmd == CM_quotation || cmd == CM_smallquotation)
+              || cmd == CM_float
+              || cmd == CM_cartouche)
+            {
+              /* args_formatted */
+              if (element->args.number > 0)
+                {
+                  int arg_idx;
+                  /* */
+                  for (arg_idx = 0; arg_idx < element->args.number; arg_idx++)
+                    {
+                      ELEMENT *arg = element->args.list[arg_idx];
+                      /* */
+                      if (arg->contents.number <= 0)
+                        /*
+                 # special case for @value argument
+                and !defined($arg->{'text'}))
+                         */
+                        {
+                          /* */
+                          continue;
+                        }
+
+                      /* for arg_type
+                         if */
+
+                      char *explanation;
+                      TEXT arg_formatted;
+                      text_init (&arg_formatted);
+                      xasprintf (&explanation, "%s A[%d]$arg_type",
+                                                command_type.text, arg_idx);
+                      convert_to_html_internal (self, arg, &arg_formatted,
+                                                explanation);
+                      free (explanation);
+                      /* push @$args_formatted, $arg_formatted; */
+                    }
+                }
+            }
+          /* */
+
+          /* args are formatted, now format the command itself */
+
+          /* */
+          return;
+        }
+      else
+        {
+          if (self->conf->DEBUG > 0 || self->conf->VERBOSE > 0)
+            fprintf (stderr, "Command not converted: %s\n", command_name);
+          return;
+        }
+      /* */
+    }
+  else if (element->type)
+    {
+      char *type_name = element_type_names[element->type];
+      TEXT type_result;
+      TEXT content_formatted;
+
+      text_init (&type_result);
+      text_append (&type_result, "");
+
+      /* */
+
+      text_init (&content_formatted);
+
+      if (element->type == ET_definfoenclose_command)
+        {
+          if (element->args.number > 0)
+            {
+              convert_to_html_internal (self, element->args.list[0],
+                                        &content_formatted, 0);
+            }
+        }
+      else if (element->contents.number > 0)
+        {
+          int content_idx;
+          text_append (&content_formatted, "");
+          for (content_idx = 0; content_idx < element->contents.number;
+               content_idx++)
+            {
+              ELEMENT *content = element->contents.list[content_idx];
+              char *explanation;
+              xasprintf (&explanation, "%s c[%d]", command_type.text,
+                        content_idx);
+              convert_to_html_internal (self, content, &content_formatted,
+                                        explanation);
+              free (explanation);
+            }
+        }
+
+      if (self->types_conversion[element->type].status)
+        {
+        /*
+      $result .= &{$self->{'types_conversion'}->{$type_name}} ($self,
+                                                 $type_name,
+                                                 $element,
+                                                 $content_formatted);
+         */
+        }
+      else if (content_formatted.end > 0)
+        {
+          text_append (&type_result, content_formatted.text);
+        }
+      free (content_formatted.text);
+      /* */
+
+      if (self->conf->DEBUG > 0)
+        {
+          fprintf (stderr, "DO type (%s) => `%s'\n", type_name,
+                           type_result.text);
+        }
+      ADD(type_result.text);
+      free (type_result.text);
+
+      return;
+    }
+  else if (element->contents.number > 0)
+    {
+      /* no type, no cmdname, but contents. */
+      /* this happens inside accents, for section/node names, for @images. */
+      TEXT content_formatted;
+
+      text_init (&content_formatted);
+      text_append (&content_formatted, "");
+
+      int content_idx;
+      for (content_idx = 0; content_idx < element->contents.number;
+           content_idx++)
+        {
+          ELEMENT *content = element->contents.list[content_idx];
+          char *explanation;
+          xasprintf (&explanation, "%s c[%d]", command_type.text,
+                     content_idx);
+          convert_to_html_internal (self, content, &content_formatted,
+                                    explanation);
+          free (explanation);
+        }
+
+      if (self->conf->DEBUG > 0)
+        fprintf (stderr, "UNNAMED HOLDER => `%s'\n", content_formatted.text);
+      ADD(content_formatted.text);
+      return;
+    }
+  else
+    {
+      if (self->conf->DEBUG > 0)
+        fprintf (stderr, "UNNAMED empty\n");
+      if (self->types_conversion[0].status
+          && self->types_conversion[0].status != FRS_status_ignored)
+        {
+          /*
+      return &{$self->{'types_conversion'}->{''}} ($self, $element);
+           */
+        }
+      else
+        return;
+    }
+  debug_str = print_element_debug (element, 0);
+  fprintf (stderr, "DEBUG: HERE!(%p:%s)\n", element, debug_str);
+  free (debug_str);
+}
+
+#undef ADD
+
diff --git a/tp/Texinfo/XS/main/builtin_commands.c 
b/tp/Texinfo/XS/main/builtin_commands.c
index e48f2ba509..dc86719f47 100644
--- a/tp/Texinfo/XS/main/builtin_commands.c
+++ b/tp/Texinfo/XS/main/builtin_commands.c
@@ -27,9 +27,6 @@
 
 #include "command_data.c"
 
-int builtin_cmd_number
-  = sizeof (builtin_command_data) / sizeof (builtin_command_data[0]);
-
 static int
 compare_command_fn (const void *a, const void *b)
 {
@@ -68,7 +65,7 @@ lookup_builtin_command (char *cmdname)
 char *
 element_command_name (ELEMENT *e)
 {
-  if (e->cmd && e->cmd < builtin_cmd_number)
+  if (e->cmd && e->cmd < BUILTIN_CMD_NUMBER)
     return builtin_command_data[e->cmd].cmdname;
   else
     {
@@ -90,8 +87,7 @@ element_builtin_cmd (ELEMENT *e)
       && e->parent->type == ET_table_term)
     return CM_item_LINE;
 
-  if (e->cmd && e->cmd <
-        sizeof(builtin_command_data) / sizeof((builtin_command_data)[0]))
+  if (e->cmd && e->cmd < BUILTIN_CMD_NUMBER)
     return e->cmd;
   else if (e->type == ET_definfoenclose_command)
     return CM_definfoenclose_command;
diff --git a/tp/Texinfo/XS/main/builtin_commands.h 
b/tp/Texinfo/XS/main/builtin_commands.h
index 2d3c525973..0f82194223 100644
--- a/tp/Texinfo/XS/main/builtin_commands.h
+++ b/tp/Texinfo/XS/main/builtin_commands.h
@@ -27,7 +27,6 @@ typedef struct command_struct {
 } COMMAND;
 
 extern COMMAND builtin_command_data[];
-extern int builtin_cmd_number;
 
 #define builtin_command_flags(e) \
    (!(e) ? 0 : (builtin_command_data[(e)->cmd].flags))
diff --git a/tp/Texinfo/XS/main/command_data.awk 
b/tp/Texinfo/XS/main/command_data.awk
index ec16fb7509..f1c55f42ca 100644
--- a/tp/Texinfo/XS/main/command_data.awk
+++ b/tp/Texinfo/XS/main/command_data.awk
@@ -144,7 +144,9 @@ END {
 
     # We want the output sorted so we can use bsearch
     PROCINFO["sorted_in"]="@ind_str_asc"
+    i = 1
     for (c in commands) {
+        i++
         # Single character commands with unusual names
         if (c ~ /^[^[:alpha:]]$/) {
                 if (c in inv_bs_escapes) {
@@ -260,6 +262,7 @@ END {
     }
     print "};" > CD
     print "};" > CI
+    print "#define BUILTIN_CMD_NUMBER " i > CI
     print "#endif" > CI
 
     print global_unique_commands_struct_str   > GCT
diff --git a/tp/Texinfo/XS/main/command_ids.h b/tp/Texinfo/XS/main/command_ids.h
index 6ec345a90a..88feaddee9 100644
--- a/tp/Texinfo/XS/main/command_ids.h
+++ b/tp/Texinfo/XS/main/command_ids.h
@@ -409,4 +409,5 @@ CM_hex_7c,
 CM_hex_7d,
 CM_hex_7e,
 };
+#define BUILTIN_CMD_NUMBER 377
 #endif
diff --git a/tp/Texinfo/XS/main/get_perl_info.c 
b/tp/Texinfo/XS/main/get_perl_info.c
index aae561d3e5..6ec0a8319c 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -383,21 +383,81 @@ set_translated_commands (CONVERTER *converter, HV *hv_in)
     }
 }
 
+
+static void
+register_formatting_reference_with_default (char *type_string,
+                FORMATTING_REFERENCE *formatting_reference,
+                char *ref_name, HV *default_hv, HV *customized_hv)
+{
+  SV **default_formatting_reference_sv;
+  SV **formatting_reference_sv;
+
+  dTHX;
+
+  default_formatting_reference_sv
+   = hv_fetch (default_hv, ref_name, strlen (ref_name), 0);
+  formatting_reference_sv
+    = hv_fetch (customized_hv, ref_name, strlen (ref_name), 0);
+  if (default_formatting_reference_sv)
+    {
+      if (SvOK (*default_formatting_reference_sv))
+        {
+          formatting_reference->sv_default = *default_formatting_reference_sv;
+          formatting_reference->status = FRS_status_default_set;
+        }
+      else
+        formatting_reference->status = FRS_status_ignored;
+    }
+  if (formatting_reference_sv)
+    {
+      if SvOK (*formatting_reference_sv)
+        {
+          formatting_reference->sv_reference = *formatting_reference_sv;
+          if (formatting_reference->status != FRS_status_default_set
+              || SvRV(*formatting_reference_sv)
+                   != SvRV(*default_formatting_reference_sv))
+            formatting_reference->status = FRS_status_customization_set;
+        }
+      else
+        formatting_reference->status = FRS_status_ignored;
+    }
+   /*
+  fprintf (stderr, "register: %s %d '%s'\n", type_string,
+           formatting_reference->status, ref_name);
+    */
+}
+
 int
 html_converter_initialize (SV *sv_in, SV *default_formatting_references,
-                           SV *default_css_string_formatting_references)
+                           SV *default_css_string_formatting_references,
+                           SV *default_commands_open,
+                           SV *default_commands_conversion,
+                           SV *default_types_open,
+                           SV *default_types_conversion)
 {
   int i;
   HV *hv_in;
   HV *default_formatting_references_hv;
   HV *default_css_string_formatting_references_hv;
+  HV *default_commands_open_hv;
+  HV *default_commands_conversion_hv;
+  HV *default_types_open_hv;
+  HV *default_types_conversion_hv;
   SV **converter_init_conf_sv;
   SV **converter_sv;
   SV **formatting_function_sv;
   SV **sorted_special_unit_varieties_sv;
   SV **no_arg_commands_formatting_sv;
   SV **style_commands_formatting_sv;
+  SV **types_open_sv;
+  SV **types_conversion_sv;
+  SV **commands_open_sv;
+  SV **commands_conversion_sv;
   HV *formatting_function_hv;
+  HV *commands_open_hv;
+  HV *commands_conversion_hv;
+  HV *types_open_hv;
+  HV *types_conversion_hv;
   CONVERTER *converter = new_converter ();
   int converter_descriptor = 0;
   DOCUMENT *document;
@@ -416,8 +476,8 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
   document = get_sv_document_document (sv_in, 0);
   converter->document = document;
 
-  converter_init_conf_sv = hv_fetch (hv_in, "converter_init_conf",
-                                   strlen ("converter_init_conf"), 0);
+#define FETCH(key) key##_sv = hv_fetch (hv_in, #key, strlen(#key), 0);
+  FETCH(converter_init_conf);
 
   if (converter_init_conf_sv && SvOK (*converter_init_conf_sv))
     {
@@ -433,9 +493,7 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
 
   /* HTML specific */
 
-  formatting_function_sv
-    = hv_fetch (hv_in, "formatting_function",
-                 strlen ("formatting_function"), 0);
+  FETCH(formatting_function);
 
   /* no need to check if it exists */
   formatting_function_hv = (HV *)SvRV (*formatting_function_sv);
@@ -445,18 +503,26 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
       char *ref_name = html_formatting_reference_names[i];
       FORMATTING_REFERENCE *formatting_reference
         = &converter->formatting_references[i];
-      SV **formatting_reference_sv
-        = hv_fetch (formatting_function_hv, ref_name, strlen (ref_name), 0);
       SV **default_formatting_reference_sv
         = hv_fetch (default_formatting_references_hv, ref_name,
                     strlen (ref_name), 0);
+      SV **formatting_reference_sv
+        = hv_fetch (formatting_function_hv, ref_name, strlen (ref_name), 0);
       /* no check, all should exist */
       if (SvOK (*default_formatting_reference_sv))
-        formatting_reference->sv_default = *default_formatting_reference_sv;
+        {
+          formatting_reference->sv_default = *default_formatting_reference_sv;
+          formatting_reference->status = FRS_status_default_set;
+        }
       if (formatting_reference_sv)
         {
           if SvOK (*formatting_reference_sv)
-            formatting_reference->sv_reference = *formatting_reference_sv;
+            {
+              formatting_reference->sv_reference = *formatting_reference_sv;
+              if (formatting_reference->status != FRS_status_default_set
+                  || *formatting_reference_sv != 
*default_formatting_reference_sv)
+                formatting_reference->status = FRS_status_customization_set;
+            }
         }
       else
         fprintf (stderr, "BUG: formatting reference %s not found\n",
@@ -483,9 +549,68 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
                          ref_name);
     }
 
-  sorted_special_unit_varieties_sv
-    = hv_fetch (hv_in, "sorted_special_unit_varieties",
-                 strlen ("sorted_special_unit_varieties"), 0);
+
+  FETCH(commands_open)
+  commands_open_hv = (HV *)SvRV (*commands_open_sv);
+  default_commands_open_hv = (HV *)SvRV (default_commands_open);
+
+  FETCH(commands_conversion)
+  commands_conversion_hv = (HV *)SvRV (*commands_conversion_sv);
+  default_commands_conversion_hv = (HV *)SvRV (default_commands_conversion);
+
+  for (i = 0; i < BUILTIN_CMD_NUMBER; i++)
+    {
+      char *ref_name;
+      if (i == 0)
+        ref_name = "";
+      else
+        ref_name = builtin_command_data[i].cmdname;
+      FORMATTING_REFERENCE *open_formatting_reference
+       = &converter->commands_open[i];
+      FORMATTING_REFERENCE *conversion_formatting_reference
+       = &converter->commands_conversion[i];
+
+      register_formatting_reference_with_default ("command_open",
+        open_formatting_reference, ref_name, default_commands_open_hv,
+        commands_open_hv);
+      register_formatting_reference_with_default ("command_conversion",
+        conversion_formatting_reference, ref_name,
+        default_commands_conversion_hv,
+        commands_conversion_hv);
+    }
+
+
+  FETCH(types_open)
+  types_open_hv = (HV *)SvRV (*types_open_sv);
+  default_types_open_hv = (HV *)SvRV (default_types_open);
+
+  FETCH(types_conversion)
+  types_conversion_hv = (HV *)SvRV (*types_conversion_sv);
+  default_types_conversion_hv = (HV *)SvRV (default_types_conversion);
+
+  for (i = 0; i < ET_special_unit_element+1; i++)
+    {
+      char *ref_name;
+      if (i == 0)
+        ref_name = "";
+      else
+        ref_name = element_type_names[i];
+      FORMATTING_REFERENCE *open_formatting_reference
+       = &converter->types_open[i];
+      FORMATTING_REFERENCE *conversion_formatting_reference
+       = &converter->types_conversion[i];
+
+      register_formatting_reference_with_default ("type_open",
+        open_formatting_reference, ref_name, default_types_open_hv,
+        types_open_hv);
+      register_formatting_reference_with_default ("type_conversion",
+        conversion_formatting_reference, ref_name,
+        default_types_conversion_hv,
+        types_conversion_hv);
+    }
+
+
+  FETCH(sorted_special_unit_varieties)
 
   if (sorted_special_unit_varieties_sv)
     {
@@ -514,8 +639,7 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
 
       converter->special_unit_varieties = special_unit_varieties;
 
-      special_unit_info_sv = hv_fetch (hv_in, "special_unit_info",
-                                       strlen ("special_unit_info"), 0);
+      FETCH(special_unit_info);
 
       special_unit_info_hv = (HV *) SvRV(*special_unit_info_sv);
 
@@ -589,14 +713,7 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
   memset (converter->global_units_directions, 0,
     (D_Last + nr_special_units+1) * sizeof (OUTPUT_UNIT));
 
-  converter->html_command_conversion = (HTML_COMMAND_CONVERSION ***)
-    malloc (builtin_cmd_number * sizeof (HTML_COMMAND_CONVERSION **));
-  memset (converter->html_command_conversion, 0,
-    builtin_cmd_number * sizeof (HTML_COMMAND_CONVERSION **));
-
-  no_arg_commands_formatting_sv
-         = hv_fetch (hv_in, "no_arg_commands_formatting",
-                     strlen ("no_arg_commands_formatting"), 0);
+  FETCH(no_arg_commands_formatting)
 
   if (no_arg_commands_formatting_sv)
     {
@@ -727,9 +844,7 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
              sizeof (enum command_id), compare_ints);
     }
 
-  style_commands_formatting_sv
-         = hv_fetch (hv_in, "style_commands_formatting",
-                     strlen ("style_commands_formatting"), 0);
+  FETCH(style_commands_formatting)
 
   if (style_commands_formatting_sv)
     {
@@ -828,6 +943,8 @@ html_converter_initialize (SV *sv_in, SV 
*default_formatting_references,
         }
     }
 
+#undef FETCH
+
   converter_descriptor = register_converter (converter);
   /* a fresh converter, registered */
   converter = retrieve_converter (converter_descriptor);
diff --git a/tp/Texinfo/XS/main/get_perl_info.h 
b/tp/Texinfo/XS/main/get_perl_info.h
index 397be575c7..87d97b8f19 100644
--- a/tp/Texinfo/XS/main/get_perl_info.h
+++ b/tp/Texinfo/XS/main/get_perl_info.h
@@ -18,7 +18,11 @@ OPTIONS *copy_sv_options (SV *sv_in);
 TEXT_OPTIONS *copy_sv_options_for_convert_text (SV *sv_in);
 
 int html_converter_initialize (SV *sv_in, SV *default_formatting_references,
-                               SV *default_css_string_formatting_references);
+                               SV *default_css_string_formatting_references,
+                               SV *default_commands_open,
+                               SV *default_commands_conversion,
+                               SV *default_types_open,
+                               SV *default_types_conversion);
 CONVERTER *set_output_converter_sv (SV *sv_in, char *warn_string);
 CONVERTER *get_sv_converter (SV *sv_in, char *warn_string);
 
diff --git a/tp/Texinfo/XS/main/utils.c b/tp/Texinfo/XS/main/utils.c
index 790dbe2191..11722237c9 100644
--- a/tp/Texinfo/XS/main/utils.c
+++ b/tp/Texinfo/XS/main/utils.c
@@ -483,6 +483,21 @@ format_expanded_p (struct expanded_format *formats, char 
*format)
   return 0;
 }
 
+/* Return the parent if in an item_line command, @*table */
+ELEMENT *
+item_line_parent (ELEMENT *current)
+{
+  if (current->type == ET_before_item && current->parent)
+    current = current->parent;
+
+  /* FIXME could it be possible that current is a user defined command? */
+  /* if (command_data(current->cmd).data == BLOCK_item_line) */
+  if (builtin_command_data[current->cmd].data == BLOCK_item_line)
+    return current;
+
+  return 0;
+}
+
 ELEMENT *
 get_label_element (ELEMENT *e)
 {
diff --git a/tp/Texinfo/XS/main/utils.h b/tp/Texinfo/XS/main/utils.h
index b451b34109..b5c7cd3b1d 100644
--- a/tp/Texinfo/XS/main/utils.h
+++ b/tp/Texinfo/XS/main/utils.h
@@ -24,6 +24,7 @@
 #include "global_commands_types.h"
 #include "tree_types.h"
 #include "command_ids.h"
+#include "builtin_commands.h"
 
 extern const char *whitespace_chars;
 extern const char *digit_chars;
@@ -250,6 +251,17 @@ enum html_css_string_formatting_reference {
   #undef html_fr_reference
 };
 
+enum formatting_reference_status {
+   FRS_status_none,
+   FRS_status_default_set,        /* default is set, no customization (or
+                                     customization is the same as default) */
+   FRS_status_customization_set,  /* customization is set, no default, or
+                                     not the same as default */
+   FRS_status_ignored,            /* explicitely ignored. Only used for
+                                     types_conversion and commands_conversion
+                                   */
+};
+
 /* down here because it requires error data from before */
 #include "document.h"
 
@@ -348,6 +360,7 @@ typedef struct FORMATTING_REFERENCE {
    but we don't want to include the Perl headers everywhere; */
     void *sv_reference;
     void *sv_default;
+    enum formatting_reference_status status;
 } FORMATTING_REFERENCE;
 
 typedef struct CONVERTER {
@@ -383,12 +396,16 @@ typedef struct CONVERTER {
     HTML_TARGET_LIST *html_targets;
     HTML_TARGET_LIST *html_special_targets[ST_footnote_location+1];
     char **directions_strings[TDS_type_rel+1];
-    HTML_COMMAND_CONVERSION ***html_command_conversion;
+    HTML_COMMAND_CONVERSION **html_command_conversion[BUILTIN_CMD_NUMBER];
     COMMAND_ID_LIST *no_arg_formatted_cmd;
     FORMATTING_REFERENCE
            formatting_references[FR_format_translate_message_string+1];
     FORMATTING_REFERENCE
            css_string_formatting_references[CSSFR_format_protect_text+1];
+    FORMATTING_REFERENCE commands_open[BUILTIN_CMD_NUMBER];
+    FORMATTING_REFERENCE commands_conversion[BUILTIN_CMD_NUMBER];
+    FORMATTING_REFERENCE types_open[ET_special_unit_element+1];
+    FORMATTING_REFERENCE types_conversion[ET_special_unit_element+1];
 } CONVERTER;
 
 typedef struct TARGET_FILENAME {
@@ -456,6 +473,7 @@ void delete_global_info (GLOBAL_INFO *global_info_ref);
 void delete_global_commands (GLOBAL_COMMANDS *global_commands_ref);
 
 char *normalize_encoding_name (char *text, int *possible_encoding);
+ELEMENT *item_line_parent (ELEMENT *current);
 ELEMENT *get_label_element (ELEMENT *e);
 INDEX *indices_info_index_by_name (INDEX **indices_information, char *name);
 INDEX *ultimate_index (INDEX *index);
diff --git a/tp/Texinfo/XS/parsetexi/handle_commands.c 
b/tp/Texinfo/XS/parsetexi/handle_commands.c
index 5e3a5cd82c..6c93460087 100644
--- a/tp/Texinfo/XS/parsetexi/handle_commands.c
+++ b/tp/Texinfo/XS/parsetexi/handle_commands.c
@@ -25,7 +25,7 @@
 #include "command_ids.h"
 #include "element_types.h"
 #include "text.h"
-/* for isascii_alnum, whitespace_chars and read_flag_name */
+/* for isascii_alnum whitespace_chars read_flag_name item_line_parent */
 #include "utils.h"
 #include "counter.h"
 #include "context_stack.h"
diff --git a/tp/Texinfo/XS/parsetexi/multitable.c 
b/tp/Texinfo/XS/parsetexi/multitable.c
index 97a0fb374c..0e1cc87d04 100644
--- a/tp/Texinfo/XS/parsetexi/multitable.c
+++ b/tp/Texinfo/XS/parsetexi/multitable.c
@@ -18,24 +18,13 @@
 #include "tree_types.h"
 #include "tree.h"
 #include "errors.h"
+/* for item_line_parent */
+#include "utils.h"
 #include "builtin_commands.h"
 #include "commands.h"
 /* check_no_text */
 #include "handle_commands.h"
 
-/* Return the parent if in an item_line command, @*table */
-ELEMENT *
-item_line_parent (ELEMENT *current)
-{
-  if (current->type == ET_before_item && current->parent)
-    current = current->parent;
-
-  if (command_data(current->cmd).data == BLOCK_item_line)
-    return current;
-
-  return 0;
-}
-
 /* Return the parent if in a multitable. */
 ELEMENT *
 item_multitable_parent (ELEMENT *current)
diff --git a/tp/Texinfo/XS/parsetexi/parser.c b/tp/Texinfo/XS/parsetexi/parser.c
index e4e5699a14..34e13a0f97 100644
--- a/tp/Texinfo/XS/parsetexi/parser.c
+++ b/tp/Texinfo/XS/parsetexi/parser.c
@@ -23,7 +23,7 @@
 #include "element_types.h"
 #include "tree_types.h"
 #include "tree.h"
-/* for isascii_alnum, whitespace_chars, read_flag_name,
+/* for isascii_alnum, whitespace_chars, read_flag_name, item_line_parent
    delete_global_info, parse_line_directive, count_multibyte */
 #include "utils.h"
 /* for relocate_source_marks */
diff --git a/tp/Texinfo/XS/parsetexi/parser.h b/tp/Texinfo/XS/parsetexi/parser.h
index 12eb724d7e..9857cff087 100644
--- a/tp/Texinfo/XS/parsetexi/parser.h
+++ b/tp/Texinfo/XS/parsetexi/parser.h
@@ -142,7 +142,6 @@ extern COUNTER count_remaining_args, count_items, 
count_cells;
 ELEMENT *setup_document_root_and_before_node_section (void);
 
 /* In multitable.c */
-ELEMENT *item_line_parent (ELEMENT *current);
 ELEMENT *item_multitable_parent (ELEMENT *current);
 void gather_previous_item (ELEMENT *current, enum command_id next_command);
 



reply via email to

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