texinfo-commits
[Top][All Lists]
Advanced

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

[no subject]


From: Patrice Dumas
Date: Thu, 28 Dec 2023 14:17:36 -0500 (EST)

branch: master
commit 238108b290d1e5b6687e412e25a5fffeb9ea2efa
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Thu Dec 28 20:17:31 2023 +0100

    * tp/Texinfo/XS/convert/convert_html.c (url_protect_file_text): cast
    char to (unsigned char) before giving to text_printf with %x format,
    as the %x modifier expects an unsigned int parameter and a char will
    usually be promoted to an int when passed to a varargs function.
    
    * tp/Texinfo/XS/convert/convert_html.c (image_files_extensions)
    (find_image_extension_file, IMAGE_FILE_LOCATION_INFO)
    (free_image_file_location_info, html_image_file_location_name)
    (convert_image_command, commands_internal_conversion_table):
    implement convert_image_command in C.
---
 ChangeLog                            |  13 +++
 tp/Texinfo/XS/convert/convert_html.c | 216 ++++++++++++++++++++++++++++++++++-
 tp/Texinfo/XS/main/convert_utils.h   |   5 +
 3 files changed, 233 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index fae8124b32..ef6988c6bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2023-12-28  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/convert/convert_html.c (url_protect_file_text): cast
+       char to (unsigned char) before giving to text_printf with %x format,
+       as the %x modifier expects an unsigned int parameter and a char will
+       usually be promoted to an int when passed to a varargs function.
+
+       * tp/Texinfo/XS/convert/convert_html.c (image_files_extensions)
+       (find_image_extension_file, IMAGE_FILE_LOCATION_INFO)
+       (free_image_file_location_info, html_image_file_location_name)
+       (convert_image_command, commands_internal_conversion_table):
+       implement convert_image_command in C.
+
 2023-12-28  Patrice Dumas  <pertusus@free.fr>
 
        * tp/Texinfo/Convert/HTML.pm (html_image_file_location_name)
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index c459298c4a..a47009b098 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -2542,7 +2542,10 @@ url_protect_file_text (CONVERTER *self, const char 
*input_string)
                 }
               for (i = 0; i < char_len; i++)
                 {
-                  text_printf (&text, "%%%02x", *p);
+            /* the reason for forcing (unsigned char) is that the %x modifier
+               expects an unsigned int parameter and a char will usually be
+               promoted to an int when passed to a varargs function */
+                  text_printf (&text, "%%%2x", (unsigned char)*p);
                   p += 1;
                 }
             }
@@ -8773,6 +8776,216 @@ convert_uref_command (CONVERTER *self, const enum 
command_id cmd,
   free (protected_url);
 }
 
