texinfo-commits
[Top][All Lists]
Advanced

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

branch master updated: * tp/Texinfo/XS/main/build_perl_info.c, tp/Texinf


From: Patrice Dumas
Subject: branch master updated: * tp/Texinfo/XS/main/build_perl_info.c, tp/Texinfo/XS/main/build_perl_info.c: move code specific of HTML to the end of the files.
Date: Mon, 06 Nov 2023 15:45:16 -0500

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

pertusus pushed a commit to branch master
in repository texinfo.

The following commit(s) were added to refs/heads/master by this push:
     new 423727ffac * tp/Texinfo/XS/main/build_perl_info.c, 
tp/Texinfo/XS/main/build_perl_info.c: move code specific of HTML to the end of 
the files.
423727ffac is described below

commit 423727ffac3b7e2b51020910e5e2a094850298ea
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Mon Nov 6 21:45:06 2023 +0100

    * tp/Texinfo/XS/main/build_perl_info.c,
    tp/Texinfo/XS/main/build_perl_info.c: move code specific of HTML to
    the end of the files.
---
 ChangeLog                            |    6 +
 tp/Texinfo/XS/main/build_perl_info.c |  671 +++++++-------
 tp/Texinfo/XS/main/get_perl_info.c   | 1614 +++++++++++++++++-----------------
 3 files changed, 1152 insertions(+), 1139 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index df90ba832a..19a7ade3ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2023-11-06  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/main/build_perl_info.c,
+       tp/Texinfo/XS/main/build_perl_info.c: move code specific of HTML to
+       the end of the files.
+
 2023-11-06  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (_sort_index_entries),
diff --git a/tp/Texinfo/XS/main/build_perl_info.c 
b/tp/Texinfo/XS/main/build_perl_info.c
index 5fef2b93f4..555188208c 100644
--- a/tp/Texinfo/XS/main/build_perl_info.c
+++ b/tp/Texinfo/XS/main/build_perl_info.c
@@ -1090,7 +1090,7 @@ get_errors (ERROR_MESSAGE* error_list, size_t 
error_number)
 
 
 /* build a minimal document, without tree/global commands/indices, only
-   with the document descriptor information, errors and information that does
+   with the document descriptor information, errors and information that do
    not refer directly to tree elements */
 SV *
 get_document (size_t document_descriptor)
@@ -1462,6 +1462,326 @@ build_output_units_list (size_t output_units_descriptor)
   return newRV_noinc ((SV *) av_output_units);
 }
 
