Menu

#1801 SVG terminal 'name' option doesn't work outside current directory

None
closed-fixed
nobody
None
2017-02-21
2016-05-26
Dan Sebald
No

To address an issue in Octave whereby the SVG terminal saves the SVG output in a subdirectory (i.e., full path), I wanted to introduce the use of 'name' option and provide the full path. Unfortunately, there is a non-obvious bug in gnuplot however that won't allow doing such a thing. Without the use of 'name', the situation is something like

mydir/nondir_test.svg
gp_image_01.png

in which nondir_test.svg references gp_image_01.png. But because gp_image_01.png is not in the same directory, the SVG view is missing the image.

With the use of 'name', here's what happens:

>> create_image_plot

gnuplot> set terminal svg enhanced size 576,432 dynamic name 'mydir/nondir_test_aux' fsize 8
                                                             ^
         line 0: name must contain only alphanumerics or _

and the result is

mydir/nondir_test.svg  [partially built before int_error called]
mydir/nondir_test_image_01.png

The PNG file ends up in the right place, but if the SVG file had a reference of "mydir/nondir_test_image_01.png" within, it again would not find the file. Basically, currently gnuplot cannot save SVG files with external links outside the current directory.

What makes sense to do here? I don't know. Certainly stripping away the directory path before the file name would work in this case where the SVG output filename and "name <plotfile>" have the same directory location. But more generally that wouldn't work...unless we did some creative programming in which we examine the output file name in relation to the 'name' specification and figured out what SVG link reference should be. (Maybe that wouldn't be too difficult.)</plotfile>

In this case, I think I might be able to change the directory path, do the plot, then return to the working directory.

Discussion

  • Ethan Merritt

    Ethan Merritt - 2016-05-26

    Maybe like this:

    original_directory = GPVAL_PWD
    set loadpath original_directory
    cwd "output/directory/path"
    set term svg ... name "FOO"
    set output 'FOO.svg'
    # Done with plot. Return to original directory
    cwd original_directory
    

    input will continue to be taken from the original directory because you added it to the loadpath. New files will go the new output directory.

     
  • Dan Sebald

    Dan Sebald - 2016-05-26

    Yes, I just did this

    diff --git a/scripts/plot/util/private/__gnuplot_print__.m b/scripts/plot/util/
    --- a/scripts/plot/util/private/__gnuplot_print__.m
    +++ b/scripts/plot/util/private/__gnuplot_print__.m
    @@ -110,8 +110,18 @@ function opts = __gnuplot_print__ (opts)
                    "print.m: '%s' output is not available for gnuplot-%s",
                    upper (opts.devopt), __gnuplot_version__ ());
           endif
    
    -    case "svg"
    -      local_drawnow (["svg dynamic " gp_opts], opts.name, opts);
    +    case {"svg", "svgstandalone"}
    +      [ndir, name, ext] = fileparts (opts.name);
    +      if (strfind (opts.devopt, "standalone"))
    +        gp_opts = sprintf ("standalone %s", gp_opts);
    +      else
    +        gp_opts = sprintf ("name '%s' %s", name, gp_opts);
    +      endif
    +      name = [name ext];
    +      pwd_temp = pwd ();
    +      cd (ndir)
    +      local_drawnow (["svg dynamic " gp_opts], name, opts);
    +      cd (pwd_temp);
         case {"eepic"}
           local_drawnow ([opts.devopt " color rotate " gp_opts], opts.name, opts);
         case {"aifm", "corel", "emf", "fig"}
    

    and it works. Still I'd consider this a bug. To fix this, I'd think that SVG would only want to have relative links, not absolute path links, so for most generality I think it would be necessary to reconstruct the full path for both the SVG and PNG files, then find the common root-directory and maybe end up with something like

    xlink:href='../../../dir1/dir2/dir3/test_image_01.png'

    within the SVG file.

     
  • Ethan Merritt

    Ethan Merritt - 2016-05-26

    The "name" string is used internally to make identifier hooks in the javascript code, so indeed it cannot contain slashes or other restricted characters.

    Another solution is to co-opt the "jsdir" parameter. It is already used to construct URLs for imported script files. It could plausibly also be used to construct URLs for imported image data files. Or I suppose you could add a new "linkdir" that functions similarly.

    As before, anything new that is added or changed will not help people using old versions of the program. The cwd work-around has the advantage that it works regardless of version.

     
  • Dan Sebald

    Dan Sebald - 2016-05-26

    Oh, I'm not real familiar with how SVG works... Yeah, nothing new helps with older versions. Octave does have version testing, but cwd works.

     
  • Dan Sebald

    Dan Sebald - 2016-05-28

    I'm attaching a patch that changes the behavior of how PNG referenced files are created. Read a description of the change within the diff file for the documentation section. I think this is a much more clean behavior.

    It can still leave some vestigial files about if the 'name' option is only changed, but that's to be expected. The alternative would be to look for what any existing SVG file contains for references and delete those, but that would likely be kind of dodgy.

    The only thing I might change is to relax the requirement of alphanumeric characters for the 'name' option but instead strip away any directory portion of the specified name. That is, if the user specified "name 'mydir/foo'", the first step would be to change that to 'foo' automatically.

    Anyway, I've been testing with things like:

    mkdir mydir
    ls > mydir/foo_image_01.png
    ls > mydir/foo_image_05.png
    gnuplot
    set term svg name 'foo'
    set output 'mydir/foo.svg'
    plot '-' with image
    0 0 0
    0 1 1
    1 0 2
    1 1 3
    e
    set output
    exit
    eog mydir/foo.svg
    

    Then take note that mydir/foo_image_05.png is gone.

     
  • Per Bothner

    Per Bothner - 2016-09-22

    I assume the recent "standalone" option ("inlining" the image using a data: URL) makes this less urgent. I think it might be reasonable to default to standalone mode for generated images (i.e. if not using a pre-existing image file), and/or if outstr is NULL (output has not been specified). Certainly, for the "domterm" terminal type using standalone mode sems to make most sense.

    If actually writing files, I'd tweak the default filename. If the outstr is "foo/bar.svg" then I think it makes sense to generate files based on that only. For example "foo/bar_image_01.png" and so on. It's not clear to me that you'd want to use the SVG_name at all, and you certainly should not use "gp" as the default prefix.

    One might also consider following the lead of web browsers when you save as "Web Page Complete". They save images and other content relating to "foo/bar.html" in a directory "foo/bar_files". Since that's an established convention, we may want to follow it. For example "foo/bar_files/image_01.png".

    Trying to "remove any possible external link files of previous versions of this file" seems unnessary and undesirable.

     
  • Ethan Merritt

    Ethan Merritt - 2017-02-20
    • status: open --> pending-fixed
    • Group: -->
    • Priority: -->
     
  • Ethan Merritt

    Ethan Merritt - 2017-02-20

    Yeah. Let's just default to embedding the png bitmaps. That obviates the whole problem.

     
  • Ethan Merritt

    Ethan Merritt - 2017-02-21
    • status: pending-fixed --> closed-fixed
     
  • Ethan Merritt

    Ethan Merritt - 2017-02-21

    Backported to 5.0 also.

     

Log in to post a comment.