changeset 18895:b8934a57e13e

Improve plot comparison scripts. * compare_plot_demos.m: Rewrite docstring. Use all three plot directories in comparison ("appearance", "draw", "util"). Rename input variable structure "in" to "arg". Terminate lines of code with semicolon. * dump_demos.m: Rewrite docstring. Use fileparts to simplify checking of output script file name. Accept a single directory or a cell string array of directories for processing. Revamp test for non-existent directory. Remove unused code providing replacement Octave functions for Matlab. Remove linkaxes, linkprops, and colormap from list of demos to process since they have interactive elements. Use sprintf format string to avoid if/else structure. Simplify generated code for each plot comparison. Use 'close all' at the end of each demo to work around issues with accumulating cruft. Follow Octave coding conventions for cuddling parentheses. * dump_demos.m (oct2mat): Use regexprep() to convert double quotes in Octave demos to single quotes for Matlab. Comment out unwind_protect blocks since Matlab has no knowledge of these. Fix up calls to sombrero without an argument since Matlab doesn't have a default for this.
author Rik <rik@octave.org>
date Fri, 04 Jul 2014 14:32:49 -0700
parents 24332f256940
children 4d75bda5df80
files scripts/testfun/private/compare_plot_demos.m scripts/testfun/private/dump_demos.m
diffstat 2 files changed, 99 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/testfun/private/compare_plot_demos.m	Thu Jul 03 20:42:41 2014 -0700
+++ b/scripts/testfun/private/compare_plot_demos.m	Fri Jul 04 14:32:49 2014 -0700
@@ -18,25 +18,26 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} compare_plot_demos ()
+## @deftypefnx {Function File} {} compare_plot_demos ("toolkits", @{@var{toolkit1}, @var{toolkit2}, @dots{}@})
 ##
-## Uses @code{dump_demos} and @code{html_compare} to produce an html
-## comparison of the plot demos for each of Octave's graphics
-## toolkits. 
+## Uses @code{dump_demos} and @code{html_compare_plot_demos} to produce an
+## html comparison of the plot demos for each of Octave's graphics toolkits. 
 ##
-## A m-file names `dump_plots.m' will be created in the pwd. This function
-## will be used to render and save the plot demo images.
+## An m-file named @file{dump_plots.m} will be created in the current working
+## directory. This function will be used to render and save the plot demo
+## images.
 ##
-## If they do not already exist, directories for each graphics toolkit
-## are created. Each toolkit's directory will be populated with images
+## If they do not already exist, directories for each available graphics
+## toolkit are created.  Each toolkit's directory will be populated with images
 ## of each plot demo in the png format.
 ##
-## Finally, an htlm document named `compare_plot_demos.html' is produced.
-## This page places each toolkits images side by side for a conventient
+## Finally, an html document named @file{compare_plot_demos.html} is produced.
+## This page places each toolkit's images side by side for a convenient
 ## comparison of the results.
 ##
-## @deftypefnx  {Function File} {} compare_plot_demos (@var{toolkits})
-## @var{toolkits} is used to specify a subset of the available graphics
-## toolkits. This list may also include `matlab'.
+## If the property @qcode{"toolkits"} is given then compare only the listed
+## toolkits in the cell string.  The list may also include the toolkit
+## @qcode{"matlab"}.
 ##
 ## @end deftypefn
 
@@ -44,75 +45,75 @@
 
 function compare_plot_demos (varargin)
 
-  in.toolkits = available_graphics_toolkits ();
-  in.directory = "plot";
-  in.fmt = "png";
-  in.fcn_file = "";
-  in.replace_images = false;
+  arg.toolkits = available_graphics_toolkits ();
+  arg.directories = {"plot/appearance", "plot/draw", "plot/util"};
+  arg.fmt = "png";
+  arg.fcn_file = "";
+  arg.replace_images = false;
 
   for n = 1:2:numel(varargin)
     if (! ischar (varargin{n}))
       print_usage ();
     else
-      in.(varargin{n}) = varargin{n+1};
+      arg.(varargin{n}) = varargin{n+1};
     endif
   endfor
 
-  if (ischar (in.toolkits))
-    in.toolkits = {in.toolkits};
-  elseif (! iscellstr (in.toolkits))
-    error ("compare_plot_demos: Invalid value for ""toolkits""")
+  if (ischar (arg.toolkits))
+    arg.toolkits = {arg.toolkits};
+  elseif (! iscellstr (arg.toolkits))
+    error ('compare_plot_demos: Invalid value for "toolkits"')
   endif
 