+/* implements Texinfo::Report::add_formatted_message */
+void
+pass_converter_errors (ERROR_MESSAGE_LIST *error_messages,
+                       HV *converter_hv)
+{
+  int i;
+  SV **errors_warnings_sv;
+  SV **error_nrs_sv;
+
+  dTHX;
+
+  if (!error_messages)
+    {
+      fprintf (stderr, "pass_converter_errors: NOTE: no error_messages\n");
+      return;
+    }
+
+  if (!converter_hv)
+    {
+      fprintf (stderr, "pass_converter_errors: BUG: no perl converter\n");
+      return;
+    }
+
+  errors_warnings_sv = hv_fetch (converter_hv, "errors_warnings",
+                                      strlen ("errors_warnings"), 0);
+
+  error_nrs_sv = hv_fetch (converter_hv, "error_nrs",
+                                      strlen ("error_nrs"), 0);
+
+  if (errors_warnings_sv && SvOK(*errors_warnings_sv))
+    {
+      AV *av = (AV *)SvRV (*errors_warnings_sv);
+      int error_nrs = 0;
+      if (error_nrs_sv)
+        error_nrs = SvIV (*error_nrs_sv);
+
+      for (i = 0; i < error_messages->number; i++)
+        {
+          ERROR_MESSAGE error_msg = error_messages->list[i];
+          SV *sv = convert_error (error_msg);
+
+          if (error_msg.type == MSG_error && !error_msg.continuation)
+            error_nrs++;
+          av_push (av, sv);
+        }
+      if (error_nrs)
+        hv_store (converter_hv, "error_nrs",
+                  strlen ("error_nrs"), newSViv (error_nrs), 0);
+    }
+
+  wipe_error_message_list (error_messages);
+}
+
+void
+rebuild_output_units_list (SV *output_units_sv, size_t output_units_descriptor)
+{
+  AV *av_output_units;
+  int status;
+
+  OUTPUT_UNIT_LIST *output_units
+    = retrieve_output_units (output_units_descriptor);
+
+  dTHX;
+
+  if (! SvOK (output_units_sv))
+    {
+      if (output_units && output_units->number)
+        fprintf (stderr, "BUG: no input sv for %zu output units (%zu)",
+                 output_units->number, output_units_descriptor);
+      return;
+    }
+
+  av_output_units = (AV *) SvRV (output_units_sv);
+  av_clear (av_output_units);
+
+  /* TODO cannot associate output_units_descriptor. A problem? */
+  if (!output_units || !output_units->number)
+    return;
+
+  status = fill_output_units (av_output_units, output_units);
+
+  /* warn? */
+  if (!status)
+    return;
+
+  /* store in the first perl output unit of the list */
+  hv_store (output_units->list[0]->hv, "output_units_descriptor",
+            strlen ("output_units_descriptor"),
+            newSViv (output_units_descriptor), 0);
+}
+
+SV *
+build_filenames (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *normalized_filename = output_unit_file->normalized_filename;
+          SV *normalized_filename_sv = newSVpv_utf8 (normalized_filename, 0);
+
+          hv_store_ent (hv, normalized_filename_sv,
+                    newSVpv_utf8 (output_unit_file->filename, 0), 0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_file_counters (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *filename = output_unit_file->filename;
+          SV *filename_sv = newSVpv_utf8 (filename, 0);
+
+          hv_store_ent (hv, filename_sv, newSViv (output_unit_file->counter), 
0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+SV *
+build_out_filepaths (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  int i;
+  HV *hv;
+
+  dTHX;
+
+  hv = newHV ();
+
+  if (output_unit_files)
+    {
+      for (i = 0; i < output_unit_files->number; i++)
+        {
+          FILE_NAME_PATH_COUNTER *output_unit_file
+            = &output_unit_files->list[i];
+          char *filename = output_unit_file->filename;
+          SV *filename_sv = newSVpv_utf8 (filename, 0);
+
+          hv_store_ent (hv, filename_sv,
+                        newSVpv_utf8 (output_unit_file->filepath, 0), 0);
+        }
+    }
+
+  return newRV_noinc ((SV *) hv);
+}
+
+void
+pass_output_unit_files (SV *converter_sv,
+                        FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
+{
+  SV *filenames_sv;
+  SV *file_counters_sv;
+  SV *out_filepaths_sv;
+
+  dTHX;
+
+  HV *converter_hv = (HV *) SvRV (converter_sv);
+
+
+  filenames_sv = build_filenames (output_unit_files);
+  file_counters_sv = build_file_counters (output_unit_files);
+  out_filepaths_sv = build_out_filepaths (output_unit_files);
+
+#define STORE(key) \
+  hv_store (converter_hv, #key, strlen (#key), key##_sv, 0); \
+  SvREFCNT_inc (key##_sv);
+  STORE(filenames);
+  STORE (file_counters);
+  STORE (out_filepaths);
+#undef STORE
+}
+
+/* Texinfo::Common output_files_information API */
+void
+build_output_files_unclosed_files (HV *hv,
+                    OUTPUT_FILES_INFORMATION *output_files_information)
+{
+  SV **unclosed_files_sv;
+  HV *unclosed_files_hv;
+
+  FILE_STREAM_LIST *unclosed_files;
+  int i;
+
+  dTHX;
+
+  unclosed_files_sv = hv_fetch (hv, "unclosed_files",
+                                strlen ("unclosed_files"), 0);
+
+  if (!unclosed_files_sv)
+    {
+      unclosed_files_hv = newHV ();
+      hv_store (hv, "unclosed_files", strlen ("unclosed_files"),
+                newRV_noinc ((SV *) unclosed_files_hv), 0);
+    }
+  else
+    {
+      unclosed_files_hv = (HV *)SvRV (*unclosed_files_sv);
+    }
+
+  unclosed_files = &output_files_information->unclosed_files;
+  if (unclosed_files->number > 0)
+    {
+      for (i = 0; i < unclosed_files->number; i++)
+        {
+          FILE_STREAM *file_stream = &unclosed_files->list[i];
+          char *file_path = file_stream->file_path;
+          /* FIXME no way to pass back the FILE *stream see comments in
+             converter_types.h.  So for now we close here.
+          SV *file_path_sv = newSVpv_byte (file_path, 0);
+          hv_store_ent (unclosed_files_hv, file_path_sv, newSV (0), 0);
+           */
+          if (strcmp (file_path, "-"))
+            {
+              fclose (file_stream->stream);
+            }
+        }
+    }
+}
+
+/* input hv should be an output_files hv, in general setup by
+ $converter->{'output_files'} = Texinfo::Common::output_files_initialize(); */
+void
+build_output_files_opened_files (HV *hv,
+                    OUTPUT_FILES_INFORMATION *output_files_information)
+{
+  SV **opened_files_sv;
+  AV *opened_files_av;
+
+  STRING_LIST *opened_files;
+  int i;
+
+  dTHX;
+
+  opened_files_sv = hv_fetch (hv, "opened_files", strlen ("opened_files"), 0);
+
+  if (!opened_files_sv)
+    {
+      opened_files_av = newAV ();
+      hv_store (hv, "opened_files", strlen ("opened_files"),
+                newRV_noinc ((SV *) opened_files_av), 0);
+    }
+  else
+    {
+      opened_files_av = (AV *)SvRV (*opened_files_sv);
+    }
+
+  opened_files = &output_files_information->opened_files;
+  if (opened_files->number > 0)
+    {
+      for (i = 0; i < opened_files->number; i++)
+        {
+          char *file_path = opened_files->list[i];
+          SV *file_path_sv = newSVpv_byte (file_path, 0);
+          av_push (opened_files_av, file_path_sv);
+        }
+    }
+}
+
+/* for the perl converter associated to CONVERTER */
+void
+build_output_files_information (CONVERTER *converter)
+{
+  HV *hv;
+  SV **output_files_sv;
+  HV *output_files_hv;
+
+  dTHX;
+
+  if (!converter->hv)
+    return;
+
+  hv = converter->hv;
+
+  output_files_sv = hv_fetch (hv, "output_files",
+                                strlen ("output_files"), 0);
+
+  if (!output_files_sv)
+    {
+      output_files_hv = newHV ();
+      hv_store (hv, "output_files", strlen ("output_files"),
+                newRV_noinc ((SV *) output_files_hv), 0);
+    }
+  else
+    {
+      output_files_hv = (HV *)SvRV (*output_files_sv);
+    }
+
+  build_output_files_opened_files (output_files_hv,
+                                   &converter->output_files_information);
+  build_output_files_unclosed_files (output_files_hv,
+                                   &converter->output_files_information);
+}
+
+
+/* HTML specific */
 HV *
 build_html_element_targets (HTML_TARGET_LIST *html_targets)
 {
@@ -1587,118 +1907,27 @@ build_html_seen_ids (STRING_LIST *seen_ids)
         {
           char *target = seen_ids->list[i];
           SV *target_sv = newSVpv_utf8 (target, 0);
-          hv_store_ent (hv, target_sv, newSViv (1), 0);
-        }
-    }
-
-  return hv;
-}
-
-void
-pass_html_seen_ids (SV *converter_sv, STRING_LIST *seen_ids)
-{
-  HV *seen_ids_hv;
-  HV *hv;
-
-  dTHX;
-
-  hv = (HV *) SvRV (converter_sv);
-
-  seen_ids_hv = build_html_seen_ids (seen_ids);
-
-  hv_store (hv, "seen_ids", strlen ("seen_ids"),
-            newRV_noinc ((SV *) seen_ids_hv), 0);
-}
-
-/* implements Texinfo::Report::add_formatted_message */
-void
-pass_converter_errors (ERROR_MESSAGE_LIST *error_messages,
-                       HV *converter_hv)
-{
-  int i;
-  SV **errors_warnings_sv;
-  SV **error_nrs_sv;
-
-  dTHX;
-
-  if (!error_messages)
-    {
-      fprintf (stderr, "pass_converter_errors: NOTE: no error_messages\n");
-      return;
-    }
-
-  if (!converter_hv)
-    {
-      fprintf (stderr, "pass_converter_errors: BUG: no perl converter\n");
-      return;
-    }
-
-  errors_warnings_sv = hv_fetch (converter_hv, "errors_warnings",
-                                      strlen ("errors_warnings"), 0);
-
-  error_nrs_sv = hv_fetch (converter_hv, "error_nrs",
-                                      strlen ("error_nrs"), 0);
-
-  if (errors_warnings_sv && SvOK(*errors_warnings_sv))
-    {
-      AV *av = (AV *)SvRV (*errors_warnings_sv);
-      int error_nrs = 0;
-      if (error_nrs_sv)
-        error_nrs = SvIV (*error_nrs_sv);
-
-      for (i = 0; i < error_messages->number; i++)
-        {
-          ERROR_MESSAGE error_msg = error_messages->list[i];
-          SV *sv = convert_error (error_msg);
-
-          if (error_msg.type == MSG_error && !error_msg.continuation)
-            error_nrs++;
-          av_push (av, sv);
-        }
-      if (error_nrs)
-        hv_store (converter_hv, "error_nrs",
-                  strlen ("error_nrs"), newSViv (error_nrs), 0);
-    }
-
-  wipe_error_message_list (error_messages);
-}
-
-void
-rebuild_output_units_list (SV *output_units_sv, size_t output_units_descriptor)
-{
-  AV *av_output_units;
-  int status;
-
-  OUTPUT_UNIT_LIST *output_units
-    = retrieve_output_units (output_units_descriptor);
-
-  dTHX;
-
-  if (! SvOK (output_units_sv))
-    {
-      if (output_units && output_units->number)
-        fprintf (stderr, "BUG: no input sv for %zu output units (%zu)",
-                 output_units->number, output_units_descriptor);
-      return;
+          hv_store_ent (hv, target_sv, newSViv (1), 0);
+        }
     }
 
-  av_output_units = (AV *) SvRV (output_units_sv);
-  av_clear (av_output_units);
+  return hv;
+}
 
-  /* TODO cannot associate output_units_descriptor. A problem? */
-  if (!output_units || !output_units->number)
-    return;
+void
+pass_html_seen_ids (SV *converter_sv, STRING_LIST *seen_ids)
+{
+  HV *seen_ids_hv;
+  HV *hv;
 
-  status = fill_output_units (av_output_units, output_units);
+  dTHX;
 
-  /* warn? */
-  if (!status)
-    return;
+  hv = (HV *) SvRV (converter_sv);
 
-  /* store in the first perl output unit of the list */
-  hv_store (output_units->list[0]->hv, "output_units_descriptor",
-            strlen ("output_units_descriptor"),
-            newSViv (output_units_descriptor), 0);
+  seen_ids_hv = build_html_seen_ids (seen_ids);
+
+  hv_store (hv, "seen_ids", strlen ("seen_ids"),
+            newRV_noinc ((SV *) seen_ids_hv), 0);
 }
 
 SV *
@@ -1857,112 +2086,6 @@ pass_html_elements_in_file_count (SV *converter_sv,
             newRV_noinc ((SV *) elements_in_file_count_hv), 0);
 }
 
-SV *
-build_filenames (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
-{
-  int i;
-  HV *hv;
-
-  dTHX;
-
-  hv = newHV ();
-
-  if (output_unit_files)
-    {
-      for (i = 0; i < output_unit_files->number; i++)
-        {
-          FILE_NAME_PATH_COUNTER *output_unit_file
-            = &output_unit_files->list[i];
-          char *normalized_filename = output_unit_file->normalized_filename;
-          SV *normalized_filename_sv = newSVpv_utf8 (normalized_filename, 0);
-
-          hv_store_ent (hv, normalized_filename_sv,
-                    newSVpv_utf8 (output_unit_file->filename, 0), 0);
-        }
-    }
-
-  return newRV_noinc ((SV *) hv);
-}
-
-SV *
-build_file_counters (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
-{
-  int i;
-  HV *hv;
-
-  dTHX;
-
-  hv = newHV ();
-
-  if (output_unit_files)
-    {
-      for (i = 0; i < output_unit_files->number; i++)
-        {
-          FILE_NAME_PATH_COUNTER *output_unit_file
-            = &output_unit_files->list[i];
-          char *filename = output_unit_file->filename;
-          SV *filename_sv = newSVpv_utf8 (filename, 0);
-
-          hv_store_ent (hv, filename_sv, newSViv (output_unit_file->counter), 
0);
-        }
-    }
-
-  return newRV_noinc ((SV *) hv);
-}
-
-SV *
-build_out_filepaths (FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
-{
-  int i;
-  HV *hv;
-
-  dTHX;
-
-  hv = newHV ();
-
-  if (output_unit_files)
-    {
-      for (i = 0; i < output_unit_files->number; i++)
-        {
-          FILE_NAME_PATH_COUNTER *output_unit_file
-            = &output_unit_files->list[i];
-          char *filename = output_unit_file->filename;
-          SV *filename_sv = newSVpv_utf8 (filename, 0);
-
-          hv_store_ent (hv, filename_sv,
-                        newSVpv_utf8 (output_unit_file->filepath, 0), 0);
-        }
-    }
-
-  return newRV_noinc ((SV *) hv);
-}
-
-void
-pass_output_unit_files (SV *converter_sv,
-                        FILE_NAME_PATH_COUNTER_LIST *output_unit_files)
-{
-  SV *filenames_sv;
-  SV *file_counters_sv;
-  SV *out_filepaths_sv;
-
-  dTHX;
-
-  HV *converter_hv = (HV *) SvRV (converter_sv);
-
-
-  filenames_sv = build_filenames (output_unit_files);
-  file_counters_sv = build_file_counters (output_unit_files);
-  out_filepaths_sv = build_out_filepaths (output_unit_files);
-
-#define STORE(key) \
-  hv_store (converter_hv, #key, strlen (#key), key##_sv, 0); \
-  SvREFCNT_inc (key##_sv);
-  STORE(filenames);
-  STORE (file_counters);
-  STORE (out_filepaths);
-#undef STORE
-}
-
 void
 build_html_translated_names (HV *hv, CONVERTER *converter)
 {
@@ -2591,127 +2714,6 @@ build_html_formatting_state (CONVERTER *converter, 
unsigned long flags)
   return newRV_noinc ((SV *) hv);
 }
 
-/* Texinfo::Common output_files_information API */
-void
-build_output_files_unclosed_files (HV *hv,
-                    OUTPUT_FILES_INFORMATION *output_files_information)
-{
-  SV **unclosed_files_sv;
-  HV *unclosed_files_hv;
-
-  FILE_STREAM_LIST *unclosed_files;
-  int i;
-
-  dTHX;
-
-  unclosed_files_sv = hv_fetch (hv, "unclosed_files",
-                                strlen ("unclosed_files"), 0);
-
-  if (!unclosed_files_sv)
-    {
-      unclosed_files_hv = newHV ();
-      hv_store (hv, "unclosed_files", strlen ("unclosed_files"),
-                newRV_noinc ((SV *) unclosed_files_hv), 0);
-    }
-  else
-    {
-      unclosed_files_hv = (HV *)SvRV (*unclosed_files_sv);
-    }
-
-  unclosed_files = &output_files_information->unclosed_files;
-  if (unclosed_files->number > 0)
-    {
-      for (i = 0; i < unclosed_files->number; i++)
-        {
-          FILE_STREAM *file_stream = &unclosed_files->list[i];
-          char *file_path = file_stream->file_path;
-          /* FIXME no way to pass back the FILE *stream see comments in
-             converter_types.h.  So for now we close here.
-          SV *file_path_sv = newSVpv_byte (file_path, 0);
-          hv_store_ent (unclosed_files_hv, file_path_sv, newSV (0), 0);
-           */
-          if (strcmp (file_path, "-"))
-            {
-              fclose (file_stream->stream);
-            }
-        }
-    }
-}
-
-/* input hv should be an output_files hv, in general setup by
- $converter->{'output_files'} = Texinfo::Common::output_files_initialize(); */
-void
-build_output_files_opened_files (HV *hv,
-                    OUTPUT_FILES_INFORMATION *output_files_information)
-{
-  SV **opened_files_sv;
-  AV *opened_files_av;
-
-  STRING_LIST *opened_files;
-  int i;
-
-  dTHX;
-
-  opened_files_sv = hv_fetch (hv, "opened_files", strlen ("opened_files"), 0);
-
-  if (!opened_files_sv)
-    {
-      opened_files_av = newAV ();
-      hv_store (hv, "opened_files", strlen ("opened_files"),
-                newRV_noinc ((SV *) opened_files_av), 0);
-    }
-  else
-    {
-      opened_files_av = (AV *)SvRV (*opened_files_sv);
-    }
-
-  opened_files = &output_files_information->opened_files;
-  if (opened_files->number > 0)
-    {
-      for (i = 0; i < opened_files->number; i++)
-        {
-          char *file_path = opened_files->list[i];
-          SV *file_path_sv = newSVpv_byte (file_path, 0);
-          av_push (opened_files_av, file_path_sv);
-        }
-    }
-}
-
-/* for the perl converter associated to CONVERTER */
-void
-build_output_files_information (CONVERTER *converter)
-{
-  HV *hv;
-  SV **output_files_sv;
-  HV *output_files_hv;
-
-  dTHX;
-
-  if (!converter->hv)
-    return;
-
-  hv = converter->hv;
-
-  output_files_sv = hv_fetch (hv, "output_files",
-                                strlen ("output_files"), 0);
-
-  if (!output_files_sv)
-    {
-      output_files_hv = newHV ();
-      hv_store (hv, "output_files", strlen ("output_files"),
-                newRV_noinc ((SV *) output_files_hv), 0);
-    }
-  else
-    {
-      output_files_hv = (HV *)SvRV (*output_files_sv);
-    }
-
-  build_output_files_opened_files (output_files_hv,
-                                   &converter->output_files_information);
-  build_output_files_unclosed_files (output_files_hv,
-                                   &converter->output_files_information);
-}
-
 SV *
 build_html_command_formatted_args (HTML_ARGS_FORMATTED *args_formatted)
 {
@@ -2785,3 +2787,4 @@ build_replaced_substrings (NAMED_STRING_ELEMENT_LIST 
*replaced_substrings)
 
   return newRV_noinc ((SV *) hv);
 }
+
diff --git a/tp/Texinfo/XS/main/get_perl_info.c 
b/tp/Texinfo/XS/main/get_perl_info.c
index 62f679e863..80a60913f5 100644
--- a/tp/Texinfo/XS/main/get_perl_info.c
+++ b/tp/Texinfo/XS/main/get_perl_info.c
@@ -350,15 +350,6 @@ get_sv_converter (SV *sv_in, char *warn_string)
   return converter;
 }
 
-int
-compare_ints (const void *a, const void *b)
-{
-  const enum command_id *int_a = (const enum command_id *) a;
-  const enum command_id *int_b = (const enum command_id *) b;
-
-  return (*int_a > *int_b) - (*int_a < *int_b);
-}
-
 void
 set_translated_commands (CONVERTER *converter, HV *hv_in)
 {
@@ -413,67 +404,6 @@ set_translated_commands (CONVERTER *converter, HV *hv_in)
     }
 }
 
-static SV **
-register_formatting_reference_default (char *type_string,
-                FORMATTING_REFERENCE *formatting_reference,
-                const char *ref_name, HV *default_hv)
-{
-  SV **default_formatting_reference_sv;
-
-  dTHX;
-
-  default_formatting_reference_sv
-   = hv_fetch (default_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;
-          /* will be replaced by customization if there are not only defaults 
*/
-          formatting_reference->sv_reference = 
*default_formatting_reference_sv;
-          formatting_reference->status = FRS_status_default_set;
-        }
-      else
-        formatting_reference->status = FRS_status_ignored;
-    }
-  return default_formatting_reference_sv;
-}
-
-static void
-register_formatting_reference_with_default (char *type_string,
-                FORMATTING_REFERENCE *formatting_reference,
-                const char *ref_name, HV *default_hv, HV *customized_hv)
-{
-  SV **default_formatting_reference_sv;
-  SV **formatting_reference_sv;
-
-  dTHX;
-
-  default_formatting_reference_sv = register_formatting_reference_default(
-                 type_string, formatting_reference, ref_name, default_hv);
-
-  formatting_reference_sv
-    = hv_fetch (customized_hv, ref_name, strlen (ref_name), 0);
-  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);
-    */
-}
-
 CONVERTER *
 converter_initialize (SV *converter_sv)
 {
@@ -510,555 +440,770 @@ converter_initialize (SV *converter_sv)
   return converter;
 }
 
-int
-html_converter_initialize_sv (SV *converter_sv,
-                              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)
+/* initialize an XS converter from a perl converter right before conversion */
+CONVERTER *
+set_output_converter_sv (SV *sv_in, char *warn_string)
 {
-  int i;
-  HV *converter_hv;
-  HV *default_formatting_references_hv;
-  HV *default_css_string_formatting_references_hv;
-  HV *default_commands_open_hv;
-  HV *default_commands_conversion_hv;
-  HV *default_css_string_commands_conversion_hv;
-  HV *default_types_open_hv;
-  HV *default_types_conversion_hv;
-  HV *default_css_string_types_conversion_hv;
-  HV *default_output_units_conversion_hv;
-  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;
-  SV **output_units_conversion_sv;
-  SV **code_types_sv;
-  SV **pre_class_types_sv;
-  HV *formatting_function_hv;
-  HV *commands_open_hv;
-  HV *commands_conversion_hv;
-  HV *types_open_hv;
-  HV *types_conversion_hv;
-  HV *output_units_conversion_hv;
-  int converter_descriptor = 0;
-  CONVERTER *converter;
+  HV *hv_in;
+  SV **converter_options_sv;
+  SV **converter_init_conf_sv;
+  CONVERTER *converter = 0;
 
   dTHX;
 
-  converter = converter_initialize (converter_sv);
-
-  converter_hv = (HV *)SvRV (converter_sv);
-
-  default_formatting_references_hv
-    = (HV *)SvRV (default_formatting_references);
-  default_css_string_formatting_references_hv
-    = (HV *)SvRV (default_css_string_formatting_references);
-
-#define FETCH(key) key##_sv = hv_fetch (converter_hv, #key, strlen(#key), 0);
-  FETCH(formatting_function);
+  converter = get_sv_converter (sv_in, warn_string);
 
-  /* no need to check if it exists */
-  formatting_function_hv = (HV *)SvRV (*formatting_function_sv);
+  hv_in = (HV *)SvRV (sv_in);
+  converter_options_sv = hv_fetch (hv_in, "conf",
+                                   strlen ("conf"), 0);
 
-  for (i = 0; i < FR_format_translate_message+1; i++)
+  if (converter_options_sv)
     {
-      char *ref_name = html_formatting_reference_names[i];
-      FORMATTING_REFERENCE *formatting_reference
-        = &converter->formatting_references[i];
-      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 for existence, all should exist */
-      if (SvOK (*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;
-              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",
-                         ref_name);
+      converter->conf
+         = copy_sv_options (*converter_options_sv);
     }
 
-  /* copy the normal formatting references and replace the css strings
-     specific references */
-  memcpy (&converter->css_string_formatting_references,
-          &converter->formatting_references,
-      (FR_format_translate_message+1) * sizeof (FORMATTING_REFERENCE));
+  converter_init_conf_sv = hv_fetch (hv_in, "output_init_conf",
+                                   strlen ("output_init_conf"), 0);
 
-  for (i = 0; i < FR_format_translate_message+1; i++)
+  if (converter_init_conf_sv && SvOK(*converter_init_conf_sv))
     {
-      char *ref_name = html_formatting_reference_names[i];
-      SV **default_formatting_reference_sv
-        = hv_fetch (default_css_string_formatting_references_hv, ref_name,
-                    strlen (ref_name), 0);
+      if (converter->init_conf)
+        free_options (converter->init_conf);
+      free (converter->init_conf);
 
-      /* no customization, current is the default */
-      if (default_formatting_reference_sv
-          && SvOK (*default_formatting_reference_sv))
-        {
-          FORMATTING_REFERENCE *formatting_reference
-            = &converter->css_string_formatting_references[i];
-          formatting_reference->sv_default = *default_formatting_reference_sv;
-          formatting_reference->sv_reference = 
*default_formatting_reference_sv;
-          formatting_reference->status = FRS_status_default_set;
-        }
+      converter->init_conf
+         = copy_sv_options (*converter_init_conf_sv);
     }
 
-  FETCH(commands_open)
-  commands_open_hv = (HV *)SvRV (*commands_open_sv);
-  default_commands_open_hv = (HV *)SvRV (default_commands_open);
+  return converter;
+}
 
-  FETCH(commands_conversion)
-  commands_conversion_hv = (HV *)SvRV (*commands_conversion_sv);
-  default_commands_conversion_hv = (HV *)SvRV (default_commands_conversion);
+/* code in comments allow to sort the index names to have a fixed order
+   in the data structure.  Not clear that it is useful or not, not enabled
+   for now */
+void
+get_sv_index_entries_sorted_by_letter (CONVERTER *converter,
+                                       SV *index_entries_sorted_by_letter)
+{
+  HV *hv_in;
+  /* for sorted index names
+  AV *index_names_av;
+  SV **index_names_av_array;
+  SV **sorted_index_names_av_array;
+  I32 i;
+   */
+  I32 index_names_nr;
 
-  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];
+  SSize_t j;
+  INDEX **index_names = converter->document->index_names;
 
-      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);
-    }
+  dTHX;
 
-  default_css_string_commands_conversion_hv
-    = (HV *)SvRV (default_css_string_commands_conversion);
-  /* copy the normal formatting references and replace the css strings
-     specific references */
-  memcpy (&converter->css_string_commands_conversion,
-          &converter->commands_conversion,
-      (BUILTIN_CMD_NUMBER) * sizeof (FORMATTING_REFERENCE));
+  if (!SvOK (index_entries_sorted_by_letter))
+    return;
 
-  for (i = 0; i < BUILTIN_CMD_NUMBER; i++)
-    {
-      char *ref_name;
-      if (i == 0)
-        ref_name = "";
-      else
-        ref_name = builtin_command_data[i].cmdname;
+  hv_in = (HV *)SvRV (index_entries_sorted_by_letter);
 
-     FORMATTING_REFERENCE *conversion_formatting_reference
-       = &converter->css_string_commands_conversion[i];
-
-     register_formatting_reference_default ("css_command_conversion",
-        conversion_formatting_reference, ref_name,
-        default_css_string_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);
+  index_names_nr = hv_iterinit (hv_in);
 
-  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];
+  /* when there is a memcpy just below, a condition that avoids negative
+     index_names_nr is important to avoid a gcc warning */
+  if (index_names_nr <= 0)
+    return;
 
-      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);
-    }
+  /* doing an AV with the keys (first step of sorting)
+  index_names_av = newAV ();
 
-  default_css_string_types_conversion_hv
-     = (HV *)SvRV (default_css_string_types_conversion);
-  /* copy the normal formatting references and replace the css strings
-     specific references */
-  memcpy (&converter->css_string_types_conversion,
-          &converter->types_conversion,
-      (ET_special_unit_element+1) * sizeof (FORMATTING_REFERENCE));
-  for (i = 0; i < ET_special_unit_element+1; i++)
+  for (i = 0; i < index_names_nr; i++)
     {
-      char *ref_name;
-      if (i == 0)
-        ref_name = "";
-      else
-        ref_name = element_type_names[i];
-      FORMATTING_REFERENCE *conversion_formatting_reference
-       = &converter->css_string_types_conversion[i];
-
-      register_formatting_reference_default ("css_type_conversion",
-        conversion_formatting_reference, ref_name,
-        default_css_string_types_conversion_hv);
+      HE *next = hv_iternext (hv_in);
+      SV *index_name_sv = hv_iterkeysv(next);
+      av_push (index_names_av, index_name_sv);
     }
+   */
+  /* copy and sort
+  index_names_av_array = AvARRAY(index_names_av);
+  sorted_index_names_av_array
+       = (SV **) malloc (sizeof (SV *) * index_names_nr);
+  memcpy (sorted_index_names_av_array, index_names_av_array,
+          sizeof (SV *) * index_names_nr);
+  sortsv (sorted_index_names_av_array, index_names_nr, Perl_sv_cmp);
+   */
 
+  converter->index_entries_by_letter = (INDEX_SORTED_BY_LETTER **)
+    malloc (index_names_nr * sizeof (INDEX_SORTED_BY_LETTER *));
 
-  FETCH(output_units_conversion)
-  output_units_conversion_hv = (HV *)SvRV (*output_units_conversion_sv);
-  default_output_units_conversion_hv
-    = (HV *)SvRV (default_output_units_conversion);
-
-  for (i = 0; i < OU_special_unit+1; i++)
+  for (j = 0; j < index_names_nr; j++)
     {
-      const char *ref_name = output_unit_type_names[i];
-      FORMATTING_REFERENCE *conversion_formatting_reference
-       = &converter->output_units_conversion[i];
-
-      register_formatting_reference_with_default ("output_unit_conversion",
-        conversion_formatting_reference, ref_name,
-        default_output_units_conversion_hv,
-        output_units_conversion_hv);
-    }
+      int i;
+      char *idx_name = 0;
+      SSize_t letter_entries_nr;
+      HE *sorted_by_letter_he;
+      SV *idx_name_sv;
+      SV *sorted_by_letter_sv;
+      AV *av;
 
-  FETCH(sorted_special_unit_varieties)
+      /* unsorted AV (to compare unsorted/sorted for debug)
+      SV **idx_name_sv_ref = av_fetch (index_names_av, j, 0);
+      if (!idx_name_sv_ref)
+        {
+          char *msg;
+          xasprintf (&msg,
+            "get_sv_index_entries_sorted_by_letter: %d: no index name\n", j);
+          fatal (msg);
+        }
+      idx_name_sv = *idx_name_sv_ref;
+       */
+       /* sorted SV**
+      idx_name_sv = sorted_index_names_av_array[j];
+       */
+      /* unsorted HV
+       */
+      HE *next = hv_iternext (hv_in);
+      idx_name_sv = hv_iterkeysv (next);
+      /* code common to all the cases above */
+      if (!idx_name_sv)
+        {
+          char *msg;
+          xasprintf (&msg,
+            "get_sv_index_entries_sorted_by_letter: %d: no index name\n", j);
+          fatal (msg);
+        }
+      idx_name = (char *) SvPVutf8_nolen (idx_name_sv);
 
-  if (sorted_special_unit_varieties_sv)
-    {
-      int j;
-      SV **special_unit_info_sv;
-      HV *special_unit_info_hv;
+      sorted_by_letter_he = hv_fetch_ent (hv_in, idx_name_sv, 0, 0);
+      if (!sorted_by_letter_he)
+        {
+          char *msg;
+          xasprintf (&msg,
+           "get_sv_index_entries_sorted_by_letter: %d: %s: cannot find 
index\n",
+                     j, idx_name);
+          fatal (msg);
+        }
 
-      STRING_LIST *special_unit_varieties = &converter->special_unit_varieties;
-      if (sorted_special_unit_varieties_sv)
-        add_svav_to_string_list (*sorted_special_unit_varieties_sv,
-                                 special_unit_varieties, 0);
+      sorted_by_letter_sv = HeVAL(sorted_by_letter_he);
+      if (!sorted_by_letter_sv)
+        {
+          char *msg;
+          xasprintf (&msg,
+            "get_sv_index_entries_sorted_by_letter: %d: %s: no letter 
entries\n",
+                     j, idx_name);
+          fatal (msg);
+        }
 
-      FETCH(special_unit_info);
+      converter->index_entries_by_letter[j] = (INDEX_SORTED_BY_LETTER *)
+                                 malloc (sizeof (INDEX_SORTED_BY_LETTER));
+      converter->index_entries_by_letter[j]->name = strdup (idx_name);
 
-      special_unit_info_hv = (HV *) SvRV(*special_unit_info_sv);
+      av = (AV *)SvRV (sorted_by_letter_sv);
 
-      for (j = 0; j < SUI_type_heading+1; j++)
+      letter_entries_nr = av_top_index (av) +1;
+      converter->index_entries_by_letter[j]->number = letter_entries_nr;
+      converter->index_entries_by_letter[j]->letter_entries
+        = (LETTER_INDEX_ENTRIES *)
+         malloc (letter_entries_nr * sizeof (LETTER_INDEX_ENTRIES));
+      for (i = 0; i < letter_entries_nr; i++)
         {
-          SV **special_unit_info_type_sv;
-          const char *sui_type = special_unit_info_type_names[j];
-          special_unit_info_type_sv = hv_fetch (special_unit_info_hv,
-                                                sui_type, strlen (sui_type), 
0);
-          if (special_unit_info_type_sv)
+          SV** letter_entries_sv = av_fetch (av, i, 0);
+          LETTER_INDEX_ENTRIES *letter_entries
+            = &converter->index_entries_by_letter[j]->letter_entries[i];
+          if (letter_entries_sv)
             {
               int k;
-              HV *special_unit_info_type_hv;
+              SSize_t entries_nr;
+              AV *entries_av;
 
-              if (!SvOK (*special_unit_info_type_sv))
+              HV *letter_entries_hv = (HV *) SvRV (*letter_entries_sv);
+              SV **letter_sv = hv_fetch (letter_entries_hv, "letter",
+                                         strlen ("letter"), 0);
+              SV **entries_sv = hv_fetch (letter_entries_hv, "entries",
+                                         strlen ("entries"), 0);
+              if (!letter_sv || !entries_sv)
                 {
-                  fprintf (stderr, "BUG: special_unit_info: %s: undef\n",
-                                   sui_type);
+                  char *msg;
+                  xasprintf (&msg,
+  "get_sv_index_entries_sorted_by_letter: %s: %d: no letter and entries\n",
+                             idx_name, i);
+                  fatal (msg);
                 }
+              letter_entries->letter
+                = (char *) SvPVutf8_nolen (*letter_sv);
 
-              special_unit_info_type_hv
-                   = (HV *) SvRV(*special_unit_info_type_sv);
+              entries_av = (AV *) SvRV (*entries_sv);
+              entries_nr = av_top_index (entries_av) +1;
+              letter_entries->number = entries_nr;
+              letter_entries->entries =
+                (INDEX_ENTRY **) malloc (entries_nr * sizeof (INDEX_ENTRY *));
+              for (k = 0; k < entries_nr; k++)
+                {
+                  SV** index_entry_sv = av_fetch (entries_av, k, 0);
+                  HV *index_entry_hv;
+                  SV** index_name_sv;
+                  SV** entry_number_sv;
+                  INDEX *idx;
+                  INDEX **n;
+                  char *entry_index_name;
+                  int entry_number;
 
-              converter->special_unit_info[j]
-               = (char **)
-                 malloc ((special_unit_varieties->number +1) * sizeof (char 
*));
-              memset (converter->special_unit_info[j], 0,
-                      (special_unit_varieties->number +1) * sizeof (char *));
+                  if (!index_entry_sv)
+                    {
+                      char *msg;
+                      xasprintf (&msg,
+  "get_sv_index_entries_sorted_by_letter: %s: %d: %s: %d: no entry\n",
+                             idx_name, i, letter_entries->letter, k);
+                      fatal (msg);
+                    }
+                  index_entry_hv = (HV *) SvRV (*index_entry_sv);
+                  index_name_sv = hv_fetch (index_entry_hv, "index_name",
+                                            strlen ("index_name"), 0);
+                  entry_number_sv = hv_fetch (index_entry_hv, "entry_number",
+                                              strlen ("entry_number"), 0);
+                  if (!index_entry_hv || !entry_number_sv)
+                    {
+                      char *msg;
+                      xasprintf (&msg,
+  "get_sv_index_entries_sorted_by_letter: %s: %d: %s: %d: no entry info\n",
+                             idx_name, i, letter_entries->letter, k);
+                      fatal (msg);
+                    }
+                  entry_index_name = (char *) SvPVutf8_nolen (*index_name_sv);
+                  entry_number = SvIV (*entry_number_sv);
 
-              for (k = 0; k < special_unit_varieties->number; k++)
-                {
-                  char *variety_name = special_unit_varieties->list[k];
-                  SV **info_type_variety_sv
-                   = hv_fetch (special_unit_info_type_hv, variety_name,
-                               strlen (variety_name), 0);
-                  if (info_type_variety_sv)
+                  for (n = index_names; (idx = *n); n++)
                     {
-                      /* can be undef if set undef in user init file */
-                      if (SvOK (*info_type_variety_sv))
+                      if (!strcmp (idx->name, entry_index_name))
                         {
-                          char *value
-                            = (char *) SvPVutf8_nolen (*info_type_variety_sv);
-                          converter->special_unit_info[j][k] = strdup (value);
+                          letter_entries->entries[k]
+                            = &idx->index_entries[entry_number];
+                          break;
                         }
-                      else
-                        converter->special_unit_info[j][k] = 0;
                     }
                 }
             }
+          else
+            {
+              char *msg;
+              xasprintf (&msg,
+    "get_sv_index_entries_sorted_by_letter: %s: %d: no letter entries\n",
+                         idx_name, i);
+              fatal (msg);
+            }
         }
     }
+}
 
-  FETCH(code_types)
-
-  if (code_types_sv)
-    {
-      I32 hv_number;
-      I32 i;
+void
+set_conf (CONVERTER *converter, const char *conf, SV *value)
+{
+  if (converter->conf)
+    get_sv_option (converter->conf, conf, value);
+   /* Too early to have options set
+  else
+    fprintf (stderr, "HHH no converter conf %s\n", conf);
+    */
+}
 
-      HV *code_types_hv = (HV *)SvRV (*code_types_sv);
 
-      hv_number = hv_iterinit (code_types_hv);
+/* Following is HTML specific */
+static SV **
+register_formatting_reference_default (char *type_string,
+                FORMATTING_REFERENCE *formatting_reference,
+                const char *ref_name, HV *default_hv)
+{
+  SV **default_formatting_reference_sv;
 
-      for (i = 0; i < hv_number; i++)
-        {
-          int j;
-          enum element_type type = ET_NONE;
-          I32 retlen;
-          char *type_name;
-          SV *code_sv = hv_iternextsv (code_types_hv,
-                                       &type_name, &retlen);
-          if (SvOK (code_sv))
-            {
-              int code_value = SvIV (code_sv);
-          /* this is not very efficient, but should be done only once
-             in the default case.  If this is needed more, a qsort/bfind
-             could be used, but the overhead could probably only be
-             justified if finding the type index happens more often */
-              for (j = 1; j < ET_special_unit_element+1; j++)
-                {
-                  if (!strcmp (element_type_names[j], type_name))
-                    {
-                      type = j;
-                      break;
-                    }
-                }
-              if (type == ET_NONE)
-                {
-                  fprintf (stderr, "ERROR: %s: code type not found\n",
-                                   type_name);
-                }
-              else
-                converter->code_types[type] = code_value;
-           }
-       }
-   }
+  dTHX;
 
-  FETCH(pre_class_types)
+  default_formatting_reference_sv
+   = hv_fetch (default_hv, ref_name, strlen (ref_name), 0);
 
-  if (pre_class_types_sv)
+  if (default_formatting_reference_sv)
     {
-      I32 hv_number;
-      I32 i;
+      if (SvOK (*default_formatting_reference_sv))
+        {
+          formatting_reference->sv_default = *default_formatting_reference_sv;
+          /* will be replaced by customization if there are not only defaults 
*/
+          formatting_reference->sv_reference = 
*default_formatting_reference_sv;
+          formatting_reference->status = FRS_status_default_set;
+        }
+      else
+        formatting_reference->status = FRS_status_ignored;
+    }
+  return default_formatting_reference_sv;
+}
 
-      HV *pre_class_types_hv = (HV *)SvRV (*pre_class_types_sv);
+static void
+register_formatting_reference_with_default (char *type_string,
+                FORMATTING_REFERENCE *formatting_reference,
+                const char *ref_name, HV *default_hv, HV *customized_hv)
+{
+  SV **default_formatting_reference_sv;
+  SV **formatting_reference_sv;
 
-      hv_number = hv_iterinit (pre_class_types_hv);
+  dTHX;
 
-      for (i = 0; i < hv_number; i++)
+  default_formatting_reference_sv = register_formatting_reference_default(
+                 type_string, formatting_reference, ref_name, default_hv);
+
+  formatting_reference_sv
+    = hv_fetch (customized_hv, ref_name, strlen (ref_name), 0);
+  if (formatting_reference_sv)
+    {
+      if SvOK (*formatting_reference_sv)
         {
-          int j;
-          I32 retlen;
-          char *type_name;
-          SV *pre_class_sv = hv_iternextsv (pre_class_types_hv,
-                                            &type_name, &retlen);
-          if (SvOK (pre_class_sv))
-            {
-              enum element_type type = ET_NONE;
-              char *pre_class = SvPV_nolen (pre_class_sv);
-          /* this is not very efficient, but should be done only once
-             in the default case.  If this is needed more, a qsort/bfind
-             could be used, but the overhead could probably only be
-             justified if finding the type index happens more often */
-              for (j = 1; j < ET_special_unit_element+1; j++)
-                {
-                  if (!strcmp (element_type_names[j], type_name))
-                    {
-                      type = j;
-                      break;
-                    }
-                }
-              if (type == ET_NONE)
-                {
-                  fprintf (stderr, "ERROR: %s: pre class type not found\n",
-                           type_name);
-                }
-              else
-                converter->pre_class_types[type] = strdup (pre_class);
-            }
+          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
+compare_ints (const void *a, const void *b)
+{
+  const enum command_id *int_a = (const enum command_id *) a;
+  const enum command_id *int_b = (const enum command_id *) b;
 
-  FETCH(no_arg_commands_formatting)
+  return (*int_a > *int_b) - (*int_a < *int_b);
+}
 
-  if (no_arg_commands_formatting_sv)
-    {
-      int max_context = HCC_type_css_string;
-      I32 hv_number;
-      I32 i;
+int
+html_converter_initialize_sv (SV *converter_sv,
+                              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)
+{
+  int i;
+  HV *converter_hv;
+  HV *default_formatting_references_hv;
+  HV *default_css_string_formatting_references_hv;
+  HV *default_commands_open_hv;
+  HV *default_commands_conversion_hv;
+  HV *default_css_string_commands_conversion_hv;
+  HV *default_types_open_hv;
+  HV *default_types_conversion_hv;
+  HV *default_css_string_types_conversion_hv;
+  HV *default_output_units_conversion_hv;
+  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;
+  SV **output_units_conversion_sv;
+  SV **code_types_sv;
+  SV **pre_class_types_sv;
+  HV *formatting_function_hv;
+  HV *commands_open_hv;
+  HV *commands_conversion_hv;
+  HV *types_open_hv;
+  HV *types_conversion_hv;
+  HV *output_units_conversion_hv;
+  int converter_descriptor = 0;
+  CONVERTER *converter;
 
-      HV *no_arg_commands_formatting_hv
-        = (HV *)SvRV (*no_arg_commands_formatting_sv);
+  dTHX;
 
-      hv_number = hv_iterinit (no_arg_commands_formatting_hv);
+  converter = converter_initialize (converter_sv);
 
-      converter->no_arg_formatted_cmd.list = (enum command_id *)
-        malloc (hv_number * sizeof (enum command_id));
-      converter->no_arg_formatted_cmd.number = hv_number;
+  converter_hv = (HV *)SvRV (converter_sv);
 
-      for (i = 0; i < hv_number; i++)
-        {
-          char *cmdname;
-          I32 retlen;
-          SV *context_sv = hv_iternextsv (no_arg_commands_formatting_hv,
-                                          &cmdname, &retlen);
-          if (SvOK (context_sv))
-            {
-              HV *context_hv = (HV *)SvRV (context_sv);
-              enum command_id cmd = lookup_builtin_command (cmdname);
+  default_formatting_references_hv
+    = (HV *)SvRV (default_formatting_references);
+  default_css_string_formatting_references_hv
+    = (HV *)SvRV (default_css_string_formatting_references);
 
-              converter->no_arg_formatted_cmd.list[i] = cmd;
+#define FETCH(key) key##_sv = hv_fetch (converter_hv, #key, strlen(#key), 0);
+  FETCH(formatting_function);
 
-              if (!cmd)
-                fprintf (stderr, "ERROR: %s: no no arg command\n", cmdname);
-              else
-                {
-                  I32 context_nr;
-                  I32 j;
-                  converter->html_command_conversion[cmd] =
-                   (HTML_COMMAND_CONVERSION **) malloc ((max_context +1) *
-                     sizeof (HTML_COMMAND_CONVERSION *));
-                  memset (converter->html_command_conversion[cmd], 0,
-                     (max_context +1) * sizeof (HTML_COMMAND_CONVERSION *));
+  /* no need to check if it exists */
+  formatting_function_hv = (HV *)SvRV (*formatting_function_sv);
 
-                  context_nr = hv_iterinit (context_hv);
-                  for (j = 0; j < context_nr; j++)
-                    {
-                      char *context_name;
-                      I32 retlen;
-                      int k;
-                      int context_idx = -1;
-                      SV *format_spec_sv = hv_iternextsv (context_hv,
-                                                 &context_name, &retlen);
-                      for (k = 0; k < max_context +1; k++)
-                        {
-                          if (!strcmp (context_name,
-                                html_conversion_context_type_names[k]))
-                            {
-                              context_idx = k;
-                              break;
-                            }
-                        }
-                      if (context_idx < 0)
+  for (i = 0; i < FR_format_translate_message+1; i++)
+    {
+      char *ref_name = html_formatting_reference_names[i];
+      FORMATTING_REFERENCE *formatting_reference
+        = &converter->formatting_references[i];
+      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 for existence, all should exist */
+      if (SvOK (*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;
+              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",
+                         ref_name);
+    }
+
+  /* copy the normal formatting references and replace the css strings
+     specific references */
+  memcpy (&converter->css_string_formatting_references,
+          &converter->formatting_references,
+      (FR_format_translate_message+1) * sizeof (FORMATTING_REFERENCE));
+
+  for (i = 0; i < FR_format_translate_message+1; i++)
+    {
+      char *ref_name = html_formatting_reference_names[i];
+      SV **default_formatting_reference_sv
+        = hv_fetch (default_css_string_formatting_references_hv, ref_name,
+                    strlen (ref_name), 0);
+
+      /* no customization, current is the default */
+      if (default_formatting_reference_sv
+          && SvOK (*default_formatting_reference_sv))
+        {
+          FORMATTING_REFERENCE *formatting_reference
+            = &converter->css_string_formatting_references[i];
+          formatting_reference->sv_default = *default_formatting_reference_sv;
+          formatting_reference->sv_reference = 
*default_formatting_reference_sv;
+          formatting_reference->status = FRS_status_default_set;
+        }
+    }
+
+  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);
+    }
+
+  default_css_string_commands_conversion_hv
+    = (HV *)SvRV (default_css_string_commands_conversion);
+  /* copy the normal formatting references and replace the css strings
+     specific references */
+  memcpy (&converter->css_string_commands_conversion,
+          &converter->commands_conversion,
+      (BUILTIN_CMD_NUMBER) * sizeof (FORMATTING_REFERENCE));
+
+  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 *conversion_formatting_reference
+       = &converter->css_string_commands_conversion[i];
+
+     register_formatting_reference_default ("css_command_conversion",
+        conversion_formatting_reference, ref_name,
+        default_css_string_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);
+    }
+
+  default_css_string_types_conversion_hv
+     = (HV *)SvRV (default_css_string_types_conversion);
+  /* copy the normal formatting references and replace the css strings
+     specific references */
+  memcpy (&converter->css_string_types_conversion,
+          &converter->types_conversion,
+      (ET_special_unit_element+1) * sizeof (FORMATTING_REFERENCE));
+  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 *conversion_formatting_reference
+       = &converter->css_string_types_conversion[i];
+
+      register_formatting_reference_default ("css_type_conversion",
+        conversion_formatting_reference, ref_name,
+        default_css_string_types_conversion_hv);
+    }
+
+
+  FETCH(output_units_conversion)
+  output_units_conversion_hv = (HV *)SvRV (*output_units_conversion_sv);
+  default_output_units_conversion_hv
+    = (HV *)SvRV (default_output_units_conversion);
+
+  for (i = 0; i < OU_special_unit+1; i++)
+    {
+      const char *ref_name = output_unit_type_names[i];
+      FORMATTING_REFERENCE *conversion_formatting_reference
+       = &converter->output_units_conversion[i];
+
+      register_formatting_reference_with_default ("output_unit_conversion",
+        conversion_formatting_reference, ref_name,
+        default_output_units_conversion_hv,
+        output_units_conversion_hv);
+    }
+
+  FETCH(sorted_special_unit_varieties)
+
+  if (sorted_special_unit_varieties_sv)
+    {
+      int j;
+      SV **special_unit_info_sv;
+      HV *special_unit_info_hv;
+
+      STRING_LIST *special_unit_varieties = &converter->special_unit_varieties;
+      if (sorted_special_unit_varieties_sv)
+        add_svav_to_string_list (*sorted_special_unit_varieties_sv,
+                                 special_unit_varieties, 0);
+
+      FETCH(special_unit_info);
+
+      special_unit_info_hv = (HV *) SvRV(*special_unit_info_sv);
+
+      for (j = 0; j < SUI_type_heading+1; j++)
+        {
+          SV **special_unit_info_type_sv;
+          const char *sui_type = special_unit_info_type_names[j];
+          special_unit_info_type_sv = hv_fetch (special_unit_info_hv,
+                                                sui_type, strlen (sui_type), 
0);
+          if (special_unit_info_type_sv)
+            {
+              int k;
+              HV *special_unit_info_type_hv;
+
+              if (!SvOK (*special_unit_info_type_sv))
+                {
+                  fprintf (stderr, "BUG: special_unit_info: %s: undef\n",
+                                   sui_type);
+                }
+
+              special_unit_info_type_hv
+                   = (HV *) SvRV(*special_unit_info_type_sv);
+
+              converter->special_unit_info[j]
+               = (char **)
+                 malloc ((special_unit_varieties->number +1) * sizeof (char 
*));
+              memset (converter->special_unit_info[j], 0,
+                      (special_unit_varieties->number +1) * sizeof (char *));
+
+              for (k = 0; k < special_unit_varieties->number; k++)
+                {
+                  char *variety_name = special_unit_varieties->list[k];
+                  SV **info_type_variety_sv
+                   = hv_fetch (special_unit_info_type_hv, variety_name,
+                               strlen (variety_name), 0);
+                  if (info_type_variety_sv)
+                    {
+                      /* can be undef if set undef in user init file */
+                      if (SvOK (*info_type_variety_sv))
                         {
-                          fprintf (stderr,
-                              "ERROR: %s: %s: unknown no arg context\n",
-                                         cmdname, context_name);
-                          break;
+                          char *value
+                            = (char *) SvPVutf8_nolen (*info_type_variety_sv);
+                          converter->special_unit_info[j][k] = strdup (value);
                         }
-                      if (SvOK (format_spec_sv))
-                        {
-                          I32 spec_number;
-                          I32 s;
-                          HTML_COMMAND_CONVERSION *format_spec;
+                      else
+                        converter->special_unit_info[j][k] = 0;
+                    }
+                }
+            }
+        }
+    }
 
-                          HV *format_spec_hv = (HV *)SvRV (format_spec_sv);
+  FETCH(code_types)
 
-                          converter->html_command_conversion[cmd][context_idx]
-                           = (HTML_COMMAND_CONVERSION *)
-                               malloc (sizeof (HTML_COMMAND_CONVERSION));
-                          format_spec
-                            = converter
-                               ->html_command_conversion[cmd][context_idx];
-                          memset (format_spec, 0,
-                                  sizeof (HTML_COMMAND_CONVERSION));
+  if (code_types_sv)
+    {
+      I32 hv_number;
+      I32 i;
 
-                          spec_number = hv_iterinit (format_spec_hv);
-                          for (s = 0; s < spec_number; s++)
-                            {
-                              char *key;
-                              I32 retlen;
-                              SV *spec_sv = hv_iternextsv (format_spec_hv,
-                                                           &key, &retlen);
-                              if (!strcmp (key, "element"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->element = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "unset"))
-                                format_spec->unset = SvIV (spec_sv);
-                              else if (!strcmp (key, "text"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->text = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "translated_converted"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->translated_converted
-                                    = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "translated_to_convert"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->translated_to_convert
-                                    = strdup (tmp_spec);
-                                }
-                            }
-                        }
+      HV *code_types_hv = (HV *)SvRV (*code_types_sv);
+
+      hv_number = hv_iterinit (code_types_hv);
+
+      for (i = 0; i < hv_number; i++)
+        {
+          int j;
+          enum element_type type = ET_NONE;
+          I32 retlen;
+          char *type_name;
+          SV *code_sv = hv_iternextsv (code_types_hv,
+                                       &type_name, &retlen);
+          if (SvOK (code_sv))
+            {
+              int code_value = SvIV (code_sv);
+          /* this is not very efficient, but should be done only once
+             in the default case.  If this is needed more, a qsort/bfind
+             could be used, but the overhead could probably only be
+             justified if finding the type index happens more often */
+              for (j = 1; j < ET_special_unit_element+1; j++)
+                {
+                  if (!strcmp (element_type_names[j], type_name))
+                    {
+                      type = j;
+                      break;
                     }
                 }
+              if (type == ET_NONE)
+                {
+                  fprintf (stderr, "ERROR: %s: code type not found\n",
+                                   type_name);
+                }
+              else
+                converter->code_types[type] = code_value;
+           }
+       }
+   }
+
+  FETCH(pre_class_types)
+
+  if (pre_class_types_sv)
+    {
+      I32 hv_number;
+      I32 i;
+
+      HV *pre_class_types_hv = (HV *)SvRV (*pre_class_types_sv);
+
+      hv_number = hv_iterinit (pre_class_types_hv);
+
+      for (i = 0; i < hv_number; i++)
+        {
+          int j;
+          I32 retlen;
+          char *type_name;
+          SV *pre_class_sv = hv_iternextsv (pre_class_types_hv,
+                                            &type_name, &retlen);
+          if (SvOK (pre_class_sv))
+            {
+              enum element_type type = ET_NONE;
+              char *pre_class = SvPV_nolen (pre_class_sv);
+          /* this is not very efficient, but should be done only once
+             in the default case.  If this is needed more, a qsort/bfind
+             could be used, but the overhead could probably only be
+             justified if finding the type index happens more often */
+              for (j = 1; j < ET_special_unit_element+1; j++)
+                {
+                  if (!strcmp (element_type_names[j], type_name))
+                    {
+                      type = j;
+                      break;
+                    }
+                }
+              if (type == ET_NONE)
+                {
+                  fprintf (stderr, "ERROR: %s: pre class type not found\n",
+                           type_name);
+                }
+              else
+                converter->pre_class_types[type] = strdup (pre_class);
             }
         }
-      qsort (converter->no_arg_formatted_cmd.list, hv_number,
-             sizeof (enum command_id), compare_ints);
     }
 
-  FETCH(style_commands_formatting)
 
-  if (style_commands_formatting_sv)
+  FETCH(no_arg_commands_formatting)
+
+  if (no_arg_commands_formatting_sv)
     {
-      int max_context = HCC_type_string;
+      int max_context = HCC_type_css_string;
       I32 hv_number;
       I32 i;
 
-      HV *style_commands_formatting_hv
-        = (HV *)SvRV (*style_commands_formatting_sv);
+      HV *no_arg_commands_formatting_hv
+        = (HV *)SvRV (*no_arg_commands_formatting_sv);
+
+      hv_number = hv_iterinit (no_arg_commands_formatting_hv);
+
+      converter->no_arg_formatted_cmd.list = (enum command_id *)
+        malloc (hv_number * sizeof (enum command_id));
+      converter->no_arg_formatted_cmd.number = hv_number;
 
-      hv_number = hv_iterinit (style_commands_formatting_hv);
       for (i = 0; i < hv_number; i++)
         {
           char *cmdname;
           I32 retlen;
-          SV *context_sv = hv_iternextsv (style_commands_formatting_hv,
+          SV *context_sv = hv_iternextsv (no_arg_commands_formatting_hv,
                                           &cmdname, &retlen);
           if (SvOK (context_sv))
             {
               HV *context_hv = (HV *)SvRV (context_sv);
               enum command_id cmd = lookup_builtin_command (cmdname);
+
+              converter->no_arg_formatted_cmd.list[i] = cmd;
+
               if (!cmd)
-                fprintf (stderr, "ERROR: %s: no style command\n", cmdname);
+                fprintf (stderr, "ERROR: %s: no no arg command\n", cmdname);
               else
                 {
                   I32 context_nr;
@@ -1090,7 +1235,7 @@ html_converter_initialize_sv (SV *converter_sv,
                       if (context_idx < 0)
                         {
                           fprintf (stderr,
-                              "ERROR: %s: %s: unknown style context\n",
+                              "ERROR: %s: %s: unknown no arg context\n",
                                          cmdname, context_name);
                           break;
                         }
@@ -1106,310 +1251,169 @@ html_converter_initialize_sv (SV *converter_sv,
                            = (HTML_COMMAND_CONVERSION *)
                                malloc (sizeof (HTML_COMMAND_CONVERSION));
                           format_spec
-                            = converter
-                               ->html_command_conversion[cmd][context_idx];
-                          memset (format_spec, 0,
-                                  sizeof (HTML_COMMAND_CONVERSION));
-
-                          spec_number = hv_iterinit (format_spec_hv);
-                          for (s = 0; s < spec_number; s++)
-                            {
-                              char *key;
-                              I32 retlen;
-                              SV *spec_sv = hv_iternextsv (format_spec_hv,
-                                                           &key, &retlen);
-                              if (!strcmp (key, "element"))
-                                {
-                                  char *tmp_spec
-                                    = (char *) SvPVutf8_nolen (spec_sv);
-                                  format_spec->element = strdup (tmp_spec);
-                                }
-                              else if (!strcmp (key, "quote"))
-                                format_spec->quote = SvIV (spec_sv);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-#undef FETCH
-
-  html_converter_initialize (converter);
-
-  converter->hv = converter_hv;
-
-  converter_descriptor = register_converter (converter);
-
-  /* store converter_descriptor in perl converter */
-  hv_store (converter_hv, "converter_descriptor",
-            strlen("converter_descriptor"),
-            newSViv (converter_descriptor), 0);
-
-  return converter_descriptor;
-}
-
-
-CONVERTER *
-set_output_converter_sv (SV *sv_in, char *warn_string)
-{
-  HV *hv_in;
-  SV **converter_options_sv;
-  SV **converter_init_conf_sv;
-  CONVERTER *converter = 0;
-
-  dTHX;
-
-  converter = get_sv_converter (sv_in, warn_string);
-
-  hv_in = (HV *)SvRV (sv_in);
-  converter_options_sv = hv_fetch (hv_in, "conf",
-                                   strlen ("conf"), 0);
-
-  if (converter_options_sv)
-    {
-      converter->conf
-         = copy_sv_options (*converter_options_sv);
-    }
-
-  converter_init_conf_sv = hv_fetch (hv_in, "output_init_conf",
-                                   strlen ("output_init_conf"), 0);
-
-  if (converter_init_conf_sv && SvOK(*converter_init_conf_sv))
-    {
-      if (converter->init_conf)
-        free_options (converter->init_conf);
-      free (converter->init_conf);
-
-      converter->init_conf
-         = copy_sv_options (*converter_init_conf_sv);
-    }
-
-  return converter;
-}
-
-/* code in comments allow to sort the index names to have a fixed order
-   in the data structure.  Not clear that it is useful or not, not enabled
-   for now */
-void
-get_sv_index_entries_sorted_by_letter (CONVERTER *converter,
-                                       SV *index_entries_sorted_by_letter)
-{
-  HV *hv_in;
-  /* for sorted index names
-  AV *index_names_av;
-  SV **index_names_av_array;
-  SV **sorted_index_names_av_array;
-  I32 i;
-   */
-  I32 index_names_nr;
-
-  SSize_t j;
-  INDEX **index_names = converter->document->index_names;
-
-  dTHX;
-
-  if (!SvOK (index_entries_sorted_by_letter))
-    return;
-
-  hv_in = (HV *)SvRV (index_entries_sorted_by_letter);
-
-  index_names_nr = hv_iterinit (hv_in);
-
-  /* when there is a memcpy just below, a condition that avoids negative
-     index_names_nr is important to avoid a gcc warning */
-  if (index_names_nr <= 0)
-    return;
-
-  /* doing an AV with the keys (first step of sorting)
-  index_names_av = newAV ();
-
-  for (i = 0; i < index_names_nr; i++)
-    {
-      HE *next = hv_iternext (hv_in);
-      SV *index_name_sv = hv_iterkeysv(next);
-      av_push (index_names_av, index_name_sv);
-    }
-   */
-  /* copy and sort
-  index_names_av_array = AvARRAY(index_names_av);
-  sorted_index_names_av_array
-       = (SV **) malloc (sizeof (SV *) * index_names_nr);
-  memcpy (sorted_index_names_av_array, index_names_av_array,
-          sizeof (SV *) * index_names_nr);
-  sortsv (sorted_index_names_av_array, index_names_nr, Perl_sv_cmp);
-   */
-
-  converter->index_entries_by_letter = (INDEX_SORTED_BY_LETTER **)
-    malloc (index_names_nr * sizeof (INDEX_SORTED_BY_LETTER *));
-
-  for (j = 0; j < index_names_nr; j++)
-    {
-      int i;
-      char *idx_name = 0;
-      SSize_t letter_entries_nr;
-      HE *sorted_by_letter_he;
-      SV *idx_name_sv;
-      SV *sorted_by_letter_sv;
-      AV *av;
-
-      /* unsorted AV (to compare unsorted/sorted for debug)
-      SV **idx_name_sv_ref = av_fetch (index_names_av, j, 0);
-      if (!idx_name_sv_ref)
-        {
-          char *msg;
-          xasprintf (&msg,
-            "get_sv_index_entries_sorted_by_letter: %d: no index name\n", j);
-          fatal (msg);
-        }
-      idx_name_sv = *idx_name_sv_ref;
-       */
-       /* sorted SV**
-      idx_name_sv = sorted_index_names_av_array[j];
-       */
-      /* unsorted HV
-       */
-      HE *next = hv_iternext (hv_in);
-      idx_name_sv = hv_iterkeysv (next);
-      /* code common to all the cases above */
-      if (!idx_name_sv)
-        {
-          char *msg;
-          xasprintf (&msg,
-            "get_sv_index_entries_sorted_by_letter: %d: no index name\n", j);
-          fatal (msg);
-        }
-      idx_name = (char *) SvPVutf8_nolen (idx_name_sv);
+                            = converter
+                               ->html_command_conversion[cmd][context_idx];
+                          memset (format_spec, 0,
+                                  sizeof (HTML_COMMAND_CONVERSION));
 
-      sorted_by_letter_he = hv_fetch_ent (hv_in, idx_name_sv, 0, 0);
-      if (!sorted_by_letter_he)
-        {
-          char *msg;
-          xasprintf (&msg,
-           "get_sv_index_entries_sorted_by_letter: %d: %s: cannot find 
index\n",
-                     j, idx_name);
-          fatal (msg);
+                          spec_number = hv_iterinit (format_spec_hv);
+                          for (s = 0; s < spec_number; s++)
+                            {
+                              char *key;
+                              I32 retlen;
+                              SV *spec_sv = hv_iternextsv (format_spec_hv,
+                                                           &key, &retlen);
+                              if (!strcmp (key, "element"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->element = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "unset"))
+                                format_spec->unset = SvIV (spec_sv);
+                              else if (!strcmp (key, "text"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->text = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "translated_converted"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->translated_converted
+                                    = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "translated_to_convert"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->translated_to_convert
+                                    = strdup (tmp_spec);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
         }
+      qsort (converter->no_arg_formatted_cmd.list, hv_number,
+             sizeof (enum command_id), compare_ints);
+    }
 
-      sorted_by_letter_sv = HeVAL(sorted_by_letter_he);
-      if (!sorted_by_letter_sv)
-        {
-          char *msg;
-          xasprintf (&msg,
-            "get_sv_index_entries_sorted_by_letter: %d: %s: no letter 
entries\n",
-                     j, idx_name);
-          fatal (msg);
-        }
+  FETCH(style_commands_formatting)
 
-      converter->index_entries_by_letter[j] = (INDEX_SORTED_BY_LETTER *)
-                                 malloc (sizeof (INDEX_SORTED_BY_LETTER));
-      converter->index_entries_by_letter[j]->name = strdup (idx_name);
+  if (style_commands_formatting_sv)
+    {
+      int max_context = HCC_type_string;
+      I32 hv_number;
+      I32 i;
 
-      av = (AV *)SvRV (sorted_by_letter_sv);
+      HV *style_commands_formatting_hv
+        = (HV *)SvRV (*style_commands_formatting_sv);
 
-      letter_entries_nr = av_top_index (av) +1;
-      converter->index_entries_by_letter[j]->number = letter_entries_nr;
-      converter->index_entries_by_letter[j]->letter_entries
-        = (LETTER_INDEX_ENTRIES *)
-         malloc (letter_entries_nr * sizeof (LETTER_INDEX_ENTRIES));
-      for (i = 0; i < letter_entries_nr; i++)
+      hv_number = hv_iterinit (style_commands_formatting_hv);
+      for (i = 0; i < hv_number; i++)
         {
-          SV** letter_entries_sv = av_fetch (av, i, 0);
-          LETTER_INDEX_ENTRIES *letter_entries
-            = &converter->index_entries_by_letter[j]->letter_entries[i];
-          if (letter_entries_sv)
+          char *cmdname;
+          I32 retlen;
+          SV *context_sv = hv_iternextsv (style_commands_formatting_hv,
+                                          &cmdname, &retlen);
+          if (SvOK (context_sv))
             {
-              int k;
-              SSize_t entries_nr;
-              AV *entries_av;
-
-              HV *letter_entries_hv = (HV *) SvRV (*letter_entries_sv);
-              SV **letter_sv = hv_fetch (letter_entries_hv, "letter",
-                                         strlen ("letter"), 0);
-              SV **entries_sv = hv_fetch (letter_entries_hv, "entries",
-                                         strlen ("entries"), 0);
-              if (!letter_sv || !entries_sv)
-                {
-                  char *msg;
-                  xasprintf (&msg,
-  "get_sv_index_entries_sorted_by_letter: %s: %d: no letter and entries\n",
-                             idx_name, i);
-                  fatal (msg);
-                }
-              letter_entries->letter
-                = (char *) SvPVutf8_nolen (*letter_sv);
-
-              entries_av = (AV *) SvRV (*entries_sv);
-              entries_nr = av_top_index (entries_av) +1;
-              letter_entries->number = entries_nr;
-              letter_entries->entries =
-                (INDEX_ENTRY **) malloc (entries_nr * sizeof (INDEX_ENTRY *));
-              for (k = 0; k < entries_nr; k++)
+              HV *context_hv = (HV *)SvRV (context_sv);
+              enum command_id cmd = lookup_builtin_command (cmdname);
+              if (!cmd)
+                fprintf (stderr, "ERROR: %s: no style command\n", cmdname);
+              else
                 {
-                  SV** index_entry_sv = av_fetch (entries_av, k, 0);
-                  HV *index_entry_hv;
-                  SV** index_name_sv;
-                  SV** entry_number_sv;
-                  INDEX *idx;
-                  INDEX **n;
-                  char *entry_index_name;
-                  int entry_number;
-
-                  if (!index_entry_sv)
-                    {
-                      char *msg;
-                      xasprintf (&msg,
-  "get_sv_index_entries_sorted_by_letter: %s: %d: %s: %d: no entry\n",
-                             idx_name, i, letter_entries->letter, k);
-                      fatal (msg);
-                    }
-                  index_entry_hv = (HV *) SvRV (*index_entry_sv);
-                  index_name_sv = hv_fetch (index_entry_hv, "index_name",
-                                            strlen ("index_name"), 0);
-                  entry_number_sv = hv_fetch (index_entry_hv, "entry_number",
-                                              strlen ("entry_number"), 0);
-                  if (!index_entry_hv || !entry_number_sv)
-                    {
-                      char *msg;
-                      xasprintf (&msg,
-  "get_sv_index_entries_sorted_by_letter: %s: %d: %s: %d: no entry info\n",
-                             idx_name, i, letter_entries->letter, k);
-                      fatal (msg);
-                    }
-                  entry_index_name = (char *) SvPVutf8_nolen (*index_name_sv);
-                  entry_number = SvIV (*entry_number_sv);
+                  I32 context_nr;
+                  I32 j;
+                  converter->html_command_conversion[cmd] =
+                   (HTML_COMMAND_CONVERSION **) malloc ((max_context +1) *
+                     sizeof (HTML_COMMAND_CONVERSION *));
+                  memset (converter->html_command_conversion[cmd], 0,
+                     (max_context +1) * sizeof (HTML_COMMAND_CONVERSION *));
 
-                  for (n = index_names; (idx = *n); n++)
+                  context_nr = hv_iterinit (context_hv);
+                  for (j = 0; j < context_nr; j++)
                     {
-                      if (!strcmp (idx->name, entry_index_name))
+                      char *context_name;
+                      I32 retlen;
+                      int k;
+                      int context_idx = -1;
+                      SV *format_spec_sv = hv_iternextsv (context_hv,
+                                                 &context_name, &retlen);
+                      for (k = 0; k < max_context +1; k++)
                         {
-                          letter_entries->entries[k]
-                            = &idx->index_entries[entry_number];
+                          if (!strcmp (context_name,
+                                html_conversion_context_type_names[k]))
+                            {
+                              context_idx = k;
+                              break;
+                            }
+                        }
+                      if (context_idx < 0)
+                        {
+                          fprintf (stderr,
+                              "ERROR: %s: %s: unknown style context\n",
+                                         cmdname, context_name);
                           break;
                         }
+                      if (SvOK (format_spec_sv))
+                        {
+                          I32 spec_number;
+                          I32 s;
+                          HTML_COMMAND_CONVERSION *format_spec;
+
+                          HV *format_spec_hv = (HV *)SvRV (format_spec_sv);
+
+                          converter->html_command_conversion[cmd][context_idx]
+                           = (HTML_COMMAND_CONVERSION *)
+                               malloc (sizeof (HTML_COMMAND_CONVERSION));
+                          format_spec
+                            = converter
+                               ->html_command_conversion[cmd][context_idx];
+                          memset (format_spec, 0,
+                                  sizeof (HTML_COMMAND_CONVERSION));
+
+                          spec_number = hv_iterinit (format_spec_hv);
+                          for (s = 0; s < spec_number; s++)
+                            {
+                              char *key;
+                              I32 retlen;
+                              SV *spec_sv = hv_iternextsv (format_spec_hv,
+                                                           &key, &retlen);
+                              if (!strcmp (key, "element"))
+                                {
+                                  char *tmp_spec
+                                    = (char *) SvPVutf8_nolen (spec_sv);
+                                  format_spec->element = strdup (tmp_spec);
+                                }
+                              else if (!strcmp (key, "quote"))
+                                format_spec->quote = SvIV (spec_sv);
+                            }
+                        }
                     }
                 }
             }
-          else
-            {
-              char *msg;
-              xasprintf (&msg,
-    "get_sv_index_entries_sorted_by_letter: %s: %d: no letter entries\n",
-                         idx_name, i);
-              fatal (msg);
-            }
         }
     }
-}
 
-void
-set_conf (CONVERTER *converter, const char *conf, SV *value)
-{
-  if (converter->conf)
-    get_sv_option (converter->conf, conf, value);
-   /* Too early to have options set
-  else
-    fprintf (stderr, "HHH no converter conf %s\n", conf);
-    */
+#undef FETCH
+
+  html_converter_initialize (converter);
+
+  converter->hv = converter_hv;
+
+  converter_descriptor = register_converter (converter);
+
+  /* store converter_descriptor in perl converter */
+  hv_store (converter_hv, "converter_descriptor",
+            strlen("converter_descriptor"),
+            newSViv (converter_descriptor), 0);
+
+  return converter_descriptor;
 }
+
+



reply via email to

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