bug-texinfo
[Top][All Lists]
Advanced

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

makeinfo: @image doesn't search @include path; patch enclosed


From: Jim Blandy
Subject: makeinfo: @image doesn't search @include path; patch enclosed
Date: Wed, 26 Sep 2001 16:30:34 -0500 (EST)

When constructing HTML or Info files with makeinfo, the @image command
doesn't search the @include path to find image files.  This is
inconsistent with texi2dvi, which searches TEXINPUTS for .eps files.
It also makes it difficult to build documentation using separate
source and build trees; one has to either copy the image files into
the build tree, or edit the .texi file to contain the full path to the
source tree.

The following patch changes the `makeinfo' @image command to search
the same path address@hidden' does.

Please let me know whether this patch is acceptable; I'm happy to
revise it as needed.

2001-09-26  Jim Blandy  <address@hidden>

        * makeinfo/makeinfo.c (cm_image): Search for image files in
        include_files_path.  Use get_file_info_in_path to find the files.
        Treat a missing .txt file as a real error, not just a warning, as
        we do missing .jpg or .png files.
        * makeinfo/files.c (get_file_info_with_extensions): New function.
        (get_file_info_in_path): Add new argument, EXTENSIONS; implement
        in terms of get_file_info_with_extensions.
        (find_and_load): Add EXTENSIONS argument to call to
        get_file_info_in_path; a value of "" preserves its old behavior.
        * makefilo/files.h (get_file_info_in_path): Add external
        declaration.
        * doc/texinfo.txi: Document the searching behavior.

*** makeinfo/makeinfo.c.~1~     Sun Sep 19 10:24:44 1999
--- makeinfo/makeinfo.c Wed Sep 26 10:49:48 2001
***************
*** 3013,3070 ****
  
    if (*name_arg)
      {
!       char *fullname = xmalloc (strlen (name_arg) + 4 + 1);
  
        if (html)
          { /* fixxme It would be nice to insert more useful alt text.  */
!           sprintf (fullname, "%s.png", name_arg);
!           if (access (fullname, R_OK) != 0)
              {
!               sprintf (fullname, "%s.jpg", name_arg);
!               if (access (fullname, R_OK) != 0)
!                 {
!                   line_error (_("No .png or .jpg for `%s'"), name_arg);
!                   return;
!                 }
!           }
  
!           add_word_args ("<img src=\"%s\" alt=\"%s\">", fullname, fullname);
          }
        else
          { /* Try to open foo.txt.  */
            FILE *image_file;
-           strcpy (fullname, name_arg);
-           strcat (fullname, ".txt");
-           image_file = fopen (fullname, "r");
-           if (image_file)
-             {
-               int ch;
-               int save_inhibit_indentation = inhibit_paragraph_indentation;
-               int save_filling_enabled = filling_enabled;
- 
-               inhibit_paragraph_indentation = 1;
-               filling_enabled = 0;
-               last_char_was_newline = 0;
- 
-               /* Maybe we need to remove the final newline if the image
-                  file is only one line to allow in-line images.  On the
-                  other hand, they could just make the file without a
-                  final newline.  */
-               while ((ch = getc (image_file)) != EOF)
-                 add_char (ch);
  
!               inhibit_paragraph_indentation = save_inhibit_indentation;
!               filling_enabled = save_filling_enabled;
  
!               if (fclose (image_file) != 0)
!                 perror (fullname);
              }
!           else
!             warning (_("@image file `%s' unreadable: %s"), fullname,
!                        strerror (errno));
          }
  
!       free (fullname);
      }
    else
      line_error (_("@image missing filename argument"));