-  if (! ischar (in.directory))
-    error ("compare_plot_demos: Invalid value for ""directory""")
+  if (ischar (arg.directories))
+    arg.directories = {arg.directories};
+  elseif (! iscellstr (arg.directories))
+    error ('compare_plot_demos: Invalid value for "directory"')
   endif
 
-  if (! ischar (in.fmt))
-    error ("compare_plot_demos: Invalid value for ""fmt""")
+  if (! ischar (arg.fmt))
+    error ('compare_plot_demos: Invalid value for "fmt"')
   endif
 
-  if (isempty (in.fcn_file))
-    in.fcn_file = sprintf ("dump_%s_demos.m", in.directory);
+  if (isempty (arg.fcn_file))
+    arg.fcn_file = "dump_plot_demos.m";
   endif
 
-  ## Generate "dump_plots.m" for rendering/saving the plot demo images
-  dump_demos ("plot", in.fcn_file, in.fmt)
+  ## Generate "dump_plot_demos.m" for rendering/saving the plot demo images
+  dump_demos (arg.directories, arg.fcn_file, arg.fmt);
 
-  [~, fcn_name] = fileparts (in.fcn_file);
+  [~, fcn_name] = fileparts (arg.fcn_file);
 
   ## Generate the plot demo images for each toolkit
   cwd = pwd ();
   unwind_protect
     addpath (pwd);
-    for n = 1:numel(in.toolkits)
-      dirs = dir ();
-      dirs = dirs([dirs.isdir]);
-      if (! any (strcmp ({dirs.name}, in.toolkits{n})))
-        mkdir (in.toolkits{n})
+    for n = 1:numel (arg.toolkits)
+      if (! isdir (fullfile (cwd, arg.toolkits{n})))
+        mkdir (arg.toolkits{n});
       endif
-      cd (in.toolkits{n})
-      if (! isempty (dir (strcat ("*.", in.fmt))) && in.replace_images)
-        delete (strcat ("*.", in.fmt))
+      cd (arg.toolkits{n});
+      if (arg.replace_images && ! isempty (dir (["*." arg.fmt])))
+        delete (["*." arg.fmt]);
       endif
-      if (! strcmp (in.toolkits{n}, "matlab"))
-        close all
-        graphics_toolkit (in.toolkits{n});
+      if (! strcmp (arg.toolkits{n}, "matlab"))
+        close all;
+        graphics_toolkit (arg.toolkits{n});
         try
           eval (fcn_name);
         catch
-          fprintf ("Error running plot demos for ""%s"" toolkit\n", in.toolkits{n})
-          disp (lasterror)
+          printf ("Error running plot demos for ""%s"" toolkit\n", arg.toolkits{n});
+          disp (lasterror);
         end_try_catch
       endif
-      cd (cwd)
+      cd (cwd);
     endfor
   unwind_protect_cleanup
     rmpath (cwd);
   end_unwind_protect
 
   ## Generate the html comparison of the images
-  ## TODO - pass the toolkits{} to allow num of columns to be formated
+  ## TODO: pass the toolkits{} to allow number of columns to be formatted
   html_compare_plot_demos ("output", "compare_plot_demos.html")
 
 endfunction
--- a/scripts/testfun/private/dump_demos.m	Thu Jul 03 20:42:41 2014 -0700
+++ b/scripts/testfun/private/dump_demos.m	Fri Jul 04 14:32:49 2014 -0700
@@ -21,14 +21,14 @@
 ## @deftypefnx {Function File} {} dump_demos (@var{dirs})
 ## @deftypefnx {Function File} {} dump_demos (@var{dirs}, @var{mfile})
 ## @deftypefnx {Function File} {} dump_demos (@var{dirs}, @var{mfile}, @var{fmt})
-## Produces a script, with the name specified by @var{mfile}, containing
-## the demos in the directories, @var{dirs}. The demos are assumed to produce
-## graphical output, whose renderings are saved with specified format,
+## Produce a script, with the name specified by @var{mfile}, containing
+## the demos in the directories, @var{dirs}.  The demos are assumed to produce
+## graphical output, whose renderings are saved with the specified format,
 ## @var{fmt}.
 ##
 ## The defaults for each input are;
 ##
-## @table @samp
+## @table @var
 ##   @item @var{dirs}
 ##   @code{@{"plot/appearance", "plot/draw", "plot/util"@}}
 ##   @item @var{mfile}
@@ -41,51 +41,45 @@
 ## in the plot directory;
 ##
 ## @example
-## @group
 ## dump_demos plot dump.m png
-## @end group
 ## @end example
 ## @seealso{fntests, test, demo}
 ## @end deftypefn
 
 ## Author: Søren Hauberg  <soren@hauberg.org>
 