+static const char *image_files_extensions[] = {
+".png", ".jpg", ".jpeg", ".gif", 0
+};
+
+/* return, IMAGE_PATH and IMAGE_PATH_ENCODING to be freed by caller */
+static char *
+find_image_extension_file (CONVERTER *self, const ELEMENT *element,
+                                  const char *image_basefile,
+                                  const char *extension,
+                                  char **image_path,
+                                  char **image_path_encoding)
+{
+  char *image_file;
+  char *input_file_encoding;
+  char *file_name;
+  char *located_image_path;
+
+  xasprintf (&image_file, "%s%s", image_basefile, extension);
+  file_name = encoded_input_file_name (self->conf, self->document->global_info,
+                   image_file, 0, &input_file_encoding, &element->source_info);
+
+  located_image_path = locate_include_file (file_name,
+                                            &self->conf->INCLUDE_DIRECTORIES);
+  free (file_name);
+
+  if (located_image_path)
+    {
+      *image_path_encoding = input_file_encoding;
+      *image_path = located_image_path;
+      return image_file;
+    }
+
+  free (image_file);
+  free (input_file_encoding);
+  return 0;
+}
+
+typedef struct IMAGE_FILE_LOCATION_INFO {
+    char *image_file;
+    char *image_extension;
+    char *image_path;
+    char *image_path_encoding;
+} IMAGE_FILE_LOCATION_INFO;
+
+void
+free_image_file_location_info (IMAGE_FILE_LOCATION_INFO *location_info)
+{
+  free (location_info->image_file);
+  free (location_info->image_extension);
+  free (location_info->image_path);
+  free (location_info->image_path_encoding);
+}
+
+IMAGE_FILE_LOCATION_INFO *
+html_image_file_location_name (CONVERTER *self, const enum command_id cmd,
+                    const ELEMENT *element, const char *image_basefile,
+                    const HTML_ARGS_FORMATTED *args_formatted)
+{
+  char *image_file = 0;
+  char *extension = 0;
+
+  IMAGE_FILE_LOCATION_INFO *result = (IMAGE_FILE_LOCATION_INFO *)
+    malloc (sizeof (IMAGE_FILE_LOCATION_INFO));
+
+  if (args_formatted->number > 4
+      && args_formatted->args[4].formatted[AFT_type_filenametext])
+    {
+      extension
+       = args_formatted->args[4].formatted[AFT_type_filenametext];
+      image_file
+        = find_image_extension_file (self, element, image_basefile,
+                                     extension, &result->image_path,
+                                     &result->image_path_encoding);
+      if (!image_file)
+        {
+          char *dot_ext;
+          xasprintf (&dot_ext, ".%s", extension);
+          image_file
+            = find_image_extension_file (self, element, image_basefile,
+                                         dot_ext, &result->image_path,
+                                         &result->image_path_encoding);
+          if (image_file)
+            result->image_extension = dot_ext;
+        }
+      else
+        result->image_extension = strdup (extension);
+    }
+
+  if (!image_file)
+    {
+      int i;
+      for (i = 0; image_files_extensions[i]; i++)
+        {
+          image_file
+            = find_image_extension_file (self, element, image_basefile,
+                        image_files_extensions[i], &result->image_path,
+                              &result->image_path_encoding);
+          if (image_file)
+            {
+              result->image_extension = strdup (image_files_extensions[i]);
+              break;
+            }
+        }
+    }
+
+  if (!image_file)
+    {
+      result->image_path = 0;
+      result->image_path_encoding = 0;
+      if (extension)
+        {
+          xasprintf (&result->image_file, "%s%s", image_basefile,
+                                                  extension);
+          result->image_extension = strdup (extension);
+        }
+      else
+        {
+          xasprintf (&result->image_file, "%s.jpg", image_basefile);
+          result->image_extension = strdup (".jpg");
+        }
+    }
+  else
+    result->image_file = image_file;
+
+  return result;
+}
+
+void
+convert_image_command (CONVERTER *self, const enum command_id cmd,
+                    const ELEMENT *element,
+                    const HTML_ARGS_FORMATTED *args_formatted,
+                    const char *content, TEXT *result)
+{
+  if (args_formatted->number > 0
+      && args_formatted->args[0].formatted[AFT_type_filenametext]
+      && strlen (args_formatted->args[0].formatted[AFT_type_filenametext]))
+    {
+      IMAGE_FILE_LOCATION_INFO *image_path_info;
+      char *image_basefile
+        = args_formatted->args[0].formatted[AFT_type_filenametext];
+      char *basefile_string = 0;
+      char *image_file;
+      char *attribute_class;
+      char *protected_image_file;
+      STRING_LIST *classes;
+      const char *alt_string;
+
+      if (args_formatted->args[0].formatted[AFT_type_monospacestring])
+        basefile_string
+          = args_formatted->args[0].formatted[AFT_type_monospacestring];
+
+      if (html_in_string (self))
+        {
+          if (basefile_string)
+            text_append (result, basefile_string);
+          return;
+        }
+
+      image_path_info = html_image_file_location_name (self, cmd, element,
+                                                       image_basefile,
+                                                       args_formatted);
+      image_file = image_path_info->image_file;
+      image_path_info->image_file = 0;
+
+      if (!image_path_info->image_path)
+        {
+          noticed_line_warn (self, element,
+                "@image file `%s' (for HTML) not found, using `%s'",
+                     image_basefile, image_file);
+        }
+      free_image_file_location_info (image_path_info);
+
+      if (self->conf->IMAGE_LINK_PREFIX)
+        {
+          char *tmp;
+          xasprintf (&tmp, "%s%s", self->conf->IMAGE_LINK_PREFIX,
+                                   image_file);
+          free (image_file);
+          image_file = tmp;
+        }
+
+      classes = (STRING_LIST *) malloc (sizeof (STRING_LIST));
+      memset (classes, 0, sizeof (STRING_LIST));
+      add_string (builtin_command_name (cmd), classes);
+
+      attribute_class = html_attribute_class (self, "img", classes);
+      destroy_strings_list (classes);
+      text_append (result, attribute_class);
+      free (attribute_class);
+
+      protected_image_file = url_protect_file_text (self, image_file);
+      free (image_file);
+
+      if (args_formatted->number > 3
+          && args_formatted->args[3].formatted[AFT_type_string]
+          && strlen (args_formatted->args[3].formatted[AFT_type_string]))
+        alt_string = args_formatted->args[3].formatted[AFT_type_string];
+      else if (basefile_string)
+        alt_string = basefile_string;
+      else
+        alt_string = "";
+
+      text_printf (result, " src=\"%s\" alt=\"%s\"", protected_image_file,
+                           alt_string);
+
+      free (protected_image_file);
+      close_html_lone_element (self, result);
+    }
+}
+
 void
 convert_indicateurl_command (CONVERTER *self, const enum command_id cmd,
                     const ELEMENT *element,
@@ -10267,6 +10480,7 @@ static COMMAND_INTERNAL_CONVERSION 
commands_internal_conversion_table[] = {
   {CM_footnote, &convert_footnote_command},
   {CM_uref, &convert_uref_command},
   {CM_url, &convert_uref_command},
+  {CM_image, convert_image_command},
 
   /* note that if indicateurl had been in self->style_formatted_cmd this
      would have prevented indicateurl to be associated to
diff --git a/tp/Texinfo/XS/main/convert_utils.h 
b/tp/Texinfo/XS/main/convert_utils.h
index bbb907fe48..e7f2773223 100644
--- a/tp/Texinfo/XS/main/convert_utils.h
+++ b/tp/Texinfo/XS/main/convert_utils.h
@@ -37,6 +37,11 @@ ELEMENT *definition_category_tree (OPTIONS *options, const 
ELEMENT *current);
 ELEMENT *translated_command_tree (CONVERTER *self, enum command_id cmd);
 void destroy_translated_commands (TRANSLATED_COMMAND *translated_commands);
 
+char *encoded_input_file_name (OPTIONS *options,
+                         GLOBAL_INFO *global_information,
+                         char *file_name, char *input_file_encoding,
+                         char **file_name_encoding,
+                         const SOURCE_INFO *source_info);
 char *encoded_output_file_name (OPTIONS *options,
                                 GLOBAL_INFO *global_information,
                                 char *file_name, char **file_name_encoding,



reply via email to

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