--- 3013,3100 ----
  
    if (*name_arg)
      {
!       char *fullpath;
!       struct stat fileinfo;
  
        if (html)
          { /* fixxme It would be nice to insert more useful alt text.  */
!           fullpath = get_file_info_in_path (name_arg, include_files_path,
!                                             ".png:.jpg", &fileinfo);
!           if (! fullpath)
              {
!               line_error (_("Couldn't find `.png' or `.jpg' file for `%s'"),
!                           name_arg);
!               free (fullpath);
!               free (name_arg);
!               return;
!             }
  
!           {
!             /* Use only the last component of the filename as
!                the image source; omit the directory path.  It's
!                the user's responsibility to install the image
!                file along with the HTML.  */
!             char *tail = strrchr (fullpath, '/');
!             if (tail)
!               tail++;
!             else
!               tail = fullpath;
!             add_word_args ("<img src=\"%s\" alt=\"%s\">",
!                            tail, tail);
!           }
          }
        else
          { /* Try to open foo.txt.  */
            FILE *image_file;
  
!           /* Find the file in the @include path.  */
!           fullpath = get_file_info_in_path (name_arg, include_files_path,
!                                             ".txt", &fileinfo);
!           if (! fullpath)
!             {
!               line_error (_("Couldn't find `.txt' file for `%s'"),
!                           name_arg);
!               free (name_arg);
!               return;
!             }
  
!           /* Try to open the file we found.  */
!           image_file = fopen (fullpath, "r");
!           if (! image_file)
!             {
!               line_error (_("Couldn't open text image file `%s': %s"),
!                           fullpath, strerror (errno));
!               free (fullpath);
!               free (name_arg);
!               return;
              }
! 
!           /* Copy the contents of the image file into the .info file.  */
!           {
!             int ch;
!             int save_inhibit_indentation = inhibit_paragraph_indentation;
!             int save_filling_enabled = filling_enabled;
! 
!             inhibit_paragraph_indentation = 1;
!             filling_enabled = 0;
!             last_char_was_newline = 0;
! 
!             /* Maybe we need to remove the final newline if the image
!                file is only one line to allow in-line images.  On the
!                other hand, they could just make the file without a
!                final newline.  */
!             while ((ch = getc (image_file)) != EOF)
!               add_char (ch);
! 
!             inhibit_paragraph_indentation = save_inhibit_indentation;
!             filling_enabled = save_filling_enabled;
!           }
!           
!           if (fclose (image_file) != 0)
!             perror (fullpath);
          }
  
!       free (fullpath);
      }
    else
      line_error (_("@image missing filename argument"));
*** makeinfo/files.h.~1~        Sat Oct 24 16:37:26 1998
--- makeinfo/files.h    Wed Sep 26 07:02:36 2001
***************
*** 41,45 ****
--- 41,46 ----
  extern char *expand_filename ();
  extern char *filename_part ();
  extern char *pathname_part ();
+ extern char *get_file_info_in_path ();
  
  #endif /* !FILES_H */
*** makeinfo/files.c.~1~        Tue Mar 23 16:42:44 1999
--- makeinfo/files.c    Wed Sep 26 08:09:40 2001
***************
*** 78,90 ****
      }
  }
  
  /* Return the full pathname for FILENAME by searching along PATH.
     When found, return the stat () info for FILENAME in FINFO.
     If PATH is NULL, only the current directory is searched.
     If the file could not be found, return a NULL pointer. */
! static char *
! get_file_info_in_path (filename, path, finfo)
!      char *filename, *path;
       struct stat *finfo;
  {
    char *dir;
--- 78,147 ----
      }
  }
  
+ 
+ /* If FILENAME exists with any of the extensions in EXTENSIONS, return
+    the extended filename, and fill in FINFO with that file's info.
+    EXTENSIONS is a colon-separated list of filename extensions, including the
+    leading `.' character.  If EXTENSIONS is "", that's treated as a list
+    containing a single extension: the empty string.
+    The returned filename is always freshly allocated with xmalloc; the
+    caller is responsible for freeing it.
+    If we can't find the file under any of the extensions given, return
+    a NULL pointer.  */
+ static char *
+ get_file_info_with_extensions (filename, extensions, finfo)
+      char *filename, *extensions;
+      struct stat *finfo;
+ {
+   int filename_len = strlen (filename);
+ 
+   /* The start of the next extensions in `extensions' we're going to
+      try.  */
+   char *ext_start = extensions;
+ 
+   do
+     {
+       int ext_len;
+       char *extended;
+ 
+       /* Find the length of the next extension.  */
+       for (ext_len = 0;
+            (   ext_start[ext_len] != '\0'
+             && ext_start[ext_len] != ':');
+            ext_len++)
+         ;
+ 
+       extended = xmalloc (filename_len + ext_len + 1);
+       strcpy (extended, filename);
+       memcpy (extended + filename_len, ext_start, ext_len);
+       extended[filename_len + ext_len] = '\0';
+ 
+       if (stat (extended, finfo) == 0)
+         return extended;
+ 
+       free (extended);
+       ext_start += ext_len;
+       if (*ext_start == ':')
+         ext_start++;
+     }
+   while (*ext_start != '\0');
+ 
+   return 0;
+ }
+ 
+ 
  /* Return the full pathname for FILENAME by searching along PATH.
     When found, return the stat () info for FILENAME in FINFO.
     If PATH is NULL, only the current directory is searched.
+    EXTENSIONS is a colon-separated list of filename extensions, including the
+    leading `.' character.  If EXTENSIONS is "", that's treated as a list
+    containing a single extension: the empty string.  We look for
+    FILENAME with each of the extensions before going on to the next
+    directory in PATH.
     If the file could not be found, return a NULL pointer. */