-function dump_demos (dirs= {"plot/appearance", "plot/draw", "plot/util"}, output="dump.m", fmt="png")
+function dump_demos (dirs={"plot/appearance", "plot/draw", "plot/util"}, output="dump.m", fmt="png")
 
   if (nargin > 3)
     print_usage ();
   endif
 
-  if (strfind (output, ".m") != numel (output) - 1)
-    output = strcat (output, ".m");
+  if (ischar (dirs))
+    dirs = {dirs};
+  elseif (! iscellstr (dirs))
+    error ("dump_demos: DIRS must be a cell array of strings with directory names");
+  endif
+
+  [~, funcname, ext] = fileparts (output);
+  if (isempty (ext))
+    output = [output ".m"];
   endif
 
   ## Create script beginning (close figures, etc.)
   fid = fopen (output, "w");
-  n = find (output == ".", 1, "last");
-  if (isempty (n))
-    n = numel (output);
-  else
-    n = n - 1;
-  endif
   fprintf (fid, "%% DO NOT EDIT!  Generated automatically by dump_demos.m\n");
-  fprintf (fid, "function %s ()\n", output(1:n));
+  fprintf (fid, "function %s ()\n", funcname);
   fprintf (fid, "close all\n");
   fprintf (fid, "more off\n");
 
   ## Run and print the demos in each directory
   for i = 1:numel (dirs)
-    if (!is_absolute_filename (dirs{i}))
-      fullname = dir_in_loadpath (dirs{i});
-      if (! isempty (fullname))
-        dirs{i} = fullname;
-      else
-        error ("dump_demos: expecting DIRS argument to be a cell arrays of strings with directory names");
-      endif
+    d = dirs{i};
+    if (! is_absolute_filename (d))
+      d = dir_in_loadpath (d);
     endif
-    d = dirs{i};
-    if (!exist (d, "dir"))
-      error ("dump_demos: directory %s doesn't exist", d);
+    if (! exist (d, "dir"))
+      error ("dump_demos: directory %s does not exist", d);
     endif
     dump_all_demos (d, fid, fmt);
   endfor
@@ -93,42 +87,6 @@
   ## Create script ending
   fprintf (fid, "end\n\n")
 
-  ## TODO - Should dump_demos() attempt to convert the demos to traditional
-  ##        syntax.
-  ##        (1) oct2mat() to convert some Octave specific syntax.
-  ##        (2) Embed sombrero(), vec(), cstrcat() and assert() in demos ?
-
-  ## sombrero has now a default argument which isn't supported from matlab
-  ## http://octave.1599824.n4.nabble.com/sombrero-default-argument-matlab-compatibility-td4665016.html
-  ## TODO: we need to change it prior running
-  ## -function [x, y, z] = sombrero (n = 41)
-  ## +function [x, y, z] = sombrero (n)
-  ## +
-  ## +  if (nargin == 0)
-  ## +    n = 41;
-  ## +  endif
-  
-  for mfile = {"sombrero"}
-    f = which (mfile{1});
-    fid2 = fopen (f);
-    code = char (fread (fid2));
-    code = oct2mat (code);
-    fprintf (fid, "%s", code);
-    fclose (fid2);
-  endfor
-%~
-  %~ fprintf (fid, "function x = vec (x)\n")
-  %~ fprintf (fid, "  x = x(:);\n")
-  %~ fprintf (fid, "end\n")
-%~
-  %~ fprintf (fid, "function str = cstrcat (varargin)\n")
-  %~ fprintf (fid, "  str = [varargin{:}];\n")
-  %~ fprintf (fid, "end\n")
-%~
-  %~ fprintf (fid, "function assert (varargin)\n")
-  %~ fprintf (fid, "%% Do nothing.\n")
-  %~ fprintf (fid, "end\n")
-
   ## Close script
   fclose (fid);
 endfunction
@@ -138,49 +96,48 @@
   flist = {dirinfo.name};
   ## Remove uigetdir, uigetfile, uiputfile, etc.
   flist = flist(! strncmp (flist, "ui", 2));
+  ## Remove linkaxes, linkprops
+  flist = flist(! strncmp (flist, "link", 4));
+  ## Remove colormap
+  flist = flist(! strncmp (flist, "colormap", 8));
   for i = 1:numel (flist)
-    fun = flist{i};
-    fun (end-1:end) = []; # remove .m
-    demos = get_demos (fun);
+    fcn = flist{i};
+    fcn(end-1:end) = [];  # remove .m
+    demos = get_demos (fcn);
     for d = 1:numel (demos)