! char *
! get_file_info_in_path (filename, path, extensions, finfo)
!      char *filename, *path, *extensions;
       struct stat *finfo;
  {
    char *dir;
***************
*** 98,113 ****
        || (*filename == '.'
            && (IS_SLASH (filename[1])
                || (filename[1] == '.' && IS_SLASH (filename[2])))))
!     {
!       if (stat (filename, finfo) == 0)
!         return xstrdup (filename);
!       else
!         return NULL;
!     }
! 
    while ((dir = extract_colon_unit (path, &index)))
      {
        char *fullpath;
  
        if (!*dir)
          {
--- 155,166 ----
        || (*filename == '.'
            && (IS_SLASH (filename[1])
                || (filename[1] == '.' && IS_SLASH (filename[2])))))
!     return get_file_info_with_extensions (filename, extensions, finfo);
!   
    while ((dir = extract_colon_unit (path, &index)))
      {
        char *fullpath;
+       char *extended_fullpath;
  
        if (!*dir)
          {
***************
*** 118,133 ****
        fullpath = xmalloc (2 + strlen (dir) + strlen (filename));
        sprintf (fullpath, "%s/%s", dir, filename);
        free (dir);
! 
!       result = stat (fullpath, finfo);
! 
!       if (result == 0)
!         return fullpath;
!       else
!         free (fullpath);
      }
    return NULL;
  }
  
  /* Find and load the file named FILENAME.  Return a pointer to
     the loaded file, or NULL if it can't be loaded. */
--- 171,186 ----
        fullpath = xmalloc (2 + strlen (dir) + strlen (filename));
        sprintf (fullpath, "%s/%s", dir, filename);
        free (dir);
!       extended_fullpath = get_file_info_with_extensions (fullpath, extensions,
!                                                          finfo);
!       free (fullpath);
!       if (extended_fullpath)
!         return extended_fullpath;
      }
    return NULL;
  }
+ 
+ 
  
  /* Find and load the file named FILENAME.  Return a pointer to
     the loaded file, or NULL if it can't be loaded. */
***************
*** 145,151 ****
  
    result = fullpath = NULL;
  
!   fullpath = get_file_info_in_path (filename, include_files_path, &fileinfo);
  
    if (!fullpath)
      goto error_exit;
--- 198,205 ----
  
    result = fullpath = NULL;
  
!   fullpath = get_file_info_in_path (filename, include_files_path, "", 
!                                     &fileinfo);
  
    if (!fullpath)
      goto error_exit;
*** doc/texinfo.txi.~1~ Tue Sep 28 14:38:01 1999
--- doc/texinfo.txi     Wed Sep 26 12:01:16 2001
***************
*** 9977,9982 ****
--- 9977,9987 ----
  to patents.)
  @end itemize
  
+ These programs search for the image file in the same directories the
+ @code{@@include} command would: @TeX{} searches the directories named in
+ the @env{TEXINPUTS} environment variable; @code{makeinfo} searches the
+ directories specified by the @code{-I} command-line switches; and so on.
+ 
  @cindex Width of images
  @cindex Height of images
  @cindex Aspect ratio of images





reply via email to

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