-      if (d < 10)
-        idx = sprintf ("0%d", d);
-      else
-        idx = sprintf ("%d", d);
-      end
+      idx = sprintf ("%02d", d);
       fprintf (fid, "\ntry\n");
-      fprintf (fid, "  %s\n\n", demos {d});
-      fprintf (fid, "  drawnow\n");
-      fprintf (fid, "  num_figures = get(0, 'currentfigure');\n");
-      fprintf (fid, "  for fig = 1:num_figures\n");
+      fprintf (fid, "  %s\n\n", demos{d});
+      fprintf (fid, "  drawnow;\n");
+      fprintf (fid, "  fig = (get (0, 'currentfigure'));\n");
+      fprintf (fid, "  if (~ isempty (fig))\n");
       fprintf (fid, "    figure (fig);\n");
-      fprintf (fid, "    name = sprintf ('%s_%s_%%d.%s', fig);\n", fun, idx, fmt);
-      fprintf (fid, "    if (numel (dir (name)) == 0)\n");
+      fprintf (fid, "    name = '%s_%s.%s';\n", fcn, idx, fmt);
+      fprintf (fid, "    if (isempty (dir (name)))\n");
       fprintf (fid, "      fprintf ('Printing ""%%s"" ... ', name);\n")
       fprintf (fid, "      print ('-d%s', name);\n", fmt);
-#     fprintf (fid, "      pause (1);\n");
       fprintf (fid, "      fprintf ('done\\n');\n");
       fprintf (fid, "    else\n");
       fprintf (fid, "      fprintf ('File ""%%s"" exists.\\n', name);\n")
       fprintf (fid, "    end\n");
-#     fprintf (fid, "    drawnow ();\n");
       fprintf (fid, "  end\n");
-      fprintf (fid, "  close (2:num_figures)\n");
+      # Temporary fix for cruft accumulating in figure window.
+      fprintf (fid, "  close ('all');\n");
       fprintf (fid, "catch\n");
-      fprintf (fid, "  fprintf ('ERROR in %s_%s: %%s\\n', lasterr ());\n", fun, idx);
+      fprintf (fid, "  fprintf ('ERROR in %s_%s: %%s\\n', lasterr ());\n", fcn, idx);
       fprintf (fid, "end\n\n");
     endfor
   endfor
   fprintf (fid, "close all\n");
 endfunction
 
-function retval = get_demos (fun)
-  [code, idx] = test (fun, "grabdemo");
+function retval = get_demos (fcn)
+  [code, idx] = test (fcn, "grabdemo");
   num_demos = length (idx) - 1;
   retval = cell (1, num_demos);
   ## Now split the demos into a cell array
   for k = 1:num_demos
-    retval {k} = oct2mat (code (idx (k):idx (k+1)-1));
+    retval{k} = oct2mat (code(idx(k):idx(k+1)-1));
   endfor
 endfunction
 
@@ -188,20 +145,25 @@
   ## Simple hacks to make things Matlab compatible
   code = strrep (code, "%!", "%%");
   code = strrep (code, "!", "~");
-  ## Simple replacing double quotes with single quotes
+  ## Simply replacing double quotes with single quotes
   ## causes problems with strings like 'hello "world"'
-  #code = strrep (code, "\"", "'");
+  ## More complicated regexprep targets only full double quoted strings
+  code = regexprep (code, "^([^']*)\"(.*)\"", "$1'$2'",
+                          "lineanchors", "dotexceptnewline");
   code = strrep (code, "#", "%");
-  ## Fix the format specs for the errobar demos
+  ## Fix the format specs for the errorbar demos changed by the line above
   code = strrep (code, "%r", "#r");
   code = strrep (code, "%~", "#~");
-  endkeywords = {"endfor", "endif", "endwhile", "end_try_catch", ...
-                 "endfunction", "end_unwind_protect"};
+  endkeywords = {"endfor", "endfunction", "endif", "endwhile", "end_try_catch"};
   for k = 1:numel (endkeywords)
     code = strrep (code, endkeywords{k}, "end");
   endfor
-  commentkeywords = {"unwind_proect"};
+  commentkeywords = {"unwind_protect", "end_unwind_protect"};
   for k = 1:numel (commentkeywords)
-    code = strrep (code, commentkeywords{k}, strcat ("%", commentkeywords{k}));
+    code = strrep (code, commentkeywords{k}, ["%" commentkeywords{k}]);
   endfor
+
+  ## Fix up sombrero which now has default argument in Octave
+  code = strrep (code, "sombrero ()", "sombrero (41)");
 endfunction
+