changeset 17467:3cc57abeca48

Merge the official development
author LYH <lyh.kernel@gmail.com>
date Mon, 23 Sep 2013 03:17:47 +0800
parents 44a301d5551a (current diff) f0ecb52097ec (diff)
children dbfc7f98de02
files build-aux/mkinstalldirs libinterp/corefcn/jit-typeinfo.cc libinterp/corefcn/pt-jit.cc libinterp/dldfcn/eigs.cc libinterp/parse-tree/pt-eval.cc scripts/mkinstalldirs scripts/plot/private/__color_str_rgb__.m
diffstat 752 files changed, 17509 insertions(+), 14491 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate
+++ b/.hgsubstate
@@ -1,1 +1,1 @@
-5a51fb7777a9950502965a043a70bd6ca5e0498b gnulib-hg
+6057744acd2c71c069a4b171c5fe1ff0d86c9e5f gnulib-hg
--- a/.hgtags
+++ b/.hgtags
@@ -78,3 +78,4 @@
 b29b10fbb7448cdfe29322446e1a589e7fe1a40a release-3-6-4
 4e50bd2946d8563d3e201cc04b3ba0720c991b06 ss-3-7-4
 608e307b49149b32a6d09c2f06493d04d3af9be4 ss-3-7-5
+3a9efb68272df556dccb84c87933dd8238e88902 ss-3-7-6
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,7 +42,6 @@
   bootstrap.conf \
   build-aux/find-files-with-tests.sh \
   build-aux/mk-opts.pl \
-  build-aux/mkinstalldirs \
   build-aux/move-if-change \
   build-aux/OctJavaQry.class \
   etc/NEWS.1 \
@@ -150,8 +149,6 @@
 	$(MAKE) -C doc/doxyhtml doxyhtml
 .PHONY: doxyhtml
 
-octetc_DATA = NEWS
-
 DIRS_TO_MAKE = \
   $(localfcnfiledir) \
   $(localapifcnfiledir) \
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,67 @@
       endfunction
     endfunction
 
+ ** Line continuations inside character strings have changed.
+
+    The sequence '...' is no longer recognized as a line continuation
+    inside a character string.  A backslash '\' followed by a newline
+    character is no longer recognized as a line continuation inside
+    single-quoted character strings.  Inside double-quoted character
+    strings, a backslash followed by a newline character is still
+    recognized as a line continuation, but the backslash character must
+    be followed *immediately* by the newline character.  No whitespace or
+    end-of-line comment may appear between them.
+
+ ** Backslash as a continuation marker outside of double-quoted strings
+    is now deprecated.
+
+    Using '\' as a continuation marker outside of double quoted strings
+    is now deprecated and will be removed from a future version of
+    Octave.  When that is done, the behavior of
+
+      (a \
+       b)
+
+    will be consistent with other binary operators.
+
+ ** Redundant terminal comma accepted by parser
+
+    A redundant terminal comma is now accepted in matrix
+    definitions which allows writing code such as 
+
+    [a,...
+     b,...
+     c,...
+    ] = deal (1,2,3)
+
+ ** Octave now has limited support for named exceptions
+
+    The following syntax is now accepted:
+
+      try
+        statements
+      catch exception-id
+        statements
+      end
+
+    The exception-id is a structure with the fields "message" and
+    "identifier".  For example
+
+      try
+        error ("Octave:error-id", "error message");
+      catch myerr
+        printf ("identifier: %s\n", myerr.identifier);
+        printf ("message:    %s\n", myerr.message);
+      end_try_catch
+
+    When classdef-style classes are added to Octave, the exception-id
+    will become an MException object.
+
+ ** Warning IDs renamed:
+
+    Octave:array-as-scalar => Octave:array-to-scalar
+    Octave:array-as-vector => Octave:array-to-vector
+
  ** 'emptymatch', 'noemptymatch' options added to regular expressions.
 
     With this addition Octave now accepts the entire set of Matlab options
@@ -67,31 +128,24 @@
     expression would have searched for a literal '\' followed by 't' and
     replaced the two characters with the sequence '\', 'n'.
 
- ** Redundant terminal comma accepted by parser
-
-    A redundant terminal comma is now accepted in matrix
-    definitions which allows writing code such as 
-
-    [a,...
-     b,...
-     c,...
-    ] = deal (1,2,3)
-
- ** Line continuations inside character strings have changed.
+ ** A TeX parser has been implemented for the FLTK toolkit and is the default
+    for any text object including titles and axis labels.  The TeX parser is
+    supported only for display on a monitor, not for printing.
+    A quick summary of features:
 
-    The sequence '...' is no longer recognized as a line continuations
-    are inside character strings.  A backslash followed by a newline
-    character is no longer recognized as a line continuation inside
-    single-quoted character strings.  Inside double-quoted character
-    strings, a backslash followed by a newline character is still
-    recognized as a line continuation but the backslash character must
-    be followed immediately by the newline character.  No whitespace or
-    end-of-linecomment may appear between them.
-
- ** Warning IDs renamed:
-
-    Octave:array-as-scalar => Octave:array-to-scalar
-    Octave:array-as-vector => Octave:array-to-vector
+    Code         Feature     Example             Comment
+    _            subscript   H_2O                formula for water
+    ^            exponent    y=x^2               formula for parabola
+    \char        symbol      \beta               Greek symbol beta
+    \fontname    font        \fontname{Arial}    set Arial font
+    \fontsize    fontsize    \fontsize{16}       set fontsize 16
+    \color[rgb]  fontcolor   \color[rgb]{1 0 1}  set magenta color 
+    \bf          bold        \bfBold Text        bold font
+    \it          italic      \itItalic Text      italic font
+    \sl          slanted     \slOblique Text     slanted font
+    \rm          normal      \bfBold\rmNormal    normal font
+    {}           group       {\bf Bold}Normal    group objects
+                             e^{i*\pi} = -1      complex example
 
  ** The m-files in the image directory have been overhauled.
 
@@ -103,12 +157,30 @@
 
     Other changes include fixes to the way indexed images are read from a
     colormap depending on the image class (integer images have a -1 offset to
-    the colormap row number), and always returning the actual indexed image
-    with imread instead of a RGB image if the colormap was not requested
-    as output.
+    the colormap row number).
+
+ ** The imread and imwrite functions have been completely rewritten
+
+    The main changes relate to the alpha channel, support for reading and
+    writing of floating point images, implemented writing of indexed images,
+    and appending images to multipage image files.
+
+    The issues that may arise due to backwards incompatibility are:
 
- ** The colormap function now provides new options--"list", "register",
-    and "unregister"--to list all available colormap functions, and to
+      * imwrite no longer interprets a length of 2 or 4 in the third dimension
+        as grayscale or RGB with alpha channel (a length of 4 will be saved
+        as CMYK image).  Alpha channel must be passed as separate argument.
+      * imread will always return the colormap indexes when reading an indexed
+        image, even if the colormap is not requested as output.
+      * transparency values are now inverted from the previous Octave versions
+        (0 is for completely transparent instead of completely opaque).
+
+    In addition, the function imformats has been implemented to expand
+    reading and writing of images of different formats through imread
+    and imwrite.
+
+ ** The colormap function now provides new options---"list", "register",
+    and "unregister"---to list all available colormap functions, and to
     add or remove a function name from the list of known colormap
     functions.  Packages that implement extra colormaps should use these
     commands with PKG_ADD and PKG_DEL statements.
@@ -161,6 +233,11 @@
     In addition two new error functions erfi (imaginary error function) and
     dawson (scaled imaginary error function) have been added.
 
+ ** The glpk function has been modified to reflect changes in the GLPK
+    library.  The "round" and "itcnt" options have been removed.  The
+    "relax" option has been replaced by the "rtest" option.  The numeric
+    values of error codes and of some options have also changed.
+
  ** The default name of the Octave crash dump file is now called
     octave-workspace instead of octave-core.
 
@@ -201,10 +278,12 @@
       dawson                     imformats        shrinkfaces               
       dblist                     importdata       splinefit                 
       debug_jit                  isaxes           stemleaf                  
-      doc_cache_create           iscolormap       strjoin   
-      ellipj                     isequaln         struct2hdl                
-      ellipke                    jit_debug        tetramesh                 
-      erfcinv                    jit_enable       waterfall 
+      desktop                    iscolormap       strjoin    
+      doc_cache_create           isequaln         struct2hdl 
+      ellipj                     jit_debug        tetramesh                 
+      ellipke                    jit_enable       waterfall                 
+      erfcinv                    
+
 
  ** Deprecated functions.
 
@@ -246,7 +325,7 @@
     The internal class <Octave_map> has been deprecated in Octave 3.8 and will
     be removed from Octave 3.12 (or whatever version is the second major
     release after 3.8).  Replacement classes are <octave_map> (struct array)
-    or <octave_scalar_map> for single structure.
+    or <octave_scalar_map> for a single structure.
 
 Summary of important user-visible changes for version 3.6:
 ---------------------------------------------------------
--- a/bootstrap
+++ b/bootstrap
@@ -1,10 +1,10 @@
 #! /bin/sh
 # Print a version string.
-scriptversion=2012-07-19.14; # UTC
+scriptversion=2013-08-15.22; # UTC
 
 # Bootstrap this package from checked-out sources.
 
-# Copyright (C) 2003-2012 Free Software Foundation, Inc.
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -140,20 +140,21 @@
 "wget --mirror -nd -q -np -A.po -P '%s' \
  http://translationproject.org/latest/%s/"
 
+# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
+# fall back to the package name (1st argument with munging)
 extract_package_name='
-  /^AC_INIT(/{
-     /.*,.*,.*, */{
-       s///
-       s/[][]//g
-       s/)$//
+  /^AC_INIT(\[*/{
+     s///
+     /^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
+       s//\1/
+       s/[],)].*//
        p
        q
      }
-     s/AC_INIT(\[*//
-     s/]*,.*//
+     s/[],)].*//
      s/^GNU //
      y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
-     s/[^A-Za-z0-9_]/-/g
+     s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
      p
   }
 '
@@ -205,10 +206,8 @@
 # default.
 bootstrap_sync=false
 
-# Don't use git to update gnulib sources. We keep gnulib under a
-# Mercurial subrepository instead
-use_git=false
-GNULIB_SRCDIR=gnulib-hg
+# Use git to update gnulib sources
+use_git=true
 
 # find_tool ENVVAR NAMES...
 # -------------------------
@@ -225,27 +224,21 @@
   find_tool_names=$@
   eval "find_tool_res=\$$find_tool_envvar"
   if test x"$find_tool_res" = x; then
-    for i
-    do
+    for i; do
       if ($i --version </dev/null) >/dev/null 2>&1; then
-       find_tool_res=$i
-       break
+        find_tool_res=$i
+        break
       fi
     done
-  else
-    find_tool_error_prefix="\$$find_tool_envvar: "
   fi
-  test x"$find_tool_res" != x \
-    || die "one of these is required: $find_tool_names"
-  ($find_tool_res --version </dev/null) >/dev/null 2>&1 \
-    || die "${find_tool_error_prefix}cannot run $find_tool_res --version"
+  if test x"$find_tool_res" = x; then
+    warn_ "one of these is required: $find_tool_names;"
+    die   "alternatively set $find_tool_envvar to a compatible tool"
+  fi
   eval "$find_tool_envvar=\$find_tool_res"
   eval "export $find_tool_envvar"
 }
 
-# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
-find_tool SHA1SUM sha1sum gsha1sum shasum
-
 # Override the default configuration, if necessary.
 # Make sure that bootstrap.conf is sourced from the current directory
 # if we were invoked as "sh bootstrap".
@@ -257,12 +250,12 @@
 # Extra files from gnulib, which override files from other sources.
 test -z "${gnulib_extra_files}" && \
   gnulib_extra_files="
-        $build_aux/install-sh
-        $build_aux/mdate-sh
-        $build_aux/texinfo.tex
-        $build_aux/depcomp
-        $build_aux/config.guess
-        $build_aux/config.sub
+        build-aux/install-sh
+        build-aux/mdate-sh
+        build-aux/texinfo.tex
+        build-aux/depcomp
+        build-aux/config.guess
+        build-aux/config.sub
         doc/INSTALL
 "
 
@@ -308,34 +301,34 @@
   die "Bootstrapping from a non-checked-out distribution is risky."
 fi
 
-# Ensure that lines starting with ! sort last, per gitignore conventions
-# for whitelisting exceptions after a more generic blacklist pattern.
-sort_patterns() {
-  sort -u "$@" | sed '/^!/ {
-    H
-    d
-  }
-  $ {
-    P
-    x
-    s/^\n//
-  }' | sed '/^$/d'
+# Strip blank and comment lines to leave significant entries.
+gitignore_entries() {
+  sed '/^#/d; /^$/d' "$@"
 }
 
-# If $STR is not already on a line by itself in $FILE, insert it,
-# sorting the new contents of the file and replacing $FILE with the result.
-insert_sorted_if_absent() {
+# If $STR is not already on a line by itself in $FILE, insert it at the start.
+# Entries are inserted at the start of the ignore list to ensure existing
+# entries starting with ! are not overridden.  Such entries support
+# whitelisting exceptions after a more generic blacklist pattern.
+insert_if_absent() {
   file=$1
   str=$2
   test -f $file || touch $file
-  echo "$str" | sort_patterns - $file | cmp -s - $file > /dev/null \
-    || { echo "$str" | sort_patterns - $file > $file.bak \
-      && mv $file.bak $file; } \
-    || die "insert_sorted_if_absent $file $str: failed"
+  test -r $file || die "Error: failed to read ignore file: $file"
+  duplicate_entries=$(gitignore_entries $file | sort | uniq -d)
+  if [ "$duplicate_entries" ] ; then
+    die "Error: Duplicate entries in $file: " $duplicate_entries
+  fi
+  linesold=$(gitignore_entries $file | wc -l)
+  linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
+  if [ $linesold != $linesnew ] ; then
+    { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
+      || die "insert_if_absent $file $str: failed"
+  fi
 }
 
 # Adjust $PATTERN for $VC_IGNORE_FILE and insert it with
-# insert_sorted_if_absent.
+# insert_if_absent.
 insert_vc_ignore() {
   vc_ignore_file="$1"
   pattern="$2"
@@ -346,7 +339,7 @@
     # .gitignore entry.
     pattern=$(echo "$pattern" | sed s,^,/,);;
   esac
-  insert_sorted_if_absent "$vc_ignore_file" "$pattern"
+  insert_if_absent "$vc_ignore_file" "$pattern"
 }
 
 # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac.
@@ -470,7 +463,7 @@
     if [ "$req_ver" = "-" ]; then
       # Merely require app to exist; not all prereq apps are well-behaved
       # so we have to rely on $? rather than get_version.
-      $app --version >/dev/null 2>&1
+      $app --version >/dev/null 2>&1 </dev/null
       if [ 126 -le $? ]; then
         warn_ "Error: '$app' not found"
         ret=1
@@ -504,6 +497,12 @@
   # can't depend on column -t
 }
 
+# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
+# Also find the compatible sha1 utility on the BSDs
+if test x"$SKIP_PO" = x; then
+  find_tool SHA1SUM sha1sum gsha1sum shasum sha1
+fi
+
 use_libtool=0
 # We'd like to use grep -E, to see if any of LT_INIT,
 # AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -552,7 +551,7 @@
 echo "$0: Bootstrapping from checked-out $package sources..."
 
 # See if we can use gnulib's git-merge-changelog merge driver.
-if test -d .git && (git --version) >/dev/null 2>/dev/null ; then
+if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then
   if git config merge.merge-changelog.driver >/dev/null ; then
     :
   elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
@@ -575,13 +574,17 @@
   test -f .gitmodules && git config --file .gitmodules "$@"
 }
 
-gnulib_path=$(git_modules_config submodule.gnulib.path)
-test -z "$gnulib_path" && gnulib_path=gnulib
+if $use_git; then
+  gnulib_path=$(git_modules_config submodule.gnulib.path)
+  test -z "$gnulib_path" && gnulib_path=gnulib
+fi
 
-# Get gnulib files.
+# Get gnulib files.  Populate $GNULIB_SRCDIR, possibly updating a
+# submodule, for use in the rest of the script.
 
 case ${GNULIB_SRCDIR--} in
 -)
+  # Note that $use_git is necessarily true in this case.
   if git_modules_config submodule.gnulib.url >/dev/null; then
     echo "$0: getting gnulib files..."
     git submodule init || exit $?
@@ -602,8 +605,8 @@
   GNULIB_SRCDIR=$gnulib_path
   ;;
 *)
-  # Use GNULIB_SRCDIR as a reference.
-  if test -d "$GNULIB_SRCDIR"/.git && \
+  # Use GNULIB_SRCDIR directly or as a reference.
+  if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
         git_modules_config submodule.gnulib.url >/dev/null; then
     echo "$0: getting gnulib files..."
     if git submodule -h|grep -- --reference > /dev/null; then
@@ -629,12 +632,19 @@
   ;;
 esac
 
+# $GNULIB_SRCDIR now points to the version of gnulib to use, and
+# we no longer need to use git or $gnulib_path below here.
+
 if $bootstrap_sync; then
   cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
     echo "$0: updating bootstrap and restarting..."
+    case $(sh -c 'echo "$1"' -- a) in
+      a) ignored=--;;
+      *) ignored=ignored;;
+    esac
     exec sh -c \
       'cp "$1" "$2" && shift && exec "${CONFIG_SHELL-/bin/sh}" "$@"' \
-      -- "$GNULIB_SRCDIR/build-aux/bootstrap" \
+      $ignored "$GNULIB_SRCDIR/build-aux/bootstrap" \
       "$0" "$@" --no-bootstrap-sync
   }
 fi
@@ -682,11 +692,10 @@
     cksum_file="$ref_po_dir/$po.s1"
     if ! test -f "$cksum_file" ||
         ! test -f "$po_dir/$po.po" ||
-        ! $SHA1SUM -c --status "$cksum_file" \
-            < "$new_po" > /dev/null; then
+        ! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
       echo "$me: updated $po_dir/$po.po..."
       cp "$new_po" "$po_dir/$po.po" \
-          && $SHA1SUM < "$new_po" > "$cksum_file"
+          && $SHA1SUM < "$new_po" > "$cksum_file" || return
     fi
   done
 }
@@ -891,20 +900,21 @@
   -depth \( -name '*.m4' -o -name '*.[ch]' \) \
   -type l -xtype l -delete > /dev/null 2>&1
 
+# Invoke autoreconf with --force --install to ensure upgrades of tools
+# such as ylwrap.
+AUTORECONFFLAGS="--verbose --install --force -I $m4_base $ACLOCAL_FLAGS"
+
 # Some systems (RHEL 5) are using ancient autotools, for which the
 # --no-recursive option had not been invented.  Detect that lack and
 # omit the option when it's not supported.  FIXME in 2017: remove this
 # hack when RHEL 5 autotools are updated, or when they become irrelevant.
-no_recursive=
 case $($AUTORECONF --help) in
-  *--no-recursive*) no_recursive=--no-recursive;;
+  *--no-recursive*) AUTORECONFFLAGS="$AUTORECONFFLAGS --no-recursive";;
 esac
 
 # Tell autoreconf not to invoke autopoint or libtoolize; they were run above.
-echo "running: AUTOPOINT=true LIBTOOLIZE=true " \
-    "$AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS"
-AUTOPOINT=true LIBTOOLIZE=true \
-    $AUTORECONF --verbose --install $no_recursive -I $m4_base $ACLOCAL_FLAGS \
+echo "running: AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS"
+AUTOPOINT=true LIBTOOLIZE=true $AUTORECONF $AUTORECONFFLAGS \
   || die "autoreconf failed"
 
 # Get some extra files from gnulib, overriding existing files.
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -49,6 +49,7 @@
   link
   lstat
   malloc-gnu
+  mbrtowc
   mkdir
   mkfifo
   mkostemp
@@ -143,6 +144,15 @@
 gnulib_name="libgnu"
 source_base="libgnu"
 
+# Don't use git to update gnulib sources. We keep gnulib under a
+# Mercurial subrepository instead.
+use_git=false
+GNULIB_SRCDIR=gnulib-hg
+
+# Don't check for translations since we don't have any in Octave yet.
+# This avoids the need for sha1sum or compatible utility in bootstrap.
+SKIP_PO=true
+
 ## Use --foreign since we auto-generate the AUTHORS file and the default
 ## --gnu strictness level doesn't like it if the AUTHORS file is missing.
 
deleted file mode 100755
--- a/build-aux/mkinstalldirs
+++ /dev/null
@@ -1,162 +0,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-
-scriptversion=2009-04-28.21; # UTC
-
-# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain.
-#
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-nl='
-'
-IFS=" ""	$nl"
-errstatus=0
-dirmode=
-
-usage="\
-Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
-
-Create each directory DIR (with mode MODE, if specified), including all
-leading file name components.
-
-Report bugs to <bug-automake@gnu.org>."
-
-# process command line arguments
-while test $# -gt 0 ; do
-  case $1 in
-    -h | --help | --h*)         # -h for help
-      echo "$usage"
-      exit $?
-      ;;
-    -m)                         # -m PERM arg
-      shift
-      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
-      dirmode=$1
-      shift
-      ;;
-    --version)
-      echo "$0 $scriptversion"
-      exit $?
-      ;;
-    --)                         # stop option processing
-      shift
-      break
-      ;;
-    -*)                         # unknown option
-      echo "$usage" 1>&2
-      exit 1
-      ;;
-    *)                          # first non-opt arg
-      break
-      ;;
-  esac
-done
-
-for file
-do
-  if test -d "$file"; then
-    shift
-  else
-    break
-  fi
-done
-
-case $# in
-  0) exit 0 ;;
-esac
-
-# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
-# mkdir -p a/c at the same time, both will detect that a is missing,
-# one will create a, then the other will try to create a and die with
-# a "File exists" error.  This is a problem when calling mkinstalldirs
-# from a parallel make.  We use --version in the probe to restrict
-# ourselves to GNU mkdir, which is thread-safe.
-case $dirmode in
-  '')
-    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
-      echo "mkdir -p -- $*"
-      exec mkdir -p -- "$@"
-    else
-      # On NextStep and OpenStep, the `mkdir' command does not
-      # recognize any option.  It will interpret all options as
-      # directories to create, and then abort because `.' already
-      # exists.
-      test -d ./-p && rmdir ./-p
-      test -d ./--version && rmdir ./--version
-    fi
-    ;;
-  *)
-    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
-       test ! -d ./--version; then
-      echo "mkdir -m $dirmode -p -- $*"
-      exec mkdir -m "$dirmode" -p -- "$@"
-    else
-      # Clean up after NextStep and OpenStep mkdir.
-      for d in ./-m ./-p ./--version "./$dirmode";
-      do
-        test -d $d && rmdir $d
-      done
-    fi
-    ;;
-esac
-
-for file
-do
-  case $file in
-    /*) pathcomp=/ ;;
-    *)  pathcomp= ;;
-  esac
-  oIFS=$IFS
-  IFS=/
-  set fnord $file
-  shift
-  IFS=$oIFS
-
-  for d
-  do
-    test "x$d" = x && continue
-
-    pathcomp=$pathcomp$d
-    case $pathcomp in
-      -*) pathcomp=./$pathcomp ;;
-    esac
-
-    if test ! -d "$pathcomp"; then
-      echo "mkdir $pathcomp"
-
-      mkdir "$pathcomp" || lasterr=$?
-
-      if test ! -d "$pathcomp"; then
-	errstatus=$lasterr
-      else
-	if test ! -z "$dirmode"; then
-	  echo "chmod $dirmode $pathcomp"
-	  lasterr=
-	  chmod "$dirmode" "$pathcomp" || lasterr=$?
-
-	  if test ! -z "$lasterr"; then
-	    errstatus=$lasterr
-	  fi
-	fi
-      fi
-    fi
-
-    pathcomp=$pathcomp/
-  done
-done
-
-exit $errstatus
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC"
-# time-stamp-end: "; # UTC"
-# End:
--- a/configure.ac
+++ b/configure.ac
@@ -19,13 +19,13 @@
 ### <http://www.gnu.org/licenses/>.
 
 AC_PREREQ([2.62])
-AC_INIT([GNU Octave], [3.7.5], [http://octave.org/bugs.html], [octave])
+AC_INIT([GNU Octave], [3.7.6+], [http://octave.org/bugs.html], [octave])
 
 dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg
 OCTAVE_VERSION="$PACKAGE_VERSION"
 OCTAVE_API_VERSION_NUMBER="48"
 OCTAVE_API_VERSION="api-v$OCTAVE_API_VERSION_NUMBER+"
-OCTAVE_RELEASE_DATE="2013-05-14"
+OCTAVE_RELEASE_DATE="2013-08-20"
 OCTAVE_COPYRIGHT="Copyright (C) 2013 John W. Eaton and others."
 AC_SUBST(OCTAVE_VERSION)
 AC_SUBST(OCTAVE_API_VERSION_NUMBER)
@@ -41,7 +41,11 @@
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
 
-AM_INIT_AUTOMAKE([1.11 tar-ustar])
+AM_INIT_AUTOMAKE([1.11 tar-ustar subdir-objects])
+
+## Add the option to enable silent rules, available since Automake 1.11
+## and included by default starting with Automake 1.13.
+AM_SILENT_RULES
 
 OCTAVE_CANONICAL_HOST
 
@@ -712,7 +716,7 @@
   AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if ZLIB is available.])
 fi
 
-### Check for the LLVM library
+ ### Check for the LLVM library
 
 build_jit=no
 AC_ARG_ENABLE([jit],
@@ -742,6 +746,7 @@
 
     save_CPPFLAGS="$CPPFLAGS"
     save_CXXFLAGS="$CXXFLAGS"
+    save_LDFLAGS="$LDFLAGS"
 
     ## Use -isystem if available because we don't want to see warnings in LLVM
     LLVM_INCLUDE_FLAG=-I
@@ -753,7 +758,11 @@
     LLVM_CPPFLAGS="$LLVM_INCLUDE_FLAG `$LLVM_CONFIG --includedir`"
     LLVM_CXXFLAGS=
     LLVM_LDFLAGS="-L`$LLVM_CONFIG --libdir`"
-    LLVM_LIBS=`$LLVM_CONFIG --libs`
+
+
+    LDFLAGS="$LDFLAGS $LLVM_LDFLAGS"
+    LLVM_SO=LLVM-`$LLVM_CONFIG --version`
+    AC_CHECK_LIB([$LLVM_SO], [LLVMBuildAdd], [LLVM_LIBS="-l$LLVM_SO"], [LLVM_LIBS=`$LLVM_CONFIG --libs`])
 
     dnl
     dnl Define some extra flags that LLVM requires in order to include headers.
@@ -766,14 +775,33 @@
     AC_CHECK_HEADER([llvm/Support/TargetSelect.h], [
       warn_llvm=
       XTRA_CXXFLAGS="$XTRA_CXXFLAGS $LLVM_CXXFLAGS $LLVM_CPPFLAGS"])
-    OCTAVE_LLVM_IRBUILDER_HEADER
-    OCTAVE_LLVM_DATALAYOUT_HEADER
+
+    have_function_h=no
+    AC_CHECK_HEADERS([llvm/IR/Function.h llvm/Function.h],
+                     [have_function_h=yes; break])
+    if test $have_function_h = no; then
+      warn_llvm="Missing LLVM file Function.h.  JIT compiler is disabled."
+    fi
+    have_irbuilder_h=no
+    AC_CHECK_HEADERS([llvm/Support/IRBuilder.h llvm/IR/IRBuilder.h \
+                      llvm/IRBuilder.h], [have_irbuilder_h=yes; break])
+    if test $have_irbuilder_h = no; then
+      warn_llvm="Missing LLVM file IRBuilder.h.  JIT compiler is disabled."
+    fi
+    have_llvm_data_h=no
+    AC_CHECK_HEADERS([llvm/Target/TargetData.h llvm/IR/DataLayout.h \
+                      llvm/DataLayout.h], [have_llvm_data_h=yes; break])
+    if test $have_llvm_data_h = no; then
+      warn_llvm="Missing LLVM file TargetData.h.  JIT compiler is disabled."
+    fi
+
     OCTAVE_LLVM_FUNCTION_ADDATTRIBUTE_API
     OCTAVE_LLVM_FUNCTION_ADDFNATTR_API
     OCTAVE_LLVM_CALLINST_ADDATTRIBUTE_API
     AC_LANG_POP(C++)
     CPPFLAGS="$save_CPPFLAGS"
     CXXFLAGS="$save_CXXFLAGS"
+    LDFLAGS="$save_LDFLAGS"
   fi
 
   if test -z "$warn_llvm"; then
@@ -868,7 +896,12 @@
 LIBS="$Z_LDFLAGS $Z_LIBS $LIBS"
 OCTAVE_CHECK_LIB(glpk, GLPK,
   [GLPK library not found.  The glpk function for solving linear programs will be disabled.],
-  [glpk/glpk.h glpk.h], [_glp_lpx_simplex])
+  [glpk/glpk.h glpk.h], [glp_simplex], [], [],
+  [warn_glpk=
+   OCTAVE_CHECK_LIB_GLPK_OK(
+    [TEXINFO_GLPK="@set HAVE_GLPK"
+    AC_DEFINE(HAVE_GLPK, 1, [Define to 1 if GLPK is available.])],
+    [warn_glpk="GLPK library found, but does not seem to work properly -- disabling glpk function"])])
 LIBS="$save_LIBS"
 CPPFLAGS="$save_CPPFLAGS"
 
@@ -1046,6 +1079,10 @@
       AC_MSG_RESULT(yes)
       AC_DEFINE(HAVE_FREETYPE, 1, [Define to 1 if you have Freetype library.])
       XTRA_CXXFLAGS="$XTRA_CXXFLAGS $FT2_CFLAGS"
+      save_LIBS="$LIBS"
+      LIBS="$FT2_LIBS $LIBS"
+      AC_CHECK_FUNCS([FT_Reference_Face])
+      LIBS="$save_LIBS"
     else
       AC_MSG_RESULT(no)
       warn_freetype="FreeType library not found.  Native graphics will be disabled."
@@ -1933,7 +1970,7 @@
 AC_CHECK_HEADERS([curses.h direct.h dlfcn.h floatingpoint.h fpu_control.h])
 AC_CHECK_HEADERS([grp.h ieeefp.h inttypes.h locale.h memory.h ncurses.h])
 AC_CHECK_HEADERS([poll.h pthread.h pwd.h sunmath.h sys/ioctl.h])
-AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/resource.h ])
+AC_CHECK_HEADERS([sys/param.h sys/poll.h sys/resource.h])
 AC_CHECK_HEADERS([sys/select.h sys/utsname.h termcap.h])
 
 ## C++ headers
--- a/doc/doxyhtml/Doxyfile.in
+++ b/doc/doxyhtml/Doxyfile.in
@@ -184,13 +184,10 @@
 
 ENABLE_PREPROCESSING   = YES
 
-# Expand the DEFUN family of macros
+# Expand all macros
 
 MACRO_EXPANSION = YES
-EXPAND_ONLY_PREDEF = YES
-EXPAND_AS_DEFINED = DEFUN DEFUN_DLD  # As defined in the Octave source
-                                     # code, i.e. not overriden by this
-                                     # config file
+EXPAND_ONLY_PREDEF = NO
 
 # So that features that are behind #ifdef HAVE_FOO macros get processed by Doxygen
 
--- a/doc/interpreter/Makefile.am
+++ b/doc/interpreter/Makefile.am
@@ -30,7 +30,7 @@
 TEXMFCNF := "..$(PATH_SEPARATOR)$(srcdir)/..$(PATH_SEPARATOR)$(TEXMFCNF)$(PATH_SEPARATOR)"
 export TEXMFCNF
 
-dist_man1_MANS = \
+dist_man_MANS = \
   mkoctfile.1 \
   octave-config.1 \
   octave.1
@@ -225,19 +225,19 @@
 		cp $(srcdir)/contributors.texi contributors.texi; \
 		touch -r $(srcdir)/contributors.texi contributors.texi; \
 	fi
-	-$(MAKEINFO) -D AUTHORSONLY \
+	-$(MAKEINFO) -D AUTHORSONLY -I $(srcdir) \
 	  --no-validate --no-headers --no-split --output AUTHORS $<
 	mv AUTHORS ../../AUTHORS
 
 ../../BUGS: bugs.texi
 	rm -f BUGS
-	-$(MAKEINFO) -D BUGSONLY \
+	-$(MAKEINFO) -D BUGSONLY -I $(srcdir) \
 	  --no-validate --no-headers --no-split --output BUGS $<
 	mv BUGS ../../BUGS
 
 ../../INSTALL.OCTAVE: install.texi
 	rm -f INSTALL
-	-$(MAKEINFO) -D INSTALLONLY \
+	-$(MAKEINFO) -D INSTALLONLY -I $(srcdir) \
 	  --no-validate --no-headers --no-split --output INSTALL $<
 	mv INSTALL ../../INSTALL.OCTAVE
 
--- a/doc/interpreter/arith.txi
+++ b/doc/interpreter/arith.txi
@@ -34,14 +34,14 @@
 
 @menu
 * Exponents and Logarithms::
-* Complex Arithmetic::          
-* Trigonometry::                
-* Sums and Products::           
-* Utility Functions::           
-* Special Functions::           
+* Complex Arithmetic::
+* Trigonometry::
+* Sums and Products::
+* Utility Functions::
+* Special Functions::
 * Rational Approximations::
 * Coordinate Transformations::
-* Mathematical Constants::      
+* Mathematical Constants::
 @end menu
 
 @node Exponents and Logarithms
--- a/doc/interpreter/basics.txi
+++ b/doc/interpreter/basics.txi
@@ -25,13 +25,13 @@
 from your shell.
 
 @menu
-* Invoking Octave from the Command Line::             
-* Quitting Octave::             
-* Getting Help::                
-* Command Line Editing::        
-* Errors::                      
-* Executable Octave Programs::  
-* Comments::                    
+* Invoking Octave from the Command Line::
+* Quitting Octave::
+* Getting Help::
+* Command Line Editing::
+* Errors::
+* Executable Octave Programs::
+* Comments::
 @end menu
 
 @node Invoking Octave from the Command Line
@@ -52,8 +52,8 @@
 shorter equivalent).
 
 @menu
-* Command Line Options::        
-* Startup Files::               
+* Command Line Options::
+* Startup Files::
 @end menu
 
 @node Command Line Options
@@ -484,14 +484,14 @@
 
 
 @menu
-* Cursor Motion::               
-* Killing and Yanking::         
-* Commands For Text::           
-* Commands For Completion::     
-* Commands For History::        
-* Customizing readline::        
-* Customizing the Prompt::      
-* Diary and Echo Commands::     
+* Cursor Motion::
+* Killing and Yanking::
+* Commands For Text::
+* Commands For Completion::
+* Commands For History::
+* Customizing readline::
+* Customizing the Prompt::
+* Diary and Echo Commands::
 @end menu
 
 @node Cursor Motion
@@ -530,7 +530,7 @@
 @item C-l
 Clear the screen, reprinting the current line at the top.
 
-@item C-_
+@item  C-_
 @itemx C-/
 Undo the last action.  You can undo all the way back to an empty line.
 
@@ -610,7 +610,7 @@
 for quickly correcting typing mistakes.
 
 @table @kbd
-@item C-q
+@item  C-q
 @itemx C-v
 Add the next character that you type to the line verbatim.  This is
 how to insert things like @kbd{C-q} for example.
@@ -678,7 +678,7 @@
 list.
 
 @table @kbd
-@item @key{LFD}
+@item  @key{LFD}
 @itemx @key{RET}
 Accept the current line regardless of where the cursor is.  If the line is
 non-empty, add it to the history list.  If the line was a history
@@ -1047,7 +1047,7 @@
 @menu
 * Single Line Comments::
 * Block Comments::
-* Comments and the Help System::                    
+* Comments and the Help System::
 @end menu
 
 @node Single Line Comments
@@ -1099,8 +1099,8 @@
 @end example
 
 @noindent
-will produce a very quick countdown from '3' to 'Blast Off' as the
-lines "@code{disp (2);}" and "@code{disp (1);}" won't be executed.
+will produce a very quick countdown from @qcode{'3'} to @qcode{"Blast Off"} as
+the lines "@code{disp (2);}" and "@code{disp (1);}" won't be executed.
 
 The block comment markers must appear alone as the only characters on a line
 (excepting whitespace) in order to be parsed correctly.
--- a/doc/interpreter/bugs.txi
+++ b/doc/interpreter/bugs.txi
@@ -52,8 +52,8 @@
 
 @menu
 * Actual Bugs::                 Bugs we will fix later.
-* Reporting Bugs::              
-* Service::                     
+* Reporting Bugs::
+* Service::
 @end menu
 
 @node Actual Bugs
@@ -105,7 +105,7 @@
 information that makes it possible to fix the bug.
 
 @menu
-* Bug Criteria::                
+* Bug Criteria::
 * Bug Tracker::        Where to submit your bug report.
 * Bug Reporting::      How to report a bug effectively.
 * Sending Patches::    How to send a patch for Octave.
--- a/doc/interpreter/container.txi
+++ b/doc/interpreter/container.txi
@@ -372,9 +372,9 @@
 @subsection Creating Structures
 @cindex dynamic naming
 
-Besides the index operator ".", Octave can use dynamic naming "(var)" or the
-@code{struct} function to create structures.  Dynamic naming uses the string
-value of a variable as the field name.  For example:
+Besides the index operator @qcode{"."}, Octave can use dynamic naming
+@qcode{"(var)"} or the @code{struct} function to create structures.  Dynamic
+naming uses the string value of a variable as the field name.  For example:
 
 @example
 @group
@@ -484,12 +484,12 @@
      @result{} ans =
         @{
           field1 =
-        
+
         @{
           [1,1] =  1
           [1,2] = one
         @}
-        
+
           field2 =  2
         @}
 @end group
@@ -587,7 +587,7 @@
 c@{1:2@}
      @result{} ans = a string
      @result{} ans =
-          
+
                0.593993   0.627732
                0.377037   0.033643
 @end group
@@ -601,14 +601,14 @@
 @group
 c@{3@} = 3
      @result{} c =
-         
+
          @{
            [1,1] = a string
            [1,2] =
-         
+
               0.593993   0.627732
               0.377037   0.033643
-         
+
            [1,3] =  3
          @}
 @end group
@@ -640,7 +640,7 @@
 @DOCSTRING(iscell)
 
 @node Creating Cell Arrays
-@subsection Creating Cell Array
+@subsection Creating Cell Arrays
 
 The introductory example (@pxref{Basic Usage of Cell Arrays}) showed
 how to create a cell array containing currently available variables.
@@ -656,7 +656,7 @@
 @group
 c = cell (2,2)
      @result{} c =
-         
+
          @{
            [1,1] = [](0x0)
            [2,1] = [](0x0)
--- a/doc/interpreter/contributors.in
+++ b/doc/interpreter/contributors.in
@@ -42,9 +42,9 @@
 Michael Creel
 Jeff Cunningham
 Martin Dalecki
+Jacob Dawid
 Jorge Barros de Abreu
 Carlo de Falco
-Jacob Dawid
 Thomas D. Dean
 Philippe Defert
 Bill Denney
@@ -75,6 +75,7 @@
 Klaus Gebhardt
 Driss Ghaddab
 Nicolo Giorgetti
+Arun Giridhar
 Michael D. Godfrey
 Michael Goffioul
 Glenn Golden
@@ -160,21 +161,21 @@
 Massimo Lorenzin
 Emil Lucretiu
 Hoxide Ma
+Colin Macdonald
 James Macnicol
 Jens-Uwe Mager
-Colin Macdonald
 Rob Mahurin
+Alexander Mamonov
 Ricardo Marranita
 Orestes Mas
 Axel Mathéi
 Makoto Matsumoto
 Tatsuro Matsuoka
+Christoph Mayer
 Laurent Mazet
 G. D. McBain
-Alexander Mamonov
-Christoph Mayer
+Ronald van der Meer
 Júlio Hoffimann Mendes
-Ronald van der Meer
 Thorsten Meyer
 Petr Mikulik
 Mike Miller
@@ -228,6 +229,7 @@
 E. Joshua Rigler
 Petter Risholm
 Matthew W. Roberts
+Peter Rosin
 Andrew Ross
 Fabio Rossi
 Mark van Rossum
@@ -273,23 +275,24 @@
 John Swensen
 Daisuke Takago
 Ariel Tankus
+Falk Tannhäuser
+Duncan Temple Lang
 Matthew Tenny
+Kris Thielemans
 Georg Thimm
-Duncan Temple Lang
-Kris Thielemans
 Olaf Till
 Christophe Tournery
 Thomas Treichl
 Karsten Trulsen
 Frederick Umminger
 Utkarsh Upadhyay
-Daniel Wagenaar
 Stefan van der Walt
 Peter Van Wieren
 James R. Van Zandt
 Risto Vanhanen
 Gregory Vanuxem
 Ivana Varekova
+Daniel Wagenaar
 Thomas Walter
 Andreas Weber
 Olaf Weber
--- a/doc/interpreter/data.txi
+++ b/doc/interpreter/data.txi
@@ -35,9 +35,9 @@
 @DOCSTRING(typeinfo)
 
 @menu
-* Built-in Data Types::         
-* User-defined Data Types::     
-* Object Sizes::                
+* Built-in Data Types::
+* User-defined Data Types::
+* Object Sizes::
 @end menu
 
 @node Built-in Data Types
@@ -70,11 +70,11 @@
 @DOCSTRING(bitunpack)
 
 @menu
-* Numeric Objects::             
-* Missing Data::                
-* String Objects::              
-* Data Structure Objects::      
-* Cell Array Objects::          
+* Numeric Objects::
+* Missing Data::
+* String Objects::
+* Data Structure Objects::
+* Cell Array Objects::
 @end menu
 
 @node Numeric Objects
--- a/doc/interpreter/diagperm.txi
+++ b/doc/interpreter/diagperm.txi
@@ -16,19 +16,19 @@
 @c along with Octave; see the file COPYING.  If not, see
 @c <http://www.gnu.org/licenses/>.
 
-@node Diagonal and Permutation Matrices 
+@node Diagonal and Permutation Matrices
 @chapter Diagonal and Permutation Matrices
 
 @menu
-* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
-* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Basic Usage::          Creation and Manipulation of Diagonal/Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal/Permutation Matrices
 * Function Support::     Functions That Are Aware of These Matrices
-* Example Code::         Some Examples of Usage
-* Zeros Treatment::      The Differences in Treatment of Zero Elements
+* Example Code::         Examples of Usage
+* Zeros Treatment::      Differences in Treatment of Zero Elements
 @end menu
 
 @node Basic Usage
-@section Creating and Manipulating Diagonal and Permutation Matrices
+@section Creating and Manipulating Diagonal/Permutation Matrices
 
 A diagonal matrix is defined as a matrix that has zero entries outside the main
 diagonal; that is, 
@@ -210,7 +210,7 @@
 be very cheap.
 
 @node Matrix Algebra
-@section Linear Algebra with Diagonal and Permutation Matrices
+@section Linear Algebra with Diagonal/Permutation Matrices
 
 As has been already said, diagonal and permutation matrices make it
 possible to use efficient algorithms while preserving natural linear
@@ -413,7 +413,7 @@
 making it possible to conveniently obtain the permutation indices.
 
 @node Example Code
-@section Some Examples of Usage
+@section Examples of Usage
 
 The following can be used to solve a linear system @code{A*x = b}
 using the pivoted LU@tie{}factorization:
@@ -476,7 +476,7 @@
 
 
 @node Zeros Treatment
-@section The Differences in Treatment of Zero Elements
+@section Differences in Treatment of Zero Elements
 
 Making diagonal and permutation matrices special matrix objects in their own
 right and the consequent usage of smarter algorithms for certain operations
--- a/doc/interpreter/diffeq.txi
+++ b/doc/interpreter/diffeq.txi
@@ -24,8 +24,8 @@
 All solvers are based on reliable ODE routines written in Fortran.
 
 @menu
-* Ordinary Differential Equations::  
-* Differential-Algebraic Equations::  
+* Ordinary Differential Equations::
+* Differential-Algebraic Equations::
 @end menu
 
 @cindex differential equations
--- a/doc/interpreter/doccheck/aspell-octave.en.pws
+++ b/doc/interpreter/doccheck/aspell-octave.en.pws
@@ -137,6 +137,7 @@
 CLI
 clim
 cloglog
+closerequestfcn
 clubsuit
 CMatrix
 cmd
@@ -151,6 +152,7 @@
 colormap
 colormaps
 ColorOrder
+colororder
 colperm
 Comint
 Commandline
@@ -184,6 +186,7 @@
 cumsum
 cURL
 CurrentObject
+currentpoint
 Cuthill
 cxsparse
 Cygwin
@@ -240,6 +243,7 @@
 dx
 dy
 EastOutside
+edgecolor
 EIDORS
 eigenpairs
 eigenvector
@@ -275,6 +279,7 @@
 errorbars
 errordlg
 ErrorHandler
+ESC
 Esmond
 et
 etree
@@ -330,12 +335,15 @@
 Frobenius
 Fs
 FSF
+fullpath
+fullpathext
 FunValCheck
 gamcdf
 gaminv
 gampdf
 gamrnd
 Gautschi
+gca
 gcbo
 GCC
 gcd
@@ -387,6 +395,7 @@
 Hackbusch
 Hadamard
 Haddad
+HandleVisibility
 Hankel
 Hanning
 hardcode
@@ -427,6 +436,7 @@
 Hypergeometric
 hypergeometric
 IEC
+ieee
 IEEE
 ifelse
 ifft
@@ -481,8 +491,10 @@
 JVM's
 Kac
 Kahan
+kendall
 keybindings
 keypress
+keypressfcn
 Kolmogorov
 kolmogorov
 Konrod
@@ -527,6 +539,8 @@
 linesearch
 linespec
 linespoints
+linestyle
+linewidth
 linkprop
 listdlg
 ListSize
@@ -570,6 +584,10 @@
 Mandriva
 MANOVA
 manova
+markeredgecolor
+markerfacecolor
+markersize
+markerstyle
 Marsaglia
 Maschhoff
 matchcase
@@ -583,6 +601,7 @@
 McNemar's
 meansq
 Mendelsohn
+menubars
 Mersenne
 meshgrid
 meshgridded
@@ -648,6 +667,7 @@
 Neudecker
 Neumann
 NeXT
+NextPlot
 nfev
 nfft
 Ng
@@ -698,13 +718,16 @@
 overridable
 paperorientation
 paperposition
+PaperPosition
 papersize
 paperunits
+PaperUnits
 parseparams
 Parter
 pbm
 PBM
 PBMplus
+pc
 pcg
 PCG
 pchip
@@ -715,6 +738,7 @@
 pcx
 pdf
 PDF
+pearson
 pentadiagonal
 periodogram
 perp
@@ -738,6 +762,7 @@
 polyeig
 polyfit
 polyval
+pos
 POSIX
 postorder
 PostScript
@@ -807,6 +832,7 @@
 ren
 renderer
 repelems
+replacechildren
 repmat
 resampled
 resampling
@@ -942,6 +968,7 @@
 subsref
 substring
 substrings
+subwindows
 SuiteSparse
 sumsq
 SunOS
@@ -989,6 +1016,7 @@
 TolX
 toolkits
 Toolkits
+toplevel
 tp
 tpdf
 traceback
@@ -997,8 +1025,11 @@
 treelayout
 treeplot
 tridiagonal
+trimesh
 triplot
 trnd
+truecolor
+TrueColor
 Tsang
 Tukey
 tuples
@@ -1035,6 +1066,8 @@
 Uninstall
 uninstalled
 univariate
+unix
+unnorm
 unnormalized
 unpadded
 unpermuted
@@ -1073,6 +1106,7 @@
 warndlg
 Wathen
 WAV
+WayPoints
 wblcdf
 wblinv
 wblpdf
@@ -1093,9 +1127,13 @@
 Wildcards
 wildcards
 Wilks
+windowbuttondownfcn
+windowbuttonmotionfcn
+windowbuttonupfcn
 windowstyle
 WinRand
 WIPO
+wireframe
 wp
 wspace
 xb
--- a/doc/interpreter/emacs.txi
+++ b/doc/interpreter/emacs.txi
@@ -44,10 +44,10 @@
 or suggestions on using EOS.
 
 @menu
-* Installing EOS::              
-* Using Octave Mode::           
-* Running Octave from Within Emacs::  
-* Using the Emacs Info Reader for Octave::  
+* Installing EOS::
+* Using Octave Mode::
+* Running Octave from Within Emacs::
+* Using the Emacs Info Reader for Octave::
 @end menu
 
 @node Installing EOS
@@ -251,7 +251,7 @@
 @samp{,} (@code{Info-index-next}) command of the Info reader.
 
 The variable @code{octave-help-files} is a list of files to search
-through and defaults to @code{'("octave")}.  If there is also an Octave
+through and defaults to @qcode{'("octave")}.  If there is also an Octave
 Local Guide with corresponding info file, say, @file{octave-LG}, you can
 have @code{octave-help} search both files by 
 @lisp
@@ -390,7 +390,7 @@
 
 This will start Octave in a special buffer the name of which is
 specified by the variable @code{inferior-octave-buffer} and defaults to
-@code{"*Inferior Octave*"}.  From within this buffer, you can
+@qcode{"*Inferior Octave*"}.  From within this buffer, you can
 interact with the inferior Octave process `as usual', i.e., by entering
 Octave commands at the prompt.  The buffer is in Inferior Octave mode,
 which is derived from the standard Comint mode, a major mode for
@@ -456,7 +456,7 @@
 The variable @code{inferior-octave-startup-args} can be used for
 specifying command lines arguments to be passed to Octave on startup
 as a list of strings.  For example, to suppress the startup message and
-use `traditional' mode, set this to @code{'("-q" "--traditional")}.
+use `traditional' mode, set this to @qcode{'("-q" "--traditional")}.
 You can also specify a startup file of Octave commands to be loaded on
 startup; note that these commands will not produce any visible output
 in the process buffer.  Which file to use is controlled by the variable
--- a/doc/interpreter/errors.txi
+++ b/doc/interpreter/errors.txi
@@ -185,8 +185,8 @@
 as will be shown in the next example.  To assign an ID to an error,
 simply call @code{error} with two string arguments, where the first
 is the identification string, and the second is the actual error.  Note
-that error IDs are in the format "NAMESPACE:ERROR-NAME".  The namespace
-"Octave" is used for Octave's own errors.  Any other string is available
+that error IDs are in the format @qcode{"NAMESPACE:ERROR-NAME"}.  The namespace
+@qcode{"Octave"} is used for Octave's own errors.  Any other string is available
 as a namespace for user's own errors.
 
 The next example counts indexing errors.  The errors are caught using the
@@ -330,9 +330,9 @@
 as will be described in the next section.  To assign an ID to a warning,
 simply call @code{warning} with two string arguments, where the first
 is the identification string, and the second is the actual warning.  Note
-that warning IDs are in the format "NAMESPACE:WARNING-NAME".  The namespace
-"Octave" is used for Octave's own warnings.  Any other string is available
-as a namespace for user's own warnings.
+that warning IDs are in the format @qcode{"NAMESPACE:WARNING-NAME"}.  The
+namespace @qcode{"Octave"} is used for Octave's own warnings.  Any other string
+is available as a namespace for user's own warnings.
 
 @DOCSTRING(warning)
 
@@ -348,7 +348,7 @@
 
 The @code{warning} function also allows you to control which warnings
 are actually printed to the screen.  If the @code{warning} function
-is called with a string argument that is either @code{"on"} or @code{"off"}
+is called with a string argument that is either @qcode{"on"} or @qcode{"off"}
 all warnings will be enabled or disabled.
 
 It is also possible to enable and disable individual warnings through
--- a/doc/interpreter/eval.txi
+++ b/doc/interpreter/eval.txi
@@ -135,7 +135,7 @@
 
 @noindent
 Here, @samp{caller} is the @code{create_data} function and @code{name1}
-is the string @code{"x"}, which evaluates simply as the value of @code{x}.
+is the string @qcode{"x"}, which evaluates simply as the value of @code{x}.
 
 You later want to load the values back from @code{mydata}
 in a different context:
--- a/doc/interpreter/expr.txi
+++ b/doc/interpreter/expr.txi
@@ -32,14 +32,14 @@
 combinations of these with various operators.
 
 @menu
-* Index Expressions::           
-* Calling Functions::           
-* Arithmetic Ops::              
-* Comparison Ops::              
-* Boolean Expressions::         
-* Assignment Ops::              
-* Increment Ops::               
-* Operator Precedence::         
+* Index Expressions::
+* Calling Functions::
+* Arithmetic Ops::
+* Comparison Ops::
+* Boolean Expressions::
+* Assignment Ops::
+* Increment Ops::
+* Operator Precedence::
 @end menu
 
 @node Index Expressions
@@ -385,8 +385,8 @@
 expressions.  See also @ref{Index Expressions}, and @ref{Assignment Ops}.
 
 @menu
-* Call by Value::               
-* Recursion::                   
+* Call by Value::
+* Recursion::
 @end menu
 
 @node Call by Value
@@ -433,7 +433,7 @@
 @noindent
 you should not think of the argument as being ``the variable
 @code{foo}.''  Instead, think of the argument as the string value,
-@code{"bar"}.
+@qcode{"bar"}.
 
 Even though Octave uses pass-by-value semantics for function arguments,
 values are not copied unnecessarily.  For example,
@@ -583,7 +583,7 @@
 Element-by-element left division.  Each element of @var{y} is divided
 by each corresponding element of @var{x}.
 
-@item @var{x} ^ @var{y}
+@item  @var{x} ^ @var{y}
 @itemx @var{x} ** @var{y}
 @opindex **
 @opindex ^
@@ -597,7 +597,7 @@
 
 The implementation of this operator needs to be improved.
 
-@item @var{x} .^ @var{y}
+@item  @var{x} .^ @var{y}
 @itemx @var{x} .** @var{y}
 @opindex .**
 @opindex .^
@@ -759,7 +759,7 @@
 @opindex >
 True if @var{x} is greater than @var{y}.
 
-@item @var{x} != @var{y}
+@item  @var{x} != @var{y}
 @itemx @var{x} ~= @var{y}
 @opindex !=
 @opindex ~=
@@ -823,8 +823,8 @@
 @cindex not operator
 
 @menu
-* Element-by-element Boolean Operators::  
-* Short-circuit Boolean Operators::  
+* Element-by-element Boolean Operators::
+* Short-circuit Boolean Operators::
 @end menu
 
 @node Element-by-element Boolean Operators
@@ -863,7 +863,7 @@
 Elements of the result are true if either of the corresponding elements
 of @var{boolean1} or @var{boolean2} is true.
 
-@item ! @var{boolean}
+@item  ! @var{boolean}
 @itemx ~ @var{boolean}
 @opindex ~
 @opindex !
@@ -1043,7 +1043,7 @@
 The @samp{=} sign is called an @dfn{assignment operator}.
 
 Assignments can store string values also.  For example, the following
-expression would store the value @code{"this food is good"} in the
+expression would store the value @qcode{"this food is good"} in the
 variable @code{message}:
 
 @example
--- a/doc/interpreter/external.txi
+++ b/doc/interpreter/external.txi
@@ -104,9 +104,9 @@
 bridge to hardware resources which often have device drivers written in C.
 
 @menu
-* Oct-Files::                   
-* Mex-Files::                   
-* Standalone Programs::         
+* Oct-Files::
+* Mex-Files::
+* Standalone Programs::
 @end menu
 
 @node Oct-Files
@@ -116,19 +116,19 @@
 @cindex oct
 
 @menu
-* Getting Started with Oct-Files::  
-* Matrices and Arrays in Oct-Files::  
-* Character Strings in Oct-Files::  
-* Cell Arrays in Oct-Files::    
-* Structures in Oct-Files::  
-* Sparse Matrices in Oct-Files::  
-* Accessing Global Variables in Oct-Files::  
-* Calling Octave Functions from Oct-Files::  
-* Calling External Code from Oct-Files::  
-* Allocating Local Memory in Oct-Files::  
-* Input Parameter Checking in Oct-Files::  
-* Exception and Error Handling in Oct-Files::  
-* Documentation and Test of Oct-Files::  
+* Getting Started with Oct-Files::
+* Matrices and Arrays in Oct-Files::
+* Character Strings in Oct-Files::
+* Cell Arrays in Oct-Files::
+* Structures in Oct-Files::
+* Sparse Matrices in Oct-Files::
+* Accessing Global Variables in Oct-Files::
+* Calling Octave Functions from Oct-Files::
+* Calling External Code from Oct-Files::
+* Allocating Local Memory in Oct-Files::
+* Input Parameter Checking in Oct-Files::
+* Exception and Error Handling in Oct-Files::
+* Documentation and Test of Oct-Files::
 @c * Application Programming Interface for Oct-Files::  
 @end menu
 
@@ -305,8 +305,8 @@
 a resemblance to functions that exist in the interpreter.  A selection of
 useful methods include
 
-@deftypefn  Method T& {operator ()} (octave_idx_type)
-@deftypefnx Method T& elem (octave_idx_type)
+@deftypefn  {Method} {T&} operator () (octave_idx_type)
+@deftypefnx {Method} {T&} elem (octave_idx_type)
 The @code{()} operator or @code{elem} method allow the values of the
 matrix or array to be read or set.  These can take a single argument,
 which is of type @code{octave_idx_type}, that is the index into the matrix or
@@ -319,30 +319,30 @@
 circumstances the user might prefer to access the data of the array or
 matrix directly through the @nospell{fortran_vec} method discussed below.
 
-@deftypefn Method octave_idx_type numel (void) const
+@deftypefn {Method} {} octave_idx_type numel (void) const
 The total number of elements in the matrix or array.
 @end deftypefn
 
-@deftypefn Method size_t byte_size (void) const
+@deftypefn {Method} {size_t} byte_size (void) const
 The number of bytes used to store the matrix or array.
 @end deftypefn
 
-@deftypefn Method dim_vector dims (void) const
+@deftypefn {Method} {dim_vector} dims (void) const
 The dimensions of the matrix or array in value of type dim_vector.
 @end deftypefn
 
-@deftypefn Method int ndims (void) const
+@deftypefn {Method} {int} ndims (void) const
 The number of dimensions of the matrix or array.  Matrices are 2-D,
 but arrays can be N-dimensional.
 @end deftypefn
 
-@deftypefn Method void resize (const dim_vector&)
+@deftypefn {Method} {void} resize (const dim_vector&)
 A method taking either an argument of type @code{dim_vector}, or in the
 case of a matrix two arguments of type @code{octave_idx_type} defining
 the number of rows and columns in the matrix.
 @end deftypefn
 
-@deftypefn Method T* fortran_vec (void)
+@deftypefn {Method} {T*} fortran_vec (void)
 This method returns a pointer to the underlying data of the matrix or
 array so that it can be manipulated directly, either within Octave or by
 an external library.
@@ -357,9 +357,7 @@
 @w{@code{DEFUN_DLD}} function is as follows
 
 @example
-@group
 @EXAMPLEFILE(addtwomatrices.cc)
-@end group
 @end example
 
 To avoid segmentation faults causing Octave to abort this function
@@ -484,9 +482,7 @@
 example is
 
 @example
-@group
 @EXAMPLEFILE(celldemo.cc)
-@end group
 @end example
 
 Note that cell arrays are used less often in standard oct-files and so
@@ -584,13 +580,13 @@
 more similar to Octave's @code{Matrix} class than its @code{NDArray} class.
 
 @menu
-* Array and Sparse Differences::  
-* Creating Sparse Matrices in Oct-Files::  
-* Using Sparse Matrices in Oct-Files::  
+* Array and Sparse Class Differences::
+* Creating Sparse Matrices in Oct-Files::
+* Using Sparse Matrices in Oct-Files::
 @end menu
 
-@node Array and Sparse Differences
-@subsubsection The Differences between the Array and Sparse Classes
+@node Array and Sparse Class Differences
+@subsubsection Array and Sparse Class Differences
 
 The number of elements in a sparse matrix is considered to be the number
 of non-zero elements rather than the product of the dimensions.  Therefore
@@ -616,7 +612,7 @@
 The use of @code{numel} should therefore be avoided useless it is known
 it won't overflow.
 
-Extreme care must be take with the elem method and the "()" operator,
+Extreme care must be take with the elem method and the @qcode{"()"} operator,
 which perform basically the same function.  The reason is that if a
 sparse object is non-const, then Octave will assume that a
 request for a zero element in a sparse matrix is in fact a request
@@ -1274,13 +1270,13 @@
 be written with the oct-file interface previously discussed.
 
 @menu
-* Getting Started with Mex-Files::  
-* Working with Matrices and Arrays in Mex-Files::  
-* Character Strings in Mex-Files::  
-* Cell Arrays with Mex-Files::  
-* Structures with Mex-Files::  
-* Sparse Matrices with Mex-Files::  
-* Calling Other Functions in Mex-Files::  
+* Getting Started with Mex-Files::
+* Working with Matrices and Arrays in Mex-Files::
+* Character Strings in Mex-Files::
+* Cell Arrays with Mex-Files::
+* Structures with Mex-Files::
+* Sparse Matrices with Mex-Files::
+* Calling Other Functions in Mex-Files::
 @c * Application Programming Interface for Mex-Files::  
 @end menu
 
@@ -1307,9 +1303,9 @@
 
 The first line @code{#include "mex.h"} makes available all of the definitions
 necessary for a mex-file.  One important difference between Octave and
-@sc{matlab} is that the header file @code{"matrix.h"} is implicitly included
-through the inclusion of @code{"mex.h"}.  This is necessary to avoid a conflict
-with the Octave file @code{"Matrix.h"} for operating systems and compilers that
+@sc{matlab} is that the header file @qcode{"matrix.h"} is implicitly included
+through the inclusion of @qcode{"mex.h"}.  This is necessary to avoid a conflict
+with the Octave file @qcode{"Matrix.h"} for operating systems and compilers that
 don't distinguish between filenames in upper and lower case.
 
 The entry point into the mex-file is defined by @code{mexFunction}.  The
@@ -1517,9 +1513,7 @@
 as shown below.
 
 @example
-@group
 @EXAMPLEFILE(mycell.c)
-@end group
 @end example
 
 @noindent
@@ -1617,23 +1611,23 @@
     b =
     @{
       this =
-    
+
       (,
         [1] = this1
         [2] = this2
         [3] = this3
         [4] = this4
       ,)
-    
+
       that =
-    
+
       (,
         [1] = that1
         [2] = that2
         [3] = that3
         [4] = that4
       ,)
-    
+
     @}
 @end example
 
@@ -1737,9 +1731,7 @@
 @file{liboctave.so}.
 
 @example
-@group
 @EXAMPLEFILE(standalone.cc)
-@end group
 @end example
 
 @noindent
@@ -1766,9 +1758,7 @@
 seen in the code
 
 @example
-@group
 @EXAMPLEFILE(embedded.cc)
-@end group
 @end example
 
 @noindent
--- a/doc/interpreter/func.txi
+++ b/doc/interpreter/func.txi
@@ -30,18 +30,18 @@
 
 @menu
 * Introduction to Function and Script Files::
-* Defining Functions::          
-* Multiple Return Values::      
-* Variable-length Argument Lists::  
-* Ignoring Arguments::  
-* Variable-length Return Lists::  
-* Returning from a Function::   
-* Default Arguments::   
-* Function Files::              
-* Script Files::                
-* Function Handles Inline Functions and Anonymous Functions::
+* Defining Functions::
+* Multiple Return Values::
+* Variable-length Argument Lists::
+* Ignoring Arguments::
+* Variable-length Return Lists::
+* Returning from a Function::
+* Default Arguments::
+* Function Files::
+* Script Files::
+* Function Handles Anonymous Functions Inline Functions::
 * Commands::
-* Organization of Functions::   
+* Organization of Functions::
 @end menu
 
 @node Introduction to Function and Script Files
@@ -114,7 +114,7 @@
 @end example
 
 The @code{printf} statement (@pxref{Input and Output}) simply tells
-Octave to print the string @code{"\a"}.  The special character @samp{\a}
+Octave to print the string @qcode{"\a"}.  The special character @samp{\a}
 stands for the alert character (ASCII 7).  @xref{Strings}.
 
 Once this function is defined, you can ask Octave to evaluate it by
@@ -737,7 +737,7 @@
 running Octave, you can improve performance by calling
 @code{ignore_function_time_stamp ("all")}, so that Octave will
 ignore the time stamps for all function files.  Passing
-@code{"system"} to this function resets the default behavior.
+@qcode{"system"} to this function resets the default behavior.
 
 @c FIXME -- note about time stamps on files in NFS environments?
 
@@ -1266,11 +1266,11 @@
 
 @DOCSTRING(source)
 
-@node Function Handles Inline Functions and Anonymous Functions
-@section Function Handles, Inline Functions, and Anonymous Functions
+@node Function Handles Anonymous Functions Inline Functions
+@section Function Handles, Anonymous Functions, Inline Functions
 @cindex handle, function handles
+@cindex anonymous functions
 @cindex inline, inline functions
-@cindex anonymous functions
 
 It can be very convenient store a function in a variable so that it
 can be passed to a different function.  For example, a function that
--- a/doc/interpreter/grammar.txi
+++ b/doc/interpreter/grammar.txi
@@ -25,8 +25,8 @@
 Octave's language.
 
 @menu
-* Keywords::                    
-* Parser::                    
+* Keywords::
+* Parser::
 @end menu
 
 @node Keywords
@@ -78,9 +78,9 @@
 @DOCSTRING(remove_input_event_hook)
 
 Finally, when the parser cannot identify an input token it calls a particular
-function to handle this.  By default, this is the function "unimplemented"
-which makes suggestions about possible Octave substitutes for @sc{matlab}
-functions.
+function to handle this.  By default, this is the function
+@qcode{"unimplemented"} which makes suggestions about possible Octave
+substitutes for @sc{matlab} functions.
 
 @DOCSTRING(missing_function_hook)
 
--- a/doc/interpreter/gui.txi
+++ b/doc/interpreter/gui.txi
@@ -36,10 +36,10 @@
 preferences.
 
 @menu
-* I/O Dialogs::       
-* Progress Bar::       
-* GUI Utility Functions::       
-* User-Defined Preferences::       
+* I/O Dialogs::
+* Progress Bar::
+* GUI Utility Functions::
+* User-Defined Preferences::
 @end menu
 
 @node I/O Dialogs
--- a/doc/interpreter/image.txi
+++ b/doc/interpreter/image.txi
@@ -204,7 +204,7 @@
 @DOCSTRING(gmap40)
 
 The following three functions modify the existing colormap rather than
-replace it.   
+replace it.
 
 @DOCSTRING(brighten)
 
--- a/doc/interpreter/install.txi
+++ b/doc/interpreter/install.txi
@@ -25,6 +25,7 @@
 @end ifclear
 
 @ifset INSTALLONLY
+@include macros.texi
 
 This file documents the installation of Octave.
 
@@ -179,7 +180,7 @@
 @table @asis
 @item BLAS
 Basic Linear Algebra Subroutine library
-(@url{http://www.netlib.org/blas}).  Accelerated BLAS libraries such as
+(@url{http://www.netlib.org/blas}).  Accelerated @sc{blas} libraries such as
 ATLAS (@url{http://math-atlas.sourceforge.net}) are recommeded for
 better performance.
 
@@ -205,7 +206,7 @@
 @table @asis
 @item ARPACK
 Library for the solution of large-scale eigenvalue problems
-(@url{http://forge.scilab.org/index.php/p/arpack-ng}).  ARPACK is
+(@url{http://forge.scilab.org/index.php/p/arpack-ng}).  @sc{arpack} is
 required to provide the functions @code{eigs} and @code{svds}.
 
 @item cURL
@@ -247,7 +248,7 @@
 
 @item HDF5
 Library for manipulating portable data files
-(@url{http://www.hdfgroup.org/HDF5}).  HDF5 is required for Octave's
+(@url{http://www.hdfgroup.org/HDF5}).  @sc{hdf5} is required for Octave's
 @code{load} and @code{save} commands to read and write HDF data files.
 
 @item LLVM
@@ -383,7 +384,7 @@
 
 @item --with-magick=<lib>
 Select the library to use for image I/O@.  The two possible values are
-"GraphicsMagick" (default) or "ImageMagick".
+@qcode{"GraphicsMagick"} (default) or @qcode{"ImageMagick"}.
 
 @item --with-sepchar=<char>
 Use <char> as the path separation character.  This option can help when
@@ -569,7 +570,7 @@
 @end table
 @end itemize
 
-@node Compiling Octave with 64-bit Indexing  
+@node Compiling Octave with 64-bit Indexing
 @section Compiling Octave with 64-bit Indexing
 
 Note: the following only applies to systems that have 64-bit pointers.
@@ -1064,7 +1065,7 @@
 @env{CFLAGS}, @env{CXXFLAGS}, @env{FFLAGS}, and @env{LDFLAGS}.  Passing
 them as options to the configure script also records them in the
 @file{config.status} file.  By default, @env{CPPFLAGS} and @env{LDFLAGS}
-are empty, @env{CFLAGS} and @env{CXXFLAGS} are set to @code{"-g -O"} and
-@env{FFLAGS} is set to @code{"-O"}.
+are empty, @env{CFLAGS} and @env{CXXFLAGS} are set to @qcode{"-g -O"} and
+@env{FFLAGS} is set to @qcode{"-O"}.
 
 @end itemize
--- a/doc/interpreter/interp.txi
+++ b/doc/interpreter/interp.txi
@@ -34,13 +34,13 @@
 @DOCSTRING(interp1)
 
 There are some important differences between the various interpolation
-methods.  The 'spline' method enforces that both the first and second
+methods.  The @qcode{"spline"} method enforces that both the first and second
 derivatives of the interpolated values have a continuous derivative,
 whereas the other methods do not.  This means that the results of the
-'spline' method are generally smoother.  If the function to be
-interpolated is in fact smooth, then 'spline' will give excellent
+@qcode{"spline"} method are generally smoother.  If the function to be
+interpolated is in fact smooth, then @qcode{"spline"} will give excellent
 results.  However, if the function to be evaluated is in some manner
-discontinuous, then 'pchip' interpolation might give better results.
+discontinuous, then @qcode{"pchip"} interpolation might give better results.
 
 This can be demonstrated by the code
 
@@ -51,16 +51,16 @@
 ti =-2:0.025:2;
 dti = 0.025;
 y = sign (t);
-ys = interp1 (t,y,ti,'spline');
-yp = interp1 (t,y,ti,'pchip');
+ys = interp1 (t,y,ti,"spline");
+yp = interp1 (t,y,ti,"pchip");
 ddys = diff (diff (ys)./dti) ./ dti;
 ddyp = diff (diff (yp)./dti) ./ dti;
 figure (1);
 plot (ti,ys,'r-', ti,yp,'g-');
-legend ('spline', 'pchip', 4);
+legend ("spline", "pchip", 4);
 figure (2);
 plot (ti,ddys,'r+', ti,ddyp,'g*');
-legend ('spline', 'pchip');
+legend ("spline", "pchip");
 @end group
 @end example
 
@@ -71,13 +71,13 @@
 
 @float Figure,fig:interpderiv1
 @center @image{interpderiv1,4in}
-@caption{Comparison of 'pchip' and 'spline' interpolation methods for a 
+@caption{Comparison of @qcode{"pchip"} and @qcode{"spline"} interpolation methods for a 
 step function}
 @end float
 
 @float Figure,fig:interpderiv2
 @center @image{interpderiv2,4in}
-@caption{Comparison of the second derivative of the 'pchip' and 'spline' 
+@caption{Comparison of the second derivative of the @qcode{"pchip"} and @qcode{"spline"} 
 interpolation methods for a step function}
 @end float
 @end ifnotinfo
@@ -107,9 +107,9 @@
 ti = t(1) + [0 : k-1]*dt*n/k;
 y = sin (4*t + 0.3) .* cos (3*t - 0.1);
 yp = sin (4*ti + 0.3) .* cos (3*ti - 0.1);
-plot (ti, yp, 'g', ti, interp1 (t, y, ti, 'spline'), 'b', ...
-      ti, interpft (y, k), 'c', t, y, 'r+');
-legend ('sin(4t+0.3)cos(3t-0.1', 'spline', 'interpft', 'data');
+plot (ti, yp, "g", ti, interp1 (t, y, ti, "spline"), "b", ...
+      ti, interpft (y, k), "c", t, y, 'r+');
+legend ('sin(4t+0.3)cos(3t-0.1', "spline", "interpft", "data");
 @end group
 @end example
 
@@ -148,12 +148,11 @@
 
 A significant difference between @code{interpn} and the other two
 multi-dimensional interpolation functions is the fashion in which the
-dimensions are treated.  For @code{interp2} and @code{interp3}, the 'y'
-axis is considered to be the columns of the matrix, whereas the 'x'
-axis corresponds to the rows of the array.  As Octave indexes arrays in
-column major order, the first dimension of any array is the columns, and
-so @code{interpn} effectively reverses the 'x' and 'y' dimensions. 
-Consider the example,
+dimensions are treated.  For @code{interp2} and @code{interp3}, the y-axis is
+considered to be the columns of the matrix, whereas the x-axis corresponds to
+the rows of the array.  As Octave indexes arrays in column major order, the
+first dimension of any array is the columns, and so @code{interpn} effectively
+reverses the 'x' and 'y' dimensions.  Consider the example,
 
 @example
 @group
@@ -163,9 +162,9 @@
 v = f (xx,yy,zz);
 xi = yi = zi = -1:0.1:1;
 [xxi, yyi, zzi] = meshgrid (xi, yi, zi);
-vi = interp3 (x, y, z, v, xxi, yyi, zzi, 'spline');
+vi = interp3 (x, y, z, v, xxi, yyi, zzi, "spline");
 [xxi, yyi, zzi] = ndgrid (xi, yi, zi);
-vi2 = interpn (x, y, z, v, xxi, yyi, zzi, 'spline');
+vi2 = interpn (x, y, z, v, xxi, yyi, zzi, "spline");
 mesh (zi, yi, squeeze (vi2(1,:,:)));
 @end group
 @end example
--- a/doc/interpreter/intro.txi
+++ b/doc/interpreter/intro.txi
@@ -38,9 +38,9 @@
 This document corresponds to Octave version @value{VERSION}.
 
 @menu
-* Running Octave::              
-* Simple Examples::             
-* Conventions::                 
+* Running Octave::
+* Simple Examples::
+* Conventions::
 @end menu
 
 @node Running Octave
@@ -419,11 +419,11 @@
 manual.  You may want to skip this section and refer back to it later.
 
 @menu
-* Fonts::                       
-* Evaluation Notation::         
-* Printing Notation::           
-* Error Messages::              
-* Format of Descriptions::      
+* Fonts::
+* Evaluation Notation::
+* Printing Notation::
+* Error Messages::
+* Format of Descriptions::
 @end menu
 
 @node Fonts
@@ -546,8 +546,8 @@
 The description follows on succeeding lines, sometimes with examples.
 
 @menu
-* A Sample Function Description::  
-* A Sample Command Description::  
+* A Sample Function Description::
+* A Sample Command Description::
 @end menu
 
 @node A Sample Function Description
--- a/doc/interpreter/io.txi
+++ b/doc/interpreter/io.txi
@@ -26,8 +26,8 @@
 after the C standard library are also provided by Octave.
 
 @menu
-* Basic Input and Output::      
-* C-Style I/O Functions::       
+* Basic Input and Output::
+* C-Style I/O Functions::
 @end menu
 
 @node Basic Input and Output
@@ -36,9 +36,9 @@
 @c We could use a two-line introduction here...
 
 @menu
-* Terminal Output::             
-* Terminal Input::              
-* Simple File I/O::             
+* Terminal Output::
+* Terminal Input::
+* Simple File I/O::
 @end menu
 
 @node Terminal Output
@@ -284,25 +284,25 @@
 @DOCSTRING(stderr)
 
 @menu
-* Opening and Closing Files::   
-* Simple Output::               
-* Line-Oriented Input::         
-* Formatted Output::            
-* Output Conversion for Matrices::  
-* Output Conversion Syntax::    
-* Table of Output Conversions::  
-* Integer Conversions::         
+* Opening and Closing Files::
+* Simple Output::
+* Line-Oriented Input::
+* Formatted Output::
+* Output Conversion for Matrices::
+* Output Conversion Syntax::
+* Table of Output Conversions::
+* Integer Conversions::
 * Floating-Point Conversions::
-* Other Output Conversions::    
-* Formatted Input::             
-* Input Conversion Syntax::     
-* Table of Input Conversions::  
-* Numeric Input Conversions::   
-* String Input Conversions::    
-* Binary I/O::                  
-* Temporary Files::             
-* EOF and Errors::              
-* File Positioning::            
+* Other Output Conversions::
+* Formatted Input::
+* Input Conversion Syntax::
+* Table of Input Conversions::
+* Numeric Input Conversions::
+* String Input Conversions::
+* Binary I/O::
+* Temporary Files::
+* EOF and Errors::
+* File Positioning::
 @end menu
 
 @node Opening and Closing Files
@@ -702,8 +702,8 @@
 followed by a digit.
 
 The following flags can be used to modify the behavior:
+@c Not @samp so we can have ' ' as an item.
 
-@c Not @samp so we can have ' ' as an item.
 @table @asis
 @item @samp{-}
 Left-justify the result in the field.  Normally the result is
@@ -977,9 +977,9 @@
 @end example
 
 @noindent
-with the conversion @samp{%10c} produces @code{" hello, wo"}, but
+with the conversion @samp{%10c} produces @qcode{" hello, wo"}, but
 reading the same input with the conversion @samp{%10s} produces
-@code{"hello,"}.
+@qcode{"hello,"}.
 
 @node Binary I/O
 @subsection Binary I/O
@@ -1008,7 +1008,7 @@
 
 @DOCSTRING(tmpnam)
 
-@node EOF and Errors, File Positioning, Temporary Files, C-Style I/O Functions
+@node EOF and Errors
 @subsection End of File and Errors
 
 Once a file has been opened its status can be acquired.  As an example
--- a/doc/interpreter/java.txi
+++ b/doc/interpreter/java.txi
@@ -145,7 +145,7 @@
 * How to make Java classes available?::
 * How to create an instance of a Java class?::
 * How can I handle memory limitations?::
-* Which @TeX{} symbols are implemented in the dialog functions?::
+* Which @TeX{} symbols are implemented in dialog functions?::
 @end menu
 
 @c ------------------------------------------------------------------------
@@ -234,7 +234,7 @@
 @item Finally, Octave looks for a next occurrence of file
 @file{javaclasspath.txt} in the m-files directory where Octave Java functions 
 live.  This is where @file{javaclasspath.m} resides, usually something like
-@file{@env{OCTAVE_HOME}/share/octave/@env{OCTAVE_VERSION}/m/java/}.  You can
+@file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}.  You can
 find this directory by executing the command
 
 @example
@@ -330,7 +330,7 @@
 The directory where the Java options file is located is specified by the
 environment variable @w{@env{OCTAVE_JAVA_DIR}}.  If unset the directory where
 @file{javaclasspath.m} resides is used instead (typically
-@file{@env{OCTAVE_HOME}/share/octave/@env{OCTAVE_VERSION}/m/java/}).  You can
+@file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}).  You can
 find this directory by executing
 
 @example
@@ -385,8 +385,8 @@
 @seealso{javamem}
 
 @c ------------------------------------------------------------------------
-@node Which @TeX{} symbols are implemented in the dialog functions?
-@subsection Which @TeX{} symbols are implemented in the dialog functions?
+@node Which @TeX{} symbols are implemented in dialog functions?
+@subsection Which @TeX{} symbols are implemented in dialog functions?
 @c - index -
 @cindex symbols, translation table
 @cindex @TeX{} symbols, translation table
--- a/doc/interpreter/linalg.txi
+++ b/doc/interpreter/linalg.txi
@@ -26,9 +26,9 @@
 
 @menu
 * Techniques Used for Linear Algebra::
-* Basic Matrix Functions::      
-* Matrix Factorizations::       
-* Functions of a Matrix::       
+* Basic Matrix Functions::
+* Matrix Factorizations::
+* Functions of a Matrix::
 * Specialized Solvers::
 @end menu
 
--- a/doc/interpreter/macros.texi
+++ b/doc/interpreter/macros.texi
@@ -16,12 +16,27 @@
 @c along with Octave; see the file COPYING.  If not, see
 @c <http://www.gnu.org/licenses/>.
 
-@c FIXME -- someday, we might replace this with @backslashchar, which
-@c has been added to Texinfo.
+@c The following macro marks words that aspell should ignore during
+@c spellchecking.  Within Texinfo it has no effect as it merely replaces
+@c the macro call with the argument itself.
+
+@macro nospell {arg}
+\arg\
+@end macro
 
-@macro xbackslashchar
-\\
+@c The following macro works around the Info/plain text expansion of @code{XXX}
+@c which is `XXX'.  This looks particularly bad when the macro body is 
+@c single or double-quoted text, such as a property value `"position"'
+@ifinfo
+@macro qcode{arg}
+\arg\
 @end macro
+@end ifinfo
+@ifnotinfo
+@macro qcode{arg}
+@code{\arg\}
+@end macro
+@end ifnotinfo
 
 @c The following macro is used for the on-line help system, but we don't
 @c want lots of `See also: foo, bar, and baz' strings cluttering the
@@ -30,7 +45,7 @@
 @c
 @c Implementation Note:
 @c For TeX, @vskip produces a nice separation.
-@c For Texinfo '@sp 1' should work, but in practice produces ugly results
+@c For Texinfo, '@sp 1' should work, but in practice produces ugly results
 @c for HTML.  We use a simple blank line to produce the correct behavior. 
 
 @macro seealso {args}
@@ -40,34 +55,34 @@
 @ifnottex
 
 @end ifnottex
-@ifinfo
-@noindent
-See also: \args\.
-@end ifinfo
 @ifnotinfo
 @noindent
 @strong{See also:} \args\.
 @end ifnotinfo
-@end macro
-
-@c The following macro marks words that aspell should ignore during
-@c spellchecking.  Within Texinfo it has no effect as it merely replaces
-@c the macro call with the argument itself.
-
-@macro nospell {arg}
-\arg\
+@ifinfo
+@noindent
+See also: \args\.
+@end ifinfo
 @end macro
 
 @c The following macro works around a situation where the Info/plain text
 @c expansion of the @code{XXX} macro is `XXX'.  The use of the apostrophe
 @c can be confusing if the code segment itself ends with a transpose operator.
 @ifinfo
-@macro xcode{arg}
+@macro tcode{arg}
 \arg\
 @end macro
 @end ifinfo
 @ifnotinfo
-@macro xcode{arg}
+@macro tcode{arg}
 @code{\arg\}
 @end macro
 @end ifnotinfo
+
+@c FIXME: someday, when Texinfo 5.X is standard, we might replace this with
+@c @backslashchar, which is a new addition to Texinfo.
+
+@macro xbackslashchar
+\\
+@end macro
+
--- a/doc/interpreter/matrix.txi
+++ b/doc/interpreter/matrix.txi
@@ -27,10 +27,10 @@
 lower-triangular parts, or sort the columns of a matrix.
 
 @menu
-* Finding Elements and Checking Conditions::  
-* Rearranging Matrices::        
-* Special Utility Matrices::    
-* Famous Matrices::             
+* Finding Elements and Checking Conditions::
+* Rearranging Matrices::
+* Special Utility Matrices::
+* Famous Matrices::
 @end menu
 
 @node Finding Elements and Checking Conditions
@@ -77,7 +77,7 @@
 @DOCSTRING(common_size)
 
 @DOCSTRING(find)
-        
+
 @DOCSTRING(lookup)
 
 If you wish to check if a variable exists at all, instead of properties
@@ -174,7 +174,7 @@
 
 The generators operate in the new or old style together, it is not
 possible to mix the two.  Initializing any generator with
-@code{"state"} or @code{"seed"} causes the others to switch to the
+@qcode{"state"} or @qcode{"seed"} causes the others to switch to the
 same style for future calls.
 
 The state of each generator is independent and calls to different
@@ -208,7 +208,7 @@
 
 @noindent
 produce equivalent results.  When the generators are initialized in
-the old style with @code{"seed"} only @code{rand} and @code{randn} are
+the old style with @qcode{"seed"} only @code{rand} and @code{randn} are
 independent, because the old @code{rande}, @code{randg} and
 @code{randp} generators make calls to @code{rand} and @code{randn}.
 
--- a/doc/interpreter/mk_doc_cache.m
+++ b/doc/interpreter/mk_doc_cache.m
@@ -24,7 +24,7 @@
 docstrings_files = args(2:end);
 
 ## Special character used as break between DOCSTRINGS
-doc_delim = char (31);
+doc_delim = char (0x1d);
 
 ## Read the contents of all the DOCSTRINGS files into TEXT.
 ## It is more efficient to fork to shell for makeinfo only once on large data
@@ -48,11 +48,23 @@
     endif
   endif
 endfor
-text = [text{:}, doc_delim];
+text = [text{:}];
+
+## Strip Texinfo marker
+text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", "");
 
-## Strip Texinfo markers and docstring separators.
-text = regexprep (text, "-\\*- texinfo -\\*-[ \t]*[\r\n]*", "");
-text = strrep (text, '@', "@@");
+## Add keywords and operators
+other_docstrings = [__keywords__; __operators__];
+for i = 1 : numel (other_docstrings)
+  name = other_docstrings{i};
+  ## Special handling of block comment operators such as '#{'
+  esc_name = regexprep (name, '([{}])', '@$1');
+  text = [text doc_delim esc_name get_help_text(name) "\n"];
+endfor
+text(end+1) = doc_delim;
+
+## Double '@' symbol for Texinfo
+text = strrep (text, [doc_delim "@"], [doc_delim "@@"]);
 
 ## Write data to temporary file for input to makeinfo
 [fid, name, msg] = mkstemp ("octave_doc_XXXXXX", true);
--- a/doc/interpreter/munge-texi.pl
+++ b/doc/interpreter/munge-texi.pl
@@ -6,7 +6,7 @@
 $top_srcdir = shift (@ARGV);
 
 # Constant patterns
-$doc_delim = qr/^\c_/;
+$doc_delim = qr/^\x{1d}/;
 $tex_delim = qr/\Q-*- texinfo -*-\E/;
 $comment_line = qr/^\s*(?:$|#)/;
 # Pre-declare hash size for efficiency
--- a/doc/interpreter/nonlin.txi
+++ b/doc/interpreter/nonlin.txi
@@ -23,7 +23,7 @@
 
 @menu
 * Solvers::
-* Minimizers::          
+* Minimizers::
 @end menu
 
 @node Solvers
--- a/doc/interpreter/numbers.txi
+++ b/doc/interpreter/numbers.txi
@@ -93,9 +93,9 @@
 * Single Precision Data Types::
 * Integer Data Types::
 * Bit Manipulations::
-* Logical Values:: 
+* Logical Values::
 * Promotion and Demotion of Data Types::
-* Predicates for Numeric Objects::  
+* Predicates for Numeric Objects::
 @end menu
 
 @node Matrices
@@ -304,7 +304,7 @@
 @DOCSTRING(fixed_point_format)
 
 @menu
-* Empty Matrices::              
+* Empty Matrices::
 @end menu
 
 @node Empty Matrices
@@ -546,6 +546,8 @@
 
 @DOCSTRING(intmin)
 
+@DOCSTRING(flintmax)
+
 @menu
 * Integer Arithmetic::
 @end menu
@@ -614,13 +616,12 @@
 for bit manipulation, particularly when forming masks, Octave supplies
 the function @code{bitmax}.
 
-@anchor{XREFflintmax}
 @DOCSTRING(bitmax)
 
 This is the double precision version of the function @code{intmax},
 previously discussed.
 
-Octave also includes the basic bitwise 'and', 'or' and 'exclusive or'
+Octave also includes the basic bitwise 'and', 'or', and 'exclusive or'
 operators.
 
 @DOCSTRING(bitand)
--- a/doc/interpreter/octave.texi
+++ b/doc/interpreter/octave.texi
@@ -17,6 +17,7 @@
 % <http://www.gnu.org/licenses/>.
 
 \input texinfo
+
 @setfilename octave.info
 
 @include macros.texi
@@ -30,10 +31,14 @@
 @end format
 @end ifinfo
 
-@c Settings for printing on 8-1/2 by 11 inch paper:
-@c -----------------------------------------------
+@c Settings for printing on 8-1/2 by 11 inch paper (default):
+@c --------------------------------------------------------
 
 @setchapternewpage odd
+@c Fix TOC margins for printed manual
+@tex
+{\globaldefs = 1 \contentsrightmargin = 0pt}
+@end tex
 
 @c Settings for small book format:
 @c ------------------------------
@@ -101,6 +106,7 @@
 @author John W. Eaton
 @author David Bateman
 @author S@o{}ren Hauberg
+@author Rik Wehbring
 @page
 @vskip 0pt plus 1filll
 Copyright @copyright{} 1996, 1997, 1999, 2000, 2001, 2002, 2005, 2006,
@@ -141,54 +147,54 @@
 @c ------------------------------------------------------------------------
 
 @menu
-* Preface::                     
+* Preface::
 * Introduction::                A brief introduction to Octave.
-* Getting Started::             
-* Data Types::                  
-* Numeric Data Types::          
-* Strings::                     
-* Data Containers::             
-* Variables::                   
-* Expressions::                 
-* Evaluation::                  
+* Getting Started::
+* Data Types::
+* Numeric Data Types::
+* Strings::
+* Data Containers::
+* Variables::
+* Expressions::
+* Evaluation::
 * Statements::                  Looping and program flow control.
-* Functions and Scripts::       
-* Errors and Warnings::              
+* Functions and Scripts::
+* Errors and Warnings::
 * Debugging::
-* Input and Output::            
-* Plotting::                    
-* Matrix Manipulation::         
-* Arithmetic::                  
+* Input and Output::
+* Plotting::
+* Matrix Manipulation::
+* Arithmetic::
 * Linear Algebra::
 * Vectorization and Faster Code Execution::
 * Nonlinear Equations::
 * Diagonal and Permutation Matrices::
 * Sparse Matrices::
-* Numerical Integration::                  
-* Differential Equations::      
-* Optimization::                
-* Statistics::                  
-* Sets::                        
-* Polynomial Manipulations::    
+* Numerical Integration::
+* Differential Equations::
+* Optimization::
+* Statistics::
+* Sets::
+* Polynomial Manipulations::
 * Interpolation::
 * Geometry::
-* Signal Processing::           
-* Image Processing::            
-* Audio Processing::            
-* Object Oriented Programming::            
-* GUI Development::            
-* System Utilities::            
+* Signal Processing::
+* Image Processing::
+* Audio Processing::
+* Object Oriented Programming::
+* GUI Development::
+* System Utilities::
 * Java Interface:: 
 * Packages:: 
 * External Code Interface::
 * Test and Demo Functions::
-* Tips and Standards::                        
+* Tips and Standards::
 * Contributing Guidelines::
 * Obsolete Functions::
 * Trouble::                     If you have trouble installing Octave.
 * Installation::                How to configure, compile and install Octave.
-* Emacs Octave Support::                       
-* Grammar and Parser::                     
+* Emacs Octave Support::
+* Grammar and Parser::
 * Copying::                     The GNU General Public License.
 * Concept Index::               An item for each concept.
 * Function Index::              An item for each documented function.
@@ -199,75 +205,75 @@
 
 Preface
 
-* Acknowledgements::            
+* Acknowledgements::
 * Citing Octave in Publications::
-* How You Can Contribute to Octave::  
-* Distribution::                
+* How You Can Contribute to Octave::
+* Distribution::
 
 Introduction
 
-* Running Octave::              
-* Simple Examples::             
-* Conventions::                 
+* Running Octave::
+* Simple Examples::
+* Conventions::
 
 Conventions
 
-* Fonts::                       
-* Evaluation Notation::         
-* Printing Notation::           
-* Error Messages::              
-* Format of Descriptions::      
+* Fonts::
+* Evaluation Notation::
+* Printing Notation::
+* Error Messages::
+* Format of Descriptions::
 
 Format of Descriptions
 
-* A Sample Function Description::  
-* A Sample Command Description::  
+* A Sample Function Description::
+* A Sample Command Description::
 
 Getting Started
 
-* Invoking Octave from the Command Line::             
-* Quitting Octave::             
-* Getting Help::                
-* Command Line Editing::        
-* Errors::                      
-* Executable Octave Programs::  
-* Comments::                    
+* Invoking Octave from the Command Line::
+* Quitting Octave::
+* Getting Help::
+* Command Line Editing::
+* Errors::
+* Executable Octave Programs::
+* Comments::
 
 Invoking Octave from the Command Line
 
-* Command Line Options::        
-* Startup Files::               
+* Command Line Options::
+* Startup Files::
 
 Command Line Editing
 
-* Cursor Motion::               
-* Killing and Yanking::         
-* Commands For Text::           
-* Commands For Completion::     
-* Commands For History::        
-* Customizing readline::        
-* Customizing the Prompt::      
-* Diary and Echo Commands::     
+* Cursor Motion::
+* Killing and Yanking::
+* Commands For Text::
+* Commands For Completion::
+* Commands For History::
+* Customizing readline::
+* Customizing the Prompt::
+* Diary and Echo Commands::
 
 Comments
 
 * Single Line Comments::
 * Block Comments::
-* Comments and the Help System::                    
+* Comments and the Help System::
 
 Data Types
 
-* Built-in Data Types::         
-* User-defined Data Types::     
-* Object Sizes::                
+* Built-in Data Types::
+* User-defined Data Types::
+* Object Sizes::
 
 Built-in Data Types
 
-* Numeric Objects::             
-* Missing Data::                
-* String Objects::              
-* Data Structure Objects::      
-* Cell Array Objects::          
+* Numeric Objects::
+* Missing Data::
+* String Objects::
+* Data Structure Objects::
+* Cell Array Objects::
 
 Numeric Data Types
 
@@ -276,13 +282,13 @@
 * Single Precision Data Types::
 * Integer Data Types::
 * Bit Manipulations::
-* Logical Values:: 
+* Logical Values::
 * Promotion and Demotion of Data Types::
-* Predicates for Numeric Objects::  
+* Predicates for Numeric Objects::
 
 Matrices
 
-* Empty Matrices::              
+* Empty Matrices::
 
 Integer Data Types
 
@@ -292,16 +298,16 @@
 
 * Escape Sequences in String Constants::
 * Character Arrays::
-* Creating Strings:: 
-* Comparing Strings::           
-* Manipulating Strings::     
-* String Conversions::          
-* Character Class Functions::   
+* Creating Strings::
+* Comparing Strings::
+* Manipulating Strings::
+* String Conversions::
+* Character Class Functions::
 
 Creating Strings
 
-* Concatenating Strings:: 
-* Conversion of Numerical Data to Strings::
+* Concatenating Strings::
+* Converting Numerical Data to Strings::
 
 Data Containers
 
@@ -332,20 +338,20 @@
 
 Variables
 
-* Global Variables::            
-* Persistent Variables::        
-* Status of Variables::         
+* Global Variables::
+* Persistent Variables::
+* Status of Variables::
 
 Expressions
 
-* Index Expressions::           
-* Calling Functions::           
-* Arithmetic Ops::              
-* Comparison Ops::              
-* Boolean Expressions::         
-* Assignment Ops::              
-* Increment Ops::               
-* Operator Precedence::         
+* Index Expressions::
+* Calling Functions::
+* Arithmetic Ops::
+* Comparison Ops::
+* Boolean Expressions::
+* Assignment Ops::
+* Increment Ops::
+* Operator Precedence::
 
 Index Expressions
 
@@ -353,13 +359,13 @@
 
 Calling Functions
 
-* Call by Value::               
-* Recursion::                   
+* Call by Value::
+* Recursion::
 
 Boolean Expressions
 
-* Element-by-element Boolean Operators::  
-* Short-circuit Boolean Operators::  
+* Element-by-element Boolean Operators::
+* Short-circuit Boolean Operators::
 
 Evaluation
 
@@ -368,40 +374,40 @@
 
 Statements
 
-* The if Statement::            
-* The switch Statement::        
-* The while Statement::         
-* The do-until Statement::      
-* The for Statement::           
-* The break Statement::         
-* The continue Statement::      
-* The unwind_protect Statement::  
-* The try Statement::           
-* Continuation Lines::          
+* The if Statement::
+* The switch Statement::
+* The while Statement::
+* The do-until Statement::
+* The for Statement::
+* The break Statement::
+* The continue Statement::
+* The unwind_protect Statement::
+* The try Statement::
+* Continuation Lines::
 
 The switch Statement
 
-* Notes for the C Programmer::  
+* Notes for the C Programmer::
 
 The for Statement
 
-* Looping Over Structure Elements::  
+* Looping Over Structure Elements::
 
 Functions and Scripts
 
 * Introduction to Function and Script Files::
-* Defining Functions::          
-* Multiple Return Values::      
-* Variable-length Argument Lists::  
-* Ignoring Arguments::  
-* Variable-length Return Lists::  
-* Returning from a Function::   
-* Default Arguments::   
-* Function Files::              
-* Script Files::                
-* Function Handles Inline Functions and Anonymous Functions::
+* Defining Functions::
+* Multiple Return Values::
+* Variable-length Argument Lists::
+* Ignoring Arguments::
+* Variable-length Return Lists::
+* Returning from a Function::
+* Default Arguments::
+* Function Files::
+* Script Files::
+* Function Handles Anonymous Functions Inline Functions::
 * Commands::
-* Organization of Functions::   
+* Organization of Functions::
 
 Function Files
 
@@ -413,7 +419,7 @@
 * Function Locking::
 * Function Precedence::
 
-Function Handles Inline Functions and Anonymous Functions
+Function Handles Anonymous Functions Inline Functions
 
 * Function Handles::
 * Anonymous Functions::
@@ -447,14 +453,14 @@
 
 Input and Output
 
-* Basic Input and Output::      
-* C-Style I/O Functions::       
+* Basic Input and Output::
+* C-Style I/O Functions::
 
 Basic Input and Output
 
-* Terminal Output::             
-* Terminal Input::              
-* Simple File I/O::             
+* Terminal Output::
+* Terminal Input::
+* Simple File I/O::
 
 Terminal Output
 
@@ -466,130 +472,130 @@
 
 C-Style I/O Functions
 
-* Opening and Closing Files::   
-* Simple Output::               
-* Line-Oriented Input::         
-* Formatted Output::            
-* Output Conversion for Matrices::  
-* Output Conversion Syntax::    
-* Table of Output Conversions::  
-* Integer Conversions::         
+* Opening and Closing Files::
+* Simple Output::
+* Line-Oriented Input::
+* Formatted Output::
+* Output Conversion for Matrices::
+* Output Conversion Syntax::
+* Table of Output Conversions::
+* Integer Conversions::
 * Floating-Point Conversions::
-* Other Output Conversions::    
-* Formatted Input::             
-* Input Conversion Syntax::     
-* Table of Input Conversions::  
-* Numeric Input Conversions::   
-* String Input Conversions::    
-* Binary I/O::                  
-* Temporary Files::             
-* EOF and Errors::              
-* File Positioning::            
+* Other Output Conversions::
+* Formatted Input::
+* Input Conversion Syntax::
+* Table of Input Conversions::
+* Numeric Input Conversions::
+* String Input Conversions::
+* Binary I/O::
+* Temporary Files::
+* EOF and Errors::
+* File Positioning::
 
 Plotting
 
-* Introduction to Plotting::    
-* High-Level Plotting::         
-* Graphics Data Structures::    
-* Advanced Plotting::           
+* Introduction to Plotting::
+* High-Level Plotting::
+* Graphics Data Structures::
+* Advanced Plotting::
 
 High-Level Plotting
 
-* Two-Dimensional Plots::       
-* Three-Dimensional Plots::  
-* Plot Annotations::            
-* Multiple Plots on One Page::  
-* Multiple Plot Windows::       
+* Two-Dimensional Plots::
+* Three-Dimensional Plots::
+* Plot Annotations::
+* Multiple Plots on One Page::
+* Multiple Plot Windows::
 * Manipulation of Plot Windows::
 * Use of the @code{interpreter} Property::
-* Printing and Saving Plots::              
-* Interacting with Plots::      
-* Test Plotting Functions::     
+* Printing and Saving Plots::
+* Interacting with Plots::
+* Test Plotting Functions::
 
 Two-Dimensional Plots
 
-* Axis Configuration::  
-* Two-dimensional Function Plotting::  
-* Two-dimensional Geometric Shapes::  
+* Axis Configuration::
+* Two-dimensional Function Plotting::
+* Two-dimensional Geometric Shapes::
 
 Three-Dimensional Plots
 
 * Aspect Ratio::
-* Three-dimensional Function Plotting::  
-* Three-dimensional Geometric Shapes::  
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
 
 Graphics Data Structures
 
-* Introduction to Graphics Structures::  
-* Graphics Objects::            
-* Graphics Object Properties::  
-* Searching Properties::        
-* Managing Default Properties::  
+* Introduction to Graphics Structures::
+* Graphics Objects::
+* Graphics Object Properties::
+* Searching Properties::
+* Managing Default Properties::
 
 Graphics Object Properties
 
-* Root Figure Properties::      
-* Figure Properties::           
-* Axes Properties::             
-* Line Properties::             
-* Text Properties::             
-* Image Properties::            
-* Patch Properties::            
-* Surface Properties::          
+* Root Figure Properties::
+* Figure Properties::
+* Axes Properties::
+* Line Properties::
+* Text Properties::
+* Image Properties::
+* Patch Properties::
+* Surface Properties::
 
 Advanced Plotting
 
-* Colors::                      
-* Line Styles::                 
-* Marker Styles::               
-* Callbacks::                   
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
 * Application-defined Data::
-* Object Groups::               
-* Graphics Toolkits::           
+* Object Groups::
+* Graphics Toolkits::
 
 Object Groups
 
-* Data Sources in Object Groups::  
-* Area Series::                 
-* Bar Series::                  
-* Contour Groups::              
-* Error Bar Series::            
-* Line Series::                 
-* Quiver Group::                
-* Scatter Group::               
-* Stair Group::                 
-* Stem Series::                 
-* Surface Group::               
+* Data Sources in Object Groups::
+* Area Series::
+* Bar Series::
+* Contour Groups::
+* Error Bar Series::
+* Line Series::
+* Quiver Group::
+* Scatter Group::
+* Stair Group::
+* Stem Series::
+* Surface Group::
 
 Graphics Toolkits
 
-* Customizing Toolkit Behavior::    
+* Customizing Toolkit Behavior::
 
 Matrix Manipulation
 
-* Finding Elements and Checking Conditions::  
-* Rearranging Matrices::        
-* Special Utility Matrices::    
-* Famous Matrices::             
+* Finding Elements and Checking Conditions::
+* Rearranging Matrices::
+* Special Utility Matrices::
+* Famous Matrices::
 
 Arithmetic
 
 * Exponents and Logarithms::
-* Complex Arithmetic::          
-* Trigonometry::                
-* Sums and Products::           
-* Utility Functions::           
-* Special Functions::           
+* Complex Arithmetic::
+* Trigonometry::
+* Sums and Products::
+* Utility Functions::
+* Special Functions::
 * Rational Approximations::
 * Coordinate Transformations::
-* Mathematical Constants::      
+* Mathematical Constants::
 
 Linear Algebra
 
 * Techniques Used for Linear Algebra::
-* Basic Matrix Functions::      
-* Matrix Factorizations::       
-* Functions of a Matrix::       
+* Basic Matrix Functions::
+* Matrix Factorizations::
+* Functions of a Matrix::
 * Specialized Solvers::
 
 Vectorization and Faster Code Execution
@@ -605,15 +611,15 @@
 Nonlinear Equations
 
 * Solvers::
-* Minimizers::          
+* Minimizers::
 
 Diagonal and Permutation Matrices
 
-* Basic Usage::          Creation and Manipulation of Diagonal and Permutation Matrices
-* Matrix Algebra::       Linear Algebra with Diagonal and Permutation Matrices
+* Basic Usage::          Creation and Manipulation of Diagonal/Permutation Matrices
+* Matrix Algebra::       Linear Algebra with Diagonal/Permutation Matrices
 * Function Support::     Functions That Are Aware of These Matrices
-* Example Code::         Some Examples of Usage
-* Zeros Treatment::      The Differences in Treatment of Zero Elements
+* Example Code::         Examples of Usage
+* Zeros Treatment::      Differences in Treatment of Zero Elements
 
 Basic Usage
 
@@ -647,37 +653,37 @@
 
 Operators and Functions
 
-* Sparse Functions::            
-* Return Types of Operators and Functions::  
-* Mathematical Considerations::  
+* Sparse Functions::
+* Return Types of Operators and Functions::
+* Mathematical Considerations::
 
 Numerical Integration
 
-* Functions of One Variable:: 
-* Orthogonal Collocation::      
-* Functions of Multiple Variables:: 
+* Functions of One Variable::
+* Orthogonal Collocation::
+* Functions of Multiple Variables::
 
 Differential Equations
 
-* Ordinary Differential Equations::  
-* Differential-Algebraic Equations::  
+* Ordinary Differential Equations::
+* Differential-Algebraic Equations::
 
 Optimization
 
-* Linear Programming::       
-* Quadratic Programming::       
-* Nonlinear Programming::       
-* Linear Least Squares::        
+* Linear Programming::
+* Quadratic Programming::
+* Nonlinear Programming::
+* Linear Least Squares::
 
 Statistics
 
 * Descriptive Statistics::
-* Basic Statistical Functions:: 
-* Statistical Plots:: 
-* Correlation and Regression Analysis::                      
-* Distributions::     
-* Tests::                       
-* Random Number Generation::          
+* Basic Statistical Functions::
+* Statistical Plots::
+* Correlation and Regression Analysis::
+* Distributions::
+* Tests::
+* Random Number Generation::
 
 Sets
 
@@ -711,11 +717,11 @@
 
 Image Processing
 
-* Loading and Saving Images::   
-* Displaying Images::           
-* Representing Images::         
-* Plotting on top of Images::   
-* Color Conversion::            
+* Loading and Saving Images::
+* Displaying Images::
+* Representing Images::
+* Plotting on top of Images::
+* Color Conversion::
 
 Object Oriented Programming
 
@@ -738,24 +744,24 @@
 
 GUI Development
 
-* I/O Dialogs::       
-* Progress Bar::       
-* GUI Utility Functions::       
-* User-Defined Preferences::       
+* I/O Dialogs::
+* Progress Bar::
+* GUI Utility Functions::
+* User-Defined Preferences::
 
 System Utilities
 
-* Timing Utilities::            
-* Filesystem Utilities::        
+* Timing Utilities::
+* Filesystem Utilities::
 * File Archiving Utilities::
 * Networking Utilities::
-* Controlling Subprocesses::    
-* Process ID Information::      
-* Environment Variables::       
-* Current Working Directory::   
-* Password Database Functions::  
-* Group Database Functions::    
-* System Information::          
+* Controlling Subprocesses::
+* Process ID Information::
+* Environment Variables::
+* Current Working Directory::
+* Password Database Functions::
+* Group Database Functions::
+* System Information::
 * Hashing Functions::
 
 Networking Utilities
@@ -776,58 +782,58 @@
 * How to make Java classes available?::
 * How to create an instance of a Java class?::
 * How can I handle memory limitations?::
-* Which @TeX{} symbols are implemented in the dialog functions?::
+* Which @TeX{} symbols are implemented in dialog functions?::
 
 Packages
 
-* Installing and Removing Packages::  
-* Using Packages::              
-* Administrating Packages::     
-* Creating Packages::           
+* Installing and Removing Packages::
+* Using Packages::
+* Administrating Packages::
+* Creating Packages::
 
 Creating Packages
 
-* The DESCRIPTION File::        
-* The INDEX File::              
-* PKG_ADD and PKG_DEL Directives::  
+* The DESCRIPTION File::
+* The INDEX File::
+* PKG_ADD and PKG_DEL Directives::
 
 External Code Interface
 
-* Oct-Files::                   
-* Mex-Files::                   
-* Standalone Programs::         
+* Oct-Files::
+* Mex-Files::
+* Standalone Programs::
 
 Oct-Files
 
-* Getting Started with Oct-Files::  
-* Matrices and Arrays in Oct-Files::  
-* Character Strings in Oct-Files::  
-* Cell Arrays in Oct-Files::    
-* Structures in Oct-Files::  
-* Sparse Matrices in Oct-Files::  
-* Accessing Global Variables in Oct-Files::  
-* Calling Octave Functions from Oct-Files::  
-* Calling External Code from Oct-Files::  
-* Allocating Local Memory in Oct-Files::  
-* Input Parameter Checking in Oct-Files::  
-* Exception and Error Handling in Oct-Files::  
-* Documentation and Test of Oct-Files::  
+* Getting Started with Oct-Files::
+* Matrices and Arrays in Oct-Files::
+* Character Strings in Oct-Files::
+* Cell Arrays in Oct-Files::
+* Structures in Oct-Files::
+* Sparse Matrices in Oct-Files::
+* Accessing Global Variables in Oct-Files::
+* Calling Octave Functions from Oct-Files::
+* Calling External Code from Oct-Files::
+* Allocating Local Memory in Oct-Files::
+* Input Parameter Checking in Oct-Files::
+* Exception and Error Handling in Oct-Files::
+* Documentation and Test of Oct-Files::
 
 Sparse Matrices in Oct-Files
 
-* Array and Sparse Differences::  
-* Creating Sparse Matrices in Oct-Files::  
-* Using Sparse Matrices in Oct-Files::  
+* Array and Sparse Class Differences::
+* Creating Sparse Matrices in Oct-Files::
+* Using Sparse Matrices in Oct-Files::
 
 Mex-Files
 
-* Getting Started with Mex-Files::  
-* Working with Matrices and Arrays in Mex-Files::  
-* Character Strings in Mex-Files::  
-* Cell Arrays with Mex-Files::  
-* Structures with Mex-Files::  
-* Sparse Matrices with Mex-Files::  
-* Calling Other Functions in Mex-Files::  
+* Getting Started with Mex-Files::
+* Working with Matrices and Arrays in Mex-Files::
+* Character Strings in Mex-Files::
+* Cell Arrays with Mex-Files::
+* Structures with Mex-Files::
+* Sparse Matrices with Mex-Files::
+* Calling Other Functions in Mex-Files::
 
 Test and Demo Functions
 
@@ -854,12 +860,12 @@
 Trouble
 
 * Actual Bugs::                 Bugs we will fix later.
-* Reporting Bugs::              
-* Service::                     
+* Reporting Bugs::
+* Service::
 
 Reporting Bugs
 
-* Bug Criteria::                
+* Bug Criteria::
 * Bug Tracker::        Where to submit your bug report.
 * Bug Reporting::      How to report a bug effectively.
 * Sending Patches::    How to send a patch for Octave.
@@ -879,15 +885,15 @@
 
 Emacs Octave Support
 
-* Installing EOS::              
-* Using Octave Mode::           
-* Running Octave from Within Emacs::  
-* Using the Emacs Info Reader for Octave::  
+* Installing EOS::
+* Using Octave Mode::
+* Running Octave from Within Emacs::
+* Using the Emacs Info Reader for Octave::
 
 Grammar and Parser
 
-* Keywords::                    
-* Parser::                    
+* Keywords::
+* Parser::
 
 @end detailmenu
 @end menu
--- a/doc/interpreter/oop.txi
+++ b/doc/interpreter/oop.txi
@@ -94,9 +94,7 @@
 our polynomial might look like
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/polynomial.m)
-@end group
 @end example
 
 Note that the return value of the constructor must be the output of
@@ -177,9 +175,7 @@
 An example of a display method for the polynomial class might be
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/display.m)
-@end group
 @end example
 
 @noindent
@@ -195,9 +191,7 @@
 all of the properties of the class.  For example:
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/get.m)
-@end group
 @end example
 
 @noindent
@@ -205,9 +199,7 @@
 object to modify, and then take property/value pairs to be modified. 
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/set.m)
-@end group
 @end example
 
 @noindent
@@ -276,15 +268,13 @@
 
 @DOCSTRING(subsref)
 
-For example we might decide that indexing with "()" evaluates the
-polynomial and indexing with "@{@}" returns the @var{n}-th coefficient (of
-@var{n}-th power).  In this case the @code{subsref} method of our polynomial
-class might look like
+For example we might decide that indexing with @qcode{"()"} evaluates the
+polynomial and indexing with @qcode{"@{@}"} returns the @var{n}-th coefficient
+(of @var{n}-th power).  In this case the @code{subsref} method of our
+polynomial class might look like
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/subsref.m)
-@end group
 @end example
 
 The equivalent functionality for subscripted assignments uses the 
@@ -640,21 +630,19 @@
 @end example
 
 @noindent
-That mixes an object of the class "double" with an object of the class
-"polynomial".  In this case we like to ensure that the return type of
-the above is of the type "polynomial" and so we use the
+That mixes an object of the class @qcode{"double"} with an object of the class
+@qcode{"polynomial"}.  In this case we like to ensure that the return type of
+the above is of the type @qcode{"polynomial"} and so we use the
 @code{superiorto} function in the class constructor.  In particular our
 polynomial class constructor would be modified to be
 
 @example
-@group
 @EXAMPLEFILE(@polynomial/polynomial_superiorto.m)
-@end group
 @end example
 
 Note that user classes always have higher precedence than built-in
 Octave types.  So in fact marking our polynomial class higher than the 
-"double" class is in fact not necessary.
+@qcode{"double"} class is in fact not necessary.
 
 When faced with two objects that have the same precedence, Octave will use the
 method of the object that appears first on the list of arguments.
@@ -692,9 +680,7 @@
 FIRfilter.m in the class directory.
 
 @example
-@group
 @EXAMPLEFILE(@FIRfilter/FIRfilter.m)
-@end group
 @end example
 
 As before, the leading comments provide command-line documentation for
@@ -758,12 +744,10 @@
 to access the fields.  The @code{subsref} method may be used for both.
 
 @example
-@group
 @EXAMPLEFILE(@FIRfilter/subsref.m)
-@end group
 @end example
 
-The "()" case allows us to filter data using the polynomial provided
+The @qcode{"()"} case allows us to filter data using the polynomial provided
 to the constructor.
 
 @example
@@ -781,7 +765,7 @@
 @end group
 @end example
 
-The "." case allows us to view the contents of the polynomial field.
+The @qcode{"."} case allows us to view the contents of the polynomial field.
 
 @example
 @group
@@ -819,9 +803,7 @@
 constructor for this case might be
 
 @example
-@group
 @EXAMPLEFILE(@FIRfilter/FIRfilter_aggregation.m)
-@end group
 @end example
 
 For our example, the remaining class methods remain unchanged.
--- a/doc/interpreter/optim.txi
+++ b/doc/interpreter/optim.txi
@@ -25,10 +25,10 @@
 Minimization.
 
 @menu
-* Linear Programming::       
-* Quadratic Programming::       
-* Nonlinear Programming::       
-* Linear Least Squares::        
+* Linear Programming::
+* Quadratic Programming::
+* Nonlinear Programming::
+* Linear Least Squares::
 @end menu
 
 @c @cindex linear programming
--- a/doc/interpreter/package.txi
+++ b/doc/interpreter/package.txi
@@ -71,7 +71,7 @@
 
 @noindent
 In this case only version 1.0.0 of the @code{image} package is
-installed.  The '*' character next to the package name shows that the
+installed.  The @qcode{'*'} character next to the package name shows that the
 image package is loaded and ready for use.
 
 It is possible to remove a package from the system using the
@@ -469,7 +469,7 @@
 @end itemize
 
 @noindent
-The format can be summarized with the following example.
+The format can be summarized with the following example:
 
 @example
 @group
@@ -571,6 +571,7 @@
 @noindent
 In both cases @code{some_octave_command} should be replaced by the
 command that should be placed in the @w{@code{PKG_ADD}} file.
-@w{@code{PKG_DEL}} directives work in the same way, except the @w{@code{PKG_ADD}}
-keyword is replaced with @w{@code{PKG_DEL}} and the commands get added
-to the @w{@code{PKG_DEL}} file.
+@w{@code{PKG_DEL}} directives work in the same way, except the
+@w{@code{PKG_ADD}} keyword is replaced with @w{@code{PKG_DEL}} and the commands
+get added to the @w{@code{PKG_DEL}} file.
+
--- a/doc/interpreter/plot.txi
+++ b/doc/interpreter/plot.txi
@@ -22,10 +22,10 @@
 @cindex graphics
 
 @menu
-* Introduction to Plotting::    
-* High-Level Plotting::         
-* Graphics Data Structures::    
-* Advanced Plotting::           
+* Introduction to Plotting::
+* High-Level Plotting::
+* Graphics Data Structures::
+* Advanced Plotting::
 @end menu
 
 @node Introduction to Plotting
@@ -57,25 +57,25 @@
 and @ref{Advanced Plotting}.
 
 @menu
-* Two-Dimensional Plots::       
-* Three-Dimensional Plots::  
-* Plot Annotations::            
-* Multiple Plots on One Page::  
-* Multiple Plot Windows::       
+* Two-Dimensional Plots::
+* Three-Dimensional Plots::
+* Plot Annotations::
+* Multiple Plots on One Page::
+* Multiple Plot Windows::
 * Manipulation of Plot Windows::
 * Use of the @code{interpreter} Property::
-* Printing and Saving Plots::              
-* Interacting with Plots::      
-* Test Plotting Functions::     
+* Printing and Saving Plots::
+* Interacting with Plots::
+* Test Plotting Functions::
 @end menu
 
 @node Two-Dimensional Plots
 @subsection Two-Dimensional Plots
 
 @menu
-* Axis Configuration::  
-* Two-dimensional Function Plotting::  
-* Two-dimensional Geometric Shapes::  
+* Axis Configuration::
+* Two-dimensional Function Plotting::
+* Two-dimensional Geometric Shapes::
 @end menu
 
 The @code{plot} function allows you to create simple x-y plots with
@@ -398,8 +398,8 @@
 
 @menu
 * Aspect Ratio::
-* Three-dimensional Function Plotting::  
-* Three-dimensional Geometric Shapes::  
+* Three-dimensional Function Plotting::
+* Three-dimensional Geometric Shapes::
 @end menu
 
 @node Aspect Ratio
@@ -588,13 +588,13 @@
 @subsection Use of the @code{interpreter} Property
 
 All text objects, including titles, labels, legends, and text, include
-the property 'interpreter', this property determines the manner in which
+the property @qcode{"interpreter"}, this property determines the manner in which
 special control sequences in the text are rendered.  If the interpreter
-is set to 'none', then no rendering occurs.  At this point the 'latex'
-option is not implemented and so the 'latex' interpreter also does not
-interpret the text.
-
-The 'tex' option implements a subset of @TeX{} functionality in the
+is set to @qcode{"none"}, then no rendering occurs.  At this point the
+@qcode{"latex"} option is not implemented and so the @qcode{"latex"}
+interpreter also does not interpret the text.
+
+The @qcode{"tex"} option implements a subset of @TeX{} functionality in the
 rendering of the text.  This allows the insertion of special characters
 such as Greek or mathematical symbols within the text.  The special
 characters are also inserted with a code starting with the back-slash
@@ -618,7 +618,7 @@
 @end example
 
 @noindent
-where the character 'a' will not appear in a bold font.  Note that to
+where the character @qcode{'a'} will not appear in a bold font.  Note that to
 avoid having Octave interpret the backslash characters in the strings,
 the strings should be in single quotes.
 
@@ -630,11 +630,11 @@
 use @tab
 @end multitable
 
-Finally, the superscript and subscripting can be controlled with the '^'
-and '_' characters.  If the '^' or '_' is followed by a @{ character,
-then all of the block surrounded by the @{ @} pair is super- or
-sub-scripted.  Without the @{ @} pair, only the character immediately
-following the '^' or '_' is super- or sub-scripted.
+Finally, the superscript and subscripting can be controlled with the @qcode{'^'}
+and @qcode{'_'} characters.  If the @qcode{'^'} or @qcode{'_'} is followed by a
+@{ character, then all of the block surrounded by the @{ @} pair is super- or
+sub-scripted.  Without the @{ @} pair, only the character immediately following
+the @qcode{'^'} or @qcode{'_'} is super- or sub-scripted.
 
 @float Table,tab:extended
 @tex
@@ -888,11 +888,11 @@
 @cindex graphics data structures
 
 @menu
-* Introduction to Graphics Structures::  
-* Graphics Objects::            
-* Graphics Object Properties::  
-* Searching Properties::        
-* Managing Default Properties::  
+* Introduction to Graphics Structures::
+* Graphics Objects::
+* Graphics Object Properties::
+* Searching Properties::
+* Managing Default Properties::
 @end menu
 
 @node Introduction to Graphics Structures
@@ -950,8 +950,8 @@
 properties of graphics objects.  In addition, the @code{get} command may be
 used to obtain property names.
 
-For example, the property "type" of the graphics object pointed to by the
-graphics handle h may be displayed by:
+For example, the property @qcode{"type"} of the graphics object pointed to by
+the graphics handle h may be displayed by:
 
 @example
 get (h, "type")
@@ -962,7 +962,7 @@
 allowed properties are wanted they may be displayed by:
 @code{get (h, "")}.
 
-Thus, for example,
+Thus, for example:
 
 @smallexample
 h = figure ();
@@ -1205,14 +1205,14 @@
 @cindex graphics object properties
 
 @menu
-* Root Figure Properties::      
-* Figure Properties::           
-* Axes Properties::             
-* Line Properties::             
-* Text Properties::             
-* Image Properties::            
-* Patch Properties::            
-* Surface Properties::          
+* Root Figure Properties::
+* Figure Properties::
+* Axes Properties::
+* Line Properties::
+* Text Properties::
+* Image Properties::
+* Patch Properties::
+* Surface Properties::
 @end menu
 
 In this Section the object properties are discussed in detail, starting
@@ -1227,12 +1227,12 @@
 
 @table @code
 @item __modified__  
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item __myhandle__
 
 @item beingdeleted  
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item busyaction
 
@@ -1243,7 +1243,7 @@
 @item children
 
 @item clipping
- --- Values: "on," "off"
+ --- Values: @qcode{"on"}, @qcode{"off"}
 
 @item createfcn
 
@@ -1252,13 +1252,13 @@
 @item deletefcn
 
 @item handlevisibility  
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item hittest
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item interruptible  
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item parent
 
@@ -1277,7 +1277,7 @@
 @item screenpixelsperinch
 
 @item showhiddenhandles  
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item tag
 
@@ -1313,7 +1313,7 @@
 @item alphamap
 
 @item beingdeleted 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item busyaction
 
@@ -1323,7 +1323,7 @@
 Handle to children.
 
 @item clipping
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item closerequestfcn 
 --- Handle of function to call on close.
@@ -1347,36 +1347,36 @@
 @item currentpoint
 Holds the coordinates of the point over which the mouse pointer was when
 the mouse button was pressed.  If a mouse callback function is defined,
-@code{"currentpoint"} holds the coordinates of the point over which the
+@qcode{"currentpoint"} holds the coordinates of the point over which the
 mouse pointer is when the function gets called.
 
 @item deletefcn
 
 @item dockcontrols 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item doublebuffer 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item filename
 
 @item handlevisibility 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item hittest
 
 @item integerhandle
 
 @item interruptible 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item inverthardcopy
 
 @item keypressfcn
-see @code{"keypressfcn"}
+see @qcode{"keypressfcn"}
 
 @item keyreleasefcn
-With @code{"keypressfcn"}, The keyboard callback functions.  These
+With @qcode{"keypressfcn"}, the keyboard callback functions.  These
 callback functions get called when a key is pressed/released
 respectively.  The functions are called with two input arguments.  The
 first argument holds the handle of the calling figure.  The second
@@ -1391,8 +1391,8 @@
 
 @item Modifier
 A cell array containing strings representing the modifiers pressed with
-the key.  Possible values are @code{"shift"}, @code{"alt"}, and
-@code{"control"}.
+the key.  Possible values are @qcode{"shift"}, @qcode{"alt"}, and
+@qcode{"control"}.
 @end table
 
 @item menubar
@@ -1404,21 +1404,21 @@
 @item nextplot
 May be one of
 
-@table @code
-@item "new"
-
-@item "add"
-
-@item "replace"
-
-@item "replacechildren"
+@table @asis
+@item @qcode{"new"}
+
+@item @qcode{"add"}
+
+@item @qcode{"replace"}
+
+@item @qcode{"replacechildren"}
 @end table
 
 @item numbertitle
 
 @item paperorientation
-Indicates the orientation for printing.  Either @code{"landscape"} or
-@code{"portrait"}.
+Indicates the orientation for printing.  Either @qcode{"landscape"} or
+@qcode{"portrait"}.
 
 @item paperposition
 
@@ -1449,7 +1449,7 @@
 @item selected
 
 @item selectionhighlight 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item selectiontype
 
@@ -1464,19 +1464,19 @@
 @item userdata
 
 @item visible
-Either @code{"on"} or @code{"off"} to toggle display of the figure.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of the figure.
 
 @item windowbuttondownfcn
-See @code{"windowbuttonupfcn"}
+See @qcode{"windowbuttonupfcn"}
 
 @item windowbuttonmotionfcn
-See @code{"windowbuttonupfcn"}
+See @qcode{"windowbuttonupfcn"}
 
 @item windowbuttonupfcn
-With @code{"windowbuttondownfcn"} and @code{"windowbuttonmotionfcn"},
-The mouse callback functions.  These callback functions get called when
+With @qcode{"windowbuttondownfcn"} and @qcode{"windowbuttonmotionfcn"},
+the mouse callback functions.  These callback functions get called when
 the mouse button is pressed, dragged, and released respectively.  When
-these callback functions are called, the @code{"currentpoint"} property
+these callback functions are called, the @qcode{"currentpoint"} property
 holds the current coordinates of the cursor.
 
 @item windowscrollwheelfcn
@@ -1517,7 +1517,7 @@
 
 @item box
 Box surrounding axes. 
---- Values: "on," "off"
+--- Values: @qcode{"on"}, @qcode{"off"}
 
 @item busyaction
 
@@ -1545,10 +1545,10 @@
 Two-element vector defining the limits for the c axis of
 an image.  See @code{pcolor} property.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item climmode
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item clipping
 
@@ -1561,7 +1561,7 @@
 @item currentpoint
 Holds the coordinates of the point over which the mouse pointer was when
 the mouse button was pressed.  If a mouse callback function is defined,
-@code{"currentpoint"} holds the coordinates of the point over which the
+@qcode{"currentpoint"} holds the coordinates of the point over which the
 mouse pointer is when the function gets called.
 
 @item dataaspectratio
@@ -1570,10 +1570,10 @@
 2]} causes the length of one unit as displayed on the y-axis to be the
 same as the length of 2 units on the x-axis.  Setting
 @code{dataaspectratio} also forces the @code{dataaspectratiomode}
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item dataaspectratiomode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item deletefcn
 
@@ -1610,14 +1610,12 @@
 @item nextplot
 May be one of
 
-@table @code
-@item "new"
-
-@item "add"
-
-@item "replace"
-
-@item "replacechildren"
+@table @asis
+@item @qcode{"add"}
+
+@item @qcode{"replace"}
+
+@item @qcode{"replacechildren"}
 @end table
 
 @item outerposition
@@ -1675,7 +1673,7 @@
 A three element vector specifying the view point for three-dimensional plots.
 
 @item visible
-Either @code{"on"} or @code{"off"} to toggle display of the axes.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of the axes.
 
 @item x_normrendertransform
 
@@ -1688,15 +1686,15 @@
 @item x_viewtransform
 
 @item xaxislocation 
-Either @code{"top"} or @code{"bottom"}.
+Either @qcode{"top"} or @qcode{"bottom"}.
 
 @item xcolor
 
 @item xdir
-Either @code{"forward"} or @code{"reverse"}.
+Either @qcode{"forward"} or @qcode{"reverse"}.
 
 @item xgrid
-Either @code{"on"} or @code{"off"} to toggle display of grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
 
 @item xlabel
 Indices to text objects for the axes labels.
@@ -1704,44 +1702,44 @@
 @item xlim
 Two-element vector defining the limits for the x-axis.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item xlimmode
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item xminorgrid 
-Either @code{"on"} or @code{"off"} to toggle display of minor grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
 
 @item xminortick
 
 @item xscale
-Either @code{"linear"} or @code{"log"}.
+Either @qcode{"linear"} or @qcode{"log"}.
 
 @item xtick
 Set position of tick marks.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item xticklabel
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item xticklabelmode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item xtickmode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item yaxislocation 
-Either @code{"left"} or @code{"right"}
+Either @qcode{"left"} or @qcode{"right"}
 
 @item ycolor
 
 @item ydir
-Either @code{"forward"} or @code{"reverse"}.
+Either @qcode{"forward"} or @qcode{"reverse"}.
 
 @item ygrid
-Either @code{"on"} or @code{"off"} to toggle display of grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
 
 @item ylabel
 Indices to text objects for the axes labels.
@@ -1749,41 +1747,41 @@
 @item ylim
 Two-element vectors defining the limits for the x, y, and z axes and the
 Setting one of these properties also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item ylimmode
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item yminorgrid 
-Either @code{"on"} or @code{"off"} to toggle display of minor grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
 
 @item yminortick
 
 @item yscale
-Either @code{"linear"} or @code{"log"}.
+Either @qcode{"linear"} or @qcode{"log"}.
 
 @item ytick
 Set position of tick marks.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item yticklabel
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item yticklabelmode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item ytickmode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item zcolor
 
 @item zdir
-Either @code{"forward"} or @code{"reverse"}.
+Either @qcode{"forward"} or @qcode{"reverse"}.
 
 @item zgrid
-Either @code{"on"} or @code{"off"} to toggle display of grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
 
 @item zlabel
 Indices to text objects for the axes labels.
@@ -1791,33 +1789,33 @@
 @item zlim
 Two-element vector defining the limits for z-axis.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item zlimmode
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item zminorgrid 
-Either @code{"on"} or @code{"off"} to toggle display of minor grid lines.
+Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
 
 @item zminortick
 
 @item zscale
-Either @code{"linear"} or @code{"log"}.
+Either @qcode{"linear"} or @qcode{"log"}.
 
 @item ztick
 Set position of tick marks.
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item zticklabel 
 Setting this property also forces the corresponding mode
-property to be set to @code{"manual"}.
+property to be set to @qcode{"manual"}.
 
 @item zticklabelmode 
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @item ztickmode
-Either @code{"manual"} or @code{"auto"}.
+Either @qcode{"manual"} or @qcode{"auto"}.
 
 @end table
 
@@ -1973,8 +1971,8 @@
 @item erasemode
 
 @item fontangle
-Flag whether the font is italic or normal.  Valid values are 'normal',
-'italic' and 'oblique'.
+Flag whether the font is italic or normal.  Valid values are @qcode{"normal"},
+@qcode{"italic"}, and @qcode{"oblique"}.
 
 @item fontname
 The font used for the text.
@@ -1985,19 +1983,19 @@
 @item fontunits
 
 @item fontweight
-Flag whether the font is bold, etc.  Valid values are 'normal', 'bold',
-'demi' or 'light'.
+Flag whether the font is bold, etc.  Valid values are @qcode{"normal"},
+@qcode{"bold"}, @qcode{"demi"}, or @qcode{"light"}.
 
 @item handlevisibility
 
 @item hittest
 
 @item horizontalalignment
-May be @code{"left"}, @code{"center"}, or @code{"right"}.
+May be @qcode{"left"}, @qcode{"center"}, or @qcode{"right"}.
 
 @item interpreter
-Determines how the text is rendered.  Valid values are 'none', 'tex' or
-'latex'.
+Determines how the text is rendered.  Valid values are @qcode{"none"},
+@qcode{"tex"}, or @qcode{"latex"}.
 
 @item interruptible
 
@@ -2029,7 +2027,7 @@
 @item uicontextmenu
 
 @item units
-May be @code{"normalized"} or @code{"graph"}.
+May be @qcode{"normalized"} or @qcode{"graph"}.
 
 @item userdata
 
@@ -2440,8 +2438,8 @@
 Although default values may be set for any object, they are set in
 parent objects and apply to child objects, of the specified object type.
 For example, setting the default @code{color} property of @code{line}
-objects to "green", for the @code{root} object, will result in all
-@code{line} objects inheriting the @code{color} "green" as the default
+objects to @qcode{"green"}, for the @code{root} object, will result in all
+@code{line} objects inheriting the @code{color} @qcode{"green"} as the default
 value.
 
 @example
@@ -2489,7 +2487,7 @@
 from the global root figure parent object.
 
 To remove a user-defined default setting, set the default property to
-the value @code{"remove"}.  For example,
+the value @qcode{"remove"}.  For example,
 
 @example
 set (gca (), "defaultlinecolor", "remove");
@@ -2502,7 +2500,7 @@
 
 @DOCSTRING(reset)
 
-Getting the @code{"default"} property of an object returns a list of
+Getting the @qcode{"default"} property of an object returns a list of
 user-defined defaults set for the object.  For example,
 
 @example
@@ -2528,13 +2526,13 @@
 
 
 @menu
-* Colors::                      
-* Line Styles::                 
-* Marker Styles::               
-* Callbacks::                   
+* Colors::
+* Line Styles::
+* Marker Styles::
+* Callbacks::
 * Application-defined Data::
-* Object Groups::               
-* Graphics Toolkits::           
+* Object Groups::
+* Graphics Toolkits::
 @end menu
 
 
@@ -2544,9 +2542,9 @@
 @cindex colors, graphics
 
 Colors may be specified as RGB triplets with values ranging from zero to
-one, or by name.  Recognized color names include @code{"blue"},
-@code{"black"}, @code{"cyan"}, @code{"green"}, @code{"magenta"},
-@code{"red"}, @code{"white"}, and @code{"yellow"}.
+one, or by name.  Recognized color names include @qcode{"blue"},
+@qcode{"black"}, @qcode{"cyan"}, @qcode{"green"}, @qcode{"magenta"},
+@qcode{"red"}, @qcode{"white"}, and @qcode{"yellow"}.
 
 @node Line Styles
 @subsection Line Styles
@@ -2572,7 +2570,7 @@
 @item "-."
 A dash-dot line.
 
-@item "none"
+@item @qcode{"none"}
 No line.  Points will still be marked using the current Marker Style.
 @end table
 
@@ -2591,14 +2589,14 @@
 @table @code
 @item marker
 A character indicating a plot marker to be place at each data point, or
-@code{"none"}, meaning no markers should be displayed.
+@qcode{"none"}, meaning no markers should be displayed.
 
 @item markeredgecolor
-The color of the edge around the marker, or @code{"auto"}, meaning that
+The color of the edge around the marker, or @qcode{"auto"}, meaning that
 the edge color is the same as the face color.  @xref{Colors}.
 
 @item markerfacecolor
-The color of the marker, or @code{"none"} to indicate that the marker
+The color of the marker, or @qcode{"none"} to indicate that the marker
 should not be filled.  @xref{Colors}.
 
 @item markersize
@@ -2686,7 +2684,7 @@
 function described below.
 
 @node Application-defined Data
-@subsection Application-defined Data 
+@subsection Application-defined Data
 @cindex application-defined data
 
 Octave has a provision for attaching application-defined data to a graphics
@@ -2829,17 +2827,17 @@
 corresponding hggroup elements.
 
 @menu
-* Data Sources in Object Groups::  
-* Area Series::                 
-* Bar Series::                  
-* Contour Groups::              
-* Error Bar Series::            
-* Line Series::                 
-* Quiver Group::                
-* Scatter Group::               
-* Stair Group::                 
-* Stem Series::                 
-* Surface Group::               
+* Data Sources in Object Groups::
+* Area Series::
+* Bar Series::
+* Contour Groups::
+* Error Bar Series::
+* Line Series::
+* Quiver Group::
+* Scatter Group::
+* Stair Group::
+* Stem Series::
+* Surface Group::
 @end menu
 
 @node Data Sources in Object Groups
@@ -2871,23 +2869,23 @@
 @item basevalue
 The value where the base of the area plot is drawn.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the edge of the patch objects making up the
 areas.  @xref{Line Styles}.
 
-@item edgecolor
+@item  edgecolor
 @itemx facecolor
 The line and fill color of the patch objects making up the areas. 
 @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 The x and y coordinates of the original columns of the data passed to
 @code{area} prior to the cumulative summation used in the @code{area}
 function.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 Data source variables.
 @end table
@@ -2902,12 +2900,12 @@
 The properties of the bar series are
 
 @table @code
-@item showbaseline
+@item  showbaseline
 @itemx baseline
 @itemx basevalue
 The property @code{showbaseline} flags whether the baseline of the bar
-series is displayed (default is "on").  The handle of the graphics object
-representing the baseline is given by the @code{baseline} property and
+series is displayed (default is @qcode{"on"}).  The handle of the graphics
+object representing the baseline is given by the @code{baseline} property and
 the y-value of the baseline by the @code{basevalue} property.
 
 Changes to any of these property are propagated to the other members of
@@ -2915,24 +2913,24 @@
 properties of the base line itself are propagated to the members of the
 corresponding bar series.
 
-@item barwidth
+@item  barwidth
 @itemx barlayout
 @itemx horizontal
 The property @code{barwidth} is the width of the bar corresponding to
 the @var{width} variable passed to @code{bar} or @var{barh}.  Whether the
-bar series is "grouped" or "stacked" is determined by the
+bar series is @qcode{"grouped"} or @qcode{"stacked"} is determined by the
 @code{barlayout} property and whether the bars are horizontal or
 vertical by the @code{horizontal} property.
 
 Changes to any of these property are propagated to the other members of
 the bar series.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the edge of the patch objects making up the
 bars.  @xref{Line Styles}.
 
-@item edgecolor
+@item  edgecolor
 @itemx facecolor
 The line and fill color of the patch objects making up the bars.  @xref{Colors}.
 
@@ -2943,7 +2941,7 @@
 @item ydata
 The y value of the bars in the @code{hggroup}.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 Data source variables.
 @end table
@@ -2964,37 +2962,37 @@
 create the contours of the plot.
 
 @item fill
-A radio property that can have the values "on" or "off" that flags whether the
-contours to plot are to be filled.
-
-@item zlevelmode
+A radio property that can have the values @qcode{"on"} or @qcode{"off"} that
+flags whether the contours to plot are to be filled.
+
+@item  zlevelmode
 @itemx zlevel
-The radio property @code{zlevelmode} can have the values "none", "auto" or
-"manual".  When its value is "none" there is no z component to the plotted
-contours.  When its value is "auto" the z value of the plotted contours is
-at the same value as the contour itself.  If the value is "manual", then the
-z value at which to plot the contour is determined by the @code{zlevel}
-property.
-
-@item levellistmode
+The radio property @code{zlevelmode} can have the values @qcode{"none"},
+@qcode{"auto"}, or @qcode{"manual"}.  When its value is @qcode{"none"} there is
+no z component to the plotted contours.  When its value is @qcode{"auto"} the z
+value of the plotted contours is at the same value as the contour itself.  If
+the value is @qcode{"manual"}, then the z value at which to plot the contour is
+determined by the @code{zlevel} property.
+
+@item  levellistmode
 @itemx levellist
 @itemx levelstepmode
 @itemx levelstep
-If @code{levellistmode} is "manual", then the levels at which to plot the
-contours is determined by @code{levellist}.  If @code{levellistmode} is
-set to "auto", then the distance between contours is determined by
-@code{levelstep}.  If both @code{levellistmode} and @code{levelstepmode}
-are set to "auto", then there are assumed to be 10 equal spaced contours.
-
-@item textlistmode
+If @code{levellistmode} is @qcode{"manual"}, then the levels at which to plot
+the contours is determined by @code{levellist}.  If @code{levellistmode} is set
+to @qcode{"auto"}, then the distance between contours is determined by
+@code{levelstep}.  If both @code{levellistmode} and @code{levelstepmode} are
+set to @qcode{"auto"}, then there are assumed to be 10 equal spaced contours.
+
+@item  textlistmode
 @itemx textlist
 @itemx textstepmode
 @itemx textstep
-If @code{textlistmode} is "manual", then the labeled contours
+If @code{textlistmode} is @qcode{"manual"}, then the labeled contours
 is determined by @code{textlist}.  If @code{textlistmode} is set to
-"auto", then the distance between labeled contours is determined by
+@qcode{"auto"}, then the distance between labeled contours is determined by
 @code{textstep}.  If both @code{textlistmode} and @code{textstepmode}
-are set to "auto", then there are assumed to be 10 equal spaced
+are set to @qcode{"auto"}, then there are assumed to be 10 equal spaced
 labeled contours.
 
 @item showtext
@@ -3011,16 +3009,16 @@
 The properties of the contour lines.  The properties @code{linewidth} and
 @code{linestyle} are similar to the corresponding properties for lines.  The
 property @code{linecolor} is a color property (@pxref{Colors}), that can also
-have the values of "none" or "auto".  If @code{linecolor} is "none", then no
-contour line is drawn.  If @code{linecolor} is "auto" then the line color is
-determined by the colormap.
-
-@item xdata
+have the values of @qcode{"none"} or @qcode{"auto"}.  If @code{linecolor} is
+@qcode{"none"}, then no contour line is drawn.  If @code{linecolor} is
+@qcode{"auto"} then the line color is determined by the colormap.
+
+@item  xdata
 @itemx ydata
 @itemx zdata
 The original x, y, and z data of the contour lines.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 Data source variables.
@@ -3040,18 +3038,18 @@
 The RGB color or color name of the line objects of the error bars. 
 @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the line objects of the error bars.  @xref{Line
 Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the markers on the error bars.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx ldata
 @itemx udata
@@ -3059,7 +3057,7 @@
 @itemx xudata
 The original x, y, l, u, xl, xu data of the error bars.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx ldatasource
 @itemx udatasource
@@ -3081,22 +3079,22 @@
 @item color
 The RGB color or color name of the line objects.  @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the line objects.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the markers.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx zdata
 The original x, y and z data.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 Data source variables.
@@ -3114,7 +3112,7 @@
 properties of the quiver series are
 
 @table @code
-@item autoscale
+@item  autoscale
 @itemx autoscalefactor
 Flag whether the length of the arrows is scaled or defined directly from
 the @var{u}, @var{v} and @var{w} data.  If the arrow length is flagged
@@ -3131,27 +3129,27 @@
 @item color
 The RGB color or color name of the line objects of the quiver.  @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the line objects of the quiver.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the marker objects at the original of the
 arrows.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx zdata
 The origins of the values of the vector field.
 
-@item udata
+@item  udata
 @itemx vdata
 @itemx wdata
 The values of the vector field to plot.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 @itemx udatasource
@@ -3174,12 +3172,12 @@
 @item linewidth
 The line width of the line objects of the points.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 The line and fill color of the markers of the points.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx zdata
 The original x, y and z data of the stems.
@@ -3192,7 +3190,7 @@
 The size data for the points of the plot.  Each point can its own size or a
 unique size can be specified.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 @itemx cdatasource
@@ -3213,21 +3211,21 @@
 @item color
 The RGB color or color name of the line objects of the stairs.  @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the line objects of the stairs.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the markers on the stairs.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 The original x and y data of the stairs.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 Data source variables.
 @end table
@@ -3243,11 +3241,11 @@
 are
 
 @table @code
-@item showbaseline
+@item  showbaseline
 @itemx baseline
 @itemx basevalue
 The property @code{showbaseline} flags whether the baseline of the
-stem series is displayed (default is "on").  The handle of the graphics
+stem series is displayed (default is @qcode{"on"}).  The handle of the graphics
 object representing the baseline is given by the @code{baseline}
 property and the y-value (or z-value for @code{stem3}) of the baseline
 by the @code{basevalue} property.
@@ -3260,22 +3258,22 @@
 @item color
 The RGB color or color name of the line objects of the stems.  @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the line objects of the stems.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the markers on the stems.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx zdata
 The original x, y and z data of the stems.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 Data source variables.
@@ -3299,23 +3297,23 @@
 The RGB color or color name of the edges or faces of the surface. 
 @xref{Colors}.
 
-@item linewidth
+@item  linewidth
 @itemx linestyle
 The line width and style of the lines on the surface.  @xref{Line Styles}.
 
-@item marker
+@item  marker
 @itemx markeredgecolor
 @itemx markerfacecolor
 @itemx markersize
 The line and fill color of the markers on the surface.  @xref{Colors}.
 
-@item xdata
+@item  xdata
 @itemx ydata
 @itemx zdata
 @itemx cdata
 The original x, y, z and c data.
 
-@item xdatasource
+@item  xdatasource
 @itemx ydatasource
 @itemx zdatasource
 @itemx cdatasource
@@ -3336,7 +3334,7 @@
 @DOCSTRING(register_graphics_toolkit)
 
 @menu
-* Customizing Toolkit Behavior::    
+* Customizing Toolkit Behavior::
 @end menu
 
 @node Customizing Toolkit Behavior
--- a/doc/interpreter/plotimages.m
+++ b/doc/interpreter/plotimages.m
@@ -34,10 +34,16 @@
   elseif (strcmp (nm, "plot"))
     x = -10:0.1:10;
     plot (x, sin (x));
+    xlabel ("x");
+    ylabel ("sin (x)");
+    title ("Simple 2-D Plot");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "hist"))
     rand ("state", 2);
     hist (randn (10000, 1), 30);
+    xlabel ("Value");
+    ylabel ("Count");
+    title ("Histogram of 10,000 normally distributed random numbers");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "errorbar"))
     rand ("state", 2);
@@ -47,9 +53,13 @@
     yu = 0.1 .* rand (size (x));
     errorbar (x, sin (x), yl, yu);
     axis ([0, 10, -1.1, 1.1]);
+    xlabel ("x");
+    ylabel ("sin (x)");
+    title ("Errorbar plot of sin (x)");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "polar"))
     polar (0:0.1:10*pi, 0:0.1:10*pi);
+    title ("Example polar plot from 0 to 10*pi");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "mesh"))
     tx = ty = linspace (-8, 8, 41)';
@@ -57,21 +67,32 @@
     r = sqrt (xx .^ 2 + yy .^ 2) + eps;
     tz = sin (r) ./ r;
     mesh (tx, ty, tz);
+    xlabel ("tx");
+    ylabel ("ty");
+    zlabel ("tz");
+    title ("3-D Sombrero plot");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "plot3"))
     t = 0:0.1:10*pi;
     r = linspace (0, 1, numel (t));
     z = linspace (0, 1, numel (t));
     plot3 (r.*sin(t), r.*cos(t), z);
+    xlabel ("r.*sin (t)");
+    ylabel ("r.*cos (t)");
+    zlabel ("z");
+    title ("plot3 display of 3-D helix");
     print ([nm "." typ], d_typ);
   elseif (strcmp (nm, "extended"))
     x = 0:0.01:3;
-    plot(x,erf(x));
+    plot (x,erf(x));
     hold on;
-    plot(x,x,"r");
-    axis([0, 3, 0, 1]);
-    text(0.65, 0.6175, ['\leftarrow x = {2/\surd\pi {\fontsize{16}', ...
-      '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175']);
+    plot (x,x,"r");
+    axis ([0, 3, 0, 1]);
+    text (0.65, 0.6175, ['\leftarrow x = {2/\surd\pi {\fontsize{16}' ...
+          '\int_{\fontsize{8}0}^{\fontsize{8}x}} e^{-t^2} dt} = 0.6175']);
+    xlabel ("x");
+    ylabel ("erf (x)");
+    title ("erf (x) with text annotation");
     print ([nm "." typ], d_typ);
   else
     error ("unrecognized plot requested");
--- a/doc/interpreter/preface.txi
+++ b/doc/interpreter/preface.txi
@@ -63,10 +63,10 @@
 you may have.
 
 @menu
-* Acknowledgements::            
+* Acknowledgements::
 * Citing Octave in Publications::
-* How You Can Contribute to Octave::  
-* Distribution::                
+* How You Can Contribute to Octave::
+* Distribution::
 @end menu
 
 @node Acknowledgements
--- a/doc/interpreter/quad.txi
+++ b/doc/interpreter/quad.txi
@@ -24,9 +24,9 @@
 1-dimensional integration problems.
 
 @menu
-* Functions of One Variable:: 
-* Orthogonal Collocation::      
-* Functions of Multiple Variables:: 
+* Functions of One Variable::
+* Orthogonal Collocation::
+* Functions of Multiple Variables::
 @end menu
 
 @node Functions of One Variable
@@ -134,9 +134,10 @@
 is reasonably accurate (to see why, examine what happens to the result
 if you move the lower bound to 0.1, then 0.01, then 0.001, etc.).
 
-The function "f" can be the string name of a function, a function handle, or
-an inline function.  These options make it quite easy to do integration
-without having to fully define a function in an m-file.  For example:
+The function @qcode{"f"} can be the string name of a function, a function
+handle, or an inline function.  These options make it quite easy to do
+integration without having to fully define a function in an m-file.  For
+example:
 
 @example
 @group
--- a/doc/interpreter/signal.txi
+++ b/doc/interpreter/signal.txi
@@ -19,18 +19,23 @@
 @node Signal Processing
 @chapter Signal Processing
 
-
 This chapter describes the signal processing and fast Fourier
 transform functions available in Octave.  Fast Fourier transforms are
 computed with the @sc{fftw} or @sc{fftpack} libraries depending on how
 Octave is built.
- 
-
-
-@DOCSTRING(detrend)
 
 @DOCSTRING(fft)
 
+@DOCSTRING(ifft)
+
+@DOCSTRING(fft2)
+
+@DOCSTRING(ifft2)
+
+@DOCSTRING(fftn)
+
+@DOCSTRING(ifftn)
+
 Octave uses the @sc{fftw} libraries to perform FFT computations.  When Octave
 starts up and initializes the @sc{fftw} libraries, they read a system wide
 file (on a Unix system, it is typically @file{/etc/fftw/wisdom}) that
@@ -45,16 +50,6 @@
 
 @DOCSTRING(fftw)
 
-@DOCSTRING(ifft)
-
-@DOCSTRING(fft2)
-
-@DOCSTRING(ifft2)
-
-@DOCSTRING(fftn)
-
-@DOCSTRING(ifftn)
-
 @DOCSTRING(fftconv)
 
 @DOCSTRING(fftfilt)
@@ -71,7 +66,7 @@
 
 @DOCSTRING(unwrap)
 
-@c FIXME -- someone needs to organize these...
+@c FIXME: someone needs to organize these ...
 
 @DOCSTRING(arch_fit)
 
@@ -87,6 +82,8 @@
 
 @DOCSTRING(blackman)
 
+@DOCSTRING(detrend)
+
 @DOCSTRING(diffpara)
 
 @DOCSTRING(durbinlevinson)
@@ -107,10 +104,6 @@
 
 @DOCSTRING(periodogram)
 
-@DOCSTRING(rectangle_lw)
-
-@DOCSTRING(rectangle_sw)
-
 @DOCSTRING(sinetone)
 
 @DOCSTRING(sinewave)
@@ -125,8 +118,5 @@
 
 @DOCSTRING(synthesis)
 
-@DOCSTRING(triangle_lw)
+@DOCSTRING(yulewalker)
 
-@DOCSTRING(triangle_sw)
-
-@DOCSTRING(yulewalker)
--- a/doc/interpreter/sparse.txi
+++ b/doc/interpreter/sparse.txi
@@ -23,7 +23,7 @@
 @set htmltex
 @end iftex
 
-@node Sparse Matrices 
+@node Sparse Matrices
 @chapter Sparse Matrices
 
 @menu
@@ -34,7 +34,7 @@
 @end menu
 
 @node Basics
-@section The Creation and Manipulation of Sparse Matrices
+@section Creation and Manipulation of Sparse Matrices
 
 The size of mathematical problems that can be treated at any particular
 time is generally limited by the available computing resources.  Both,
@@ -308,10 +308,10 @@
 The above problem of memory reallocation can be avoided in
 oct-files.  However, the construction of a sparse matrix from an oct-file
 is more complex than can be discussed here.  @xref{External Code Interface},
-for a a full description of the techniques involved.
+for a full description of the techniques involved.
 
 @node Information
-@subsection Finding out Information about Sparse Matrices
+@subsection Finding Information about Sparse Matrices
 
 There are a number of functions that allow information concerning
 sparse matrices to be obtained.  The most basic of these is
@@ -442,9 +442,9 @@
 @subsection Basic Operators and Functions on Sparse Matrices
 
 @menu
-* Sparse Functions::            
-* Return Types of Operators and Functions::  
-* Mathematical Considerations::  
+* Sparse Functions::
+* Return Types of Operators and Functions::
+* Mathematical Considerations::
 @end menu
 
 @node Sparse Functions
@@ -504,7 +504,7 @@
 details.
 
 @node Return Types of Operators and Functions
-@subsubsection The Return Types of Operators and Functions
+@subsubsection Return Types of Operators and Functions
 
 The two basic reasons to use sparse matrices are to reduce the memory 
 usage and to not have to do calculations on zero elements.  The two are
@@ -573,8 +573,8 @@
 same manner as there full counterparts.  However, there are certain differences
 and especially differences with other products sparse implementations.
 
-Firstly, the "./" and ".^" operators must be used with care.  Consider what
-the examples
+Firstly, the @qcode{"./"} and @qcode{".^"} operators must be used with care. 
+Consider what the examples
 
 @example
 @group
@@ -855,7 +855,7 @@
 @DOCSTRING(svds)
 
 @node Iterative Techniques
-@section Iterative Techniques applied to sparse matrices
+@section Iterative Techniques Applied to Sparse Matrices
 
 The left division @code{\} and right division @code{/} operators,
 discussed in the previous section, use direct solvers to resolve a
@@ -876,7 +876,7 @@
 @DOCSTRING(luinc)
 
 @node Real Life Example
-@section Real Life Example of the use of Sparse Matrices
+@section Real Life Example using Sparse Matrices
 
 A common application for sparse matrices is in the solution of Finite
 Element Models.  Finite element models allow numerical solution of
--- a/doc/interpreter/stats.txi
+++ b/doc/interpreter/stats.txi
@@ -47,12 +47,12 @@
 
 @menu
 * Descriptive Statistics::
-* Basic Statistical Functions:: 
-* Statistical Plots:: 
-* Correlation and Regression Analysis::                      
-* Distributions::     
-* Tests::                       
-* Random Number Generation::          
+* Basic Statistical Functions::
+* Statistical Plots::
+* Correlation and Regression Analysis::
+* Distributions::
+* Tests::
+* Random Number Generation::
 @end menu
 
 @node Descriptive Statistics
--- a/doc/interpreter/stmt.txi
+++ b/doc/interpreter/stmt.txi
@@ -46,16 +46,16 @@
 @dfn{body} of a control statement.
 
 @menu
-* The if Statement::            
-* The switch Statement::        
-* The while Statement::         
-* The do-until Statement::      
-* The for Statement::           
-* The break Statement::         
-* The continue Statement::      
-* The unwind_protect Statement::  
-* The try Statement::           
-* Continuation Lines::          
+* The if Statement::
+* The switch Statement::
+* The while Statement::
+* The do-until Statement::
+* The for Statement::
+* The break Statement::
+* The continue Statement::
+* The unwind_protect Statement::
+* The try Statement::
+* Continuation Lines::
 @end menu
 
 @node The if Statement
@@ -328,7 +328,7 @@
 @end example
 
 @menu
-* Notes for the C Programmer::  
+* Notes for the C Programmer::
 @end menu
 
 @node Notes for the C Programmer
@@ -601,7 +601,7 @@
 something to do inside the loop.
 
 @menu
-* Looping Over Structure Elements::  
+* Looping Over Structure Elements::
 @end menu
 
 @node Looping Over Structure Elements
@@ -850,50 +850,55 @@
 @var{catch} statements are evaluated.  @xref{Errors and Warnings}, for more
 information about the @code{lasterr} function.
 
+@node Continuation Lines
+@section Continuation Lines
 @cindex continuation lines
 @cindex @code{...} continuation marker
 @cindex @code{\} continuation marker
 
-@node Continuation Lines
-@section Continuation Lines
-
 In the Octave language, most statements end with a newline character and
 you must tell Octave to ignore the newline character in order to
 continue a statement from one line to the next.  Lines that end with the
-characters @code{...} or @code{\} are joined with the following line
-before they are divided into tokens by Octave's parser.  For example,
-the lines
+characters @code{...} are joined with the following line before they are
+divided into tokens by Octave's parser.  For example, the lines
 
 @example
 @group
 x = long_variable_name ...
-    + longer_variable_name \
+    + longer_variable_name ...
     - 42
 @end group
 @end example
 
 @noindent
-form a single statement.  The backslash character on the second line
-above is interpreted as a continuation character, @emph{not} as a division
-operator.
+form a single statement.
 
-For continuation lines that do not occur inside string constants,
-whitespace and comments may appear between the continuation marker and
-the newline character.  For example, the statement
+Any text between the continuation marker and the newline character is
+ignored.  For example, the statement
 
 @example
 @group
-x = long_variable_name ...     # comment one
-    + longer_variable_name \   # comment two
-    - 42                       # last comment
+x = long_variable_name ...    # comment one
+    + longer_variable_name ...comment two
+    - 42                      # last comment
 @end group
 @end example
 
 @noindent
-is equivalent to the one shown above.  Inside string constants, the
-continuation marker must appear at the end of the line just before the
-newline character.
+is equivalent to the one shown above.
+
+Inside double-quoted string constants, the character @code{\} has to be
+used as continuation marker.  The @code{\} must appear at the end of the
+line just before the newline character:
 
+@example
+@group
+s = "This text starts in the first line \
+and is continued in the second line."
+@end group
+@end example
+
+@noindent
 Input that occurs inside parentheses can be continued to the next line
 without having to use a continuation marker.  For example, it is
 possible to write statements like
--- a/doc/interpreter/strings.txi
+++ b/doc/interpreter/strings.txi
@@ -56,11 +56,11 @@
 @menu
 * Escape Sequences in String Constants::
 * Character Arrays::
-* Creating Strings:: 
-* Comparing Strings::           
-* Manipulating Strings::     
-* String Conversions::          
-* Character Class Functions::   
+* Creating Strings::
+* Comparing Strings::
+* Manipulating Strings::
+* String Conversions::
+* Character Class Functions::
 @end menu
 
 @node Escape Sequences in String Constants
@@ -119,21 +119,17 @@
 @item \v
 Represents a vertical tab, control-k, ASCII code 11.
 
-@c We don't do octal or hex this way yet.
-@c
-@c @item \@var{nnn}
-@c Represents the octal value @var{nnn}, where @var{nnn} are one to three
-@c digits between 0 and 7.  For example, the code for the ASCII ESC
-@c (escape) character is @samp{\033}.@refill
-@c 
-@c @item \x@var{hh}@dots{}
-@c Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal
-@c digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or
-@c @samp{a} through @samp{f}).  Like the same construct in @sc{ansi} C,
-@c the escape 
-@c sequence continues until the first non-hexadecimal digit is seen.  However,
-@c using more than two hexadecimal digits produces undefined results.  (The
-@c @samp{\x} escape sequence is not allowed in @sc{posix} @code{awk}.)@refill
+@item \@var{nnn}
+Represents the octal value @var{nnn}, where @var{nnn} are one to three
+digits between 0 and 7.  For example, the code for the ASCII ESC
+(escape) character is @samp{\033}.
+
+@item \x@var{hh}@dots{}
+Represents the hexadecimal value @var{hh}, where @var{hh} are hexadecimal
+digits (@samp{0} through @samp{9} and either @samp{A} through @samp{F} or
+@samp{a} through @samp{f}).  Like the same construct in @sc{ansi} C,
+the escape sequence continues until the first non-hexadecimal digit is seen.
+However, using more than two hexadecimal digits produces undefined results.
 @end table
 
 In a single-quoted string there is only one escape sequence: you may insert a
@@ -158,13 +154,13 @@
 @section Character Arrays
 
 The string representation used by Octave is an array of characters, so
-internally the string @nospell{"dddddddddd"} is actually a row vector of length
-10 containing the value 100 in all places (100 is the ASCII code of "d").  This
-lends itself to the obvious generalization to character matrices.  Using a
-matrix of characters, it is possible to represent a collection of same-length
-strings in one variable.  The convention used in Octave is that each row in a
-character matrix is a separate string, but letting each column represent a
-string is equally possible.
+internally the string @nospell{@qcode{"dddddddddd"}} is actually a row vector
+of length 10 containing the value 100 in all places (100 is the ASCII code of
+@qcode{"d"}).  This lends itself to the obvious generalization to character
+matrices.  Using a matrix of characters, it is possible to represent a
+collection of same-length strings in one variable.  The convention used in
+Octave is that each row in a character matrix is a separate string, but letting
+each column represent a string is equally possible.
 
 The easiest way to create a character matrix is to put several strings
 together into a matrix.
@@ -222,8 +218,8 @@
 @DOCSTRING(blanks)
 
 @menu
-* Concatenating Strings:: 
-* Conversion of Numerical Data to Strings::
+* Concatenating Strings::
+* Converting Numerical Data to Strings::
 @end menu
 
 @node Concatenating Strings
@@ -292,8 +288,8 @@
 char ("orange", "green", "", "red")
     @result{} orange
        green 
-             
-       red   
+
+       red
 @end group
 
 @group
@@ -335,7 +331,7 @@
 @example
 @group
 strcat (["dir1";"directory2"], ["/";"/"], ["file1";"file2"])
-     @result{} dir1/file1      
+     @result{} dir1/file1
         directory2/file2
 @end group
 @group
@@ -359,8 +355,8 @@
 
 @DOCSTRING(cstrcat)
 
-@node Conversion of Numerical Data to Strings 
-@subsection Conversion of Numerical Data to Strings
+@node Converting Numerical Data to Strings
+@subsection Converting Numerical Data to Strings
 Apart from the string concatenation functions (@pxref{Concatenating Strings})
 which cast numerical data to the corresponding ASCII characters, there are
 several functions that format numerical data as strings.  @code{mat2str} and
--- a/doc/interpreter/system.txi
+++ b/doc/interpreter/system.txi
@@ -26,17 +26,17 @@
 and even start other programs from the Octave prompt.
 
 @menu
-* Timing Utilities::            
-* Filesystem Utilities::        
+* Timing Utilities::
+* Filesystem Utilities::
 * File Archiving Utilities::
 * Networking Utilities::
-* Controlling Subprocesses::    
-* Process ID Information::      
-* Environment Variables::       
-* Current Working Directory::   
-* Password Database Functions::  
-* Group Database Functions::    
-* System Information::          
+* Controlling Subprocesses::
+* Process ID Information::
+* Environment Variables::
+* Current Working Directory::
+* Password Database Functions::
+* Group Database Functions::
+* System Information::
 * Hashing Functions::
 @end menu
 
@@ -491,7 +491,7 @@
 @DOCSTRING(getgrent)
 
 @DOCSTRING(getgrgid)
-         
+
 @DOCSTRING(getgrnam)
 
 @DOCSTRING(setgrent)
--- a/doc/interpreter/tips.txi
+++ b/doc/interpreter/tips.txi
@@ -352,7 +352,7 @@
 Help text in Texinfo format.  Code samples should be marked 
 like @@code@{sample of code@} and variables should be marked
 as @@var@{variable@}.
-@@seealso@{fn2@}
+@@seealso@{fn2, fn3@}
 @@end deftypefn
 @end group
 @end example
@@ -385,7 +385,13 @@
 All samples of code should be marked with this macro for the same
 reasons as the @@var macro.
 
-@item @@seealso@{function2@}
+@item  @nospell{@@qcode@{"sample_code"@}}
+@itemx @nospell{@@qcode@{'sample_code'@}}
+All samples of code which are quoted should use this more specialized macro.
+This happens frequently when discussing graphics properties such as "position"
+or options such as "on"/"off".
+
+@item @@seealso@{function2, function3@}
 This is a comma separated list of function names that allows cross
 referencing from one function documentation string to another.
 @end table
@@ -467,8 +473,8 @@
 The @code{@@group} block prevents the example from being split across a
 page boundary, while the @code{@@result@{@}} macro produces a right
 arrow signifying the result of a command.  If your example is larger than
-20 lines it is better NOT to use grouping so that a reasonable page boundary
-can be calculated.
+20 lines it is better @emph{NOT} to use grouping so that a reasonable page
+boundary can be calculated.
 
 In many cases a function has multiple ways in which it can be called,
 and the @code{@@deftypefnx} macro can be used to give alternatives.  For
@@ -556,14 +562,15 @@
 @@seealso@{bincoeff, perms@}
 @@end deftypefn
 @end example
+
 @noindent
 which demonstrates most of the concepts discussed above.
 @iftex
 This documentation string renders as
-
 @c Note: use the actual output of info below, rather than try and 
 @c reproduce it here to prevent it looking different from how it would
 @c appear with info.
+
 @example
  -- Function File: C = nchoosek (N, K)
  -- Function File: C = nchoosek (SET, K)
--- a/doc/interpreter/var.txi
+++ b/doc/interpreter/var.txi
@@ -72,9 +72,9 @@
 @DOCSTRING(namelengthmax)
 
 @menu
-* Global Variables::            
-* Persistent Variables::        
-* Status of Variables::         
+* Global Variables::
+* Persistent Variables::
+* Status of Variables::
 @end menu
 
 @node Global Variables
--- a/doc/interpreter/vectorize.txi
+++ b/doc/interpreter/vectorize.txi
@@ -606,7 +606,7 @@
 @group
 a = zeros (1000); # create a 1000x1000 matrix
 b = a(:,10:100);  # lazy slice
-a = []; # the original a array is still allocated
+a = []; # the original "a" array is still allocated
 c@{1@} = b; # b is reallocated at this point
 @end group
 @end example
@@ -674,7 +674,7 @@
 @item Use @code{ignore_function_time_stamp} when appropriate.
 If you are calling lots of functions, and none of them will need to change
 during your run, set the variable @code{ignore_function_time_stamp} to
-@code{"all"}.  This will stop Octave from checking the time stamp of a function
+@qcode{"all"}.  This will stop Octave from checking the time stamp of a function
 file to see if it has been updated while the program is being run.
 @end itemize
 
--- a/etc/OLD-ChangeLogs/scripts-ChangeLog
+++ b/etc/OLD-ChangeLogs/scripts-ChangeLog
@@ -6297,7 +6297,7 @@
 
 	* plot/grid.m: Document handle argument.
 
-2009-01-15  Peter L. S�ndergaard  <peter@sonderport.dk>
+2009-01-15  Peter L. Søndergaard  <peter@sonderport.dk>
 
 	* general/nargoutchk.m: Doc fix.
 	* general/nargchk.m: Improve compatibility.  New tests.
@@ -6503,7 +6503,7 @@
 	systems. Simplify & fix indexing. Use left division for step problem.
 	Fix output args.
 
-2008-12-13  Francesco Potort�  <pot@gnu.org>
+2008-12-13  Francesco Potortì  <pot@gnu.org>
 
 	* specfun/nchoosek.m: Check for input arguments, signal loss of
 	precision, correctly handle k==0 and k==n cases, add proper tests.
@@ -6592,7 +6592,7 @@
 2008-11-10  John W. Eaton  <jwe@octave.org>
 
 	* polynomial/spline.m: Delete debugging statements.  From
-	Sebastian Sch�ps <sebastian@schoeps.org>.
+	Sebastian Schöps <sebastian@schoeps.org>.
 
 2008-11-07  Thorsten Meyer  <thorsten.meyier@gmx.de>
 
--- a/examples/mysparse.c
+++ b/examples/mysparse.c
@@ -11,14 +11,14 @@
   double *pr2, *pi2;
   mwIndex *ir, *jc;
   mwIndex *ir2, *jc2;
-  
+
   if (nrhs != 1 || ! mxIsSparse (prhs[0]))
     mexErrMsgTxt ("ARG1 must be a sparse matrix");
 
   m = mxGetM (prhs[0]);
   n = mxGetN (prhs[0]);
   nz = mxGetNzmax (prhs[0]);
-  
+
   if (mxIsComplex (prhs[0]))
     {
       mexPrintf ("Matrix is %d-by-%d complex sparse matrix", m, n);
@@ -40,7 +40,7 @@
       pi2 = mxGetPi (v);
       ir2 = mxGetIr (v);
       jc2 = mxGetJc (v);
-      
+
       for (i = 0; i < nz; i++)
         {
           pr2[i] = 2 * pr[i];
@@ -72,7 +72,7 @@
       pbr2 = mxGetLogicals (v);
       ir2 = mxGetIr (v);
       jc2 = mxGetJc (v);
-      
+
       for (i = 0; i < nz; i++)
         {
           pbr2[i] = pbr[i];
@@ -102,7 +102,7 @@
       pr2 = mxGetPr (v);
       ir2 = mxGetIr (v);
       jc2 = mxGetJc (v);
-      
+
       for (i = 0; i < nz; i++)
         {
           pr2[i] = 2 * pr[i];
--- a/libgui/Makefile.am
+++ b/libgui/Makefile.am
@@ -20,8 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-AUTOMAKE_OPTIONS = subdir-objects
-
 MOC_CPPFLAGS =
 
 octlib_LTLIBRARIES = liboctgui.la
@@ -109,5 +107,6 @@
 	$(LRELEASE) -qm $@ $<
 
 DISTCLEANFILES = \
+  default-qt-settings \
   $(LOCALES)
 
--- a/libgui/languages/de_DE.ts
+++ b/libgui/languages/de_DE.ts
@@ -83,7 +83,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1451"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1527"/>
         <source>copied selection to clipboard</source>
         <translation>Auswahl in die Zwischenablage kopiert</translation>
     </message>
@@ -104,19 +104,19 @@
 <context>
     <name>file_editor</name>
     <message>
-        <location filename="../src/m-editor/file-editor.cc" line="+294"/>
+        <location filename="../src/m-editor/file-editor.cc" line="+300"/>
         <location line="+49"/>
         <location line="+28"/>
         <source>Octave Editor</source>
         <translation>Octave Editor</translation>
     </message>
     <message>
-        <location line="-193"/>
+        <location line="-199"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Octave Dateien (*.m);;Alle Dateien (*)</translation>
     </message>
     <message>
-        <location line="+117"/>
+        <location line="+123"/>
         <source>Could not open file %1 for read:
 %2.</source>
         <translation>Kann die Datei &lt;b&gt;%1&lt;/b&gt; nicht zum Lesen öffnen:
@@ -142,7 +142,7 @@
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+159"/>
+        <location line="+160"/>
         <source>&amp;New File</source>
         <translation>&amp;Neue Datei</translation>
     </message>
@@ -157,12 +157,12 @@
         <translation>Datei &amp;speichern</translation>
     </message>
     <message>
-        <location line="+4"/>
+        <location line="+3"/>
         <source>Save File &amp;As</source>
         <translation>Datei speichern &amp;als</translation>
     </message>
     <message>
-        <location line="+4"/>
+        <location line="+3"/>
         <source>Print</source>
         <translation>Drucken</translation>
     </message>
@@ -192,17 +192,17 @@
         <translation>Einfügen</translation>
     </message>
     <message>
-        <location line="+3"/>
+        <location line="+2"/>
         <source>&amp;Next Bookmark</source>
         <translation>&amp;Nächstes Lesezeichen</translation>
     </message>
     <message>
-        <location line="+3"/>
+        <location line="+2"/>
         <source>Pre&amp;vious Bookmark</source>
         <translation>&amp;Voriges Lesezeichen</translation>
     </message>
     <message>
-        <location line="+3"/>
+        <location line="+2"/>
         <source>Toggle &amp;Bookmark</source>
         <translation>&amp;Lesezeichen setzen</translation>
     </message>
@@ -242,34 +242,34 @@
         <translation>Kommentar &amp;entfernen</translation>
     </message>
     <message>
-        <location line="+73"/>
+        <location line="+63"/>
         <source>&amp;Recent Editor Files</source>
         <translation>&amp;Zuletzt bearbeitete Dateien</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+16"/>
         <source>&amp;Close</source>
         <translation>S&amp;chließen</translation>
     </message>
     <message>
-        <location line="+5"/>
+        <location line="+4"/>
         <source>Close All</source>
         <translation>Alle schließen</translation>
     </message>
     <message>
-        <location line="+4"/>
+        <location line="+5"/>
         <source>Close Other Files</source>
         <translation>Andere Dokumente schließen</translation>
     </message>
     <message>
-        <location line="-94"/>
+        <location line="-85"/>
         <source>&amp;Find and Replace</source>
         <translation>&amp;Suchen und Ersetzen</translation>
     </message>
     <message>
         <location line="+3"/>
         <source>Save File And Run</source>
-        <translation>Datei speichern und ausrühren</translation>
+        <translation>Datei speichern und ausführen</translation>
     </message>
     <message>
         <location line="+2"/>
@@ -277,12 +277,12 @@
         <translation>&amp;Gehe zu Zeile</translation>
     </message>
     <message>
-        <location line="+63"/>
+        <location line="+53"/>
         <source>&amp;File</source>
         <translation>&amp;Datei</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+36"/>
         <source>&amp;Edit</source>
         <translation>&amp;Editieren</translation>
     </message>
@@ -327,14 +327,14 @@
     <message>
         <location line="+4"/>
         <location line="+114"/>
-        <location line="+104"/>
+        <location line="+109"/>
         <location line="+66"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Octave Editor</translation>
     </message>
     <message>
-        <location line="-305"/>
+        <location line="-310"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -345,7 +345,7 @@
 %2</translation>
     </message>
     <message>
-        <location line="+184"/>
+        <location line="+189"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Octave Dateien (*.m);;All Files (*)</translation>
     </message>
@@ -375,14 +375,14 @@
 wurde gelöscht oder umbenannt. Soll die Datei jetzt gespeichert werden?%2</translation>
     </message>
     <message>
-        <location line="-192"/>
+        <location line="-197"/>
         <source>Could not open file %1 for write:
 %2.</source>
-        <translation>Die Datei %1  konnte nicht zum Schrieben geöffnet werden:
+        <translation>Die Datei %1  konnte nicht zum Schreiben geöffnet werden:
 %2.</translation>
     </message>
     <message>
-        <location line="+170"/>
+        <location line="+175"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Die Datei %1 wurde von einer anderen Anwendung verändert. Soll der neue Inhalt geladen werden?</translation>
     </message>
@@ -437,7 +437,7 @@
     <message>
         <location line="+3"/>
         <source>Show Home directory</source>
-        <translation>Wechlse zum Heimatverzeichnis</translation>
+        <translation>Wechsle zum Heimatverzeichnis</translation>
     </message>
     <message>
         <location line="+10"/>
@@ -544,12 +544,12 @@
         <translation>Verzeichnis ist nicht leer und kann daher nicht gelöscht werden</translation>
     </message>
     <message>
-        <location line="+128"/>
+        <location line="+131"/>
         <source>Set directory of file browser</source>
         <translation>Setze aktuelles Browser Verzeichnis</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+28"/>
         <source>Create File</source>
         <translation>Neue Datei</translation>
     </message>
@@ -644,7 +644,7 @@
         <translation>In Auswah&amp;l suchen</translation>
     </message>
     <message>
-        <location line="+61"/>
+        <location line="+71"/>
         <source>Search from end</source>
         <translation>Vom Ende suchen</translation>
     </message>
@@ -689,7 +689,7 @@
     <message>
         <location line="+2"/>
         <source>Enter the filename expression</source>
-        <translation>EIngabe eines Ausdrucks für den Dateinamen</translation>
+        <translation>Eingabe eines Ausdrucks für den Dateinamen</translation>
     </message>
     <message>
         <location line="+5"/>
@@ -729,7 +729,7 @@
     <message>
         <location line="+2"/>
         <source>Include matching directories in search results</source>
-        <translation>Auch Verzeichnisse berücksichitgen, die die Suchanfrage erfüllen</translation>
+        <translation>Auch Verzeichnisse berücksichtigen, die die Suchanfrage erfüllen</translation>
     </message>
     <message>
         <location line="+2"/>
@@ -739,7 +739,7 @@
     <message>
         <location line="+2"/>
         <source>Set matching name is case insensitive</source>
-        <translation>Groß-/Kleinschriebung bei der Dateisuche ignorieren</translation>
+        <translation>Groß-/Kleinschreibung bei der Dateisuche ignorieren</translation>
     </message>
     <message>
         <location line="+2"/>
@@ -767,12 +767,12 @@
         <translation>Groß-/Kleinschreibung beim Text beachten</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+11"/>
         <source>Search results</source>
         <translation>Suchergebnisse</translation>
     </message>
     <message>
-        <location line="+11"/>
+        <location line="+14"/>
         <source>Idle.</source>
         <translation>Leerlauf.</translation>
     </message>
@@ -820,7 +820,7 @@
 <context>
     <name>find_files_model</name>
     <message>
-        <location filename="../src/find-files-model.cc" line="+29"/>
+        <location filename="../src/find-files-model.cc" line="+76"/>
         <source>Filename</source>
         <translation>Dateiname</translation>
     </message>
@@ -833,7 +833,7 @@
 <context>
     <name>history_dock_widget</name>
     <message>
-        <location filename="../src/history-dock-widget.cc" line="+42"/>
+        <location filename="../src/history-dock-widget.cc" line="+43"/>
         <source>Browse and search the command history.</source>
         <translation>Durchsuchen Sie die Befehlshistorie.</translation>
     </message>
@@ -871,23 +871,23 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="+155"/>
+        <location filename="../src/main-window.cc" line="+160"/>
         <source>Load Workspace</source>
         <translation>Lade Arbeitsumgebung</translation>
     </message>
     <message>
-        <location line="+355"/>
-        <location line="+769"/>
+        <location line="+375"/>
+        <location line="+828"/>
         <source>About Octave</source>
         <translation>Über Octave</translation>
     </message>
     <message>
-        <location line="-338"/>
+        <location line="-348"/>
         <source>&amp;File</source>
         <translation>&amp;Datei</translation>
     </message>
     <message>
-        <location line="+52"/>
+        <location line="+54"/>
         <source>New</source>
         <translation>Neu</translation>
     </message>
@@ -897,7 +897,7 @@
         <translation>Skript</translation>
     </message>
     <message>
-        <location line="+2"/>
+        <location line="+3"/>
         <source>Function</source>
         <translation>Funktion</translation>
     </message>
@@ -907,12 +907,12 @@
         <translation>Abbildung</translation>
     </message>
     <message>
-        <location line="-55"/>
+        <location line="-58"/>
         <source>Open...</source>
         <translation>Öffnen...</translation>
     </message>
     <message>
-        <location line="+18"/>
+        <location line="+20"/>
         <source>Preferences...</source>
         <translation>Einstellungen...</translation>
     </message>
@@ -922,7 +922,7 @@
         <translation>Beenden</translation>
     </message>
     <message>
-        <location line="+51"/>
+        <location line="+52"/>
         <source>&amp;Edit</source>
         <translation>&amp;Editieren</translation>
     </message>
@@ -937,28 +937,33 @@
         <translation>Kopieren</translation>
     </message>
     <message>
-        <location line="+5"/>
+        <location line="+6"/>
         <source>Paste</source>
         <translation>Einfügen</translation>
     </message>
     <message>
-        <location line="-895"/>
-        <location line="+817"/>
+        <location line="-968"/>
+        <location line="+888"/>
         <source>Save Workspace As</source>
         <translation>Arbeitsumgebung speichern als</translation>
     </message>
     <message>
-        <location line="-602"/>
+        <location line="-653"/>
         <source>Set working directory</source>
         <translation>Arbeitsverzeichnis setzen</translation>
     </message>
     <message>
-        <location line="+686"/>
+        <location line="+737"/>
+        <source>Clear Clipboard</source>
+        <translation>Zwischenablage leeren</translation>
+    </message>
+    <message>
+        <location line="+5"/>
         <source>Find Files...</source>
         <translation>Suche Dateien...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+5"/>
         <source>Clear Command Window</source>
         <translation>Befehlsfenster löschen</translation>
     </message>
@@ -973,14 +978,14 @@
         <translation>Arbeitsumgebung löschen</translation>
     </message>
     <message>
-        <location line="+36"/>
+        <location line="+40"/>
         <source>De&amp;bug</source>
         <translation>De&amp;bug</translation>
     </message>
     <message>
         <location line="+3"/>
         <source>Step</source>
-        <translation>EInzelschritt</translation>
+        <translation>Einzelschritt</translation>
     </message>
     <message>
         <location line="+3"/>
@@ -995,7 +1000,7 @@
     <message>
         <location line="+4"/>
         <source>Continue</source>
-        <translation>Fortführen</translation>
+        <translation>Fortfahren</translation>
     </message>
     <message>
         <location line="+8"/>
@@ -1048,12 +1053,12 @@
         <translation>Verzeichnis suchen</translation>
     </message>
     <message>
-        <location line="-392"/>
+        <location line="-400"/>
         <source>Load workspace</source>
         <translation>Arbeitsumgebung laden</translation>
     </message>
     <message>
-        <location line="+192"/>
+        <location line="+200"/>
         <source>&amp;Window</source>
         <translation>&amp;Fenster</translation>
     </message>
@@ -1133,17 +1138,17 @@
     <name>octave_dock_widget</name>
     <message>
         <location filename="../src/octave-dock-widget.cc" line="+52"/>
-        <location line="+120"/>
+        <location line="+129"/>
         <source>Undock widget</source>
         <translation>Fenster lösen</translation>
     </message>
     <message>
-        <location line="-111"/>
+        <location line="-119"/>
         <source>Hide widget</source>
         <translation>Fenster verbergen</translation>
     </message>
     <message>
-        <location line="+82"/>
+        <location line="+86"/>
         <source>Dock widget</source>
         <translation>Fenster andocken</translation>
     </message>
@@ -1166,7 +1171,7 @@
     <message>
         <location line="+1"/>
         <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Die Datei %1 wird von einer gleichnamigen Datei im Suchpfad überdeckt. Um die editierte Funktion zu debuggen, in das Verzeichnis %2 gewechselt werden.</translation>
+        <translation>Die Datei %1 wird von einer gleichnamigen Datei im Suchpfad überdeckt. Um die editierte Funktion zu debuggen, muss in das Verzeichnis %2 gewechselt werden.</translation>
     </message>
     <message>
         <location line="+2"/>
@@ -1224,7 +1229,7 @@
     <message>
         <location line="+27"/>
         <source>Do not show white spaces used for indentation</source>
-        <translation>Keine Leezeichen der Einrückung anzeigen</translation>
+        <translation>Keine Leerzeichen der Einrückung anzeigen</translation>
     </message>
     <message>
         <location line="+28"/>
@@ -1279,7 +1284,7 @@
     <message>
         <location line="+13"/>
         <source>Replace word by suggested one</source>
-        <translation>Wort durch Vorschalg ersetzen</translation>
+        <translation>Wort durch Vorschlag ersetzen</translation>
     </message>
     <message>
         <location line="+23"/>
@@ -1409,7 +1414,7 @@
     <message>
         <location line="+7"/>
         <source>Alternating row colors</source>
-        <translation>Alternierende Farben verwenden</translation>
+        <translation>Alternierende Farben für die Zeilen verwenden</translation>
     </message>
     <message>
         <location line="+21"/>
@@ -1506,7 +1511,7 @@
     <message>
         <location line="+129"/>
         <source>Difference to the default size</source>
-        <translation>Differenz zur Stnadgröße</translation>
+        <translation>Differenz zur Standardgröße</translation>
     </message>
     <message>
         <location line="+6"/>
@@ -1540,9 +1545,9 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+78"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
         <source>Type here and press &apos;Return&apos; to search</source>
-        <translation>Suchbegriff eingeben und mit &apos;Enter&apos; die Scuhe starten</translation>
+        <translation>Suchbegriff eingeben und mit &apos;Enter&apos; die Suche starten</translation>
     </message>
     <message>
         <location line="+4"/>
@@ -1562,7 +1567,7 @@
         <source>It appears that you have launched Octave GUI for the first time on this computer, since no configuration file could be found at &apos;~/.octave-gui&apos;. This wizard will guide you through the essential settings you should make before you can start using Octave GUI. If you want to transfer your settings you have previously made just close this dialog and copy over the settings file to your home folder. The presence of that file will automatically be detected and will skip this wizard. IMPORTANT: This wizard is not fully functional yet. Just click your way to the end and it will create a standard settings file.</source>
         <translation>Es scheint, dass Sie Octave-GUI das erste Mal auf diesem Computer ausführen, da die Konfigurationsdatei 
 ~/.config/octave/qt-settings
-nicht gefunden wurde. Die Default-Konfiguration wird beim Fortfahren an diese Stelle kopiert. Wenn bestehende Einstellungen verwendet werden sollen, muss dieser Dialog geschlossen und  die vorhandene Datei an die oben angegebene Stelle kopiert werden. Eine vorhandene Konfigurationsdatei wird beim nächsten Start automatisch erkannt.
+nicht gefunden wurde. Die Standard-Konfiguration wird beim Fortfahren an diese Stelle kopiert. Wenn bestehende Einstellungen verwendet werden sollen, muss dieser Dialog geschlossen und die vorhandene Datei an die oben angegebene Stelle kopiert werden. Eine vorhandene Konfigurationsdatei wird beim nächsten Start automatisch erkannt.
 
 Nach dem Programmstart können die Einstellungen im Menü &quot;Datei/Einstellungen&quot; angepasst werden.</translation>
     </message>
@@ -1590,12 +1595,12 @@
     <message>
         <location line="+7"/>
         <source>This is the development version of Octave with the first official GUI.</source>
-        <translation>Dieses ist die Entwicklungsversion von Octave mit der ersten offiziellen GUI.</translation>
+        <translation>Dies ist die Entwicklungsversion von Octave mit der ersten offiziellen GUI.</translation>
     </message>
     <message>
         <location line="+10"/>
         <source>You seem to run Octave GUI for the first time on this computer. This assistant will help you to configure this software installation. Click &apos;Finish&apos; to write a configuration file and launch Octave GUI.</source>
-        <translation>Die GUI von Octave wird offenbar das erste mal auf diesem Computer ausgeführt. Dieser Assistent erstellt beim Klick auf &apos;Beenden&apos; eine Standarkonfiguration und startet Octve-GUI.  </translation>
+        <translation>Die Octave GUI wird offenbar erstmals auf diesem Computer ausgeführt. Dieser Assistent erstellt beim Klick auf &apos;Beenden&apos; eine Standardkonfiguration und startet die Octave GUI.</translation>
     </message>
     <message>
         <location line="+48"/>
@@ -1633,7 +1638,7 @@
     <message>
         <location line="+107"/>
         <source>Right click to copy, rename, or display</source>
-        <translation>Rechtsklick zum Kopeiren, Umbenennen oder Anzeigen</translation>
+        <translation>Rechtsklick zum Kopieren, Umbenennen oder Anzeigen</translation>
     </message>
 </context>
 <context>
@@ -1661,12 +1666,12 @@
     <message>
         <location line="+8"/>
         <source>Only top-level symbols may be renamed.</source>
-        <translation>Nur Varaiblen auf höchster Ebene können umbenannt werden.</translation>
+        <translation>Nur Variablen auf höchster Ebene können umbenannt werden.</translation>
     </message>
     <message>
         <location line="+125"/>
         <source>View the variables in the active workspace.&lt;br&gt;</source>
-        <translation>Einsehen der Varaiblen der aktiven Arbeitsumgebung.&lt;br&gt;</translation>
+        <translation>Einsehen der Variablen der aktiven Arbeitsumgebung.&lt;br&gt;</translation>
     </message>
     <message>
         <location line="+1"/>
--- a/libgui/qterminal/libqterminal/unix/Screen.cpp
+++ b/libgui/qterminal/libqterminal/unix/Screen.cpp
@@ -788,8 +788,8 @@
 
   lastPos = loc(cuX,cuY);
 
-  // check if selection is still valid.
-  checkSelection(cuX,cuY);
+  // clear selection on text input
+  clearSelection ();
 
   Character& currentChar = screenLines[cuY][cuX];
 
--- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp
+++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp
@@ -94,6 +94,68 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+static QString translateKey (QKeyEvent *ev)
+{
+  QString esc = "\x1b";
+  QString s;
+
+  if (ev->key () == Qt::Key_Delete)
+    s = esc + "[C\b";
+  else if (!ev->text ().isEmpty ())
+    s = ev->text ();
+  else
+    {
+
+      switch (ev->key ())
+        {
+        case Qt::Key_Up:
+          s = esc + "[A";
+          break;
+
+        case Qt::Key_Down:
+          s = esc + "[B";
+          break;
+
+        case Qt::Key_Right:
+          s = esc + "[C";
+          break;
+
+        case Qt::Key_Left:
+          s = esc + "[D";
+          break;
+
+        case Qt::Key_Home:
+          s = esc + "[H";
+          break;
+
+        case Qt::Key_End:
+          s = esc + "[F";
+          break;
+
+        case Qt::Key_Insert:
+          s = esc + "[2~";
+          break;
+
+        case Qt::Key_PageUp:
+          s = esc + "[5~";
+          break;
+
+        case Qt::Key_PageDown:
+          s = esc + "[6~";
+          break;
+
+        case Qt::Key_Escape:
+          s = esc;
+          break;
+
+        default:
+          break;
+        }
+    }
+
+  return s;
+}
+
 class QConsolePrivate
 {
   friend class QWinTerminalImpl;
@@ -1101,6 +1163,9 @@
 
 #define TEXT_CHUNK_SIZE 512
 
+  // clear any selection on inserting text
+  clearSelection();
+
   int len = s.length ();
   INPUT_RECORD events[TEXT_CHUNK_SIZE];
   DWORD nEvents = 0, written;
@@ -1164,6 +1229,8 @@
 QWinTerminalImpl::QWinTerminalImpl (QWidget* parent)
     : QTerminal (parent), d (new QConsolePrivate (this))
 {
+    installEventFilter (this);
+
     connect (this, SIGNAL (set_global_shortcuts_signal (bool)),
            parent, SLOT (set_global_shortcuts (bool)));
 }
@@ -1294,27 +1361,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-bool QWinTerminalImpl::winEvent (MSG* msg, long* result)
-{
-  switch (msg->message)
-    {
-    case WM_KEYDOWN:
-    case WM_KEYUP:
-    //case WM_CHAR:
-      // Forward Win32 message to the console window
-      PostMessage (d->m_consoleWindow,
-                   msg->message,
-                   msg->wParam,
-                   msg->lParam);
-      result = 0;
-      return true;
-    default:
-      return false;
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
 void QWinTerminalImpl::scrollValueChanged (int value)
 {
   d->setScrollValue (value);
@@ -1355,8 +1401,28 @@
   QWidget::focusOutEvent (event);
 }
 
+bool QWinTerminalImpl::eventFilter (QObject *obj, QEvent * event)
+{
+  // if a keypress, filter out tab keys so that the next/prev tabbing is
+  // disabled - but we still need to pass along to the console .
+  if (event->type () == QEvent::KeyPress)
+  {
+    QKeyEvent* k = static_cast<QKeyEvent*>(event);
+    if (k->key () == Qt::Key_Tab)
+    {
+      sendText ("\t");
+      return true;
+    }
+  }
+  return false;
+}
+
 void QWinTerminalImpl::keyPressEvent (QKeyEvent* event)
 {
+  QString s = translateKey (event);
+  if (!s.isEmpty ())
+    sendText (s);
+
   if (d->m_hasBlinkingCursor)
     {
       d->m_blinkCursorTimer->start (d->BLINK_DELAY);
--- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h
+++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h
@@ -81,12 +81,13 @@
   void focusInEvent (QFocusEvent*);
   void focusOutEvent (QFocusEvent*);
   void keyPressEvent (QKeyEvent*);
-  bool winEvent (MSG*, long*);
   virtual void start (void);
   void mouseMoveEvent (QMouseEvent *event);
   void mousePressEvent (QMouseEvent *event);
   void mouseReleaseEvent (QMouseEvent *event);
 
+  bool eventFilter(QObject *obj, QEvent *ev);
+
 private slots:
   void scrollValueChanged (int value);
   void monitorConsole (void);
--- a/libgui/src/dialog.cc
+++ b/libgui/src/dialog.cc
@@ -420,7 +420,7 @@
   buttonCancel_clicked ();
 }
 
-FileDialog::FileDialog (const QStringList& filters, const QString& title,
+FileDialog::FileDialog (const QStringList& name_filters, const QString& title,
                         const QString& filename, const QString& dirname,
                         const QString& multimode)
   : QFileDialog()
@@ -456,7 +456,7 @@
       setAcceptMode (QFileDialog::AcceptOpen);
     }
 
-  setNameFilters (filters);
+  setNameFilters (name_filters);
 
   selectFile (filename);
   
@@ -493,8 +493,8 @@
 
   path = directory ().absolutePath ();
 
-  QStringList filters = nameFilters ();
-  idx = filters.indexOf (selectedNameFilter ()) + 1;
+  QStringList name_filters = nameFilters ();
+  idx = name_filters.indexOf (selectedNameFilter ()) + 1;
   
   // send the selected info
   emit finish_input (string_result, path, idx);
--- a/libgui/src/find-files-model.cc
+++ b/libgui/src/find-files-model.cc
@@ -111,13 +111,13 @@
 }
 
 int 
-find_files_model::rowCount (const QModelIndex & p) const
+find_files_model::rowCount (const QModelIndex &) const
 {
   return _files.size();
 }
 
 int 
-find_files_model::columnCount (const QModelIndex & p) const
+find_files_model::columnCount (const QModelIndex &) const
 {
   return _columnNames.size ();
 }
--- a/libgui/src/history-dock-widget.cc
+++ b/libgui/src/history-dock-widget.cc
@@ -28,6 +28,7 @@
 #include <QClipboard>
 #include <QVBoxLayout>
 #include <QMenu>
+#include <QScrollBar>
 
 #include "error.h"
 
@@ -104,11 +105,17 @@
   QItemSelectionModel *selectionModel = _history_list_view->selectionModel();
   QModelIndexList rows = selectionModel->selectedRows();
   QModelIndexList::iterator it;
-  for (it=rows.begin() ; it != rows.end(); it++) {
-    if ((*it).isValid()) {
-      text += (*it).data().toString()+"\n";
+  bool prev_valid_row = false;
+  for (it = rows.begin(); it != rows.end(); it++)
+    {
+      if ((*it).isValid())
+        {
+          if (prev_valid_row)
+            text += "\n";
+          text += (*it).data().toString();
+          prev_valid_row = true;
+        }
     }
-  }
   QApplication::clipboard()->setText(text);
 }
 
@@ -117,11 +124,11 @@
   QItemSelectionModel *selectionModel = _history_list_view->selectionModel();
   QModelIndexList rows = selectionModel->selectedRows();
   QModelIndexList::iterator it;
-  for (it=rows.begin() ; it != rows.end(); it++) {
-    if ((*it).isValid()) {
-      emit command_double_clicked ((*it).data().toString()+"\n");
+  for (it = rows.begin() ; it != rows.end(); it++)
+    {
+      if ((*it).isValid())
+        emit command_double_clicked ((*it).data().toString());
     }
-  }
 }
 
 void
@@ -131,10 +138,16 @@
   QItemSelectionModel *selectionModel = _history_list_view->selectionModel ();
   QModelIndexList rows = selectionModel->selectedRows ();
 
+  bool prev_valid_row = false;
   for (QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++)
     {
       if ((*it).isValid ())
-        text += (*it).data().toString() + "\n";
+        {
+          if (prev_valid_row)
+            text += "\n";
+          text += (*it).data().toString();
+          prev_valid_row = true;
+        }
     }
 
   if (text.length () > 0)
@@ -145,7 +158,7 @@
 void
 history_dock_widget::handle_double_click (QModelIndex modelIndex)
 {
-  emit command_double_clicked (modelIndex.data().toString()+"\n");
+  emit command_double_clicked (modelIndex.data().toString());
 }
 
 void
@@ -160,8 +173,16 @@
 {
   QStringList lst = _history_model->stringList ();
   lst.append (hist_entry);
+
+  QScrollBar *scroll_bar = _history_list_view->verticalScrollBar ();
+
+  bool at_bottom = scroll_bar->maximum () - scroll_bar->value () < 1;
+
   _history_model->setStringList (lst);
-  _history_list_view->scrollToBottom ();
+
+  // Scroll if slider position at bottom.
+  if (at_bottom)
+    _history_list_view->scrollToBottom ();
 }
 
 void
@@ -186,11 +207,11 @@
 history_dock_widget::pasteClipboard ()
 {
   if(_filter_line_edit->hasFocus ())
-  {
-     QClipboard *clipboard = QApplication::clipboard ();
-     QString str =  clipboard->text ();
-     if (str.length() > 0)
-       _filter_line_edit->insert (str);
-  } 
+    {
+      QClipboard *clipboard = QApplication::clipboard ();
+      QString str =  clipboard->text ();
+      if (str.length() > 0)
+        _filter_line_edit->insert (str);
+    }
 }
 
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -78,7 +78,10 @@
     find_files_dlg (0),
     _octave_main_thread (0),
     _octave_qt_link (0),
-    _clipboard (QApplication::clipboard ())
+    _clipboard (QApplication::clipboard ()),
+    _cmd_queue (new QStringList ()),  // no command pending
+    _cmd_processing (1),
+    _cmd_queue_mutex ()
 {
   // We have to set up all our windows, before we finally launch octave.
   construct ();
@@ -104,6 +107,7 @@
     }
   delete _octave_main_thread;
   delete _octave_qt_link;
+  delete _cmd_queue;
 }
 
 bool
@@ -198,9 +202,7 @@
 void
 main_window::execute_command_in_terminal (const QString& command)
 {
-  octave_link::post_event (this, &main_window::execute_command_callback,
-                           command.toStdString ());
-
+  queue_command (command);
   focus_command_window ();
 }
 
@@ -211,6 +213,28 @@
 }
 
 void
+main_window::run_file_callback (const QFileInfo& info)
+{
+  QString dir = info.absolutePath ();
+  QString function_name = info.fileName ();
+  function_name.chop (info.suffix ().length () + 1);
+  if (octave_qt_link::file_in_path (info.absoluteFilePath ().toStdString (),
+                                    dir.toStdString ()))
+    queue_command (function_name);
+}
+
+void
+main_window::queue_command (QString command)
+{
+  _cmd_queue_mutex.lock ();
+  _cmd_queue->append (command);   // queue command
+  _cmd_queue_mutex.unlock ();
+
+  if (_cmd_processing.tryAcquire ())   // if callback is not processing, post event
+    octave_link::post_event (this, &main_window::execute_command_callback);
+}
+
+void
 main_window::handle_new_figure_request (void)
 {
   octave_link::post_event (this, &main_window::new_figure_callback);
@@ -1482,29 +1506,34 @@
 }
 
 void
-main_window::execute_command_callback (const std::string& command)
+main_window::execute_command_callback ()
 {
-  std::string pending_input = command_editor::get_current_line ();
+  bool repost = false;          // flag for reposting event for this callback
 
-  command_editor::set_initial_input (pending_input);
-
-  command_editor::replace_line (command);
-  command_editor::redisplay ();
+  if (!_cmd_queue->isEmpty ())  // list can not be empty here, just to make sure
+    {
+      std::string pending_input = command_editor::get_current_line ();
+      command_editor::set_initial_input (pending_input);
 
-  // We are executing inside the command editor event loop.  Force
-  // the current line to be returned for processing.
-  command_editor::interrupt ();
-}
+      _cmd_queue_mutex.lock (); // critical path
+      std::string command = _cmd_queue->takeFirst ().toStdString ();
+      if (_cmd_queue->isEmpty ())
+        _cmd_processing.release ();  // command queue empty, processing will stop
+      else
+        repost = true;          // not empty, repost at end
+      _cmd_queue_mutex.unlock ();
+
+      command_editor::replace_line (command);
 
-void
-main_window::run_file_callback (const QFileInfo& info)
-{
-  QString dir = info.absolutePath ();
-  QString function_name = info.fileName ();
-  function_name.chop (info.suffix ().length () + 1);
-  if (octave_qt_link::file_in_path (info.absoluteFilePath ().toStdString (),
-                                    dir.toStdString ()))
-    execute_command_callback (function_name.toStdString ());
+      command_editor::redisplay ();
+      // We are executing inside the command editor event loop.  Force
+      // the current line to be returned for processing.
+      command_editor::interrupt ();
+    }
+
+  if (repost)  // queue not empty, so repost event for further processing
+    octave_link::post_event (this, &main_window::execute_command_callback);
+
 }
 
 void
--- a/libgui/src/main-window.h
+++ b/libgui/src/main-window.h
@@ -36,6 +36,7 @@
 #include <QCloseEvent>
 #include <QToolButton>
 #include <QComboBox>
+#include <QSemaphore>
 
 // Editor includes
 #include "file-editor-interface.h"
@@ -233,7 +234,7 @@
 
   void clear_history_callback (void);
 
-  void execute_command_callback (const std::string& command);
+  void execute_command_callback ();
   void run_file_callback (const QFileInfo& info);
 
   void new_figure_callback (void);
@@ -252,7 +253,8 @@
 
   void exit_callback (void);
 
-  // Data models.
+  void queue_command (QString command);  // Data models.
+
   workspace_model *_workspace_model;
 
   // Toolbars.
@@ -272,7 +274,9 @@
     list.append (static_cast<octave_dock_widget *> (history_window));
     list.append (static_cast<octave_dock_widget *> (file_browser_window));
     list.append (static_cast<octave_dock_widget *> (doc_browser_window));
+#ifdef HAVE_QSCINTILLA
     list.append (static_cast<octave_dock_widget *> (editor_window));
+#endif
     list.append (static_cast<octave_dock_widget *> (workspace_window));
     return list;
   }
@@ -315,6 +319,11 @@
 
   // Flag for closing whole application.
   bool _closing;
+
+  // semaphore to synchronize execution signals and related callback
+  QStringList *_cmd_queue;
+  QSemaphore   _cmd_processing;
+  QMutex       _cmd_queue_mutex;
 };
 
 #endif // MAINWINDOW_H
--- a/libgui/src/octave-gui.cc
+++ b/libgui/src/octave-gui.cc
@@ -123,6 +123,11 @@
 
           if (term.empty ())
             octave_env::putenv ("TERM", "xterm");
+#else
+          std::string term = octave_env::getenv ("TERM");
+
+          if (term.empty ())
+            octave_env::putenv ("TERM", "cygwin");
 #endif
 
           // create main window, read settings, and show window
--- a/libgui/src/resource-manager.cc
+++ b/libgui/src/resource-manager.cc
@@ -235,1564 +235,3 @@
 {
   return QTerminal::default_colors ();
 }
-
-const char*
-resource_manager::octave_keywords (void)
-{
-  return
-      ".nargin. "
-      "EDITOR "
-      "EXEC_PATH "
-      "F_DUPFD "
-      "F_GETFD "
-      "F_GETFL "
-      "F_SETFD "
-      "F_SETFL "
-      "I "
-      "IMAGE_PATH "
-      "Inf "
-      "J "
-      "NA "
-      "NaN "
-      "OCTAVE_HOME "
-      "OCTAVE_VERSION "
-      "O_APPEND "
-      "O_ASYNC "
-      "O_CREAT "
-      "O_EXCL "
-      "O_NONBLOCK "
-      "O_RDONLY "
-      "O_RDWR "
-      "O_SYNC "
-      "O_TRUNC "
-      "O_WRONLY "
-      "PAGER "
-      "PAGER_FLAGS "
-      "PS1 "
-      "PS2 "
-      "PS4 "
-      "P_tmpdir "
-      "SEEK_CUR "
-      "SEEK_END "
-      "SEEK_SET "
-      "SIG "
-      "S_ISBLK "
-      "S_ISCHR "
-      "S_ISDIR "
-      "S_ISFIFO "
-      "S_ISLNK "
-      "S_ISREG "
-      "S_ISSOCK "
-      "WCONTINUE "
-      "WCOREDUMP "
-      "WEXITSTATUS "
-      "WIFCONTINUED "
-      "WIFEXITED "
-      "WIFSIGNALED "
-      "WIFSTOPPED "
-      "WNOHANG "
-      "WSTOPSIG "
-      "WTERMSIG "
-      "WUNTRACED "
-      "__accumarray_max__ "
-      "__accumarray_min__ "
-      "__accumarray_sum__ "
-      "__accumdim_sum__ "
-      "__all_opts__ "
-      "__builtins__ "
-      "__calc_dimensions__ "
-      "__contourc__ "
-      "__current_scope__ "
-      "__delaunayn__ "
-      "__dispatch__ "
-      "__display_tokens__ "
-      "__dsearchn__ "
-      "__dump_symtab_info__ "
-      "__end__ "
-      "__error_text__ "
-      "__finish__ "
-      "__fltk_ginput__ "
-      "__fltk_print__ "
-      "__fltk_uigetfile__ "
-      "__ftp__ "
-      "__ftp_ascii__ "
-      "__ftp_binary__ "
-      "__ftp_close__ "
-      "__ftp_cwd__ "
-      "__ftp_delete__ "
-      "__ftp_dir__ "
-      "__ftp_mget__ "
-      "__ftp_mkdir__ "
-      "__ftp_mode__ "
-      "__ftp_mput__ "
-      "__ftp_pwd__ "
-      "__ftp_rename__ "
-      "__ftp_rmdir__ "
-      "__get__ "
-      "__glpk__ "
-      "__gnuplot_drawnow__ "
-      "__gnuplot_get_var__ "
-      "__gnuplot_ginput__ "
-      "__gnuplot_has_feature__ "
-      "__gnuplot_open_stream__ "
-      "__gnuplot_print__ "
-      "__gnuplot_version__ "
-      "__go_axes__ "
-      "__go_axes_init__ "
-      "__go_close_all__ "
-      "__go_delete__ "
-      "__go_draw_axes__ "
-      "__go_draw_figure__ "
-      "__go_execute_callback__ "
-      "__go_figure__ "
-      "__go_figure_handles__ "
-      "__go_handles__ "
-      "__go_hggroup__ "
-      "__go_image__ "
-      "__go_line__ "
-      "__go_patch__ "
-      "__go_surface__ "
-      "__go_text__ "
-      "__go_uimenu__ "
-      "__gud_mode__ "
-      "__image_pixel_size__ "
-      "__init_fltk__ "
-      "__isa_parent__ "
-      "__keywords__ "
-      "__lexer_debug_flag__ "
-      "__lin_interpn__ "
-      "__list_functions__ "
-      "__magick_finfo__ "
-      "__magick_format_list__ "
-      "__magick_read__ "
-      "__magick_write__ "
-      "__makeinfo__ "
-      "__marching_cube__ "
-      "__next_line_color__ "
-      "__next_line_style__ "
-      "__operators__ "
-      "__parent_classes__ "
-      "__parser_debug_flag__ "
-      "__pathorig__ "
-      "__pchip_deriv__ "
-      "__plt_get_axis_arg__ "
-      "__print_parse_opts__ "
-      "__qp__ "
-      "__request_drawnow__ "
-      "__sort_rows_idx__ "
-      "__strip_html_tags__ "
-      "__token_count__ "
-      "__unimplemented__ "
-      "__varval__ "
-      "__version_info__ "
-      "__voronoi__ "
-      "__which__ "
-      "abs "
-      "accumarray "
-      "accumdim "
-      "acos "
-      "acosd "
-      "acosh "
-      "acot "
-      "acotd "
-      "acoth "
-      "acsc "
-      "acscd "
-      "acsch "
-      "add_input_event_hook "
-      "addlistener "
-      "addpath "
-      "addproperty "
-      "addtodate "
-      "airy "
-      "all "
-      "allchild "
-      "allow_noninteger_range_as_index "
-      "amd "
-      "ancestor "
-      "and "
-      "angle "
-      "anova "
-      "ans "
-      "any "
-      "arch_fit "
-      "arch_rnd "
-      "arch_test "
-      "area "
-      "arg "
-      "argnames "
-      "argv "
-      "arma_rnd "
-      "arrayfun "
-      "asctime "
-      "asec "
-      "asecd "
-      "asech "
-      "asin "
-      "asind "
-      "asinh "
-      "assert "
-      "assignin "
-      "atan "
-      "atan2 "
-      "atand "
-      "atanh "
-      "atexit "
-      "autocor "
-      "autocov "
-      "autoload "
-      "autoreg_matrix "
-      "autumn "
-      "available_graphics_toolkits "
-      "axes "
-      "axis "
-      "balance "
-      "bar "
-      "barh "
-      "bartlett "
-      "bartlett_test "
-      "base2dec "
-      "beep "
-      "beep_on_error "
-      "bessel "
-      "besselh "
-      "besseli "
-      "besselj "
-      "besselk "
-      "bessely "
-      "beta "
-      "betacdf "
-      "betai "
-      "betainc "
-      "betainv "
-      "betaln "
-      "betapdf "
-      "betarnd "
-      "bicgstab "
-      "bicubic "
-      "bin2dec "
-      "bincoeff "
-      "binocdf "
-      "binoinv "
-      "binopdf "
-      "binornd "
-      "bitand "
-      "bitcmp "
-      "bitget "
-      "bitmax "
-      "bitor "
-      "bitpack "
-      "bitset "
-      "bitshift "
-      "bitunpack "
-      "bitxor "
-      "blackman "
-      "blanks "
-      "blkdiag "
-      "blkmm "
-      "bone "
-      "box "
-      "break "
-      "brighten "
-      "bsxfun "
-      "bug_report "
-      "builtin "
-      "bunzip2 "
-      "bzip2 "
-      "calendar "
-      "canonicalize_file_name "
-      "cart2pol "
-      "cart2sph "
-      "case "
-      "cast "
-      "cat "
-      "catch "
-      "cauchy_cdf "
-      "cauchy_inv "
-      "cauchy_pdf "
-      "cauchy_rnd "
-      "caxis "
-      "cbrt "
-      "ccolamd "
-      "cd "
-      "ceil "
-      "cell "
-      "cell2mat "
-      "cell2struct "
-      "celldisp "
-      "cellfun "
-      "cellidx "
-      "cellindexmat "
-      "cellslices "
-      "cellstr "
-      "center "
-      "cgs "
-      "char "
-      "chdir "
-      "chi2cdf "
-      "chi2inv "
-      "chi2pdf "
-      "chi2rnd "
-      "chisquare_test_homogeneity "
-      "chisquare_test_independence "
-      "chol "
-      "chol2inv "
-      "choldelete "
-      "cholinsert "
-      "cholinv "
-      "cholshift "
-      "cholupdate "
-      "chop "
-      "circshift "
-      "cla "
-      "clabel "
-      "class "
-      "clc "
-      "clear "
-      "clf "
-      "clg "
-      "clock "
-      "cloglog "
-      "close "
-      "closereq "
-      "colamd "
-      "colloc "
-      "colon "
-      "colorbar "
-      "colormap "
-      "colperm "
-      "colstyle "
-      "columns "
-      "comet "
-      "comet3 "
-      "comma "
-      "command_line_path "
-      "common_size "
-      "commutation_matrix "
-      "compan "
-      "compare_versions "
-      "compass "
-      "complement "
-      "completion_append_char "
-      "completion_matches "
-      "complex "
-      "computer "
-      "cond "
-      "condest "
-      "confirm_recursive_rmdir "
-      "conj "
-      "continue "
-      "contour "
-      "contour3 "
-      "contourc "
-      "contourf "
-      "contrast "
-      "conv "
-      "conv2 "
-      "convhull "
-      "convhulln "
-      "convn "
-      "cool "
-      "copper "
-      "copyfile "
-      "cor "
-      "cor_test "
-      "corrcoef "
-      "cos "
-      "cosd "
-      "cosh "
-      "cot "
-      "cotd "
-      "coth "
-      "cov "
-      "cplxpair "
-      "cputime "
-      "cquad "
-      "crash_dumps_octave_core "
-      "create_set "
-      "cross "
-      "csc "
-      "cscd "
-      "csch "
-      "cstrcat "
-      "csvread "
-      "csvwrite "
-      "csymamd "
-      "ctime "
-      "ctranspose "
-      "cummax "
-      "cummin "
-      "cumprod "
-      "cumsum "
-      "cumtrapz "
-      "curl "
-      "cut "
-      "cylinder "
-      "daspect "
-      "daspk "
-      "daspk_options "
-      "dasrt "
-      "dasrt_options "
-      "dassl "
-      "dassl_options "
-      "date "
-      "datenum "
-      "datestr "
-      "datetick "
-      "datevec "
-      "dbclear "
-      "dbcont "
-      "dbdown "
-      "dblquad "
-      "dbnext "
-      "dbquit "
-      "dbstack "
-      "dbstatus "
-      "dbstep "
-      "dbstop "
-      "dbtype "
-      "dbup "
-      "dbwhere "
-      "deal "
-      "deblank "
-      "debug "
-      "debug_on_error "
-      "debug_on_interrupt "
-      "debug_on_warning "
-      "dec2base "
-      "dec2bin "
-      "dec2hex "
-      "deconv "
-      "del2 "
-      "delaunay "
-      "delaunay3 "
-      "delaunayn "
-      "delete "
-      "dellistener "
-      "demo "
-      "det "
-      "detrend "
-      "diag "
-      "diary "
-      "diff "
-      "diffpara "
-      "diffuse "
-      "dir "
-      "discrete_cdf "
-      "discrete_inv "
-      "discrete_pdf "
-      "discrete_rnd "
-      "disp "
-      "dispatch "
-      "display "
-      "divergence "
-      "dlmread "
-      "dlmwrite "
-      "dmperm "
-      "dmult "
-      "do "
-      "do_braindead_shortcircuit_evaluation "
-      "do_string_escapes "
-      "doc "
-      "doc_cache_create "
-      "doc_cache_file "
-      "dos "
-      "dot "
-      "double "
-      "drawnow "
-      "dsearch "
-      "dsearchn "
-      "dump_prefs "
-      "dup2 "
-      "duplication_matrix "
-      "durbinlevinson "
-      "e "
-      "echo "
-      "echo_executing_commands "
-      "edit "
-      "edit_history "
-      "eig "
-      "eigs "
-      "ellipsoid "
-      "else "
-      "elseif "
-      "empirical_cdf "
-      "empirical_inv "
-      "empirical_pdf "
-      "empirical_rnd "
-      "end "
-      "end_try_catch "
-      "end_unwind_protect "
-      "endfor "
-      "endfunction "
-      "endgrent "
-      "endif "
-      "endpwent "
-      "endswitch "
-      "endwhile "
-      "eomday "
-      "eps "
-      "eq "
-      "erf "
-      "erfc "
-      "erfcx "
-      "erfinv "
-      "errno "
-      "errno_list "
-      "error "
-      "error_text "
-      "errorbar "
-      "etime "
-      "etree "
-      "etreeplot "
-      "eval "
-      "evalin "
-      "example "
-      "exec "
-      "exist "
-      "exit "
-      "exp "
-      "expcdf "
-      "expinv "
-      "expm "
-      "expm1 "
-      "exppdf "
-      "exprnd "
-      "eye "
-      "ezcontour "
-      "ezcontourf "
-      "ezmesh "
-      "ezmeshc "
-      "ezplot "
-      "ezplot3 "
-      "ezpolar "
-      "ezsurf "
-      "ezsurfc "
-      "f_test_regression "
-      "factor "
-      "factorial "
-      "fail "
-      "false "
-      "fcdf "
-      "fclear "
-      "fclose "
-      "fcntl "
-      "fdisp "
-      "feather "
-      "feof "
-      "ferror "
-      "feval "
-      "fflush "
-      "fft "
-      "fft2 "
-      "fftconv "
-      "fftfilt "
-      "fftn "
-      "fftshift "
-      "fftw "
-      "fgetl "
-      "fgets "
-      "fieldnames "
-      "figure "
-      "file_in_loadpath "
-      "file_in_path "
-      "fileattrib "
-      "filemarker "
-      "fileparts "
-      "fileread "
-      "filesep "
-      "fill "
-      "filter "
-      "filter2 "
-      "find "
-      "find_dir_in_path "
-      "findall "
-      "findobj "
-      "findstr "
-      "finite "
-      "finv "
-      "fix "
-      "fixed_point_format "
-      "flag "
-      "flipdim "
-      "fliplr "
-      "flipud "
-      "floor "
-      "fminbnd "
-      "fminunc "
-      "fmod "
-      "fnmatch "
-      "fopen "
-      "for "
-      "fork "
-      "format "
-      "formula "
-      "fpdf "
-      "fplot "
-      "fprintf "
-      "fputs "
-      "fractdiff "
-      "fread "
-      "freport "
-      "freqz "
-      "freqz_plot "
-      "frewind "
-      "frnd "
-      "fscanf "
-      "fseek "
-      "fskipl "
-      "fsolve "
-      "fstat "
-      "ftell "
-      "full "
-      "fullfile "
-      "func2str "
-      "function "
-      "functions "
-      "fwrite "
-      "fzero "
-      "gamcdf "
-      "gaminv "
-      "gamma "
-      "gammai "
-      "gammainc "
-      "gammaln "
-      "gampdf "
-      "gamrnd "
-      "gca "
-      "gcbf "
-      "gcbo "
-      "gcd "
-      "gcf "
-      "ge "
-      "genpath "
-      "genvarname "
-      "geocdf "
-      "geoinv "
-      "geopdf "
-      "geornd "
-      "get "
-      "get_first_help_sentence "
-      "get_help_text "
-      "get_help_text_from_file "
-      "getappdata "
-      "getegid "
-      "getenv "
-      "geteuid "
-      "getfield "
-      "getgid "
-      "getgrent "
-      "getgrgid "
-      "getgrnam "
-      "gethostname "
-      "getpgrp "
-      "getpid "
-      "getppid "
-      "getpwent "
-      "getpwnam "
-      "getpwuid "
-      "getrusage "
-      "getuid "
-      "ginput "
-      "givens "
-      "glob "
-      "global "
-      "glpk "
-      "glpkmex "
-      "gls "
-      "gmap40 "
-      "gmres "
-      "gmtime "
-      "gnuplot_binary "
-      "gplot "
-      "gradient "
-      "graphics_toolkit "
-      "gray "
-      "gray2ind "
-      "grid "
-      "griddata "
-      "griddata3 "
-      "griddatan "
-      "gt "
-      "gtext "
-      "gunzip "
-      "gzip "
-      "hadamard "
-      "hamming "
-      "hankel "
-      "hanning "
-      "help "
-      "hess "
-      "hex2dec "
-      "hex2num "
-      "hggroup "
-      "hidden "
-      "hilb "
-      "hist "
-      "histc "
-      "history "
-      "history_control "
-      "history_file "
-      "history_save "
-      "history_size "
-      "history_timestamp_format_string "
-      "hold "
-      "home "
-      "horzcat "
-      "hot "
-      "hotelling_test "
-      "hotelling_test_2 "
-      "housh "
-      "hsv "
-      "hsv2rgb "
-      "hurst "
-      "hygecdf "
-      "hygeinv "
-      "hygepdf "
-      "hygernd "
-      "hypot "
-      "i "
-      "idivide "
-      "if "
-      "ifelse "
-      "ifft "
-      "ifft2 "
-      "ifftn "
-      "ifftshift "
-      "ignore_function_time_stamp "
-      "imag "
-      "image "
-      "imagesc "
-      "imfinfo "
-      "imread "
-      "imshow "
-      "imwrite "
-      "ind2gray "
-      "ind2rgb "
-      "ind2sub "
-      "index "
-      "inf "
-      "inferiorto "
-      "info "
-      "info_file "
-      "info_program "
-      "inline "
-      "inpolygon "
-      "input "
-      "inputname "
-      "int16 "
-      "int2str "
-      "int32 "
-      "int64 "
-      "int8 "
-      "interp1 "
-      "interp1q "
-      "interp2 "
-      "interp3 "
-      "interpft "
-      "interpn "
-      "intersect "
-      "intmax "
-      "intmin "
-      "intwarning "
-      "inv "
-      "inverse "
-      "invhilb "
-      "ipermute "
-      "iqr "
-      "is_absolute_filename "
-      "is_duplicate_entry "
-      "is_global "
-      "is_leap_year "
-      "is_rooted_relative_filename "
-      "is_valid_file_id "
-      "isa "
-      "isalnum "
-      "isalpha "
-      "isappdata "
-      "isargout "
-      "isascii "
-      "isbool "
-      "iscell "
-      "iscellstr "
-      "ischar "
-      "iscntrl "
-      "iscolumn "
-      "iscommand "
-      "iscomplex "
-      "isdebugmode "
-      "isdefinite "
-      "isdeployed "
-      "isdigit "
-      "isdir "
-      "isempty "
-      "isequal "
-      "isequalwithequalnans "
-      "isfield "
-      "isfigure "
-      "isfinite "
-      "isfloat "
-      "isglobal "
-      "isgraph "
-      "ishandle "
-      "ishermitian "
-      "ishghandle "
-      "ishold "
-      "isieee "
-      "isindex "
-      "isinf "
-      "isinteger "
-      "iskeyword "
-      "isletter "
-      "islogical "
-      "islower "
-      "ismac "
-      "ismatrix "
-      "ismember "
-      "ismethod "
-      "isna "
-      "isnan "
-      "isnull "
-      "isnumeric "
-      "isobject "
-      "isocolors "
-      "isonormals "
-      "isosurface "
-      "ispc "
-      "isprime "
-      "isprint "
-      "isprop "
-      "ispunct "
-      "israwcommand "
-      "isreal "
-      "isrow "
-      "isscalar "
-      "issorted "
-      "isspace "
-      "issparse "
-      "issquare "
-      "isstr "
-      "isstrprop "
-      "isstruct "
-      "issymmetric "
-      "isunix "
-      "isupper "
-      "isvarname "
-      "isvector "
-      "isxdigit "
-      "j "
-      "jet "
-      "kbhit "
-      "kendall "
-      "keyboard "
-      "kill "
-      "kolmogorov_smirnov_cdf "
-      "kolmogorov_smirnov_test "
-      "kolmogorov_smirnov_test_2 "
-      "kron "
-      "kruskal_wallis_test "
-      "krylov "
-      "krylovb "
-      "kurtosis "
-      "laplace_cdf "
-      "laplace_inv "
-      "laplace_pdf "
-      "laplace_rnd "
-      "lasterr "
-      "lasterror "
-      "lastwarn "
-      "lchol "
-      "lcm "
-      "ldivide "
-      "le "
-      "legend "
-      "legendre "
-      "length "
-      "lgamma "
-      "license "
-      "lin2mu "
-      "line "
-      "link "
-      "linkprop "
-      "linspace "
-      "list "
-      "list_in_columns "
-      "list_primes "
-      "load "
-      "loadaudio "
-      "loadimage "
-      "loadobj "
-      "localtime "
-      "log "
-      "log10 "
-      "log1p "
-      "log2 "
-      "logical "
-      "logistic_cdf "
-      "logistic_inv "
-      "logistic_pdf "
-      "logistic_regression "
-      "logistic_rnd "
-      "logit "
-      "loglog "
-      "loglogerr "
-      "logm "
-      "logncdf "
-      "logninv "
-      "lognpdf "
-      "lognrnd "
-      "logspace "
-      "lookfor "
-      "lookup "
-      "lower "
-      "ls "
-      "ls_command "
-      "lsode "
-      "lsode_options "
-      "lsqnonneg "
-      "lstat "
-      "lt "
-      "lu "
-      "luinc "
-      "luupdate "
-      "magic "
-      "mahalanobis "
-      "make_absolute_filename "
-      "makeinfo_program "
-      "manova "
-      "mark_as_command "
-      "mark_as_rawcommand "
-      "mat2cell "
-      "mat2str "
-      "matlabroot "
-      "matrix_type "
-      "max "
-      "max_recursion_depth "
-      "mcnemar_test "
-      "md5sum "
-      "mean "
-      "meansq "
-      "median "
-      "menu "
-      "merge "
-      "mesh "
-      "meshc "
-      "meshgrid "
-      "meshz "
-      "methods "
-      "mex "
-      "mexext "
-      "mfilename "
-      "mgorth "
-      "min "
-      "minus "
-      "mislocked "
-      "missing_function_hook "
-      "mist "
-      "mkdir "
-      "mkfifo "
-      "mkoctfile "
-      "mkpp "
-      "mkstemp "
-      "mktime "
-      "mldivide "
-      "mlock "
-      "mod "
-      "mode "
-      "moment "
-      "more "
-      "most "
-      "movefile "
-      "mpoles "
-      "mpower "
-      "mrdivide "
-      "mtimes "
-      "mu2lin "
-      "munlock "
-      "namelengthmax "
-      "nan "
-      "nargchk "
-      "nargin "
-      "nargout "
-      "nargoutchk "
-      "native_float_format "
-      "nbincdf "
-      "nbininv "
-      "nbinpdf "
-      "nbinrnd "
-      "nchoosek "
-      "ndgrid "
-      "ndims "
-      "ne "
-      "newplot "
-      "news "
-      "nextpow2 "
-      "nfields "
-      "nnz "
-      "nonzeros "
-      "norm "
-      "normcdf "
-      "normest "
-      "norminv "
-      "normpdf "
-      "normrnd "
-      "not "
-      "now "
-      "nproc "
-      "nth_element "
-      "nthroot "
-      "ntsc2rgb "
-      "null "
-      "num2cell "
-      "num2hex "
-      "num2str "
-      "numel "
-      "nzmax "
-      "ocean "
-      "octave_config_info "
-      "octave_core_file_limit "
-      "octave_core_file_name "
-      "octave_core_file_options "
-      "octave_tmp_file_name "
-      "ols "
-      "onCleanup "
-      "onenormest "
-      "ones "
-      "optimget "
-      "optimize_subsasgn_calls "
-      "optimset "
-      "or "
-      "orderfields "
-      "orient "
-      "orth "
-      "otherwise "
-      "output_max_field_width "
-      "output_precision "
-      "pack "
-      "page_output_immediately "
-      "page_screen_output "
-      "paren "
-      "pareto "
-      "parseparams "
-      "pascal "
-      "patch "
-      "path "
-      "pathdef "
-      "pathsep "
-      "pause "
-      "pbaspect "
-      "pcg "
-      "pchip "
-      "pclose "
-      "pcolor "
-      "pcr "
-      "peaks "
-      "periodogram "
-      "perl "
-      "perms "
-      "permute "
-      "perror "
-      "persistent "
-      "pi "
-      "pie "
-      "pie3 "
-      "pink "
-      "pinv "
-      "pipe "
-      "pkg "
-      "planerot "
-      "playaudio "
-      "plot "
-      "plot3 "
-      "plotmatrix "
-      "plotyy "
-      "plus "
-      "poisscdf "
-      "poissinv "
-      "poisspdf "
-      "poissrnd "
-      "pol2cart "
-      "polar "
-      "poly "
-      "polyaffine "
-      "polyarea "
-      "polyder "
-      "polyderiv "
-      "polyfit "
-      "polygcd "
-      "polyint "
-      "polyout "
-      "polyreduce "
-      "polyval "
-      "polyvalm "
-      "popen "
-      "popen2 "
-      "postpad "
-      "pow2 "
-      "power "
-      "powerset "
-      "ppder "
-      "ppint "
-      "ppjumps "
-      "ppplot "
-      "ppval "
-      "pqpnonneg "
-      "prctile "
-      "prepad "
-      "primes "
-      "print "
-      "print_empty_dimensions "
-      "print_struct_array_contents "
-      "print_usage "
-      "printf "
-      "prism "
-      "probit "
-      "prod "
-      "program_invocation_name "
-      "program_name "
-      "prop_test_2 "
-      "putenv "
-      "puts "
-      "pwd "
-      "qp "
-      "qqplot "
-      "qr "
-      "qrdelete "
-      "qrinsert "
-      "qrshift "
-      "qrupdate "
-      "quad "
-      "quad_options "
-      "quadcc "
-      "quadgk "
-      "quadl "
-      "quadv "
-      "quantile "
-      "quit "
-      "quiver "
-      "quiver3 "
-      "qz "
-      "qzhess "
-      "rainbow "
-      "rand "
-      "rande "
-      "randg "
-      "randi "
-      "randn "
-      "randp "
-      "randperm "
-      "range "
-      "rank "
-      "ranks "
-      "rat "
-      "rats "
-      "rcond "
-      "rdivide "
-      "re_read_readline_init_file "
-      "readdir "
-      "readline_re_read_init_file "
-      "readline_read_init_file "
-      "readlink "
-      "real "
-      "reallog "
-      "realmax "
-      "realmin "
-      "realpow "
-      "realsqrt "
-      "record "
-      "rectangle "
-      "rectint "
-      "refresh "
-      "refreshdata "
-      "regexp "
-      "regexpi "
-      "regexprep "
-      "regexptranslate "
-      "rehash "
-      "rem "
-      "remove_input_event_hook "
-      "rename "
-      "repelems "
-      "replot "
-      "repmat "
-      "reset "
-      "reshape "
-      "residue "
-      "resize "
-      "restoredefaultpath "
-      "rethrow "
-      "return "
-      "rgb2hsv "
-      "rgb2ind "
-      "rgb2ntsc "
-      "ribbon "
-      "rindex "
-      "rmappdata "
-      "rmdir "
-      "rmfield "
-      "rmpath "
-      "roots "
-      "rose "
-      "rosser "
-      "rot90 "
-      "rotdim "
-      "round "
-      "roundb "
-      "rows "
-      "rref "
-      "rsf2csf "
-      "run "
-      "run_count "
-      "run_history "
-      "run_test "
-      "rundemos "
-      "runlength "
-      "runtests "
-      "save "
-      "save_default_options "
-      "save_header_format_string "
-      "save_precision "
-      "saveas "
-      "saveaudio "
-      "saveimage "
-      "saveobj "
-      "savepath "
-      "scanf "
-      "scatter "
-      "scatter3 "
-      "schur "
-      "sec "
-      "secd "
-      "sech "
-      "semicolon "
-      "semilogx "
-      "semilogxerr "
-      "semilogy "
-      "semilogyerr "
-      "set "
-      "setappdata "
-      "setaudio "
-      "setdiff "
-      "setenv "
-      "setfield "
-      "setgrent "
-      "setpwent "
-      "setstr "
-      "setxor "
-      "shading "
-      "shell_cmd "
-      "shg "
-      "shift "
-      "shiftdim "
-      "sighup_dumps_octave_core "
-      "sign "
-      "sign_test "
-      "sigterm_dumps_octave_core "
-      "silent_functions "
-      "sin "
-      "sinc "
-      "sind "
-      "sinetone "
-      "sinewave "
-      "single "
-      "sinh "
-      "size "
-      "size_equal "
-      "sizemax "
-      "sizeof "
-      "skewness "
-      "sleep "
-      "slice "
-      "sombrero "
-      "sort "
-      "sortrows "
-      "source "
-      "spalloc "
-      "sparse "
-      "sparse_auto_mutate "
-      "spatan2 "
-      "spaugment "
-      "spchol "
-      "spchol2inv "
-      "spcholinv "
-      "spconvert "
-      "spcumprod "
-      "spcumsum "
-      "spdet "
-      "spdiag "
-      "spdiags "
-      "spearman "
-      "spectral_adf "
-      "spectral_xdf "
-      "specular "
-      "speed "
-      "spencer "
-      "speye "
-      "spfind "
-      "spfun "
-      "sph2cart "
-      "sphcat "
-      "sphere "
-      "spinmap "
-      "spinv "
-      "spkron "
-      "splchol "
-      "spline "
-      "split "
-      "split_long_rows "
-      "splu "
-      "spmax "
-      "spmin "
-      "spones "
-      "spparms "
-      "spprod "
-      "spqr "
-      "sprand "
-      "sprandn "
-      "sprandsym "
-      "sprank "
-      "spring "
-      "sprintf "
-      "spstats "
-      "spsum "
-      "spsumsq "
-      "spvcat "
-      "spy "
-      "sqp "
-      "sqrt "
-      "sqrtm "
-      "squeeze "
-      "sscanf "
-      "stairs "
-      "stat "
-      "static "
-      "statistics "
-      "std "
-      "stderr "
-      "stdin "
-      "stdnormal_cdf "
-      "stdnormal_inv "
-      "stdnormal_pdf "
-      "stdnormal_rnd "
-      "stdout "
-      "stem "
-      "stem3 "
-      "stft "
-      "str2double "
-      "str2func "
-      "str2mat "
-      "str2num "
-      "strcat "
-      "strchr "
-      "strcmp "
-      "strcmpi "
-      "strerror "
-      "strfind "
-      "strftime "
-      "string_fill_char "
-      "strjust "
-      "strmatch "
-      "strncmp "
-      "strncmpi "
-      "strptime "
-      "strread "
-      "strrep "
-      "strsplit "
-      "strtok "
-      "strtrim "
-      "strtrunc "
-      "struct "
-      "struct2cell "
-      "struct_levels_to_print "
-      "structfun "
-      "strvcat "
-      "studentize "
-      "sub2ind "
-      "subplot "
-      "subsasgn "
-      "subsindex "
-      "subspace "
-      "subsref "
-      "substr "
-      "substruct "
-      "sum "
-      "summer "
-      "sumsq "
-      "superiorto "
-      "suppress_verbose_help_message "
-      "surf "
-      "surface "
-      "surfc "
-      "surfl "
-      "surfnorm "
-      "svd "
-      "svd_driver "
-      "svds "
-      "swapbytes "
-      "switch "
-      "syl "
-      "sylvester_matrix "
-      "symamd "
-      "symbfact "
-      "symlink "
-      "symrcm "
-      "symvar "
-      "synthesis "
-      "system "
-      "t_test "
-      "t_test_2 "
-      "t_test_regression "
-      "table "
-      "tan "
-      "tand "
-      "tanh "
-      "tar "
-      "tcdf "
-      "tempdir "
-      "tempname "
-      "terminal_size "
-      "test "
-      "test2 "
-      "test3 "
-      "text "
-      "textread "
-      "textscan "
-      "tic "
-      "tilde_expand "
-      "time "
-      "times "
-      "tinv "
-      "title "
-      "tmpfile "
-      "tmpnam "
-      "toascii "
-      "toc "
-      "toeplitz "
-      "tolower "
-      "toupper "
-      "tpdf "
-      "trace "
-      "transpose "
-      "trapz "
-      "treelayout "
-      "treeplot "
-      "tril "
-      "trimesh "
-      "triplequad "
-      "triplot "
-      "trisurf "
-      "triu "
-      "trnd "
-      "true "
-      "try "
-      "tsearch "
-      "tsearchn "
-      "type "
-      "typecast "
-      "typeinfo "
-      "u_test "
-      "uigetdir "
-      "uigetfile "
-      "uimenu "
-      "uint16 "
-      "uint32 "
-      "uint64 "
-      "uint8 "
-      "uiputfile "
-      "umask "
-      "uminus "
-      "uname "
-      "undo_string_escapes "
-      "unidcdf "
-      "unidinv "
-      "unidpdf "
-      "unidrnd "
-      "unifcdf "
-      "unifinv "
-      "unifpdf "
-      "unifrnd "
-      "union "
-      "unique "
-      "unix "
-      "unlink "
-      "unmark_command "
-      "unmark_rawcommand "
-      "unmkpp "
-      "unpack "
-      "untabify "
-      "untar "
-      "until "
-      "unwind_protect "
-      "unwind_protect_cleanup "
-      "unwrap "
-      "unzip "
-      "uplus "
-      "upper "
-      "urlread "
-      "urlwrite "
-      "usage "
-      "usleep "
-      "validatestring "
-      "values "
-      "vander "
-      "var "
-      "var_test "
-      "varargin "
-      "varargout "
-      "vec "
-      "vech "
-      "vectorize "
-      "ver "
-      "version "
-      "vertcat "
-      "view "
-      "voronoi "
-      "voronoin "
-      "waitforbuttonpress "
-      "waitpid "
-      "warning "
-      "warning_ids "
-      "warranty "
-      "wavread "
-      "wavwrite "
-      "wblcdf "
-      "wblinv "
-      "wblpdf "
-      "wblrnd "
-      "weekday "
-      "weibcdf "
-      "weibinv "
-      "weibpdf "
-      "weibrnd "
-      "welch_test "
-      "what "
-      "which "
-      "while "
-      "white "
-      "whitebg "
-      "who "
-      "whos "
-      "whos_line_format "
-      "wienrnd "
-      "wilcoxon_test "
-      "wilkinson "
-      "winter "
-      "xlabel "
-      "xlim "
-      "xor "
-      "yes_or_no "
-      "ylabel "
-      "ylim "
-      "yulewalker "
-      "z_test "
-      "z_test_2 "
-      "zeros "
-      "zip "
-      "zlabel "
-      "zlim ";
-  /*            "break case catch continue do else elseif end end_unwind_protect "
-              "endfor endfunction endif endswitch endwhile for function "
-              "global if otherwise persistent return switch try until "
-              "unwind_protect unwind_protect_cleanup while";
-  */
-}
--- a/libgui/src/resource-manager.h
+++ b/libgui/src/resource-manager.h
@@ -81,8 +81,6 @@
     return instance_ok () ? instance->do_is_first_run () : true;
   }
 
-  static const char *octave_keywords (void);
-  
   static QString storage_class_chars (void) { return "afghip"; }
   static QStringList storage_class_names (void);
   static QList<QColor> storage_class_default_colors (void);
--- a/libinterp/Makefile.am
+++ b/libinterp/Makefile.am
@@ -20,8 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-AUTOMAKE_OPTIONS = subdir-objects
-
 ## Search local directories before those specified by the user.
 AM_CPPFLAGS = \
   -I$(top_srcdir)/liboctave/cruft/misc \
@@ -51,6 +49,9 @@
   corefcn/defaults.h \
   corefcn/graphics-props.cc \
   corefcn/graphics.h \
+  corefcn/oct-tex-lexer.cc \
+  corefcn/oct-tex-parser.cc \
+  corefcn/oct-tex-symbols.cc \
   operators/ops.cc \
   parse-tree/lex.cc \
   parse-tree/oct-gperf.h \
@@ -62,6 +63,9 @@
   builtins.cc
 
 BUILT_DISTFILES = \
+  corefcn/oct-tex-lexer.ll \
+  corefcn/oct-tex-parser.h \
+  corefcn/oct-tex-symbols.cc \
   parse-tree/oct-gperf.h \
   parse-tree/oct-parse.h \
   parse-tree/oct-parse.yy
@@ -96,7 +100,6 @@
   mkdefs \
   mkops \
   oct-conf.in.h \
-  parse-tree/oct-parse.in.yy \
   version.in.h \
   $(BUILT_DISTFILES)
 
@@ -124,7 +127,8 @@
   $(OCTAVE_VALUE_SRC) \
   $(PARSE_TREE_SRC) \
   $(PARSER_SRC) \
-  $(COREFCN_SRC)
+  $(COREFCN_SRC) \
+  $(TEX_PARSER_SRC)
 
 noinst_LTLIBRARIES =
 
@@ -175,6 +179,7 @@
   parse-tree/libparse-tree.la \
   parse-tree/libparser.la \
   corefcn/libcorefcn.la \
+  corefcn/libtex_parser.la \
   $(top_builddir)/liboctave/liboctave.la \
   $(LIBOCTINTERP_LINK_DEPS)
 
@@ -194,7 +199,7 @@
 ## Section for defining and creating DEF_FILES
 
 ULT_DIST_SRC := \
-  $(filter-out parse-tree/oct-parse.yy, $(DIST_SRC)) parse-tree/oct-parse.in.yy
+  $(filter-out corefcn/oct-tex-lexer.ll parse-tree/oct-parse.yy, $(DIST_SRC)) corefcn/oct-tex-lexer.in.ll parse-tree/oct-parse.in.yy
 
 SRC_DEF_FILES := $(shell $(srcdir)/find-defun-files.sh "$(srcdir)" $(ULT_DIST_SRC))
 
@@ -248,7 +253,7 @@
 ## though we don't want it.  It would be super awesome if automake
 ## would allow users to choose the header file extension.
 .yy.cc:
-	$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
+	$(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h $*.h y.output $*.output -- $(YACCCOMPILE)
 
 ## Special rules:
 ## Mostly for sources which must be built before rest of compilation.
@@ -316,7 +321,7 @@
 
 if AMCOND_ENABLE_DYNAMIC_LINKING
 install-oct:
-	$(top_srcdir)/build-aux/mkinstalldirs $(DESTDIR)$(octfiledir)
+	$(MKDIR_P) $(DESTDIR)$(octfiledir)
 	if [ -n "`cat $(DLDFCN_PKG_ADD_FILE)`" ]; then \
 	  $(INSTALL_DATA) $(DLDFCN_PKG_ADD_FILE) $(DESTDIR)$(octfiledir)/PKG_ADD; \
 	fi
@@ -357,6 +362,7 @@
 CLEANFILES = \
   $(DLDFCN_PKG_ADD_FILE) \
   corefcn/graphics-props.cc \
+  corefcn/oct-tex-parser.output \
   parse-tree/oct-parse.output
 
 DISTCLEANFILES = \
--- a/libinterp/corefcn/balance.cc
+++ b/libinterp/corefcn/balance.cc
@@ -75,10 +75,10 @@
 The eigenvalue balancing option @var{opt} may be one of:\n\
 \n\
 @table @asis\n\
-@item \"noperm\", \"S\"\n\
+@item @qcode{\"noperm\"}, @qcode{\"S\"}\n\
 Scale only; do not permute.\n\
 \n\
-@item \"noscal\", \"P\"\n\
+@item @qcode{\"noscal\"}, @qcode{\"P\"}\n\
 Permute only; do not scale.\n\
 @end table\n\
 \n\
--- a/libinterp/corefcn/besselj.cc
+++ b/libinterp/corefcn/besselj.cc
@@ -649,11 +649,10 @@
 }
 
 /*
-%! # Test values computed with GP/PARI version 2.3.3
-%!
+## Test values computed with GP/PARI version 2.3.3
 %!shared alpha, x, jx, yx, ix, kx, nix
 %!
-%! # Bessel functions, even order, positive and negative x
+%! ## Bessel functions, even order, positive and negative x
 %! alpha = 2;  x = 1.25;
 %! jx = 0.1710911312405234823613091417;
 %! yx = -1.193199310178553861283790424;
@@ -706,7 +705,7 @@
 %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
 %!
-%! # Bessel functions, odd order, positive and negative x
+%! ## Bessel functions, odd order, positive and negative x
 %! alpha = 3;  x = 2.5;
 %! jx = 0.2166003910391135247666890035;
 %! yx = -0.7560554967536709968379029772;
@@ -761,7 +760,7 @@
 %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
 %!
-%! # Bessel functions, fractional order, positive and negative x
+%! ## Bessel functions, fractional order, positive and negative x
 %!
 %! alpha = 3.5;  x = 2.75;
 %! jx = 0.1691636439842384154644784389;
@@ -819,7 +818,7 @@
 %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
 %!
-%! # Bessel functions, even order, complex x
+%! ## Bessel functions, even order, complex x
 %!
 %! alpha = 2;  x = 1.25 + 3.625 * I;
 %! jx = -1.299533366810794494030065917 + 4.370833116012278943267479589*I;
@@ -855,7 +854,7 @@
 %!assert (besselh (-alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (-alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
 %!
-%! # Bessel functions, odd order, complex x
+%! ## Bessel functions, odd order, complex x
 %!
 %! alpha = 3; x = 2.5 + 1.875 * I;
 %! jx = 0.1330721523048277493333458596 + 0.5386295217249660078754395597*I;
@@ -891,7 +890,7 @@
 %!assert (besselh (-alpha,1,x,1), -(jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (-alpha,2,x,1), -(jx - I*yx)*exp(I*x), 100*eps)
 %!
-%! # Bessel functions, fractional order, complex x
+%! ## Bessel functions, fractional order, complex x
 %!
 %! alpha = 3.5;  x = 1.75 + 4.125 * I;
 %! jx = -3.018566131370455929707009100 - 0.7585648436793900607704057611*I;
@@ -913,7 +912,7 @@
 %!assert (besselh (alpha,1,x,1), (jx + I*yx)*exp(-I*x), 100*eps)
 %!assert (besselh (alpha,2,x,1), (jx - I*yx)*exp(I*x), 100*eps)
 %!
-%!  nix = 0.09822388691172060573913739253 - 0.7110230642207380127317227407*I;
+%! nix = 0.09822388691172060573913739253 - 0.7110230642207380127317227407*I;
 %!
 %!assert (besselj (-alpha,x), yx, 100*eps)
 %!assert (bessely (-alpha,x), -jx, 100*eps)
--- a/libinterp/corefcn/bitfcns.cc
+++ b/libinterp/corefcn/bitfcns.cc
@@ -24,6 +24,8 @@
 #include <config.h>
 #endif
 
+#include <limits>
+
 #include "str-vec.h"
 #include "quit.h"
 
@@ -38,6 +40,7 @@
 #include "ov-int32.h"
 #include "ov-int16.h"
 #include "ov-int8.h"
+#include "ov-float.h"
 #include "ov-scalar.h"
 #include "ov-re-mat.h"
 #include "ov-bool.h"
@@ -138,25 +141,55 @@
   if (nargin == 2)
     {
       if ((args(0).class_name () == octave_scalar::static_class_name ())
+          || (args(0).class_name () == octave_float_scalar::static_class_name ())
           || (args(0).class_name () == octave_bool::static_class_name ())
           || (args(1).class_name () == octave_scalar::static_class_name ())
+          || (args(1).class_name () == octave_float_scalar::static_class_name ())
           || (args(1).class_name () == octave_bool::static_class_name ()))
         {
           bool arg0_is_int = (args(0).class_name () !=
                               octave_scalar::static_class_name () &&
                               args(0).class_name () !=
+                              octave_float_scalar::static_class_name () &&
+                              args(0).class_name () !=
                               octave_bool::static_class_name ());
           bool arg1_is_int = (args(1).class_name () !=
                               octave_scalar::static_class_name () &&
                               args(1).class_name () !=
+                              octave_float_scalar::static_class_name () &&
+                              args(1).class_name () !=
                               octave_bool::static_class_name ());
+          bool arg0_is_float = args(0).class_name () ==
+                               octave_float_scalar::static_class_name ();
+          bool arg1_is_float = args(1).class_name () ==
+                               octave_float_scalar::static_class_name ();
 
           if (! (arg0_is_int || arg1_is_int))
             {
-              uint64NDArray x (args(0).array_value ());
-              uint64NDArray y (args(1).array_value ());
-              if (! error_state)
-                retval = bitopx (fname, x, y).array_value ();
+              if (! (arg0_is_float || arg1_is_float))
+                {
+                  uint64NDArray x (args(0).array_value ());
+                  uint64NDArray y (args(1).array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).array_value ();
+                }
+              else if (arg0_is_float && arg1_is_float)
+                {
+                  uint64NDArray x (args(0).float_array_value ());
+                  uint64NDArray y (args(1).float_array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).float_array_value ();
+                }
+              else
+                {
+                  int p = (arg0_is_float ? 1 : 0);
+                  int q = (arg0_is_float ? 0 : 1);
+
+                  uint64NDArray x (args(p).array_value ());
+                  uint64NDArray y (args(q).float_array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).float_array_value ();
+                }
             }
           else
             {
@@ -344,6 +377,13 @@
   return bitop ("bitxor", args);
 }
 
+template <typename T>
+static int64_t
+max_mantissa_value ()
+{
+  return (static_cast<int64_t> (1) << std::numeric_limits<T>::digits) - 1;
+}
+
 static int64_t
 bitshift (double a, int n, int64_t mask)
 {
@@ -543,16 +583,30 @@
         DO_SBITSHIFT (int64, nbits < 64 ? nbits : 64);
       else if (cname == "double")
         {
-          nbits = (nbits < 53 ? nbits : 53);
-          int64_t mask = 0x1FFFFFFFFFFFFFLL;
-          if (nbits < 53)
-            mask = mask >> (53 - nbits);
+          static const int bits_in_mantissa = std::numeric_limits<double>::digits;
+          nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
+          int64_t mask = max_mantissa_value<double> ();
+          if (nbits < bits_in_mantissa)
+            mask = mask >> (bits_in_mantissa - nbits);
           else if (nbits < 1)
             mask = 0;
-          int bits_in_type = 64;
+          int bits_in_type = sizeof (double) * std::numeric_limits<unsigned char>::digits;
           NDArray m = m_arg.array_value ();
           DO_BITSHIFT ( );
         }
+      else if (cname == "single")
+        {
+          static const int bits_in_mantissa = std::numeric_limits<float>::digits;
+          nbits = (nbits < bits_in_mantissa ? nbits : bits_in_mantissa);
+          int64_t mask = max_mantissa_value<float> ();
+          if (nbits < bits_in_mantissa)
+            mask = mask >> (bits_in_mantissa - nbits);
+          else if (nbits < 1)
+            mask = 0;
+          int bits_in_type = sizeof (float) * std::numeric_limits<unsigned char>::digits;
+          FloatNDArray m = m_arg.float_array_value ();
+          DO_BITSHIFT (Float);
+        }
       else
         error ("bitshift: not defined for %s objects", cname.c_str ());
     }
@@ -567,15 +621,12 @@
 @deftypefn  {Built-in Function} {} bitmax ()\n\
 @deftypefnx {Built-in Function} {} bitmax (\"double\")\n\
 @deftypefnx {Built-in Function} {} bitmax (\"single\")\n\
-@deftypefnx {Built-in Function} {} flintmax (@dots{})\n\
 Return the largest integer that can be represented within a floating point\n\
-value.  The default class is \"double\", but \"single\" is a valid option.\n\
-On IEEE-754 compatible systems, @code{bitmax} is @w{@math{2^{53} - 1}} for\n\
-\"double\" and @w{@math{2^{24} -1}} for \"single\".\n\
-\n\
-@code{flintmax} for FLoating point INTeger MAXimum is an alias for\n\
-@code{bitmax}.\n\
-@seealso{intmax, realmax, realmin}\n\
+value.  The default class is @qcode{\"double\"}, but @qcode{\"single\"} is a\n\
+valid option.  On IEEE-754 compatible systems, @code{bitmax} is\n\
+@w{@math{2^{53} - 1}} for @qcode{\"double\"} and @w{@math{2^{24} -1}} for\n\
+@qcode{\"single\"}.\n\
+@seealso{flintmax, intmax, realmax, realmin}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -591,16 +642,48 @@
     }
 
   if (cname == "double")
-    retval = (static_cast<double> (0x1FFFFFFFFFFFFFLL));
+    retval = (static_cast<double> (max_mantissa_value<double> ()));
   else if (cname == "single")
-    retval = (static_cast<double> (0xFFFFFFL));
+    retval = (static_cast<float> (max_mantissa_value<float> ()));
   else
     error ("bitmax: not defined for class '%s'", cname.c_str ());
 
   return retval;
 }
 
-DEFALIAS(flintmax, bitmax)
+DEFUN (flintmax, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {} flintmax ()\n\
+@deftypefnx {Built-in Function} {} flintmax (\"double\")\n\
+@deftypefnx {Built-in Function} {} flintmax (\"single\")\n\
+Return the largest integer that can be represented consecutively in a\n\
+floating point value.  The default class is @qcode{\"double\"}, but @qcode{\"single\"}\n\
+is a valid option.  On IEEE-754 compatible systems, @code{flintmax} is @w{@math{2^53}}\n\
+for @qcode{\"double\"} and @w{@math{2^24}} for @qcode{\"single\"}.\n\
+@seealso{bitmax, intmax, realmax, realmin}\n\
+@end deftypefn")
+{
+  octave_value retval;
+  std::string cname = "double";
+  int nargin = args.length ();
+
+  if (nargin == 1 && args(0).is_string ())
+    cname = args(0).string_value ();
+  else if (nargin != 0)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (cname == "double")
+    retval = (static_cast<double> (max_mantissa_value<double> () + 1));
+  else if (cname == "single")
+    retval = (static_cast<float> (max_mantissa_value<float> () + 1));
+  else
+    error ("flintmax: not defined for class '%s'", cname.c_str ());
+
+  return retval;
+}
 
 DEFUN (intmax, args, ,
   "-*- texinfo -*-\n\
@@ -635,7 +718,7 @@
 @end table\n\
 \n\
 The default for @var{type} is @code{uint32}.\n\
-@seealso{intmin, bitmax}\n\
+@seealso{intmin, flintmax, bitmax}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -705,7 +788,7 @@
 @end table\n\
 \n\
 The default for @var{type} is @code{uint32}.\n\
-@seealso{intmax, bitmax}\n\
+@seealso{intmax, flintmax, bitmax}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/corefcn/bsxfun.cc
+++ b/libinterp/corefcn/bsxfun.cc
@@ -773,12 +773,12 @@
 %% Test automatic bsxfun
 %
 %!test
-%! funs = {@plus, @minus, @times, @rdivide, @ldivide, @power, @max, @min, \
-%!         @rem, @mod, @atan2, @hypot, @eq, @ne, @lt, @le, @gt, @ge, \
+%! funs = {@plus, @minus, @times, @rdivide, @ldivide, @power, @max, @min, ...
+%!         @rem, @mod, @atan2, @hypot, @eq, @ne, @lt, @le, @gt, @ge, ...
 %!         @and, @or, @xor };
 %!
 %! float_types = {@single, @double};
-%! int_types = {@int8, @int16, @int32, @int64, \
+%! int_types = {@int8, @int16, @int32, @int64, ...
 %!              @uint8, @uint16, @uint32, @uint64};
 %!
 %! x = rand (3) * 10-5;
@@ -792,19 +792,19 @@
 %!       f_type = float_types{j};
 %!       i_type = int_types{k};
 %!
-%!         assert (bsxfun (fun, f_type (x), i_type (y)), \
+%!         assert (bsxfun (fun, f_type (x), i_type (y)), ...
 %!                 fun (f_type(x), i_type (y)));
-%!         assert (bsxfun (fun, f_type (y), i_type (x)), \
+%!         assert (bsxfun (fun, f_type (y), i_type (x)), ...
 %!                 fun (f_type(y), i_type (x)));
 %!
-%!         assert (bsxfun (fun, i_type (x), i_type (y)), \
+%!         assert (bsxfun (fun, i_type (x), i_type (y)), ...
 %!                 fun (i_type (x), i_type (y)));
-%!         assert (bsxfun (fun, i_type (y), i_type (x)), \
+%!         assert (bsxfun (fun, i_type (y), i_type (x)), ...
 %!                 fun (i_type (y), i_type (x)));
 %!
-%!         assert (bsxfun (fun, f_type (x), f_type (y)), \
+%!         assert (bsxfun (fun, f_type (x), f_type (y)), ...
 %!                 fun (f_type (x), f_type (y)));
-%!         assert (bsxfun (fun, f_type(y), f_type(x)), \
+%!         assert (bsxfun (fun, f_type(y), f_type(x)), ...
 %!                 fun (f_type (y), f_type (x)));
 %!     endfor
 %!   endfor
--- a/libinterp/corefcn/cellfun.cc
+++ b/libinterp/corefcn/cellfun.cc
@@ -297,7 +297,7 @@
 @item ndims\n\
 Return the number of dimensions of each element.\n\
 \n\
-@item numel\n\
+@item  numel\n\
 @itemx prodofsize\n\
 Return the number of elements contained within each cell element.  The\n\
 number is the product of the dimensions of the object at each cell element.\n\
@@ -347,10 +347,10 @@
 the input arguments.  Input arguments that are singleton (1x1) cells will be\n\
 automatically expanded to the size of the other arguments.\n\
 \n\
-If the parameter \"UniformOutput\" is set to true (the default), then the\n\
-function must return scalars which will be concatenated into the return\n\
-array(s).  If \"UniformOutput\" is false, the outputs are concatenated into a\n\
-cell array (or cell arrays).  For example:\n\
+If the parameter @qcode{\"UniformOutput\"} is set to true (the default),\n\
+then the function must return scalars which will be concatenated into the\n\
+return array(s).  If @qcode{\"UniformOutput\"} is false, the outputs are\n\
+concatenated into a cell array (or cell arrays).  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -360,8 +360,9 @@
 @end group\n\
 @end example\n\
 \n\
-Given the parameter \"ErrorHandler\", then @var{errfunc} defines a function\n\
-to call in case @var{func} generates an error.  The form of the function is\n\
+Given the parameter @qcode{\"ErrorHandler\"}, then @var{errfunc} defines a\n\
+function to call in case @var{func} generates an error.  The form of the\n\
+function is\n\
 \n\
 @example\n\
 function [@dots{}] = errfunc (@var{s}, @dots{})\n\
@@ -370,9 +371,9 @@
 @noindent\n\
 where there is an additional input argument to @var{errfunc} relative to\n\
 @var{func}, given by @var{s}.  This is a structure with the elements\n\
-'identifier', 'message' and 'index', giving respectively the error\n\
-identifier, the error message, and the index into the input arguments\n\
-of the element that caused the error.  For example:\n\
+@qcode{\"identifier\"}, @qcode{\"message\"} and @qcode{\"index\"}, giving\n\
+respectively the error identifier, the error message, and the index into the\n\
+input arguments of the element that caused the error.  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -816,7 +817,7 @@
 %! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5});
 %! assert (A, [6, 7, 8]);
 %!test
-%! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}, \
+%! A = cellfun (@(x,y,z) x + y + z, {1, 1, 1}, {2, 2, 2}, {3, 4, 5}, ...
 %!              "UniformOutput", false);
 %! assert (A, {6, 7, 8});
 %!test %% Two input arguments of different types
@@ -837,20 +838,20 @@
 %! A = cellfun (@(x,y) x == y, {false, true}, {true, true});
 %! assert (A, [false, true]);
 %!test
-%! A = cellfun (@(x,y) x == y, {false; true}, {true; true}, \
+%! A = cellfun (@(x,y) x == y, {false; true}, {true; true}, ...
 %!              "UniformOutput", true);
 %! assert (A, [false; true]);
 %!test
 %! A = cellfun (@(x) x, {false, true; false, true}, "UniformOutput", false);
 %! assert (A, {false, true; false, true});
 %!test %% Three ouptut arguments of same type
-%! [A, B, C] = cellfun (@find, {true, false; false, true}, \
+%! [A, B, C] = cellfun (@find, {true, false; false, true}, ...
 %!                      "UniformOutput", false);
 %! assert (isequal (A, {true, []; [], true}));
 %! assert (isequal (B, {true, []; [], true}));
 %! assert (isequal (C, {true, []; [], true}));
 %!test
-%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, ...
 %!              "ErrorHandler", @__cellfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -858,7 +859,7 @@
 %! assert (isempty (A.message), false);
 %! assert (A.index, 1);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {true}, {true}, ...
 %!              "UniformOutput", true, "ErrorHandler", @__cellfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -871,7 +872,7 @@
 %! A = cellfun (@(x,y) x>y, {1.1, 4.2}, {3.1, 2+3*i});
 %! assert (A, [false, true]);
 %!test
-%! A = cellfun (@(x,y) x>y, {1.1, 4.2; 2, 4}, {3.1, 2; 2, 4+2*i}, \
+%! A = cellfun (@(x,y) x>y, {1.1, 4.2; 2, 4}, {3.1, 2; 2, 4+2*i}, ...
 %!              "UniformOutput", true);
 %! assert (A, [false, true; false, false]);
 %!test
@@ -884,7 +885,7 @@
 %! assert (isequal (B, {true, true; [], true}));
 %! assert (isequal (C, {10, 11; [], 12}));
 %!test
-%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, ...
 %!              "ErrorHandler", @__cellfunerror);
 %! B = isfield (A(1), "message") && isfield (A(1), "index");
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
@@ -893,7 +894,7 @@
 %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
 %! assert ([A(1).index, A(2).index], [1, 2]);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {1.1, 4}, {3.1, 6}, ...
 %!              "UniformOutput", true, "ErrorHandler", @__cellfunerror);
 %! B = isfield (A(1), "message") && isfield (A(1), "index");
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
@@ -912,7 +913,7 @@
 %! A = cellfun (@(x,y) x:y, {"a", "d"}, {"c", "f"}, "UniformOutput", false);
 %! assert (A, {"abc", "def"});
 %!test
-%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, ...
 %!              "ErrorHandler", @__cellfunerror);
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
 %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
@@ -920,7 +921,7 @@
 %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
 %! assert ([A(1).index, A(2).index], [1, 2]);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, \
+%! A = cellfun (@(x,y) cell2str (x,y), {"a", "d"}, {"c", "f"}, ...
 %!              "UniformOutput", true, "ErrorHandler", @__cellfunerror);
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
 %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
@@ -938,15 +939,15 @@
 %! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}});
 %! assert (A, [1, 0], 1e-16);
 %!test
-%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}; {4.2}}, {{3.1}; {2}}, \
+%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}; {4.2}}, {{3.1}; {2}}, ...
 %!              "UniformOutput", true);
 %! assert (A, [1; 0], 1e-16);
 %!test
-%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%! A = cellfun (@(x,y) x{1} < y{1}, {{1.1}, {4.2}}, {{3.1}, {2}}, ...
 %!              "UniformOutput", false);
 %! assert (A, {true, false});
 %!test
-%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, ...
 %!              "ErrorHandler", @__cellfunerror);
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
 %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
@@ -954,7 +955,7 @@
 %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
 %! assert ([A(1).index, A(2).index], [1, 2]);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, \
+%! A = cellfun (@(x,y) mat2str (x,y), {{1.1}, {4.2}}, {{3.1}, {2}}, ...
 %!              "UniformOutput", true, "ErrorHandler", @__cellfunerror);
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
 %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
@@ -969,17 +970,17 @@
 %! assert (A, true);
 %!test
 %! a = struct ("a", 1, "b", 2);  b = struct ("a", 1, "b", 3);
-%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \
+%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, ...
 %!              "UniformOutput", true);
 %! assert (A, true);
 %!test
 %! a = struct ("a", 1, "b", 2);  b = struct ("a", 1, "b", 3);
-%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, \
+%! A = cellfun (@(x,y) (x.a == y.a) && (x.b < y.b) , {a}, {b}, ...
 %!              "UniformOutput", false);
 %! assert (A, {true});
 %!test
 %! a = struct ("a", 1, "b", 2);  b = struct ("a", 1, "b", 3);
-%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \
+%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, ...
 %!              "ErrorHandler", @__cellfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -988,7 +989,7 @@
 %! assert (A.index, 1);
 %!test %% Overwriting setting of "UniformOutput" true
 %! a = struct ("a", 1, "b", 2);  b = struct ("a", 1, "b", 3);
-%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, \
+%! A = cellfun (@(x,y) cell2str (x.a, y.a), {a}, {b}, ...
 %!              "UniformOutput", true, "ErrorHandler", @__cellfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -1070,7 +1071,7 @@
 @end example\n\
 \n\
 If the parameter @var{val} after a further string input argument\n\
-\"UniformOutput\" is set @code{true} (the default), then the named\n\
+@qcode{\"UniformOutput\"} is set @code{true} (the default), then the named\n\
 function @var{func} must return a single element which then will be\n\
 concatenated into the return value and is of type matrix.  Otherwise,\n\
 if that parameter is set to @code{false}, then the outputs are\n\
@@ -1115,7 +1116,7 @@
 @end example\n\
 \n\
 If the parameter @var{errfunc} after a further string input argument\n\
-\"ErrorHandler\" is another string, a function handle, an inline\n\
+@qcode{\"ErrorHandler\"} is another string, a function handle, an inline\n\
 function, or an anonymous function, then @var{errfunc} defines a\n\
 function to call in the case that @var{func} generates an error.\n\
 The definition of the function must be of the form\n\
@@ -1127,11 +1128,11 @@
 @noindent\n\
 where there is an additional input argument to @var{errfunc}\n\
 relative to @var{func}, given by @var{s}.  This is a structure with\n\
-the elements \"identifier\", \"message\", and \"index\" giving,\n\
-respectively, the error identifier, the error message, and the index of\n\
-the array elements that caused the error.  The size of the output\n\
-argument of @var{errfunc} must have the same size as the output\n\
-argument of @var{func}, otherwise a real error is thrown.  For\n\
+the elements @qcode{\"identifier\"}, @qcode{\"message\"}, and\n\
+@qcode{\"index\"} giving, respectively, the error identifier, the error\n\
+message, and the index of the array elements that caused the error.  The\n\
+size of the output argument of @var{errfunc} must have the same size as the\n\
+output argument of @var{func}, otherwise a real error is thrown.  For\n\
 example:\n\
 \n\
 @example\n\
@@ -1559,7 +1560,7 @@
 %! assert (isequal (B, {true, []; [], true}));
 %! assert (isequal (C, {true, []; [], true}));
 %!test
-%! A = arrayfun (@(x,y) array2str (x,y), true, true, \
+%! A = arrayfun (@(x,y) array2str (x,y), true, true, ...
 %!               "ErrorHandler", @__arrayfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -1567,7 +1568,7 @@
 %! assert (isempty (A.message), false);
 %! assert (A.index, 1);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = arrayfun (@(x,y) array2str (x,y), true, true, "UniformOutput", true, \
+%! A = arrayfun (@(x,y) array2str (x,y), true, true, "UniformOutput", true, ...
 %!               "ErrorHandler", @__arrayfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -1592,7 +1593,7 @@
 %! assert (isequal (B, {true, true; [], true}));
 %! assert (isequal (C, {10, 11; [], 12}));
 %!test
-%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, \
+%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, ...
 %!               "ErrorHandler", @__arrayfunerror);
 %! B = isfield (A(1), "message") && isfield (A(1), "index");
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
@@ -1601,7 +1602,7 @@
 %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
 %! assert ([A(1).index, A(2).index], [1, 2]);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, \
+%! A = arrayfun (@(x,y) array2str (x,y), {1.1, 4}, {3.1, 6}, ...
 %!               "UniformOutput", true, "ErrorHandler", @__arrayfunerror);
 %! B = isfield (A(1), "message") && isfield (A(1), "index");
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
@@ -1621,7 +1622,7 @@
 %! A = arrayfun (@(x,y) x:y, ["a", "d"], ["c", "f"], "UniformOutput", false);
 %! assert (A, {"abc", "def"});
 %!test
-%! A = arrayfun (@(x,y) cell2str (x,y), ["a", "d"], ["c", "f"], \
+%! A = arrayfun (@(x,y) cell2str (x,y), ["a", "d"], ["c", "f"], ...
 %!               "ErrorHandler", @__arrayfunerror);
 %! B = isfield (A(1), "identifier") && isfield (A(1), "message") && isfield (A(1), "index");
 %! assert (B, true);
@@ -1647,7 +1648,7 @@
 %! assert (isempty (A.message), false);
 %! assert (A.index, 1);
 %!test %% Overwriting setting of "UniformOutput" true
-%! A = arrayfun (@(x) mat2str(x), "a", "UniformOutput", true, \
+%! A = arrayfun (@(x) mat2str(x), "a", "UniformOutput", true, ...
 %!               "ErrorHandler", @__arrayfunerror);
 %! assert (isfield (A, "identifier"), true);
 %! assert (isfield (A, "message"), true);
@@ -1673,7 +1674,7 @@
 %! assert ([(isempty (A(1).message)), (isempty (A(2).message))], [false, false]);
 %! assert ([A(1).index, A(2).index], [1, 2]);
 %!test
-%! A = arrayfun (@(x,y) num2str (x,y), {1.1, 4.2}, {3.1, 2}, \
+%! A = arrayfun (@(x,y) num2str (x,y), {1.1, 4.2}, {3.1, 2}, ...
 %!               "UniformOutput", true, "ErrorHandler", @__arrayfunerror);
 %! assert ([(isfield (A(1), "identifier")), (isfield (A(2), "identifier"))], [true, true]);
 %! assert ([(isfield (A(1), "message")), (isfield (A(2), "message"))], [true, true]);
@@ -2229,7 +2230,7 @@
       bool sparse = a.is_sparse_type ();
       if (sparse && nargin > 3)
         {
-          error ("mat2cell: sparse arguments only support 2D indexing");
+          error ("mat2cell: sparse arguments only support 2-D indexing");
           return retval;
         }
 
--- a/libinterp/corefcn/conv2.cc
+++ b/libinterp/corefcn/conv2.cc
@@ -44,15 +44,15 @@
 values\n\
 \n\
 @table @asis\n\
-@item @var{shape} = \"full\"\n\
+@item @var{shape} = @qcode{\"full\"}\n\
 Return the full convolution.  (default)\n\
 \n\
-@item @var{shape} = \"same\"\n\
+@item @var{shape} = @qcode{\"same\"}\n\
 Return the central part of the convolution with the same size as @var{A}.\n\
 The central part of the convolution begins at the indices\n\
 @code{floor ([size(@var{B})/2] + 1)}.\n\
 \n\
-@item @var{shape} = \"valid\"\n\
+@item @var{shape} = @qcode{\"valid\"}\n\
 Return only the parts which do not include zero-padded edges.\n\
 The size of the result is @code{max (size (A) - size (B) + 1, 0)}.\n\
 @end table\n\
@@ -277,7 +277,7 @@
 %! y = ones (5);
 %! A = conv2 (x, y)(5:end-4,5:end-4);
 %! B = conv2 (x, y, "valid");
-%! assert (B, A); ## Yes, this test is for *exact* equivalence.
+%! assert (B, A);   # Yes, this test is for *exact* equivalence.
 
 
 %% Test input validation
@@ -299,15 +299,15 @@
 values\n\
 \n\
 @table @asis\n\
-@item @var{shape} = \"full\"\n\
+@item @var{shape} = @qcode{\"full\"}\n\
 Return the full convolution.  (default)\n\
 \n\
-@item @var{shape} = \"same\"\n\
+@item @var{shape} = @qcode{\"same\"}\n\
 Return central part of the convolution with the same size as @var{A}.\n\
 The central part of the convolution begins at the indices\n\
 @code{floor ([size(@var{B})/2] + 1)}.\n\
 \n\
-@item @var{shape} = \"valid\"\n\
+@item @var{shape} = @qcode{\"valid\"}\n\
 Return only the parts which do not include zero-padded edges.\n\
 The size of the result is @code{max (size (A) - size (B) + 1, 0)}.\n\
 @end table\n\
--- a/libinterp/corefcn/data.cc
+++ b/libinterp/corefcn/data.cc
@@ -1095,8 +1095,8 @@
 Cumulative sum of elements along dimension @var{dim}.  If @var{dim}\n\
 is omitted, it defaults to the first non-singleton dimension.\n\
 \n\
-See @code{sum} for an explanation of the optional parameters \"native\",\n\
-\"double\", and \"extra\".\n\
+See @code{sum} for an explanation of the optional parameters\n\
+@qcode{\"native\"}, @qcode{\"double\"}, and @qcode{\"extra\"}.\n\
 @seealso{sum, cumprod}\n\
 @end deftypefn")
 {
@@ -2375,10 +2375,13 @@
 DEFUN (length, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} length (@var{a})\n\
-Return the \"length\" of the object @var{a}.  For matrix objects, the\n\
-length is the number of rows or columns, whichever is greater (this\n\
-odd definition is used for compatibility with @sc{matlab}).\n\
-@seealso{size}\n\
+Return the length of the object @var{a}.\n\
+\n\
+The length is 0 for empty objects, 1 for scalars, and the number of elements\n\
+for vectors.  For matrix objects, the length is the number of rows or\n\
+columns, whichever is greater (this odd definition is used for compatibility\n\
+with @sc{matlab}).\n\
+@seealso{numel, size}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -2671,9 +2674,9 @@
 Sum of elements along dimension @var{dim}.  If @var{dim} is\n\
 omitted, it defaults to the first non-singleton dimension.\n\
 \n\
-If the optional argument \"native\" is given, then the sum is performed\n\
-in the same type as the original argument, rather than in the default\n\
-double type.  For example:\n\
+If the optional argument @qcode{\"native\"} is given, then the sum is\n\
+performed in the same type as the original argument, rather than in the\n\
+default double type.  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -2684,13 +2687,13 @@
 @end group\n\
 @end example\n\
 \n\
-On the contrary, if \"double\" is given, the sum is performed in double\n\
-precision even for single precision inputs.\n\
-\n\
-For double precision inputs, \"extra\" indicates that a more accurate\n\
+On the contrary, if @qcode{\"double\"} is given, the sum is performed in\n\
+double precision even for single precision inputs.\n\
+\n\
+For double precision inputs, @qcode{\"extra\"} indicates that a more accurate\n\
 algorithm than straightforward summation is to be used.  For single precision\n\
-inputs, \"extra\" is the same as \"double\".  Otherwise, \"extra\" has no\n\
-effect.\n\
+inputs, @qcode{\"extra\"} is the same as @qcode{\"double\"}.  Otherwise,\n\
+@qcode{\"extra\"} has no effect.\n\
 @seealso{cumsum, sumsq, prod}\n\
 @end deftypefn")
 {
@@ -3970,7 +3973,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{isinf, NaN}\n\
 @end deftypefn")
 {
@@ -4029,7 +4032,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{isnan, Inf}\n\
 @end deftypefn")
 {
@@ -4078,7 +4081,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{log, exp, pi, I}\n\
 @end deftypefn")
 {
@@ -4119,7 +4122,7 @@
 the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{realmax, realmin, intmax, bitmax}\n\
 @end deftypefn")
 {
@@ -4243,7 +4246,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{e, I}\n\
 @end deftypefn")
 {
@@ -4276,13 +4279,13 @@
 for single precision.\n\
 \n\
 When called with no arguments, return a scalar with the value\n\
-@code{realmax (\"double\")}.\n\
+@code{realmax (@qcode{\"double\"})}.\n\
 When called with a single argument, return a square matrix with the dimension\n\
 specified.  When called with more than one scalar argument the first two\n\
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{realmin, intmax, bitmax, eps}\n\
 @end deftypefn")
 {
@@ -4310,13 +4313,13 @@
 for single precision.\n\
 \n\
 When called with no arguments, return a scalar with the value\n\
-@code{realmin (\"double\")}.\n\
+@code{realmin (@qcode{\"double\"})}.\n\
 When called with a single argument, return a square matrix with the dimension\n\
 specified.  When called with more than one scalar argument the first two\n\
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{realmax, intmin, eps}\n\
 @end deftypefn")
 {
@@ -4354,7 +4357,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{e, pi, log, exp}\n\
 @end deftypefn")
 {
@@ -4384,7 +4387,7 @@
 arguments are taken as the number of rows and columns and any further\n\
 arguments specify additional matrix dimensions.\n\
 The optional argument @var{class} specifies the return type and may be\n\
-either \"double\" or \"single\".\n\
+either @qcode{\"double\"} or @qcode{\"single\"}.\n\
 @seealso{isna}\n\
 @end deftypefn")
 {
@@ -4783,9 +4786,9 @@
 %! assert (size (x2) == [1, 10] && x2(1) == 1 && x2(10) == 2);
 %! assert (size (x3) == [1, 10] && x3(1) == 1 && x3(10) == -2);
 
-%assert (linspace ([1, 2; 3, 4], 5, 6), linspace (1, 5, 6))
-
-%assert (linspace (0, 1, []), 1)
+%! ##assert (linspace ([1, 2; 3, 4], 5, 6), linspace (1, 5, 6))
+
+%!assert (linspace (0, 1, []), 1)
 
 %!error linspace ()
 %!error linspace (1, 2, 3, 4)
@@ -5144,11 +5147,11 @@
 @item @var{p} = @code{2}\n\
 Largest singular value of @var{A}.\n\
 \n\
-@item @var{p} = @code{Inf} or @code{\"inf\"}\n\
+@item @var{p} = @code{Inf} or @qcode{\"inf\"}\n\
 @cindex infinity norm\n\
 Infinity norm, the largest row sum of the absolute values of @var{A}.\n\
 \n\
-@item @var{p} = @code{\"fro\"}\n\
+@item @var{p} = @qcode{\"fro\"}\n\
 @cindex Frobenius norm\n\
 Frobenius norm of @var{A}, @code{sqrt (sum (diag (@var{A}' * @var{A})))}.\n\
 \n\
@@ -5160,13 +5163,13 @@
 If @var{A} is a vector or a scalar:\n\
 \n\
 @table @asis\n\
-@item @var{p} = @code{Inf} or @code{\"inf\"}\n\
+@item @var{p} = @code{Inf} or @qcode{\"inf\"}\n\
 @code{max (abs (@var{A}))}.\n\
 \n\
 @item @var{p} = @code{-Inf}\n\
 @code{min (abs (@var{A}))}.\n\
 \n\
-@item @var{p} = @code{\"fro\"}\n\
+@item @var{p} = @qcode{\"fro\"}\n\
 Frobenius norm of @var{A}, @code{sqrt (sumsq (abs (A)))}.\n\
 \n\
 @item @var{p} = 0\n\
@@ -5179,10 +5182,10 @@
 the p-pseudonorm defined as above.\n\
 @end table\n\
 \n\
-If @var{opt} is the value @code{\"rows\"}, treat each row as a vector and\n\
+If @var{opt} is the value @qcode{\"rows\"}, treat each row as a vector and\n\
 compute its norm.  The result is returned as a column vector.\n\
-Similarly, if @var{opt} is @code{\"columns\"} or @code{\"cols\"} then compute\n\
-the norms of each column and return a row vector.\n\
+Similarly, if @var{opt} is @qcode{\"columns\"} or @qcode{\"cols\"} then\n\
+compute the norms of each column and return a row vector.\n\
 @seealso{cond, svd}\n\
 @end deftypefn")
 {
@@ -5369,7 +5372,7 @@
 DEFUN (uplus, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} uplus (@var{x})\n\
-This function and @w{@xcode{+ x}} are equivalent.\n\
+This function and @w{@tcode{+ x}} are equivalent.\n\
 @seealso{uminus, plus, minus}\n\
 @end deftypefn")
 {
@@ -5379,7 +5382,7 @@
 DEFUN (uminus, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} uminus (@var{x})\n\
-This function and @w{@xcode{- x}} are equivalent.\n\
+This function and @w{@tcode{- x}} are equivalent.\n\
 @seealso{uplus, minus}\n\
 @end deftypefn")
 {
@@ -5390,7 +5393,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} transpose (@var{x})\n\
 Return the transpose of @var{x}.\n\
-This function and @xcode{x.'} are equivalent.\n\
+This function and @tcode{x.'} are equivalent.\n\
 @seealso{ctranspose}\n\
 @end deftypefn")
 {
@@ -5421,7 +5424,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} ctranspose (@var{x})\n\
 Return the complex conjugate transpose of @var{x}.\n\
-This function and @xcode{x'} are equivalent.\n\
+This function and @tcode{x'} are equivalent.\n\
 @seealso{transpose}\n\
 @end deftypefn")
 {
@@ -5495,7 +5498,7 @@
   "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} plus (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} plus (@var{x1}, @var{x2}, @dots{})\n\
-This function and @w{@xcode{x + y}} are equivalent.\n\
+This function and @w{@tcode{x + y}} are equivalent.\n\
 If more arguments are given, the summation is applied\n\
 cumulatively from left to right:\n\
 \n\
@@ -5514,7 +5517,7 @@
 DEFUN (minus, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} minus (@var{x}, @var{y})\n\
-This function and @w{@xcode{x - y}} are equivalent.\n\
+This function and @w{@tcode{x - y}} are equivalent.\n\
 @seealso{plus, uminus}\n\
 @end deftypefn")
 {
@@ -5526,7 +5529,7 @@
 @deftypefn  {Built-in Function} {} mtimes (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} mtimes (@var{x1}, @var{x2}, @dots{})\n\
 Return the matrix multiplication product of inputs.\n\
-This function and @w{@xcode{x * y}} are equivalent.\n\
+This function and @w{@tcode{x * y}} are equivalent.\n\
 If more arguments are given, the multiplication is applied\n\
 cumulatively from left to right:\n\
 \n\
@@ -5546,7 +5549,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} mrdivide (@var{x}, @var{y})\n\
 Return the matrix right division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x / y}} are equivalent.\n\
+This function and @w{@tcode{x / y}} are equivalent.\n\
 @seealso{mldivide, rdivide, plus, minus}\n\
 @end deftypefn")
 {
@@ -5557,7 +5560,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} mpower (@var{x}, @var{y})\n\
 Return the matrix power operation of @var{x} raised to the @var{y} power.\n\
-This function and @w{@xcode{x ^ y}} are equivalent.\n\
+This function and @w{@tcode{x ^ y}} are equivalent.\n\
 @seealso{power, mtimes, plus, minus}\n\
 @end deftypefn")
 {
@@ -5568,7 +5571,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} mldivide (@var{x}, @var{y})\n\
 Return the matrix left division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x @xbackslashchar{} y}} are equivalent.\n\
+This function and @w{@tcode{x @xbackslashchar{} y}} are equivalent.\n\
 @seealso{mrdivide, ldivide, rdivide}\n\
 @end deftypefn")
 {
@@ -5642,7 +5645,7 @@
 @deftypefn  {Built-in Function} {} times (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} times (@var{x1}, @var{x2}, @dots{})\n\
 Return the element-by-element multiplication product of inputs.\n\
-This function and @w{@xcode{x .* y}} are equivalent.\n\
+This function and @w{@tcode{x .* y}} are equivalent.\n\
 If more arguments are given, the multiplication is applied\n\
 cumulatively from left to right:\n\
 \n\
@@ -5662,7 +5665,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} rdivide (@var{x}, @var{y})\n\
 Return the element-by-element right division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x ./ y}} are equivalent.\n\
+This function and @w{@tcode{x ./ y}} are equivalent.\n\
 @seealso{ldivide, mrdivide, times, plus}\n\
 @end deftypefn")
 {
@@ -5678,7 +5681,7 @@
 @code{realpow}, @code{realsqrt}, @code{cbrt}, or @code{nthroot} if a\n\
 real result is preferred.\n\
 \n\
-This function and @w{@xcode{x .^ y}} are equivalent.\n\
+This function and @w{@tcode{x .^ y}} are equivalent.\n\
 @seealso{mpower, realpow, realsqrt, cbrt, nthroot}\n\
 @end deftypefn")
 {
@@ -5689,7 +5692,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} ldivide (@var{x}, @var{y})\n\
 Return the element-by-element left division of @var{x} and @var{y}.\n\
-This function and @w{@xcode{x .@xbackslashchar{} y}} are equivalent.\n\
+This function and @w{@tcode{x .@xbackslashchar{} y}} are equivalent.\n\
 @seealso{rdivide, mldivide, times, plus}\n\
 @end deftypefn")
 {
@@ -5965,7 +5968,7 @@
 If the optional argument @var{dim} is given, then the matrix is sorted\n\
 along the dimension defined by @var{dim}.  The optional argument @code{mode}\n\
 defines the order in which the values will be sorted.  Valid values of\n\
-@code{mode} are \"ascend\" or \"descend\".\n\
+@code{mode} are @qcode{\"ascend\"} or @qcode{\"descend\"}.\n\
 \n\
 The @code{sort} function may also be used to produce a matrix\n\
 containing the original row indices of the elements in the sorted\n\
@@ -6358,11 +6361,11 @@
 @deftypefnx {Built-in Function} {} issorted (@var{a}, @var{mode})\n\
 @deftypefnx {Built-in Function} {} issorted (@var{a}, \"rows\", @var{mode})\n\
 Return true if the array is sorted according to @var{mode}, which\n\
-may be either \"ascending\", \"descending\", or \"either\".  By default,\n\
- @var{mode} is \"ascending\".  NaNs are treated in the same manner as\n\
-@code{sort}.\n\
-\n\
-If the optional argument \"rows\" is supplied, check whether\n\
+may be either @qcode{\"ascending\"}, @qcode{\"descending\"}, or\n\
+@qcode{\"either\"}.  By default,  @var{mode} is @qcode{\"ascending\"}.  NaNs\n\
+are treated in the same manner as @code{sort}.\n\
+\n\
+If the optional argument @qcode{\"rows\"} is supplied, check whether\n\
 the array is sorted by rows as output by the function @code{sortrows}\n\
 (with no options).\n\
 \n\
--- a/libinterp/corefcn/debug.cc
+++ b/libinterp/corefcn/debug.cc
@@ -917,8 +917,8 @@
 \n\
 When called with no arguments in debugging mode, display the script file\n\
 currently being debugged.  An optional range specification can be used to\n\
-list only a portion of the file.  The special keyword \"end\" is a valid\n\
-line number specification for the last line of the file.\n\
+list only a portion of the file.  The special keyword @qcode{\"end\"} is a\n\
+valid line number specification for the last line of the file.\n\
 \n\
 When called with the name of a function, list that script file with line\n\
 numbers.\n\
@@ -1041,7 +1041,7 @@
 @deftypefn  {Command} {} dblist\n\
 @deftypefnx {Command} {} dblist @var{n}\n\
 In debugging mode, list @var{n} lines of the function being debugged\n\
-centered around the the current line to be executed.  If unspecified @var{n}\n\
+centered around the current line to be executed.  If unspecified @var{n}\n\
 defaults to 10 (+/- 5 lines)\n\
 @seealso{dbwhere, dbtype}\n\
 @end deftypefn")
--- a/libinterp/corefcn/defaults.cc
+++ b/libinterp/corefcn/defaults.cc
@@ -474,11 +474,11 @@
 use with the @code{edit_history} command.  The default value is taken from\n\
 the environment variable @w{@env{EDITOR}} when Octave starts.  If the\n\
 environment variable is not initialized, @w{@env{EDITOR}} will be set to\n\
-@code{\"emacs\"}.\n\
+@qcode{\"emacs\"}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 \n\
 @seealso{edit_history}\n\
 @end deftypefn")
@@ -509,9 +509,9 @@
 @w{@env{OCTAVE_EXEC_PATH}}, but that value can be overridden by\n\
 the command line argument @option{--exec-path PATH}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 \n\
 @seealso{IMAGE_PATH, OCTAVE_HOME}\n\
 @end deftypefn")
@@ -544,9 +544,9 @@
 Query or set the internal variable that specifies a colon separated\n\
 list of directories in which to search for image files.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 \n\
 @seealso{EXEC_PATH, OCTAVE_HOME}\n\
 @end deftypefn")
--- a/libinterp/corefcn/dirfns.cc
+++ b/libinterp/corefcn/dirfns.cc
@@ -94,11 +94,16 @@
 
 DEFUN (cd, args, nargout,
   "-*- texinfo -*-\n\
-@deftypefn  {Command} {} cd dir\n\
-@deftypefnx {Command} {} chdir dir\n\
-Change the current working directory to @var{dir}.  If @var{dir} is\n\
-omitted, the current directory is changed to the user's home\n\
-directory.  For example,\n\
+@deftypefn  {Command} {} cd @var{dir}\n\
+@deftypefnx {Command} {} cd\n\
+@deftypefnx {Built-in Function} {@var{old_dir} =} cd @var{dir}\n\
+@deftypefnx {Command} {} chdir @dots{}\n\
+Change the current working directory to @var{dir}.\n\
+\n\
+If @var{dir} is omitted, the current directory is changed to the user's home\n\
+directory (@qcode{\"~\"}).\n\
+\n\
+For example,\n\
 \n\
 @example\n\
 cd ~/octave\n\
@@ -108,7 +113,13 @@
 changes the current working directory to @file{~/octave}.  If the\n\
 directory does not exist, an error message is printed and the working\n\
 directory is not changed.\n\
-@seealso{mkdir, rmdir, dir}\n\
+\n\
+@code{chdir} is an alias for @code{cd} and can be used in all of the same\n\
+calling formats.\n\
+\n\
+Compatibility Note: When called with no arguments, @sc{matlab} prints the\n\
+present working directory rather than changing to the user's home directory.\n\
+@seealso{pwd, mkdir, rmdir, dir, ls}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -120,30 +131,22 @@
   if (error_state)
     return retval;
 
+  if (nargout > 0)
+    retval = octave_value (octave_env::get_current_directory ());
+
   if (argc > 1)
     {
       std::string dirname = argv[1];
 
-      if (dirname.length () > 0
-          && ! octave_change_to_directory (dirname))
-        {
-          return retval;
-        }
+      if (dirname.length () > 0)
+        octave_change_to_directory (dirname);
     }
   else
     {
-      // Behave like Unixy shells for "cd" by itself, but be Matlab
-      // compatible if doing "current_dir = cd".
+      std::string home_dir = octave_env::get_home_directory ();
 
-      if (nargout == 0)
-        {
-          std::string home_dir = octave_env::get_home_directory ();
-
-          if (home_dir.empty () || ! octave_change_to_directory (home_dir))
-            return retval;
-        }
-      else
-        retval = octave_value (octave_env::get_current_directory ());
+      if (! home_dir.empty ())
+        octave_change_to_directory (home_dir);
     }
 
   return retval;
@@ -153,9 +156,10 @@
 
 DEFUN (pwd, , ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} pwd ()\n\
+@deftypefn  {Built-in Function} {} pwd ()\n\
+@deftypefnx {Built-in Function} {@var{dir} =} pwd ()\n\
 Return the current working directory.\n\
-@seealso{dir, ls}\n\
+@seealso{cd, dir, ls, mkdir, rmdir}\n\
 @end deftypefn")
 {
   return octave_value (octave_env::get_current_directory ());
@@ -163,14 +167,16 @@
 
 DEFUN (readdir, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})\n\
-Return names of the files in the directory @var{dir} as a cell array of\n\
-strings.  If an error occurs, return an empty cell array in @var{files}.\n\
+@deftypefn  {Built-in Function} {@var{files} =} readdir (@var{dir})\n\
+@deftypefnx {Built-in Function} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})\n\
+Return the names of files in the directory @var{dir} as a cell array of\n\
+strings.\n\
 \n\
+If an error occurs, return an empty cell array in @var{files}.\n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
-@seealso{ls, dir, glob}\n\
+@seealso{ls, dir, glob, what}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -207,20 +213,24 @@
   return retval;
 }
 
-// FIXME -- should maybe also allow second arg to specify
-// mode?  OTOH, that might cause trouble with compatibility later...
+// FIXME: should maybe also allow second arg to specify mode?
+//        OTOH, that might cause trouble with compatibility later...
 
 DEFUNX ("mkdir", Fmkdir, args, ,
   "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{dir})\n\
-@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@var{parent}, @var{dir})\n\
+@deftypefn  {Built-in Function} {} mkdir @var{dir}\n\
+@deftypefnx {Built-in Function} {} mkdir (@var{parent}, @var{dir})\n\
+@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} mkdir (@dots{})\n\
 Create a directory named @var{dir} in the directory @var{parent}.\n\
 \n\
-If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
-character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
-system-dependent error message, and @var{msgid} contains a unique\n\
-message identifier.\n\
-@seealso{rmdir}\n\
+If no @var{parent} directory is specified the present working directory is\n\
+used.\n\
+\n\
+If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty\n\
+character strings ("").  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique message\n\
+identifier.\n\
+@seealso{rmdir, pwd, cd}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -295,18 +305,19 @@
 
 DEFUNX ("rmdir", Frmdir, args, ,
   "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir})\n\
-@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@var{dir}, \"s\")\n\
+@deftypefn  {Built-in Function} {} rmdir @var{dir}\n\
+@deftypefnx {Built-in Function} {} rmdir (@var{dir}, \"s\")\n\
+@deftypefnx {Built-in Function} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@dots{})\n\
 Remove the directory named @var{dir}.\n\
 \n\
-If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty\n\
-character strings.  Otherwise, @var{status} is 0, @var{msg} contains a\n\
-system-dependent error message, and @var{msgid} contains a unique\n\
-message identifier.\n\
+If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty\n\
+character strings ("").  Otherwise, @var{status} is 0, @var{msg} contains a\n\
+system-dependent error message, and @var{msgid} contains a unique message\n\
+identifier.\n\
 \n\
-If the optional second parameter is supplied with value @code{\"s\"},\n\
+If the optional second parameter is supplied with value @qcode{\"s\"},\n\
 recursively remove all subdirectories as well.\n\
-@seealso{mkdir, confirm_recursive_rmdir}\n\
+@seealso{mkdir, confirm_recursive_rmdir, pwd}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -369,13 +380,14 @@
 
 DEFUNX ("link", Flink, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\
+@deftypefn  {Built-in Function} {} link @var{old} @var{new}\n\
+@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} link (@var{old}, @var{new})\n\
 Create a new link (also known as a hard link) to an existing file.\n\
 \n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
-@seealso{symlink}\n\
+@seealso{symlink, unlink, readlink, lstat}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -401,10 +413,9 @@
 
               int status = octave_link (from, to, msg);
 
-              retval(0) = status;
-
               if (status < 0)
                 retval(1) = msg;
+              retval(0) = status;
             }
         }
     }
@@ -416,13 +427,14 @@
 
 DEFUNX ("symlink", Fsymlink, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\
+@deftypefn  {Built-in Function} {} symlink @var{old} @var{new}\n\
+@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} symlink (@var{old}, @var{new})\n\
 Create a symbolic link @var{new} which contains the string @var{old}.\n\
 \n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
-@seealso{link, readlink}\n\
+@seealso{link, unlink, readlink, lstat}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -448,10 +460,9 @@
 
               int status = octave_symlink (from, to, msg);
 
-              retval(0) = status;
-
               if (status < 0)
                 retval(1) = msg;
+              retval(0) = status;
             }
         }
     }
@@ -463,14 +474,15 @@
 
 DEFUNX ("readlink", Freadlink, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\
+@deftypefn  {Built-in Function} {} readlink @var{symlink}\n\
+@deftypefnx {Built-in Function} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})\n\
 Read the value of the symbolic link @var{symlink}.\n\
 \n\
 If successful, @var{result} contains the contents of the symbolic link\n\
-@var{symlink}, @var{err} is 0 and @var{msg} is an empty string.\n\
-Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
-system-dependent error message.\n\
-@seealso{link, symlink}\n\
+@var{symlink}, @var{err} is 0, and @var{msg} is an empty string.\n\
+Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent\n\
+error message.\n\
+@seealso{lstat, symlink, link, unlink, delete}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -506,13 +518,14 @@
 
 DEFUNX ("rename", Frename, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\
+@deftypefn  {Built-in Function} {} rename @var{old} @var{new}\n\
+@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} rename (@var{old}, @var{new})\n\
 Change the name of file @var{old} to @var{new}.\n\
 \n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
-@seealso{ls, dir}\n\
+@seealso{movefile, copyfile, ls, dir}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -538,10 +551,9 @@
 
               int status = octave_rename (from, to, msg);
 
-              retval(0) = status;
-
               if (status < 0)
                 retval(1) = msg;
+              retval(0) = status;
             }
         }
     }
@@ -571,9 +583,8 @@
 matches any of the enclosed characters.\n\
 @end table\n\
 \n\
-Tilde expansion\n\
-is performed on each of the patterns before looking for matching file\n\
-names.  For example:\n\
+Tilde expansion is performed on each of the patterns before looking for\n\
+matching file names.  For example:\n\
 \n\
 @example\n\
 ls\n\
@@ -597,7 +608,7 @@
         [2,1] = file2\n\
       @}\n\
 @end example\n\
-@seealso{ls, dir, readdir}\n\
+@seealso{ls, dir, readdir, what, fnmatch}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -656,7 +667,7 @@
 DEFUNX ("fnmatch", Ffnmatch, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})\n\
-Return 1 or zero for each element of @var{string} that matches any of\n\
+Return true or false for each element of @var{string} that matches any of\n\
 the elements of the string array @var{pattern}, using the rules of\n\
 filename pattern matching.  For example:\n\
 \n\
@@ -666,6 +677,7 @@
      @result{} [ 1; 1; 0 ]\n\
 @end group\n\
 @end example\n\
+@seealso{glob, regexp}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -696,8 +708,8 @@
 @deftypefnx {Built-in Function} {} filesep (\"all\")\n\
 Return the system-dependent character used to separate directory names.\n\
 \n\
-If \"all\" is given, the function returns all valid file separators in\n\
-the form of a string.  The list of file separators is system-dependent.\n\
+If @qcode{\"all\"} is given, the function returns all valid file separators\n\
+in the form of a string.  The list of file separators is system-dependent.\n\
 It is @samp{/} (forward slash) under UNIX or @w{Mac OS X}, @samp{/} and\n\
 @samp{\\} (forward and backward slashes) under Windows.\n\
 @seealso{pathsep}\n\
@@ -780,9 +792,10 @@
 Query or set the internal variable that controls whether Octave\n\
 will ask for confirmation before recursively removing a directory tree.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
+@seealso{rmdir}\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (confirm_recursive_rmdir);
--- a/libinterp/corefcn/dlmread.cc
+++ b/libinterp/corefcn/dlmread.cc
@@ -173,14 +173,15 @@
 The @var{range} parameter may be a 4-element vector containing the upper\n\
 left and lower right corner @code{[@var{R0},@var{C0},@var{R1},@var{C1}]}\n\
 where the lowest index value is zero.  Alternatively, a spreadsheet style\n\
-range such as \"A2..Q15\" or \"T1:AA5\" can be used.  The lowest alphabetical\n\
-index 'A' refers to the first column.  The lowest row index is 1.\n\
+range such as @qcode{\"A2..Q15\"} or @qcode{\"T1:AA5\"} can be used.  The\n\
+lowest alphabetical index @qcode{'A'} refers to the first column.  The\n\
+lowest row index is 1.\n\
 \n\
 @var{file} should be a file name or file id given by @code{fopen}.  In the\n\
 latter case, the file is read until end of file is reached.\n\
 \n\
-The \"emptyvalue\" option may be used to specify the value used to fill empty\n\
-fields.  The default is zero.\n\
+The @qcode{\"emptyvalue\"} option may be used to specify the value used to\n\
+fill empty fields.  The default is zero.\n\
 @seealso{csvread, textscan, textread, dlmwrite}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/ellipj.cc
+++ b/libinterp/corefcn/ellipj.cc
@@ -1,6 +1,6 @@
 /*
 
-// Author: Leopoldo Cerbaro <redbliss@libero.it>
+Copyright (C) 2013 Leopoldo Cerbaro <redbliss@libero.it>
 
 This file is part of Octave.
 
@@ -35,7 +35,7 @@
 }
 
 static void
-sncndn (double u, double m, double& sn, double& cn, double& dn, double& err)
+do_ellipj (const double u, const double m, double& sn, double& cn, double& dn, double& err)
 {
   static const int Nmax = 16;
   double m1, t=0, si_u, co_u, se_u, ta_u, b, c[Nmax], a[Nmax], phi;
@@ -43,7 +43,7 @@
 
   if (m < 0 || m > 1)
     {
-      warning ("ellipj: expecting 0 <= m <= 1"); /* -lc- */
+      warning ("ellipj: expecting 0 <= M <= 1"); // -lc-
       sn = cn = dn = lo_ieee_nan_value ();
       return;
     }
@@ -51,7 +51,7 @@
   double sqrt_eps = sqrt (std::numeric_limits<double>::epsilon ());
   if (m < sqrt_eps)
     {
-      /*  # For small m, ( Abramowitz and Stegun, Section 16.13 ) */
+      // For small m, ( Abramowitz and Stegun, Section 16.13 ) 
       si_u = sin (u);
       co_u = cos (u);
       t = 0.25*m*(u - si_u*co_u);
@@ -61,7 +61,7 @@
     }
   else if ((1 - m) < sqrt_eps)
     {
-      /*  For m1 = (1-m) small ( Abramowitz and Stegun, Section 16.15 ) */
+      // For m1 = (1-m) small ( Abramowitz and Stegun, Section 16.15 )
       m1 = 1 - m;
       si_u = sinh (u);
       co_u = cosh (u);
@@ -108,25 +108,25 @@
 }
 
 static void
-sncndn (Complex& u, double m, Complex& sn, Complex& cn, Complex& dn,
+do_ellipj (const Complex& u, const double m, Complex& sn, Complex& cn, Complex& dn,
         double& err)
 {
   double m1 = 1 - m, ss1, cc1, dd1;
 
-  sncndn (imag (u), m1, ss1, cc1, dd1, err);
+  do_ellipj (imag (u), m1, ss1, cc1, dd1, err);
   if (real (u) == 0)
     {
-      /* u is pure imag: Jacoby imag. transf. */
+      // u is pure imag: Jacoby imag. transf.
       sn = Complex (0, ss1/cc1);
       cn = 1/cc1;         //    cn.imag = 0;
       dn = dd1/cc1;       //    dn.imag = 0;
     }
   else
     {
-      /* u is generic complex */
+      // u is generic complex
       double ss, cc, dd, ddd;
 
-      sncndn (real (u), m, ss, cc, dd, err);
+      do_ellipj (real (u), m, ss, cc, dd, err);
       ddd = cc1*cc1 + m*ss*ss*ss1*ss1;
       sn = Complex (ss*dd1/ddd, cc*dd*ss1*cc1/ddd);
       cn = Complex (cc*cc1/ddd, -ss*dd*ss1*dd1/ddd);
@@ -146,13 +146,14 @@
 If @var{u} is a column vector and @var{m} is a row vector, the\n\
 results are matrices with @code{length (@var{u})} rows and\n\
 @code{length (@var{m})} columns.  Otherwise, @var{u} and\n\
-@var{m} must conform and the results will be the same size.\n\
+@var{m} must conform in size and the results will be the same size as the\n\
+inputs.\n\
 \n\
 The value of @var{u} may be complex.\n\
-The value of @var{m} must be 0 @leq{} m @leq{} 1.\n\
+The value of @var{m} must be 0 @leq{} @var{m} @leq{} 1.\n\
 \n\
-@var{tol} is currently ignored (@sc{matlab} uses this to allow faster,\n\
-less accurate approximation).\n\
+The optinoal input @var{tol} is currently ignored (@sc{matlab} uses this to\n\
+allow faster, less accurate approximation).\n\
 \n\
 If requested, @var{err} contains the following status information\n\
 and is the same size as the result.\n\
@@ -165,9 +166,11 @@
 Error---no computation, algorithm termination condition not met,\n\
 return @code{NaN}.\n\
 @end enumerate\n\
- Ref: Abramowitz, Milton and Stegun, Irene A\n\
-      Handbook of Mathematical Functions, Dover, 1965\n\
-      Chapter 16 (Sections 16.4, 16.13 and 16.15)\n\
+\n\
+Reference: Milton Abramowitz and Irene A Stegun,\n\
+@cite{Handbook of Mathematical Functions}, Chapter 16 (Sections 16.4, 16.13,\n\
+and 16.15), Dover, 1965.\n\
+\n\
 @seealso{ellipke}\n\
 @end deftypefn")
 {
@@ -197,7 +200,7 @@
       if (u_arg.is_scalar_type ())
         {
           if (u_arg.is_real_type ())
-            {  // u real
+            {  // u real, m scalar
               double u = args(0).double_value ();
 
               if (error_state)
@@ -205,65 +208,75 @@
                   gripe_ellipj_arg ("first");
                   return retval;
                 }
+
               double sn, cn, dn;
               double err = 0;
 
-              sncndn (u, m, sn, cn, dn, err);
-              retval (0) = sn;
-              retval (1) = cn;
-              retval (2) = dn;
-              if (nargout > 3) retval(3) =  err;
+              do_ellipj (u, m, sn, cn, dn, err);
+
+              if (nargout > 3)
+                retval(3) = err;
+              retval(2) = dn;
+              retval(1) = cn;
+              retval(0) = sn;
             }
           else
-            {  // u complex
+            {  // u complex, m scalar
               Complex u = u_arg.complex_value ();
 
               if (error_state)
                 {
-                  gripe_ellipj_arg ("second");
+                  gripe_ellipj_arg ("first");
                   return retval;
                 }
 
               Complex sn, cn, dn;
-              double err;
+              double err = 0;
 
-              sncndn (u, m, sn, cn, dn, err);
+              do_ellipj (u, m, sn, cn, dn, err);
 
-              retval (0) = sn;
-              retval (1) = cn;
-              retval (2) = dn;
-              if (nargout > 3) retval(3) = err;
+              if (nargout > 3)
+                retval(3) = err;
+              retval(2) = dn;
+              retval(1) = cn;
+              retval(0) = sn;
             }
         }
       else
-        {  /* u is matrix ( m is scalar ) */
-          ComplexMatrix u = u_arg.complex_matrix_value ();
-
+        {  // u is matrix, m is scalar
+          ComplexNDArray u = u_arg.complex_array_value ();
+          
           if (error_state)
             {
               gripe_ellipj_arg ("first");
               return retval;
             }
 
-          octave_idx_type nr = u.rows ();
-          octave_idx_type nc = u.cols ();
+          dim_vector sz_u = u.dims ();
 
-          ComplexMatrix sn (nr, nc), cn (nr, nc), dn (nr, nc);
-          Matrix err (nr, nc);
+          ComplexNDArray sn (sz_u), cn (sz_u), dn (sz_u);
+          NDArray err (sz_u);
 
-          for (octave_idx_type j = 0; j < nc; j++)
-            for (octave_idx_type i = 0; i < nr; i++)
-              sncndn (u(i,j), m, sn(i,j), cn(i,j), dn(i,j), err(i,j));
+          const Complex *pu = u.data ();
+          Complex *psn = sn.fortran_vec ();
+          Complex *pcn = cn.fortran_vec ();
+          Complex *pdn = dn.fortran_vec ();
+          double *perr = err.fortran_vec ();
+          octave_idx_type nel = u.numel ();
 
-          retval (0) = sn;
-          retval (1) = cn;
-          retval (2) = dn;
-          if (nargout > 3) retval(3) = err;
+          for (octave_idx_type i = 0; i < nel; i++)
+            do_ellipj (pu[i], m, psn[i], pcn[i], pdn[i], perr[i]);
+
+          if (nargout > 3)
+            retval(3) = err;
+          retval(2) = dn;
+          retval(1) = cn;
+          retval(0) = sn;
         }
     }
   else
     {
-      Matrix m = args(1).matrix_value ();
+      NDArray m = args(1).array_value ();
 
       if (error_state)
         {
@@ -271,17 +284,12 @@
           return retval;
         }
 
-      octave_idx_type mr = m.rows ();
-      octave_idx_type mc = m.cols ();
+      dim_vector sz_m = m.dims ();
 
       if (u_arg.is_scalar_type ())
-        {    /* u is scalar */
-          octave_idx_type nr = m.rows ();
-          octave_idx_type nc = m.cols ();
-          Matrix err (nr, nc);
-
+        {  // u is scalar, m is array
           if (u_arg.is_real_type ())
-            {
+            {  // u is real scalar, m is array
               double u = u_arg.double_value ();
 
               if (error_state)
@@ -290,129 +298,176 @@
                   return retval;
                 }
 
-              Matrix sn (nr, nc), cn (nr, nc), dn (nr, nc);
-              for (octave_idx_type j = 0; j < nc; j++)
-                for (octave_idx_type i = 0; i < nr; i++)
-                  sncndn (u, m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
+              NDArray sn (sz_m), cn (sz_m), dn (sz_m);
+              NDArray err (sz_m);
 
-              retval (0) = sn;
-              retval (1) = cn;
-              retval (2) = dn;
-              if (nargout > 3)  retval(3) = err;
+              const double *pm = m.data ();
+              double *psn = sn.fortran_vec ();
+              double *pcn = cn.fortran_vec ();
+              double *pdn = dn.fortran_vec ();
+              double *perr = err.fortran_vec ();
+              octave_idx_type nel = m.numel ();
+
+              for (octave_idx_type i = 0; i < nel; i++)
+                do_ellipj (u, pm[i], psn[i], pcn[i], pdn[i], perr[i]);
+
+              if (nargout > 3)
+                retval(3) = err;
+              retval(2) = dn;
+              retval(1) = cn;
+              retval(0) = sn;
             }
           else
-            {
+            {  // u is complex scalar, m is array
               Complex u = u_arg.complex_value ();
+
+              if (error_state)
+                {
+                  gripe_ellipj_arg ("first");
+                  return retval;
+                }
+
+              ComplexNDArray sn (sz_m), cn (sz_m), dn (sz_m);
+              NDArray err (sz_m);
+
+              const double *pm = m.data ();
+              Complex *psn = sn.fortran_vec ();
+              Complex *pcn = cn.fortran_vec ();
+              Complex *pdn = dn.fortran_vec ();
+              double *perr = err.fortran_vec ();
+              octave_idx_type nel = m.numel ();
+
+              for (octave_idx_type i = 0; i < nel; i++)
+                do_ellipj (u, pm[i], psn[i], pcn[i], pdn[i], perr[i]);
+
+              if (nargout > 3)
+                retval(3) = err;
+              retval(2) = dn;
+              retval(1) = cn;
+              retval(0) = sn;
+            }
+        }
+      else
+        {  // u is array, m is array
+          if (u_arg.is_real_type ())
+            {  // u is real array, m is array
+              NDArray u = u_arg.array_value ();
+
               if (error_state)
                 {
                   gripe_ellipj_arg ("first");
                   return retval;
                 }
 
-              ComplexMatrix sn (nr, nc), cn (nr, nc), dn (nr, nc);
-              for (octave_idx_type j = 0; j < nc; j++)
-                for (octave_idx_type i = 0; i < nr; i++)
-                  sncndn (u, m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
-              retval (0) = sn;
-              retval (1) = cn;
-              retval (2) = dn;
-              if (nargout > 3)  retval(3) = err;
-            }
-        }
-      else
-        {    // u is matrix  (m is matrix)
-          if (u_arg.is_real_type ())
-            {  // u real matrix
+              dim_vector sz_u = u.dims ();
 
-              Matrix u = u_arg.matrix_value ();
-              if (error_state)
-                {
-                  gripe_ellipj_arg ("first ");
-                  return retval;
-                }
+              if (sz_u.length () == 2 && sz_m.length () == 2
+                  && sz_u(1) == 1 && sz_m(0) == 1)
+                {  // u is real column vector, m is row vector
+                  octave_idx_type ur = sz_u(0);
+                  octave_idx_type mc = sz_m(1);
+                  dim_vector sz_out (ur, mc);
 
-              octave_idx_type ur = u.rows ();
-              octave_idx_type uc = u.cols ();
+                  NDArray sn (sz_out), cn (sz_out), dn (sz_out);
+                  NDArray err (sz_out);
 
-              if (mr == 1 && uc == 1)
-                {  // u column, m row
-                  RowVector rm = m.row (0);
-                  ColumnVector cu = u.column (0);
-
-                  Matrix sn (ur, mc), cn (ur, mc), dn (ur, mc);
-                  Matrix err (ur,mc);
+                  const double *pu = u.data ();
+                  const double *pm = m.data ();
 
                   for (octave_idx_type j = 0; j < mc; j++)
                     for (octave_idx_type i = 0; i < ur; i++)
-                      sncndn (cu(i), rm(j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
+                      do_ellipj (pu[i], pm[j], sn(i,j), cn(i,j), dn(i,j), err(i,j));
 
-                  retval (0) = sn;
-                  retval (1) = cn;
-                  retval (2) = dn;
-                  if (nargout > 3)  retval(3) = err;
+                  if (nargout > 3)
+                    retval(3) = err;
+                  retval(2) = dn;
+                  retval(1) = cn;
+                  retval(0) = sn;
                 }
-              else if (ur == mr && uc == mc)
+              else if (sz_m == sz_u)
                 {
-                  Matrix sn (ur, mc), cn (ur, mc), dn (ur, mc);
-                  Matrix err (ur,mc);
+                  NDArray sn (sz_m), cn (sz_m), dn (sz_m);
+                  NDArray err (sz_m);
 
-                  for (octave_idx_type j = 0; j < uc; j++)
-                    for (octave_idx_type i = 0; i < ur; i++)
-                      sncndn (u(i,j), m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
+                  const double *pu = u.data ();
+                  const double *pm = m.data ();
+                  double *psn = sn.fortran_vec ();
+                  double *pcn = cn.fortran_vec ();
+                  double *pdn = dn.fortran_vec ();
+                  double *perr = err.fortran_vec ();
+                  octave_idx_type nel = m.numel ();
 
-                  retval (0) = sn;
-                  retval (1) = cn;
-                  retval (2) = dn;
-                  if (nargout > 3)  retval(3) = err;
+                  for (octave_idx_type i = 0; i < nel; i++)
+                    do_ellipj (pu[i], pm[i], psn[i], pcn[i], pdn[i], perr[i]);
+
+                  if (nargout > 3)
+                    retval(3) = err;
+                  retval(2) = dn;
+                  retval(1) = cn;
+                  retval(0) = sn;
                 }
               else
-                error ("u m invalid");
+                error ("ellipj: Invalid size combination for U and M");
             }
           else
-            {  // u complex matrix
-              ComplexMatrix u = u_arg.complex_matrix_value ();
+            {  // u is complex array, m is array
+              ComplexNDArray u = u_arg.complex_array_value ();
+
               if (error_state)
                 {
                   gripe_ellipj_arg ("second");
                   return retval;
                 }
 
-              octave_idx_type ur = u.rows ();
-              octave_idx_type uc = u.cols ();
+              dim_vector sz_u = u.dims ();
 
-              if (mr == 1 && uc == 1)
-                {
-                  RowVector rm = m.row (0);
-                  ComplexColumnVector cu = u.column (0);
+              if (sz_u.length () == 2 && sz_m.length () == 2
+                  && sz_u(1) == 1 && sz_m(0) == 1)
+                {  // u is complex column vector, m is row vector
+                  octave_idx_type ur = sz_u(0);
+                  octave_idx_type mc = sz_m(1);
+                  dim_vector sz_out (ur, mc);
 
-                  ComplexMatrix sn (ur, mc), cn (ur, mc), dn (ur, mc);
-                  Matrix err (ur,mc);
+                  ComplexNDArray sn (sz_out), cn (sz_out), dn (sz_out);
+                  NDArray err (sz_out);
+
+                  const Complex *pu = u.data ();
+                  const double  *pm = m.data ();
 
                   for (octave_idx_type j = 0; j < mc; j++)
                     for (octave_idx_type i = 0; i < ur; i++)
-                      sncndn (cu(i), rm(j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
+                      do_ellipj (pu[i], pm[j], sn(i,j), cn(i,j), dn(i,j), err(i,j));
 
-                  retval (0) = sn;
-                  retval (1) = cn;
-                  retval (2) = dn;
-                  if (nargout > 3)  retval(3) = err;
+                  if (nargout > 3)
+                    retval(3) = err;
+                  retval(2) = dn;
+                  retval(1) = cn;
+                  retval(0) = sn;
                 }
-              else if (ur == mr && uc == mc)
+              else if (sz_m == sz_u)
                 {
-                  ComplexMatrix sn (ur, mc), cn (ur, mc), dn (ur, mc);
-                  Matrix err (ur,mc);
+                  ComplexNDArray sn (sz_m), cn (sz_m), dn (sz_m);
+                  NDArray err (sz_m);
 
-                  for (octave_idx_type j = 0; j < uc; j++)
-                    for (octave_idx_type i = 0; i < ur; i++)
-                      sncndn (u(i,j), m(i,j), sn(i,j), cn(i,j), dn(i,j), err(i,j));
+                  const Complex *pu = u.data ();
+                  const double  *pm = m.data ();
+                  Complex *psn = sn.fortran_vec ();
+                  Complex *pcn = cn.fortran_vec ();
+                  Complex *pdn = dn.fortran_vec ();
+                  double *perr = err.fortran_vec ();
+                  octave_idx_type nel = m.numel ();
 
-                  retval (0) = sn;
-                  retval (1) = cn;
-                  retval (2) = dn;
-                  if (nargout > 3)  retval(3) = err;
+                  for (octave_idx_type i = 0; i < nel; i++)
+                    do_ellipj (pu[i], pm[i], psn[i], pcn[i], pdn[i], perr[i]);
+
+                  if (nargout > 3)
+                    retval(3) = err;
+                  retval(2) = dn;
+                  retval(1) = cn;
+                  retval(0) = sn;
                 }
               else
-                error ("u m invalid");
+                error ("ellipj: Invalid size combination for U and M");
             }
         }
     }  // m matrix
@@ -425,53 +480,52 @@
 
 %!demo
 %! N = 150;
-%! % m = [1-logspace(0,log(eps),N-1), 1]; ## m near 1
-%! % m = [0, logspace(log(eps),0,N-1)];   ## m near 0
-%!   m = linspace(0,1,N);                 ## m equally spaced
-%! u = linspace(-20,20,N);
-%! M = ones(length(u),1) * m;
-%! U = u' * ones(1, length(m));
-%! [sn, cn, dn] = ellipj(U,M);
+%! # m = [1-logspace(0,log(eps),N-1), 1]; # m near 1
+%! # m = [0, logspace(log(eps),0,N-1)];   # m near 0
+%!   m = linspace (0,1,N);                # m equally spaced
+%! u = linspace (-20, 20, N);
+%! M = ones (length (u), 1) * m;
+%! U = u' * ones (1, length (m));
+%! [sn, cn, dn] = ellipj (U,M);
 %!
-%! %% Plotting
-%! c = colormap(hot(64));
+%! ## Plotting
 %! data = {sn,cn,dn};
 %! dname = {"sn","cn","dn"};
 %! for i=1:3
-%!   subplot(1,3,i);
+%!   subplot (1,3,i);
 %!   data{i}(data{i} > 1) = 1;
 %!   data{i}(data{i} < -1) = -1;
-%!   image(m,u,32*data{i}+32);
-%!   title(dname{i});
-%! end
-%! colormap(c);
+%!   image (m,u,32*data{i}+32);
+%!   title (dname{i});
+%! endfor
+%! colormap (hot (64));
 
 %!demo
 %! N = 200;
-%! % m = [1-logspace(0,log(eps),N-1), 1]; ## m near 1
-%! % m = [0, logspace(log(eps),0,N-1)];   ## m near 0
-%!   m = linspace(0,1,N);                 ## m equally spaced
-%! u = linspace(0,20,5);
-%! M = ones(length(u),1) * m;
-%! U = u' * ones(1, length(m));
-%! [sn, cn, dn] = ellipj(U,M);
+%! # m = [1-logspace(0,log(eps),N-1), 1]; # m near 1
+%! # m = [0, logspace(log(eps),0,N-1)];   # m near 0
+%!   m = linspace (0,1,N);                # m equally spaced
+%! u = linspace (0,20,5);
+%! M = ones (length (u), 1) * m;
+%! U = u' * ones (1, length (m));
+%! [sn, cn, dn] = ellipj (U,M);
 %!
-%! %% Plotting
+%! ## Plotting
 %! data = {sn,cn,dn};
 %! dname = {"sn","cn","dn"};
 %! for i=1:3
-%!   subplot(1,3,i);
-%!   plot(m, data{i});
-%!   title(dname{i});
+%!   subplot (1,3,i);
+%!   plot (m, data{i});
+%!   title (dname{i});
 %!   grid on;
-%! end
+%! endfor
 */
 
 /*
 ## tests taken from inst/test_sncndn.m
 
 %!test
-%! k = (tan(pi/8.))^2; m = k*k;
+%! k = (tan(pi/8.))^2;  m = k*k;
 %! SN = [
 %! -1. + I * 0. ,  -0.8392965923 + 0. * I
 %! -1. + I * 0.2 ,  -0.8559363407 + 0.108250955 * I
@@ -848,9 +902,9 @@
 %!     ui =  y * 0.2;
 %!     ii = 1 + y + x*11;
 %!     [sn, cn, dn] = ellipj (ur + I * ui, m);
-%!     assert (SN (ii, 2), sn, tol);
-%!     assert (CN (ii, 2), cn, tol);
-%!     assert (DN (ii, 2), dn, tol);
+%!     assert (sn, SN(ii, 2), tol);
+%!     assert (cn, CN(ii, 2), tol);
+%!     assert (dn, DN(ii, 2), tol);
 %!   endfor
 %! endfor
 
@@ -858,61 +912,69 @@
 %!test
 %! u1 = pi/3; m1 = 0;
 %! res1 = [sin(pi/3), cos(pi/3), 1];
-%! [sn,cn,dn]=ellipj(u1,m1);
-%! assert([sn,cn,dn], res1, 10*eps);
+%! [sn,cn,dn] = ellipj (u1,m1);
+%! assert ([sn,cn,dn], res1, 10*eps);
 
 %!test
 %! u2 = log(2); m2 = 1;
 %! res2 = [ 3/5, 4/5, 4/5 ];
-%! [sn,cn,dn]=ellipj(u2,m2);
-%! assert([sn,cn,dn], res2, 10*eps);
+%! [sn,cn,dn] = ellipj (u2,m2);
+%! assert ([sn,cn,dn], res2, 10*eps);
 
 %!test
 %! u3 = log(2)*1i; m3 = 0;
 %! res3 = [3i/4,5/4,1];
-%! [sn,cn,dn]=ellipj(u3,m3);
-%! assert([sn,cn,dn], res3, 10*eps);
+%! [sn,cn,dn] = ellipj (u3,m3);
+%! assert ([sn,cn,dn], res3, 10*eps);
 
 %!test
-%! u4 = -1; m4 = tan(pi/8)^4;
+%! u4 = -1; m4 = tan (pi/8)^4;
 %! res4 = [-0.8392965923,0.5436738271,0.9895776106];
-%! [sn,cn,dn]=ellipj(u4, m4);
-%! assert([sn,cn,dn], res4, 1e-10);
+%! [sn,cn,dn] = ellipj (u4, m4);
+%! assert ([sn,cn,dn], res4, 1e-10);
 
 %!test
 %! u5 = -0.2 + 0.4i; m5 = tan(pi/8)^4;
 %! res5 = [ -0.2152524522 + 0.402598347i, ...
 %!           1.059453907  + 0.08179712295i, ...
 %!           1.001705496  + 0.00254669712i ];
-%! [sn,cn,dn]=ellipj(u5,m5);
-%! assert([sn,cn,dn], res5, 1e-9);
+%! [sn,cn,dn] = ellipj (u5,m5);
+%! assert ([sn,cn,dn], res5, 1e-9);
 
 %!test
 %! u6 = 0.2 + 0.6i; m6 = tan(pi/8)^4;
 %! res6 = [ 0.2369100139 + 0.624633635i, ...
 %!          1.16200643   - 0.1273503824i, ...
-%!          1.004913944 - 0.004334880912i ];
-%! [sn,cn,dn]=ellipj(u6,m6);
-%! assert([sn,cn,dn], res6, 1e-8);
+%!          1.004913944  - 0.004334880912i ];
+%! [sn,cn,dn] = ellipj (u6,m6);
+%! assert ([sn,cn,dn], res6, 1e-8);
 
 %!test
-%! u7 = 0.8 + 0.8i; m7 = tan(pi/8)^4;
+%! u7 = 0.8 + 0.8i; m7 = tan (pi/8)^4;
 %! res7 = [0.9588386397 + 0.6107824358i, ...
 %!         0.9245978896 - 0.6334016187i, ...
 %!         0.9920785856 - 0.01737733806i ];
-%! [sn,cn,dn]=ellipj(u7,m7);
-%! assert([sn,cn,dn], res7, 1e-10);
+%! [sn,cn,dn] = ellipj (u7,m7);
+%! assert ([sn,cn,dn], res7, 1e-10);
 
 %!test
-%! u=[0,pi/6,pi/4,pi/2]; m=0;
+%! u = [0,pi/6,pi/4,pi/2]; m=0;
 %! res = [0,1/2,1/sqrt(2),1;1,cos(pi/6),1/sqrt(2),0;1,1,1,1];
-%! [sn,cn,dn]=ellipj(u,m);
-%! assert([sn;cn;dn],res, 100*eps);
-%! [sn,cn,dn]=ellipj(u',0);
-%! assert([sn,cn,dn],res', 100*eps);
+%! [sn,cn,dn] = ellipj (u,m);
+%! assert ([sn;cn;dn], res, 100*eps);
+%! [sn,cn,dn] = ellipj (u',0);
+%! assert ([sn,cn,dn], res', 100*eps);
+
+## FIXME: need to check [real,complex]x[scalar,rowvec,colvec,matrix]x[u,m]
 
-## XXX FIXME XXX
-## need to check [real,complex]x[scalar,rowvec,colvec,matrix]x[u,m]
+## One test for u column vector x m row vector
+%!test
+%! u = [0,pi/6,pi/4,pi/2]';  m = [0 0 0 0];
+%! res = [0,1/2,1/sqrt(2),1;1,cos(pi/6),1/sqrt(2),0;1,1,1,1]';
+%! [sn,cn,dn] = ellipj (u,m);
+%! assert (sn, repmat (res(:,1), [1,4]), 100*eps);
+%! assert (cn, repmat (res(:,2), [1,4]), 100*eps);
+%! assert (dn, repmat (res(:,3), [1,4]), 100*eps);
 
 %!test
 %! ## Test Jacobi elliptic functions
@@ -921,27 +983,46 @@
 %! ## 1 February 2001
 %! u = [ 0.25; 0.25; 0.20; 0.20; 0.672; 0.5];
 %! m = [ 0.0;  1.0;  0.19; 0.81; 0.36;  0.9999999999];
-%! S = [ sin(0.25); tanh(0.25);
-%!  0.19842311013970879516;
-%!  0.19762082367187648571;
-%!  0.6095196917919021945;
-%!  0.4621171572617320908 ];
-%! C = [ cos(0.25); sech(0.25);
-%!  0.9801164570409401062;
-%!  0.9802785369736752032;
-%!  0.7927709286533560550;
-%!  0.8868188839691764094 ];
-%! D = [ 1.0;  sech(0.25);
-%!  0.9962526643271134302;
-%!  0.9840560289645665155;
-%!  0.9307281387786906491;
-%!  0.8868188839812167635 ];
-%! [sn,cn,dn] = ellipj(u,m);
-%! assert(sn,S,8*eps);
-%! assert(cn,C,8*eps);
-%! assert(dn,D,8*eps);
+%! S = [ sin(0.25);
+%!       tanh(0.25);
+%!       0.19842311013970879516;
+%!       0.19762082367187648571;
+%!       0.6095196917919021945;
+%!       0.4621171572617320908 ];
+%! C = [ cos(0.25);
+%!       sech(0.25);
+%!       0.9801164570409401062;
+%!       0.9802785369736752032;
+%!       0.7927709286533560550;
+%!       0.8868188839691764094 ];
+%! D = [ 1.0;
+%!       sech(0.25);
+%!       0.9962526643271134302;
+%!       0.9840560289645665155;
+%!       0.9307281387786906491;
+%!       0.8868188839812167635 ];
+%! [sn,cn,dn] = ellipj (u,m);
+%! assert (sn, S, 8*eps);
+%! assert (cn, C, 8*eps);
+%! assert (dn, D, 8*eps);
 
 %!error ellipj ()
 %!error ellipj (1)
 %!error ellipj (1,2,3,4)
+%!warning <expecting 0 <= M <= 1> ellipj (1,2);
+## FIXME: errors commented out untill lasterr() truly returns the last error.
+%!#error <expecting scalar or matrix as second argument> ellipj (1, "1")
+%!#error <expecting scalar or matrix as first argument> ellipj ("1", 1)
+%!#error <expecting scalar or matrix as first argument> ellipj ({1}, 1)
+%!#error <expecting scalar or matrix as first argument> ellipj ({1, 2}, 1)
+%!#error <expecting scalar or matrix as second argument> ellipj (1, {1, 2})
+%!#error <expecting scalar or matrix as first argument> ellipj ("1", [1, 2])
+%!#error <expecting scalar or matrix as first argument> ellipj ({1}, [1, 2])
+%!#error <expecting scalar or matrix as first argument> ellipj ({1}, [1, 2])
+%!#error <expecting scalar or matrix as first argument> ellipj ("1,2", [1, 2])
+%!#error <expecting scalar or matrix as first argument> ellipj ({1, 2}, [1, 2])
+%!error <Invalid size combination for U and M> ellipj ([1:4], [1:3])
+%!error <Invalid size combination for U and M> ellipj (complex (1:4,1:4), [1:3])
+
 */
+
--- a/libinterp/corefcn/error.cc
+++ b/libinterp/corefcn/error.cc
@@ -830,10 +830,10 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} rethrow (@var{err})\n\
 Reissue a previous error as defined by @var{err}.  @var{err} is a structure\n\
-that must contain at least the 'message' and 'identifier' fields.  @var{err}\n\
-can also contain a field 'stack' that gives information on the assumed\n\
-location of the error.  Typically @var{err} is returned from\n\
-@code{lasterror}.\n\
+that must contain at least the @qcode{\"message\"} and @qcode{\"identifier\"}\n\
+fields.  @var{err} can also contain a field @qcode{\"stack\"} that gives\n\
+information on the assumed location of the error.  Typically @var{err} is\n\
+returned from @code{lasterror}.\n\
 @seealso{lasterror, lasterr, error}\n\
 @end deftypefn")
 {
@@ -1091,7 +1091,7 @@
 which will only stop execution if an error has been found.\n\
 \n\
 Implementation Note: For compatibility with @sc{matlab}, escape\n\
-sequences (e.g., \"\\n\" => newline) are processed in @var{template}\n\
+sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{template}\n\
 regardless of whether @var{template} has been defined within single quotes\n\
 as long as there are two or more input arguments.\n\
 Use a second backslash to stop interpolation of the escape sequence (e.g.,\n\
@@ -1235,17 +1235,17 @@
 \n\
 The optional message identifier allows users to enable or disable\n\
 warnings tagged by @var{id}.  A message identifier is of the form\n\
-\"NAMESPACE:WARNING-NAME\".  Octave's own warnings use the \"Octave\"\n\
-namespace (@pxref{XREFwarning_ids}).  The special identifier @samp{\"all\"}\n\
+\"NAMESPACE:WARNING-NAME\".  Octave's own warnings use the @qcode{\"Octave\"}\n\
+namespace (@pxref{XREFwarning_ids}).  The special identifier @qcode{\"all\"}\n\
 may be used to set the state of all warnings.\n\
 \n\
-If the first argument is @samp{\"on\"} or @samp{\"off\"}, set the state\n\
-of a particular warning using the identifier @var{id}.  If the first\n\
-argument is @samp{\"query\"}, query the state of this warning instead.\n\
-If the identifier is omitted, a value of @samp{\"all\"} is assumed.  If\n\
-you set the state of a warning to @samp{\"error\"}, the warning named by\n\
-@var{id} is handled as if it were an error instead.  So, for example, the\n\
-following handles all warnings as errors:\n\
+If the first argument is @qcode{\"on\"} or @qcode{\"off\"},\n\
+set the state of a particular warning using the identifier @var{id}.  If the\n\
+first argument is @qcode{\"query\"}, query the state of this warning\n\
+instead.  If the identifier is omitted, a value of @qcode{\"all\"} is\n\
+assumed.  If you set the state of a warning to @qcode{\"error\"}, the\n\
+warning named by @var{id} is handled as if it were an error instead.  So,\n\
+for example, the following handles all warnings as errors:\n\
 \n\
 @example\n\
 @group\n\
@@ -1253,17 +1253,17 @@
 @end group\n\
 @end example\n\
 \n\
-If the state is @samp{\"on\"}, @samp{\"off\"}, or @samp{\"error\"}\n\
-and the third argument is @samp{\"local\"}, then the warning state\n\
+If the state is @qcode{\"on\"}, @qcode{\"off\"}, or @qcode{\"error\"}\n\
+and the third argument is @qcode{\"local\"}, then the warning state\n\
 will be set temporarily, until the end of the current function.\n\
 Changes to warning states that are set locally affect the current\n\
 function and all functions called from the current scope.  The\n\
 previous warning state is restored on return from the current\n\
-function.  The \"local\" option is ignored if used in the top-level\n\
+function.  The @qcode{\"local\"} option is ignored if used in the top-level\n\
 workspace.\n\
 \n\
 Implementation Note: For compatibility with @sc{matlab}, escape\n\
-sequences (e.g., \"\\n\" => newline) are processed in @var{template}\n\
+sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{template}\n\
 regardless of whether @var{template} has been defined within single quotes\n\
 as long as there are two or more input arguments.\n\
 Use a second backslash to stop interpolation of the escape sequence (e.g.,\n\
@@ -1654,29 +1654,29 @@
 arguments, return a structure containing the last error message and other\n\
 information related to this error.  The elements of the structure are:\n\
 \n\
-@table @asis\n\
-@item 'message'\n\
+@table @code\n\
+@item message\n\
 The text of the last error message\n\
 \n\
-@item 'identifier'\n\
+@item identifier\n\
 The message identifier of this error message\n\
 \n\
-@item 'stack'\n\
+@item stack\n\
 A structure containing information on where the message occurred.  This may\n\
 be an empty structure if the information cannot\n\
 be obtained.  The fields of the structure are:\n\
 \n\
-@table @asis\n\
-@item 'file'\n\
+@table @code\n\
+@item file\n\
 The name of the file where the error occurred\n\
 \n\
-@item 'name'\n\
+@item name\n\
 The name of function in which the error occurred\n\
 \n\
-@item 'line'\n\
+@item line\n\
 The line number at which the error occurred\n\
 \n\
-@item 'column'\n\
+@item column\n\
 An optional field with the column number at which the error occurred\n\
 @end table\n\
 @end table\n\
@@ -1685,8 +1685,8 @@
 as input.  Any fields of @var{err} that match those above are set while any\n\
 unspecified fields are initialized with default values.\n\
 \n\
-If @code{lasterror} is called with the argument \"reset\", all fields are\n\
-set to their default values.\n\
+If @code{lasterror} is called with the argument @qcode{\"reset\"}, all\n\
+fields are set to their default values.\n\
 @seealso{lasterr, error, lastwarn}\n\
 @end deftypefn")
 {
@@ -1956,9 +1956,9 @@
 Query or set the internal variable that controls whether Octave will try\n\
 to ring the terminal bell before printing an error message.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (beep_on_error);
@@ -1974,9 +1974,9 @@
 inhibit printing of the normal traceback message (you will only see\n\
 the top-level error message).\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{debug_on_warning, debug_on_interrupt}\n\
 @end deftypefn")
 {
@@ -1991,9 +1991,9 @@
 Query or set the internal variable that controls whether Octave will try\n\
 to enter the debugger when a warning is encountered.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{debug_on_error, debug_on_interrupt}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/file-io.cc
+++ b/libinterp/corefcn/file-io.cc
@@ -647,14 +647,14 @@
 file.\n\
 @end table\n\
 \n\
-Append a \"t\" to the mode string to open the file in text mode or a\n\
-\"b\" to open in binary mode.  On Windows and Macintosh systems, text\n\
+Append a @qcode{\"t\"} to the mode string to open the file in text mode or a\n\
+@qcode{\"b\"} to open in binary mode.  On Windows and Macintosh systems, text\n\
 mode reading and writing automatically converts linefeeds to the\n\
 appropriate line end character for the system (carriage-return linefeed\n\
 on Windows, carriage-return on Macintosh).  The default if no mode is\n\
 specified is binary mode.\n\
 \n\
-Additionally, you may append a \"z\" to the mode string to open a\n\
+Additionally, you may append a @qcode{\"z\"} to the mode string to open a\n\
 gzipped file for reading or writing.  For this to be successful, you\n\
 must also open the file in binary mode.\n\
 \n\
@@ -670,15 +670,6 @@
 \n\
 @item ieee-le\n\
 IEEE little endian format.\n\
-\n\
-@item vaxd\n\
-VAX D floating format.\n\
-\n\
-@item vaxg\n\
-VAX G floating format.\n\
-\n\
-@item cray\n\
-Cray floating format.\n\
 @end table\n\
 \n\
 @noindent\n\
@@ -825,8 +816,10 @@
 The pointer is positioned @var{offset} characters from the @var{origin},\n\
 which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
 position), @w{@code{SEEK_SET}} (beginning), or @w{@code{SEEK_END}} (end of\n\
-file) or strings \"cof\", \"bof\" or \"eof\".  If @var{origin} is omitted,\n\
-@w{@code{SEEK_SET}} is assumed.  @var{offset} may be positive, negative, or zero but not all combinations of @var{origin} and @var{offset} can be realized.\n\
+file) or strings @qcode{\"cof\"}, @qcode{\"bof\"} or @qcode{\"eof\"}.  If\n\
+@var{origin} is omitted, @w{@code{SEEK_SET}} is assumed.  @var{offset} may\n\
+be positive, negative, or zero but not all combinations of @var{origin} and\n\
+@var{offset} can be realized.\n\
 \n\
 Return 0 on success and -1 on error.\n\
 @seealso{fskipl, frewind, ftell, fopen}\n\
@@ -1440,84 +1433,84 @@
 data to read and may be one of\n\
 \n\
 @table @asis\n\
-@item \"schar\"\n\
-@itemx \"signed char\"\n\
+@item  @qcode{\"schar\"}\n\
+@itemx @qcode{\"signed char\"}\n\
 Signed character.\n\
 \n\
-@item \"uchar\"\n\
-@itemx \"unsigned char\"\n\
+@item  @qcode{\"uchar\"}\n\
+@itemx @qcode{\"unsigned char\"}\n\
 Unsigned character.\n\
 \n\
-@item \"int8\"\n\
-@itemx \"integer*1\"\n\
+@item  @qcode{\"int8\"}\n\
+@itemx @qcode{\"integer*1\"}\n\
 \n\
 8-bit signed integer.\n\
 \n\
-@item \"int16\"\n\
-@itemx \"integer*2\"\n\
+@item  @qcode{\"int16\"}\n\
+@itemx @qcode{\"integer*2\"}\n\
 16-bit signed integer.\n\
 \n\
-@item \"int32\"\n\
-@itemx \"integer*4\"\n\
+@item  @qcode{\"int32\"}\n\
+@itemx @qcode{\"integer*4\"}\n\
 32-bit signed integer.\n\
 \n\
-@item \"int64\"\n\
-@itemx \"integer*8\"\n\
+@item  @qcode{\"int64\"}\n\
+@itemx @qcode{\"integer*8\"}\n\
 64-bit signed integer.\n\
 \n\
-@item \"uint8\"\n\
+@item @qcode{\"uint8\"}\n\
 8-bit unsigned integer.\n\
 \n\
-@item \"uint16\"\n\
+@item @qcode{\"uint16\"}\n\
 16-bit unsigned integer.\n\
 \n\
-@item \"uint32\"\n\
+@item @qcode{\"uint32\"}\n\
 32-bit unsigned integer.\n\
 \n\
-@item \"uint64\"\n\
+@item @qcode{\"uint64\"}\n\
 64-bit unsigned integer.\n\
 \n\
-@item \"single\"\n\
-@itemx \"float32\"\n\
-@itemx \"real*4\"\n\
+@item  @qcode{\"single\"}\n\
+@itemx @qcode{\"float32\"}\n\
+@itemx @qcode{\"real*4\"}\n\
 32-bit floating point number.\n\
 \n\
-@item \"double\"\n\
-@itemx \"float64\"\n\
-@itemx \"real*8\"\n\
+@item  @qcode{\"double\"}\n\
+@itemx @qcode{\"float64\"}\n\
+@itemx @qcode{\"real*8\"}\n\
 64-bit floating point number.\n\
 \n\
-@item \"char\"\n\
-@itemx \"char*1\"\n\
+@item  @qcode{\"char\"}\n\
+@itemx @qcode{\"char*1\"}\n\
 Single character.\n\
 \n\
-@item \"short\"\n\
+@item @qcode{\"short\"}\n\
 Short integer (size is platform dependent).\n\
 \n\
-@item \"int\"\n\
+@item @qcode{\"int\"}\n\
 Integer (size is platform dependent).\n\
 \n\
-@item \"long\"\n\
+@item @qcode{\"long\"}\n\
 Long integer (size is platform dependent).\n\
 \n\
-@item \"ushort\"\n\
-@itemx \"unsigned short\"\n\
+@item  @qcode{\"ushort\"}\n\
+@itemx @qcode{\"unsigned short\"}\n\
 Unsigned short integer (size is platform dependent).\n\
 \n\
-@item \"uint\"\n\
-@itemx \"unsigned int\"\n\
+@item  @qcode{\"uint\"}\n\
+@itemx @qcode{\"unsigned int\"}\n\
 Unsigned integer (size is platform dependent).\n\
 \n\
-@item \"ulong\"\n\
-@itemx \"unsigned long\"\n\
+@item  @qcode{\"ulong\"}\n\
+@itemx @qcode{\"unsigned long\"}\n\
 Unsigned long integer (size is platform dependent).\n\
 \n\
-@item \"float\"\n\
+@item @qcode{\"float\"}\n\
 Single precision floating point number (size is platform dependent).\n\
 @end table\n\
 \n\
 @noindent\n\
-The default precision is @code{\"uchar\"}.\n\
+The default precision is @qcode{\"uchar\"}.\n\
 \n\
 The @var{precision} argument may also specify an optional repeat\n\
 count.  For example, @samp{32*single} causes @code{fread} to read\n\
@@ -1553,7 +1546,7 @@
 for the file.  Valid values are\n\
 \n\
 @table @code\n\
-@item \"native\"\n\
+@item @qcode{\"native\"}\n\
 The format of the current machine.\n\
 \n\
 @item \"ieee-be\"\n\
@@ -1561,21 +1554,8 @@
 \n\
 @item \"ieee-le\"\n\
 IEEE little endian.\n\
-\n\
-@item \"vaxd\"\n\
-VAX D floating format.\n\
-\n\
-@item \"vaxg\"\n\
-VAX G floating format.\n\
-\n\
-@item \"cray\"\n\
-Cray floating format.\n\
 @end table\n\
 \n\
-@noindent\n\
-Conversions are currently only supported for @code{\"ieee-be\"} and\n\
-@code{\"ieee-le\"} formats.\n\
-\n\
 The data read from the file is returned in @var{val}, and the number of\n\
 values read is returned in @code{count}\n\
 @seealso{fwrite, fgets, fgetl, fscanf, fopen}\n\
@@ -1827,11 +1807,11 @@
 @var{mode} may be\n\
 \n\
 @table @code\n\
-@item \"r\"\n\
+@item @qcode{\"r\"}\n\
 The pipe will be connected to the standard output of the process, and\n\
 open for reading.\n\
 \n\
-@item \"w\"\n\
+@item @qcode{\"w\"}\n\
 The pipe will be connected to the standard input of the process, and\n\
 open for writing.\n\
 @end table\n\
@@ -1922,7 +1902,7 @@
 @deftypefnx {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
 Return a unique temporary file name as a string.\n\
 \n\
-If @var{prefix} is omitted, a value of @code{\"oct-\"} is used.\n\
+If @var{prefix} is omitted, a value of @qcode{\"oct-\"} is used.\n\
 If @var{dir} is also omitted, the default directory for temporary files\n\
 is used.  If @var{dir} is provided, it must exist, otherwise the default\n\
 directory for temporary files is used.  Since the named file is not\n\
@@ -1964,7 +1944,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
 Return the file ID corresponding to a new temporary file with a unique\n\
-name.  The file is opened in binary read/write (@code{\"w+b\"}) mode.\n\
+name.  The file is opened in binary read/write (@qcode{\"w+b\"}) mode.\n\
 The file will be deleted automatically when it is closed or when Octave\n\
 exits.\n\
 \n\
--- a/libinterp/corefcn/find.cc
+++ b/libinterp/corefcn/find.cc
@@ -377,9 +377,10 @@
 If two inputs are given, @var{n} indicates the maximum number of\n\
 elements to find from the beginning of the matrix or vector.\n\
 \n\
-If three inputs are given, @var{direction} should be one of \"first\" or\n\
-\"last\", requesting only the first or last @var{n} indices, respectively.\n\
-However, the indices are always returned in ascending order.\n\
+If three inputs are given, @var{direction} should be one of\n\
+@qcode{\"first\"} or @qcode{\"last\"}, requesting only the first or last\n\
+@var{n} indices, respectively.  However, the indices are always returned in\n\
+ascending order.\n\
 \n\
 Note that this function is particularly useful for sparse matrices, as\n\
 it extracts the non-zero elements as vectors, which can then be used to\n\
--- a/libinterp/corefcn/gammainc.cc
+++ b/libinterp/corefcn/gammainc.cc
@@ -66,8 +66,8 @@
 @var{a} must agree, and @code{gammainc} is applied element-by-element.\n\
 \n\
 By default the incomplete gamma function integrated from 0 to @var{x} is\n\
-computed.  If \"upper\" is given then the complementary function integrated\n\
-from @var{x} to infinity is calculated.  It should be noted that\n\
+computed.  If @qcode{\"upper\"} is given then the complementary function\n\
+integrated from @var{x} to infinity is calculated.  It should be noted that\n\
 \n\
 @example\n\
 gammainc (@var{x}, @var{a}) @equiv{} 1 - gammainc (@var{x}, @var{a}, \"upper\")\n\
--- a/libinterp/corefcn/gl-render.cc
+++ b/libinterp/corefcn/gl-render.cc
@@ -3009,7 +3009,7 @@
 {
 #if HAVE_FREETYPE
   text_renderer.text_to_pixels (txt, pixels, bbox,
-                                halign, valign, rotation);
+                                halign, valign, rotation, "none");
 #endif
 }
 
--- a/libinterp/corefcn/graphics.cc
+++ b/libinterp/corefcn/graphics.cc
@@ -1978,11 +1978,14 @@
 /*
 ## test set with name, value pairs
 %!test
-%! set (gcf, "visible", "off");
+%! hf = figure ("visible", "off");
 %! h = plot (1:10, 10:-1:1);
 %! set (h, "linewidth", 10, "marker", "x");
-%! assert (get (h, "linewidth"), 10);
-%! assert (get (h, "marker"), "x");
+%! lw = get (h, "linewidth");
+%! mk = get (h, "marker");
+%! close (hf);
+%! assert (lw, 10);
+%! assert (mk, "x");
 */
 
 // Set properties given in two cell arrays containing names and values.
@@ -2013,32 +2016,47 @@
 /*
 ## test set with cell array arguments
 %!test
-%! set (gcf, "visible", "off");
+%! hf = figure ("visible", "off");
 %! h = plot (1:10, 10:-1:1);
 %! set (h, {"linewidth", "marker"}, {10, "x"});
-%! assert (get (h, "linewidth"), 10);
-%! assert (get (h, "marker"), "x");
+%! lw = get (h, "linewidth");
+%! mk = get (h, "marker");
+%! close (hf);
+%! assert (lw, 10);
+%! assert (mk, "x");
 
 ## test set with multiple handles and cell array arguments
 %!test
-%! set (gcf, "visible", "off");
-%! h = plot (1:10, 10:-1:1, 1:10, 1:10);
-%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"});
-%! assert (get (h, "linewidth"), {10; 5});
-%! assert (get (h, "marker"), {"x"; "o"});
-%! set (h, {"linewidth", "marker"}, {10, "x"});
-%! assert (get (h, "linewidth"), {10; 10});
-%! assert (get (h, "marker"), {"x"; "x"});
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = plot (1:10, 10:-1:1, 1:10, 1:10);
+%!   set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"});
+%!   assert (get (h, "linewidth"), {10; 5});
+%!   assert (get (h, "marker"), {"x"; "o"});
+%!   set (h, {"linewidth", "marker"}, {10, "x"});
+%!   assert (get (h, "linewidth"), {10; 10});
+%!   assert (get (h, "marker"), {"x"; "x"});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect;
 
 %!error <set: number of graphics handles must match number of value rows>
-%! set (gcf, "visible", "off");
-%! h = plot (1:10, 10:-1:1, 1:10, 1:10);
-%! set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"; 7, "."});
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = plot (1:10, 10:-1:1, 1:10, 1:10);
+%!   set (h, {"linewidth", "marker"}, {10, "x"; 5, "o"; 7, "."});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
 
 %!error <set: number of names must match number of value columns>
-%! set (gcf, "visible", "off");
-%! h = plot (1:10, 10:-1:1, 1:10, 1:10);
-%! set (h, {"linewidth"}, {10, "x"; 5, "o"});
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = plot (1:10, 10:-1:1, 1:10, 1:10);
+%!   set (h, {"linewidth"}, {10, "x"; 5, "o"});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
 */
 
 // Set properties given in a struct array
@@ -2061,27 +2079,34 @@
 /*
 ## test set ticklabels for compatibility
 %!test
-%! set (gcf (), "visible", "off");
+%! hf = figure ("visible", "off");
 %! set (gca (), "xticklabel", [0, 0.2, 0.4, 0.6, 0.8, 1]);
 %! xticklabel = get (gca (), "xticklabel");
+%! close (hf);
 %! assert (class (xticklabel), "char");
 %! assert (size (xticklabel), [6, 3]);
+
 %!test
-%! set (gcf (), "visible", "off");
+%! hf = figure ("visible", "off");
 %! set (gca (), "xticklabel", "0|0.2|0.4|0.6|0.8|1");
 %! xticklabel = get (gca (), "xticklabel");
+%! close (hf);
 %! assert (class (xticklabel), "char");
 %! assert (size (xticklabel), [6, 3]);
+
 %!test
-%! set (gcf (), "visible", "off");
+%! hf = figure ("visible", "off");
 %! set (gca (), "xticklabel", ["0 "; "0.2"; "0.4"; "0.6"; "0.8"; "1 "]);
 %! xticklabel = get (gca (), "xticklabel");
+%! close (hf);
 %! assert (class (xticklabel), "char");
 %! assert (size (xticklabel), [6, 3]);
+
 %!test
-%! set (gcf (), "visible", "off");
+%! hf = figure ("visible", "off");
 %! set (gca (), "xticklabel", {"0", "0.2", "0.4", "0.6", "0.8", "1"});
 %! xticklabel = get (gca (), "xticklabel");
+%! close (hf);
 %! assert (class (xticklabel), "cell");
 %! assert (size (xticklabel), [6, 1]);
 */
@@ -2089,40 +2114,47 @@
 /*
 ## test set with struct arguments
 %!test
-%! set (gcf, "visible", "off");
-%! h = plot (1:10, 10:-1:1);
-%! set (h, struct ("linewidth", 10, "marker", "x"));
-%! assert (get (h, "linewidth"), 10);
-%! assert (get (h, "marker"), "x");
-%! h = plot (1:10, 10:-1:1, 1:10, 1:10);
-%! set (h, struct ("linewidth", {5, 10}));
-%! assert (get (h, "linewidth"), {10; 10});
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = plot (1:10, 10:-1:1);
+%!   set (h, struct ("linewidth", 10, "marker", "x"));
+%!   assert (get (h, "linewidth"), 10);
+%!   assert (get (h, "marker"), "x");
+%!   h = plot (1:10, 10:-1:1, 1:10, 1:10);
+%!   set (h, struct ("linewidth", {5, 10}));
+%!   assert (get (h, "linewidth"), {10; 10});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
 ## test ordering
 %!test
 %! markchanged = @(h, foobar, name) set (h, "userdata", [get(h,"userdata"); {name}]);
-%! figure (1, "visible", "off")
-%! clf ();
-%! h = line ();
-%! set (h, "userdata", {});
-%! addlistener (h, "color", {markchanged, "color"});
-%! addlistener (h, "linewidth", {markchanged, "linewidth"});
-%! # "linewidth" first
-%! props.linewidth = 2;
-%! props.color = "r";
-%! set (h, props);
-%! assert (get (h, "userdata"), fieldnames (props));
-%! clear props
-%! clf ();
-%! h = line ();
-%! set (h, "userdata", {});
-%! addlistener (h, "color", {markchanged, "color"});
-%! addlistener (h, "linewidth", {markchanged, "linewidth"});
-%! # "color" first
-%! props.color = "r";
-%! props.linewidth = 2;
-%! set (h, props);
-%! assert (get (h, "userdata"), fieldnames (props));
-%! close (1);
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = line ();
+%!   set (h, "userdata", {});
+%!   addlistener (h, "color", {markchanged, "color"});
+%!   addlistener (h, "linewidth", {markchanged, "linewidth"});
+%!   ## "linewidth" first
+%!   props.linewidth = 2;
+%!   props.color = "r";
+%!   set (h, props);
+%!   assert (get (h, "userdata"), fieldnames (props));
+%!   clear props;
+%!   clf ();
+%!   h = line ();
+%!   set (h, "userdata", {});
+%!   addlistener (h, "color", {markchanged, "color"});
+%!   addlistener (h, "linewidth", {markchanged, "linewidth"});
+%!   ## "color" first
+%!   props.color = "r";
+%!   props.linewidth = 2;
+%!   set (h, props);
+%!   assert (get (h, "userdata"), fieldnames (props));
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
 */
 
 // Set a property to a value or to its (factory) default value.
@@ -2173,13 +2205,19 @@
 /*
 ## test setting of default values
 %!test
-%! set (gcf, "visible", "off");
-%! h = plot (1:10, 10:-1:1);
-%! set (0, "defaultlinelinewidth", 20);
-%! set (h, "linewidth", "default");
-%! assert (get (h, "linewidth"), 20);
-%! set (h, "linewidth", "factory");
-%! assert (get (h, "linewidth"), 0.5);
+%! old_lw = get (0, "defaultlinelinewidth");
+%! unwind_protect
+%!   hf = figure ("visible", "off");
+%!   h = plot (1:10, 10:-1:1);
+%!   set (0, "defaultlinelinewidth", 20);
+%!   set (h, "linewidth", "default");
+%!   assert (get (h, "linewidth"), 20);
+%!   set (h, "linewidth", "factory");
+%!   assert (get (h, "linewidth"), 0.5);
+%! unwind_protect_cleanup
+%!   close (hf);
+%!   set (0, "defaultlinelinewidth", old_lw);
+%! end_unwind_protect
 */
 
 static double
@@ -3125,19 +3163,24 @@
 
 /*
 %!test
-%! set (0, "units", "pixels");
-%! sz = get (0, "screensize") - [1, 1, 0, 0];
-%! dpi = get (0, "screenpixelsperinch");
-%! set (0, "units", "inches");
-%! assert (get (0, "screensize"), sz / dpi, 0.5 / dpi);
-%! set (0, "units", "centimeters");
-%! assert (get (0, "screensize"), sz / dpi * 2.54, 0.5 / dpi * 2.54);
-%! set (0, "units", "points");
-%! assert (get (0, "screensize"), sz / dpi * 72, 0.5 / dpi * 72);
-%! set (0, "units", "normalized");
-%! assert (get (0, "screensize"), [0.0, 0.0, 1.0, 1.0]);
-%! set (0, "units", "pixels");
-%! assert (get (0, "screensize"), sz + [1, 1, 0, 0]);
+%! old_units = get (0, "units");
+%! unwind_protect
+%!   set (0, "units", "pixels");
+%!   sz = get (0, "screensize") - [1, 1, 0, 0];
+%!   dpi = get (0, "screenpixelsperinch");
+%!   set (0, "units", "inches");
+%!   assert (get (0, "screensize"), sz / dpi, 0.5 / dpi);
+%!   set (0, "units", "centimeters");
+%!   assert (get (0, "screensize"), sz / dpi * 2.54, 0.5 / dpi * 2.54);
+%!   set (0, "units", "points");
+%!   assert (get (0, "screensize"), sz / dpi * 72, 0.5 / dpi * 72);
+%!   set (0, "units", "normalized");
+%!   assert (get (0, "screensize"), [0.0, 0.0, 1.0, 1.0]);
+%!   set (0, "units", "pixels");
+%!   assert (get (0, "screensize"), sz + [1, 1, 0, 0]);
+%! unwind_protect_cleanup
+%!   set (0, "units", old_units);
+%! end_unwind_protect
 */
 
 void
@@ -3745,27 +3788,34 @@
 
 /*
 %!test
-%! figure (1, "visible", "off");
-%! set (1, "paperunits", "inches");
-%! set (1, "papersize", [5, 4]);
-%! set (1, "paperunits", "points");
-%! assert (get (1, "papersize"), [5, 4] * 72, 1);
-%! papersize = get (gcf, "papersize");
-%! set (1, "papersize", papersize + 1);
-%! set (1, "papersize", papersize);
-%! assert (get (1, "papersize"), [5, 4] * 72, 1);
-%! close (1);
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   set (hf, "paperunits", "inches");
+%!   set (hf, "papersize", [5, 4]);
+%!   set (hf, "paperunits", "points");
+%!   assert (get (hf, "papersize"), [5, 4] * 72, 1);
+%!   papersize = get (hf, "papersize");
+%!   set (hf, "papersize", papersize + 1);
+%!   set (hf, "papersize", papersize);
+%!   assert (get (hf, "papersize"), [5, 4] * 72, 1);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
 %!test
-%! figure (1, "visible", "off");
-%! set (1, "paperunits", "inches");
-%! set (1, "papersize", [5, 4]);
-%! set (1, "paperunits", "centimeters");
-%! assert (get (1, "papersize"), [5, 4] * 2.54, 2.54/72);
-%! papersize = get (gcf, "papersize");
-%! set (1, "papersize", papersize + 1);
-%! set (1, "papersize", papersize);
-%! assert (get (1, "papersize"), [5, 4] * 2.54, 2.54/72);
-%! close (1);
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   set (hf, "paperunits", "inches");
+%!   set (hf, "papersize", [5, 4]);
+%!   set (hf, "paperunits", "centimeters");
+%!   assert (get (hf, "papersize"), [5, 4] * 2.54, 2.54/72);
+%!   papersize = get (hf, "papersize");
+%!   set (hf, "papersize", papersize + 1);
+%!   set (hf, "papersize", papersize);
+%!   assert (get (hf, "papersize"), [5, 4] * 2.54, 2.54/72);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
 */
 
 void
@@ -3789,25 +3839,29 @@
 
 /*
 %!test
-%! figure (1, "visible", false);
-%! tol = 100 * eps ();
-%! ## UPPER case and MiXed case is part of test and should not be changed.
-%! set (gcf (), "paperorientation", "PORTRAIT");
-%! set (gcf (), "paperunits", "inches");
-%! set (gcf (), "papertype", "USletter");
-%! assert (get (gcf (), "papersize"), [8.5, 11.0], tol);
-%! set (gcf (), "paperorientation", "Landscape");
-%! assert (get (gcf (), "papersize"), [11.0, 8.5], tol);
-%! set (gcf (), "paperunits", "centimeters");
-%! assert (get (gcf (), "papersize"), [11.0, 8.5] * 2.54, tol);
-%! set (gcf (), "papertype", "a4");
-%! assert (get (gcf (), "papersize"), [29.7, 21.0], tol);
-%! set (gcf (), "paperunits", "inches", "papersize", [8.5, 11.0]);
-%! assert (get (gcf (), "papertype"), "usletter");
-%! assert (get (gcf (), "paperorientation"), "portrait");
-%! set (gcf (), "papersize", [11.0, 8.5]);
-%! assert (get (gcf (), "papertype"), "usletter");
-%! assert (get (gcf (), "paperorientation"), "landscape");
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 100 * eps ();
+%!   ## UPPER case and MiXed case is part of test and should not be changed.
+%!   set (hf, "paperorientation", "PORTRAIT");
+%!   set (hf, "paperunits", "inches");
+%!   set (hf, "papertype", "USletter");
+%!   assert (get (hf, "papersize"), [8.5, 11.0], tol);
+%!   set (hf, "paperorientation", "Landscape");
+%!   assert (get (hf, "papersize"), [11.0, 8.5], tol);
+%!   set (hf, "paperunits", "centimeters");
+%!   assert (get (hf, "papersize"), [11.0, 8.5] * 2.54, tol);
+%!   set (hf, "papertype", "a4");
+%!   assert (get (hf, "papersize"), [29.7, 21.0], tol);
+%!   set (hf, "paperunits", "inches", "papersize", [8.5, 11.0]);
+%!   assert (get (hf, "papertype"), "usletter");
+%!   assert (get (hf, "paperorientation"), "portrait");
+%!   set (hf, "papersize", [11.0, 8.5]);
+%!   assert (get (hf, "papertype"), "usletter");
+%!   assert (get (hf, "paperorientation"), "landscape");
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
 */
 
 void
@@ -3833,13 +3887,20 @@
 
 /*
 %!test
-%! figure (1, "visible", false);
-%! set (0, "units", "pixels");
-%! rsz = get (0, "screensize");
-%! set (gcf (), "units", "pixels");
-%! fsz = get (gcf (), "position");
-%! set (gcf (), "units", "normalized");
-%! assert (get (gcf (), "position"), (fsz - [1, 1, 0, 0]) ./ rsz([3, 4, 3, 4]));
+%! hf = figure ("visible", "off");
+%! old_units = get (0, "units");
+%! unwind_protect
+%!   set (0, "units", "pixels");
+%!   rsz = get (0, "screensize");
+%!   set (gcf (), "units", "pixels");
+%!   fsz = get (gcf (), "position");
+%!   set (gcf (), "units", "normalized");
+%!   pos = get (gcf (), "position");
+%!   assert (pos, (fsz - [1, 1, 0, 0]) ./ rsz([3, 4, 3, 4]));
+%! unwind_protect_cleanup
+%!   close (hf);
+%!   set (0, "units", old_units);
+%! end_unwind_protect
 */
 
 std::string
@@ -4007,6 +4068,10 @@
 axes::properties::sync_positions (void)
 {
   // First part is equivalent to `update_tightinset ()'
+  if (activepositionproperty.is ("position"))
+    update_position ();
+  else
+    update_outerposition ();
   caseless_str old_units = get_units ();
   set_units ("normalized");
   Matrix pos = position.get ().matrix_value ();
@@ -4020,8 +4085,6 @@
   tightinset = tinset;
   set_units (old_units);
   update_transform ();
-  // Changes to tightinset may result in changes to the inactive
-  // position property
   if (activepositionproperty.is ("position"))
     update_position ();
   else
@@ -4029,22 +4092,61 @@
 }
 
 /*
-%!xtest
+%!testif HAVE_FLTK
+%! hf = figure ("visible", "off");
+%! graphics_toolkit (hf, "fltk");
 %! unwind_protect
-%!   hf = figure (gcf (), "__graphics_toolkit__", "fltk", "visible", "off");
-%!   clf;
-%!   subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1))
+%!   subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1));
 %!   hax = findall (gcf (), "type", "axes");
 %!   positions = cell2mat (get (hax, "position"));
 %!   outerpositions = cell2mat (get (hax, "outerposition"));
 %!   looseinsets = cell2mat (get (hax, "looseinset"));
 %!   tightinsets = cell2mat (get (hax, "tightinset"));
-%!   subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1))
+%!   subplot(2,1,1); plot(rand(10,1)); subplot(2,1,2); plot(rand(10,1));
 %!   hax = findall (gcf (), "type", "axes");
-%!   assert (cell2mat (get (hax, "position")), positions)
-%!   assert (cell2mat (get (hax, "outerposition")), outerpositions)
-%!   assert (cell2mat (get (hax, "looseinset")), looseinsets)
-%!   assert (cell2mat (get (hax, "tightinset")), tightinsets)
+%!   assert (cell2mat (get (hax, "position")), positions, 1e-4);
+%!   assert (cell2mat (get (hax, "outerposition")), outerpositions, 1e-4);
+%!   assert (cell2mat (get (hax, "looseinset")), looseinsets, 1e-4);
+%!   assert (cell2mat (get (hax, "tightinset")), tightinsets, 1e-4);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+%!testif HAVE_FLTK
+%! hf = figure ("visible", "off");
+%! graphics_toolkit (hf, "fltk");
+%! fpos = get (hf, "position");
+%! unwind_protect
+%!   plot (rand (3))
+%!   position = get (gca, "position");
+%!   outerposition = get (gca, "outerposition");
+%!   looseinset = get (gca, "looseinset");
+%!   tightinset = get (gca, "tightinset");
+%!   set (hf, "position", [fpos(1:2), 2*fpos(3:4)])
+%!   set (hf, "position", fpos);
+%!   assert (get (gca, "outerposition"), outerposition, 0.001)
+%!   assert (get (gca, "position"), position, 0.001)
+%!   assert (get (gca, "looseinset"), looseinset, 0.001)
+%!   assert (get (gca, "tightinset"), tightinset, 0.001)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+%!testif HAVE_FLTK
+%! hf = figure ("visible", "off");
+%! graphics_toolkit (hf, "fltk");
+%! fpos = get (hf, "position");
+%! set (gca, "activepositionproperty", "position")
+%! unwind_protect
+%!   plot (rand (3))
+%!   position = get (gca, "position");
+%!   outerposition = get (gca, "outerposition");
+%!   looseinset = get (gca, "looseinset");
+%!   tightinset = get (gca, "tightinset");
+%!   set (hf, "position", [fpos(1:2), 2*fpos(3:4)])
+%!   set (hf, "position", fpos);
+%!   assert (get (gca, "position"), position, 0.001)
+%!   assert (get (gca, "outerposition"), outerposition, 0.001)
+%!   assert (get (gca, "looseinset"), looseinset, 0.001)
+%!   assert (get (gca, "tightinset"), tightinset, 0.001)
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
@@ -5680,6 +5782,56 @@
     }
 }
 
+// Almost identical to convert_ticklabel_string but it only accepts
+// cellstr or string, not numeric input.
+static octave_value
+convert_linestyleorder_string (const octave_value& val)
+{
+  octave_value retval = val;
+
+  if (val.is_cellstr ())
+    {
+      // Always return a column vector for Matlab Compatibility
+      if (val.columns () > 1)
+        retval = val.reshape (dim_vector (val.numel (), 1));
+    }
+  else
+    {
+      string_vector sv;
+      if (val.is_string () && val.rows () == 1)
+        {
+          std::string valstr = val.string_value ();
+          std::istringstream iss (valstr);
+          std::string tmpstr;
+
+          // Split string with delimiter '|'
+          while (std::getline (iss, tmpstr, '|'))
+            sv.append (tmpstr);
+          
+          // If string ends with '|' Matlab appends a null string
+          if (*valstr.rbegin () == '|')
+            sv.append (std::string (""));
+        }
+      else
+        return retval;
+
+      charMatrix chmat (sv, ' ');
+
+      retval = octave_value (chmat);
+    }
+
+  return retval;
+}
+
+void
+axes::properties::set_linestyleorder (const octave_value& v)
+{
+  if (!error_state)
+    {
+      linestyleorder.set (convert_linestyleorder_string (v), false);
+    }
+}
+
 void
 axes::properties::set_units (const octave_value& v)
 {
@@ -6190,7 +6342,7 @@
           label.erase (0, label.find_first_not_of (" "));
           label = label.substr (0, label.find_last_not_of (" ")+1);
 #ifdef HAVE_FREETYPE
-          ext = text_renderer.get_extent (label);
+          ext = text_renderer.get_extent (label, 0.0, "none");
           wmax = std::max (wmax, ext(0));
           hmax = std::max (hmax, ext(1));
 #else
@@ -7026,7 +7178,8 @@
   string_vector sv = string_prop.all_strings ();
 
   renderer.text_to_pixels (sv.join ("\n"), pixels, bbox,
-                           halign, valign, get_rotation ());
+                           halign, valign, get_rotation (),
+                           get_interpreter ());
   /* The bbox is relative to the text's position.
      We'll leave it that way, because get_position () does not return
      valid results when the text is first constructed.
@@ -7471,7 +7624,7 @@
   // FIXME: parsed content should be cached for efficiency
   // FIXME: support multiline text
 
-  elt = text_parser_none ().parse (get_string_string ());
+  elt = text_parser::parse (get_string_string (), "none");
 #ifdef HAVE_FONTCONFIG
   text_renderer.set_font (get_fontname (),
                           get_fontweight (),
@@ -7479,6 +7632,7 @@
                           get_fontsize ());
 #endif
   box = text_renderer.get_extent (elt, 0);
+  delete elt;
 
   Matrix ext (1, 4, 0.0);
 
@@ -8363,9 +8517,10 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} reset (@var{h}, @var{property})\n\
 Remove any defaults set for the handle @var{h}.  The default figure\n\
-properties of \"position\", \"units\", \"windowstyle\" and\n\
-\"paperunits\" and the default axes properties of \"position\" and \"units\"\n\
-are not reset.\n\
+properties of @qcode{\"position\"}, @qcode{\"units\"},\n\
+@qcode{\"windowstyle\"} and @qcode{\"paperunits\"} and the default axes\n\
+properties of @qcode{\"position\"} and @qcode{\"units\"} are not reset.\n\
+@seealso{cla, clf}\n\
 @end deftypefn")
 {
   int nargin = args.length ();
@@ -9447,7 +9602,7 @@
 @deftypefnx {Built-in Function} {} drawnow (@var{term}, @var{file}, @var{mono}, @var{debug_file})\n\
 Update figure windows and their children.  The event queue is flushed and\n\
 any callbacks generated are executed.  With the optional argument\n\
-@code{\"expose\"}, only graphic objects are updated and no other events or\n\
+@qcode{\"expose\"}, only graphic objects are updated and no other events or\n\
 callbacks are processed.\n\
 The third calling form of @code{drawnow} is for debugging and is\n\
 undocumented.\n\
--- a/libinterp/corefcn/graphics.in.h
+++ b/libinterp/corefcn/graphics.in.h
@@ -3811,7 +3811,8 @@
       //       more sense to have it so that axis ticklabels can use it.
       radio_property interpreter , "tex|{none}|latex"
       radio_property layer u , "{bottom}|top"
-      string_array_property linestyleorder , "-"
+      // FIXME: should be kind of string array.
+      any_property linestyleorder S , "-"
       double_property linewidth , 0.5
       radio_property minorgridlinestyle , "-|--|{:}|-.|none"
       radio_property nextplot , "add|replacechildren|{replace}"
--- a/libinterp/corefcn/help.cc
+++ b/libinterp/corefcn/help.cc
@@ -641,8 +641,8 @@
 
   pair_type ("parfor",
     "-*- texinfo -*-\n\
-@deftypefn  {Keyword} {} for @var{i} = @var{range}\n\
-@deftypefnx {Keyword} {} for (@var{i} = @var{range}, @var{maxproc})\n\
+@deftypefn  {Keyword} {} parfor @var{i} = @var{range}\n\
+@deftypefnx {Keyword} {} parfor (@var{i} = @var{range}, @var{maxproc})\n\
 Begin a for loop that may execute in parallel.\n\
 \n\
 @example\n\
@@ -967,7 +967,7 @@
   if (file)
     {
       // Ignore header;
-      file.ignore (1000, 0x1f);
+      file.ignore (1000, 0x1d);
 
       if (file.gcount () == 1000)
         {
@@ -988,7 +988,7 @@
 
       while (! file.eof ())
         {
-          file.getline (buf, bufsize, 0x1f);
+          file.getline (buf, bufsize, 0x1d);
 
           std::string tmp (buf);
 
@@ -1066,8 +1066,8 @@
 Return the raw help text of function @var{name}.\n\
 \n\
 The raw help text is returned in @var{text} and the format in @var{format}\n\
-The format is a string which is one of @t{\"texinfo\"}, @t{\"html\"}, or\n\
-@t{\"plain text\"}.\n\
+The format is a string which is one of @qcode{\"texinfo\"},\n\
+@qcode{\"html\"}, or @qcode{\"plain text\"}.\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1135,8 +1135,8 @@
 Return the raw help text from the file @var{fname}.\n\
 \n\
 The raw help text is returned in @var{text} and the format in @var{format}\n\
-The format is a string which is one of @t{\"texinfo\"}, @t{\"html\"}, or\n\
-@t{\"plain text\"}.\n\
+The format is a string which is one of @qcode{\"texinfo\"},\n\
+@qcode{\"html\"}, or @qcode{\"plain text\"}.\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1398,9 +1398,9 @@
 @w{@env{OCTAVE_DOC_CACHE_FILE}}, or the command line argument\n\
 @samp{--doc-cache-file FNAME}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{doc_cache_create, lookfor, info_program, doc, help, makeinfo_program}\n\
 @end deftypefn")
 {
@@ -1422,9 +1422,9 @@
 @w{@env{OCTAVE_TEXI_MACROS_FILE}}, or the command line argument\n\
 @samp{--texi-macros-file FNAME}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{makeinfo_program}\n\
 @end deftypefn")
 {
@@ -1444,9 +1444,9 @@
 @w{@env{OCTAVE_INFO_FILE}}, or the command line argument\n\
 @samp{--info-file FNAME}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{info_program, doc, help, makeinfo_program}\n\
 @end deftypefn")
 {
@@ -1468,9 +1468,9 @@
 @w{@env{OCTAVE_INFO_PROGRAM}}, or the command line argument\n\
 @samp{--info-program NAME}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{info_file, doc, help, makeinfo_program}\n\
 @end deftypefn")
 {
@@ -1486,9 +1486,9 @@
 program that Octave runs to format help text containing\n\
 Texinfo markup commands.  The default value is @code{makeinfo}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{texi_macros_file, info_file, info_program, doc, help}\n\
 @end deftypefn")
 {
@@ -1504,9 +1504,9 @@
 will add additional help information to the end of the output from\n\
 the @code{help} command and usage messages for built-in commands.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (suppress_verbose_help_message);
--- a/libinterp/corefcn/hex2num.cc
+++ b/libinterp/corefcn/hex2num.cc
@@ -34,10 +34,11 @@
 
 DEFUN (hex2num, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{n} =} hex2num (@var{s})\n\
+@deftypefn  {Built-in Function} {@var{n} =} hex2num (@var{s})\n\
+@deftypefnx {Built-in Function} {@var{n} =} hex2num (@var{s}, @var{class})\n\
 Typecast the 16 character hexadecimal character string to an IEEE 754\n\
 double precision number.  If fewer than 16 characters are given the\n\
-strings are right padded with '0' characters.\n\
+strings are right padded with @qcode{'0'} characters.\n\
 \n\
 Given a string matrix, @code{hex2num} treats each row as a separate\n\
 number.\n\
@@ -48,70 +49,142 @@
    @result{} [2.7183; 10.000]\n\
 @end group\n\
 @end example\n\
+\n\
+The optional argument @var{class} can be passed as the string\n\
+@qcode{\"single\"} to specify that the given string should be interpreted as\n\
+a single precision number.  In this case, @var{s} should be an 8 character\n\
+hexadecimal string.  For example: \n\
+\n\
+@example\n\
+@group\n\
+hex2num ([\"402df854\"; \"41200000\"], \"single\")\n\
+   @result{} [2.7183; 10.000]\n\
+@end group\n\
+@end example\n\
 @seealso{num2hex, hex2dec, dec2hex}\n\
 @end deftypefn")
 {
   int nargin = args.length ();
   octave_value retval;
 
-  if (nargin != 1)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
+  else if (nargin == 2 && ! args(1).is_string ())
+    error ("hex2num: CLASS must be a string");
   else
     {
       const charMatrix cmat = args(0).char_matrix_value ();
+      std::string prec = (nargin == 2) ? args(1).string_value () : "double";
+      bool is_single = (prec == "single");
+      octave_idx_type nchars = (is_single) ? 8 : 16;
 
-      if (cmat.columns () > 16)
-        error ("hex2num: S must be no more than 16 characters");
+      if (cmat.columns () > nchars)
+        error ("hex2num: S must be no more than %d characters", nchars);
+      else if (prec != "double" && prec != "single")
+        error ("hex2num: CLASS must be either \"double\" or \"single\"");
       else if (! error_state)
         {
           octave_idx_type nr = cmat.rows ();
           octave_idx_type nc = cmat.columns ();
-          ColumnVector m (nr);
 
-          for (octave_idx_type i = 0; i < nr; i++)
+          if (is_single)
             {
-              union
-              {
-                uint64_t ival;
-                double dval;
-              } num;
+              FloatColumnVector m (nr);
 
-              num.ival = 0;
+              for (octave_idx_type i = 0; i < nr; i++)
+                {
+                  union
+                  {
+                    uint32_t ival;
+                    float dval;
+                  } num;
+
+                  num.ival = 0;
+
+                  for (octave_idx_type j = 0; j < nc; j++)
+                    {
+                      unsigned char ch = cmat.elem (i, j);
 
-              for (octave_idx_type j = 0; j < nc; j++)
-                {
-                  unsigned char ch = cmat.elem (i, j);
+                      if (isxdigit (ch))
+                        {
+                          num.ival <<= 4;
+                          if (ch >= 'a')
+                            num.ival += static_cast<uint32_t> (ch - 'a' + 10);
+                          else if (ch >= 'A')
+                            num.ival += static_cast<uint32_t> (ch - 'A' + 10);
+                          else
+                            num.ival += static_cast<uint32_t> (ch - '0');
+                        }
+                      else
+                        {
+                          error ("hex2num: illegal character found in string S");
+                          break;
+                        }
+                    }
 
-                  if (isxdigit (ch))
-                    {
-                      num.ival <<= 4;
-                      if (ch >= 'a')
-                        num.ival += static_cast<uint64_t> (ch - 'a' + 10);
-                      else if (ch >= 'A')
-                        num.ival += static_cast<uint64_t> (ch - 'A' + 10);
-                      else
-                        num.ival += static_cast<uint64_t> (ch - '0');
-                    }
+                  if (error_state)
+                    break;
                   else
                     {
-                      error ("hex2num: illegal character found in string S");
-                      break;
+                      if (nc < nchars)
+                        num.ival <<= (nchars - nc) * 4;
+
+                      m(i) = num.dval;
                     }
                 }
 
-              if (error_state)
-                break;
-              else
+              if (! error_state)
+                retval =  m;
+            }
+          else
+            {
+              ColumnVector m (nr);
+
+              for (octave_idx_type i = 0; i < nr; i++)
                 {
-                  if (nc < 16)
-                    num.ival <<= (16 - nc) * 4;
+                  union
+                  {
+                    uint64_t ival;
+                    double dval;
+                  } num;
+
+                  num.ival = 0;
+
+                  for (octave_idx_type j = 0; j < nc; j++)
+                    {
+                      unsigned char ch = cmat.elem (i, j);
 
-                  m(i) = num.dval;
+                      if (isxdigit (ch))
+                        {
+                          num.ival <<= 4;
+                          if (ch >= 'a')
+                            num.ival += static_cast<uint64_t> (ch - 'a' + 10);
+                          else if (ch >= 'A')
+                            num.ival += static_cast<uint64_t> (ch - 'A' + 10);
+                          else
+                            num.ival += static_cast<uint64_t> (ch - '0');
+                        }
+                      else
+                        {
+                          error ("hex2num: illegal character found in string S");
+                          break;
+                        }
+                    }
+
+                  if (error_state)
+                    break;
+                  else
+                    {
+                      if (nc < nchars)
+                        num.ival <<= (nchars - nc) * 4;
+
+                      m(i) = num.dval;
+                    }
                 }
+
+              if (! error_state)
+                retval =  m;
             }
-
-          if (! error_state)
-            retval =  m;
         }
     }
 
@@ -120,23 +193,36 @@
 
 /*
 %!assert (hex2num (["c00";"bff";"000";"3ff";"400"]), [-2:2]')
+%!assert (hex2num (["c00";"bf8";"000";"3f8";"400"], "single"), single([-2:2])')
 */
 
 DEFUN (num2hex, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{s} =} num2hex (@var{n})\n\
-Typecast a double precision number or vector to a 16 character hexadecimal\n\
-string of the IEEE 754 representation of the number.  For example:\n\
+Typecast a double or single precision number or vector to a 8 or 16\n\
+character hexadecimal string of the IEEE 754 representation of the number.\n\
+For example:\n\
 \n\
 @example\n\
 @group\n\
-num2hex ([-1, 1, e, Inf, NaN, NA])\n\
+num2hex ([-1, 1, e, Inf])\n\
 @result{} \"bff0000000000000\n\
     3ff0000000000000\n\
     4005bf0a8b145769\n\
-    7ff0000000000000\n\
-    fff8000000000000\n\
-    7ff00000000007a2\"\n\
+    7ff0000000000000\"\n\
+@end group\n\
+@end example\n\
+\n\
+If the argument @var{n} is a single precision number or vector, the returned\n\
+string has a length of 8.  For example:\n\
+\n\
+@example\n\
+@group\n\
+num2hex (single ([-1, 1, e, Inf]))\n\
+@result{} \"bf800000\n\
+    3f800000\n\
+    402df854\n\
+    7f800000\"\n\
 @end group\n\
 @end example\n\
 @seealso{hex2num, hex2dec, dec2hex}\n\
@@ -147,14 +233,52 @@
 
   if (nargin != 1)
     print_usage ();
+  else if (args(0).is_single_type ())
+    {
+      const FloatColumnVector v (args(0).float_vector_value ());
+
+      if (! error_state)
+        {
+          octave_idx_type nchars = 8;
+          octave_idx_type nr = v.length ();
+          charMatrix m (nr, nchars);
+          const float *pv = v.fortran_vec ();
+
+          for (octave_idx_type i = 0; i < nr; i++)
+            {
+              union
+              {
+                uint32_t ival;
+                float dval;
+              } num;
+
+              num.dval = *pv++;
+
+              for (octave_idx_type j = 0; j < nchars; j++)
+                {
+                  unsigned char ch =
+                    static_cast<char> (num.ival >> ((nchars - 1 - j) * 4) & 0xF);
+                  if (ch >= 10)
+                    ch += 'a' - 10;
+                  else
+                    ch += '0';
+
+                  m.elem (i, j) = ch;
+                }
+            }
+
+          retval = m;
+        }
+    }
   else
     {
       const ColumnVector v (args(0).vector_value ());
 
       if (! error_state)
         {
+          octave_idx_type nchars = 16;
           octave_idx_type nr = v.length ();
-          charMatrix m (nr, 16);
+          charMatrix m (nr, nchars);
           const double *pv = v.fortran_vec ();
 
           for (octave_idx_type i = 0; i < nr; i++)
@@ -167,10 +291,10 @@
 
               num.dval = *pv++;
 
-              for (octave_idx_type j = 0; j < 16; j++)
+              for (octave_idx_type j = 0; j < nchars; j++)
                 {
                   unsigned char ch =
-                    static_cast<char> (num.ival >> ((15 - j) * 4) & 0xF);
+                    static_cast<char> (num.ival >> ((nchars - 1 - j) * 4) & 0xF);
                   if (ch >= 10)
                     ch += 'a' - 10;
                   else
@@ -189,4 +313,5 @@
 
 /*
 %!assert (num2hex (-2:2), ["c000000000000000";"bff0000000000000";"0000000000000000";"3ff0000000000000";"4000000000000000"])
+%!assert (num2hex (single (-2:2)), ["c0000000";"bf800000";"00000000";"3f800000";"40000000"])
 */
--- a/libinterp/corefcn/input.cc
+++ b/libinterp/corefcn/input.cc
@@ -147,7 +147,7 @@
 void
 octave_base_reader::do_input_echo (const std::string& input_string) const
 {
-  int do_echo = LEXER->reading_script_file ?
+  int do_echo = (LEXER && LEXER->reading_script_file) ?
     (Vecho_executing_commands & ECHO_SCRIPTS)
       : (Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive;
 
@@ -272,9 +272,7 @@
     {
       if (! history_skip_auto_repeated_debugging_command)
         {
-          command_history::add (retval);
-
-          if (! command_history::ignoring_entries ())
+          if (command_history::add (retval))
             octave_link::append_history (retval);
         }
 
@@ -556,10 +554,10 @@
   VPS1 = prompt;
 
   if (! (interactive || forced_interactive)
-      || LEXER->reading_fcn_file
-      || LEXER->reading_classdef_file
-      || LEXER->reading_script_file
-      || LEXER->input_from_eval_string ())
+      || (LEXER && (LEXER->reading_fcn_file
+                    || LEXER->reading_classdef_file
+                    || LEXER->reading_script_file
+                    || LEXER->input_from_eval_string ())))
     {
       frame.protect_var (forced_interactive);
       forced_interactive = true;
@@ -741,7 +739,7 @@
 of values produced by the evaluation of the expression.\n\
 \n\
 If you are only interested in getting a literal string value, you can\n\
-call @code{input} with the character string @code{\"s\"} as the second\n\
+call @code{input} with the character string @qcode{\"s\"} as the second\n\
 argument.  This tells Octave to return the string entered by the user\n\
 directly, without evaluating it first.\n\
 \n\
@@ -1228,7 +1226,7 @@
 Query or set the primary prompt string.  When executing interactively,\n\
 Octave displays the primary prompt when it is ready to read a command.\n\
 \n\
-The default value of the primary prompt string is @code{\"\\s:\\#> \"}.\n\
+The default value of the primary prompt string is @qcode{\"\\s:\\#> \"}.\n\
 To change it, use a command like\n\
 \n\
 @example\n\
@@ -1251,9 +1249,9 @@
 @noindent\n\
 will give the default Octave prompt a red coloring.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{PS2, PS4}\n\
 @end deftypefn")
 {
@@ -1270,11 +1268,11 @@
 command.  For example, if you are typing a @code{for} loop that spans several\n\
 lines, Octave will print the secondary prompt at the beginning of\n\
 each line after the first.  The default value of the secondary prompt\n\
-string is @code{\"> \"}.\n\
+string is @qcode{\"> \"}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{PS1, PS4}\n\
 @end deftypefn")
 {
@@ -1288,12 +1286,12 @@
 @deftypefnx {Built-in Function} {} PS4 (@var{new_val}, \"local\")\n\
 Query or set the character string used to prefix output produced\n\
 when echoing commands is enabled.\n\
-The default value is @code{\"+ \"}.\n\
+The default value is @qcode{\"+ \"}.\n\
 @xref{Diary and Echo Commands}, for a description of echoing commands.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{echo, echo_executing_commands, PS1, PS2}\n\
 @end deftypefn")
 {
@@ -1307,11 +1305,11 @@
 @deftypefnx {Built-in Function} {} completion_append_char (@var{new_val}, \"local\")\n\
 Query or set the internal character variable that is appended to\n\
 successful command-line completion attempts.  The default\n\
-value is @code{\" \"} (a single space).\n\
+value is @qcode{\" \"} (a single space).\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (completion_append_char);
@@ -1342,9 +1340,9 @@
 The value of @code{echo_executing_commands} may be set by the @kbd{echo}\n\
 command or the command line option @option{--echo-commands}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (echo_executing_commands);
@@ -1417,9 +1415,9 @@
 @noindent\n\
 will set a breakpoint at the first line of the subfunction @code{mysubfunc}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   char tmp = Vfilemarker;
--- a/libinterp/corefcn/jit-ir.cc
+++ b/libinterp/corefcn/jit-ir.cc
@@ -34,8 +34,13 @@
 
 #include "jit-ir.h"
 
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+#include <llvm/IR/BasicBlock.h>
+#include <llvm/IR/Instructions.h>
+#else
 #include <llvm/BasicBlock.h>
 #include <llvm/Instructions.h>
+#endif
 
 #include "error.h"
 
--- a/libinterp/corefcn/jit-typeinfo.cc
+++ b/libinterp/corefcn/jit-typeinfo.cc
@@ -35,17 +35,30 @@
 #include "jit-typeinfo.h"
 
 #include <llvm/Analysis/Verifier.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+#include <llvm/IR/GlobalVariable.h>
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/Instructions.h>
+#include <llvm/IR/Intrinsics.h>
+#else
 #include <llvm/GlobalVariable.h>
-#include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include <llvm/LLVMContext.h>
 #include <llvm/Function.h>
 #include <llvm/Instructions.h>
 #include <llvm/Intrinsics.h>
-#ifdef IRBUILDER_HEADER_IN_SUPPORT_DIR
+#endif
+
+#ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H
 #include <llvm/Support/IRBuilder.h>
+#elif defined(HAVE_LLVM_IR_IRBUILDER_H)
+#include <llvm/IR/IRBuilder.h>
 #else
 #include <llvm/IRBuilder.h>
 #endif
+
 #include <llvm/Support/raw_os_ostream.h>
 
 #include "jit-ir.h"
--- a/libinterp/corefcn/jit-util.cc
+++ b/libinterp/corefcn/jit-util.cc
@@ -32,7 +32,12 @@
 
 #ifdef HAVE_LLVM
 
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+#include <llvm/IR/Value.h>
+#else
 #include <llvm/Value.h>
+#endif
+
 #include <llvm/Support/raw_os_ostream.h>
 
 std::ostream&
--- a/libinterp/corefcn/jit-util.h
+++ b/libinterp/corefcn/jit-util.h
@@ -31,6 +31,10 @@
 
 #include <stdexcept>
 
+#if defined(HAVE_LLVM_IR_DATALAYOUT_H) || defined(HAVE_LLVM_DATALAYOUT_H)
+#define HAVE_LLVM_DATALAYOUT
+#endif
+
 // we don't want to include llvm headers here, as they require
 // __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS be defined in the entire
 // compilation unit
--- a/libinterp/corefcn/load-path.cc
+++ b/libinterp/corefcn/load-path.cc
@@ -2166,8 +2166,8 @@
 @deftypefn  {Built-in Function} {} addpath (@var{dir1}, @dots{})\n\
 @deftypefnx {Built-in Function} {} addpath (@var{dir1}, @dots{}, @var{option})\n\
 Add named directories to the function search path.  If\n\
-@var{option} is \"-begin\" or 0 (the default), prepend the\n\
-directory name to the current path.  If @var{option} is \"-end\"\n\
+@var{option} is @qcode{\"-begin\"} or 0 (the default), prepend the\n\
+directory name to the current path.  If @var{option} is @qcode{\"-end\"}\n\
 or 1, append the directory name to the current path.\n\
 Directories added to the path must exist.\n\
 \n\
--- a/libinterp/corefcn/load-save.cc
+++ b/libinterp/corefcn/load-save.cc
@@ -269,6 +269,20 @@
 
               if (! tmp.empty ())
                 retval = LS_ASCII;
+              else
+                {
+                  file.clear ();
+                  file.seekg (0, std::ios::beg);
+
+                  // FIXME -- looks_like_mat_ascii_file does not check to see
+                  // whether the file contains numbers.  It just skips comments and
+                  // checks for the same number of words on each line.  We may need
+                  // a better check here.  The best way to do that might be just
+                  // to try to read the file and see if it works.
+
+                  if (looks_like_mat_ascii_file (file, filename))
+                    retval = LS_MAT_ASCII;
+                }
             }
         }
     }
@@ -288,39 +302,36 @@
     return LS_HDF5;
 #endif /* HAVE_HDF5 */
 
-  std::ifstream file (fname.c_str ());
+#ifdef HAVE_ZLIB
+  use_zlib = check_gzip_magic (fname);
+#else
   use_zlib = false;
-
-  if (file)
-    {
-      retval = get_file_format (file, orig_fname);
-      file.close ();
-
-#ifdef HAVE_ZLIB
-      if (retval == LS_UNKNOWN && check_gzip_magic (fname))
-        {
-          gzifstream gzfile (fname.c_str ());
-          use_zlib = true;
-
-          if (gzfile)
-            {
-              retval = get_file_format (gzfile, orig_fname);
-              gzfile.close ();
-            }
-        }
 #endif
 
-      // FIXME -- looks_like_mat_ascii_file does not check to see
-      // whether the file contains numbers.  It just skips comments and
-      // checks for the same number of words on each line.  We may need
-      // a better check here.  The best way to do that might be just
-      // to try to read the file and see if it works.
-
-      if (retval == LS_UNKNOWN && looks_like_mat_ascii_file (fname))
-        retval = LS_MAT_ASCII;
+  if (! use_zlib)
+    {
+      std::ifstream file (fname.c_str ());
+      if (file)
+        {
+          retval = get_file_format (file, orig_fname);
+          file.close ();
+        }
+      else if (! quiet)
+        gripe_file_open ("load", orig_fname);
     }
-  else if (! quiet)
-    gripe_file_open ("load", orig_fname);
+#ifdef HAVE_ZLIB
+  else
+    {
+      gzifstream gzfile (fname.c_str ());
+      if (gzfile)
+        {
+          retval = get_file_format (gzfile, orig_fname);
+          gzfile.close ();
+        }
+      else if (! quiet)
+        gripe_file_open ("load", orig_fname);
+    }
+#endif
 
   return retval;
 }
@@ -617,7 +628,7 @@
 Octave can now support multi-dimensional HDF data and automatically\n\
 modifies variable names if they are invalid Octave identifiers.\n\
 \n\
-@item -mat\n\
+@item  -mat\n\
 @itemx -mat-binary\n\
 @itemx -6\n\
 @itemx -v6\n\
@@ -1315,6 +1326,8 @@
     {
       for (int i = argv_idx; i < argc; i++)
         {
+          if (argv[i] == "")
+            continue;  // Skip empty vars for Matlab compatibility
           if (! save_vars (os, argv[i], fmt, save_as_floats))
             warning ("save: no such variable '%s'", argv[i].c_str ());
         }
@@ -1509,20 +1522,20 @@
 Only use this format if you know that all the\n\
 values to be saved can be represented in single precision.\n\
 \n\
-@item -V7\n\
+@item  -V7\n\
 @itemx -v7\n\
 @itemx -7\n\
 @itemx -mat7-binary\n\
 Save the data in @sc{matlab}'s v7 binary data format.\n\
 \n\
-@item -V6\n\
+@item  -V6\n\
 @itemx -v6\n\
 @itemx -6\n\
 @itemx -mat\n\
 @itemx -mat-binary\n\
 Save the data in @sc{matlab}'s v6 binary data format.\n\
 \n\
-@item -V4\n\
+@item  -V4\n\
 @itemx -v4\n\
 @itemx -4\n\
 @itemx -mat4-binary\n\
@@ -1531,7 +1544,7 @@
 @item -text\n\
 Save the data in Octave's text data format.  (default).\n\
 \n\
-@item -zip\n\
+@item  -zip\n\
 @itemx -z\n\
 Use the gzip algorithm to compress the file.  This works equally on files\n\
 that are compressed with gzip outside of octave, and gzip can equally be\n\
@@ -1761,12 +1774,12 @@
 @deftypefnx {Built-in Function} {@var{old_val} =} crash_dumps_octave_core (@var{new_val})\n\
 @deftypefnx {Built-in Function} {} crash_dumps_octave_core (@var{new_val}, \"local\")\n\
 Query or set the internal variable that controls whether Octave tries\n\
-to save all current variables to the file \"octave-workspace\" if it\n\
+to save all current variables to the file @file{octave-workspace} if it\n\
 crashes or receives a hangup, terminate or similar signal.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{octave_core_file_limit, octave_core_file_name, octave_core_file_options}\n\
 @end deftypefn")
 {
@@ -1780,12 +1793,12 @@
 @deftypefnx {Built-in Function} {} save_default_options (@var{new_val}, \"local\")\n\
 Query or set the internal variable that specifies the default options\n\
 for the @code{save} command, and defines the default format.\n\
-Typical values include @code{\"-ascii\"}, @code{\"-text -zip\"}.\n\
+Typical values include @qcode{\"-ascii\"}, @qcode{\"-text -zip\"}.\n\
 The default value is @option{-text}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{save}\n\
 @end deftypefn")
 {
@@ -1806,9 +1819,9 @@
 size of the file.  If a text file format is used, then the file could\n\
 be much larger than the limit.  The default value is -1 (unlimited)\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
 @end deftypefn")
 {
@@ -1822,11 +1835,11 @@
 @deftypefnx {Built-in Function} {} octave_core_file_name (@var{new_val}, \"local\")\n\
 Query or set the internal variable that specifies the name of the file\n\
 used for saving data from the top-level workspace if Octave aborts.\n\
-The default value is @code{\"octave-workspace\"}\n\
+The default value is @qcode{\"octave-workspace\"}\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_options}\n\
 @end deftypefn")
 {
@@ -1844,9 +1857,9 @@
 options for the @code{save} function.  The default value is Octave's binary\n\
 format.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{crash_dumps_octave_core, octave_core_file_name, octave_core_file_limit}\n\
 @end deftypefn")
 {
@@ -1872,9 +1885,9 @@
 \"# Created by Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>\"\n\
 @end smallexample\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{strftime, save}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/ls-mat-ascii.cc
+++ b/libinterp/corefcn/ls-mat-ascii.cc
@@ -107,7 +107,7 @@
 }
 
 static void
-get_lines_and_columns (std::istream& is, 
+get_lines_and_columns (std::istream& is,
                        octave_idx_type& nr, octave_idx_type& nc,
                        const std::string& filename = std::string (),
                        bool quiet = false, bool check_numeric = false)
@@ -410,21 +410,14 @@
 }
 
 bool
-looks_like_mat_ascii_file (const std::string& filename)
+looks_like_mat_ascii_file (std::istream& is, const std::string& filename)
 {
   bool retval = false;
-
-  std::ifstream is (filename.c_str ());
+  octave_idx_type nr = 0;
+  octave_idx_type nc = 0;
 
-  if (is)
-    {
-      octave_idx_type nr = 0;
-      octave_idx_type nc = 0;
-
-      get_lines_and_columns (is, nr, nc, filename, true, true);
-
-      retval = (nr != 0 && nc != 0);
-    }
+  get_lines_and_columns (is, nr, nc, filename, true, true);
+  retval = (nr != 0 && nc != 0);
 
   return retval;
 }
--- a/libinterp/corefcn/ls-mat-ascii.h
+++ b/libinterp/corefcn/ls-mat-ascii.h
@@ -31,6 +31,6 @@
 save_mat_ascii_data (std::ostream& os, const octave_value& val_arg,
                      int precision, bool tabs = false);
 
-extern bool looks_like_mat_ascii_file (const std::string& filename);
+extern bool looks_like_mat_ascii_file (std::istream& is, const std::string& filename);
 
 #endif
--- a/libinterp/corefcn/ls-mat4.cc
+++ b/libinterp/corefcn/ls-mat4.cc
@@ -194,17 +194,8 @@
       break;
 
     case 2:
-      flt_fmt = oct_mach_info::flt_fmt_vax_d;
-      break;
-
     case 3:
-      flt_fmt = oct_mach_info::flt_fmt_vax_g;
-      break;
-
     case 4:
-      flt_fmt = oct_mach_info::flt_fmt_cray;
-      break;
-
     default:
       flt_fmt = oct_mach_info::flt_fmt_unknown;
       break;
@@ -228,18 +219,6 @@
       retval = 1;
       break;
 
-    case oct_mach_info::flt_fmt_vax_d:
-      retval = 2;
-      break;
-
-    case oct_mach_info::flt_fmt_vax_g:
-      retval = 3;
-      break;
-
-    case oct_mach_info::flt_fmt_cray:
-      retval = 4;
-      break;
-
     default:
       break;
     }
--- a/libinterp/corefcn/ls-oct-ascii.cc
+++ b/libinterp/corefcn/ls-oct-ascii.cc
@@ -367,7 +367,7 @@
 
   if (tc.is_real_matrix ())
     {
-      os << "# 3D data...\n"
+      os << "# 3-D data...\n"
          << "# type: matrix\n"
          << "# total rows: " << nr << "\n"
          << "# total columns: " << nc << "\n";
@@ -408,7 +408,7 @@
     }
   else
     {
-      ::error ("for now, I can only save real matrices in 3D format");
+      ::error ("for now, I can only save real matrices in 3-D format");
       fail = true;
     }
 
@@ -423,9 +423,9 @@
 Query or set the internal variable that specifies the number of\n\
 digits to keep when saving data in text format.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.\n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1,
--- a/libinterp/corefcn/lu.cc
+++ b/libinterp/corefcn/lu.cc
@@ -125,10 +125,10 @@
 pivoting strategy and the second for the symmetric strategy.  By default,\n\
 the values defined by @code{spparms} are used ([0.1, 0.001]).\n\
 \n\
-Given the string argument \"vector\", @code{lu} returns the values of @var{P}\n\
-and @var{Q} as vector values, such that for full matrix, @code{@var{A}\n\
-(@var{P},:) = @var{L} * @var{U}}, and @code{@var{R}(@var{P},:) * @var{A}\n\
-(:, @var{Q}) = @var{L} * @var{U}}.\n\
+Given the string argument @qcode{\"vector\"}, @code{lu} returns the values\n\
+of @var{P} and @var{Q} as vector values, such that for full matrix,\n\
+@code{@var{A} (@var{P},:) = @var{L} * @var{U}}, and @code{@var{R}(@var{P},:)\n\
+* @var{A} (:, @var{Q}) = @var{L} * @var{U}}.\n\
 \n\
 With two output arguments, returns the permuted forms of the upper and\n\
 lower triangular matrices, such that @code{@var{A} = @var{L} * @var{U}}.\n\
@@ -615,7 +615,7 @@
 @end example\n\
 \n\
 @noindent\n\
-then a factorization of @xcode{@var{A}+@var{x}*@var{y}.'} can be obtained\n\
+then a factorization of @tcode{@var{A}+@var{x}*@var{y}.'} can be obtained\n\
 either as\n\
 \n\
 @example\n\
--- a/libinterp/corefcn/luinc.cc
+++ b/libinterp/corefcn/luinc.cc
@@ -47,7 +47,7 @@
 Two types of incomplete factorization are possible, and the type\n\
 is determined by the second argument to @code{luinc}.\n\
 \n\
-Called with a second argument of '0', the zero-level incomplete\n\
+Called with a second argument of @qcode{'0'}, the zero-level incomplete\n\
 LU@tie{}factorization is produced.  This creates a factorization of @var{A}\n\
 where the position of the non-zero arguments correspond to the same\n\
 positions as in the matrix @var{A}.\n\
@@ -91,8 +91,8 @@
 All other fields in @var{opts} are ignored.  The outputs from @code{luinc}\n\
 are the same as for @code{lu}.\n\
 \n\
-Given the string argument \"vector\", @code{luinc} returns the values of\n\
-@var{p} @var{q} as vector values.\n\
+Given the string argument @qcode{\"vector\"}, @code{luinc} returns the\n\
+values of @var{p} @var{q} as vector values.\n\
 @seealso{sparse, lu}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/matrix_type.cc
+++ b/libinterp/corefcn/matrix_type.cc
@@ -50,48 +50,49 @@
 matrix and caches it for future use.  Called with more than one argument,\n\
 @code{matrix_type} allows the type of the matrix to be defined.\n\
 \n\
-If the option \"nocompute\" is given, the function will not attempt to guess\n\
-the type if it is still unknown.  This is useful for debugging purposes.\n\
+If the option @qcode{\"nocompute\"} is given, the function will not attempt\n\
+to guess the type if it is still unknown.  This is useful for debugging\n\
+purposes.\n\
 \n\
 The possible matrix types depend on whether the matrix is full or sparse, and\n\
 can be one of the following\n\
 \n\
 @table @asis\n\
-@item \"unknown\"\n\
+@item @qcode{\"unknown\"}\n\
 Remove any previously cached matrix type, and mark type as unknown.\n\
 \n\
-@item \"full\"\n\
+@item @qcode{\"full\"}\n\
 Mark the matrix as full.\n\
 \n\
-@item \"positive definite\"\n\
+@item @qcode{\"positive definite\"}\n\
 Probable full positive definite matrix.\n\
 \n\
-@item \"diagonal\"\n\
+@item @qcode{\"diagonal\"}\n\
 Diagonal matrix.  (Sparse matrices only)\n\
 \n\
-@item \"permuted diagonal\"\n\
+@item @qcode{\"permuted diagonal\"}\n\
 Permuted Diagonal matrix.  The permutation does not need to be specifically\n\
 indicated, as the structure of the matrix explicitly gives this.  (Sparse\n\
 matrices only)\n\
 \n\
-@item \"upper\"\n\
+@item @qcode{\"upper\"}\n\
 Upper triangular.  If the optional third argument @var{perm} is given, the\n\
 matrix is assumed to be a permuted upper triangular with the permutations\n\
 defined by the vector @var{perm}.\n\
 \n\
-@item \"lower\"\n\
+@item @qcode{\"lower\"}\n\
 Lower triangular.  If the optional third argument @var{perm} is given, the\n\
 matrix is assumed to be a permuted lower triangular with the permutations\n\
 defined by the vector @var{perm}.\n\
 \n\
-@item \"banded\"\n\
-@itemx \"banded positive definite\"\n\
+@item  @qcode{\"banded\"}\n\
+@itemx @qcode{\"banded positive definite\"}\n\
 Banded matrix with the band size of @var{nl} below the diagonal and @var{nu}\n\
 above it.  If @var{nl} and @var{nu} are 1, then the matrix is tridiagonal and\n\
 treated with specialized code.  In addition the matrix can be marked as\n\
 probably a positive definite.  (Sparse matrices only)\n\
 \n\
-@item \"singular\"\n\
+@item @qcode{\"singular\"}\n\
 The matrix is assumed to be singular and will be treated with a minimum norm\n\
 solution.\n\
 \n\
--- a/libinterp/corefcn/max.cc
+++ b/libinterp/corefcn/max.cc
@@ -663,8 +663,10 @@
 @deftypefn  {Built-in Function} {} cummin (@var{x})\n\
 @deftypefnx {Built-in Function} {} cummin (@var{x}, @var{dim})\n\
 @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummin (@var{x})\n\
-Return the cumulative minimum values along dimension @var{dim}.  If @var{dim}\n\
-is unspecified it defaults to column-wise operation.  For example:\n\
+Return the cumulative minimum values along dimension @var{dim}.\n\
+\n\
+If @var{dim} is unspecified it defaults to column-wise operation.  For\n\
+example:\n\
 \n\
 @example\n\
 @group\n\
@@ -673,40 +675,52 @@
 @end group\n\
 @end example\n\
 \n\
-\n\
-The call\n\
-\n\
-@example\n\
-  [w, iw] = cummin (x)\n\
-@end example\n\
-\n\
-@noindent\n\
-with @code{x} a vector, is equivalent to the following code:\n\
+If called with two output arguments the index of the minimum value is also\n\
+returned.\n\
 \n\
 @example\n\
 @group\n\
-w = iw = zeros (size (x));\n\
-for i = 1:length (x)\n\
-  [w(i), iw(i)] = max (x(1:i));\n\
-endfor\n\
+[w, iw] = cummin ([5 4 6 2 3 1])\n\
+@result{}\n\
+w =  5  4  4  2  2  1\n\
+iw = 1  2  2  4  4  6\n\
 @end group\n\
 @end example\n\
 \n\
-@noindent\n\
-but computed in a much faster manner.\n\
 @seealso{cummax, min, max}\n\
 @end deftypefn")
 {
   return do_cumminmax_body (args, nargout, true);
 }
 
+/*
+%!assert (cummin ([1, 4, 2, 3]), [1 1 1 1])
+%!assert (cummin ([1; -10; 5; -2]), [1; -10; -10; -10])
+%!assert (cummin ([4, i; -2, 2]), [4, i; -2, i])
+
+%!test
+%! x = reshape (1:8, [2,2,2]);
+%! assert (cummin (x, 1), reshape ([1 1 3 3 5 5 7 7], [2,2,2]));
+%! assert (cummin (x, 2), reshape ([1 2 1 2 5 6 5 6], [2,2,2]));
+%! [w, iw] = cummin (x, 3);
+%! assert (ndims (w), 3);
+%! assert (w, repmat ([1 3; 2 4], [1 1 2]));
+%! assert (ndims (iw), 3);
+%! assert (iw, ones (2,2,2));
+
+%!error cummin ()
+%!error cummin (1, 2, 3)
+*/
+
 DEFUN (cummax, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} cummax (@var{x})\n\
 @deftypefnx {Built-in Function} {} cummax (@var{x}, @var{dim})\n\
-@deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummax (@var{x})\n\
-Return the cumulative maximum values along dimension @var{dim}.  If @var{dim}\n\
-is unspecified it defaults to column-wise operation.  For example:\n\
+@deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} cummax (@dots{})\n\
+Return the cumulative maximum values along dimension @var{dim}.\n\
+\n\
+If @var{dim} is unspecified it defaults to column-wise operation.  For\n\
+example:\n\
 \n\
 @example\n\
 @group\n\
@@ -715,28 +729,40 @@
 @end group\n\
 @end example\n\
 \n\
-The call\n\
-\n\
-@example\n\
-[w, iw] = cummax (x, dim)\n\
-@end example\n\
-\n\
-@noindent\n\
-with @code{x} a vector, is equivalent to the following code:\n\
+If called with two output arguments the index of the maximum value is also\n\
+returned.\n\
 \n\
 @example\n\
 @group\n\
-w = iw = zeros (size (x));\n\
-for i = 1:length (x)\n\
-  [w(i), iw(i)] = max (x(1:i));\n\
-endfor\n\
+[w, iw] = cummax ([1 3 2 6 4 5])\n\
+@result{}\n\
+w =  1  3  3  6  6  6\n\
+iw = 1  2  2  4  4  4\n\
 @end group\n\
 @end example\n\
 \n\
-@noindent\n\
-but computed in a much faster manner.\n\
 @seealso{cummin, max, min}\n\
 @end deftypefn")
 {
   return do_cumminmax_body (args, nargout, false);
 }
+
+/*
+%!assert (cummax ([1, 4, 2, 3]), [1 4 4 4])
+%!assert (cummax ([1; -10; 5; -2]), [1; 1; 5; 5])
+%!assert (cummax ([4, i 4.9, -2, 2, 3+4i]), [4, 4, 4.9, 4.9, 4.9, 3+4i])
+
+%!test
+%! x = reshape (8:-1:1, [2,2,2]);
+%! assert (cummax (x, 1), reshape ([8 8 6 6 4 4 2 2], [2,2,2]));
+%! assert (cummax (x, 2), reshape ([8 7 8 7 4 3 4 3], [2,2,2]));
+%! [w, iw] = cummax (x, 3);
+%! assert (ndims (w), 3);
+%! assert (w, repmat ([8 6; 7 5], [1 1 2]));
+%! assert (ndims (iw), 3);
+%! assert (iw, ones (2,2,2));
+
+%!error cummax ()
+%!error cummax (1, 2, 3)
+*/
+
--- a/libinterp/corefcn/mex.cc
+++ b/libinterp/corefcn/mex.cc
@@ -1164,7 +1164,7 @@
     switch (get_class_id ())
       {
       case mxLOGICAL_CLASS:
-        retval = int_to_ov<bool, boolNDArray, bool> (dv);
+        retval = int_to_ov<mxLogical, boolNDArray, bool> (dv);
         break;
 
       case mxCHAR_CLASS:
--- a/libinterp/corefcn/module.mk
+++ b/libinterp/corefcn/module.mk
@@ -4,7 +4,9 @@
   corefcn/gl2ps.c \
   corefcn/graphics.in.h \
   corefcn/mxarray.in.h \
-  corefcn/oct-errno.in.cc
+  corefcn/oct-errno.in.cc \
+  corefcn/oct-tex-lexer.in.ll \
+  corefcn/oct-tex-symbols.in
 
 ## Options functions for Fortran packages like LSODE, DASPK.
 ## These are generated automagically by configure and Perl.
@@ -35,6 +37,9 @@
   corefcn/jit-ir.h \
   corefcn/pt-jit.h
 
+TEX_PARSER_INC = \
+  corefcn/oct-tex-parser.h
+
 COREFCN_INC = \
   corefcn/Cell.h \
   corefcn/action-container.h \
@@ -108,7 +113,8 @@
   corefcn/xnorm.h \
   corefcn/xpow.h \
   corefcn/zfstream.h \
-  $(JIT_INC)
+  $(JIT_INC) \
+  $(TEX_PARSER_INC)
 
 JIT_SRC = \
   corefcn/jit-util.cc \
@@ -116,6 +122,10 @@
   corefcn/jit-ir.cc \
   corefcn/pt-jit.cc
 
+TEX_PARSER_SRC = \
+  corefcn/oct-tex-lexer.ll \
+  corefcn/oct-tex-parser.yy
+
 C_COREFCN_SRC = \
   corefcn/cutils.c \
   corefcn/matherr.c \
@@ -240,6 +250,7 @@
   corefcn/time.cc \
   corefcn/toplev.cc \
   corefcn/tril.cc \
+  corefcn/txt-eng.cc \
   corefcn/txt-eng-ft.cc \
   corefcn/typecast.cc \
   corefcn/unwind-prot.cc \
@@ -290,8 +301,28 @@
 	  -e "s|%OCTAVE_IDX_TYPE%|${OCTAVE_IDX_TYPE}|" > $@-t
 	mv $@-t $@
 
-noinst_LTLIBRARIES += corefcn/libcorefcn.la
+corefcn/oct-tex-lexer.ll: corefcn/oct-tex-lexer.in.ll corefcn/oct-tex-symbols.in Makefile.am
+	$(AWK) 'BEGIN { print "/* DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-lexer.in.ll and oct-tex-symbols.in. */"; } /^@SYMBOL_RULES@$$/ { count = 0; while (getline < "$(srcdir)/corefcn/oct-tex-symbols.in") { if ($$0 !~ /^#.*/ && NF == 3) { printf("\"\\\\%s\" { yylval->sym = %d; return SYM; }\n", $$1, count); count++; } } getline } ! /^@SYMBOL_RULES@$$/ { print }' $< > $@-t
+	mv $@-t $@
+
+corefcn/oct-tex-symbols.cc: corefcn/oct-tex-symbols.in Makefile.am
+	$(AWK) 'BEGIN { print "// DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-symbols.in."; print "static uint32_t symbol_codes[][2] = {"; count = 0; } END { print "};"; printf("static int num_symbol_codes = %d;\n", count); } /^#/ { } { if (NF == 3) { printf("  { %s, %s },\n", $$2, $$3); count++; } }' $< > $@-t
+	mv $@-t $@
+
+corefcn/txt-eng.cc: corefcn/oct-tex-symbols.cc
+corefcn/oct-tex-lexer.cc: LEX_OUTPUT_ROOT := lex.octave_tex_
+corefcn/oct-tex-parser.h: corefcn/oct-tex-parser.yy
+
+
+noinst_LTLIBRARIES += \
+  corefcn/libcorefcn.la \
+  corefcn/libtex_parser.la
 
 corefcn_libcorefcn_la_SOURCES = $(COREFCN_SRC)
 corefcn_libcorefcn_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS) $(FFTW_XCPPFLAGS)
 
+corefcn_libtex_parser_la_SOURCES = $(TEX_PARSER_SRC)
+corefcn_libtex_parser_la_CPPFLAGS = $(liboctinterp_la_CPPFLAGS)
+corefcn_libtex_parser_la_CXXFLAGS = \
+  $(filter-out -Wold-style-cast, $(AM_CXXFLAGS))
+
--- a/libinterp/corefcn/oct-hist.cc
+++ b/libinterp/corefcn/oct-hist.cc
@@ -328,10 +328,8 @@
         tmp.resize (len - 1);
 
       if (! tmp.empty ())
-        {
-          command_history::add (tmp);
+        if (command_history::add (tmp))
           octave_link::append_history (tmp);
-        }
     }
 }
 
@@ -580,10 +578,8 @@
   std::string timestamp = now.strftime (Vhistory_timestamp_format_string);
 
   if (! timestamp.empty ())
-    {
-      command_history::add (timestamp); 
+    if (command_history::add (timestamp))
       octave_link::append_history (timestamp);
-   }
 }
 
 DEFUN (edit_history, args, ,
@@ -759,12 +755,13 @@
 @seealso{history_file, history_size, history_timestamp_format_string, history_save}\n\
 @end deftypefn")
 {
+  octave_value retval;
+
   std::string old_history_control = command_history::histcontrol ();
 
   std::string tmp = old_history_control;
 
-  octave_value retval = set_internal_variable (tmp, args, nargout,
-                                               "history_control");
+  retval = set_internal_variable (tmp, args, nargout, "history_control");
 
   if (tmp != old_history_control)
     command_history::process_histcontrol (tmp);
@@ -782,13 +779,15 @@
 @seealso{history_file, history_timestamp_format_string, history_save}\n\
 @end deftypefn")
 {
+  octave_value retval;
+
   int old_history_size = command_history::size ();
 
   int tmp = old_history_size;
 
-  octave_value retval = set_internal_variable (tmp, args, nargout,
-                                               "history_size", -1,
-                                               std::numeric_limits<int>::max ());
+  retval = set_internal_variable (tmp, args, nargout,
+                                  "history_size", -1,
+                                  std::numeric_limits<int>::max ());
 
   if (tmp != old_history_size)
     command_history::set_size (tmp);
@@ -807,12 +806,13 @@
 @seealso{history_size, history_save, history_timestamp_format_string}\n\
 @end deftypefn")
 {
+  octave_value retval;
+
   std::string old_history_file = command_history::file ();
 
   std::string tmp = old_history_file;
 
-  octave_value retval = set_internal_variable (tmp, args, nargout,
-                                               "history_file");
+  retval = set_internal_variable (tmp, args, nargout, "history_file");
 
   if (tmp != old_history_file)
     command_history::set_file (tmp);
@@ -834,9 +834,9 @@
 \"# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>\"\n\
 @end example\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{strftime, history_file, history_size, history_save}\n\
 @end deftypefn")
 {
@@ -851,18 +851,19 @@
 Query or set the internal variable that controls whether commands entered\n\
 on the command line are saved in the history file.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{history_control, history_file, history_size, history_timestamp_format_string}\n\
 @end deftypefn")
 {
+  octave_value retval;
+
   bool old_history_save = ! command_history::ignoring_entries ();
 
   bool tmp = old_history_save;
 
-  octave_value retval = set_internal_variable (tmp, args, nargout,
-                                               "history_save");
+  retval = set_internal_variable (tmp, args, nargout, "history_save");
 
   if (tmp != old_history_save)
     command_history::ignore_entries (! tmp);
--- a/libinterp/corefcn/oct-stream.cc
+++ b/libinterp/corefcn/oct-stream.cc
@@ -1189,29 +1189,6 @@
   return is >> valptr;
 }
 
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, long int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, short int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, unsigned int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, unsigned long int*);
-
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, unsigned short int*);
-
-#if 0
-template std::istream&
-octave_scan (std::istream&, const scanf_format_elt&, float*);
-#endif
-
 template<>
 std::istream&
 octave_scan<> (std::istream& is, const scanf_format_elt& fmt, double* valptr)
@@ -1278,36 +1255,6 @@
 }
 
 template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, long int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, short int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned long int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, unsigned short int*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-
-#if 0
-template void
-do_scanf_conv (std::istream&, const scanf_format_elt&, float*,
-               Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
-#endif
-
-template void
 do_scanf_conv (std::istream&, const scanf_format_elt&, double*,
                Matrix&, double*, octave_idx_type&, octave_idx_type&, octave_idx_type, octave_idx_type, bool);
 
@@ -2402,30 +2349,6 @@
   return retval;
 }
 
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, int,
-                const std::string&);
-
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, long,
-                const std::string&);
-
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, unsigned int,
-                const std::string&);
-
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, unsigned long,
-                const std::string&);
-
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, double,
-                const std::string&);
-
-template int
-do_printf_conv (std::ostream&, const char*, int, int, int, const char*,
-                const std::string&);
-
 #define DO_DOUBLE_CONV(TQUAL) \
   do \
     { \
@@ -2544,9 +2467,17 @@
                                 nsa--;
                             }
 
-                          const char *tval = xisinf (val)
-                            ? (val < 0 ? "-Inf" : "Inf")
-                            : (lo_ieee_is_NA (val) ? "NA" : "NaN");
+                          const char *tval;
+                          if (xisinf (val))
+                            if (elt->flags.find ('+') != std::string::npos)
+                              tval = (val < 0 ? "-Inf" : "+Inf");
+                            else
+                              tval = (val < 0 ? "-Inf" : "Inf");
+                          else
+                            if (elt->flags.find ('+') != std::string::npos)
+                              tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN");
+                            else
+                              tval = (lo_ieee_is_NA (val) ? "NA" : "NaN");
 
                           retval += do_printf_conv (os, tfmt.c_str (),
                                                     nsa, sa_1, sa_2,
@@ -3027,229 +2958,174 @@
     rep->close ();
 }
 
-template <class RET_T, class READ_T>
+template <class SRC_T, class DST_T>
+static octave_value
+convert_and_copy (std::list<void *>& input_buf_list,
+                  octave_idx_type input_buf_elts,
+                  octave_idx_type elts_read,
+                  octave_idx_type nr, octave_idx_type nc, bool swap,
+                  bool do_float_fmt_conv, bool do_NA_conv,
+                  oct_mach_info::float_format from_flt_fmt)
+{
+  typedef typename DST_T::element_type dst_elt_type;
+
+  DST_T conv (dim_vector (nr, nc));
+
+  dst_elt_type *conv_data = conv.fortran_vec ();
+
+  octave_idx_type j = 0;
+
+  for (std::list<void *>::const_iterator it = input_buf_list.begin ();
+       it != input_buf_list.end (); it++)
+    {
+      SRC_T *data = static_cast<SRC_T *> (*it);
+
+      for (octave_idx_type i = 0; i < input_buf_elts && j < elts_read; i++, j++)
+        {
+          if (swap)
+            swap_bytes<sizeof (SRC_T)> (&data[i]);
+          else if (do_float_fmt_conv)
+            do_float_format_conversion (&data[i], sizeof (SRC_T),
+                                        1, from_flt_fmt,
+                                        oct_mach_info::float_format ());
+
+          dst_elt_type tmp (data[i]);
+
+          if (do_NA_conv && __lo_ieee_is_old_NA (tmp))
+            tmp = __lo_ieee_replace_old_NA (tmp);
+
+          conv_data[j] = tmp;
+        }
+
+      delete [] data;
+    }
+
+  input_buf_list.clear ();
+
+  for (octave_idx_type i = elts_read; i < nr * nc; i++)
+    conv_data[i] = dst_elt_type (0);
+
+  return conv;
+}
+
+typedef octave_value (*conv_fptr)
+  (std::list<void *>& input_buf_list, octave_idx_type input_buf_elts,
+   octave_idx_type elts_read, octave_idx_type nr, octave_idx_type nc,
+   bool swap, bool do_float_fmt_conv, bool do_NA_conv,
+   oct_mach_info::float_format from_flt_fmt);
+
+#define TABLE_ELT(T, U, V, W) \
+  conv_fptr_table[oct_data_conv::T][oct_data_conv::U] = convert_and_copy<V, W>
+
+#undef FILL_TABLE_ROW
+#define FILL_TABLE_ROW(T, V) \
+  TABLE_ELT (T, dt_int8, V, int8NDArray); \
+  TABLE_ELT (T, dt_uint8, V, uint8NDArray); \
+  TABLE_ELT (T, dt_int16, V, int16NDArray); \
+  TABLE_ELT (T, dt_uint16, V, uint16NDArray); \
+  TABLE_ELT (T, dt_int32, V, int32NDArray); \
+  TABLE_ELT (T, dt_uint32, V, uint32NDArray); \
+  TABLE_ELT (T, dt_int64, V, int64NDArray); \
+  TABLE_ELT (T, dt_uint64, V, uint64NDArray); \
+  TABLE_ELT (T, dt_single, V, FloatNDArray); \
+  TABLE_ELT (T, dt_double, V, NDArray); \
+  TABLE_ELT (T, dt_char, V, charNDArray); \
+  TABLE_ELT (T, dt_schar, V, charNDArray); \
+  TABLE_ELT (T, dt_uchar, V, charNDArray); \
+  TABLE_ELT (T, dt_logical, V, boolNDArray);
+
 octave_value
-do_read (octave_stream& strm, octave_idx_type nr, octave_idx_type nc, octave_idx_type block_size,
-         octave_idx_type skip, bool do_float_fmt_conv, bool do_NA_conv,
-         oct_mach_info::float_format from_flt_fmt, octave_idx_type& count)
+octave_stream::finalize_read (std::list<void *>& input_buf_list,
+                              octave_idx_type input_buf_elts,
+                              octave_idx_type elts_read,
+                              octave_idx_type nr, octave_idx_type nc,
+                              oct_data_conv::data_type input_type,
+                              oct_data_conv::data_type output_type,
+                              oct_mach_info::float_format ffmt)
 {
   octave_value retval;
 
-  RET_T nda;
-
-  count = 0;
-
-  typedef typename RET_T::element_type ELMT;
-  ELMT elt_zero = ELMT ();
-
-  ELMT *dat = 0;
-
-  octave_idx_type max_size = 0;
-
-  octave_idx_type final_nr = 0;
-  octave_idx_type final_nc = 1;
-
-  if (nr > 0)
+  static bool initialized = false;
+
+  // Table function pointers for return types x read types.
+
+  static conv_fptr conv_fptr_table[oct_data_conv::dt_unknown][14];
+
+  if (! initialized)
     {
-      if (nc > 0)
-        {
-          nda.resize (dim_vector (nr, nc), elt_zero);
-          dat = nda.fortran_vec ();
-          max_size = nr * nc;
-        }
-      else
-        {
-          nda.resize (dim_vector (nr, 32), elt_zero);
-          dat = nda.fortran_vec ();
-          max_size = nr * 32;
-        }
+      for (int i = 0; i < oct_data_conv::dt_unknown; i++)
+        for (int j = 0; j < 14; j++)
+          conv_fptr_table[i][j] = 0;
+
+      FILL_TABLE_ROW (dt_int8, int8_t);
+      FILL_TABLE_ROW (dt_uint8, uint8_t);
+      FILL_TABLE_ROW (dt_int16, int16_t);
+      FILL_TABLE_ROW (dt_uint16, uint16_t);
+      FILL_TABLE_ROW (dt_int32, int32_t);
+      FILL_TABLE_ROW (dt_uint32, uint32_t);
+      FILL_TABLE_ROW (dt_int64, int64_t);
+      FILL_TABLE_ROW (dt_uint64, uint64_t);
+      FILL_TABLE_ROW (dt_single, float);
+      FILL_TABLE_ROW (dt_double, double);
+      FILL_TABLE_ROW (dt_char, char);
+      FILL_TABLE_ROW (dt_schar, signed char);
+      FILL_TABLE_ROW (dt_uchar, unsigned char);
+      FILL_TABLE_ROW (dt_logical, bool);
+
+      initialized = true;
     }
-  else
-    {
-      nda.resize (dim_vector (32, 1), elt_zero);
-      dat = nda.fortran_vec ();
-      max_size = 32;
-    }
-
-  // FIXME -- byte order for Cray?
 
   bool swap = false;
 
+  if (ffmt == oct_mach_info::flt_fmt_unknown)
+    ffmt = float_format ();
+
   if (oct_mach_info::words_big_endian ())
-    swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
-            || from_flt_fmt == oct_mach_info::flt_fmt_vax_g
-            || from_flt_fmt == oct_mach_info::flt_fmt_vax_g);
+    swap = (ffmt == oct_mach_info::flt_fmt_ieee_little_endian);
   else
-    swap = (from_flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
-
-  union
-  {
-    char buf[sizeof (typename strip_template_param<octave_int, READ_T>::type)];
-    typename strip_template_param<octave_int, READ_T>::type val;
-  } u;
-
-  std::istream *isp = strm.input_stream ();
-
-  if (isp)
+    swap = (ffmt == oct_mach_info::flt_fmt_ieee_big_endian);
+
+  bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double
+                             || input_type == oct_data_conv::dt_single)
+                            && ffmt != float_format ());
+
+  bool do_NA_conv = (output_type == oct_data_conv::dt_double);
+
+  switch (output_type)
     {
-      std::istream& is = *isp;
-
-      octave_idx_type elts_read = 0;
-
-      for (;;)
-        {
-          // FIXME -- maybe there should be a special case for
-          // skip == 0.
-
-          if (is)
-            {
-              if (nr > 0 && nc > 0 && count == max_size)
-                {
-                  final_nr = nr;
-                  final_nc = nc;
-
-                  break;
-                }
-
-              is.read (u.buf, sizeof (typename strip_template_param<octave_int, READ_T>::type));
-
-              // We only swap bytes for integer types.  For float
-              // types, the format conversion will also handle byte
-              // swapping.
-
-              if (swap)
-                swap_bytes<sizeof (typename strip_template_param<octave_int, READ_T>::type)> (u.buf);
-              else if (do_float_fmt_conv)
-                do_float_format_conversion
-                  (u.buf,
-                   sizeof (typename strip_template_param<octave_int, READ_T>::type),
-                   1, from_flt_fmt, oct_mach_info::float_format ());
-
-              typename RET_T::element_type tmp
-                = static_cast <typename RET_T::element_type> (u.val);
-
-              if (is)
-                {
-                  if (count == max_size)
-                    {
-                      max_size *= 2;
-
-                      if (nr > 0)
-                        nda.resize (dim_vector (nr, max_size / nr),
-                                    elt_zero);
-                      else
-                        nda.resize (dim_vector (max_size, 1), elt_zero);
-
-                      dat = nda.fortran_vec ();
-                    }
-
-                  if (do_NA_conv && __lo_ieee_is_old_NA (tmp))
-                    tmp = __lo_ieee_replace_old_NA (tmp);
-
-                  dat[count++] = tmp;
-
-                  elts_read++;
-                }
-
-              int seek_status = 0;
-
-              if (skip != 0 && elts_read == block_size)
-                {
-                  seek_status = strm.seek (skip, SEEK_CUR);
-                  elts_read = 0;
-                }
-
-              if (is.eof () || seek_status < 0)
-                {
-                  if (nr > 0)
-                    {
-                      if (count > nr)
-                        {
-                          final_nr = nr;
-                          final_nc = (count - 1) / nr + 1;
-                        }
-                      else
-                        {
-                          final_nr = count;
-                          final_nc = 1;
-                        }
-                    }
-                  else
-                    {
-                      final_nr = count;
-                      final_nc = 1;
-                    }
-
-                  break;
-                }
-            }
-          else if (is.eof ())
-            break;
-        }
+    case oct_data_conv::dt_int8:
+    case oct_data_conv::dt_uint8:
+    case oct_data_conv::dt_int16:
+    case oct_data_conv::dt_uint16:
+    case oct_data_conv::dt_int32:
+    case oct_data_conv::dt_uint32:
+    case oct_data_conv::dt_int64:
+    case oct_data_conv::dt_uint64:
+    case oct_data_conv::dt_single:
+    case oct_data_conv::dt_double:
+    case oct_data_conv::dt_char:
+    case oct_data_conv::dt_schar:
+    case oct_data_conv::dt_uchar:
+    case oct_data_conv::dt_logical:
+      {
+        conv_fptr fptr = conv_fptr_table[input_type][output_type];
+
+        retval = fptr (input_buf_list, input_buf_elts, elts_read,
+                       nr, nc, swap, do_float_fmt_conv, do_NA_conv, ffmt);
+      }
+      break;
+
+    default:
+      retval = false;
+      (*current_liboctave_error_handler)
+        ("read: invalid type specification");
+      break;
     }
-
-  nda.resize (dim_vector (final_nr, final_nc), elt_zero);
-
-  retval = nda;
+  
 
   return retval;
 }
 
-#define DO_READ_VAL_TEMPLATE(RET_T, READ_T) \
-  template octave_value \
-  do_read<RET_T, READ_T> (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool, \
-                          oct_mach_info::float_format, octave_idx_type&)
-
-// FIXME -- should we only have float if it is a different
-// size from double?
-
-#define INSTANTIATE_DO_READ(VAL_T) \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_int8); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint8); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_int16); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint16); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_int32); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint32); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_int64); \
-  DO_READ_VAL_TEMPLATE (VAL_T, octave_uint64); \
-  DO_READ_VAL_TEMPLATE (VAL_T, float); \
-  DO_READ_VAL_TEMPLATE (VAL_T, double); \
-  DO_READ_VAL_TEMPLATE (VAL_T, char); \
-  DO_READ_VAL_TEMPLATE (VAL_T, signed char); \
-  DO_READ_VAL_TEMPLATE (VAL_T, unsigned char)
-
-INSTANTIATE_DO_READ (int8NDArray);
-INSTANTIATE_DO_READ (uint8NDArray);
-INSTANTIATE_DO_READ (int16NDArray);
-INSTANTIATE_DO_READ (uint16NDArray);
-INSTANTIATE_DO_READ (int32NDArray);
-INSTANTIATE_DO_READ (uint32NDArray);
-INSTANTIATE_DO_READ (int64NDArray);
-INSTANTIATE_DO_READ (uint64NDArray);
-INSTANTIATE_DO_READ (FloatNDArray);
-INSTANTIATE_DO_READ (NDArray);
-INSTANTIATE_DO_READ (charNDArray);
-INSTANTIATE_DO_READ (boolNDArray);
-
-typedef octave_value (*read_fptr) (octave_stream&, octave_idx_type, octave_idx_type, octave_idx_type, octave_idx_type, bool, bool,
-                                   oct_mach_info::float_format ffmt, octave_idx_type&);
-
-#define FILL_TABLE_ROW(R, VAL_T) \
-  read_fptr_table[R][oct_data_conv::dt_int8] = do_read<VAL_T, octave_int8>; \
-  read_fptr_table[R][oct_data_conv::dt_uint8] = do_read<VAL_T, octave_uint8>; \
-  read_fptr_table[R][oct_data_conv::dt_int16] = do_read<VAL_T, octave_int16>; \
-  read_fptr_table[R][oct_data_conv::dt_uint16] = do_read<VAL_T, octave_uint16>; \
-  read_fptr_table[R][oct_data_conv::dt_int32] = do_read<VAL_T, octave_int32>; \
-  read_fptr_table[R][oct_data_conv::dt_uint32] = do_read<VAL_T, octave_uint32>; \
-  read_fptr_table[R][oct_data_conv::dt_int64] = do_read<VAL_T, octave_int64>; \
-  read_fptr_table[R][oct_data_conv::dt_uint64] = do_read<VAL_T, octave_uint64>; \
-  read_fptr_table[R][oct_data_conv::dt_single] = do_read<VAL_T, float>; \
-  read_fptr_table[R][oct_data_conv::dt_double] = do_read<VAL_T, double>; \
-  read_fptr_table[R][oct_data_conv::dt_char] = do_read<VAL_T, char>; \
-  read_fptr_table[R][oct_data_conv::dt_schar] = do_read<VAL_T, signed char>; \
-  read_fptr_table[R][oct_data_conv::dt_uchar] = do_read<VAL_T, unsigned char>; \
-  read_fptr_table[R][oct_data_conv::dt_logical] = do_read<VAL_T, unsigned char>
-
 octave_value
 octave_stream::read (const Array<double>& size, octave_idx_type block_size,
                      oct_data_conv::data_type input_type,
@@ -3257,38 +3133,13 @@
                      octave_idx_type skip, oct_mach_info::float_format ffmt,
                      octave_idx_type& char_count)
 {
-  static bool initialized = false;
-
-  // Table function pointers for return types x read types.
-
-  static read_fptr read_fptr_table[oct_data_conv::dt_unknown][14];
-
-  if (! initialized)
-    {
-      for (int i = 0; i < oct_data_conv::dt_unknown; i++)
-        for (int j = 0; j < 14; j++)
-          read_fptr_table[i][j] = 0;
-
-      FILL_TABLE_ROW (oct_data_conv::dt_int8, int8NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_uint8, uint8NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_int16, int16NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_uint16, uint16NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_int32, int32NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_uint32, uint32NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_int64, int64NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_uint64, uint64NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_single, FloatNDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_double, NDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_char, charNDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_schar, charNDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_uchar, charNDArray);
-      FILL_TABLE_ROW (oct_data_conv::dt_logical, boolNDArray);
-
-      initialized = true;
-    }
-
   octave_value retval;
 
+  octave_idx_type nr = -1;
+  octave_idx_type nc = -1;
+
+  bool one_elt_size_spec = false;
+
   if (stream_ok ())
     {
       // FIXME -- we may eventually want to make this extensible.
@@ -3299,47 +3150,112 @@
 
       char_count = 0;
 
-      octave_idx_type nr = -1;
-      octave_idx_type nc = -1;
-
-      bool ignore;
-
-      get_size (size, nr, nc, ignore, "fread");
+      get_size (size, nr, nc, one_elt_size_spec, "fread");
 
       if (! error_state)
         {
-          if (nr == 0 || nc == 0)
-            retval = Matrix (nr, nc);
+
+          octave_idx_type elts_to_read = std::numeric_limits<octave_idx_type>::max ();
+
+          if (one_elt_size_spec)
+            {
+              // If NR == 0, Matlab returns [](0x0).
+
+              // If NR > 0, the result will be a column vector with the given
+              // number of rows.
+
+              // If NR < 0, then we have Inf and the result will be a column
+              // vector but we have to wait to see how big NR will be.
+
+              if (nr == 0)
+                nr = nc = 0;
+              else
+                nc = 1;
+            }
           else
             {
-              if (ffmt == oct_mach_info::flt_fmt_unknown)
-                ffmt = float_format ();
-
-              read_fptr fcn = read_fptr_table[output_type][input_type];
-
-              bool do_float_fmt_conv = ((input_type == oct_data_conv::dt_double
-                                         || input_type == oct_data_conv::dt_single)
-                                        && ffmt != float_format ());
-
-              bool do_NA_conv = (output_type == oct_data_conv::dt_double);
-
-              if (fcn)
+              // Matlab returns [] even if there are two elements in the size
+              // specification and one is nonzero.
+
+              // If NC < 0 we have [NR, Inf] and we'll wait to decide how big NC
+              // should be.
+
+              if (nr == 0 || nc == 0)
+                nr = nc = 0;
+            }
+
+          // FIXME -- ensure that this does not overflow.
+
+          elts_to_read = nr * nc;
+
+          bool read_to_eof = elts_to_read < 0;
+
+          octave_idx_type input_buf_elts = -1;
+
+          if (skip == 0)
+            {
+              if (read_to_eof)
+                input_buf_elts = 1024 * 1024;
+              else
+                input_buf_elts = elts_to_read;
+            }
+          else
+            input_buf_elts = block_size;
+
+          octave_idx_type input_elt_size = oct_data_conv::data_type_size (input_type);
+
+          octave_idx_type input_buf_size = input_buf_elts * input_elt_size;
+
+          assert (input_buf_size >= 0);
+
+          // Must also work and return correct type object for 0 elements to read.
+
+          std::istream *isp = input_stream ();
+
+          if (isp)
+            {
+              std::istream& is = *isp;
+
+              std::list <void *> input_buf_list;
+
+              octave_idx_type elts_read = 0;
+
+              while (is && ! is.eof () && (read_to_eof || elts_read < elts_to_read))
                 {
-                  retval = (*fcn) (*this, nr, nc, block_size, skip,
-                                   do_float_fmt_conv, do_NA_conv,
-                                   ffmt, char_count);
-
-                  // FIXME -- kluge!
-
-                  if (! error_state
-                      && (output_type == oct_data_conv::dt_char
-                          || output_type == oct_data_conv::dt_schar
-                          || output_type == oct_data_conv::dt_uchar))
-                    retval = retval.char_matrix_value ();
+                  char *input_buf = new char [input_buf_size];
+
+                  is.read (input_buf, input_buf_size);
+
+                  size_t count = is.gcount ();
+
+                  char_count += count;
+
+                  elts_read += count / input_elt_size;
+
+                  input_buf_list.push_back (input_buf);
+
+                  if (is && skip != 0 && elts_read == block_size)
+                    {
+                      int seek_status = seek (skip, SEEK_CUR);
+
+                      if (seek_status < 0)
+                        break;
+                    }
                 }
-              else
-                error ("fread: unable to read and convert requested types");
+
+              if (read_to_eof)
+                {
+                  if (nc < 0)
+                    nc = elts_read / nr + 1;
+                  else
+                    nr = elts_read;
+                }
+
+              retval = finalize_read (input_buf_list, input_buf_elts, elts_read,
+                                      nr, nc, input_type, output_type, ffmt);
             }
+          else
+            error ("fread: invalid input stream");
         }
       else
         invalid_operation ("fread", "reading");
@@ -3377,103 +3293,106 @@
   return retval;
 }
 
-template <class T>
-void
-write_int (std::ostream& os, bool swap, const T& val)
+template <class T, class V>
+static void
+convert_ints (const T *data, void *conv_data, octave_idx_type n_elts,
+              bool swap)
 {
-  typename T::val_type tmp = val.value ();
-
-  if (swap)
-    swap_bytes<sizeof (typename T::val_type)> (&tmp);
-
-  os.write (reinterpret_cast<const char *> (&tmp),
-            sizeof (typename T::val_type));
+  typedef typename V::val_type val_type;
+
+  val_type *vt_data = static_cast <val_type *> (conv_data);
+
+  for (octave_idx_type i = 0; i < n_elts; i++)
+    {
+      V val (data[i]);
+
+      vt_data[i] = val.value ();
+
+      if (swap)
+        swap_bytes<sizeof (val_type)> (&vt_data[i]);
+    }
 }
 
-template void write_int (std::ostream&, bool, const octave_int8&);
-template void write_int (std::ostream&, bool, const octave_uint8&);
-template void write_int (std::ostream&, bool, const octave_int16&);
-template void write_int (std::ostream&, bool, const octave_uint16&);
-template void write_int (std::ostream&, bool, const octave_int32&);
-template void write_int (std::ostream&, bool, const octave_uint32&);
-template void write_int (std::ostream&, bool, const octave_int64&);
-template void write_int (std::ostream&, bool, const octave_uint64&);
-
 template <class T>
-static inline bool
-do_write (std::ostream& os, const T& val, oct_data_conv::data_type output_type,
-          oct_mach_info::float_format flt_fmt, bool swap,
-          bool do_float_conversion)
+static bool
+convert_data (const T *data, void *conv_data, octave_idx_type n_elts,
+              oct_data_conv::data_type output_type,
+              oct_mach_info::float_format flt_fmt)
 {
   bool retval = true;
 
-  // For compatibility, Octave converts to the output type, then
-  // writes.  This means that truncation happens on the conversion.
-  // For example, the following program prints 0:
-  //
-  //   x = int8 (-1)
-  //   f = fopen ("foo.dat", "w");
-  //   fwrite (f, x, "unsigned char");
-  //   fclose (f);
-  //   f = fopen ("foo.dat", "r");
-  //   y = fread (f, 1, "unsigned char");
-  //   printf ("%d\n", y);
+  bool swap
+    = ((oct_mach_info::words_big_endian ()
+        && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian)
+       || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
+
+  bool do_float_conversion =  flt_fmt != oct_mach_info::float_format ();
+
+  // We use octave_intN classes here instead of converting directly to
+  // intN_t so that we get integer saturation semantics.
 
   switch (output_type)
     {
     case oct_data_conv::dt_char:
     case oct_data_conv::dt_schar:
     case oct_data_conv::dt_int8:
-      write_int (os, swap, octave_int8 (val));
+      convert_ints<T, octave_int8> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_uchar:
     case oct_data_conv::dt_uint8:
-      write_int (os, swap, octave_uint8 (val));
+      convert_ints<T, octave_uint8> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_int16:
-      write_int (os, swap, octave_int16 (val));
+      convert_ints<T, octave_int16> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_uint16:
-      write_int (os, swap, octave_uint16 (val));
+      convert_ints<T, octave_uint16> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_int32:
-      write_int (os, swap, octave_int32 (val));
+      convert_ints<T, octave_int32> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_uint32:
-      write_int (os, swap, octave_uint32 (val));
+      convert_ints<T, octave_uint32> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_int64:
-      write_int (os, swap, octave_int64 (val));
+      convert_ints<T, octave_int64> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_uint64:
-      write_int (os, swap, octave_uint64 (val));
+      convert_ints<T, octave_uint64> (data, conv_data, n_elts, swap);
       break;
 
     case oct_data_conv::dt_single:
       {
-        float f = static_cast<float> (val);
-
-        if (do_float_conversion)
-          do_float_format_conversion (&f, 1, flt_fmt);
-
-        os.write (reinterpret_cast<const char *> (&f), sizeof (float));
+        float *vt_data = static_cast <float *> (conv_data);
+
+        for (octave_idx_type i = 0; i < n_elts; i++)
+          {
+            vt_data[i] = data[i];
+
+            if (do_float_conversion)
+              do_float_format_conversion (&vt_data[i], 1, flt_fmt);
+          }
       }
       break;
 
     case oct_data_conv::dt_double:
       {
-        double d = static_cast<double> (val);
-        if (do_float_conversion)
-          do_double_format_conversion (&d, 1, flt_fmt);
-
-        os.write (reinterpret_cast<const char *> (&d), sizeof (double));
+        double *vt_data = static_cast <double *> (conv_data);
+
+        for (octave_idx_type i = 0; i < n_elts; i++)
+          {
+            vt_data[i] = data[i];
+
+            if (do_float_conversion)
+              do_double_format_conversion (&vt_data[i], 1, flt_fmt);
+          }
       }
       break;
 
@@ -3487,198 +3406,174 @@
   return retval;
 }
 
-template bool
-do_write (std::ostream&, const octave_int8&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_uint8&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_int16&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_uint16&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_int32&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_uint32&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_int64&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
-
-template bool
-do_write (std::ostream&, const octave_uint64&, oct_data_conv::data_type,
-          oct_mach_info::float_format, bool, bool);
+bool
+octave_stream::write_bytes (const void *data, size_t nbytes)
+{
+  bool status = false;
+
+  std::ostream *osp = output_stream ();
+
+  if (osp)
+    {
+      std::ostream& os = *osp;
+
+      if (os)
+        {
+          os.write (static_cast<const char *> (data), nbytes);
+
+          if (os)
+            status = true;
+        }
+    }
+
+  return status;
+}
+
+bool
+octave_stream::skip_bytes (size_t skip)
+{
+  bool status = false;
+
+  std::ostream *osp = output_stream ();
+
+  if (osp)
+    {
+      std::ostream& os = *osp;
+
+      // Seek to skip when inside bounds of existing file.
+      // Otherwise, write NUL to skip.
+
+      off_t orig_pos = tell ();
+
+      seek (0, SEEK_END);
+
+      off_t eof_pos = tell ();
+
+      // Is it possible for this to fail to return us to the
+      // original position?
+      seek (orig_pos, SEEK_SET);
+
+      size_t remaining = eof_pos - orig_pos;
+
+      if (remaining < skip)
+        {
+          seek (0, SEEK_END);
+
+          // FIXME -- probably should try to write larger blocks...
+
+          unsigned char zero = 0;
+          for (size_t j = 0; j < skip - remaining; j++)
+            os.write (reinterpret_cast<const char *> (&zero), 1);
+        }
+      else
+        seek (skip, SEEK_CUR);
+
+      if (os)
+        status = true;
+    }
+
+  return status;
+}
 
 template <class T>
 octave_idx_type
 octave_stream::write (const Array<T>& data, octave_idx_type block_size,
                       oct_data_conv::data_type output_type,
-                      octave_idx_type skip, oct_mach_info::float_format flt_fmt)
+                      octave_idx_type skip,
+                      oct_mach_info::float_format flt_fmt)
 {
-  octave_idx_type retval = -1;
-
-  bool status = true;
-
-  octave_idx_type count = 0;
-
-  const T *d = data.data ();
-
-  octave_idx_type n = data.length ();
-
-  oct_mach_info::float_format native_flt_fmt
-    = oct_mach_info::float_format ();
-
-  bool do_float_conversion = (flt_fmt != native_flt_fmt);
-
-  // FIXME -- byte order for Cray?
-
-  bool swap = false;
-
-  if (oct_mach_info::words_big_endian ())
-    swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian
-            || flt_fmt == oct_mach_info::flt_fmt_vax_g
-            || flt_fmt == oct_mach_info::flt_fmt_vax_g);
+  bool swap
+    = ((oct_mach_info::words_big_endian ()
+        && flt_fmt == oct_mach_info::flt_fmt_ieee_little_endian)
+       || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
+
+  bool do_data_conversion
+    = (swap || ! is_equivalent_type<T> (output_type) 
+       || flt_fmt != oct_mach_info::float_format ());
+
+  octave_idx_type nel = data.numel ();
+
+  octave_idx_type chunk_size;
+
+  if (skip != 0)
+    chunk_size = block_size;
+  else if (do_data_conversion)
+    chunk_size = 1024 * 1024;
   else
-    swap = (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian);
-
-  for (octave_idx_type i = 0; i < n; i++)
+    chunk_size = nel;
+
+  octave_idx_type i = 0;
+
+  const T *pdata = data.data ();
+
+  while (i < nel)
     {
-      std::ostream *osp = output_stream ();
-
-      if (osp)
+      if (skip != 0)
         {
-          std::ostream& os = *osp;
-
-          if (skip != 0 && (i % block_size) == 0)
-            {
-              // Seek to skip when inside bounds of existing file.
-              // Otherwise, write NUL to skip.
-
-              off_t orig_pos = tell ();
-
-              seek (0, SEEK_END);
-
-              off_t eof_pos = tell ();
-
-              // Is it possible for this to fail to return us to the
-              // original position?
-              seek (orig_pos, SEEK_SET);
-
-              off_t remaining = eof_pos - orig_pos;
-
-              if (remaining < skip)
-                {
-                  seek (0, SEEK_END);
-
-                  // FIXME -- probably should try to write larger
-                  // blocks...
-
-                  unsigned char zero = 0;
-                  for (octave_idx_type j = 0; j < skip - remaining; j++)
-                    os.write (reinterpret_cast<const char *> (&zero), 1);
-                }
-              else
-                seek (skip, SEEK_CUR);
-            }
-
-          if (os)
-            {
-              status = do_write (os, d[i], output_type, flt_fmt, swap,
-                                 do_float_conversion);
-
-              if (os && status)
-                count++;
-              else
-                break;
-            }
-          else
-            {
-              status = false;
-              break;
-            }
+          if (! skip_bytes (skip))
+            return -1;
+        }
+
+      octave_idx_type remaining_nel = nel - i;
+
+      if (chunk_size > remaining_nel)
+        chunk_size = remaining_nel;
+
+      bool status = false;
+
+      if (do_data_conversion)
+        {
+          size_t output_size
+            = chunk_size * oct_data_conv::data_type_size (output_type);
+
+          OCTAVE_LOCAL_BUFFER (unsigned char, conv_data, output_size);
+
+          status = convert_data (&pdata[i], conv_data, chunk_size,
+                                 output_type, flt_fmt);
+
+          if (status)
+            status = write_bytes (conv_data, output_size);
         }
       else
-        {
-          status = false;
-          break;
-        }
+        status = write_bytes (pdata, sizeof (T) * chunk_size);
+
+      if (! status)
+        return -1;
+
+      i += chunk_size;
     }
 
-  if (status)
-    retval = count;
-
-  return retval;
+  return nel;
 }
 
-template octave_idx_type
-octave_stream::write (const Array<char>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<bool>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<double>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<float>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_int8>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_uint8>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_int16>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_uint16>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_int32>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_uint32>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_int64>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
-
-template octave_idx_type
-octave_stream::write (const Array<octave_uint64>&, octave_idx_type,
-                      oct_data_conv::data_type,
-                      octave_idx_type, oct_mach_info::float_format);
+#define INSTANTIATE_WRITE(T) \
+  template \
+  octave_idx_type \
+  octave_stream::write (const Array<T>& data, octave_idx_type block_size, \
+                        oct_data_conv::data_type output_type, \
+                        octave_idx_type skip, \
+                        oct_mach_info::float_format flt_fmt)
+
+INSTANTIATE_WRITE (octave_int8);
+INSTANTIATE_WRITE (octave_uint8);
+INSTANTIATE_WRITE (octave_int16);
+INSTANTIATE_WRITE (octave_uint16);
+INSTANTIATE_WRITE (octave_int32);
+INSTANTIATE_WRITE (octave_uint32);
+INSTANTIATE_WRITE (octave_int64);
+INSTANTIATE_WRITE (octave_uint64);
+INSTANTIATE_WRITE (int8_t);
+INSTANTIATE_WRITE (uint8_t);
+INSTANTIATE_WRITE (int16_t);
+INSTANTIATE_WRITE (uint16_t);
+INSTANTIATE_WRITE (int32_t);
+INSTANTIATE_WRITE (uint32_t);
+INSTANTIATE_WRITE (int64_t);
+INSTANTIATE_WRITE (uint64_t);
+INSTANTIATE_WRITE (bool);
+INSTANTIATE_WRITE (char);
+INSTANTIATE_WRITE (float);
+INSTANTIATE_WRITE (double);
 
 octave_value
 octave_stream::scanf (const std::string& fmt, const Array<double>& size,
--- a/libinterp/corefcn/oct-stream.h
+++ b/libinterp/corefcn/oct-stream.h
@@ -31,12 +31,14 @@
 #include <iosfwd>
 #include <sstream>
 #include <string>
+#include <list>
 #include <map>
 
 #include "Array.h"
 #include "data-conv.h"
 #include "lo-utils.h"
 #include "mach-info.h"
+#include "oct-locbuf.h"
 #include "oct-refcount.h"
 
 class
@@ -539,13 +541,19 @@
                      octave_idx_type& count);
 
   octave_idx_type write (const octave_value& data, octave_idx_type block_size,
-             oct_data_conv::data_type output_type,
-             octave_idx_type skip, oct_mach_info::float_format flt_fmt);
+                         oct_data_conv::data_type output_type,
+                         octave_idx_type skip,
+                         oct_mach_info::float_format flt_fmt);
+
+  bool write_bytes (const void *data, size_t n_elts);
+
+  bool skip_bytes (size_t n_elts);
 
   template <class T>
-  octave_idx_type write (const Array<T>&, octave_idx_type block_size,
-             oct_data_conv::data_type output_type,
-             octave_idx_type skip, oct_mach_info::float_format flt_fmt);
+  octave_idx_type write (const Array<T>& data, octave_idx_type block_size,
+                         oct_data_conv::data_type output_type,
+                         octave_idx_type skip,
+                         oct_mach_info::float_format flt_fmt);
 
   octave_value scanf (const std::string& fmt, const Array<double>& size,
                       octave_idx_type& count, const std::string& who /* = "scanf" */);
@@ -641,6 +649,15 @@
       if (rep)
         rep->invalid_operation (who, rw);
     }
+
+  octave_value
+  finalize_read (std::list<void *>& input_buf_list,
+                 octave_idx_type input_buf_elts,
+                 octave_idx_type elts_read,
+                 octave_idx_type nr, octave_idx_type nc,
+                 oct_data_conv::data_type input_type,
+                 oct_data_conv::data_type output_type,
+                 oct_mach_info::float_format ffmt);
 };
 
 class
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/oct-tex-lexer.in.ll
@@ -0,0 +1,146 @@
+/*
+
+Copyright (C) 2013 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+%option prefix = "octave_tex_"
+%option noyywrap
+%option reentrant
+%option bison-bridge
+
+%top {
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "txt-eng.h"
+#include "oct-tex-parser.h"
+}
+
+%x	NUM_MODE
+%x	MAYBE_NUM_MODE
+
+D       [0-9]
+NUM	(({D}+\.?{D}*)|(\.{D}+))
+
+%%
+
+%{
+// Numeric values
+%}
+
+<NUM_MODE>{NUM}		{
+    int nread;
+
+    nread = sscanf (yytext, "%lf", &(yylval->num));
+    if (nread == 1)
+      return NUM;
+  }
+<NUM_MODE>[ \t]+	{ }
+<NUM_MODE>"\n"|.	{ yyless (0); BEGIN (INITIAL); }
+
+<MAYBE_NUM_MODE>"{"	{ BEGIN (NUM_MODE); return START; }
+<MAYBE_NUM_MODE>"\n"|.	{ yyless (0); BEGIN (INITIAL); }
+
+%{
+// Simple commands
+%}
+
+"\\bf"		{ return BF; }
+"\\it"		{ return IT; }
+"\\sl"		{ return SL; }
+"\\rm"		{ return RM; }
+
+%{
+// Generic font commands
+%}
+
+"\\fontname"	{ return FONTNAME; }
+"\\fontsize"	{ BEGIN (MAYBE_NUM_MODE); return FONTSIZE; }
+"\\color[rgb]"	{ BEGIN (MAYBE_NUM_MODE); return COLOR_RGB; }
+"\\color"	{ return COLOR; }
+
+%{
+// Special characters
+%}
+
+"{"	{ return START; }
+"}"	{ return END; }
+"^"	{ return SUPER; }
+"_"	{ return SUB; }
+
+"\\{"	|
+"\\}"	|
+"\\^"	|
+"\\_"	|
+"\\\\"	{ yylval->ch = yytext[1]; return CH; }
+
+%{
+// Symbols
+%}
+
+@SYMBOL_RULES@
+
+%{
+// Generic character
+%}
+
+"\n"	|
+.	{ yylval->ch = yytext[0]; return CH; }
+
+%%
+
+bool
+text_parser_tex::init_lexer (const std::string& s)
+{
+  if (! scanner)
+    octave_tex_lex_init (&scanner);
+
+  if (scanner)
+    {
+      if (buffer_state)
+        {
+          octave_tex__delete_buffer (reinterpret_cast<YY_BUFFER_STATE> (buffer_state),
+                                     scanner);
+          buffer_state = 0;
+        }
+
+      buffer_state = octave_tex__scan_bytes (s.data (), s.length (), scanner);
+    }
+
+  return (scanner && buffer_state);
+}
+
+void
+text_parser_tex::destroy_lexer (void)
+{
+  if (buffer_state)
+    {
+      octave_tex__delete_buffer (reinterpret_cast<YY_BUFFER_STATE> (buffer_state),
+                                 scanner);
+      buffer_state = 0;
+    }
+
+  if (scanner)
+    {
+      octave_tex_lex_destroy (scanner);
+      scanner = 0;
+    }
+}
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/oct-tex-parser.yy
@@ -0,0 +1,210 @@
+/*
+
+Copyright (C) 2013 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+%{
+#define YYDEBUG 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "txt-eng.h"
+#include "oct-tex-parser.h"
+
+extern int octave_tex_lex (YYSTYPE *, void *);
+static void yyerror (text_parser_tex& parser, const char *s);
+
+#define scanner parser.get_scanner ()
+%}
+
+%name-prefix="octave_tex_"
+%define api.pure
+%parse-param { text_parser_tex& parser } 
+%lex-param { void *scanner }
+
+%code requires {#include <string>}
+
+%union {
+  /* Leaf symbols produced by the scanner */
+  char                       ch;
+  double                     num;
+  int                        sym;
+
+  /* Used for string buffering */
+  std::string*               str;
+
+  /* Objects produced by the parser */
+  text_element*              e_base;
+  text_element_list*         e_list;
+}
+
+%token BF IT SL RM
+%token FONTNAME FONTSIZE
+%token COLOR COLOR_RGB
+%token START END SUPER SUB
+%token<ch> CH
+%token<num> NUM
+%token<sym> SYM
+
+%type<str> simple_string
+%type<e_base> string_element symbol_element
+%type<e_base> superscript_element subscript_element combined_script_element
+%type<e_base> font_modifier_element fontname_element fontsize_element color_element
+%type<e_list> string_element_list scoped_string_element_list
+
+/* Make sure there's no memory leak on parse error. */
+%destructor { } <ch> <num> <sym>
+%destructor { delete $$; } <*>
+
+%nonassoc SCRIPT
+%nonassoc SUB SUPER
+
+%nonassoc STR
+%nonassoc CH
+
+%start string
+
+%%
+
+simple_string			: CH
+				  { $$ = new std::string (1, $1); }
+				| simple_string CH
+				  { $1->append (1, $2); $$ = $1; }
+				;
+
+symbol_element			: SYM
+				  { $$ = new text_element_symbol ($1); }
+				;
+
+font_modifier_element		: BF
+				  { $$ = new text_element_fontstyle (text_element_fontstyle::bold); }
+				| IT
+				  { $$ = new text_element_fontstyle (text_element_fontstyle::italic); }
+				| SL
+				  { $$ = new text_element_fontstyle (text_element_fontstyle::oblique); }
+				| RM
+				  { $$ = new text_element_fontstyle (text_element_fontstyle::normal); }
+				;
+
+fontsize_element		: FONTSIZE START NUM END
+				  { $$ = new text_element_fontsize ($3); }
+				;
+
+fontname_element		: FONTNAME START simple_string END
+				  {
+				    $$ = new text_element_fontname (*$3);
+				    delete $3;
+				  }
+				;
+
+color_element			: COLOR START simple_string END
+				  {
+				    $$ = new text_element_color (*$3);
+				    delete $3;
+				  }
+				| COLOR_RGB START NUM NUM NUM END
+				  {
+				    $$ = new text_element_color ($3, $4, $5);
+				  }
+				;
+
+string_element			: simple_string %prec STR
+				  {
+				    $$ = new text_element_string (*$1);
+				    delete $1;
+				  }
+				| scoped_string_element_list
+				  /* This is just to avoid a warning in bison. */
+				  { $$ = $1; }
+				| symbol_element
+				| font_modifier_element
+				| fontsize_element
+				| fontname_element
+				| color_element
+				| superscript_element %prec SCRIPT
+				| subscript_element %prec SCRIPT
+				| combined_script_element
+				;
+
+superscript_element		: SUPER CH
+				  { $$ = new text_element_superscript ($2); }
+				| SUPER scoped_string_element_list
+				  { $$ = new text_element_superscript ($2); }
+				| SUPER symbol_element
+				  { $$ = new text_element_superscript ($2); }
+				;
+
+subscript_element		: SUB CH
+				  { $$ = new text_element_subscript ($2); }
+				| SUB scoped_string_element_list
+				  { $$ = new text_element_subscript ($2); }
+				| SUB symbol_element
+				  { $$ = new text_element_subscript ($2); }
+				;
+
+combined_script_element		: subscript_element superscript_element
+				  { $$ = new text_element_combined ($1, $2); }
+				| superscript_element subscript_element
+				  { $$ = new text_element_combined ($1, $2); }
+				;
+
+string_element_list		: string_element
+				  { $$ = new text_element_list ($1); }
+				| string_element_list string_element
+				  { $1->push_back ($2); $$ = $1; }
+				;
+
+scoped_string_element_list	: START string_element_list END
+				  { $$ = $2; }
+				| START END
+				  { $$ = new text_element_list (); }
+				;
+
+string				: /* empty */
+				  { parser.set_parse_result (new text_element_string ("")); }
+				| string_element_list
+				  { parser.set_parse_result ($1); }
+				;
+
+%%
+
+text_element*
+text_parser_tex::parse (const std::string& s)
+{
+  octave_tex_debug = 0;
+
+  if (init_lexer (s))
+    {
+      result = 0;
+
+      if (octave_tex_parse (*this) == 0)
+        return result;
+    }
+
+  return new text_element_string (s);
+}
+
+static void
+yyerror (text_parser_tex&, const char *s)
+{
+  fprintf (stderr, "TeX parse error: %s\n", s);
+}
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/oct-tex-symbols.in
@@ -0,0 +1,112 @@
+# List of supported symbols for the TeX interpreter
+# (http://www.mathworks.com/help/matlab/ref/text_props.html):
+# - symbol name
+# - Unicode code
+# - MS symbol code (http://www.kostis.net/charsets/symbol.htm)
+
+alpha           0x03B1  0xF061
+angle           0x2220  0xF0D0
+ast             0x2217  0xF02A
+beta            0x03B2  0xF062
+gamma           0x03B3  0xF067
+delta           0x03B4  0xF064
+epsilon         0x03B5  0xF065
+zeta            0x03B6  0xF07A
+eta             0x03B7  0xF068
+theta           0x03B8  0xF071
+vartheta        0x03D1  0xF04A
+iota            0x03B9  0xF069
+kappa           0x03BA  0xF06B
+lambda          0x03BB  0xF06C
+mu              0x03BC  0xF06D
+nu              0x03BD  0xF06E
+xi              0x03BE  0xF078
+pi              0x03C0  0xF070
+rho             0x03C1  0xF072
+sigma           0x03C3  0xF073
+varsigma        0x03C2  0xF056
+tau             0x03C4  0xF074
+equiv           0x2261  0xF0BA
+Im              0x2111  0xF0C1
+otimes          0x2297  0xF0C4
+cap             0x2229  0xF0C7
+supset          0x2283  0xF0C9
+int             0x222B  0xF0F2
+rfloor          0x230B  0xF0FB
+lfloor          0x230A  0xF0EB
+perp            0x22A5  0xF05E
+wedge           0x2227  0xF0D9
+rceil           0x2309  0xF0F9
+vee             0x2228  0xF0DA
+langle          0x27E8  0xF0E1
+
+upsilon         0x03C5  0xF075
+phi             0x03C6  0xF066
+chi             0x03C7  0xF063
+psi             0x03C8  0xF079
+omega           0x03C9  0xF077
+Gamma           0x0393  0xF047
+Delta           0x0394  0xF044
+Theta           0x0398  0xF051
+Lambda          0x039B  0xF04C
+Xi              0x039E  0xF058
+Pi              0x03A0  0xF050
+Sigma           0x03A3  0xF053
+Upsilon         0x03D2  0xF055
+Phi             0x03A6  0xF046
+Psi             0x03A8  0xF059
+Omega           0x03A9  0xF057
+forall          0x2200  0xF022
+exists          0x2203  0xF024
+ni              0x220B  0xF027
+cong            0x2245  0xF040
+approx          0x2248  0xF0BB
+Re              0x211C  0xF0C2
+oplus           0x2295  0xF0C5
+cup             0x222A  0xF0C8
+subseteq        0x2286  0xF0CD
+in              0x2208  0xF0CE
+lceil           0x2308  0xF0E9
+cdot            0x22C5  0xF0D7
+neg             0x00AC  0xF0D8
+times           0x00D7  0xF0B4
+surd            0x221A  0xF0D6
+varpi           0x03D6  0xF076
+rangle          0x27E9  0xF0F1
+
+sim             0x223C  0xF07E
+leq             0x2264  0xF0A3
+infty           0x221E  0xF0A5
+clubsuit        0x2663  0xF0A7
+diamondsuit     0x2666  0xF0A8
+heartsuit       0x2665  0xF0A9
+spadesuit       0x2660  0xF0AA
+leftrightarrow  0x2194  0xF0AB
+leftarrow       0x2190  0xF0AC
+Leftarrow       0x21D0  0xF0DC
+uparrow         0x2191  0xF0AD
+rightarrow      0x2192  0xF0AE
+Rightarrow      0x21D2  0xF0DE
+downarrow       0x2193  0xF0AF
+circ            0x2218  0xF0B0
+pm              0x00B1  0xF0B1
+geq             0x2265  0xF0B3
+propto          0x221D  0xF0B5
+partial         0x2202  0xF0B6
+bullet          0x2219  0xF0B7
+div             0x00F7  0xF0B8
+neq             0x2260  0xF0B9
+aleph           0x2135  0xF0C0
+wp              0x2118  0xF0C3
+oslash          0x2298  0xF0C6
+supseteq        0x2287  0xF0CA
+subset          0x2282  0xF0CC
+o               0x03BF  0xF0B0
+nabla           0x2207  0xF0D1
+ldots           0x2026  0xF0BC
+prime           0x2032  0xF0A2
+0               0x2205  0xF0C6
+mid             0x2223  0xF0BD
+copyright       0x00A9  0xF0E3
+
+deg             0x00B0  0xF0B0
--- a/libinterp/corefcn/octave-link.cc
+++ b/libinterp/corefcn/octave-link.cc
@@ -231,7 +231,7 @@
 
           retval.resize (3);
 
-          // If 3, then is filename, directory and selected index.
+          // If 3, then retval is filename, directory, and selected index.
           if (nel <= 3)
             {
               int idx = 0;
@@ -250,12 +250,12 @@
           else
             {
               // Multiple files.
-              nel = items_lst.size ();
+              nel = items_lst.size () - 2;
               Cell items (dim_vector (1, nel));
 
               std::list<std::string>::iterator it = items_lst.begin ();
 
-              for (unsigned int idx = 0; idx < items_lst.size ()-2; idx++)
+              for (int idx = 0; idx < nel; idx++)
                 {
                   items.xelem (idx) = *it;
                   it++;
--- a/libinterp/corefcn/pager.cc
+++ b/libinterp/corefcn/pager.cc
@@ -514,23 +514,29 @@
 
 DEFUN (diary, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Command} {} diary options\n\
+@deftypefn  {Command} {} diary\n\
+@deftypefnx {Command} {} diary on\n\
+@deftypefnx {Command} {} diary off\n\
+@deftypefnx {Command} {} diary @var{filename}\n\
 Record a list of all commands @emph{and} the output they produce, mixed\n\
-together just as you see them on your terminal.  Valid options are:\n\
+together just as they appear on the terminal.\n\
 \n\
-@table @code\n\
+Valid options are:\n\
+\n\
+@table @asis\n\
 @item on\n\
-Start recording your session in a file called @file{diary} in your\n\
+Start recording a session in a file called @file{diary} in the\n\
 current working directory.\n\
 \n\
 @item off\n\
-Stop recording your session in the diary file.\n\
+Stop recording the session in the diary file.\n\
 \n\
-@item @var{file}\n\
-Record your session in the file named @var{file}.\n\
+@item @var{filename}\n\
+Record the session in the file named @var{filename}.\n\
 @end table\n\
 \n\
 With no arguments, @code{diary} toggles the current diary state.\n\
+@seealso{history}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -648,9 +654,9 @@
 buffers its output and waits until just before the prompt is printed to\n\
 flush it to the pager.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{page_screen_output, more, PAGER, PAGER_FLAGS}\n\
 @end deftypefn")
 {
@@ -668,9 +674,9 @@
 (such as @code{less}---see @ref{Installation}) are also capable of moving\n\
 backward on the output.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{more, page_output_immediately, PAGER, PAGER_FLAGS}\n\
 @end deftypefn")
 {
@@ -684,13 +690,13 @@
 @deftypefnx {Built-in Function} {} PAGER (@var{new_val}, \"local\")\n\
 Query or set the internal variable that specifies the program to use\n\
 to display terminal output on your system.  The default value is\n\
-normally @code{\"less\"}, @code{\"more\"}, or\n\
-@code{\"pg\"}, depending on what programs are installed on your system.\n\
+normally @qcode{\"less\"}, @qcode{\"more\"}, or\n\
+@qcode{\"pg\"}, depending on what programs are installed on your system.\n\
 @xref{Installation}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{PAGER_FLAGS, page_output_immediately, more, page_screen_output}\n\
 @end deftypefn")
 {
@@ -705,9 +711,9 @@
 Query or set the internal variable that specifies the options to pass\n\
 to the pager.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{PAGER, more, page_screen_output, page_output_immediately}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/pinv.cc
+++ b/libinterp/corefcn/pinv.cc
@@ -172,12 +172,12 @@
 
 /*
 %!shared a, b, tol, hitol, d, u, x, y
-%! a = reshape (rand*[1:16], 4, 4);   ## Rank 2 matrix
+%! a = reshape (rand*[1:16], 4, 4);  # Rank 2 matrix
 %! b = pinv (a);
 %! tol = 4e-14;
 %! hitol = 40*sqrt (eps);
 %! d = diag ([rand, rand, hitol, hitol]);
-%! u = rand (4);                      ## Could be singular by freak accident
+%! u = rand (4);                     # Could be singular by freak accident
 %! x = inv (u)*d*u;
 %! y = pinv (x, sqrt (eps));
 %!
--- a/libinterp/corefcn/pr-output.cc
+++ b/libinterp/corefcn/pr-output.cc
@@ -1459,9 +1459,6 @@
           // Unless explicitly asked for, always print in big-endian
           // format.
 
-          // FIXME -- is it correct to swap bytes for VAX
-          // formats and not for Cray?
-
           // FIXME -- will bad things happen if we are
           // interrupted before resetting the format flags and fill
           // character?
@@ -1475,9 +1472,7 @@
             = os.flags (std::ios::right | std::ios::hex);
 
           if (hex_format > 1
-              || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
-              || flt_fmt == oct_mach_info::flt_fmt_cray
-              || flt_fmt == oct_mach_info::flt_fmt_unknown)
+              || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian)
             {
               for (size_t i = 0; i < sizeof (double); i++)
                 os << std::setw (2) << static_cast<int> (tmp.i[i]);
@@ -1496,15 +1491,10 @@
           equiv tmp;
           tmp.d = d;
 
-          // FIXME -- is it correct to swap bytes for VAX
-          // formats and not for Cray?
-
           oct_mach_info::float_format flt_fmt =
             oct_mach_info::native_float_format ();
 
-          if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian
-              || flt_fmt == oct_mach_info::flt_fmt_cray
-              || flt_fmt == oct_mach_info::flt_fmt_unknown)
+          if (flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian)
             {
               for (size_t i = 0; i < sizeof (double); i++)
                 PRINT_CHAR_BITS (os, tmp.i[i]);
@@ -3803,7 +3793,7 @@
 @samp{e} format if it is unable to format a matrix properly using the\n\
 current format.\n\
 \n\
-@item short e\n\
+@item  short e\n\
 @itemx long e\n\
 Exponential format.  The number to be represented is split between a mantissa\n\
 and an exponent (power of 10).  The mantissa has 5 significant digits in the\n\
@@ -3811,14 +3801,14 @@
 For example, with the @samp{short e} format, @code{pi} is displayed as\n\
 @code{3.1416e+00}.\n\
 \n\
-@item short E\n\
+@item  short E\n\
 @itemx long E\n\
 Identical to @samp{short e} or @samp{long e} but displays an uppercase\n\
 @samp{E} to indicate the exponent.\n\
 For example, with the @samp{long E} format, @code{pi} is displayed as\n\
 @code{3.14159265358979E+00}.\n\
 \n\
-@item short g\n\
+@item  short g\n\
 @itemx long g\n\
 Optimally choose between fixed point and exponential format based on\n\
 the magnitude of the number.\n\
@@ -3837,19 +3827,19 @@
 @end group\n\
 @end example\n\
 \n\
-@item short eng\n\
+@item  short eng\n\
 @itemx long eng\n\
 Identical to @samp{short e} or @samp{long e} but displays the value\n\
 using an engineering format, where the exponent is divisible by 3. For\n\
 example, with the @samp{short eng} format, @code{10 * pi} is displayed as\n\
 @code{31.4159e+00}.\n\
 \n\
-@item long G\n\
+@item  long G\n\
 @itemx short G\n\
 Identical to @samp{short g} or @samp{long g} but displays an uppercase\n\
 @samp{E} to indicate the exponent.\n\
 \n\
-@item free\n\
+@item  free\n\
 @itemx none\n\
 Print output in free format, without trying to line up columns of\n\
 matrices on the decimal point.  This also causes complex numbers to be\n\
@@ -3982,9 +3972,9 @@
 this reason, you should be careful when setting\n\
 @code{fixed_point_format} to a nonzero value.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{format, output_max_field_width, output_precision}\n\
 @end deftypefn")
 {
@@ -4011,9 +4001,9 @@
 ans = [](3x0)\n\
 @end example\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{format}\n\
 @end deftypefn")
 {
@@ -4049,9 +4039,9 @@
 @end group\n\
 @end example\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{format}\n\
 @end deftypefn")
 {
@@ -4066,9 +4056,9 @@
 Query or set the internal variable that specifies the maximum width\n\
 of a numeric output field.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{format, fixed_point_format, output_precision}\n\
 @end deftypefn")
 {
@@ -4084,9 +4074,9 @@
 Query or set the internal variable that specifies the minimum number of\n\
 significant figures to display for numeric output.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{format, fixed_point_format, output_max_field_width}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/pt-jit.cc
+++ b/libinterp/corefcn/pt-jit.cc
@@ -50,23 +50,37 @@
 #include <llvm/Analysis/Passes.h>
 #include <llvm/Analysis/Verifier.h>
 #include <llvm/Bitcode/ReaderWriter.h>
-#include <llvm/LLVMContext.h>
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include <llvm/ExecutionEngine/JIT.h>
+#include <llvm/PassManager.h>
+
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+#include <llvm/IR/LLVMContext.h>
+#include <llvm/IR/Module.h>
+#else
+#include <llvm/LLVMContext.h>
 #include <llvm/Module.h>
-#include <llvm/PassManager.h>
-#ifdef IRBUILDER_HEADER_IN_SUPPORT_DIR
+#endif
+
+#ifdef HAVE_LLVM_SUPPORT_IRBUILDER_H
 #include <llvm/Support/IRBuilder.h>
+#elif defined(HAVE_LLVM_IR_IRBUILDER_H)
+#include <llvm/IR/IRBuilder.h>
 #else
 #include <llvm/IRBuilder.h>
 #endif
+
 #include <llvm/Support/raw_os_ostream.h>
 #include <llvm/Support/TargetSelect.h>
-#ifdef HAVE_DATALAYOUT
+
+#ifdef HAVE_LLVM_IR_DATALAYOUT_H
+#include <llvm/IR/DataLayout.h>
+#elif defined(HAVE_LLVM_DATALAYOUT_H)
 #include <llvm/DataLayout.h>
 #else
 #include <llvm/Target/TargetData.h>
 #endif
+
 #include <llvm/Transforms/IPO.h>
 #include <llvm/Transforms/Scalar.h>
 
@@ -2047,7 +2061,7 @@
   module_pass_manager->add (llvm::createAlwaysInlinerPass ());
 
   pass_manager = new llvm::FunctionPassManager (module);
-#if HAVE_DATALAYOUT
+#ifdef HAVE_LLVM_DATALAYOUT
   pass_manager->add (new llvm::DataLayout (*engine->getDataLayout ()));
 #else
   pass_manager->add (new llvm::TargetData (*engine->getTargetData ()));
@@ -2477,9 +2491,9 @@
 Query or set the internal variable that determines whether\n\
 debugging/tracing is enabled for Octave's JIT compiler.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{jit_enable, jit_startcnt}\n\
 @end deftypefn")
 {
@@ -2498,9 +2512,9 @@
 @deftypefnx {Built-in Function} {} jit_enable (@var{new_val}, \"local\")\n\
 Query or set the internal variable that enables Octave's JIT compiler.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{jit_startcnt, debug_jit}\n\
 @end deftypefn")
 {
@@ -2522,9 +2536,9 @@
 operation it does not make sense to employ JIT when the loop count is low.\n\
 By default only loops with greater than 1000 iterations will be accelerated.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{jit_enable, debug_jit}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/qz.cc
+++ b/libinterp/corefcn/qz.cc
@@ -346,20 +346,20 @@
 of the revised pencil contains all eigenvalues that satisfy:\n\
 \n\
 @table @asis\n\
-@item \"N\"\n\
+@item @qcode{\"N\"}\n\
 = unordered (default)\n\
 \n\
-@item \"S\"\n\
+@item @qcode{\"S\"}\n\
 = small: leading block has all |lambda| @leq{} 1\n\
 \n\
-@item \"B\"\n\
+@item @qcode{\"B\"}\n\
 = big: leading block has all |lambda| @geq{} 1\n\
 \n\
-@item \"-\"\n\
+@item @qcode{\"-\"}\n\
 = negative real part: leading block has all eigenvalues\n\
 in the open left half-plane\n\
 \n\
-@item \"+\"\n\
+@item @qcode{\"+\"}\n\
 = non-negative real part: leading block has all eigenvalues\n\
 in the closed right half-plane\n\
 @end table\n\
--- a/libinterp/corefcn/rand.cc
+++ b/libinterp/corefcn/rand.cc
@@ -49,7 +49,7 @@
 
 /*
 %!shared __random_statistical_tests__
-%! # Flag whether the statistical tests should be run in "make check" or not
+%! ## Flag whether the statistical tests should be run in "make check" or not
 %! __random_statistical_tests__ = 0;
 */
 
@@ -424,7 +424,7 @@
 random numbers with a significantly longer cycle time.  However, in\n\
 some circumstances it might be desirable to obtain the same random\n\
 sequences as used by the old generators.  To do this the keyword\n\
-\"seed\" is used to specify that the old generators should be use,\n\
+@qcode{\"seed\"} is used to specify that the old generators should be use,\n\
 as in\n\
 \n\
 @example\n\
@@ -442,13 +442,15 @@
 However, it should be noted that querying the seed will not cause\n\
 @code{rand} to use the old generators, only setting the seed will.\n\
 To cause @code{rand} to once again use the new generators, the\n\
-keyword \"state\" should be used to reset the state of the @code{rand}.\n\
+keyword @qcode{\"state\"} should be used to reset the state of the\n\
+@code{rand}.\n\
 \n\
 The state or seed of the generator can be reset to a new random value\n\
-using the \"reset\" keyword.\n\
+using the @qcode{\"reset\"} keyword.\n\
 \n\
-The class of the value returned can be controlled by a trailing \"double\"\n\
-or \"single\" argument.  These are the only valid classes.\n\
+The class of the value returned can be controlled by a trailing\n\
+@qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
+classes.\n\
 @seealso{randn, rande, randg, randp}\n\
 @end deftypefn")
 {
@@ -500,16 +502,16 @@
 
 /*
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! rand ("state", 1);
 %! assert (rand (1,6), [0.1343642441124013 0.8474337369372327 0.763774618976614 0.2550690257394218 0.495435087091941 0.4494910647887382], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! rand ("seed", 1);
 %! assert (rand (1,6), [0.8668024251237512 0.9126510815694928 0.09366085007786751 0.1664607301354408 0.7408077004365623 0.7615650338120759], 1e-6);
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   rand ("state", 12);
 %!   x = rand (100000, 1);
 %!   assert (max (x) < 1);   #*** Please report this!!! ***
@@ -521,7 +523,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   rand ("seed", 12);
 %!   x = rand (100000, 1);
 %!   assert (max (x) < 1);   #*** Please report this!!! ***
@@ -533,6 +535,19 @@
 %! endif
 */
 
+/*
+%!# Test out-of-range values as rand() seeds.  See oct-rand.cc: double2uint32().
+%!function v = __rand_sample__ (initval)
+%!  rand ("state", initval);
+%!  v = rand (1, 6);
+%!endfunction
+%!
+%!assert (__rand_sample__ (0), __rand_sample__ (2^32))
+%!assert (__rand_sample__ (-2), __rand_sample__ (2^32-2))
+%!assert (__rand_sample__ (Inf), __rand_sample__ (NaN))
+%!assert (! isequal (__rand_sample__ (-1), __rand_sample__ (-2)))
+*/
+
 static std::string current_distribution = octave_rand::distribution ();
 
 DEFUN (randn, args, ,
@@ -555,8 +570,9 @@
 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
 to transform from a uniform to a normal distribution.\n\
 \n\
-The class of the value returned can be controlled by a trailing \"double\"\n\
-or \"single\" argument.  These are the only valid classes.\n\
+The class of the value returned can be controlled by a trailing\n\
+@qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
+classes.\n\
 \n\
 Reference: G. Marsaglia and W.W. Tsang,\n\
 @cite{Ziggurat Method for Generating Random Variables},\n\
@@ -577,16 +593,16 @@
 
 /*
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randn ("state", 1);
 %! assert (randn (1, 6), [-2.666521678978671 -0.7381719971724564 1.507903992673601 0.6019427189162239 -0.450661261143348 -0.7054431351574116], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randn ("seed", 1);
 %! assert (randn (1, 6), [-1.039402365684509 -1.25938892364502 0.1968704611063004 0.3874166905879974 -0.5976632833480835 -0.6615074276924133], 1e-6);
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randn ("state", 12);
 %!   x = randn (100000, 1);
 %!   assert (mean (x), 0, 0.01);
@@ -596,7 +612,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randn ("seed", 12);
 %!   x = randn (100000, 1);
 %!   assert (mean (x), 0, 0.01);
@@ -625,8 +641,9 @@
 By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
 to transform from a uniform to an exponential distribution.\n\
 \n\
-The class of the value returned can be controlled by a trailing \"double\"\n\
-or \"single\" argument.  These are the only valid classes.\n\
+The class of the value returned can be controlled by a trailing\n\
+@qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
+classes.\n\
 \n\
 Reference: G. Marsaglia and W.W. Tsang,\n\
 @cite{Ziggurat Method for Generating Random Variables},\n\
@@ -647,16 +664,16 @@
 
 /*
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! rande ("state", 1);
 %! assert (rande (1, 6), [3.602973885835625 0.1386190677555021 0.6743112889616958 0.4512830847258422 0.7255744741233175 0.3415969205292291], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! rande ("seed", 1);
 %! assert (rande (1, 6), [0.06492075175653866 1.717980206012726 0.4816154008731246 0.5231300676241517 0.103910739364359 1.668931916356087], 1e-6);
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally
+%!   ## statistical tests may fail occasionally
 %!   rande ("state", 1);
 %!   x = rande (100000, 1);
 %!   assert (min (x) > 0);   # *** Please report this!!! ***
@@ -667,7 +684,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally
+%!   ## statistical tests may fail occasionally
 %!   rande ("seed", 1);
 %!   x = rande (100000, 1);
 %!   assert (min (x)>0);   # *** Please report this!!! ***
@@ -771,8 +788,9 @@
 \n\
 @end table\n\
 \n\
-The class of the value returned can be controlled by a trailing \"double\"\n\
-or \"single\" argument.  These are the only valid classes.\n\
+The class of the value returned can be controlled by a trailing\n\
+@qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
+classes.\n\
 @seealso{rand, randn, rande, randp}\n\
 @end deftypefn")
 {
@@ -794,49 +812,49 @@
 %! assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]); # *** Please report
 
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randg ("state", 1);
 %! assert (randg (0.1, 1, 6), [0.0103951513331241 8.335671459898252e-05 0.00138691397249762 0.000587308416993855 0.495590518784736 2.3921917414795e-12], 1e-6);
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randg ("state", 1);
 %! assert (randg (0.95, 1, 6), [3.099382433255327 0.3974529788871218 0.644367450750855 1.143261091802246 1.964111762696822 0.04011915547957939], 1e-6);
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randg ("state", 1);
 %! assert (randg (1, 1, 6), [0.2273389379645993 1.288822625058359 0.2406335209340746 1.218869553370733 1.024649860162554 0.09631230343599533], 1e-6);
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randg ("state", 1);
 %! assert (randg (10, 1, 6), [3.520369644331133 15.15369864472106 8.332112081991205 8.406211067432674 11.81193475187611 10.88792728177059], 1e-5);
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randg ("state", 1);
 %! assert (randg (100, 1, 6), [75.34570255262264 115.4911985594699 95.23493031356388 95.48926019250911 106.2397448229803 103.4813150404118], 1e-4);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randg ("seed", 1);
 %! assert (randg (0.1, 1, 6), [0.07144210487604141 0.460641473531723 0.4749028384685516 0.06823389977216721 0.000293838675133884 1.802567535340305e-12], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randg ("seed", 1);
 %! assert (randg (0.95, 1, 6), [1.664905071258545 1.879976987838745 1.905677795410156 0.9948706030845642 0.5606933236122131 0.0766092911362648], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randg ("seed", 1);
 %! assert (randg (1, 1, 6), [0.03512085229158401 0.6488978862762451 0.8114678859710693 0.1666885763406754 1.60791552066803 1.90356981754303], 1e-6);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randg ("seed", 1);
 %! assert (randg (10, 1, 6), [6.566435813903809 10.11648464202881 10.73162078857422 7.747178077697754 6.278522491455078 6.240195751190186], 1e-5);
 %!test
-%! # Test fixed seed
+%! ## Test fixed seed
 %! randg ("seed", 1);
 %! assert (randg (100, 1, 6), [89.40208435058594 101.4734725952148 103.4020004272461 93.62763214111328 88.33104705810547 88.1871337890625], 1e-4);
 
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("state", 12);
 %!   a = 0.1;
 %!   x = randg (a, 100000, 1);
@@ -847,7 +865,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("state", 12);
 %!   a = 0.95;
 %!   x = randg (a, 100000, 1);
@@ -858,7 +876,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("state", 12);
 %!   a = 1;
 %!   x = randg (a, 100000, 1);
@@ -869,7 +887,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("state", 12);
 %!   a = 10;
 %!   x = randg (a, 100000, 1);
@@ -880,7 +898,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("state", 12);
 %!   a = 100;
 %!   x = randg (a, 100000, 1);
@@ -894,7 +912,7 @@
 %!assert (randg ([-inf, -1, 0, inf, nan]), [nan, nan, nan, nan, nan]) # *** Please report
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("seed", 12);
 %!   a = 0.1;
 %!   x = randg (a, 100000, 1);
@@ -905,7 +923,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("seed", 12);
 %!   a = 0.95;
 %!   x = randg (a, 100000, 1);
@@ -916,7 +934,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("seed", 12);
 %!   a = 1;
 %!   x = randg (a, 100000, 1);
@@ -927,7 +945,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("seed", 12);
 %!   a = 10;
 %!   x = randg (a, 100000, 1);
@@ -938,7 +956,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randg ("seed", 12);
 %!   a = 100;
 %!   x = randg (a, 100000, 1);
@@ -993,8 +1011,9 @@
 D 50 p1284, 1994.\n\
 @end table\n\
 \n\
-The class of the value returned can be controlled by a trailing \"double\"\n\
-or \"single\" argument.  These are the only valid classes.\n\
+The class of the value returned can be controlled by a trailing\n\
+@qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
+classes.\n\
 @seealso{rand, randn, rande, randg}\n\
 @end deftypefn")
 {
@@ -1015,33 +1034,33 @@
 %! randp ("state", 12);
 %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]);   # *** Please report
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("state", 1);
 %! assert (randp (5, 1, 6), [5 5 3 7 7 3])
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("state", 1);
 %! assert (randp (15, 1, 6), [13 15 8 18 18 15])
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("state", 1);
 %! assert (randp (1e9, 1, 6), [999915677 999976657 1000047684 1000019035 999985749 999977692], -1e-6)
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("seed", 1);
 %! %%assert (randp (5, 1, 6), [8 2 3 6 6 8])
 %! assert (randp (5, 1, 5), [8 2 3 6 6])
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("seed", 1);
 %! assert (randp (15, 1, 6), [15 16 12 10 10 12])
 %!test
-%! # Test fixed state
+%! ## Test fixed state
 %! randp ("seed", 1);
 %! assert (randp (1e9, 1, 6), [1000006208 1000012224 999981120 999963520 999963072 999981440], -1e-6)
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randp ("state", 12);
 %!   for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
 %!     x = randp (a (1), 100000, 1);
@@ -1054,7 +1073,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randp ("state", 12);
 %!   for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
 %!     x = randp (a(1)*ones (100000, 1), 100000, 1);
@@ -1070,7 +1089,7 @@
 %! assert (randp ([-inf, -1, 0, inf, nan]), [nan, nan, 0, nan, nan]);   # *** Please report
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randp ("seed", 12);
 %!   for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
 %!     x = randp (a(1), 100000, 1);
@@ -1083,7 +1102,7 @@
 %! endif
 %!test
 %! if (__random_statistical_tests__)
-%!   # statistical tests may fail occasionally.
+%!   ## statistical tests may fail occasionally.
 %!   randp ("seed", 12);
 %!   for a = [5, 15, 1e9; 0.03, 0.03, -5e-3; 0.03, 0.03, 0.03]
 %!     x = randp (a(1)*ones (100000, 1), 100000, 1);
--- a/libinterp/corefcn/regexp.cc
+++ b/libinterp/corefcn/regexp.cc
@@ -677,7 +677,7 @@
 @end table\n\
 \n\
 Implementation Note: For compatibility with @sc{matlab}, ordinary escape\n\
-sequences (e.g., \"\\n\" => newline) are processed in @var{pat}\n\
+sequences (e.g., @qcode{\"\\n\"} => newline) are processed in @var{pat}\n\
 regardless of whether @var{pat} has been defined within single quotes.  Use\n\
 a second backslash to stop interpolation of the escape sequence (e.g.,\n\
 \"\\\\n\") or use the @code{regexptranslate} function.\n\
@@ -717,13 +717,13 @@
 are\n\
 \n\
 @multitable @columnfractions 0.2 0.3 0.3 0.2\n\
-@item @tab 'start'        @tab @var{s}  @tab\n\
-@item @tab 'end'          @tab @var{e}  @tab\n\
-@item @tab 'tokenExtents' @tab @var{te} @tab\n\
-@item @tab 'match'        @tab @var{m}  @tab\n\
-@item @tab 'tokens'       @tab @var{t}  @tab\n\
-@item @tab 'names'        @tab @var{nm} @tab\n\
-@item @tab 'split'        @tab @var{sp} @tab\n\
+@item @tab @qcode{'start'}        @tab @var{s}  @tab\n\
+@item @tab @qcode{'end'}          @tab @var{e}  @tab\n\
+@item @tab @qcode{'tokenExtents'} @tab @var{te} @tab\n\
+@item @tab @qcode{'match'}        @tab @var{m}  @tab\n\
+@item @tab @qcode{'tokens'}       @tab @var{t}  @tab\n\
+@item @tab @qcode{'names'}        @tab @var{nm} @tab\n\
+@item @tab @qcode{'split'}        @tab @var{sp} @tab\n\
 @end multitable\n\
 \n\
 Additional arguments are summarized below.\n\
@@ -782,8 +782,8 @@
 @item emptymatch\n\
 Return zero-length matches.\n\
 \n\
-@code{regexp ('a', 'b*', 'emptymatch'} returns @code{[1 2]} because there are\n\
-zero or more 'b' characters at positions 1 and end-of-string.\n\
+@code{regexp ('a', 'b*', 'emptymatch')} returns @code{[1 2]} because there\n\
+are zero or more @qcode{'b'} characters at positions 1 and end-of-string.\n\
 \n\
 @end table\n\
 @seealso{regexpi, strfind, regexprep}\n\
@@ -925,7 +925,7 @@
 
 ## Tests for named tokens
 %!test
-%! # Parenthesis in named token (ie (int)) causes a problem
+%! ## Parenthesis in named token (ie (int)) causes a problem
 %! assert (regexp ('qwe int asd', ['(?<typestr>(int))'], 'names'), struct ('typestr', 'int'));
 
 %!test
@@ -1309,7 +1309,7 @@
 @end table\n\
 \n\
 Implementation Note: For compatibility with @sc{matlab}, ordinary escape\n\
-sequences (e.g., \"\\n\" => newline) are processed in both @var{pat}\n\
+sequences (e.g., @qcode{\"\\n\"} => newline) are processed in both @var{pat}\n\
 and @var{repstr} regardless of whether they were defined within single\n\
 quotes.  Use a second backslash to stop interpolation of the escape sequence\n\
 (e.g., \"\\\\n\") or use the @code{regexptranslate} function.\n\
--- a/libinterp/corefcn/schur.cc
+++ b/libinterp/corefcn/schur.cc
@@ -107,7 +107,8 @@
 blocks, when appropriate) are the eigenvalues of @var{A} and @var{S}.\n\
 \n\
 The default for real matrices is a real Schur@tie{}decomposition.\n\
-A complex decomposition may be forced by passing the flag \"complex\".\n\
+A complex decomposition may be forced by passing the flag\n\
+@qcode{\"complex\"}.\n\
 \n\
 The eigenvalues are optionally ordered along the diagonal according to\n\
 the value of @var{opt}.  @code{@var{opt} = \"a\"} indicates that all\n\
@@ -305,7 +306,7 @@
 $U^{\\dagger} U$ is the identity matrix I.\n\
 @end tex\n\
 @ifnottex\n\
-@xcode{@var{UR} * @var{TR} * @var{UR}' = @var{U} * @var{T} * @var{U}'} and\n\
+@tcode{@var{UR} * @var{TR} * @var{UR}' = @var{U} * @var{T} * @var{U}'} and\n\
 @code{@var{U}' * @var{U}} is the identity matrix I.\n\
 @end ifnottex\n\
 \n\
--- a/libinterp/corefcn/sighandlers.cc
+++ b/libinterp/corefcn/sighandlers.cc
@@ -908,9 +908,9 @@
 generated with @kbd{C-c}).  If a second interrupt signal is received\n\
 before reaching the debugging mode, a normal interrupt will occur.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{debug_on_error, debug_on_warning}\n\
 @end deftypefn")
 {
@@ -935,12 +935,12 @@
 @deftypefnx {Built-in Function} {@var{old_val} =} sighup_dumps_octave_core (@var{new_val})\n\
 @deftypefnx {Built-in Function} {} sighup_dumps_octave_core (@var{new_val}, \"local\")\n\
 Query or set the internal variable that controls whether Octave tries\n\
-to save all current variables to the file \"octave-workspace\" if it receives\n\
-a hangup signal.\n\
+to save all current variables to the file @file{octave-workspace} if it\n\
+receives a hangup signal.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core);
@@ -964,12 +964,12 @@
 @deftypefnx {Built-in Function} {@var{old_val} =} sigterm_dumps_octave_core (@var{new_val})\n\
 @deftypefnx {Built-in Function} {} sigterm_dumps_octave_core (@var{new_val}, \"local\")\n\
 Query or set the internal variable that controls whether Octave tries\n\
-to save all current variables to the file \"octave-workspace\" if it receives\n\
-a terminate signal.\n\
+to save all current variables to the file @file{octave-workspace} if it\n\
+receives a terminate signal.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core);
--- a/libinterp/corefcn/sparse.cc
+++ b/libinterp/corefcn/sparse.cc
@@ -91,8 +91,9 @@
 @end group\n\
 @end example\n\
 \n\
-Given the option \"unique\". if more than two values are specified for the\n\
-same @var{i}, @var{j} indices, the last specified value will be used.\n\
+Given the option @qcode{\"unique\"}, if more than two values are specified\n\
+for the same @var{i}, @var{j} indices, the last specified value will be\n\
+used.\n\
 \n\
 @code{sparse (@var{m}, @var{n})} is equivalent to\n\
 @code{sparse ([], [], [], @var{m}, @var{n}, 0)}\n\
--- a/libinterp/corefcn/spparms.cc
+++ b/libinterp/corefcn/spparms.cc
@@ -97,9 +97,9 @@
 The value of individual keys can be set with\n\
 @code{spparms (@var{key}, @var{val})}.\n\
 The default values can be restored with the special keyword\n\
-\"defaults\".  The special keyword \"tight\" can be used to set the mmd\n\
-solvers to attempt a sparser solution at the potential cost of longer\n\
-running time.\n\
+@qcode{\"defaults\"}.  The special keyword @qcode{\"tight\"} can be used to\n\
+set the mmd solvers to attempt a sparser solution at the potential cost of\n\
+longer running time.\n\
 @end deftypefn")
 {
   octave_value_list retval;
--- a/libinterp/corefcn/sqrtm.cc
+++ b/libinterp/corefcn/sqrtm.cc
@@ -272,5 +272,5 @@
 %! z = eye (4);  z(2,2) = z(3,3) = 2^-13;  z(1,4) = 0.5;
 %! [y, err] = sqrtm (x);
 %! assert (y, z);
-%! assert (err, 0);   ## Yes, this one has to hold exactly
+%! assert (err, 0);   # Yes, this one has to hold exactly
 */
--- a/libinterp/corefcn/str2double.cc
+++ b/libinterp/corefcn/str2double.cc
@@ -42,9 +42,11 @@
 is_imag_unit (int c)
 { return c == 'i' || c == 'j'; }
 
-static std::istringstream&
-single_num (std::istringstream& is, double& num)
+static double
+single_num (std::istringstream& is)
 {
+  double num;
+
   char c = is.peek ();
 
   // Skip spaces.
@@ -92,7 +94,7 @@
   else
     is >> num;
 
-  return is;
+  return num;
 }
 
 static std::istringstream&
@@ -114,10 +116,10 @@
   // Accept leading sign.
   if (c == '+' || c == '-')
     {
+      have_sign = true;
       negative = c == '-';
       is.get ();
       c = is.peek ();
-      have_sign = true;
     }
 
   // Skip spaces after sign.
@@ -138,13 +140,11 @@
         {
           // just 'i' and string is finished.  Return immediately.
           imag = true;
-          num = 1.0;
-          if (negative)
-            num = -num;
+          num = negative ? -1.0 : 1.0;
           return is;
         }
       else
-        { 
+        {
           if (std::tolower (c) != 'n')
             imag = true;
           is.unget ();
@@ -152,7 +152,7 @@
     }
   else if (c == 'j')
     imag = true;
-    
+
   // It's i*num or just i
   if (imag)
     {
@@ -169,7 +169,7 @@
         {
           // Multiplier follows, we extract it as a number.
           is.get ();
-          single_num (is, num);
+          num = single_num (is);
           if (is.good ())
             c = is.peek ();
         }
@@ -179,7 +179,7 @@
   else
     {
       // It's num, num*i, or numi.
-      single_num (is, num);
+      num = single_num (is);
       if (is.good ())
         {
           c = is.peek ();
@@ -265,10 +265,9 @@
 
   std::string str = str_arg;
 
-  // FIXME -- removing all commas does too much...
-  std::string::iterator se = str.end ();
-  se = std::remove (str.begin (), se, ',');
-  str.erase (se, str.end ());
+  // FIXME: removing all commas doesn't allow actual parsing.
+  //        Example: "1,23.45" is wrong, but passes Octave.
+  str.erase (std::remove (str.begin (), str.end(), ','), str.end ());
   std::istringstream is (str);
 
   double num;
@@ -300,7 +299,7 @@
 Convert a string to a real or complex number.\n\
 \n\
 The string must be in one of the following formats where\n\
-a and b are real numbers and the complex unit is 'i' or 'j':\n\
+a and b are real numbers and the complex unit is @qcode{'i'} or @qcode{'j'}:\n\
 \n\
 @itemize\n\
 @item a + bi\n\
@@ -317,17 +316,24 @@
 @end itemize\n\
 \n\
 If present, a and/or b are of the form @nospell{[+-]d[,.]d[[eE][+-]d]} where\n\
-the brackets indicate optional arguments and 'd' indicates zero or more\n\
-digits.  The special input values @code{Inf}, @code{NaN}, and @code{NA} are\n\
-also accepted.\n\
+the brackets indicate optional arguments and @qcode{'d'} indicates zero or\n\
+more digits.  The special input values @code{Inf}, @code{NaN}, and @code{NA}\n\
+are also accepted.\n\
 \n\
-@var{s} may also be a character matrix, in which case the conversion is\n\
-repeated for each row.  Or @var{s} may be a cell array of strings, in which\n\
-case each element is converted and an array of the same dimensions is\n\
-returned.\n\
+@var{s} may be a character string, character matrix, or cell array.\n\
+For character arrays the conversion is repeated for every row, and\n\
+a double or complex array is returned.  Empty rows in @var{s} are deleted\n\
+and not returned in the numeric array.  For cell arrays each character\n\
+string element is processed and a double or complex array of the same\n\
+dimensions as @var{s} is returned.\n\
 \n\
-@code{str2double} returns NaN for elements of @var{s} which cannot be\n\
-converted.\n\
+For unconvertible scalar or character string input @code{str2double} returns\n\
+a NaN@.  Similarly, for character array input @code{str2double} returns a\n\
+NaN for any row of @var{s} that could not be converted.  For a cell array,\n\
+@code{str2double} returns a NaN for any element of @var{s} for which\n\
+conversion fails.  Note that numeric elements in a mixed string/numeric\n\
+cell array are not strings and the conversion will fail for these elements\n\
+and return NaN.\n\
 \n\
 @code{str2double} can replace @code{str2num}, and it avoids the security\n\
 risk of using @code{eval} on unknown data.\n\
@@ -340,7 +346,11 @@
     print_usage ();
   else if (args(0).is_string ())
     {
-      if (args(0).rows () == 1 && args(0).ndims () == 2)
+      if (args(0).rows () == 0 || args(0).columns () == 0)
+        {
+          retval = Matrix (1, 1, octave_NaN);
+        }
+      else if (args(0).rows () == 1 && args(0).ndims () == 2)
         {
           retval = str2double1 (args(0).string_value ());
         }
@@ -367,7 +377,7 @@
       }
     }
   else
-    retval = NDArray (args(0).dims (), octave_NaN);
+    retval = Matrix (1, 1, octave_NaN);
 
 
   return retval;
@@ -377,7 +387,6 @@
 %!assert (str2double ("1"), 1)
 %!assert (str2double ("-.1e-5"), -1e-6)
 %!assert (str2double (char ("1", "2 3", "4i")), [1; NaN; 4i])
-%!assert (str2double ("-.1e-5"), -1e-6)
 %!assert (str2double ("1,222.5"), 1222.5)
 %!assert (str2double ("i"), i)
 %!assert (str2double ("2j"), 2i)
@@ -402,5 +411,8 @@
 %!assert (str2double ("-i*NaN - Inf"), complex (-Inf, -NaN))
 %!assert (str2double ({"abc", "4i"}), [NaN + 0i, 4i])
 %!assert (str2double ({2, "4i"}), [NaN + 0i, 4i])
-%!assert (str2double (zeros (3,1,2)), NaN (3,1,2))
-*/
+%!assert (str2double (zeros (3,1,2)), NaN)
+%!assert (str2double (''), NaN)
+%!assert (str2double ([]), NaN)
+%!assert (str2double (char(zeros(3,0))), NaN)
+ */
--- a/libinterp/corefcn/strfind.cc
+++ b/libinterp/corefcn/strfind.cc
@@ -149,20 +149,29 @@
   "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{idx} =} strfind (@var{str}, @var{pattern})\n\
 @deftypefnx {Built-in Function} {@var{idx} =} strfind (@var{cellstr}, @var{pattern})\n\
+@deftypefnx {Built-in Function} {@var{idx} =} strfind (@dots{}, \"overlaps\", @var{val})\n\
 Search for @var{pattern} in the string @var{str} and return the\n\
 starting index of every such occurrence in the vector @var{idx}.\n\
+\n\
 If there is no such occurrence, or if @var{pattern} is longer\n\
 than @var{str}, then @var{idx} is the empty array @code{[]}.\n\
+The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\
+can match at every position in @var{str} (true), or only for unique\n\
+occurrences of the complete pattern (false).  The default is true.\n\
 \n\
 If a cell array of strings @var{cellstr} is specified\n\
-then @var{idx} is a cell array of vectors, as specified\n\
-above.  Examples:\n\
+then @var{idx} is a cell array of vectors, as specified above.\n\
+\n\
+Examples:\n\
 \n\
 @example\n\
 @group\n\
 strfind (\"abababa\", \"aba\")\n\
      @result{} [1, 3, 5]\n\
 \n\
+strfind (\"abababa\", \"aba\", \"overlaps\", false)\n\
+     @result{} [1, 5]\n\
+\n\
 strfind (@{\"abababa\", \"bebebe\", \"ab\"@}, \"aba\")\n\
      @result{}\n\
         @{\n\
@@ -321,10 +330,20 @@
 
 DEFUN (strrep, args, ,
   "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} strrep (@var{s}, @var{ptn}, @var{rep})\n\
-@deftypefnx {Built-in Function} {} strrep (@var{s}, @var{ptn}, @var{rep}, \"overlaps\", @var{o})\n\
-Replace all occurrences of the substring @var{ptn} in the string @var{s}\n\
-with the string @var{rep} and return the result.  For example:\n\
+@deftypefn  {Built-in Function} {@var{newstr} =} strrep (@var{str}, @var{ptn}, @var{rep})\n\
+@deftypefnx {Built-in Function} {@var{newstr} =} strrep (@var{cellstr}, @var{ptn}, @var{rep})\n\
+@deftypefnx {Built-in Function} {@var{newstr} =} strrep (@dots{}, \"overlaps\", @var{val})\n\
+Replace all occurrences of the pattern @var{ptn} in the string @var{str}\n\
+with the string @var{rep} and return the result.\n\
+\n\
+The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\
+can match at every position in @var{str} (true), or only for unique\n\
+occurrences of the complete pattern (false).  The default is true.\n\
+\n\
+@var{s} may also be a cell array of strings, in which case the replacement is\n\
+done for each element and a cell array is returned.\n\
+\n\
+Example:\n\
 \n\
 @example\n\
 @group\n\
@@ -333,8 +352,6 @@
 @end group\n\
 @end example\n\
 \n\
-@var{s} may also be a cell array of strings, in which case the replacement is\n\
-done for each element and a cell array is returned.\n\
 @seealso{regexprep, strfind, findstr}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/svd.cc
+++ b/libinterp/corefcn/svd.cc
@@ -408,12 +408,12 @@
 @deftypefnx {Built-in Function} {@var{old_val} =} svd_driver (@var{new_val})\n\
 @deftypefnx {Built-in Function} {} svd_driver (@var{new_val}, \"local\")\n\
 Query or set the underlying @sc{lapack} driver used by @code{svd}.\n\
-Currently recognized values are \"gesvd\" and \"gesdd\".  The default\n\
-is \"gesvd\".\n\
+Currently recognized values are @qcode{\"gesvd\"} and @qcode{\"gesdd\"}.  \n\
+The default is @qcode{\"gesvd\"}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{svd}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/symtab.cc
+++ b/libinterp/corefcn/symtab.cc
@@ -1527,14 +1527,14 @@
 @deftypefnx {Built-in Function} {@var{old_val} =} ignore_function_time_stamp (@var{new_val})\n\
 Query or set the internal variable that controls whether Octave checks\n\
 the time stamp on files each time it looks up functions defined in\n\
-function files.  If the internal variable is set to @code{\"system\"},\n\
+function files.  If the internal variable is set to @qcode{\"system\"},\n\
 Octave will not automatically recompile function files in subdirectories of\n\
 @file{@var{octave-home}/lib/@var{version}} if they have changed since\n\
 they were last compiled, but will recompile other function files in the\n\
-search path if they change.  If set to @code{\"all\"}, Octave will not\n\
+search path if they change.  If set to @qcode{\"all\"}, Octave will not\n\
 recompile any function files unless their definitions are removed with\n\
-@code{clear}.  If set to \"none\", Octave will always check time stamps\n\
-on files to determine whether functions defined in function files\n\
+@code{clear}.  If set to @qcode{\"none\"}, Octave will always check time\n\
+stamps on files to determine whether functions defined in function files\n\
 need to recompiled.\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/syscalls.cc
+++ b/libinterp/corefcn/syscalls.cc
@@ -38,6 +38,7 @@
 
 #include <fcntl.h>
 
+#include "cmd-hist.h"
 #include "file-ops.h"
 #include "file-stat.h"
 #include "oct-env.h"
@@ -48,6 +49,7 @@
 #include "error.h"
 #include "gripes.h"
 #include "lo-utils.h"
+#include "oct-hist.h"
 #include "oct-map.h"
 #include "oct-obj.h"
 #include "oct-stdstrm.h"
@@ -220,6 +222,11 @@
 
           if (! error_state)
             {
+              octave_history_write_timestamp ();
+
+              if (! command_history::ignoring_entries ())
+                command_history::clean_up_and_save ();
+
               std::string msg;
 
               int status = octave_syscalls::execvp (exec_file, exec_args, msg);
@@ -276,7 +283,7 @@
    @print{} are\n\
 @end example\n\
 \n\
-Note that @code{popen2}, unlike @code{popen}, will not \"reap\" the\n\
+Note that @code{popen2}, unlike @code{popen}, will not @qcode{\"reap\"} the\n\
 child process.  If you don't use @code{waitpid} to check the child's\n\
 exit status, it will linger until Octave exits.\n\
 @end deftypefn")
@@ -742,11 +749,13 @@
 
 DEFUNX ("lstat", Flstat, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{symlink})\n\
+@deftypefn  {Built-in Function} {@var{info} =} lstat (@var{symlink})\n\
+@deftypefnx {Built-in Function} {[@var{info}, @var{err}, @var{msg}] =} lstat (@var{symlink})\n\
 Return a structure @var{info} containing information about the symbolic link\n\
-@var{symlink}.  The function outputs are described in the documentation for\n\
-@code{stat}.\n\
-@seealso{stat}\n\
+@var{symlink}.\n\
+\n\
+The function outputs are described in the documentation for @code{stat}.\n\
+@seealso{stat, symlink}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -770,12 +779,14 @@
 
 DEFUNX ("mkfifo", Fmkfifo, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\
-Create a @var{fifo} special file named @var{name} with file mode @var{mode}\n\
+@deftypefn  {Built-in Function} {} mkfifo (@var{name}, @var{mode})\n\
+@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} mkfifo (@var{name}, @var{mode})\n\
+Create a FIFO special file named @var{name} with file mode @var{mode}\n\
 \n\
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
+@seealso{pipe}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -830,6 +841,7 @@
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
+@seealso{mkfifo}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -893,9 +905,9 @@
 \n\
 @item mode\n\
 File mode, as an integer.  Use the functions @w{@code{S_ISREG}},\n\
-@w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}}, @w{@code{S_ISFIFO}},\n\
-@w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract information from this\n\
-value.\n\
+@w{@code{S_ISDIR}}, @w{@code{S_ISCHR}}, @w{@code{S_ISBLK}},\n\
+@w{@code{S_ISFIFO}}, @w{@code{S_ISLNK}}, or @w{@code{S_ISSOCK}} to extract\n\
+information from this value.\n\
 \n\
 @item modestr\n\
 File mode, as a string of ten letters or dashes as would be returned by\n\
@@ -968,6 +980,7 @@
   @result{} err = 0\n\
   @result{} msg =\n\
 @end example\n\
+@seealso{lstat, ls, dir}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1006,8 +1019,9 @@
 DEFUNX ("S_ISREG", FS_ISREG, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISREG (@var{mode})\n\
-Return true if @var{mode} corresponds to a regular file.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a regular file.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1031,8 +1045,9 @@
 DEFUNX ("S_ISDIR", FS_ISDIR, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISDIR (@var{mode})\n\
-Return true if @var{mode} corresponds to a directory.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a directory.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1056,8 +1071,9 @@
 DEFUNX ("S_ISCHR", FS_ISCHR, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISCHR (@var{mode})\n\
-Return true if @var{mode} corresponds to a character device.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a character device.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1081,8 +1097,9 @@
 DEFUNX ("S_ISBLK", FS_ISBLK, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISBLK (@var{mode})\n\
-Return true if @var{mode} corresponds to a block device.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a block device.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1106,8 +1123,9 @@
 DEFUNX ("S_ISFIFO", FS_ISFIFO, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISFIFO (@var{mode})\n\
-Return true if @var{mode} corresponds to a fifo.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a fifo.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1131,8 +1149,9 @@
 DEFUNX ("S_ISLNK", FS_ISLNK, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISLNK (@var{mode})\n\
-Return true if @var{mode} corresponds to a symbolic link.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a symbolic link.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
@@ -1156,8 +1175,9 @@
 DEFUNX ("S_ISSOCK", FS_ISSOCK, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} S_ISSOCK (@var{mode})\n\
-Return true if @var{mode} corresponds to a socket.  The value\n\
-of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
+Return true if @var{mode} corresponds to a socket.\n\
+\n\
+The value of @var{mode} is assumed to be returned from a call to @code{stat}.\n\
 @seealso{stat, lstat}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/toplev.cc
+++ b/libinterp/corefcn/toplev.cc
@@ -916,11 +916,11 @@
 @deftypefnx {Built-in Function} {} system (\"@var{string}\", @var{return_output}, @var{type})\n\
 @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} system (@dots{})\n\
 Execute a shell command specified by @var{string}.\n\
-If the optional argument @var{type} is \"async\", the process\n\
+If the optional argument @var{type} is @qcode{\"async\"}, the process\n\
 is started in the background and the process ID of the child process\n\
 is returned immediately.  Otherwise, the child process is started and\n\
 Octave waits until it exits.  If the @var{type} argument is omitted, it\n\
-defaults to the value \"sync\".\n\
+defaults to the value @qcode{\"sync\"}.\n\
 \n\
 If @var{system} is called with one or more output arguments, or if the\n\
 optional argument @var{return_output} is true and the subprocess is started\n\
@@ -1142,7 +1142,7 @@
 @end example\n\
 \n\
 @noindent\n\
-will print the message \"Bye bye\" when Octave exits.\n\
+will print the message @qcode{\"Bye bye\"} when Octave exits.\n\
 \n\
 The additional argument @var{flag} will register or unregister\n\
 @var{fcn} from the list of functions to be called when Octave\n\
--- a/libinterp/corefcn/tril.cc
+++ b/libinterp/corefcn/tril.cc
@@ -386,9 +386,9 @@
 @end group\n\
 @end example\n\
 \n\
-If the option \"pack\" is given as third argument, the extracted elements\n\
-are not inserted into a matrix, but rather stacked column-wise one above\n\
-other.\n\
+If the option @qcode{\"pack\"} is given as third argument, the extracted\n\
+elements are not inserted into a matrix, but rather stacked column-wise one\n\
+above other.\n\
 @seealso{diag}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/txt-eng-ft.cc
+++ b/libinterp/corefcn/txt-eng-ft.cc
@@ -30,7 +30,11 @@
 #include <fontconfig/fontconfig.h>
 #endif
 
+#include <clocale>
+#include <cwchar>
 #include <iostream>
+#include <map>
+#include <utility>
 
 #include "singleton-cleanup.h"
 
@@ -38,33 +42,36 @@
 #include "pr-output.h"
 #include "txt-eng-ft.h"
 
-// FIXME -- maybe issue at most one warning per glyph/font/size/weight
-// combination.
+// FIXME: maybe issue at most one warning per glyph/font/size/weight
+//        combination.
 
 static void
-gripe_missing_glyph (char c)
+gripe_missing_glyph (FT_ULong c)
 {
   warning_with_id ("Octave:missing-glyph",
-                   "ft_render: skipping missing glyph for character '%c'",
+                   "ft_render: skipping missing glyph for character '%x'",
                    c);
 }
 
 static void
-gripe_glyph_render (char c)
+gripe_glyph_render (FT_ULong c)
 {
   warning_with_id ("Octave:glyph-render",
-                   "ft_render: unable to render glyph for character '%c'",
+                   "ft_render: unable to render glyph for character '%x'",
                    c);
 }
 
 #ifdef _MSC_VER
-// This is just a trick to avoid multiply symbols definition.
+// This is just a trick to avoid multiple symbol definitions.
 // PermMatrix.h contains a dllexport'ed Array<octave_idx_type>
-// that will make MSVC not to generate new instantiation and
-// use the imported one.
+// that will cause MSVC not to generate a new instantiation and
+// use the imported one instead.
 #include "PermMatrix.h"
 #endif
 
+// Forward declaration
+static void ft_face_destroyed (void* object);
+
 class
 ft_manager
 {
@@ -99,10 +106,24 @@
               ? instance->do_get_font (name, weight, angle, size)
               : 0); }
 
+  static void font_destroyed (FT_Face face)
+    {
+      if (instance_ok ())
+        instance->do_font_destroyed (face);
+    }
+
 private:
 
   static ft_manager *instance;
 
+  typedef std::pair<std::string, double> ft_key;
+  typedef std::map<ft_key, FT_Face> ft_cache;
+
+  // Cache the fonts loaded by freetype. This cache only contains
+  // weak references to the fonts, strong references are only present
+  // in class ft_render.
+  ft_cache cache;
+
 private:
 
   // No copying!
@@ -133,8 +154,7 @@
         FT_Done_FreeType (library);
 
 #if defined (HAVE_FONTCONFIG)
-      // FIXME -- Skip the call to FcFini because it can trigger the
-      // assertion
+      // FIXME: Skip the call to FcFini because it can trigger the assertion
       //
       //   octave: fccache.c:507: FcCacheFini: Assertion 'fcCacheChains[i] == ((void *)0)' failed.
       //
@@ -149,6 +169,20 @@
     {
       FT_Face retval = 0;
 
+#if HAVE_FT_REFERENCE_FACE
+      // Look first into the font cache, then use fontconfig. If the font
+      // is present in the cache, simply add a reference and return it.
+
+      ft_key key (name + ":" + weight + ":" + angle, size);
+      ft_cache::const_iterator it = cache.find (key);
+
+      if (it != cache.end ())
+        {
+          FT_Reference_Face (it->second);
+          return it->second;
+        }
+#endif
+
       std::string file;
 
 #if defined (HAVE_FONTCONFIG)
@@ -190,7 +224,7 @@
               FcDefaultSubstitute (pat);
               match = FcFontMatch (0, pat, &res);
 
-              // FIXME -- originally, this test also required that
+              // FIXME: originally, this test also required that
               // res != FcResultNoMatch.  Is that really needed?
               if (match)
                 {
@@ -221,12 +255,42 @@
 #endif
         }
 
-      if (! file.empty () && FT_New_Face (library, file.c_str (), 0, &retval))
-        ::warning ("ft_manager: unable to load font: %s", file.c_str ());
+      if (! file.empty ())
+        {
+          if (FT_New_Face (library, file.c_str (), 0, &retval))
+            ::warning ("ft_manager: unable to load font: %s", file.c_str ());
+#if HAVE_FT_REFERENCE_FACE
+          else
+            {
+              // Install a finalizer to notify ft_manager that the font is
+              // being destroyed. The class ft_manager only keeps weak
+              // references to font objects.
+
+              retval->generic.data = new ft_key (key);
+              retval->generic.finalizer = ft_face_destroyed;
+
+              // Insert loaded font into the cache.
+
+              cache[key] = retval;
+            }
+#endif
+        }
 
       return retval;
     }
 
+  void do_font_destroyed (FT_Face face)
+    {
+      if (face->generic.data)
+        {
+          ft_key* pkey = reinterpret_cast<ft_key*> (face->generic.data);
+
+          cache.erase (*pkey);
+          delete pkey;
+          face->generic.data = 0;
+        }
+    }
+
 private:
   FT_Library library;
   bool freetype_initialized;
@@ -235,39 +299,164 @@
 
 ft_manager* ft_manager::instance = 0;
 
+static void
+ft_face_destroyed (void* object)
+{ ft_manager::font_destroyed (reinterpret_cast<FT_Face> (object)); }
+
 // ---------------------------------------------------------------------------
 
 ft_render::ft_render (void)
-    : text_processor (), face (0), bbox (1, 4, 0.0),
-      xoffset (0), yoffset (0), multiline_halign (0),
-      multiline_align_xoffsets (), mode (MODE_BBOX),
-      red (0), green (0), blue (0)
+    : text_processor (), font (), bbox (1, 4, 0.0), halign (0), xoffset (0),
+      line_yoffset (0), yoffset (0), mode (MODE_BBOX),
+      color (dim_vector (1, 3), 0)
 {
 }
 
 ft_render::~ft_render (void)
 {
-  if (face)
-    FT_Done_Face (face);
 }
 
 void
 ft_render::set_font (const std::string& name, const std::string& weight,
                      const std::string& angle, double size)
 {
-  if (face)
-    FT_Done_Face (face);
+  // FIXME: take "fontunits" into account
+
+  font = ft_font (name, weight, angle, size, 0);
+}
+
+void
+ft_render::push_new_line (void)
+{
+  switch (mode)
+    {
+    case MODE_BBOX:
+        {
+          // Create a new bbox entry based on the current font.
+
+          FT_Face face = font.get_face ();
+
+          if (face)
+            {
+              int asc = face->size->metrics.ascender >> 6;
+              int desc = face->size->metrics.descender >> 6;
+              int h = face->size->metrics.height >> 6;
+
+              Matrix bb (1, 5, 0.0);
+
+              bb(1) = desc;
+              bb(3) = asc - desc;
+              bb(4) = h;
+
+              line_bbox.push_back (bb);
 
-  // FIXME: take "fontunits" into account
-  face = ft_manager::get_font (name, weight, angle, size);
+              xoffset = yoffset = 0;
+            }
+        }
+      break;
+
+    case MODE_RENDER:
+        {
+          // Move to the next line bbox, adjust xoffset based on alignment
+          // and yoffset based on the old and new line bbox.
+
+          Matrix old_bbox = line_bbox.front ();
+          line_bbox.pop_front ();
+          Matrix new_bbox = line_bbox.front ();
+
+          xoffset = compute_line_xoffset (new_bbox);
+          line_yoffset += (old_bbox(1) - (new_bbox(1) + new_bbox(3)));
+          yoffset = 0;
+        }
+      break;
+    }
+}
+
+int
+ft_render::compute_line_xoffset (const Matrix& lb) const
+{
+  if (! bbox.is_empty ())
+    {
+      switch (halign)
+        {
+        case 0:
+          return 0;
+        case 1:
+          return (bbox(2) - lb(2)) / 2;
+        case 2:
+          return (bbox(2) - lb(2));
+        }
+    }
 
-  if (face)
+  return 0;
+}
+
+void
+ft_render::compute_bbox (void)
+{
+  // Stack the various line bbox together and compute the final
+  // bounding box for the entire text string.
+
+  bbox = Matrix ();
+
+  switch (line_bbox.size ())
     {
-      if (FT_Set_Char_Size (face, 0, size*64, 0, 0))
-        ::warning ("ft_render: unable to set font size to %d", size);
+    case 0:
+      break;
+    case 1:
+      bbox = line_bbox.front ().extract (0, 0, 0, 3);
+      break;
+    default:
+      for (std::list<Matrix>::const_iterator it = line_bbox.begin ();
+           it != line_bbox.end (); ++it)
+        {
+          if (bbox.is_empty ())
+            bbox = it->extract (0, 0, 0, 3);
+          else
+            {
+              bbox(1) -= (*it)(3);
+              bbox(3) += (*it)(3);
+              bbox(2) = xmax (bbox(2), (*it)(2));
+            }
+        }
+      break;
     }
-  else
-    ::warning ("ft_render: unable to load appropriate font");
+}
+
+void
+ft_render::update_line_bbox (void)
+{
+  // Called after a font change, when in MODE_BBOX mode, to update the
+  // current line bbox with the new font metrics. This also includes the
+  // current yoffset, that is the offset of the current glyph's baseline
+  // the line's baseline.
+
+  if (mode == MODE_BBOX)
+    {
+      int asc = font.get_face ()->size->metrics.ascender >> 6;
+      int desc = font.get_face ()->size->metrics.descender >> 6;
+
+      Matrix& bb = line_bbox.front ();
+
+      if ((yoffset + desc) < bb(1))
+        {
+          // The new font goes below the bottom of the current bbox.
+
+          int delta = bb(1) - (yoffset + desc);
+
+          bb(1) -= delta;
+          bb(3) += delta;
+        }
+
+      if ((yoffset + asc) > (bb(1) + bb(3)))
+        {
+          // The new font goes above the top of the current bbox.
+
+          int delta = (yoffset + asc) - (bb(1) + bb(3));
+
+          bb(3) += delta;
+        }
+    }
 }
 
 void
@@ -278,23 +467,26 @@
   switch (mode)
     {
     case MODE_BBOX:
-      xoffset = yoffset = 0;
+      xoffset = line_yoffset = yoffset = 0;
       bbox = Matrix (1, 4, 0.0);
+      line_bbox.clear ();
+      push_new_line ();
       break;
     case MODE_RENDER:
       if (bbox.numel () != 4)
         {
           ::warning ("ft_render: invalid bounding box, cannot render");
 
-          xoffset = yoffset = 0;
+          xoffset = line_yoffset = yoffset = 0;
           pixels = uint8NDArray ();
         }
       else
         {
           pixels = uint8NDArray (dim_vector (4, bbox(2), bbox(3)),
                                  static_cast<uint8_t> (0));
-          xoffset = 0;
-          yoffset = -bbox(1)-1;
+          xoffset = compute_line_xoffset (line_bbox.front ());
+          line_yoffset = -bbox(1)-1;
+          yoffset = 0;
         }
       break;
     default:
@@ -303,187 +495,335 @@
     }
 }
 
+FT_UInt
+ft_render::process_character (FT_ULong code, FT_UInt previous)
+{
+  FT_Face face = font.get_face ();
+  FT_UInt glyph_index = 0;
+
+  if (face)
+    {
+      glyph_index = FT_Get_Char_Index (face, code);
+
+      if (code != '\n'
+          && (! glyph_index
+              || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)))
+        {
+          glyph_index = 0;
+          gripe_missing_glyph (code);
+        }
+      else
+        {
+          switch (mode)
+            {
+            case MODE_RENDER:
+              if (code == '\n')
+                {
+                  glyph_index = FT_Get_Char_Index (face, ' ');
+                  if (!glyph_index || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
+                    {
+                      glyph_index = 0;
+                      gripe_missing_glyph (' ');
+                    }
+                  else
+                    push_new_line ();
+                }
+              else if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL))
+                {
+                  glyph_index = 0;
+                  gripe_glyph_render (code);
+                }
+              else
+                {
+                  FT_Bitmap& bitmap = face->glyph->bitmap;
+                  int x0, y0;
+
+                  if (previous)
+                    {
+                      FT_Vector delta;
+
+                      FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
+                      xoffset += (delta.x >> 6);
+                    }
+
+                  x0 = xoffset + face->glyph->bitmap_left;
+                  y0 = line_yoffset + yoffset + face->glyph->bitmap_top;
+
+                  // 'w' seems to have a negative -1
+                  // face->glyph->bitmap_left, this is so we don't
+                  // index out of bound, and assumes we we allocated
+                  // the right amount of horizontal space in the bbox.
+                  if (x0 < 0)
+                    x0 = 0;
+
+                  for (int r = 0; r < bitmap.rows; r++)
+                    for (int c = 0; c < bitmap.width; c++)
+                      {
+                        unsigned char pix = bitmap.buffer[r*bitmap.width+c];
+                        if (x0+c < 0 || x0+c >= pixels.dim2 ()
+                            || y0-r < 0 || y0-r >= pixels.dim3 ())
+                          {
+                            //::warning ("ft_render: pixel out of bound (char=%d, (x,y)=(%d,%d), (w,h)=(%d,%d)",
+                            //           str[i], x0+c, y0-r, pixels.dim2 (), pixels.dim3 ());
+                          }
+                        else if (pixels(3, x0+c, y0-r).value () == 0)
+                          {
+                            pixels(0, x0+c, y0-r) = color(0);
+                            pixels(1, x0+c, y0-r) = color(1);
+                            pixels(2, x0+c, y0-r) = color(2);
+                            pixels(3, x0+c, y0-r) = pix;
+                          }
+                      }
+
+                  xoffset += (face->glyph->advance.x >> 6);
+                }
+              break;
+
+            case MODE_BBOX:
+              if (code == '\n')
+                {
+                  glyph_index = FT_Get_Char_Index (face, ' ');
+                  if (! glyph_index
+                      || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
+                    {
+                      glyph_index = 0;
+                      gripe_missing_glyph (' ');
+                    }
+                  else
+                    push_new_line ();
+                }
+              else
+                {
+                  Matrix& bb = line_bbox.back ();
+
+                  // If we have a previous glyph, use kerning information.
+                  // This usually means moving a bit backward before adding
+                  // the next glyph. That is, "delta.x" is usually < 0.
+                  if (previous)
+                    {
+                      FT_Vector delta;
+
+                      FT_Get_Kerning (face, previous, glyph_index,
+                                      FT_KERNING_DEFAULT, &delta);
+
+                      xoffset += (delta.x >> 6);
+                    }
+
+                  // Extend current X offset box by the width of the current
+                  // glyph. Then extend the line bounding box if necessary.
+
+                  xoffset += (face->glyph->advance.x >> 6);
+                  bb(2) = xmax (bb(2), xoffset);
+                }
+              break;
+            }
+        }
+    }
+
+  return glyph_index;
+}
+
 void
 ft_render::visit (text_element_string& e)
 {
-  if (face)
+  if (font.is_valid ())
     {
-      int line_index = 0;
-      FT_UInt box_line_width = 0;
-      std::string str = e.string_value ();
       FT_UInt glyph_index, previous = 0;
 
-      if (mode == MODE_BBOX)
-        multiline_align_xoffsets.clear ();
-      else if (mode == MODE_RENDER)
-        xoffset += multiline_align_xoffsets[line_index];
+      std::string str = e.string_value ();
+      size_t n = str.length (), curr = 0;
+      mbstate_t ps;
+      memset (&ps, 0, sizeof (ps));  // Initialize state to 0.
+      wchar_t wc;
 
-      for (size_t i = 0; i < str.length (); i++)
+      while (n > 0)
         {
-          glyph_index = FT_Get_Char_Index (face, str[i]);
+          size_t r = gnulib::mbrtowc (&wc, str.data () + curr, n, &ps);
 
-          if (str[i] != '\n'
-              && (! glyph_index
-              || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT)))
-            gripe_missing_glyph (str[i]);
+          if (r > 0
+              && r != static_cast<size_t> (-1)
+              && r != static_cast<size_t> (-2))
+            {
+              n -= r;
+              curr += r;
+
+              glyph_index = process_character (wc, previous);
+
+              if (wc == L'\n')
+                previous = 0;
+              else
+                previous = glyph_index;
+            }
           else
             {
-              switch (mode)
-                {
-                case MODE_RENDER:
-                  if (str[i] == '\n')
-                    {
-                    glyph_index = FT_Get_Char_Index (face, ' ');
-                    if (!glyph_index || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
-                      {
-                        gripe_missing_glyph (' ');
-                      }
-                    else
-                      {
-                        line_index++;
-                        xoffset = multiline_align_xoffsets[line_index];
-                        yoffset -= (face->size->metrics.height >> 6);
-                      }
-                    }
-                  else if (FT_Render_Glyph (face->glyph, FT_RENDER_MODE_NORMAL))
-                    {
-                      gripe_glyph_render (str[i]);
-                    }
-                  else
-                    {
-                      FT_Bitmap& bitmap = face->glyph->bitmap;
-                      int x0, y0;
-
-                      if (previous)
-                        {
-                          FT_Vector delta;
-
-                          FT_Get_Kerning (face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
-                          xoffset += (delta.x >> 6);
-                        }
-
-                      x0 = xoffset+face->glyph->bitmap_left;
-                      y0 = yoffset+face->glyph->bitmap_top;
-
-                      // 'w' seems to have a negative -1
-                      // face->glyph->bitmap_left, this is so we don't
-                      // index out of bound, and assumes we we allocated
-                      // the right amount of horizontal space in the bbox.
-                      if (x0 < 0)
-                        x0 = 0;
-
-                      for (int r = 0; r < bitmap.rows; r++)
-                        for (int c = 0; c < bitmap.width; c++)
-                          {
-                            unsigned char pix = bitmap.buffer[r*bitmap.width+c];
-                            if (x0+c < 0 || x0+c >= pixels.dim2 ()
-                                || y0-r < 0 || y0-r >= pixels.dim3 ())
-                              {
-                                //::error ("out-of-bound indexing!!");
-                              }
-                            else if (pixels(3, x0+c, y0-r).value () == 0)
-                              {
-                                pixels(0, x0+c, y0-r) = red;
-                                pixels(1, x0+c, y0-r) = green;
-                                pixels(2, x0+c, y0-r) = blue;
-                                pixels(3, x0+c, y0-r) = pix;
-                              }
-                          }
-
-                      xoffset += (face->glyph->advance.x >> 6);
-                    }
-                  break;
-
-                case MODE_BBOX:
-                  if (str[i] == '\n')
-                    {
-                      glyph_index = FT_Get_Char_Index (face, ' ');
-                      if (! glyph_index
-                          || FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT))
-                      {
-                        gripe_missing_glyph (' ');
-                      }
-                    else
-                      {
-                        multiline_align_xoffsets.push_back (box_line_width);
-                        // Reset the pixel width for this newline, so we don't
-                        // allocate a bounding box larger than the horizontal
-                        // width of the multi-line
-                        box_line_width = 0;
-                        bbox(1) -= (face->size->metrics.height >> 6);
-                      }
-                    }
-                  else
-                    {
-                    // width
-                    if (previous)
-                      {
-                        FT_Vector delta;
-
-                        FT_Get_Kerning (face, previous, glyph_index,
-                                        FT_KERNING_DEFAULT, &delta);
-
-                        box_line_width += (delta.x >> 6);
-                      }
-
-                    box_line_width += (face->glyph->advance.x >> 6);
-
-                    int asc, desc;
-
-                    if (false /*tight*/)
-                      {
-                        desc = face->glyph->metrics.horiBearingY - face->glyph->metrics.height;
-                        asc = face->glyph->metrics.horiBearingY;
-                      }
-                    else
-                      {
-                        asc = face->size->metrics.ascender;
-                        desc = face->size->metrics.descender;
-                      }
-
-                    asc = yoffset + (asc >> 6);
-                    desc = yoffset + (desc >> 6);
-
-                    if (desc < bbox(1))
-                      {
-                        bbox(3) += (bbox(1) - desc);
-                        bbox(1) = desc;
-                      }
-                    if (asc > (bbox(3)+bbox(1)))
-                      bbox(3) = asc-bbox(1);
-                    if (bbox(2) < box_line_width)
-                      bbox(2) = box_line_width;
-                  }
-                  break;
-                }
-                if (str[i] == '\n')
-                  previous = 0;
-                else
-                  previous = glyph_index;
-            }
-        }
-      if (mode == MODE_BBOX)
-        {
-          /* Push last the width associated with the last line */
-          multiline_align_xoffsets.push_back (box_line_width);
-
-          for (unsigned int i = 0; i < multiline_align_xoffsets.size (); i++)
-            {
-            /* Center align */
-            if (multiline_halign == 1)
-              multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i])/2;
-            /* Right align */
-            else if (multiline_halign == 2)
-              multiline_align_xoffsets[i] = (bbox(2) - multiline_align_xoffsets[i]);
-            /* Left align */
-            else
-              multiline_align_xoffsets[i] = 0;
+              if (r != 0)
+                ::warning ("ft_render: failed to decode string `%s' with "
+                           "locale `%s'", str.c_str (),
+                           std::setlocale (LC_CTYPE, NULL));
+              break;
             }
         }
     }
 }
 
 void
+ft_render::visit (text_element_list& e)
+{
+  // Save and restore (after processing the list) the current font and color.
+
+  ft_font saved_font (font);
+  uint8NDArray saved_color (color);
+
+  text_processor::visit (e);
+
+  font = saved_font;
+  color = saved_color;
+}
+
+void
+ft_render::visit (text_element_subscript& e)
+{
+  ft_font saved_font (font);
+  int saved_line_yoffset = line_yoffset;
+  int saved_yoffset = yoffset;
+
+  set_font (font.get_name (), font.get_weight (), font.get_angle (),
+            font.get_size () - 2);
+
+  if (font.is_valid ())
+    {
+      int h = font.get_face ()->size->metrics.height >> 6;
+
+      // Shifting the baseline by 2/3 the font height seems to produce
+      // decent result.
+      yoffset -= (h * 2) / 3;
+
+      if (mode == MODE_BBOX)
+        update_line_bbox ();
+    }
+
+  text_processor::visit (e);
+
+  font = saved_font;
+  // If line_yoffset changed, this means we moved to a new line; hence yoffset
+  // cannot be restored, because the saved value is not relevant anymore.
+  if (line_yoffset == saved_line_yoffset)
+    yoffset = saved_yoffset;
+}
+
+void
+ft_render::visit (text_element_superscript& e)
+{
+  ft_font saved_font (font);
+  int saved_line_yoffset = line_yoffset;
+  int saved_yoffset = yoffset;
+
+  set_font (font.get_name (), font.get_weight (), font.get_angle (),
+            font.get_size () - 2);
+
+  if (saved_font.is_valid ())
+    {
+      int s_asc = saved_font.get_face ()->size->metrics.ascender >> 6;
+
+      // Shifting the baseline by 2/3 base font ascender seems to produce
+      // decent result.
+      yoffset += (s_asc * 2) / 3;
+
+      if (mode == MODE_BBOX)
+        update_line_bbox ();
+    }
+
+  text_processor::visit (e);
+
+  font = saved_font;
+  // If line_yoffset changed, this means we moved to a new line; hence yoffset
+  // cannot be restored, because the saved value is not relevant anymore.
+  if (line_yoffset == saved_line_yoffset)
+    yoffset = saved_yoffset;
+}
+
+void
+ft_render::visit (text_element_color& e)
+{
+  if (mode == MODE_RENDER)
+    set_color (e.get_color ());
+}
+
+void
+ft_render::visit (text_element_fontsize& e)
+{
+  double sz = e.get_fontsize ();
+
+  // FIXME: Matlab documentation says that the font size is expressed
+  //        in the text object FontUnit.
+
+  set_font (font.get_name (), font.get_weight (), font.get_angle (), sz);
+
+  if (mode == MODE_BBOX)
+    update_line_bbox ();
+}
+
+void
+ft_render::visit (text_element_fontname& e)
+{
+  set_font (e.get_fontname (), font.get_weight (), font.get_angle (),
+            font.get_size ());
+
+  if (mode == MODE_BBOX)
+    update_line_bbox ();
+}
+
+void
+ft_render::visit (text_element_fontstyle& e)
+{
+  switch (e.get_fontstyle ())
+    {
+    case text_element_fontstyle::normal:
+      set_font (font.get_name (), "normal", "normal", font.get_size ());
+      break;
+    case text_element_fontstyle::bold:
+      set_font (font.get_name (), "bold", "normal", font.get_size ());
+      break;
+    case text_element_fontstyle::italic:
+      set_font (font.get_name (), "normal", "italic", font.get_size ());
+      break;
+    case text_element_fontstyle::oblique:
+      set_font (font.get_name (), "normal", "oblique", font.get_size ());
+      break;
+    }
+
+  if (mode == MODE_BBOX)
+    update_line_bbox ();
+}
+
+void
+ft_render::visit (text_element_symbol& e)
+{
+  uint32_t code = e.get_symbol_code ();
+
+  if (code != text_element_symbol::invalid_code && font.is_valid ())
+    process_character (code);
+  else if (font.is_valid ())
+    ::warning ("ignoring unknown symbol: %d", e.get_symbol ());
+}
+
+void
+ft_render::visit (text_element_combined& e)
+{
+  int saved_xoffset = xoffset;
+  int max_xoffset = xoffset;
+
+  for (text_element_combined::iterator it = e.begin (); it != e.end (); ++it)
+    {
+      xoffset = saved_xoffset;
+      (*it)->accept (*this);
+      max_xoffset = xmax (xoffset, max_xoffset);
+    }
+
+  xoffset = max_xoffset;
+}
+
+void
 ft_render::reset (void)
 {
   set_mode (MODE_BBOX);
@@ -495,9 +835,9 @@
 {
   if (c.numel () == 3)
     {
-      red = static_cast<uint8_t> (c(0)*255);
-      green = static_cast<uint8_t> (c(1)*255);
-      blue = static_cast<uint8_t> (c(2)*255);
+      color(0) = static_cast<uint8_t> (c(0)*255);
+      color(1) = static_cast<uint8_t> (c(1)*255);
+      color(2) = static_cast<uint8_t> (c(2)*255);
     }
   else
     ::warning ("ft_render::set_color: invalid color");
@@ -508,6 +848,7 @@
 {
   set_mode (MODE_BBOX);
   elt->accept (*this);
+  compute_bbox ();
   box = bbox;
 
   set_mode (MODE_RENDER);
@@ -574,6 +915,7 @@
 {
   set_mode (MODE_BBOX);
   elt->accept (*this);
+  compute_bbox ();
 
   Matrix extent (1, 2, 0.0);
 
@@ -594,9 +936,10 @@
 }
 
 Matrix
-ft_render::get_extent (const std::string& txt, double rotation)
+ft_render::get_extent (const std::string& txt, double rotation,
+                       const caseless_str& interpreter)
 {
-  text_element *elt = text_parser_none ().parse (txt);
+  text_element *elt = text_parser::parse (txt, interpreter);
   Matrix extent = get_extent (elt, rotation);
   delete elt;
 
@@ -621,14 +964,15 @@
 void
 ft_render::text_to_pixels (const std::string& txt,
                            uint8NDArray& pixels_, Matrix& box,
-                           int halign, int valign, double rotation)
+                           int _halign, int valign, double rotation,
+                           const caseless_str& interpreter)
 {
   // FIXME: clip "rotation" between 0 and 360
   int rot_mode = rotation_to_mode (rotation);
 
-  multiline_halign = halign;
+  halign = _halign;
 
-  text_element *elt = text_parser_none ().parse (txt);
+  text_element *elt = text_parser::parse (txt, interpreter);
   pixels_ = render (elt, box, rot_mode);
   delete elt;
 
@@ -672,4 +1016,61 @@
     }
 }
 
+ft_render::ft_font::ft_font (const ft_font& ft)
+     : name (ft.name), weight (ft.weight), angle (ft.angle), size (ft.size),
+       face (0)
+{
+#if HAVE_FT_REFERENCE_FACE
+  FT_Face ft_face = ft.get_face ();
+
+  if (ft_face && FT_Reference_Face (ft_face) == 0)
+    face = ft_face;
+#endif
+}
+
+ft_render::ft_font&
+ft_render::ft_font::operator = (const ft_font& ft)
+{
+  if (&ft != this)
+    {
+      name = ft.name;
+      weight = ft.weight;
+      angle = ft.angle;
+      size = ft.size;
+      if (face)
+        {
+          FT_Done_Face (face);
+          face = 0;
+        }
+
+#if HAVE_FT_REFERENCE_FACE
+      FT_Face ft_face = ft.get_face ();
+
+      if (ft_face && FT_Reference_Face (ft_face) == 0)
+        face = ft_face;
+#endif
+    }
+
+  return *this;
+}
+
+FT_Face
+ft_render::ft_font::get_face (void) const
+{
+  if (! face && ! name.empty ())
+    {
+      face = ft_manager::get_font (name, weight, angle, size);
+
+      if (face)
+        {
+          if (FT_Set_Char_Size (face, 0, size*64, 0, 0))
+            ::warning ("ft_render: unable to set font size to %g", size);
+        }
+      else
+        ::warning ("ft_render: unable to load appropriate font");
+    }
+
+  return face;
+}
+
 #endif // HAVE_FREETYPE
--- a/libinterp/corefcn/txt-eng-ft.h
+++ b/libinterp/corefcn/txt-eng-ft.h
@@ -25,6 +25,7 @@
 
 #if HAVE_FREETYPE
 
+#include <list>
 #include <vector>
 
 #include <ft2build.h>
@@ -58,6 +59,24 @@
 
   void visit (text_element_string& e);
 
+  void visit (text_element_list& e);
+
+  void visit (text_element_subscript& e);
+
+  void visit (text_element_superscript& e);
+
+  void visit (text_element_color& e);
+
+  void visit (text_element_fontsize& e);
+
+  void visit (text_element_fontname& e);
+
+  void visit (text_element_fontstyle& e);
+
+  void visit (text_element_symbol& e);
+
+  void visit (text_element_combined& e);
+
   void reset (void);
 
   uint8NDArray get_pixels (void) const { return pixels; }
@@ -68,7 +87,8 @@
                        int rotation = ROTATION_0);
 
   Matrix get_extent (text_element *elt, double rotation = 0.0);
-  Matrix get_extent (const std::string& txt, double rotation = 0.0);
+  Matrix get_extent (const std::string& txt, double rotation = 0.0,
+                     const caseless_str& interpreter = "tex");
 
   void set_font (const std::string& name, const std::string& weight,
                  const std::string& angle, double size);
@@ -79,7 +99,8 @@
 
   void text_to_pixels (const std::string& txt,
                        uint8NDArray& pixels_, Matrix& bbox,
-                       int halign, int valign, double rotation);
+                       int halign, int valign, double rotation,
+                       const caseless_str& interpreter = "tex");
 
 private:
   int rotation_to_mode (double rotation) const;
@@ -90,16 +111,96 @@
 
   ft_render& operator = (const ft_render&);
 
+  // Class to hold information about fonts and a strong
+  // reference to the font objects loaded by freetype.
+  class ft_font
+    {
+    public:
+      ft_font (void)
+        : name (), weight (), angle (), size (0), face (0) { }
+
+      ft_font (const std::string& nm, const std::string& wt,
+               const std::string& ang, double sz, FT_Face f = 0)
+        : name (nm), weight (wt), angle (ang), size (sz), face (f) { }
+
+      ft_font (const ft_font& ft);
+
+      ~ft_font (void)
+        {
+          if (face)
+            FT_Done_Face (face);
+        }
+
+      ft_font& operator = (const ft_font& ft);
+
+      bool is_valid (void) const { return get_face (); }
+
+      std::string get_name (void) const { return name; }
+
+      std::string get_weight (void) const { return weight; }
+
+      std::string get_angle (void) const { return angle; }
+
+      double get_size (void) const { return size; }
+
+      FT_Face get_face (void) const;
+
+    private:
+      std::string name;
+      std::string weight;
+      std::string angle;
+      double size;
+      mutable FT_Face face;
+    };
+
+  void push_new_line (void);
+
+  void update_line_bbox (void);
+
+  void compute_bbox (void);
+
+  int compute_line_xoffset (const Matrix& lb) const;
+
+  FT_UInt process_character (FT_ULong code, FT_UInt previous = 0);
+
 private:
-  FT_Face face;
+  // The current font used by the renderer.
+  ft_font font;
+
+  // Used to stored the bounding box corresponding to the rendered text.
+  // The bounding box has the form [x, y, w, h] where x and y represent the
+  // coordinates of the bottom left corner relative to the anchor point of
+  // the text (== start of text on the baseline). Due to font descent or
+  // multiple lines, the value y is usually negative.
   Matrix bbox;
+
+  // Used to stored the rendered text. It's a 3D matrix with size MxNx4
+  // where M and N are the width and height of the bounding box.
   uint8NDArray pixels;
+
+  // Used to store the bounding box of each line. This is used to layout
+  // multiline text properly.
+  std::list<Matrix> line_bbox;
+
+  // The current horizontal alignment. This is used to align multi-line text.
+  int halign;
+
+  // The X offset for the next glyph.
   int xoffset;
+
+  // The Y offset of the baseline for the current line.
+  int line_yoffset;
+
+  // The Y offset of the baseline for the next glyph. The offset is relative
+  // to line_yoffset. The total Y offset is computed with:
+  // line_yoffset + yoffset.
   int yoffset;
-  int multiline_halign;
-  std::vector<int> multiline_align_xoffsets;
+
+  // The current mode of the rendering process (box computing or rendering).
   int mode;
-  uint8_t red, green, blue;
+
+  // The base color of the rendered text.
+  uint8NDArray color;
 };
 
 #endif // HAVE_FREETYPE
new file mode 100644
--- /dev/null
+++ b/libinterp/corefcn/txt-eng.cc
@@ -0,0 +1,39 @@
+/*
+
+Copyright (C) 2013 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "txt-eng.h"
+#include "oct-tex-symbols.cc"
+
+uint32_t
+text_element_symbol::get_symbol_code (void) const
+{
+  uint32_t code = invalid_code;
+
+  if (0 <= symbol && symbol < num_symbol_codes)
+    code = symbol_codes[symbol][0];
+
+  return code;
+}
--- a/libinterp/corefcn/txt-eng.h
+++ b/libinterp/corefcn/txt-eng.h
@@ -23,13 +23,24 @@
 #if ! defined (txt_eng_h)
 #define txt_eng_h 1
 
+#include <memory>
+#include <string>
+
 #include "base-list.h"
+#include "caseless-str.h"
+#include "dMatrix.h"
 
 class text_element;
 class text_element_string;
+class text_element_symbol;
 class text_element_list;
-class text_subscript_element;
-class text_superscript_element;
+class text_element_subscript;
+class text_element_superscript;
+class text_element_combined;
+class text_element_fontname;
+class text_element_fontsize;
+class text_element_fontstyle;
+class text_element_color;
 
 class text_processor;
 
@@ -54,7 +65,7 @@
 {
 public:
   text_element_string (const std::string& s = "")
-      : text_element (), str (s) { }
+    : text_element (), str (s) { }
 
   ~text_element_string (void) { }
 
@@ -71,13 +82,40 @@
 
 class
 OCTINTERP_API
+text_element_symbol : public text_element
+{
+public:
+  enum { invalid_code = 0xFFFFFFFFU };
+
+public:
+  text_element_symbol (int sym)
+    : text_element (), symbol (sym) { }
+
+  ~text_element_symbol (void) { }
+
+  int get_symbol (void) const { return symbol; }
+
+  uint32_t get_symbol_code (void) const;
+
+  void accept (text_processor& p);
+
+private:
+  int symbol;
+};
+
+class
+OCTINTERP_API
 text_element_list :
     public text_element,
     public octave_base_list<text_element *>
 {
 public:
   text_element_list (void)
-      : text_element (), octave_base_list<text_element*> () { }
+    : text_element (), octave_base_list<text_element*> () { }
+
+  text_element_list (text_element* e)
+    : text_element (), octave_base_list<text_element*> ()
+    { push_back (e); }
 
   ~text_element_list (void)
     {
@@ -94,28 +132,181 @@
 
 class
 OCTINTERP_API
-text_subscript_element : public text_element_list
+text_element_subscript : public text_element
+{
+public:
+  text_element_subscript (text_element* e)
+    : text_element (), elem (e) { }
+
+  text_element_subscript (char c)
+    : text_element ()
+    { elem = new text_element_string (std::string (1, c)); }
+
+  ~text_element_subscript (void)
+    { delete elem; }
+
+  void accept (text_processor& p);
+
+  text_element* get_element (void) { return elem; }
+
+private:
+  text_element* elem;
+
+private:
+  text_element_subscript (void);
+};
+
+class
+OCTINTERP_API
+text_element_superscript : public text_element
 {
 public:
-  text_subscript_element (void)
-      : text_element_list () { }
+  text_element_superscript (text_element* e)
+    : text_element (), elem (e) { }
+
+  text_element_superscript (char c)
+    : text_element ()
+    { elem = new text_element_string (std::string (1, c)); }
+
+  ~text_element_superscript (void)
+    { delete elem; }
+
+  void accept (text_processor& p);
+
+  text_element* get_element (void) { return elem; }
 
-  ~text_subscript_element (void) { }
+private:
+  text_element* elem;
+
+private:
+  text_element_superscript (void);
+};
+
+class
+OCTINTERP_API
+text_element_combined : public text_element_list
+{
+public:
+  text_element_combined (text_element* e)
+    : text_element_list (e) { }
+
+  text_element_combined (text_element* e1, text_element* e2)
+    : text_element_list(e1)
+    { push_back (e2); }
 
   void accept (text_processor& p);
 };
 
 class
 OCTINTERP_API
-text_superscript_element : public text_element_list
+text_element_fontstyle : public text_element
+{
+public:
+  enum fontstyle
+    {
+      normal,
+      bold,
+      italic,
+      oblique
+    };
+
+  text_element_fontstyle (fontstyle st)
+    : text_element (), style (st) { }
+
+  ~text_element_fontstyle (void) { }
+
+  fontstyle get_fontstyle (void) const { return style; }
+
+  void accept (text_processor& p);
+
+private:
+  fontstyle style;
+
+private:
+  text_element_fontstyle (void);
+};
+
+class
+OCTINTERP_API
+text_element_fontname : public text_element
+{
+public:
+  text_element_fontname (const std::string& fname)
+    : text_element (), name (fname) { }
+
+  ~text_element_fontname (void) { }
+
+  const std::string& get_fontname (void) const { return name; }
+
+  void accept (text_processor& p);
+
+private:
+  std::string name;
+
+private:
+  text_element_fontname (void);
+};
+
+class
+OCTINTERP_API
+text_element_fontsize : public text_element
 {
 public:
-  text_superscript_element (void)
-      : text_element_list () { }
+  text_element_fontsize (double fsize)
+    : text_element (), size (fsize) { }
 
-  ~text_superscript_element (void) { }
+  ~text_element_fontsize (void) { }
+
+  double get_fontsize (void) const { return size; }
 
   void accept (text_processor& p);
+
+private:
+  double size;
+
+private:
+  text_element_fontsize (void);
+};
+
+class
+OCTINTERP_API
+text_element_color : public text_element
+{
+public:
+  text_element_color (double r, double g, double b)
+    : text_element (), rgb (1, 3, 0.0)
+    {
+      rgb(0) = r;
+      rgb(1) = g;
+      rgb(2) = b;
+    }
+
+  text_element_color (const std::string& cname)
+    : text_element (), rgb (1, 3, 0.0)
+    {
+#define ASSIGN_COLOR(r,g,b) { rgb(0) = r; rgb(1) = g; rgb(2) = b; }
+      if (cname == "red") ASSIGN_COLOR(1, 0, 0)
+      else if (cname == "green") ASSIGN_COLOR(0, 1, 0)
+      else if (cname == "yellow") ASSIGN_COLOR(1, 1, 0)
+      else if (cname == "magenta") ASSIGN_COLOR(1, 0, 1)
+      else if (cname == "blue") ASSIGN_COLOR(0, 0, 1)
+      else if (cname == "black") ASSIGN_COLOR(0, 0, 0)
+      else if (cname == "white") ASSIGN_COLOR(1, 1, 1)
+      else if (cname == "gray") ASSIGN_COLOR(.5, .5, .5)
+      else if (cname == "darkGreen") ASSIGN_COLOR(0, .5, 0)
+      else if (cname == "orange") ASSIGN_COLOR(1, .65, 0)
+      else if (cname == "lightBlue") ASSIGN_COLOR(0.68, .85, .9)
+#undef ASSIGN_COLOR
+    }
+
+  ~text_element_color (void) { }
+
+  Matrix get_color (void) { return rgb; }
+
+  void accept (text_processor& p);
+
+private:
+  Matrix rgb;
 };
 
 class
@@ -125,6 +316,8 @@
 public:
   virtual void visit (text_element_string& e) = 0;
 
+  virtual void visit (text_element_symbol&) { }
+
   virtual void visit (text_element_list& e)
     {
       for (text_element_list::iterator it = e.begin ();
@@ -134,11 +327,21 @@
         }
     }
 
-  virtual void visit (text_subscript_element& e)
-    { visit (dynamic_cast<text_element_list&> (e)); }
+  virtual void visit (text_element_subscript& e)
+    { e.get_element ()->accept (*this); }
+
+  virtual void visit (text_element_superscript& e)
+    { e.get_element ()->accept (*this); }
+
+  virtual void visit (text_element_combined&) { }
 
-  virtual void visit (text_superscript_element& e)
-    { visit (dynamic_cast<text_element_list&> (e)); }
+  virtual void visit (text_element_fontstyle&) { }
+
+  virtual void visit (text_element_fontname&) { }
+
+  virtual void visit (text_element_fontsize&) { }
+
+  virtual void visit (text_element_color&) { }
 
   virtual void reset (void) { }
 
@@ -154,9 +357,15 @@
 { p.visit (*this); }
 
 TEXT_ELEMENT_ACCEPT(text_element_string)
+TEXT_ELEMENT_ACCEPT(text_element_symbol)
 TEXT_ELEMENT_ACCEPT(text_element_list)
-TEXT_ELEMENT_ACCEPT(text_subscript_element)
-TEXT_ELEMENT_ACCEPT(text_superscript_element)
+TEXT_ELEMENT_ACCEPT(text_element_subscript)
+TEXT_ELEMENT_ACCEPT(text_element_superscript)
+TEXT_ELEMENT_ACCEPT(text_element_combined)
+TEXT_ELEMENT_ACCEPT(text_element_fontstyle)
+TEXT_ELEMENT_ACCEPT(text_element_fontname)
+TEXT_ELEMENT_ACCEPT(text_element_fontsize)
+TEXT_ELEMENT_ACCEPT(text_element_color)
 
 class
 OCTINTERP_API
@@ -168,6 +377,10 @@
   virtual ~text_parser (void) { }
 
   virtual text_element* parse (const std::string& s) = 0;
+
+public:
+  static text_element* parse (const std::string& s,
+                              const caseless_str& interpreter);
 };
 
 class
@@ -190,4 +403,50 @@
     }
 };
 
+class
+OCTINTERP_API
+text_parser_tex : public text_parser
+{
+public:
+  text_parser_tex (void)
+    : text_parser (), scanner (0), buffer_state (0), result (0)
+    { }
+
+  ~text_parser_tex (void)
+    { destroy_lexer (); }
+
+  text_element* parse (const std::string& s);
+
+  void* get_scanner (void) { return scanner; }
+
+  void set_parse_result (text_element* e) { result = e; }
+
+  text_element* get_parse_result (void) { return result; }
+
+private:
+  bool init_lexer (const std::string& s);
+
+  void destroy_lexer (void);
+
+private:
+  void* scanner;
+
+  void* buffer_state;
+
+  text_element* result;
+};
+
+inline text_element*
+text_parser::parse (const std::string& s, const caseless_str& interpreter)
+{
+  std::auto_ptr<text_parser> parser;
+
+  if (interpreter.compare ("tex"))
+    parser.reset (new text_parser_tex ());
+  else
+    parser.reset (new text_parser_none ());
+
+  return parser->parse (s);
+}
+
 #endif
--- a/libinterp/corefcn/typecast.cc
+++ b/libinterp/corefcn/typecast.cc
@@ -25,7 +25,7 @@
 #include <config.h>
 #endif
 
-#include <climits>
+#include <limits>
 
 #include "mx-base.h"
 
@@ -121,10 +121,10 @@
 their bit counts.  Both logical and char are typically one byte wide;\n\
 however, this is not guaranteed by C++.  If your system is IEEE conformant,\n\
 single and double should be 4 bytes and 8 bytes wide, respectively.\n\
-\"logical\" is not allowed for @var{class}.  If the input is a row vector,\n\
-the return value is a row vector, otherwise it is a column vector.  If the\n\
-bit length of @var{x} is not divisible by that of @var{class}, an error\n\
-occurs.\n\
+@qcode{\"logical\"} is not allowed for @var{class}.  If the input is a row\n\
+vector, the return value is a row vector, otherwise it is a column vector.  \n\
+If the bit length of @var{x} is not divisible by that of @var{class}, an\n\
+error occurs.\n\
 \n\
 An example of the use of typecast on a little-endian machine is\n\
 \n\
@@ -242,9 +242,9 @@
 do_bitpack (const boolNDArray& bitp)
 {
   typedef typename ArrayType::element_type T;
-  octave_idx_type n = bitp.numel () / (sizeof (T) * CHAR_BIT);
+  octave_idx_type n = bitp.numel () / (sizeof (T) * std::numeric_limits<unsigned char>::digits);
 
-  if (n * static_cast<int> (sizeof (T)) * CHAR_BIT == bitp.numel ())
+  if (n * static_cast<int> (sizeof (T)) * std::numeric_limits<unsigned char>::digits == bitp.numel ())
     {
 
       ArrayType retval (get_vec_dims (bitp.dims (), n));
@@ -257,11 +257,11 @@
       for (octave_idx_type i = 0; i < m; i++)
         {
           char c = bits[0];
-          for (int j = 1; j < CHAR_BIT; j++)
+          for (int j = 1; j < std::numeric_limits<unsigned char>::digits; j++)
             c |= bits[j] << j;
 
           packed[i] = c;
-          bits += CHAR_BIT;
+          bits += std::numeric_limits<unsigned char>::digits;
         }
 
       return retval;
@@ -361,22 +361,22 @@
 do_bitunpack (const ArrayType& array)
 {
   typedef typename ArrayType::element_type T;
-  octave_idx_type n = array.numel () * sizeof (T) * CHAR_BIT;
+  octave_idx_type n = array.numel () * sizeof (T) * std::numeric_limits<unsigned char>::digits;
 
   boolNDArray retval (get_vec_dims (array.dims (), n));
 
   const char *packed = reinterpret_cast<const char *> (array.fortran_vec ());
   bool *bits = retval.fortran_vec ();
 
-  octave_idx_type m = n / CHAR_BIT;
+  octave_idx_type m = n / std::numeric_limits<unsigned char>::digits;
 
   for (octave_idx_type i = 0; i < m; i++)
     {
       char c = packed[i];
       bits[0] = c & 1;
-      for (int j = 1; j < CHAR_BIT; j++)
+      for (int j = 1; j < std::numeric_limits<unsigned char>::digits; j++)
         bits[j] = (c >>= 1) & 1;
-      bits += CHAR_BIT;
+      bits += std::numeric_limits<unsigned char>::digits;
     }
 
   return retval;
--- a/libinterp/corefcn/utils.cc
+++ b/libinterp/corefcn/utils.cc
@@ -299,7 +299,7 @@
 directory of the loadpath for element of the cell array and return\n\
 the first that matches.\n\
 \n\
-If the second optional argument @code{\"all\"} is supplied, return\n\
+If the second optional argument @qcode{\"all\"} is supplied, return\n\
 a cell array containing the list of all files that have the same\n\
 name in the path.  If no files are found, return an empty cell array.\n\
 @seealso{file_in_path, path}\n\
@@ -375,7 +375,7 @@
 directory of the path for element of the cell array and return\n\
 the first that matches.\n\
 \n\
-If the third optional argument @code{\"all\"} is supplied, return\n\
+If the third optional argument @qcode{\"all\"} is supplied, return\n\
 a cell array containing the list of all files that have the same\n\
 name in the path.  If no files are found, return an empty cell array.\n\
 @seealso{file_in_loadpath}\n\
@@ -896,9 +896,10 @@
 @deftypefnx {Built-in Function} {} find_dir_in_path (@var{dir}, \"all\")\n\
 Return the full name of the path element matching @var{dir}.  The\n\
 match is performed at the end of each path element.  For example, if\n\
-@var{dir} is @code{\"foo/bar\"}, it matches the path element\n\
-@code{\"/some/dir/foo/bar\"}, but not @code{\"/some/dir/foo/bar/baz\"}\n\
-or @code{\"/some/dir/allfoo/bar\"}.\n\
+@var{dir} is @qcode{\"foo/bar\"}, it matches the path element\n\
+@nospell{@qcode{\"/some/dir/foo/bar\"}}, but not\n\
+@nospell{@qcode{\"/some/dir/foo/bar/baz\"}}\n\
+@nospell{@qcode{\"/some/dir/allfoo/bar\"}}.\n\
 \n\
 The second argument is optional.  If it is supplied, return a cell array\n\
 containing all name matches rather than just the first.\n\
--- a/libinterp/corefcn/variables.cc
+++ b/libinterp/corefcn/variables.cc
@@ -401,6 +401,8 @@
       struct_elts = name.substr (pos+1);
       symbol_name = name.substr (0, pos);
     }
+  else if (is_keyword (symbol_name))
+    return retval;
 
   // We shouldn't need to look in the global symbol table, since any
   // name that is visible in the current scope will be in the local
@@ -537,16 +539,16 @@
 symbols of the specified type.  Valid types are\n\
 \n\
 @table @asis\n\
-@item \"var\"\n\
+@item @qcode{\"var\"}\n\
 Check only for variables.\n\
 \n\
-@item \"builtin\"\n\
+@item @qcode{\"builtin\"}\n\
 Check only for built-in functions.\n\
 \n\
-@item \"file\"\n\
+@item @qcode{\"file\"}\n\
 Check only for files and directories.\n\
 \n\
-@item \"dir\"\n\
+@item @qcode{\"dir\"}\n\
 Check only for directories.\n\
 @end table\n\
 \n\
@@ -2530,11 +2532,11 @@
 left of the specified balance column.\n\
 \n\
 The default format is\n\
-@code{\"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\\n\"}.\n\
+@qcode{\"  %a:4; %ln:6; %cs:16:6:1;  %rb:12;  %lc:-1;\\n\"}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{whos}\n\
 @end deftypefn")
 {
@@ -2551,9 +2553,9 @@
 Query or set the internal variable that specifies the function to call when\n\
 an unknown identifier is requested.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (missing_function_hook);
rename from libinterp/dldfcn/eigs.cc
rename to libinterp/dldfcn/__eigs__.cc
--- a/libinterp/dldfcn/eigs.cc
+++ b/libinterp/dldfcn/__eigs__.cc
@@ -129,179 +129,29 @@
   return retval;
 }
 
-DEFUN_DLD (eigs, args, nargout,
+DEFUN_DLD (__eigs__, args, nargout,
   "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{d} =} eigs (@var{A})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})\n\
-@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})\n\
-Calculate a limited number of eigenvalues and eigenvectors of @var{A},\n\
-based on a selection criteria.  The number of eigenvalues and eigenvectors to\n\
-calculate is given by @var{k} and defaults to 6.\n\
-\n\
-By default, @code{eigs} solve the equation\n\
-@tex\n\
-$A \\nu = \\lambda \\nu$,\n\
-@end tex\n\
-@ifinfo\n\
-@code{A * v = lambda * v},\n\
-@end ifinfo\n\
-where\n\
-@tex\n\
-$\\lambda$ is a scalar representing one of the eigenvalues, and $\\nu$\n\
-@end tex\n\
-@ifinfo\n\
-@code{lambda} is a scalar representing one of the eigenvalues, and @code{v}\n\
-@end ifinfo\n\
-is the corresponding eigenvector.  If given the positive definite matrix\n\
-@var{B} then @code{eigs} solves the general eigenvalue equation\n\
-@tex\n\
-$A \\nu = \\lambda B \\nu$.\n\
-@end tex\n\
-@ifinfo\n\
-@code{A * v = lambda * B * v}.\n\
-@end ifinfo\n\
-\n\
-The argument @var{sigma} determines which eigenvalues are returned.\n\
-@var{sigma} can be either a scalar or a string.  When @var{sigma} is a\n\
-scalar, the @var{k} eigenvalues closest to @var{sigma} are returned.  If\n\
-@var{sigma} is a string, it must have one of the following values.\n\
-\n\
-@table @asis\n\
-@item \"lm\"\n\
-Largest Magnitude (default).\n\
-\n\
-@item \"sm\"\n\
-Smallest Magnitude.\n\
-\n\
-@item \"la\"\n\
-Largest Algebraic (valid only for real symmetric problems).\n\
-\n\
-@item \"sa\"\n\
-Smallest Algebraic (valid only for real symmetric problems).\n\
-\n\
-@item \"be\"\n\
-Both Ends, with one more from the high-end if @var{k} is odd (valid only for\n\
-real symmetric problems).\n\
-\n\
-@item \"lr\"\n\
-Largest Real part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"sr\"\n\
-Smallest Real part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"li\"\n\
-Largest Imaginary part (valid only for complex or unsymmetric problems).\n\
-\n\
-@item \"si\"\n\
-Smallest Imaginary part (valid only for complex or unsymmetric problems).\n\
-@end table\n\
-\n\
-If @var{opts} is given, it is a structure defining possible options that\n\
-@code{eigs} should use.  The fields of the @var{opts} structure are:\n\
-\n\
-@table @code\n\
-@item issym\n\
-If @var{af} is given, then flags whether the function @var{af} defines a\n\
-symmetric problem.  It is ignored if @var{A} is given.  The default is false.\n\
-\n\
-@item isreal\n\
-If @var{af} is given, then flags whether the function @var{af} defines a\n\
-real problem.  It is ignored if @var{A} is given.  The default is true.\n\
-\n\
-@item tol\n\
-Defines the required convergence tolerance, calculated as\n\
-@code{tol * norm (A)}.  The default is @code{eps}.\n\
-\n\
-@item maxit\n\
-The maximum number of iterations.  The default is 300.\n\
-\n\
-@item p\n\
-The number of Lanzcos basis vectors to use.  More vectors will result in\n\
-faster convergence, but a greater use of memory.  The optimal value of\n\
-@code{p} is problem dependent and should be in the range @var{k} to @var{n}.\n\
-The default value is @code{2 * @var{k}}.\n\
-\n\
-@item v0\n\
-The starting vector for the algorithm.  An initial vector close to the\n\
-final vector will speed up convergence.  The default is for @sc{arpack}\n\
-to randomly generate a starting vector.  If specified, @code{v0} must be\n\
-an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}\n\
-\n\
-@item disp\n\
-The level of diagnostic printout (0|1|2).  If @code{disp} is 0 then\n\
-diagnostics are disabled.  The default value is 0.\n\
-\n\
-@item cholB\n\
-Flag if @code{chol (@var{B})} is passed rather than @var{B}.  The default is\n\
-false.\n\
-\n\
-@item permB\n\
-The permutation vector of the Cholesky@tie{}factorization of @var{B} if\n\
-@code{cholB} is true.  That is @code{chol (@var{B}(permB, permB))}.  The\n\
-default is @code{1:@var{n}}.\n\
-\n\
-@end table\n\
-\n\
-It is also possible to represent @var{A} by a function denoted @var{af}.\n\
-@var{af} must be followed by a scalar argument @var{n} defining the length\n\
-of the vector argument accepted by @var{af}.  @var{af} can be\n\
-a function handle, an inline function, or a string.  When @var{af} is a\n\
-string it holds the name of the function to use.\n\
-\n\
-@var{af} is a function of the form @code{y = af (x)}\n\
-where the required return value of @var{af} is determined by\n\
-the value of @var{sigma}.  The four possible forms are\n\
-\n\
-@table @code\n\
-@item A * x\n\
-if @var{sigma} is not given or is a string other than \"sm\".\n\
-\n\
-@item A \\ x\n\
-if @var{sigma} is 0 or \"sm\".\n\
-\n\
-@item (A - sigma * I) \\ x\n\
-for the standard eigenvalue problem, where @code{I} is the identity matrix of\n\
-the same size as @var{A}.\n\
-\n\
-@item (A - sigma * B) \\ x\n\
-for the general eigenvalue problem.\n\
-@end table\n\
-\n\
-The return arguments of @code{eigs} depend on the number of return arguments\n\
-requested.  With a single return argument, a vector @var{d} of length @var{k}\n\
-is returned containing the @var{k} eigenvalues that have been found.  With\n\
-two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns\n\
-are the @var{k} eigenvectors corresponding to the returned eigenvalues.  The\n\
-eigenvalues themselves are returned in @var{d} in the form of a\n\
-@var{n}-by-@var{k} matrix, where the elements on the diagonal are the\n\
-eigenvalues.\n\
-\n\
-Given a third return argument @var{flag}, @code{eigs} returns the status\n\
-of the convergence.  If @var{flag} is 0 then all eigenvalues have converged.\n\
-Any other value indicates a failure to converge.\n\
-\n\
-This function is based on the @sc{arpack} package, written by R. Lehoucq,\n\
-K. Maschhoff, D. Sorensen, and C. Yang.  For more information see\n\
-@url{http://www.caam.rice.edu/software/ARPACK/}.\n\
-\n\
-@seealso{eig, svds}\n\
+@deftypefn  {Loadable Function} {@var{d} =} __eigs__ (@var{A})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {@var{d} =} __eigs__ (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} __eigs__ (@var{A}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}] =} __eigs__ (@var{af}, @var{n}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} __eigs__ (@var{A}, @dots{})\n\
+@deftypefnx {Loadable Function} {[@var{V}, @var{d}, @var{flag}] =} __eigs__ (@var{af}, @var{n}, @dots{})\n\
+Undocumented internal function.\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -766,756 +616,3 @@
 
   return retval;
 }
-
-/* #### SPARSE MATRIX VERSIONS #### */
-
-/*
-## Real positive definite tests, n must be even
-%!shared n, k, A, d0, d2
-%! n = 20;
-%! k = 4;
-%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]);
-%! d0 = eig (A);
-%! d2 = sort (d0);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); # initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (d1, d0(end:-1:(end-k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "la");
-%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sa");
-%! assert (d1, d2(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "be");
-%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1, "be");
-%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (d1, eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! AA = speye (10);
-%! fn = @(x) AA * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! assert (eigs (fn, 10, AA, 3, "lm", opts), [1; 1; 1], 10*eps);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "la");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sa");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "be");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Real unsymmetric tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A =  sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (d0));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Complex hermitian tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]);
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_CHOLMOD
-%! d1 = eigs (A, speye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, speye (n), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK, HAVE_UMFPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/* #### FULL MATRIX VERSIONS #### */
-
-/*
-## Real positive definite tests, n must be even
-%!shared n, k, A, d0, d2
-%! n = 20;
-%! k = 4;
-%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]));
-%! d0 = eig (A);
-%! d2 = sort (d0);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (d1, d0(end:-1:(end-k)),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "la");
-%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sa");
-%! assert (d1, d2(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "be");
-%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1, "be");
-%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (d1, d0(k:-1:1), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 1;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (d1, eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "la");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sa");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "be");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Real unsymmetric tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A =  full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]));
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (d0));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 1;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
-
-/*
-## Complex hermitian tests
-%!shared n, k, A, d0
-%! n = 20;
-%! k = 4;
-%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]));
-%! d0 = eig (A);
-%! [~, idx] = sort (abs (d0));
-%! d0 = d0(idx);
-%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k+1);
-%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sm");
-%! assert (abs (d1), abs (d0(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "lr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "sr");
-%! [~, idx] = sort (real (abs (d0)));
-%! d2 = d0(idx);
-%! assert (real (d1), real (d2(1:k)), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "li");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, "si");
-%! [~, idx] = sort (imag (abs (d0)));
-%! d2 = d0(idx);
-%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, k, 4.1);
-%! [~, idx0] = sort (abs (d0 - 4.1));
-%! [~, idx1] = sort (abs (d1 - 4.1));
-%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
-%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
-%!testif HAVE_ARPACK
-%! d1 = eigs (A, eye (n), k, "lm");
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! d1 = eigs (A, eye (n), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! opts.cholB = true;
-%! q = [2:n,1];
-%! opts.permB = q;
-%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
-%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
-%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
-%!testif HAVE_ARPACK
-%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A * x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "lm", opts);
-%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) A \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, "sm", opts);
-%! assert (abs (d1), d0(1:k), 1e-11);
-%!testif HAVE_ARPACK
-%! fn = @(x) (A - 4.1 * eye (n)) \ x;
-%! opts.issym = 0;  opts.isreal = 0;
-%! d1 = eigs (fn, n, k, 4.1, opts);
-%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sm");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "lr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "sr");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "li");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-%!testif HAVE_ARPACK
-%! [v1,d1] = eigs (A, k, "si");
-%! d1 = diag (d1);
-%! for i=1:k
-%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
-%! endfor
-*/
--- a/libinterp/dldfcn/__glpk__.cc
+++ b/libinterp/dldfcn/__glpk__.cc
@@ -1,6 +1,7 @@
 /*
 
 Copyright (C) 2005-2012 Nicolo' Giorgetti
+Copyright (C) 2013 Sébastien Villemot <sebastien@debian.org>
 
 This file is part of Octave.
 
@@ -46,191 +47,86 @@
 #else
 #include <glpk.h>
 #endif
-
-#if 0
-#ifdef GLPK_PRE_4_14
-
-#ifndef _GLPLIB_H
-#include <glplib.h>
-#endif
-#ifndef lib_set_fault_hook
-#define lib_set_fault_hook lib_fault_hook
-#endif
-#ifndef lib_set_print_hook
-#define lib_set_print_hook lib_print_hook
-#endif
-
-#else
-
-void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info);
-void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info);
-
-#endif
-#endif
 }
 
-#define NIntP 17
-#define NRealP 10
-
-int lpxIntParam[NIntP] = {
-  0,
-  1,
-  0,
-  1,
-  0,
-  -1,
-  0,
-  200,
-  1,
-  2,
-  0,
-  1,
-  0,
-  0,
-  2,
-  2,
-  1
-};
-
-int IParam[NIntP] = {
-  LPX_K_MSGLEV,
-  LPX_K_SCALE,
-  LPX_K_DUAL,
-  LPX_K_PRICE,
-  LPX_K_ROUND,
-  LPX_K_ITLIM,
-  LPX_K_ITCNT,
-  LPX_K_OUTFRQ,
-  LPX_K_MPSINFO,
-  LPX_K_MPSOBJ,
-  LPX_K_MPSORIG,
-  LPX_K_MPSWIDE,
-  LPX_K_MPSFREE,
-  LPX_K_MPSSKIP,
-  LPX_K_BRANCH,
-  LPX_K_BTRACK,
-  LPX_K_PRESOL
-};
-
-
-double lpxRealParam[NRealP] = {
-  0.07,
-  1e-7,
-  1e-7,
-  1e-9,
-  -std::numeric_limits<double>::max (),
-  std::numeric_limits<double>::max (),
-  -1.0,
-  0.0,
-  1e-6,
-  1e-7
-};
-
-int RParam[NRealP] = {
-  LPX_K_RELAX,
-  LPX_K_TOLBND,
-  LPX_K_TOLDJ,
-  LPX_K_TOLPIV,
-  LPX_K_OBJLL,
-  LPX_K_OBJUL,
-  LPX_K_TMLIM,
-  LPX_K_OUTDLY,
-  LPX_K_TOLINT,
-  LPX_K_TOLOBJ
+struct control_params
+{
+  int msglev;
+  int dual;
+  int price;
+  int itlim;
+  int outfrq;
+  int branch;
+  int btrack;
+  int presol;
+  int rtest;
+  int tmlim;
+  int outdly;
+  double tolbnd;
+  double toldj;
+  double tolpiv;
+  double objll;
+  double objul;
+  double tolint;
+  double tolobj;
 };
 
 static jmp_buf mark;  //-- Address for long jump to jump to
 
-#if 0
-int
-glpk_fault_hook (void * /* info */, char *msg)
-{
-  error ("CRITICAL ERROR in GLPK: %s", msg);
-  longjmp (mark, -1);
-}
-
-int
-glpk_print_hook (void * /* info */, char *msg)
-{
-  message (0, "%s", msg);
-  return 1;
-}
-#endif
-
 int
 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn,
       double *a, double *b, char *ctype, int *freeLB, double *lb,
       int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver,
-      int save_pb, double *xmin, double *fmin, double *status,
-      double *lambda, double *redcosts, double *time, double *mem)
+      int save_pb, int scale, const control_params *par,
+      double *xmin, double *fmin, int *status,
+      double *lambda, double *redcosts, double *time)
 {
-  int errnum;
   int typx = 0;
-  int method;
+  int errnum = 0;
 
   clock_t t_start = clock ();
 
-#if 0
-#ifdef GLPK_PRE_4_14
-  lib_set_fault_hook (0, glpk_fault_hook);
-#else
-  _glp_lib_fault_hook (glpk_fault_hook, 0);
-#endif
-
-  if (lpxIntParam[0] > 1)
-#ifdef GLPK_PRE_4_14
-    lib_set_print_hook (0, glpk_print_hook);
-#else
-    _glp_lib_print_hook (glpk_print_hook, 0);
-#endif
-#endif
-
-  LPX *lp = lpx_create_prob ();
-
+  glp_prob *lp = glp_create_prob ();
 
   //-- Set the sense of optimization
   if (sense == 1)
-    lpx_set_obj_dir (lp, LPX_MIN);
+    glp_set_obj_dir (lp, GLP_MIN);
   else
-    lpx_set_obj_dir (lp, LPX_MAX);
+    glp_set_obj_dir (lp, GLP_MAX);
 
-  //-- If the problem has integer structural variables switch to MIP
-  if (isMIP)
-    lpx_set_class (lp, LPX_MIP);
-
-  lpx_add_cols (lp, n);
+  glp_add_cols (lp, n);
   for (int i = 0; i < n; i++)
     {
       //-- Define type of the structural variables
       if (! freeLB[i] && ! freeUB[i])
         {
           if (lb[i] != ub[i])
-            lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]);
+            glp_set_col_bnds (lp, i+1, GLP_DB, lb[i], ub[i]);
           else
-            lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]);
+            glp_set_col_bnds (lp, i+1, GLP_FX, lb[i], ub[i]);
         }
       else
         {
           if (! freeLB[i] && freeUB[i])
-            lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]);
+            glp_set_col_bnds (lp, i+1, GLP_LO, lb[i], ub[i]);
           else
             {
               if (freeLB[i] && ! freeUB[i])
-                lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]);
+                glp_set_col_bnds (lp, i+1, GLP_UP, lb[i], ub[i]);
               else
-                lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]);
+                glp_set_col_bnds (lp, i+1, GLP_FR, lb[i], ub[i]);
             }
         }
 
       // -- Set the objective coefficient of the corresponding
       // -- structural variable. No constant term is assumed.
-      lpx_set_obj_coef(lp,i+1,c[i]);
+      glp_set_obj_coef(lp,i+1,c[i]);
 
       if (isMIP)
-        lpx_set_col_kind (lp, i+1, vartype[i]);
+        glp_set_col_kind (lp, i+1, vartype[i]);
     }
 
-  lpx_add_rows (lp, m);
+  glp_add_rows (lp, m);
 
   for (int i = 0; i < m; i++)
     {
@@ -245,124 +141,123 @@
       switch (ctype[i])
         {
         case 'F':
-          typx = LPX_FR;
+          typx = GLP_FR;
           break;
 
         case 'U':
-          typx = LPX_UP;
+          typx = GLP_UP;
           break;
 
         case 'L':
-          typx = LPX_LO;
+          typx = GLP_LO;
           break;
 
         case 'S':
-          typx = LPX_FX;
+          typx = GLP_FX;
           break;
 
         case 'D':
-          typx = LPX_DB;
+          typx = GLP_DB;
           break;
         }
 
-      lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]);
+      glp_set_row_bnds (lp, i+1, typx, b[i], b[i]);
 
     }
 
-  lpx_load_matrix (lp, nz, rn, cn, a);
+  glp_load_matrix (lp, nz, rn, cn, a);
 
   if (save_pb)
     {
       static char tmp[] = "outpb.lp";
-      if (lpx_write_cpxlp (lp, tmp) != 0)
+      if (glp_write_lp (lp, NULL, tmp) != 0)
         {
           error ("__glpk__: unable to write problem");
           longjmp (mark, -1);
         }
     }
 
-  //-- scale the problem data (if required)
-  //-- if (scale && (!presol || method == 1)) lpx_scale_prob (lp);
-  //-- LPX_K_SCALE=IParam[1]  LPX_K_PRESOL=IParam[16]
-  if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1))
-    lpx_scale_prob (lp);
+  //-- scale the problem data
+  if (!par->presol || lpsolver != 1)
+    glp_scale_prob (lp, scale);
 
   //-- build advanced initial basis (if required)
-  if (lpsolver == 1 && ! lpxIntParam[16])
-    lpx_adv_basis (lp);
-
-  for (int i = 0; i < NIntP; i++)
-    lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]);
+  if (lpsolver == 1 && !par->presol)
+    glp_adv_basis (lp, 0);
 
-  for (int i = 0; i < NRealP; i++)
-    lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]);
-
-  if (lpsolver == 1)
-    method = 'S';
-  else
-    method = 'T';
-
-  switch (method)
+  /* For MIP problems without a presolver, a first pass with glp_simplex
+     is required */
+  if ((!isMIP && lpsolver == 1)
+      || (isMIP && !par->presol))
     {
-    case 'S':
-      {
-        if (isMIP)
-          {
-            method = 'I';
-            errnum = lpx_simplex (lp);
-            errnum = lpx_integer (lp);
-          }
-        else
-          errnum = lpx_simplex (lp);
-      }
-     break;
-
-    case 'T':
-      errnum = lpx_interior (lp);
-      break;
-
-    default:
-      break;
-#if 0
-#ifdef GLPK_PRE_4_14
-      insist (method != method);
-#else
-      static char tmp[] = "method != method";
-      glpk_fault_hook (0, tmp);
-#endif
-#endif
+      glp_smcp smcp;
+      glp_init_smcp (&smcp);
+      smcp.msg_lev = par->msglev;
+      smcp.meth = par->dual;
+      smcp.pricing = par->price;
+      smcp.r_test = par->rtest;
+      smcp.tol_bnd = par->tolbnd;
+      smcp.tol_dj = par->toldj;
+      smcp.tol_piv = par->tolpiv;
+      smcp.obj_ll = par->objll;
+      smcp.obj_ul = par->objul;
+      smcp.it_lim = par->itlim;
+      smcp.tm_lim = par->tmlim;
+      smcp.out_frq = par->outfrq;
+      smcp.out_dly = par->outdly;
+      smcp.presolve = par->presol;
+      errnum = glp_simplex (lp, &smcp);
     }
 
-  /*  errnum assumes the following results:
-      errnum = 0 <=> No errors
-      errnum = 1 <=> Iteration limit exceeded.
-      errnum = 2 <=> Numerical problems with basis matrix.
-  */
-  if (errnum == LPX_E_OK)
+  if (isMIP)
+    {
+      glp_iocp iocp;
+      glp_init_iocp (&iocp);
+      iocp.msg_lev = par->msglev;
+      iocp.br_tech = par->branch;
+      iocp.bt_tech = par->btrack;
+      iocp.tol_int = par->tolint;
+      iocp.tol_obj = par->tolobj;
+      iocp.tm_lim = par->tmlim;
+      iocp.out_frq = par->outfrq;
+      iocp.out_dly = par->outdly;
+      iocp.presolve = par->presol;
+      errnum = glp_intopt (lp, &iocp);
+    }
+
+  if (!isMIP && lpsolver == 2)
+    {
+      glp_iptcp iptcp;
+      glp_init_iptcp (&iptcp);
+      iptcp.msg_lev = par->msglev;
+      errnum = glp_interior (lp, &iptcp);
+    }
+
+  if (errnum == 0)
     {
       if (isMIP)
         {
-          *status = lpx_mip_status (lp);
-          *fmin = lpx_mip_obj_val (lp);
+          *status = glp_mip_status (lp);
+          *fmin = glp_mip_obj_val (lp);
         }
       else
         {
           if (lpsolver == 1)
             {
-              *status = lpx_get_status (lp);
-              *fmin = lpx_get_obj_val (lp);
+              *status = glp_get_status (lp);
+              *fmin = glp_get_obj_val (lp);
             }
           else
             {
-              *status = lpx_ipt_status (lp);
-              *fmin = lpx_ipt_obj_val (lp);
+              *status = glp_ipt_status (lp);
+              *fmin = glp_ipt_obj_val (lp);
             }
         }
 
       if (isMIP)
         {
           for (int i = 0; i < n; i++)
-            xmin[i] = lpx_mip_col_val (lp, i+1);
+            xmin[i] = glp_mip_col_val (lp, i+1);
         }
       else
         {
@@ -370,52 +265,41 @@
           for (int i = 0; i < n; i++)
             {
               if (lpsolver == 1)
-                xmin[i] = lpx_get_col_prim (lp, i+1);
+                xmin[i] = glp_get_col_prim (lp, i+1);
               else
-                xmin[i] = lpx_ipt_col_prim (lp, i+1);
+                xmin[i] = glp_ipt_col_prim (lp, i+1);
             }
 
           /* Dual values */
           for (int i = 0; i < m; i++)
             {
               if (lpsolver == 1)
-                lambda[i] = lpx_get_row_dual (lp, i+1);
+                lambda[i] = glp_get_row_dual (lp, i+1);
               else
-                lambda[i] = lpx_ipt_row_dual (lp, i+1);
+                lambda[i] = glp_ipt_row_dual (lp, i+1);
             }
 
           /* Reduced costs */
-          for (int i = 0; i < lpx_get_num_cols (lp); i++)
+          for (int i = 0; i < glp_get_num_cols (lp); i++)
             {
               if (lpsolver == 1)
-                redcosts[i] = lpx_get_col_dual (lp, i+1);
+                redcosts[i] = glp_get_col_dual (lp, i+1);
               else
-                redcosts[i] = lpx_ipt_col_dual (lp, i+1);
+                redcosts[i] = glp_ipt_col_dual (lp, i+1);
             }
         }
 
       *time = (clock () - t_start) / CLOCKS_PER_SEC;
-
-#ifdef GLPK_PRE_4_14
-      *mem = (lib_env_ptr () -> mem_tpeak);
-#else
-      *mem = 0;
-#endif
-
-      lpx_delete_prob (lp);
-      return 0;
     }
 
-   lpx_delete_prob (lp);
-
-   *status = errnum;
+   glp_delete_prob (lp);
 
    return errnum;
 }
 
 #endif
 
-#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \
+#define OCTAVE_GLPK_GET_REAL_PARAM(NAME, VAL) \
   do \
     { \
       octave_value tmp = PARAM.getfield (NAME); \
@@ -424,7 +308,7 @@
         { \
           if (! tmp.is_empty ()) \
             { \
-              lpxRealParam[IDX] = tmp.scalar_value (); \
+              VAL = tmp.scalar_value (); \
  \
               if (error_state) \
                 { \
@@ -659,10 +543,10 @@
       if (VTYPE(i,0) == 'I')
         {
           isMIP = 1;
-          vartype(i) = LPX_IV;
+          vartype(i) = GLP_IV;
         }
       else
-        vartype(i) = LPX_CV;
+        vartype(i) = GLP_CV;
     }
 
   //-- 8th Input. Sense of optimization.
@@ -689,78 +573,78 @@
       return retval;
     }
 
+  control_params par;
+
   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   //-- Integer parameters
   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
   //-- Level of messages output by the solver
-  OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]);
-  if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3)
+  par.msglev = 1;
+  OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev);
+  if (par.msglev < 0 || par.msglev > 3)
     {
-      error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)");
+      error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)");
       return retval;
     }
 
   //-- scaling option
-  OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]);
-  if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2)
+  volatile int scale = 16;
+  OCTAVE_GLPK_GET_INT_PARAM ("scale", scale);
+  if (scale < 0 || scale > 128)
     {
-      error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)");
+      error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled");
       return retval;
     }
 
-  //-- Dual dimplex option
-  OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]);
-  if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1)
+  //-- Dual simplex option
+  par.dual = 1;
+  OCTAVE_GLPK_GET_INT_PARAM ("dual", par.dual);
+  if (par.dual < 1 || par.dual > 3)
     {
-      error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)");
+      error ("__glpk__: PARAM.dual must be 1 (use two-phase primal simplex [default]) or 2 (use two-phase dual simplex) or 3 (use two-phase dual simplex, and if it fails, switch to the primal simplex)");
       return retval;
     }
 
   //-- Pricing option
-  OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]);
-  if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1)
+  par.price = 34;
+  OCTAVE_GLPK_GET_INT_PARAM ("price", par.price);
+  if (par.price != 17 && par.price != 34)
     {
-      error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])");
-      return retval;
-    }
-
-  //-- Solution rounding option
-  OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]);
-  if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1)
-    {
-      error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)");
+      error ("__glpk__: PARAM.price must be 17 (textbook pricing) or 34 (steepest edge pricing [default])");
       return retval;
     }
 
   //-- Simplex iterations limit
-  OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]);
-
-  //-- Simplex iterations count
-  OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]);
+  par.itlim = std::numeric_limits<int>::max ();
+  OCTAVE_GLPK_GET_INT_PARAM ("itlim", par.itlim);
 
   //-- Output frequency, in iterations
-  OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]);
+  par.outfrq = 200;
+  OCTAVE_GLPK_GET_INT_PARAM ("outfrq", par.outfrq);
 
   //-- Branching heuristic option
-  OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]);
-  if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2)
+  par.branch = 4;
+  OCTAVE_GLPK_GET_INT_PARAM ("branch", par.branch);
+  if (par.branch < 1 || par.branch > 5)
     {
-      error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]");
+      error ("__glpk__: PARAM.branch must be 1 (first fractional variable) or 2 (last fractional variable) or 3 (most fractional variable) or 4 (heuristic by Driebeck and Tomlin [default]) or 5 (hybrid pseudocost heuristic)");
       return retval;
     }
 
   //-- Backtracking heuristic option
-  OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]);
-  if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2)
+  par.btrack = 4;
+  OCTAVE_GLPK_GET_INT_PARAM ("btrack", par.btrack);
+  if (par.btrack < 1 || par.btrack > 4)
     {
-      error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]");
+      error ("__glpk__: PARAM.btrack must be 1 (depth first search) or 2 (breadth first search) or 3 (best local bound) or 4 (best projection heuristic [default]");
       return retval;
     }
 
   //-- Presolver option
-  OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]);
-  if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1)
+  par.presol = 1;
+  OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol);
+  if (par.presol < 0 || par.presol > 1)
     {
       error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])");
       return retval;
@@ -775,6 +659,21 @@
       return retval;
     }
 
+  //-- Ratio test option
+  par.rtest = 34;
+  OCTAVE_GLPK_GET_INT_PARAM ("rtest", par.rtest);
+  if (par.rtest != 17 && par.rtest != 34)
+    {
+      error ("__glpk__: PARAM.rtest must be 17 (standard ratio test) or 34 (Harris' two-pass ratio test [default])");
+      return retval;
+    }
+
+  par.tmlim = std::numeric_limits<int>::max ();
+  OCTAVE_GLPK_GET_INT_PARAM ("tmlim", par.tmlim);
+
+  par.outdly = 0;
+  OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly);
+
   //-- Save option
   volatile int save_pb = 0;
   OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb);
@@ -784,51 +683,50 @@
   //-- Real parameters
   //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
-  //-- Ratio test option
-  OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0);
-
   //-- Relative tolerance used to check if the current basic solution
   //-- is primal feasible
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1);
+  par.tolbnd = 1e-7;
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", par.tolbnd);
 
   //-- Absolute tolerance used to check if the current basic solution
   //-- is dual feasible
-  OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2);
+  par.toldj = 1e-7;
+  OCTAVE_GLPK_GET_REAL_PARAM ("toldj", par.toldj);
 
   //-- Relative tolerance used to choose eligible pivotal elements of
   //--  the simplex table in the ratio test
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3);
+  par.tolpiv = 1e-10;
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", par.tolpiv);
 
-  OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5);
+  par.objll = -std::numeric_limits<double>::max ();
+  OCTAVE_GLPK_GET_REAL_PARAM ("objll", par.objll);
 
-  OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6);
-
-  OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7);
+  par.objul = std::numeric_limits<double>::max ();
+  OCTAVE_GLPK_GET_REAL_PARAM ("objul", par.objul);
 
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8);
+  par.tolint = 1e-5;
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolint", par.tolint);
 
-  OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9);
+  par.tolobj = 1e-7;
+  OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", par.tolobj);
 
   //-- Assign pointers to the output parameters
   ColumnVector xmin (mrowsc, octave_NA);
   double fmin = octave_NA;
-  double status;
   ColumnVector lambda (mrowsA, octave_NA);
   ColumnVector redcosts (mrowsc, octave_NA);
   double time;
-  double mem;
+  int status, errnum = 0;
 
   int jmpret = setjmp (mark);
 
   if (jmpret == 0)
-    glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
-          cn.fortran_vec (), a.fortran_vec (), b, ctype,
-          freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
-          vartype.fortran_vec (), isMIP, lpsolver, save_pb,
-          xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (),
-          redcosts.fortran_vec (), &time, &mem);
+    errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (),
+                   cn.fortran_vec (), a.fortran_vec (), b, ctype,
+                   freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub,
+                   vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale, &par,
+                   xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (),
+                   redcosts.fortran_vec (), &time);
 
   octave_scalar_map extra;
 
@@ -839,10 +737,10 @@
     }
 
   extra.assign ("time", time);
-  extra.assign ("mem", mem);
+  extra.assign ("status", status);
 
   retval(3) = extra;
-  retval(2) = status;
+  retval(2) = errnum;
   retval(1) = fmin;
   retval(0) = xmin;
 
--- a/libinterp/dldfcn/__init_fltk__.cc
+++ b/libinterp/dldfcn/__init_fltk__.cc
@@ -255,7 +255,7 @@
 };
 
 // Parameter controlling how fast we zoom when using the scrool wheel.
-static double wheel_zoom_speed = 0.05;
+static double Vwheel_zoom_speed = 0.05;
 // Parameter controlling the GUI mode.
 static enum { pan_zoom, rotate_zoom, none } gui_mode;
 
@@ -680,8 +680,6 @@
 
     begin ();
     {
-      //Fl_Window::resize (xx, yy - menu_h, ww, hh + menu_h + status_h);
-      
       // bbox of plot canvas = [xx, yy, ww, hh];
       // (xx, yy) = UL coordinate relative to UL window.
 
@@ -1110,9 +1108,7 @@
       {
         Matrix pos (1,2,0);
         pos(0) = px;
-        pos(1) = h () - menu_h - py;
-        if (! uimenu->is_visible ())
-          pos(1) = pos(1) +  menu_h;
+        pos(1) = h () - (py + status_h + menu_dy ());
         fp.set_currentpoint (pos);
         graphics_object robj = gh_manager::get_object (fp.get_parent ());
         root_figure::properties& rp =
@@ -1142,6 +1138,14 @@
       }
   }
 
+  int menu_dy ()
+    {
+      if (uimenu->is_visible ())
+        return menu_h;
+      else
+        return 0;
+    }
+
   int key2shift (int key)
   {
     if (key == FL_Shift_L || key == FL_Shift_R)
@@ -1190,14 +1194,9 @@
 
     Matrix pos (1,4,0);
     pos(0) = xx;
-    pos(1) = yy + menu_h;
+    pos(1) = yy + menu_dy ();
     pos(2) = ww;
-    pos(3) = hh - menu_h - status_h;
-    if (! uimenu->is_visible ())
-      {
-        pos(1) = yy;
-        pos(3) = hh - status_h;
-      }
+    pos(3) = hh - menu_dy () - status_h;
 
     fp.set_boundingbox (pos, true);
   }
@@ -1208,18 +1207,10 @@
     Matrix pos = fp.get_boundingbox (true);
     int canvas_h = pos(3);
     int canvas_w = pos(2);
-    int canvas_y = menu_h;
-    int toolbar_y = menu_h + canvas_h;
-    pos(1) = pos(1) - menu_h;
-    pos(3) = pos(3) + menu_h + status_h;
-
-    if (! uimenu->is_visible ())
-      {
-        pos(1) = pos(1) + menu_h;
-        pos(3) = pos(3) - menu_h;
-        toolbar_y = toolbar_y - menu_h;
-        canvas_y = canvas_y - menu_h;
-      }
+    int canvas_y = menu_dy ();
+    int toolbar_y = menu_dy () + canvas_h;
+    pos(1) = pos(1) - menu_dy ();
+    pos(3) = pos(3) + menu_dy () + status_h;
 
     Fl_Window::resize (pos(0), pos(1), pos(2), pos(3));
 
@@ -1308,15 +1299,15 @@
             break;
 
           case FL_MOVE:
-            pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y ()),
-                          Fl::event_x (), Fl::event_y ());
+            pixel2status (pixel2axes_or_ca (Fl::event_x (), Fl::event_y () - menu_dy ()),
+                          Fl::event_x (), Fl::event_y () - menu_dy ());
             break;
 
           case FL_PUSH:
             pos_x = Fl::event_x ();
-            pos_y = Fl::event_y ();
+            pos_y = Fl::event_y () - menu_dy ();
 
-            set_currentpoint (Fl::event_x (), Fl::event_y ());
+            set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
 
             gh = pixel2axes_or_ca (pos_x, pos_y);
 
@@ -1336,7 +1327,7 @@
           case FL_DRAG:
             if (fp.get_windowbuttonmotionfcn ().is_defined ())
               {
-                set_currentpoint (Fl::event_x (), Fl::event_y ());
+                set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
                 fp.execute_windowbuttonmotionfcn ();
               }
 
@@ -1346,7 +1337,7 @@
                   {
                     if (gui_mode == pan_zoom)
                       pixel2status (ax_obj, pos_x, pos_y,
-                                    Fl::event_x (), Fl::event_y ());
+                                    Fl::event_x (), Fl::event_y () - menu_dy ());
                     else
                       view2status (ax_obj);
                     axes::properties& ap =
@@ -1355,7 +1346,7 @@
                     double x0, y0, x1, y1;
                     Matrix pos = fp.get_boundingbox (true);
                     pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
-                    pixel2pos (ax_obj, Fl::event_x (), Fl::event_y (), x1, y1);
+                    pixel2pos (ax_obj, Fl::event_x (), Fl::event_y () - menu_dy (), x1, y1);
 
                     if (gui_mode == pan_zoom)
                       ap.translate_view (x0, x1, y0, y1);
@@ -1363,12 +1354,12 @@
                       {
                         double daz, del;
                         daz = (Fl::event_x () - pos_x) / pos(2) * 360;
-                        del = (Fl::event_y () - pos_y) / pos(3) * 360;
+                        del = (Fl::event_y () - menu_dy () - pos_y) / pos(3) * 360;
                         ap.rotate_view (del, daz);
                       }
 
                     pos_x = Fl::event_x ();
-                    pos_y = Fl::event_y ();
+                    pos_y = Fl::event_y () - menu_dy ();
                     mark_modified ();
                   }
                 return 1;
@@ -1376,12 +1367,12 @@
             else if (Fl::event_button () == 3)
               {
                 pixel2status (ax_obj, pos_x, pos_y,
-                              Fl::event_x (), Fl::event_y ());
+                              Fl::event_x (), Fl::event_y () - menu_dy ());
                 Matrix zoom_box (1,4,0);
                 zoom_box (0) = pos_x;
                 zoom_box (1) = pos_y;
                 zoom_box (2) =  Fl::event_x ();
-                zoom_box (3) =  Fl::event_y ();
+                zoom_box (3) =  Fl::event_y () - menu_dy ();
                 canvas->set_zoom_box (zoom_box);
                 canvas->zoom (true);
                 canvas->redraw ();
@@ -1393,7 +1384,7 @@
             {
               graphics_object ax =
                 gh_manager::get_object (pixel2axes_or_ca (Fl::event_x (),
-                                                          Fl::event_y ()));
+                                                          Fl::event_y () - menu_dy ()));
               if (ax && ax.isa ("axes"))
                 {
                   axes::properties& ap =
@@ -1401,11 +1392,12 @@
 
                   // Determine if we're zooming in or out.
                   const double factor =
-                    (Fl::event_dy () > 0) ? 1.0 + wheel_zoom_speed : 1.0 - wheel_zoom_speed;
+                    (Fl::event_dy () > 0) ? 1 / (1.0 - Vwheel_zoom_speed)
+                                          : 1.0 - Vwheel_zoom_speed;
 
                   // Get the point we're zooming about.
                   double x1, y1;
-                  pixel2pos (ax, Fl::event_x (), Fl::event_y (), x1, y1);
+                  pixel2pos (ax, Fl::event_x (), Fl::event_y () - menu_dy (), x1, y1);
 
                   ap.zoom_about_point (x1, y1, factor, false);
                   mark_modified ();
@@ -1416,7 +1408,7 @@
           case FL_RELEASE:
             if (fp.get_windowbuttonupfcn ().is_defined ())
               {
-                set_currentpoint (Fl::event_x (), Fl::event_y ());
+                set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
                 fp.execute_windowbuttonupfcn ();
               }
 
@@ -1448,7 +1440,7 @@
                           dynamic_cast<axes::properties&> (ax_obj.get_properties ());
                         pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
                         int pos_x1 = Fl::event_x ();
-                        int pos_y1 = Fl::event_y ();
+                        int pos_y1 = Fl::event_y () - menu_dy ();
                         pixel2pos (ax_obj, pos_x1, pos_y1, x1, y1);
                         Matrix xl (1,2,0);
                         Matrix yl (1,2,0);
@@ -2137,35 +2129,35 @@
   return retval;
 }
 
-// FIXME -- This function should be abstracted and made potentially
+// FIXME: This function should be abstracted and made potentially
 // available to all graphics toolkits.  This suggests putting it in
 // graphics.cc as is done for drawnow() and having the master
 // mouse_wheel_zoom function call fltk_mouse_wheel_zoom.  The same
 // should be done for gui_mode and fltk_gui_mode.  For now (2011.01.30),
 // just changing function names and docstrings.
 
-DEFUN_DLD (mouse_wheel_zoom, args, ,
+DEFUN_DLD (mouse_wheel_zoom, args, nargout,
   "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{speed} =} mouse_wheel_zoom ()\n\
-@deftypefnx {Built-in Function} {} mouse_wheel_zoom (@var{speed})\n\
+@deftypefn  {Loadable Function} {@var{val} =} mouse_wheel_zoom ()\n\
+@deftypefnx {Loadable Function} {@var{old_val} =} mouse_wheel_zoom (@var{new_val})\n\
+@deftypefnx {Loadable Function} {} mouse_wheel_zoom (@var{new_val}, \"local\")\n\
 Query or set the mouse wheel zoom factor.\n\
 \n\
+The zoom factor is a number in the range (0,1) which is the percentage of the\n\
+current axis limits that will be used when zooming.  For example, if the\n\
+current x-axis limits are [0, 50] and @code{mouse_wheel_zoom} is 0.4 (40%),\n\
+then a zoom operation will change the limits by 20.\n\
+\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
+\n\
 This function is currently implemented only for the FLTK graphics toolkit.\n\
 @seealso{gui_mode}\n\
 @end deftypefn")
 {
 #ifdef HAVE_FLTK
-  octave_value retval = wheel_zoom_speed;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_real_scalar ())
-        wheel_zoom_speed = args(0).double_value ();
-      else
-        error ("mouse_wheel_zoom: SPEED must be a real scalar");
-    }
-
-  return retval;
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS(wheel_zoom_speed, 0.0001, 0.9999);
 #else
   error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
   return octave_value ();
@@ -2180,13 +2172,13 @@
 The @var{mode} argument can be one of the following strings:\n\
 \n\
 @table @asis\n\
-@item '2d'\n\
+@item @qcode{\"2d\"}\n\
 Allows panning and zooming of current axes.\n\
 \n\
-@item '3d'\n\
+@item @qcode{\"3d\"}\n\
 Allows rotating and zooming of current axes.\n\
 \n\
-@item 'none'\n\
+@item @qcode{\"none\"}\n\
 Mouse inputs have no effect.\n\
 @end table\n\
 \n\
--- a/libinterp/dldfcn/__magick_read__.cc
+++ b/libinterp/dldfcn/__magick_read__.cc
@@ -27,8 +27,6 @@
 #include <config.h>
 #endif
 
-#include <cmath>
-
 #include "file-stat.h"
 #include "oct-env.h"
 #include "oct-time.h"
@@ -44,6 +42,99 @@
 #include <Magick++.h>
 #include <clocale>
 
+// In theory, it should be enough to check the class:
+// Magick::ClassType
+// PseudoClass:
+// Image is composed of pixels which specify an index in a color palette.
+// DirectClass:
+// Image is composed of pixels which represent literal color values.
+//
+//  GraphicsMagick does not really distinguishes between indexed and
+//  normal images. After reading a file, it decides itself the optimal
+//  way to store the image in memory, independently of the how the
+//  image was stored in the file. That's what ClassType returns. While
+//  it seems to match the original file most of the times, this is
+//  not necessarily true all the times. See
+//    https://sourceforge.net/mailarchive/message.php?msg_id=31180507
+//  In addition to the ClassType, there is also ImageType which has a
+//  type for indexed images (PaletteType and PaletteMatteType). However,
+//  they also don't represent the original image. Not only does DirectClass
+//  can have a PaletteType, but also does a PseudoClass have non Palette
+//  types.
+//
+//        We can't do better without having format specific code which is
+//        what we are trying to avoid by using a library such as GM. We at
+//        least create workarounds for the most common problems.
+//
+// 1) A grayscale jpeg image can report being indexed even though the
+//    JPEG format has no support for indexed images. We can at least
+//    fix this one.
+// 2) A PNG file is only an indexed image if color type orig is 3 (value comes
+//    from libpng)
+static bool
+is_indexed (const Magick::Image& img)
+{
+  bool retval = false;
+  const std::string format = img.magick ();
+  if (img.classType () == Magick::PseudoClass
+      && format != "JPEG"
+      && (format != "PNG"
+          || const_cast<Magick::Image&> (img).attribute ("PNG:IHDR.color-type-orig") == "3"))
+    retval = true;
+
+  return retval;
+}
+
+//  The depth from depth() is not always correct for us but seems to be the
+//  best value we can get. For example, a grayscale png image with 1 bit
+//  per channel should return a depth of 1 but instead we get 8.
+//  We could check channelDepth() but then, which channel has the data
+//  is not straightforward. So we'd have to check all
+//  the channels and select the highest value. But then, I also
+//  have a 16bit TIFF whose depth returns 16 (correct), but all of the
+//  channels gives 8 (wrong). No idea why, maybe a bug in GM?
+//  Anyway, using depth() seems that only causes problems for binary
+//  images, and the problem with channelDepth() is not making set them
+//  all to 1. So we will guess that if all channels have depth of 1,
+//  then we must have a binary image.
+//  Note that we can't use AllChannels it doesn't work for this.
+//  Instead of checking all of the individual channels, we check one
+//  from RGB, CMYK, grayscale, and transparency.
+static octave_idx_type
+get_depth (Magick::Image& img)
+{
+  octave_idx_type depth = img.depth ();
+  if (depth == 8
+      && img.channelDepth (Magick::RedChannel)     == 1
+      && img.channelDepth (Magick::CyanChannel)    == 1
+      && img.channelDepth (Magick::OpacityChannel) == 1
+      && img.channelDepth (Magick::GrayChannel)    == 1)
+    depth = 1;
+
+  return depth;
+}
+
+// We need this in case one of the sides of the image being read has
+// width 1. In those cases, the type will come as scalar instead of range
+// since that's the behaviour of the colon operator (1:1:1 will be a scalar,
+// not a range).
+static Range
+get_region_range (const octave_value& region)
+{
+  Range output;
+  if (region.is_range ())
+    output = region.range_value ();
+  else if (region.is_scalar_type ())
+    {
+      double value = region.scalar_value ();
+      output = Range (value, value);
+    }
+  else
+    error ("__magick_read__: unknow datatype for Region option");
+
+  return output;
+}
+
 static std::map<std::string, octave_idx_type>
 calculate_region (const octave_scalar_map& options)
 {
@@ -51,8 +142,8 @@
   const Cell pixel_region = options.getfield ("region").cell_value ();
 
   // Subtract 1 to account for 0 indexing.
-  const Range rows     = pixel_region (0).range_value ();
-  const Range cols     = pixel_region (1).range_value ();
+  const Range rows     = get_region_range (pixel_region (0));
+  const Range cols     = get_region_range (pixel_region (1));
   region["row_start"]  = rows.base () -1;
   region["col_start"]  = cols.base () -1;
   region["row_end"]    = rows.max ()  -1;
@@ -75,11 +166,32 @@
   return region;
 }
 
+static octave_value_list
+read_maps (Magick::Image& img)
+{
+  // can't call colorMapSize on const Magick::Image
+  const octave_idx_type mapsize = img.colorMapSize ();
+  Matrix cmap                   = Matrix (mapsize, 3); // colormap
+  ColumnVector amap             = ColumnVector (mapsize); // alpha map
+  for (octave_idx_type i = 0; i < mapsize; i++)
+    {
+      const Magick::ColorRGB c = img.colorMap (i);
+      cmap(i,0) = c.red   ();
+      cmap(i,1) = c.green ();
+      cmap(i,2) = c.blue  ();
+      amap(i)   = c.alpha ();
+    }
+  octave_value_list maps;
+  maps(0) = cmap;
+  maps(1) = amap;
+  return maps;
+}
+
 template <class T>
 static octave_value_list
-read_indexed_images (std::vector<Magick::Image>& imvec,
+read_indexed_images (const std::vector<Magick::Image>& imvec,
                      const Array<octave_idx_type>& frameidx,
-                     const octave_idx_type nargout,
+                     const octave_idx_type& nargout,
                      const octave_scalar_map& options)
 {
   typedef typename T::element_type P;
@@ -91,6 +203,11 @@
   const octave_idx_type nRows = region["row_out"];
   const octave_idx_type nCols = region["col_out"];
 
+  // imvec has all of the pages of a file, even the ones we are not
+  // interested in. We will use the first image that we will be actually
+  // reading to get information about the image.
+  const octave_idx_type def_elem = frameidx(0);
+
   T img       = T (dim_vector (nRows, nCols, 1, nFrames));
   P* img_fvec = img.fortran_vec ();
 
@@ -125,57 +242,36 @@
     }
   retval(0) = octave_value (img);
 
-  // Do we need to get the colormap to interpret the image and alpha channel?
+//   Only bother reading the colormap if it was requested as output.
   if (nargout > 1)
     {
-      const octave_idx_type mapsize = imvec[0].colorMapSize ();
-      Matrix cmap                   = Matrix (mapsize, 3);
-
       // In theory, it should be possible for each frame of an image to
       // have different colormaps but for Matlab compatibility, we only
-      // return the colormap of the first frame.
+      // return the colormap of the first frame.  To obtain the colormaps
+      // of different frames, one needs can either use imfinfo or a for
+      // loop around imread.
+      const octave_value_list maps =
+        read_maps (const_cast<Magick::Image&> (imvec[frameidx(def_elem)]));
 
-      // only get alpha channel if it exists and was requested as output
-      if (imvec[0].matte () && nargout >= 3)
+      retval(1) = maps(0);
+
+      // only interpret alpha channel if it exists and was requested as output
+      if (imvec[def_elem].matte () && nargout >= 3)
         {
-          Matrix amap = Matrix (mapsize, 1);
-          for (octave_idx_type i = 0; i < mapsize; i++)
-            {
-              const Magick::ColorRGB c = imvec[0].colorMap (i);
-              cmap(i,0) = c.red   ();
-              cmap(i,1) = c.green ();
-              cmap(i,2) = c.blue  ();
-              amap(i,0) = c.alpha ();
-            }
+          const Matrix amap = maps(1).matrix_value ();
+          const double* amap_fvec = amap.fortran_vec ();
 
           NDArray alpha (dim_vector (nRows, nCols, 1, nFrames));
-          const octave_idx_type nPixels = alpha.numel ();
-
           double* alpha_fvec = alpha.fortran_vec ();
 
-          idx = 0;
+          // GraphicsMagick stores the alpha values inverted, i.e.,
+          // 1 for transparent and 0 for opaque so we fix that here.
+          const octave_idx_type nPixels = alpha.numel ();
           for (octave_idx_type pix = 0; pix < nPixels; pix++)
-            {
-              // GraphicsMagick stores the alpha values inverted, i.e.,
-              // 1 for transparent and 0 for opaque so we fix that here.
-              alpha_fvec[idx] = abs (amap(img(idx), 0) - 1);
-              idx++;
-            }
+            alpha_fvec[pix] = 1 - amap_fvec[static_cast<int> (img_fvec[3])];
+
           retval(2) = alpha;
         }
-
-      else
-        {
-          for (octave_idx_type i = 0; i < mapsize; i++)
-            {
-              const Magick::ColorRGB c = imvec[0].colorMap (i);
-              cmap(i,0) = c.red   ();
-              cmap(i,1) = c.green ();
-              cmap(i,2) = c.blue  ();
-            }
-        }
-
-      retval(1) = cmap;
     }
 
   return retval;
@@ -189,7 +285,7 @@
 octave_value_list
 read_images (std::vector<Magick::Image>& imvec,
              const Array<octave_idx_type>& frameidx,
-             const octave_idx_type nargout,
+             const octave_idx_type& nargout,
              const octave_scalar_map& options)
 {
   typedef typename T::element_type P;
@@ -202,6 +298,11 @@
   const octave_idx_type nCols = region["col_out"];
   T img;
 
+  // imvec has all of the pages of a file, even the ones we are not
+  // interested in. We will use the first image that we will be actually
+  // reading to get information about the image.
+  const octave_idx_type def_elem = frameidx(0);
+
   const octave_idx_type row_start  = region["row_start"];
   const octave_idx_type col_start  = region["col_start"];
   const octave_idx_type row_shift  = region["row_shift"];
@@ -223,10 +324,15 @@
   // using quantumOperator for the cases where we will be returning floating
   // point and want things in the range [0 1]. This is the same reason why
   // the divisor is of type double.
-  const bool   float_out = imvec[0].depth () == 32;
-  const double type_max  = float_out ? 1 : ((uint64_t (1) << QuantumDepth) - 1);
-  const double divisor   = float_out ? std::numeric_limits<uint32_t>::max () :
-                           type_max / ((uint64_t (1) << imvec[0].depth ()) - 1);
+  // uint64_t is used in expression because default 32-bit value overflows
+  // when depth() is 32.
+  // TODO in the next release of GraphicsMagick, MaxRGB should be replaced
+  //      with QuantumRange since MaxRGB is already deprecated in ImageMagick.
+  double divisor;
+  if (imvec[def_elem].depth () == 32)
+    divisor = std::numeric_limits<uint32_t>::max ();
+  else
+    divisor = MaxRGB / ((uint64_t (1) << imvec[def_elem].depth ()) - 1);
 
   // FIXME: this workaround should probably be fixed in GM by creating a
   //        new ImageType BilevelMatteType
@@ -235,10 +341,48 @@
   // black (1 color), and have a second channel set for transparency (2nd
   // color). Its type will be bilevel since there is no BilevelMatte. The
   // only way to check for this seems to be by checking matte ().
-  Magick::ImageType type = imvec[0].type ();
-  if (type == Magick::BilevelType && imvec[0].matte ())
+  Magick::ImageType type = imvec[def_elem].type ();
+  if (type == Magick::BilevelType && imvec[def_elem].matte ())
+    type = Magick::GrayscaleMatteType;
+
+  // FIXME: ImageType is the type being used to represent the image in memory
+  // by GM. The real type may be different (see among others bug #36820). For
+  // example, a png file where all channels are equal may report being
+  // grayscale or even bilevel. But we must always return the real image in
+  // file. In some cases, the original image attributes are stored in the
+  // attributes but this is undocumented. This should be fixed in GM so that
+  // a method such as original_type returns an actual Magick::ImageType
+  if (imvec[0].magick () == "PNG")
     {
-      type = Magick::GrayscaleMatteType;
+      // These values come from libpng, not GM:
+      //      Grayscale         = 0
+      //      Palette           = 2 + 1
+      //      RGB               = 2
+      //      RGB + Alpha       = 2 + 4
+      //      Grayscale + Alpha = 4
+      // We won't bother with case 3 (palette) since those should be
+      // read by the function to read indexed images
+      const std::string type_str = imvec[0].attribute ("PNG:IHDR.color-type-orig");
+      if (type_str == "0")
+        type = Magick::GrayscaleType;
+      else if (type_str == "2")
+        type = Magick::TrueColorType;
+      else if (type_str == "6")
+        type = Magick::TrueColorMatteType;
+      else if (type_str == "4")
+        type = Magick::GrayscaleMatteType;
+      // Color types 0, 2, and 3 can also have alpha channel, conveyed
+      // via the "tRNS" chunk.  For 0 and 2, it's limited to GIF-style
+      // binary transparency, while 3 can have any level of alpha per
+      // palette entry. We thus must check matte() to see if the image
+      // really doesn't have an alpha channel.
+      if (imvec[0].matte ())
+        {
+          if (type == Magick::GrayscaleType)
+            type = Magick::GrayscaleMatteType;
+          else if (type == Magick::TrueColorType)
+            type = Magick::TrueColorMatteType;
+        }
     }
 
   // If the alpha channel was not requested, treat images as if
@@ -248,30 +392,25 @@
       switch (type)
         {
         case Magick::GrayscaleMatteType:
-          {
-            type = Magick::GrayscaleType;
-            break;
-          }
+          type = Magick::GrayscaleType;
+          break;
+
         case Magick::PaletteMatteType:
-          {
-            type = Magick::PaletteType;
-            break;
-          }
+          type = Magick::PaletteType;
+          break;
+
         case Magick::TrueColorMatteType:
-          {
-            type = Magick::TrueColorType;
-            break;
-          }
+          type = Magick::TrueColorType;
+          break;
+
         case Magick::ColorSeparationMatteType:
-          {
-            type = Magick::ColorSeparationType;
-            break;
-          }
+          type = Magick::ColorSeparationType;
+          break;
+
         default:
-          {
-            // do nothing, other than silencing warnings about enumeration
-            // values not being handled in switch.
-          }
+          // Do nothing other than silencing warnings about enumeration
+          // values not being handled in switch.
+          ;
         }
     }
 
@@ -322,7 +461,7 @@
                 for (octave_idx_type row = 0; row < nRows; row++)
                   {
                     img_fvec[idx] = pix->red / divisor;
-                    a_fvec[idx]   = abs ((pix->opacity / divisor) - type_max);
+                    a_fvec[idx]   = (MaxRGB - pix->opacity) / divisor;
                     pix += row_shift;
                     idx++;
                   }
@@ -397,10 +536,9 @@
                     rbuf[idx]     = pix->red     / divisor;
                     gbuf[idx]     = pix->green   / divisor;
                     bbuf[idx]     = pix->blue    / divisor;
-                    a_fvec[idx]   = abs ((pix->opacity / divisor) - type_max);
+                    a_fvec[a_idx++] = (MaxRGB - pix->opacity) / divisor;
                     pix += row_shift;
                     idx++;
-                    a_idx++;
                   }
                 pix -= col_shift;
               }
@@ -480,10 +618,9 @@
                     mbuf[idx]     = pix->green   / divisor;
                     ybuf[idx]     = pix->blue    / divisor;
                     kbuf[idx]     = pix->opacity / divisor;
-                    a_fvec[idx]   = abs ((*apix / divisor) - type_max);
+                    a_fvec[a_idx++] = (MaxRGB - *apix) / divisor;
                     pix += row_shift;
                     idx++;
-                    a_idx++;
                   }
                 pix -= col_shift;
               }
@@ -501,13 +638,12 @@
   return retval;
 }
 
-
+// Read a file into vector of image objects.
 void static
-read_file (const std::string filename, std::vector<Magick::Image>& imvec)
+read_file (const std::string& filename, std::vector<Magick::Image>& imvec)
 {
   try
     {
-      // Read a file into vector of image objects
       Magick::readImages (&imvec, filename);
     }
   catch (Magick::Warning& w)
@@ -527,7 +663,6 @@
     }
 }
 
-
 static void
 maybe_initialize_magick (void)
 {
@@ -547,10 +682,9 @@
       setlocale (LC_ALL, locale.c_str ());
 
       if (QuantumDepth < 32)
-        {
-          warning ("your version of %s limits images to %d bits per pixel",
-                   MagickPackageName, QuantumDepth);
-        }
+        warning ("your version of %s limits images to %d bits per pixel",
+                 MagickPackageName, QuantumDepth);
+
       initialized = true;
     }
 }
@@ -585,14 +719,13 @@
   if (error_state)
     {
       error ("__magick_read__: OPTIONS must be a struct");
+      return output;
     }
 
   std::vector<Magick::Image> imvec;
   read_file (args(0).string_value (), imvec);
   if (error_state)
-    {
-      return output;
-    }
+    return output;
 
   // Prepare an Array with the indexes for the requested frames.
   const octave_idx_type nFrames = imvec.size ();
@@ -602,9 +735,7 @@
     {
       frameidx.resize (dim_vector (1, nFrames));
       for (octave_idx_type i = 0; i < nFrames; i++)
-        {
-          frameidx(i) = i;
-        }
+        frameidx(i) = i;
     }
   else
     {
@@ -612,6 +743,7 @@
       if (error_state)
         {
           error ("__magick_read__: invalid value for Index/Frame");
+          return output;
         }
       // Fix indexes from base 1 to base 0, and at the same time, make
       // sure none of the indexes is outside the range of image number.
@@ -627,43 +759,18 @@
         }
     }
 
-  const Magick::ClassType klass = imvec[0].classType ();
-  const octave_idx_type depth   = imvec[0].depth ();
-
-  // Magick::ClassType
-  // PseudoClass:
-  // Image is composed of pixels which specify an index in a color palette.
-  // DirectClass:
-  // Image is composed of pixels which represent literal color values.
-
-  // FIXME: GraphicsMagick does not really distinguishes between indexed and
-  //        normal images. After reading a file, it decides itself the optimal
-  //        way to store the image in memory, independently of the how the
-  //        image was stored in the file. That's what ClassType returns. While
-  //        it seems to match the original file most of the times, this is
-  //        not necessarily true all the times. See
-  //          https://sourceforge.net/mailarchive/message.php?msg_id=31180507
-  //        A grayscale jpeg image reports being indexed even though the JPEG
-  //        format has no support for indexed images. So we can skip at least
-  //        for that.
-
-  if (klass == Magick::PseudoClass && imvec[0].magick () != "JPEG")
+  const octave_idx_type depth = get_depth (imvec[frameidx(0)]);
+  if (is_indexed (imvec[frameidx(0)]))
     {
       if (depth <= 1)
-        {
-          output = read_indexed_images <boolNDArray>   (imvec, frameidx,
-                                                        nargout, options);
-        }
+        output = read_indexed_images<boolNDArray>   (imvec, frameidx,
+                                                     nargout, options);
       else if (depth <= 8)
-        {
-          output = read_indexed_images <uint8NDArray>  (imvec, frameidx,
-                                                        nargout, options);
-        }
+        output = read_indexed_images<uint8NDArray>  (imvec, frameidx,
+                                                     nargout, options);
       else if (depth <= 16)
-        {
-          output = read_indexed_images <uint16NDArray> (imvec, frameidx,
-                                                        nargout, options);
-        }
+        output = read_indexed_images<uint16NDArray> (imvec, frameidx,
+                                                     nargout, options);
       else
         {
           error ("imread: indexed images with depths greater than 16-bit are not supported");
@@ -674,25 +781,13 @@
   else
     {
       if (depth <= 1)
-        {
-          output = read_images<boolNDArray>   (imvec, frameidx,
-                                               nargout, options);
-        }
+        output = read_images<boolNDArray>   (imvec, frameidx, nargout, options);
       else if (depth <= 8)
-        {
-          output = read_images<uint8NDArray>  (imvec, frameidx,
-                                               nargout, options);
-        }
+        output = read_images<uint8NDArray>  (imvec, frameidx, nargout, options);
       else if (depth <= 16)
-        {
-          output = read_images<uint16NDArray> (imvec, frameidx,
-                                               nargout, options);
-        }
+        output = read_images<uint16NDArray> (imvec, frameidx, nargout, options);
       else if (depth <= 32)
-        {
-          output = read_images<FloatNDArray>  (imvec, frameidx,
-                                               nargout, options);
-        }
+        output = read_images<FloatNDArray>  (imvec, frameidx, nargout, options);
       else
         {
           error ("imread: reading of images with %i-bit depth is not supported",
@@ -711,228 +806,452 @@
 
 #ifdef HAVE_MAGICK
 
-static void
-encode_bool_image (std::vector<Magick::Image>& imvec, const octave_value& img)
+template <class T>
+static uint32NDArray
+img_float2uint (const T& img)
 {
-  unsigned int nframes = 1;
-  boolNDArray m = img.bool_array_value ();
+  typedef typename T::element_type P;
+  uint32NDArray out (img.dims ());
+
+  octave_uint32* out_fvec = out.fortran_vec ();
+  const P*       img_fvec = img.fortran_vec ();
+
+  const octave_uint32 max = octave_uint32::max ();
+  const octave_idx_type numel = img.numel ();
+  for (octave_idx_type idx = 0; idx < numel; idx++)
+    out_fvec[idx] = img_fvec[idx] * max;
+
+  return out;
+}
 
-  dim_vector dsizes = m.dims ();
-  if (dsizes.length () == 4)
-    nframes = dsizes(3);
+// Gets the bitdepth to be used for an Octave class, i.e, returns 8 for
+// uint8, 16 for uint16, and 32 for uint32
+template <class T>
+static octave_idx_type
+bitdepth_from_class ()
+{
+  typedef typename T::element_type P;
+  const octave_idx_type bitdepth =
+    sizeof (P) * std::numeric_limits<unsigned char>::digits;
+  return bitdepth;
+}
 
-  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
+static Magick::Image
+init_enconde_image (const octave_idx_type& nCols, const octave_idx_type& nRows,
+                    const octave_idx_type& bitdepth,
+                    const Magick::ImageType& type,
+                    const Magick::ClassType& klass)
+{
+  Magick::Image img (Magick::Geometry (nCols, nRows), "black");
+  // Ensure that there are no other references to this image.
+  img.modifyImage ();
 
-  octave_idx_type rows = m.rows ();
-  octave_idx_type columns = m.columns ();
-
-  for (unsigned int ii = 0; ii < nframes; ii++)
+  img.classType (klass);
+  img.type (type);
+  // FIXME: for some reason, setting bitdepth doesn't seem to work for
+  //        indexed images.
+  img.depth (bitdepth);
+  switch (type)
     {
-      Magick::Image im (Magick::Geometry (columns, rows), "black");
-      im.classType (Magick::DirectClass);
-      im.depth (1);
+      case Magick::GrayscaleMatteType:
+      case Magick::TrueColorMatteType:
+      case Magick::ColorSeparationMatteType:
+      case Magick::PaletteMatteType:
+        img.matte (true);
+        break;
+
+      default:
+        img.matte (false);
+    }
+
+  return img;
+}
+
+template <class T>
+static void
+encode_indexed_images (std::vector<Magick::Image>& imvec,
+                       const T& img,
+                       const Matrix& cmap)
+{
+  typedef typename T::element_type P;
+  const octave_idx_type nFrames   = img.ndims () < 4 ? 1 : img.dims ()(3);
+  const octave_idx_type nRows     = img.rows ();
+  const octave_idx_type nCols     = img.columns ();
+  const octave_idx_type cmap_size = cmap.rows ();
+  const octave_idx_type bitdepth  = bitdepth_from_class<T> ();
 
-      for (int y = 0; y < columns; y++)
+  // There is no colormap object, we need to build a new one for each frame,
+  // even if it's always the same. We can least get a vector for the Colors.
+  std::vector<Magick::ColorRGB> colormap;
+  {
+    const double* cmap_fvec = cmap.fortran_vec ();
+    const octave_idx_type G_offset = cmap_size;
+    const octave_idx_type B_offset = cmap_size * 2;
+    for (octave_idx_type map_idx = 0; map_idx < cmap_size; map_idx++)
+      colormap.push_back (Magick::ColorRGB (cmap_fvec[map_idx],
+                                            cmap_fvec[map_idx + G_offset],
+                                            cmap_fvec[map_idx + B_offset]));
+  }
+
+  for (octave_idx_type frame = 0; frame < nFrames; frame++)
+    {
+      Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                Magick::PaletteType,
+                                                Magick::PseudoClass);
+
+      // Insert colormap.
+      m_img.colorMapSize (cmap_size);
+      for (octave_idx_type map_idx = 0; map_idx < cmap_size; map_idx++)
+        m_img.colorMap (map_idx, colormap[map_idx]);
+
+      // Why are we also setting the pixel values instead of only the
+      // index values? We don't know if a file format supports indexed
+      // images. If we only set the indexes and then try to save the
+      // image as JPEG for example, the indexed values get discarded,
+      // there is no conversion from the indexes, it's the initial values
+      // that get used. An alternative would be to only set the pixel
+      // values (no indexes), then set the image as PseudoClass and GM
+      // would create a colormap for us. However, we wouldn't have control
+      // over the order of that colormap. And that's why we set both.
+      Magick::PixelPacket* pix  = m_img.getPixels (0, 0, nCols, nRows);
+      Magick::IndexPacket* ind  = m_img.getIndexes ();
+      const P* img_fvec         = img.fortran_vec ();
+
+      octave_idx_type GM_idx = 0;
+      for (octave_idx_type column = 0; column < nCols; column++)
         {
-          idx(1) = y;
-
-          for (int x = 0; x < rows; x++)
+          for (octave_idx_type row = 0; row < nRows; row++)
             {
-              if (nframes > 1)
-                {
-                  idx(2) = 0;
-                  idx(3) = ii;
-                }
-
-              idx(0) = x;
-
-              if (m(idx))
-                im.pixelColor (y, x, "white");
+              ind[GM_idx] = double (*img_fvec);
+              pix[GM_idx] = m_img.colorMap (double (*img_fvec));
+              img_fvec++;
+              GM_idx += nCols;
             }
+          GM_idx -= nCols * nRows - 1;
         }
 
-      im.quantizeColorSpace (Magick::GRAYColorspace);
-      im.quantizeColors (2);
-      im.quantize ();
+      // Save changes to underlying image.
+      m_img.syncPixels ();
+      imvec.push_back (m_img);
+    }
+}
+
+static void
+encode_bool_image (std::vector<Magick::Image>& imvec, const boolNDArray& img)
+{
+  const octave_idx_type nFrames   = img.ndims () < 4 ? 1 : img.dims ()(3);
+  const octave_idx_type nRows     = img.rows ();
+  const octave_idx_type nCols     = img.columns ();
+
+  // The initialized image will be black, this is for the other pixels
+  const Magick::Color white ("white");
 
-      imvec.push_back (im);
+  const bool *img_fvec = img.fortran_vec ();
+  octave_idx_type img_idx = 0;
+  for (octave_idx_type frame = 0; frame < nFrames; frame++)
+    {
+      // For some reason, we can't set the type to Magick::BilevelType or
+      // the output image will be black, changing to white has no effect.
+      // However, this will still work fine and a binary image will be
+      // saved because we are setting the bitdepth to 1.
+      Magick::Image m_img = init_enconde_image (nCols, nRows, 1,
+                                                Magick::GrayscaleType,
+                                                Magick::DirectClass);
+
+      Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+      octave_idx_type GM_idx = 0;
+      for (octave_idx_type col = 0; col < nCols; col++)
+        {
+          for (octave_idx_type row = 0; row < nRows; row++)
+            {
+              if (img_fvec[img_idx])
+                pix[GM_idx] = white;
+
+              img_idx++;
+              GM_idx += nCols;
+            }
+          GM_idx -= nCols * nRows - 1;
+        }
+      // Save changes to underlying image.
+      m_img.syncPixels ();
+      // While we could not set it to Bilevel at the start, we can do it
+      // here otherwise some coders won't save it as binary.
+      m_img.type (Magick::BilevelType);
+      imvec.push_back (m_img);
     }
 }
 
 template <class T>
 static void
 encode_uint_image (std::vector<Magick::Image>& imvec,
-                   const octave_value& img,
-                   const bool has_map)
+                   const T& img, const T& alpha)
 {
-  unsigned int bitdepth = 0;
-  T m;
+  typedef typename T::element_type P;
+  const octave_idx_type channels  = img.ndims () < 3 ? 1 : img.dims ()(2);
+  const octave_idx_type nFrames   = img.ndims () < 4 ? 1 : img.dims ()(3);
+  const octave_idx_type nRows     = img.rows ();
+  const octave_idx_type nCols     = img.columns ();
+  const octave_idx_type bitdepth  = bitdepth_from_class<T> ();
 
-  if (img.is_uint8_type ())
-    {
-      bitdepth = 8;
-      m = img.uint8_array_value ();
-    }
-  else if (img.is_uint16_type ())
+  Magick::ImageType type;
+  const bool has_alpha = ! alpha.is_empty ();
+  switch (channels)
     {
-      bitdepth = 16;
-      m = img.uint16_array_value ();
-    }
-  else
-    error ("__magick_write__: invalid image class");
+    case 1:
+      if (has_alpha)
+        type = Magick::GrayscaleMatteType;
+      else
+        type = Magick::GrayscaleType;
+      break;
+
+    case 3:
+      if (has_alpha)
+        type = Magick::TrueColorMatteType;
+      else
+        type = Magick::TrueColorType;
+      break;
 
-  const dim_vector dsizes = m.dims ();
-  unsigned int nframes = 1;
-  if (dsizes.length () == 4)
-    nframes = dsizes(3);
+    case 4:
+      if (has_alpha)
+        type = Magick::ColorSeparationMatteType;
+      else
+        type = Magick::ColorSeparationType;
+      break;
 
-  const bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2));
-  const bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4));
+    default:
+      {
+        // __imwrite should have already filtered this cases
+        error ("__magick_write__: wrong size on 3rd dimension");
+        return;
+      }
+    }
+
+  // We will be passing the values as integers with depth as specified
+  // by QuantumDepth (maximum value specified by MaxRGB). This is independent
+  // of the actual depth of the image. GM will then convert the values but
+  // while in memory, it always keeps the values as specified by QuantumDepth.
+  // From GM documentation:
+  //  Color arguments are must be scaled to fit the Quantum size according to
+  //  the range of MaxRGB
+  const double divisor = static_cast<double>((1 << bitdepth) - 1) / MaxRGB;
 
-  Array<octave_idx_type> idx (dim_vector (dsizes.length (), 1));
-  octave_idx_type rows = m.rows ();
-  octave_idx_type columns = m.columns ();
-
-  unsigned int div_factor = (1 << bitdepth) - 1;
-
-  for (unsigned int ii = 0; ii < nframes; ii++)
+  const P *img_fvec = img.fortran_vec ();
+  const P *a_fvec   = alpha.fortran_vec ();
+  switch (type)
     {
-      Magick::Image im (Magick::Geometry (columns, rows), "black");
-
-      im.depth (bitdepth);
+    case Magick::GrayscaleType:
+      {
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-      if (has_map)
-        im.classType (Magick::PseudoClass);
-      else
-        im.classType (Magick::DirectClass);
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c;
+                    c.redQuantum (double (*img_fvec) / divisor);
+                    pix[GM_idx] = c;
+                    img_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-      if (is_color)
-        {
-          if (has_alpha)
-            im.type (Magick::TrueColorMatteType);
-          else
-            im.type (Magick::TrueColorType);
+    case Magick::GrayscaleMatteType:
+      {
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-          Magick::ColorRGB c;
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c;
+                    c.redQuantum   (double (*img_fvec) / divisor);
+                    c.alphaQuantum (MaxRGB - (double (*a_fvec) / divisor));
+                    pix[GM_idx] = c;
+                    img_fvec++;
+                    a_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-          for (int y = 0; y < columns; y++)
-            {
-              idx(1) = y;
-
-              for (int x = 0; x < rows; x++)
-                {
-                  idx(0) = x;
+    case Magick::TrueColorType:
+      {
+        // The fortran_vec offset for the green and blue channels
+        const octave_idx_type G_offset = nCols * nRows;
+        const octave_idx_type B_offset = nCols * nRows * 2;
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-                  if (nframes > 1)
-                    idx(3) = ii;
-
-                  idx(2) = 0;
-                  c.red (static_cast<double>(m(idx)) / div_factor);
-
-                  idx(2) = 1;
-                  c.green (static_cast<double>(m(idx)) / div_factor);
-
-                  idx(2) = 2;
-                  c.blue (static_cast<double>(m(idx)) / div_factor);
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c (double (*img_fvec)          / divisor,
+                                     double (img_fvec[G_offset]) / divisor,
+                                     double (img_fvec[B_offset]) / divisor);
+                    pix[GM_idx] = c;
+                    img_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-                  if (has_alpha)
-                    {
-                      idx(2) = 3;
-                      c.alpha (static_cast<double>(m(idx)) / div_factor);
-                    }
+    case Magick::TrueColorMatteType:
+      {
+        // The fortran_vec offset for the green and blue channels
+        const octave_idx_type G_offset = nCols * nRows;
+        const octave_idx_type B_offset = nCols * nRows * 2;
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-                  im.pixelColor (y, x, c);
-                }
-            }
-        }
-      else
-        {
-          if (has_alpha)
-            im.type (Magick::GrayscaleMatteType);
-          else
-            im.type (Magick::GrayscaleType);
-
-          Magick::ColorGray c;
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c (double (*img_fvec)          / divisor,
+                                     double (img_fvec[G_offset]) / divisor,
+                                     double (img_fvec[B_offset]) / divisor,
+                                     MaxRGB - (double (*a_fvec) / divisor));
+                    pix[GM_idx] = c;
+                    img_fvec++;
+                    a_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-          for (int y = 0; y < columns; y++)
-            {
-              idx(1) = y;
+    case Magick::ColorSeparationType:
+      {
+        // The fortran_vec offset for the Magenta, Yellow, and blacK channels
+        const octave_idx_type M_offset = nCols * nRows;
+        const octave_idx_type Y_offset = nCols * nRows * 2;
+        const octave_idx_type K_offset = nCols * nRows * 3;
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-              for (int x=0; x < rows; x++)
-                {
-                  idx(0) = x;
-
-                  if (nframes > 1)
-                    {
-                      idx(2) = 0;
-                      idx(3) = ii;
-                    }
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c (double (*img_fvec)          / divisor,
+                                     double (img_fvec[M_offset]) / divisor,
+                                     double (img_fvec[Y_offset]) / divisor,
+                                     double (img_fvec[K_offset]) / divisor);
+                    pix[GM_idx] = c;
+                    img_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-                  if (has_alpha)
-                    {
-                      idx(2) = 1;
-                      c.alpha (static_cast<double>(m(idx)) / div_factor);
-                      idx(2) = 0;
-                    }
-
-                  c.shade (static_cast<double>(m(idx)) / div_factor);
+    case Magick::ColorSeparationMatteType:
+      {
+        // The fortran_vec offset for the Magenta, Yellow, and blacK channels
+        const octave_idx_type M_offset = nCols * nRows;
+        const octave_idx_type Y_offset = nCols * nRows * 2;
+        const octave_idx_type K_offset = nCols * nRows * 3;
+        octave_idx_type GM_idx = 0;
+        for (octave_idx_type frame = 0; frame < nFrames; frame++)
+          {
+            Magick::Image m_img = init_enconde_image (nCols, nRows, bitdepth,
+                                                      type,
+                                                      Magick::DirectClass);
 
-                  im.pixelColor (y, x, c);
-                }
-            }
+            Magick::PixelPacket *pix = m_img.getPixels (0, 0, nCols, nRows);
+            Magick::IndexPacket *ind = m_img.getIndexes ();
+            for (octave_idx_type col = 0; col < nCols; col++)
+              {
+                for (octave_idx_type row = 0; row < nRows; row++)
+                  {
+                    Magick::Color c (double (*img_fvec)          / divisor,
+                                     double (img_fvec[M_offset]) / divisor,
+                                     double (img_fvec[Y_offset]) / divisor,
+                                     double (img_fvec[K_offset]) / divisor);
+                    pix[GM_idx] = c;
+                    ind[GM_idx] = MaxRGB - (double (*a_fvec) / divisor);
+                    img_fvec++;
+                    a_fvec++;
+                    GM_idx += nCols;
+                  }
+                GM_idx -= nCols * nRows - 1;
+              }
+            // Save changes to underlying image.
+            m_img.syncPixels ();
+            imvec.push_back (m_img);
+          }
+        break;
+      }
 
-          im.quantizeColorSpace (Magick::GRAYColorspace);
-          im.quantizeColors (1 << bitdepth);
-          im.quantize ();
-        }
-
-      imvec.push_back (im);
+    default:
+      {
+        error ("__magick_write__: unrecognized Magick::ImageType");
+        return;
+      }
     }
+  return;
 }
 
-// FIXME: this will be needed to write indexed images
-//static void
-//encode_map (std::vector<Magick::Image>& imvec, const NDArray& cmap)
-//{
-//  unsigned int mapsize = cmap.dim1 ();
-
-//  for (size_t fnum = 0; fnum < imvec.size (); fnum++)
-//    {
-//      imvec[fnum].colorMapSize (mapsize);
-//      imvec[fnum].type (Magick::PaletteType);
-//    }
-
-//  for (unsigned int ii = 0; ii < mapsize; ii++)
-//    {
-//      Magick::ColorRGB c (cmap(ii,0), cmap(ii,1), cmap(ii,2));
-
-//      // FIXME -- is this case needed?
-//      if (cmap.dim2 () == 4)
-//        c.alpha (cmap(ii,3));
-
-//      try
-//        {
-//          for_each (imvec.begin (), imvec.end (),
-//                    Magick::colorMapImage (ii, c));
-//        }
-//      catch (Magick::Warning& w)
-//        {
-//          warning ("Magick++ warning: %s", w.what ());
-//        }
-//      catch (Magick::ErrorCoder& e)
-//        {
-//          warning ("Magick++ coder error: %s", e.what ());
-//        }
-//      catch (Magick::Exception& e)
-//        {
-//          error ("Magick++ exception: %s", e.what ());
-//        }
-//    }
-//}
-
 void static
-write_file (const std::string filename,
-            const std::string ext,
+write_file (const std::string& filename,
+            const std::string& ext,
             std::vector<Magick::Image>& imvec)
 {
   try
@@ -983,10 +1302,11 @@
   const std::string filename = args(0).string_value ();
   const std::string ext      = args(1).string_value ();
 
-  const octave_map options   = args(4).map_value ();
+  const octave_scalar_map options = args(4).scalar_map_value ();
   if (error_state)
     {
       error ("__magick_write__: OPTIONS must be a struct");
+      return retval;
     }
 
   const octave_value img  = args(2);
@@ -994,81 +1314,97 @@
   if (error_state)
     {
       error ("__magick_write__: invalid IMG or MAP");
-    }
-  const bool is_indexed = ! cmap.is_empty ();
-
-  // Create vector with the images to write
-  std::vector<Magick::Image> imvec;
-  if (img.is_bool_type ())
-    {
-      encode_bool_image (imvec, img);
-    }
-  else if (img.is_uint8_type ())
-    {
-      encode_uint_image<uint8NDArray> (imvec, img, is_indexed);
-    }
-  else if (img.is_uint16_type ())
-    {
-      encode_uint_image<uint16NDArray> (imvec, img, is_indexed);
-    }
-  else
-    {
-      error ("__magick_write__: image type not supported");
-      return retval;
-    }
-  const int nframes = imvec.size ();
-
-  // Add colormap to image
-  if (is_indexed)
-    {
-    // FIXME: this should be implemented. At the moment, imwrite is doing the
-    //        conversion in case of indexed images.
-      error ("__magick_write__: direct saving of indexed images not currently supported; use ind2rgb and save converted image");
-//      encode_map (imvec, cmap);
       return retval;
     }
 
-  // Set quality.
-  // FIXME What happens when we try to set with formats that do not support it?
-  const unsigned int quality = options.getfield ("quality")(0).int_value ();
-  for (int i = 0; i < nframes; i++)
-    {
-      imvec[i].quality (quality);
-    }
+  std::vector<Magick::Image> imvec;
 
-  // Finally, save the file.
-  // If writemode is set to append, read the image first, append to it,
-  // and then save it. But even if set to append, make sure anything was
-  // read at all.
-  const std::string writemode = options.getfield ("writemode")(0).string_value ();
-  std::vector<Magick::Image> ini_imvec;
-  if (writemode == "append" && file_stat (filename).exists ())
+  if (cmap.is_empty ())
     {
-      read_file (filename, ini_imvec);
-      if (error_state)
+      const octave_value alpha = options.getfield ("alpha");
+      if (img.is_bool_type ())
+        encode_bool_image (imvec, img.bool_array_value ());
+      else if (img.is_uint8_type ())
+        encode_uint_image<uint8NDArray>  (imvec, img.uint8_array_value (),
+                                          alpha.uint8_array_value ());
+      else if (img.is_uint16_type ())
+        encode_uint_image<uint16NDArray> (imvec, img.uint16_array_value (),
+                                          alpha.uint16_array_value ());
+      else if (img.is_uint32_type ())
+        encode_uint_image<uint32NDArray> (imvec, img.uint32_array_value (),
+                                          alpha.uint32_array_value ());
+      else if (img.is_float_type ())
         {
-          return retval;
+          // For image formats that support floating point values, we write
+          // the actual values. For those who don't, we only use the values
+          // on the range [0 1] and save integer values.
+          // But here, even for formats that would support floating point
+          // values, GM seems unable to do that so we at least make them uint32.
+          uint32NDArray clip_img;
+          uint32NDArray clip_alpha;
+          if (img.is_single_type ())
+            {
+              clip_img   = img_float2uint<FloatNDArray> (img.float_array_value ());
+              clip_alpha = img_float2uint<FloatNDArray> (alpha.float_array_value ());
+            }
+          else
+            {
+              clip_img   = img_float2uint<NDArray> (img.array_value ());
+              clip_alpha = img_float2uint<NDArray> (alpha.array_value ());
+            }
+          encode_uint_image<uint32NDArray> (imvec, clip_img, clip_alpha);
         }
-    }
-
-  if (ini_imvec.size () > 0)
-    {
-      ini_imvec.insert (ini_imvec.end (), imvec.begin (), imvec.end ());
-      write_file (filename, ext, ini_imvec);
-      if (error_state)
+      else
         {
+          error ("__magick_write__: image type not supported");
           return retval;
         }
     }
   else
     {
-      write_file (filename, ext, imvec);
-      if (error_state)
+      // We should not get floating point indexed images here because we
+      // converted them in __imwrite__.m. We should probably do it here
+      // but it would look much messier.
+      if (img.is_uint8_type ())
+        encode_indexed_images<uint8NDArray>  (imvec, img.uint8_array_value (),
+                                              cmap);
+      else if (img.is_uint16_type ())
+        encode_indexed_images<uint16NDArray> (imvec, img.uint16_array_value (),
+                                              cmap);
+      else
         {
+          error ("__magick_write__: indexed image must be uint8, uint16 or float.");
           return retval;
         }
     }
 
+  const octave_idx_type nFrames = imvec.size ();
+
+  // FIXME What happens when we try to set with formats that do not support it?
+  const octave_idx_type quality = options.getfield ("quality").int_value ();
+  for (octave_idx_type i = 0; i < nFrames; i++)
+    imvec[i].quality (quality);
+
+  // If writemode is set to append, read the image and append to it. Even
+  // if set to append, make sure that something was read at all.
+  const std::string writemode = options.getfield ("writemode").string_value ();
+  if (writemode == "append" && file_stat (filename).exists ())
+    {
+      std::vector<Magick::Image> ini_imvec;
+      read_file (filename, ini_imvec);
+      if (error_state)
+          return retval;
+      if (ini_imvec.size () > 0)
+        {
+          ini_imvec.insert (ini_imvec.end (), imvec.begin (), imvec.end ());
+          ini_imvec.swap (imvec);
+        }
+    }
+
+  write_file (filename, ext, imvec);
+  if (error_state)
+    return retval;
+
 #endif
   return retval;
 }
@@ -1078,81 +1414,245 @@
 %!assert (1)
 */
 
-#ifdef HAVE_MAGICK
+// Gets the minimum information from images such as its size and format. Much
+// faster than using imfinfo, which slows down a lot since. Note than without
+// this, we need to read the image once for imfinfo to set defaults (which is
+// done in Octave language), and then again for the actual reading.
+DEFUN_DLD (__magick_ping__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __magick_ping__ (@var{fname}, @var{idx})\n\
+Ping image information with GraphicsMagick or ImageMagick.\n\
+\n\
+This is a private internal function not intended for direct use.\n\
+\n\
+@seealso{imfinfo}\n\
+@end deftypefn")
+{
+  octave_value retval;
+#ifndef HAVE_MAGICK
+  gripe_disabled_feature ("imfinfo", "Image IO");
+#else
+  maybe_initialize_magick ();
 
-template<class T>
+  if (args.length () < 1 || ! args(0).is_string ())
+    {
+      print_usage ();
+      return retval;
+    }
+  const std::string filename = args(0).string_value ();
+  int idx;
+  if (args.length () > 1)
+    idx = args(1).int_value () -1;
+  else
+    idx = 0;
+
+  Magick::Image img;
+  img.subImage (idx);
+  img.subRange (1);
+  img.ping (filename);
+  static const char *fields[] = {"rows", "columns", "format", 0};
+  octave_scalar_map ping = octave_scalar_map (string_vector (fields));
+  ping.setfield ("rows",    octave_value (img.rows ()));
+  ping.setfield ("columns", octave_value (img.columns ()));
+  ping.setfield ("format",  octave_value (img.magick ()));
+  retval = octave_value (ping);
+#endif
+  return retval;
+}
+
+#ifdef HAVE_MAGICK
 static octave_value
-magick_to_octave_value (const T magick)
+magick_to_octave_value (const Magick::CompressionType& magick)
 {
-  return octave_value (magick);
+  switch (magick)
+    {
+      case Magick::NoCompression:
+        return octave_value ("none");
+      case Magick::BZipCompression:
+        return octave_value ("bzip");
+      case Magick::FaxCompression:
+        return octave_value ("fax3");
+      case Magick::Group4Compression:
+        return octave_value ("fax4");
+      case Magick::JPEGCompression:
+        return octave_value ("jpeg");
+      case Magick::LZWCompression:
+        return octave_value ("lzw");
+      case Magick::RLECompression:
+        // This is named "rle" for the HDF, but the same thing is named
+        // "ccitt" and "PackBits" for binary and non-binary images in TIFF.
+        return octave_value ("rle");
+      case Magick::ZipCompression:
+        return octave_value ("deflate");
+
+      // The following are present only in recent versions of GraphicsMagick.
+      // At the moment the only use of this would be to have imfinfo report
+      // the compression method. In the future, someone could implement
+      // the Compression option for imwrite in which case a macro in
+      // configure.ac will have to check for their presence of this.
+      // See bug #39913
+//      case Magick::LZMACompression:
+//        return octave_value ("lzma");
+//      case Magick::JPEG2000Compression:
+//        return octave_value ("jpeg2000");
+//      case Magick::JBIG1Compression:
+//        return octave_value ("jbig1");
+//      case Magick::JBIG2Compression:
+//        return octave_value ("jbig2");
+      default:
+        return octave_value ("undefined");
+    }
 }
 
 static octave_value
-magick_to_octave_value (const Magick::EndianType magick)
+magick_to_octave_value (const Magick::EndianType& magick)
 {
   switch (magick)
     {
       case Magick::LSBEndian:
         return octave_value ("little-endian");
-
       case Magick::MSBEndian:
         return octave_value ("big-endian");
-
       default:
         return octave_value ("undefined");
     }
 }
 
 static octave_value
-magick_to_octave_value (const Magick::ResolutionType magick)
+magick_to_octave_value (const Magick::OrientationType& magick)
+{
+  switch (magick)
+    {
+      // Values come from the TIFF6 spec
+      case Magick::TopLeftOrientation:
+        return octave_value (1);
+      case Magick::TopRightOrientation:
+        return octave_value (2);
+      case Magick::BottomRightOrientation:
+        return octave_value (3);
+      case Magick::BottomLeftOrientation:
+        return octave_value (4);
+      case Magick::LeftTopOrientation:
+        return octave_value (5);
+      case Magick::RightTopOrientation:
+        return octave_value (6);
+      case Magick::RightBottomOrientation:
+        return octave_value (7);
+      case Magick::LeftBottomOrientation:
+        return octave_value (8);
+      default:
+        return octave_value (1);
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ResolutionType& magick)
 {
   switch (magick)
     {
       case Magick::PixelsPerInchResolution:
-        return octave_value ("pixels per inch");
-
+        return octave_value ("Inch");
       case Magick::PixelsPerCentimeterResolution:
-        return octave_value ("pixels per centimeter");
-
+        return octave_value ("Centimeter");
       default:
         return octave_value ("undefined");
     }
 }
 
-static octave_value
-magick_to_octave_value (const Magick::ImageType magick)
+// Meant to be shared with both imfinfo and imwrite.
+static std::map<octave_idx_type, std::string>
+init_disposal_methods ()
 {
-  switch (magick)
+  //  GIF Specifications:
+  //
+  // Disposal Method - Indicates the way in which the graphic is to
+  //                    be treated after being displayed.
+  //
+  //  0 -   No disposal specified. The decoder is
+  //        not required to take any action.
+  //  1 -   Do not dispose. The graphic is to be left
+  //        in place.
+  //  2 -   Restore to background color. The area used by the
+  //        graphic must be restored to the background color.
+  //  3 -   Restore to previous. The decoder is required to
+  //        restore the area overwritten by the graphic with
+  //        what was there prior to rendering the graphic.
+  //  4-7 - To be defined.
+  static std::map<octave_idx_type, std::string> methods;
+  if (methods.empty ())
     {
-      case Magick::BilevelType:
-      case Magick::GrayscaleType:
-      case Magick::GrayscaleMatteType:
-        return octave_value ("grayscale");
+      methods[0] = "doNotSpecify";
+      methods[1] = "leaveInPlace";
+      methods[2] = "restoreBG";
+      methods[3] = "restorePrevious";
+    }
+  return methods;
+}
 
-      case Magick::PaletteType:
-      case Magick::PaletteMatteType:
-        return octave_value ("indexed");
-
-      case Magick::TrueColorType:
-      case Magick::TrueColorMatteType:
-      case Magick::ColorSeparationType:
-        return octave_value ("truecolor");
-
-      default:
-        return octave_value ("undefined");
-    }
+static bool
+is_valid_exif (const std::string& val)
+{
+  // Sometimes GM will return the string "unknown" instead of empty
+  // for an empty value.
+  return (! val.empty () && val != "unknown");
 }
 
-// We put this in a try-block because GraphicsMagick will throw
-// exceptions if a parameter isn't present in the current image.
-#define GET_PARAM(NAME, OUTNAME) \
-  try \
-    { \
-      info.contents (OUTNAME)(frame,0) = magick_to_octave_value (im.NAME ()); \
-    } \
-  catch (Magick::Warning& w) \
-    { \
+static void
+fill_exif (octave_scalar_map& map, Magick::Image& img,
+           const std::string& key)
+{
+  const std::string attr = img.attribute ("EXIF:" + key);
+  if (is_valid_exif (attr))
+    map.setfield (key, octave_value (attr));
+  return;
+}
+
+static void
+fill_exif_ints (octave_scalar_map& map, Magick::Image& img,
+                const std::string& key)
+{
+  const std::string attr = img.attribute ("EXIF:" + key);
+  if (is_valid_exif (attr))
+    {
+      // string of the type "float,float,float....."
+      float number;
+      ColumnVector values (std::count (attr.begin (), attr.end (), ',') +1);
+      std::string sub;
+      std::istringstream sstream (attr);
+      octave_idx_type n = 0;
+      while (std::getline (sstream, sub, char (',')))
+        {
+          sscanf (sub.c_str (), "%f", &number);
+          values(n++) = number;
+        }
+      map.setfield (key, octave_value (values));
     }
+  return;
+}
+
+static void
+fill_exif_floats (octave_scalar_map& map, Magick::Image& img,
+                  const std::string& key)
+{
+  const std::string attr = img.attribute ("EXIF:" + key);
+  if (is_valid_exif (attr))
+    {
+      // string of the type "int/int,int/int,int/int....."
+      int numerator;
+      int denominator;
+      ColumnVector values (std::count (attr.begin (), attr.end (), ',') +1);
+      std::string sub;
+      std::istringstream sstream (attr);
+      octave_idx_type n = 0;
+      while (std::getline (sstream, sub, ','))
+        {
+          sscanf (sub.c_str (), "%i/%i", &numerator, &denominator);
+          values(n++) = double (numerator) / double (denominator);
+        }
+      map.setfield (key, octave_value (values));
+    }
+  return;
+}
 
 #endif
 
@@ -1172,125 +1672,427 @@
 #ifndef HAVE_MAGICK
   gripe_disabled_feature ("imfinfo", "Image IO");
 #else
-
   maybe_initialize_magick ();
 
-  if (args.length () < 1 || ! args (0).is_string ())
+  if (args.length () < 1 || ! args(0).is_string ())
     {
       print_usage ();
       return retval;
     }
-
-  const std::string filename = args (0).string_value ();
+  const std::string filename = args(0).string_value ();
 
-  try
-    {
-      // Read the file.
-      std::vector<Magick::Image> imvec;
-      Magick::readImages (&imvec, args(0).string_value ());
-      int nframes = imvec.size ();
-
-      // Create the right size for the output.
+  std::vector<Magick::Image> imvec;
+  read_file (filename, imvec);
+  if (error_state)
+    return retval;
+  const octave_idx_type nFrames = imvec.size ();
+  const std::string format = imvec[0].magick ();
 
-      static const char *fields[] =
-        {
-          "Filename",
-          "FileModDate",
-          "FileSize",
-          "Height",
-          "Width",
-          "BitDepth",
-          "Format",
-          "LongFormat",
-          "XResolution",
-          "YResolution",
-          "TotalColors",
-          "TileName",
-          "AnimationDelay",
-          "AnimationIterations",
-          "ByteOrder",
-          "Gamma",
-          "Matte",
-          "ModulusDepth",
-          "Quality",
-          "QuantizeColors",
-          "ResolutionUnits",
-          "ColorType",
-          "View",
-          0
-        };
+  // Here's how this function works. We need to return a struct array, one
+  // struct for each image in the file (remember, there are image
+  // that allow for multiple images in the same file). Now, Matlab seems
+  // to have format specific code so the fields on the struct are different
+  // for each format. It only has a small subset that is common to all
+  // of them, the others are undocumented. Because we try to abstract from
+  // the formats we always return the same list of fields (note that with
+  // GM we support more than 88 formats. That's way more than Matlab, and
+  // I don't want to write specific code for each of them).
+  //
+  // So what we do is we create an octave_scalar_map, fill it with the
+  // information for that image, and then insert it into an octave_map.
+  // Because in the same file, different images may have values for
+  // different fields, we can't create a field only if there's a value.
+  // Bad things happen if we merge octave_scalar_maps with different
+  // fields from the others (suppose for example a TIFF file with 4 images,
+  // where only the third image has a colormap.
 
-      octave_map info (dim_vector (nframes, 1), string_vector (fields));
-
-      file_stat fs (filename);
-
-      std::string filetime;
-
-      if (fs)
-        {
-          octave_localtime mtime = fs.mtime ();
+  static const char *fields[] =
+    {
+      // These are fields that must always appear for Matlab.
+      "Filename",
+      "FileModDate",
+      "FileSize",
+      "Format",
+      "FormatVersion",
+      "Width",
+      "Height",
+      "BitDepth",
+      "ColorType",
 
-          filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S");
-        }
-      else
-        {
-          std::string msg = fs.error ();
-
-          error ("imfinfo: error reading '%s': %s",
-                 filename.c_str (), msg.c_str ());
-
-          return retval;
-        }
-
-      // For each frame in the image (some images contain multiple
-      // layers, each to be treated like a separate image).
-      for (int frame = 0; frame < nframes; frame++)
-        {
-          Magick::Image im = imvec[frame];
-
-          // Add file name and timestamp.
-          info.contents ("Filename")(frame,0) = filename;
-          info.contents ("FileModDate")(frame,0) = filetime;
+      // These are format specific or not existent in Matlab. The most
+      // annoying thing is that Matlab may have different names for the
+      // same thing in different formats.
+      "DelayTime",
+      "DisposalMethod",
+      "LoopCount",
+      "ByteOrder",
+      "Gamma",
+      "Chromaticities",
+      "Comment",
+      "Quality",
+      "Compression",        // same as CompressionType
+      "Colormap",           // same as ColorTable (in PNG)
+      "Orientation",
+      "ResolutionUnit",
+      "XResolution",
+      "YResolution",
+      "Software",           // sometimes is an Exif tag
+      "Make",               // actually an Exif tag
+      "Model",              // actually an Exif tag
+      "DateTime",           // actually an Exif tag
+      "ImageDescription",   // actually an Exif tag
+      "Artist",             // actually an Exif tag
+      "Copyright",          // actually an Exif tag
+      "DigitalCamera",
+      "GPSInfo",
+      // Notes for the future: GM allows to get many attributes, and even has
+      // attribute() to obtain arbitrary ones, that may exist in only some
+      // cases. The following is a list of some methods and into what possible
+      // Matlab compatible values they may be converted.
+      //
+      //  colorSpace()      -> PhotometricInterpretation
+      //  backgroundColor() -> BackgroundColor
+      //  interlaceType()   -> Interlaced, InterlaceType, and PlanarConfiguration
+      //  label()           -> Title
+      0
+    };
 
-          // Annoying CamelCase naming is for Matlab compatibility.
-          GET_PARAM (fileSize, "FileSize")
-          GET_PARAM (rows, "Height")
-          GET_PARAM (columns, "Width")
-          GET_PARAM (depth, "BitDepth")
-          GET_PARAM (magick, "Format")
-          GET_PARAM (format, "LongFormat")
-          GET_PARAM (xResolution, "XResolution")
-          GET_PARAM (yResolution, "YResolution")
-          GET_PARAM (totalColors, "TotalColors")
-          GET_PARAM (tileName, "TileName")
-          GET_PARAM (animationDelay, "AnimationDelay")
-          GET_PARAM (animationIterations, "AnimationIterations")
-          GET_PARAM (endian, "ByteOrder")
-          GET_PARAM (gamma, "Gamma")
-          GET_PARAM (matte, "Matte")
-          GET_PARAM (modulusDepth, "ModulusDepth")
-          GET_PARAM (quality, "Quality")
-          GET_PARAM (quantizeColors, "QuantizeColors")
-          GET_PARAM (resolutionUnits, "ResolutionUnits")
-          GET_PARAM (type, "ColorType")
-          GET_PARAM (view, "View")
-        }
+  // The one we will return at the end
+  octave_map info (dim_vector (nFrames, 1), string_vector (fields));
+
+  // Some of the fields in the struct are about file information and will be
+  // the same for all images in the file. So we create a template, fill in
+  // those values, and make a copy of the template for each image.
+  octave_scalar_map template_info = (string_vector (fields));
+
+  template_info.setfield ("Format", octave_value (format));
+  // We can't actually get FormatVersion but even Matlab sometimes can't.
+  template_info.setfield ("FormatVersion", octave_value (""));
 
-      retval = octave_value (info);
-    }
-  catch (Magick::Warning& w)
+  const file_stat fs (filename);
+  if (fs)
     {
-      warning ("Magick++ warning: %s", w.what ());
+      const octave_localtime mtime (fs.mtime ());
+      const std::string filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S");
+      template_info.setfield ("Filename",    octave_value (filename));
+      template_info.setfield ("FileModDate", octave_value (filetime));
+      template_info.setfield ("FileSize",    octave_value (fs.size ()));
     }
-  catch (Magick::ErrorCoder& e)
+  else
     {
-      warning ("Magick++ coder error: %s", e.what ());
-    }
-  catch (Magick::Exception& e)
-    {
-      error ("Magick++ exception: %s", e.what ());
+      error ("imfinfo: error reading '%s': %s",
+             filename.c_str (), fs.error ().c_str ());
       return retval;
     }
+
+  for (octave_idx_type frame = 0; frame < nFrames; frame++)
+    {
+      octave_scalar_map info_frame (template_info);
+      const Magick::Image img = imvec[frame];
+
+      info_frame.setfield ("Width",  octave_value (img.columns ()));
+      info_frame.setfield ("Height", octave_value (img.rows ()));
+      info_frame.setfield ("BitDepth",
+        octave_value (get_depth (const_cast<Magick::Image&> (img))));
+
+      // Stuff related to colormap, image class and type
+      // Because GM is too smart for us... Read the comments in is_indexed()
+      {
+        std::string color_type;
+        Matrix cmap;
+        if (is_indexed (img))
+          {
+            color_type = "indexed";
+            cmap = read_maps (const_cast<Magick::Image&> (img))(0).matrix_value ();
+          }
+        else
+          {
+            switch (img.type ())
+              {
+                case Magick::BilevelType:
+                case Magick::GrayscaleType:
+                case Magick::GrayscaleMatteType:
+                  color_type = "grayscale";
+                  break;
+
+                case Magick::TrueColorType:
+                case Magick::TrueColorMatteType:
+                  color_type = "truecolor";
+                  break;
+
+                case Magick::PaletteType:
+                case Magick::PaletteMatteType:
+                  // we should never get here or is_indexed needs to be fixed
+                  color_type = "indexed";
+                  break;
+
+                case Magick::ColorSeparationType:
+                case Magick::ColorSeparationMatteType:
+                  color_type = "CMYK";
+                  break;
+
+                default:
+                  color_type = "undefined";
+              }
+          }
+        info_frame.setfield ("ColorType", octave_value (color_type));
+        info_frame.setfield ("Colormap",  octave_value (cmap));
+      }
+
+      {
+        // Not all images have chroma values. In such cases, they'll
+        // be all zeros. So rather than send a matrix of zeros, we will
+        // check for that, and send an empty vector instead.
+        RowVector chromaticities (8);
+        double* chroma_fvec = chromaticities.fortran_vec ();
+        img.chromaWhitePoint    (&chroma_fvec[0], &chroma_fvec[1]);
+        img.chromaRedPrimary    (&chroma_fvec[2], &chroma_fvec[3]);
+        img.chromaGreenPrimary  (&chroma_fvec[4], &chroma_fvec[5]);
+        img.chromaBluePrimary   (&chroma_fvec[6], &chroma_fvec[7]);
+        if (chromaticities.nnz () == 0)
+          chromaticities = RowVector (0);
+        info_frame.setfield ("Chromaticities", octave_value (chromaticities));
+      }
+
+      info_frame.setfield ("Gamma",         octave_value (img.gamma ()));
+      info_frame.setfield ("XResolution",   octave_value (img.xResolution ()));
+      info_frame.setfield ("YResolution",   octave_value (img.yResolution ()));
+      info_frame.setfield ("DelayTime",     octave_value (img.animationDelay ()));
+      info_frame.setfield ("LoopCount",     octave_value (img.animationIterations ()));
+      info_frame.setfield ("Quality",       octave_value (img.quality ()));
+      info_frame.setfield ("Comment",       octave_value (img.comment ()));
+
+      info_frame.setfield ("Compression",
+        magick_to_octave_value (img.compressType ()));
+      info_frame.setfield ("Orientation",
+        magick_to_octave_value (img.orientation ()));
+      info_frame.setfield ("ResolutionUnit",
+        magick_to_octave_value (img.resolutionUnits ()));
+      info_frame.setfield ("ByteOrder",
+        magick_to_octave_value (img.endian ()));
+
+      // It is not possible to know if there's an Exif field so we just
+      // check for the Exif Version value. If it does exists, then we
+      // bother about looking for specific fields.
+      {
+        Magick::Image& cimg = const_cast<Magick::Image&> (img);
+
+        // These will be in Exif tags but must appear as fields in the
+        // base struct array, not as another struct in one of its fields.
+        // This is likely because they belong to the Baseline TIFF specs
+        // and may appear out of the Exif tag. So first we check if it
+        // exists outside the Exif tag.
+        // See Section 4.6.4, table 4, page 28 of Exif specs version 2.3
+        // (CIPA DC- 008-Translation- 2010)
+        static const char *base_exif_str_fields[] = {
+          "DateTime",
+          "ImageDescription",
+          "Make",
+          "Model",
+          "Software",
+          "Artist",
+          "Copyright",
+          0,
+        };
+        static const string_vector base_exif_str (base_exif_str_fields);
+        static const octave_idx_type n_base_exif_str = base_exif_str.numel ();
+        for (octave_idx_type field = 0; field < n_base_exif_str; field++)
+          {
+            info_frame.setfield (base_exif_str[field],
+              octave_value (cimg.attribute (base_exif_str[field])));
+            fill_exif (info_frame, cimg, base_exif_str[field]);
+          }
+
+        octave_scalar_map camera;
+        octave_scalar_map gps;
+        if (! cimg.attribute ("EXIF:ExifVersion").empty ())
+          {
+            // See Section 4.6.5, table 7 and 8, over pages page 42 to 43
+            // of Exif specs version 2.3 (CIPA DC- 008-Translation- 2010)
+
+            // Listed on the Exif specs as being of type ASCII.
+            static const char *exif_str_fields[] = {
+              "RelatedSoundFile",
+              "DateTimeOriginal",
+              "DateTimeDigitized",
+              "SubSecTime",
+              "DateTimeOriginal",
+              "SubSecTimeOriginal",
+              "SubSecTimeDigitized",
+              "ImageUniqueID",
+              "CameraOwnerName",
+              "BodySerialNumber",
+              "LensMake",
+              "LensModel",
+              "LensSerialNumber",
+              "SpectralSensitivity",
+              // These last two are of type undefined but most likely will
+              // be strings. Even if they're not GM returns a string anyway.
+              "UserComment",
+              "MakerComment",
+              0
+            };
+            static const string_vector exif_str (exif_str_fields);
+            static const octave_idx_type n_exif_str = exif_str.numel ();
+            for (octave_idx_type field = 0; field < n_exif_str; field++)
+              fill_exif (camera, cimg, exif_str[field]);
+
+            // Listed on the Exif specs as being of type SHORT or LONG.
+            static const char *exif_int_fields[] = {
+              "ColorSpace",
+              "ExifImageWidth",  // PixelXDimension (CPixelXDimension in Matlab)
+              "ExifImageHeight", // PixelYDimension (CPixelYDimension in Matlab)
+              "PhotographicSensitivity",
+              "StandardOutputSensitivity",
+              "RecommendedExposureIndex",
+              "ISOSpeed",
+              "ISOSpeedLatitudeyyy",
+              "ISOSpeedLatitudezzz",
+              "FocalPlaneResolutionUnit",
+              "FocalLengthIn35mmFilm",
+              // Listed as SHORT or LONG but with more than 1 count.
+              "SubjectArea",
+              "SubjectLocation",
+              // While the following are an integer, their value have a meaning
+              // that must be represented as a string for Matlab compatibility.
+              // For example, a 3 on ExposureProgram, would return
+              // "Aperture priority" as defined on the Exif specs.
+              "ExposureProgram",
+              "SensitivityType",
+              "MeteringMode",
+              "LightSource",
+              "Flash",
+              "SensingMethod",
+              "FileSource",
+              "CustomRendered",
+              "ExposureMode",
+              "WhiteBalance",
+              "SceneCaptureType",
+              "GainControl",
+              "Contrast",
+              "Saturation",
+              "Sharpness",
+              "SubjectDistanceRange",
+              0
+            };
+            static const string_vector exif_int (exif_int_fields);
+            static const octave_idx_type n_exif_int = exif_int.numel ();
+            for (octave_idx_type field = 0; field < n_exif_int; field++)
+              fill_exif_ints (camera, cimg, exif_int[field]);
+
+            // Listed as RATIONAL or SRATIONAL
+            static const char *exif_float_fields[] = {
+              "Gamma",
+              "CompressedBitsPerPixel",
+              "ExposureTime",
+              "FNumber",
+              "ShutterSpeedValue",  // SRATIONAL
+              "ApertureValue",
+              "BrightnessValue",    // SRATIONAL
+              "ExposureBiasValue",  // SRATIONAL
+              "MaxApertureValue",
+              "SubjectDistance",
+              "FocalLength",
+              "FlashEnergy",
+              "FocalPlaneXResolution",
+              "FocalPlaneYResolution",
+              "ExposureIndex",
+              "DigitalZoomRatio",
+              // Listed as RATIONAL or SRATIONAL with more than 1 count.
+              "LensSpecification",
+              0
+            };
+            static const string_vector exif_float (exif_float_fields);
+            static const octave_idx_type n_exif_float = exif_float.numel ();
+            for (octave_idx_type field = 0; field < n_exif_float; field++)
+              fill_exif_floats (camera, cimg, exif_float[field]);
+
+            // Inside a Exif field, it is possible that there is also a
+            // GPS field. This is not the same as ExifVersion but seems
+            // to be how we have to check for it.
+            if (cimg.attribute ("EXIF:GPSInfo") != "unknown")
+              {
+                // The story here is the same as with Exif.
+                // See Section 4.6.6, table 15 on page 68 of Exif specs
+                // version 2.3 (CIPA DC- 008-Translation- 2010)
+
+                static const char *gps_str_fields[] = {
+                  "GPSLatitudeRef",
+                  "GPSLongitudeRef",
+                  "GPSAltitudeRef",
+                  "GPSSatellites",
+                  "GPSStatus",
+                  "GPSMeasureMode",
+                  "GPSSpeedRef",
+                  "GPSTrackRef",
+                  "GPSImgDirectionRef",
+                  "GPSMapDatum",
+                  "GPSDestLatitudeRef",
+                  "GPSDestLongitudeRef",
+                  "GPSDestBearingRef",
+                  "GPSDestDistanceRef",
+                  "GPSDateStamp",
+                  0
+                };
+                static const string_vector gps_str (gps_str_fields);
+                static const octave_idx_type n_gps_str = gps_str.numel ();
+                for (octave_idx_type field = 0; field < n_gps_str; field++)
+                  fill_exif (gps, cimg, gps_str[field]);
+
+                static const char *gps_int_fields[] = {
+                  "GPSDifferential",
+                  0
+                };
+                static const string_vector gps_int (gps_int_fields);
+                static const octave_idx_type n_gps_int = gps_int.numel ();
+                for (octave_idx_type field = 0; field < n_gps_int; field++)
+                  fill_exif_ints (gps, cimg, gps_int[field]);
+
+                static const char *gps_float_fields[] = {
+                  "GPSAltitude",
+                  "GPSDOP",
+                  "GPSSpeed",
+                  "GPSTrack",
+                  "GPSImgDirection",
+                  "GPSDestBearing",
+                  "GPSDestDistance",
+                  "GPSHPositioningError",
+                  // Listed as RATIONAL or SRATIONAL with more than 1 count.
+                  "GPSLatitude",
+                  "GPSLongitude",
+                  "GPSTimeStamp",
+                  "GPSDestLatitude",
+                  "GPSDestLongitude",
+                  0
+                };
+                static const string_vector gps_float (gps_float_fields);
+                static const octave_idx_type n_gps_float = gps_float.numel ();
+                for (octave_idx_type field = 0; field < n_gps_float; field++)
+                  fill_exif_floats (gps, cimg, gps_float[field]);
+
+              }
+          }
+        info_frame.setfield ("DigitalCamera", octave_value (camera));
+        info_frame.setfield ("GPSInfo",       octave_value (gps));
+      }
+
+      info.fast_elem_insert (frame, info_frame);
+    }
+
+  if (format == "GIF")
+    {
+      static std::map<octave_idx_type, std::string> disposal_methods
+        = init_disposal_methods ();
+      string_vector methods (nFrames);
+      for (octave_idx_type frame = 0; frame < nFrames; frame++)
+        methods[frame] = disposal_methods[imvec[frame].gifDisposeMethod ()];
+      info.setfield ("DisposalMethod", Cell (methods));
+    }
+  else
+    info.setfield ("DisposalMethod",
+                   Cell (dim_vector (nFrames, 1), octave_value ("")));
+
+  retval = octave_value (info);
 #endif
   return retval;
 }
@@ -1300,8 +2102,6 @@
 %!assert (1)
 */
 
-#undef GET_PARAM
-
 DEFUN_DLD (__magick_formats__, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {} __magick_imformats__ (@var{formats})\n\
@@ -1314,7 +2114,7 @@
 #ifndef HAVE_MAGICK
   gripe_disabled_feature ("imformats", "Image IO");
 #else
-  if (args.length () != 1 || ! args (0).is_map ())
+  if (args.length () != 1 || ! args(0).is_map ())
     {
       print_usage ();
       return retval;
--- a/libinterp/dldfcn/chol.cc
+++ b/libinterp/dldfcn/chol.cc
@@ -103,8 +103,8 @@
 @end ifnottex\n\
 \n\
 The sparsity preserving permutation is generally returned as a matrix.\n\
-However, given the flag \"vector\", @var{Q} will be returned as a vector\n\
-such that\n\
+However, given the flag @qcode{\"vector\"}, @var{Q} will be returned as a\n\
+vector such that\n\
 @tex\n\
 $ R^T R = A (Q, Q)$.\n\
 @end tex\n\
@@ -116,8 +116,8 @@
 \n\
 @end ifnottex\n\
 \n\
-Called with either a sparse or full matrix and using the \"lower\" flag,\n\
-@code{chol} returns the lower triangular factorization such that\n\
+Called with either a sparse or full matrix and using the @qcode{\"lower\"}\n\
+flag, @code{chol} returns the lower triangular factorization such that\n\
 @tex\n\
 $ L L^T = A $.\n\
 @end tex\n\
@@ -129,9 +129,9 @@
 \n\
 @end ifnottex\n\
 \n\
-For full matrices, if the \"lower\" flag is set only the lower triangular\n\
-part of the matrix is used for the factorization, otherwise the upper\n\
-triangular part is used.\n\
+For full matrices, if the @qcode{\"lower\"} flag is set only the lower\n\
+triangular part of the matrix is used for the factorization, otherwise the\n\
+upper triangular part is used.\n\
 \n\
 In general the lower triangular factorization is significantly faster for\n\
 sparse matrices.\n\
@@ -631,14 +631,14 @@
 @itemize @bullet\n\
 @item\n\
 @var{R1}'*@var{R1} = @var{R}'*@var{R} + @var{u}*@var{u}'\n\
-if @var{op} is \"+\"\n\
+if @var{op} is @qcode{\"+\"}\n\
 \n\
 @item\n\
 @var{R1}'*@var{R1} = @var{R}'*@var{R} - @var{u}*@var{u}'\n\
-if @var{op} is \"-\"\n\
+if @var{op} is @qcode{\"-\"}\n\
 @end itemize\n\
 \n\
-If @var{op} is \"-\", @var{info} is set to\n\
+If @var{op} is @qcode{\"-\"}, @var{info} is set to\n\
 \n\
 @itemize\n\
 @item 0 if the downdate was successful,\n\
--- a/libinterp/dldfcn/colamd.cc
+++ b/libinterp/dldfcn/colamd.cc
@@ -651,7 +651,8 @@
 is assumed to be symmetric and the symmetric elimination tree is\n\
 returned.  The argument @var{typ} controls whether a symmetric or\n\
 column elimination tree is returned.  Valid values of @var{typ} are\n\
-\"sym\" or \"col\", for symmetric or column elimination tree respectively\n\
+@qcode{\"sym\"} or @qcode{\"col\"}, for symmetric or column elimination tree\n\
+respectively.\n\
 \n\
 Called with a second argument, @code{etree} also returns the postorder\n\
 permutations on the tree.\n\
--- a/libinterp/dldfcn/fftw.cc
+++ b/libinterp/dldfcn/fftw.cc
@@ -70,31 +70,32 @@
 wisdom can be treated:\n\
 \n\
 @table @asis\n\
-@item \"estimate\"\n\
+@item @qcode{\"estimate\"}\n\
 Specifies that no run-time measurement of the optimal means of\n\
 calculating a particular is performed, and a simple heuristic is used\n\
 to pick a (probably sub-optimal) plan.  The advantage of this method is\n\
 that there is little or no overhead in the generation of the plan, which\n\
 is appropriate for a Fourier transform that will be calculated once.\n\
 \n\
-@item \"measure\"\n\
+@item @qcode{\"measure\"}\n\
 In this case a range of algorithms to perform the transform is considered\n\
 and the best is selected based on their execution time.\n\
 \n\
-@item \"patient\"\n\
-Similar to \"measure\", but a wider range of algorithms is considered.\n\
+@item @qcode{\"patient\"}\n\
+Similar to @qcode{\"measure\"}, but a wider range of algorithms is\n\
+considered.\n\
 \n\
-@item \"exhaustive\"\n\
-Like \"measure\", but all possible algorithms that may be used to\n\
+@item @qcode{\"exhaustive\"}\n\
+Like @qcode{\"measure\"}, but all possible algorithms that may be used to\n\
 treat the transform are considered.\n\
 \n\
-@item \"hybrid\"\n\
+@item @qcode{\"hybrid\"}\n\
 As run-time measurement of the algorithm can be expensive, this is a\n\
-compromise where \"measure\" is used for transforms up to the size of 8192\n\
-and beyond that the \"estimate\" method is used.\n\
+compromise where @qcode{\"measure\"} is used for transforms up to the size\n\
+of 8192 and beyond that the @qcode{\"estimate\"} method is used.\n\
 @end table\n\
 \n\
-The default method is \"estimate\".  The current method can\n\
+The default method is @qcode{\"estimate\"}.  The current method can\n\
 be queried with\n\
 \n\
 @example\n\
--- a/libinterp/dldfcn/module-files
+++ b/libinterp/dldfcn/module-files
@@ -1,6 +1,7 @@
 # FILE|CPPFLAGS|LDFLAGS|LIBRARIES
 __delaunayn__.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
 __dsearchn__.cc
+__eigs__.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)
 __fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
 __glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS)
 __init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) $(OPENGL_LIBS)
@@ -13,7 +14,6 @@
 colamd.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
 convhulln.cc|$(QHULL_CPPFLAGS)|$(QHULL_LDFLAGS)|$(QHULL_LIBS)
 dmperm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
-eigs.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)
 fftw.cc|$(FFTW_XCPPFLAGS)|$(FFTW_XLDFLAGS)|$(FFTW_XLIBS)
 qr.cc|$(QRUPDATE_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(QRUPDATE_LDFLAGS) $(SPARSE_XLDFLAGS)|$(QRUPDATE_LIBS) $(SPARSE_XLIBS)
 symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
--- a/libinterp/dldfcn/qr.cc
+++ b/libinterp/dldfcn/qr.cc
@@ -133,7 +133,7 @@
 @var{R} is upper triangular.\n\
 @end ifnottex\n\
 \n\
-If given a second argument of '0', @code{qr} returns an economy-sized\n\
+If given a second argument of @qcode{'0'}, @code{qr} returns an economy-sized\n\
 QR@tie{}factorization, omitting zero rows of @var{R} and the corresponding\n\
 columns of @var{Q}.\n\
 \n\
@@ -942,13 +942,13 @@
 @w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
 @var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
 @w{[A(:,1:j-1) x A(:,j:n)]}, where @var{u} is a column vector to be\n\
-inserted into @var{A} (if @var{orient} is @code{\"col\"}), or the\n\
+inserted into @var{A} (if @var{orient} is @qcode{\"col\"}), or the\n\
 QR@tie{}factorization of @w{[A(1:j-1,:);x;A(:,j:n)]}, where @var{x}\n\
 is a row vector to be inserted into @var{A} (if @var{orient} is\n\
-@code{\"row\"}).\n\
+@qcode{\"row\"}).\n\
 \n\
-The default value of @var{orient} is @code{\"col\"}.\n\
-If @var{orient} is @code{\"col\"},\n\
+The default value of @var{orient} is @qcode{\"col\"}.\n\
+If @var{orient} is @qcode{\"col\"},\n\
 @var{u} may be a matrix and @var{j} an index vector\n\
 resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
 @w{B(:,@var{j})} gives @var{u} and @w{B(:,@var{j}) = []} gives @var{A}.\n\
@@ -956,11 +956,11 @@
 thus, for k large enough, it will be both faster and more accurate to\n\
 recompute the factorization from scratch.\n\
 \n\
-If @var{orient} is @code{\"col\"},\n\
+If @var{orient} is @qcode{\"col\"},\n\
 the QR@tie{}factorization supplied may be either full\n\
 (Q is square) or economized (R is square).\n\
 \n\
-If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+If @var{orient} is @qcode{\"row\"}, full factorization is needed.\n\
 @seealso{qr, qrupdate, qrdelete, qrshift}\n\
 @end deftypefn")
 {
@@ -1161,13 +1161,13 @@
 @w{@var{A} = @var{Q}*@var{R}}, @var{Q}@tie{}unitary and\n\
 @var{R}@tie{}upper trapezoidal, return the QR@tie{}factorization of\n\
 @w{[A(:,1:j-1) A(:,j+1:n)]}, i.e., @var{A} with one column deleted\n\
-(if @var{orient} is \"col\"), or the QR@tie{}factorization of\n\
+(if @var{orient} is @qcode{\"col\"}), or the QR@tie{}factorization of\n\
 @w{[A(1:j-1,:);A(j+1:n,:)]}, i.e., @var{A} with one row deleted (if\n\
-@var{orient} is \"row\").\n\
+@var{orient} is @qcode{\"row\"}).\n\
 \n\
-The default value of @var{orient} is \"col\".\n\
+The default value of @var{orient} is @qcode{\"col\"}.\n\
 \n\
-If @var{orient} is @code{\"col\"},\n\
+If @var{orient} is @qcode{\"col\"},\n\
 @var{j} may be an index vector\n\
 resulting in the QR@tie{}factorization of a matrix @var{B} such that\n\
 @w{A(:,@var{j}) = []} gives @var{B}.\n\
@@ -1175,11 +1175,11 @@
 thus, for k large enough, it will be both faster and more accurate to\n\
 recompute the factorization from scratch.\n\
 \n\
-If @var{orient} is @code{\"col\"},\n\
+If @var{orient} is @qcode{\"col\"},\n\
 the QR@tie{}factorization supplied may be either full\n\
 (Q is square) or economized (R is square).\n\
 \n\
-If @var{orient} is @code{\"row\"}, full factorization is needed.\n\
+If @var{orient} is @qcode{\"row\"}, full factorization is needed.\n\
 @seealso{qr, qrupdate, qrinsert, qrshift}\n\
 @end deftypefn")
 {
@@ -1392,7 +1392,7 @@
 %! assert (norm (vec (triu (R) - R), Inf) == 0);
 %! assert (norm (vec (Q*R - [AA(1:2,:);AA(4:5,:)]), Inf) < norm (AA)*1e1*eps ("single"));
 %!testif HAVE_QRUPDATE
-%! # Same test as above but with more precicision
+%! ## Same test as above but with more precicision
 %! AA = single ([0.091364  0.613038  0.027504  0.999083;
 %!               0.594638  0.425302  0.562834  0.603537;
 %!               0.383594  0.291238  0.742073  0.085574;
--- a/libinterp/dldfcn/symbfact.cc
+++ b/libinterp/dldfcn/symbfact.cc
@@ -63,18 +63,18 @@
 Factorize @code{@var{S}' * @var{S}}.\n\
 \n\
 @item row\n\
-Factorize @xcode{@var{S} * @var{S}'}.\n\
+Factorize @tcode{@var{S} * @var{S}'}.\n\
 \n\
 @item lo\n\
-Factorize @xcode{@var{S}'}\n\
+Factorize @tcode{@var{S}'}\n\
 @end table\n\
 \n\
 @item mode\n\
 The default is to return the Cholesky@tie{}factorization for @var{r}, and if\n\
-@var{mode} is 'L', the conjugate transpose of the Cholesky@tie{}factorization\n\
-is returned.  The conjugate transpose version is faster and uses less\n\
-memory, but returns the same values for @var{count}, @var{h}, @var{parent}\n\
-and @var{post} outputs.\n\
+@var{mode} is @qcode{'L'}, the conjugate transpose of the\n\
+Cholesky@tie{}factorization is returned.  The conjugate transpose version is\n\
+faster and uses less memory, but returns the same values for @var{count},\n\
+@var{h}, @var{parent} and @var{post} outputs.\n\
 @end table\n\
 \n\
 The output variables are\n\
--- a/libinterp/dldfcn/urlwrite.cc
+++ b/libinterp/dldfcn/urlwrite.cc
@@ -48,6 +48,7 @@
 #include "oct-map.h"
 #include "oct-refcount.h"
 #include "unwind-prot.h"
+#include "gripes.h"
 
 #ifdef HAVE_CURL
 
@@ -843,7 +844,7 @@
     error ("urlwrite: curl: %s", curl.lasterror ().c_str ());
 
 #else
-  error ("urlwrite: not available in this version of Octave");
+  gripe_disabled_feature ("urlwrite", "urlwrite");
 #endif
 
   return retval;
@@ -962,7 +963,7 @@
     error ("urlread: curl: %s", curl.lasterror().c_str());
 
 #else
-  error ("urlread: not available in this version of Octave");
+  gripe_disabled_feature ("urlread", "urlread");
 #endif
 
   return retval;
@@ -1004,7 +1005,7 @@
         }
     }
 #else
-  error ("__ftp__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp__", "FTP");
 #endif
 
   return octave_value ();
@@ -1037,7 +1038,7 @@
         }
     }
 #else
-  error ("__ftp_pwd__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_pwd__", "FTP");
 #endif
 
   return retval;
@@ -1073,7 +1074,7 @@
         }
     }
 #else
-  error ("__ftp_cwd__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_cwd__", "FTP");
 #endif
 
   return octave_value ();
@@ -1153,7 +1154,7 @@
         }
     }
 #else
-  error ("__ftp_dir__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_dir__", "FTP");
 #endif
 
   return retval;
@@ -1185,7 +1186,7 @@
         }
     }
 #else
-  error ("__ftp_ascii__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_ascii__", "FTP");
 #endif
 
   return octave_value ();
@@ -1217,7 +1218,7 @@
         }
     }
 #else
-  error ("__ftp_binary__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_binary__", "FTP");
 #endif
 
   return octave_value ();
@@ -1226,46 +1227,46 @@
 DEFUN_DLD (__ftp_close__, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {} __ftp_close__ (@var{handle})\n\
- Undocumented internal function\n\
- @end deftypefn")
- {
- #ifdef HAVE_CURL
-   int nargin = args.length ();
+Undocumented internal function\n\
+@end deftypefn")
+{
+#ifdef HAVE_CURL
+  int nargin = args.length ();
 
-   if (nargin != 1)
-     error ("__ftp_close__: incorrect number of arguments");
-   else
-     {
-       std::string handle = args(0).string_value ();
+  if (nargin != 1)
+    error ("__ftp_close__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
 
-       if (!error_state)
-         handles.del (handle);
-     }
- #else
-   error ("__ftp_close__: not available in this version of Octave");
- #endif
+      if (! error_state)
+        handles.del (handle);
+    }
+#else
+  gripe_disabled_feature ("__ftp_close__", "FTP");
+#endif
 
-   return octave_value ();
- }
+  return octave_value ();
+}
 
 DEFUN_DLD (__ftp_mode__, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {} __ftp_mode__ (@var{handle})\n\
- Undocumented internal function\n\
- @end deftypefn")
- {
-   octave_value retval;
- #ifdef HAVE_CURL
-   int nargin = args.length ();
+Undocumented internal function\n\
+@end deftypefn")
+{
+  octave_value retval;
+#ifdef HAVE_CURL
+  int nargin = args.length ();
 
-   if (nargin != 1)
-     error ("__ftp_mode__: incorrect number of arguments");
-   else
-     {
-       std::string handle = args(0).string_value ();
+  if (nargin != 1)
+    error ("__ftp_mode__: incorrect number of arguments");
+  else
+    {
+      std::string handle = args(0).string_value ();
 
 
-      if (!error_state)
+      if (! error_state)
         {
           const curl_handle curl = handles.contents (handle);
 
@@ -1274,13 +1275,13 @@
           else
             error ("__ftp_binary__: invalid ftp handle");
         }
-     }
- #else
-   error ("__ftp_mode__: not available in this version of Octave");
- #endif
+    }
+#else
+  gripe_disabled_feature ("__ftp_mode__", "FTP");
+#endif
 
-   return retval;
- }
+  return retval;
+}
 
 DEFUN_DLD (__ftp_delete__, args, ,
   "-*- texinfo -*-\n\
@@ -1309,7 +1310,7 @@
         }
     }
 #else
-  error ("__ftp_delete__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_delete__", "FTP");
 #endif
 
   return octave_value ();
@@ -1342,7 +1343,7 @@
         }
     }
 #else
-  error ("__ftp_rmdir__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_rmdir__", "FTP");
 #endif
 
   return octave_value ();
@@ -1375,7 +1376,7 @@
         }
     }
 #else
-  error ("__ftp_mkdir__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_mkdir__", "FTP");
 #endif
 
   return octave_value ();
@@ -1409,7 +1410,7 @@
         }
     }
 #else
-  error ("__ftp_rename__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_rename__", "FTP");
 #endif
 
   return octave_value ();
@@ -1574,7 +1575,7 @@
         }
     }
 #else
-  error ("__ftp_mput__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_mput__", "FTP");
 #endif
 
   return (nargout > 0 ? octave_value (retval) : octave_value ());
@@ -1735,7 +1736,7 @@
         }
     }
 #else
-  error ("__ftp_mget__: not available in this version of Octave");
+  gripe_disabled_feature ("__ftp_mget__", "FTP");
 #endif
 
   return octave_value ();
--- a/libinterp/gendoc.pl
+++ b/libinterp/gendoc.pl
@@ -64,7 +64,7 @@
   foreach $i (0 .. $#func_list)
   {
     $func = $func_list[$i];
-    print "$func\n";
+    print "\x{1d}$func\n";
     print "\@c $func $src_fname\n";
     print $docstr[$i],"\n";
   }
--- a/libinterp/octave-value/ov-base.cc
+++ b/libinterp/octave-value/ov-base.cc
@@ -1565,9 +1565,9 @@
 @end group\n\
 @end example\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (sparse_auto_mutate);
--- a/libinterp/octave-value/ov-bool-sparse.cc
+++ b/libinterp/octave-value/ov-bool-sparse.cc
@@ -273,7 +273,7 @@
     swap_bytes<4> (&tmp);
 
   if (tmp != -2) {
-    error ("load: only 2D sparse matrices are supported");
+    error ("load: only 2-D sparse matrices are supported");
     return false;
   }
 
--- a/libinterp/octave-value/ov-cx-sparse.cc
+++ b/libinterp/octave-value/ov-cx-sparse.cc
@@ -305,7 +305,7 @@
     swap_bytes<4> (&tmp);
 
   if (tmp != -2) {
-    error ("load: only 2D sparse matrices are supported");
+    error ("load: only 2-D sparse matrices are supported");
     return false;
   }
 
--- a/libinterp/octave-value/ov-fcn-handle.cc
+++ b/libinterp/octave-value/ov-fcn-handle.cc
@@ -1792,8 +1792,8 @@
 @deftypefn  {Built-in Function} {} str2func (@var{fcn_name})\n\
 @deftypefnx {Built-in Function} {} str2func (@var{fcn_name}, \"global\")\n\
 Return a function handle constructed from the string @var{fcn_name}.\n\
-If the optional \"global\" argument is passed, locally visible functions\n\
-are ignored in the lookup.\n\
+If the optional @qcode{\"global\"} argument is passed, locally visible\n\
+functions are ignored in the lookup.\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/octave-value/ov-fcn-inline.cc
+++ b/libinterp/octave-value/ov-fcn-inline.cc
@@ -652,7 +652,7 @@
 they are the names of the arguments of the function.\n\
 \n\
 If the second argument is an integer @var{n}, the arguments are\n\
-@code{\"x\"}, @code{\"P1\"}, @dots{}, @code{\"P@var{N}\"}.\n\
+@qcode{\"x\"}, @qcode{\"P1\"}, @dots{}, @qcode{\"P@var{N}\"}.\n\
 @seealso{argnames, formula, vectorize}\n\
 @end deftypefn")
 {
--- a/libinterp/octave-value/ov-java.cc
+++ b/libinterp/octave-value/ov-java.cc
@@ -2304,9 +2304,9 @@
 Query or set the internal variable that controls whether Java arrays are\n\
 automatically converted to Octave matrices.  The default value is false.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{java_unsigned_autoconversion, debug_java}\n\
 @end deftypefn")
 {
@@ -2328,9 +2328,9 @@
 Java arrays of class Byte or Integer are converted to matrices of class\n\
 uint8 or uint32 respectively.  The default value is true.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{java_matrix_autoconversion, debug_java}\n\
 @end deftypefn")
 {
@@ -2351,9 +2351,9 @@
 information regarding the initialization of the JVM and any Java exceptions\n\
 is printed.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @seealso{java_matrix_autoconversion, java_unsigned_autoconversion}\n\
 @end deftypefn")
 {
--- a/libinterp/octave-value/ov-range.cc
+++ b/libinterp/octave-value/ov-range.cc
@@ -688,9 +688,9 @@
 compatibility; however, it is still not entirely compatible because\n\
 @sc{matlab} treats the range expression differently in different contexts.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (allow_noninteger_range_as_index);
--- a/libinterp/octave-value/ov-re-sparse.cc
+++ b/libinterp/octave-value/ov-re-sparse.cc
@@ -338,7 +338,7 @@
     swap_bytes<4> (&tmp);
 
   if (tmp != -2) {
-    error ("load: only 2D sparse matrices are supported");
+    error ("load: only 2-D sparse matrices are supported");
     return false;
   }
 
--- a/libinterp/octave-value/ov-struct.cc
+++ b/libinterp/octave-value/ov-struct.cc
@@ -2285,9 +2285,9 @@
 Query or set the internal variable that specifies the number of\n\
 structure levels to display.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE_WITH_LIMITS (struct_levels_to_print, -1,
@@ -2305,9 +2305,9 @@
 are always printed.  In both cases, however, printing will be limited to\n\
 the number of levels specified by @var{struct_levels_to_print}.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (print_struct_array_contents);
--- a/libinterp/octave-value/ov-usr-fcn.cc
+++ b/libinterp/octave-value/ov-usr-fcn.cc
@@ -978,9 +978,9 @@
 If true, Octave will attempt to eliminate the redundant copying when calling\n\
 subsasgn method of a user-defined class.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (optimize_subsasgn_calls);
--- a/libinterp/parse-tree/lex.ll
+++ b/libinterp/parse-tree/lex.ll
@@ -250,7 +250,6 @@
 D       [0-9]
 S       [ \t]
 NL      ((\n)|(\r)|(\r\n))
-CONT    ((\.\.\.)|(\\))
 Im      [iIjJ]
 CCHAR   [#%]
 IDENT   ([_$a-zA-Z][_$a-zA-Z0-9]*)
@@ -694,6 +693,21 @@
       curr_lexer->string_text += static_cast<unsigned char> (result);
   }
 
+<DQ_STRING_START>\\x[0-9a-fA-F]+ {
+    curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\x[0-9a-fA-F]+");
+
+    curr_lexer->current_input_column += yyleng;
+
+    int result;
+    sscanf (yytext+2, "%x", &result);
+
+    // Truncate the value silently instead of checking the range like
+    // we do for octal above.  This is to match C/C++ where any number
+    // of digits is allowed but the value is implementation-defined if
+    // it exceeds the range of the character type.
+    curr_lexer->string_text += static_cast<unsigned char> (result);
+  }
+
 <DQ_STRING_START>"\\a" {
     curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\a\"");
 
@@ -946,12 +960,33 @@
   }
 
 %{
-// Continuation lines.  Allow comments after continuations.
+// Continuation lines.  Allow arbitrary text after continuations.
+%}
+
+\.\.\..*{NL} {
+    curr_lexer->lexer_debug ("\\.\\.\\..*{NL}");
+
+    curr_lexer->handle_continuation ();
+  }
+
+%{
+// Deprecated C preprocessor style continuation markers.
 %}
 
-{CONT}{S}*{NL} |
-{CONT}{S}*{CCHAR}.*{NL} {
-    curr_lexer->lexer_debug ("{CONT}{S}*{NL}|{CONT}{S}*{CCHAR}.*{NL}");
+\\{S}*{NL} |
+\\{S}*{CCHAR}.*{NL} {
+    curr_lexer->lexer_debug ("\\\\{S}*{NL}|\\\\{S}*{CCHAR}.*{NL}");
+
+    static const char *msg = "using continuation marker \\ outside of double quoted strings is deprecated and will be removed in a future version of Octave";
+
+    std::string nm = curr_lexer->fcn_file_full_name;
+
+    if (nm.empty ())
+      warning_with_id ("Octave:deprecated-syntax", "%s", msg);
+    else
+      warning_with_id ("Octave:deprecated-syntax",
+                       "%s; near line %d of file '%s'", msg,
+                       curr_lexer->input_line_number, nm.c_str ());
 
     curr_lexer->handle_continuation ();
   }
@@ -2688,11 +2723,7 @@
       return kw_token;
     }
 
-  // Find the token in the symbol table.  Beware the magic
-  // transformation of the end keyword...
-
-  if (tok == "end")
-    tok = "__end__";
+  // Find the token in the symbol table.
 
   symbol_table::scope_id sid = symtab_context.curr_scope ();
 
@@ -2719,7 +2750,9 @@
 
   current_input_column += flex_yyleng ();
 
-  if (tok != "__end__")
+  // The magic end index can't be indexed.
+
+  if (tok != "end")
     looking_for_object_index = true;
 
   at_beginning_of_statement = false;
--- a/libinterp/parse-tree/module.mk
+++ b/libinterp/parse-tree/module.mk
@@ -1,5 +1,6 @@
 EXTRA_DIST += \
   parse-tree/module.mk \
+  parse-tree/oct-parse.in.yy \
   parse-tree/octave.gperf
 
 PARSER_INC = \
--- a/libinterp/parse-tree/oct-parse.in.yy
+++ b/libinterp/parse-tree/oct-parse.in.yy
@@ -259,12 +259,12 @@
 %type <tree_switch_command_type> switch_command
 %type <tree_switch_case_type> switch_case default_case
 %type <tree_switch_case_list_type> case_list1 case_list
-%type <tree_decl_elt_type> decl2
+%type <tree_decl_elt_type> decl2 param_list_elt
 %type <tree_decl_init_list_type> decl1
 %type <tree_decl_command_type> declaration
 %type <tree_statement_type> statement function_end classdef_end
 %type <tree_statement_list_type> simple_list simple_list1 list list1
-%type <tree_statement_list_type> opt_list input1
+%type <tree_statement_list_type> opt_list
 // These types need to be specified.
 %type <dummy_type> attr
 %type <dummy_type> class_event
@@ -307,33 +307,24 @@
 // Statements and statement lists
 // ==============================
 
-input           : input1
+input           : simple_list '\n'
                   {
                     parser.stmt_list = $1;
                     YYACCEPT;
                   }
-                | simple_list parse_error
-                  { ABORT_PARSE; }
+                | simple_list END_OF_INPUT
+                  {
+                    lexer.end_of_input = true;
+                    parser.stmt_list = $1;
+                    YYACCEPT;
+                  }
                 | parse_error
                   { ABORT_PARSE; }
                 ;
 
-input1          : '\n'
+simple_list     : opt_sep_no_nl
                   { $$ = 0; }
-                | END_OF_INPUT
-                  {
-                    lexer.end_of_input = true;
-                    $$ = 0;
-                  }
-                | simple_list
-                  { $$ = $1; }
-                | simple_list '\n'
-                  { $$ = $1; }
-                | simple_list END_OF_INPUT
-                  { $$ = $1; }
-                ;
-
-simple_list     : simple_list1 opt_sep_no_nl
+                | simple_list1 opt_sep_no_nl
                   { $$ = parser.set_stmt_print_flag ($1, $2, false); }
                 ;
 
@@ -798,10 +789,6 @@
                     lexer.looking_at_initializer_expression = false;
                     $$ = new tree_decl_elt ($1, $4);
                   }
-                | magic_tilde
-                  {
-                    $$ = new tree_decl_elt ($1);
-                  }
                 ;
 
 // ====================
@@ -975,15 +962,15 @@
                     if (! ($$ = parser.make_unwind_command ($1, $4, $8, $9, $2, $6)))
                       ABORT_PARSE;
                   }
-                | TRY stash_comment opt_sep opt_list CATCH
-                  stash_comment opt_sep opt_list END
+                | TRY stash_comment opt_sep opt_list CATCH stash_comment
+                  opt_sep opt_list END
                   {
-                    if (! ($$ = parser.make_try_command ($1, $4, $8, $9, $2, $6)))
+                    if (! ($$ = parser.make_try_command ($1, $4, $7, $8, $9, $2, $6)))
                       ABORT_PARSE;
                   }
                 | TRY stash_comment opt_sep opt_list END
                   {
-                    if (! ($$ = parser.make_try_command ($1, $4, 0, $5, $2, 0)))
+                    if (! ($$ = parser.make_try_command ($1, $4, 0, 0, $5, $2, 0)))
                       ABORT_PARSE;
                   }
                 ;
@@ -1070,15 +1057,21 @@
                   }
                 ;
 
-param_list2     : decl2
+param_list2     : param_list_elt
                   { $$ = new tree_parameter_list ($1); }
-                | param_list2 ',' decl2
+                | param_list2 ',' param_list_elt
                   {
                     $1->append ($3);
                     $$ = $1;
                   }
                 ;
 
+param_list_elt  : decl2
+                  { $$ = $1; }
+                | magic_tilde
+                  { $$ = new tree_decl_elt ($1); }
+                ;
+
 // ===================================
 // List of function return value names
 // ===================================
@@ -1086,19 +1079,31 @@
 return_list     : '[' ']'
                   {
                     lexer.looking_at_return_list = false;
+
                     $$ = new tree_parameter_list ();
                   }
-                | return_list1
+                | identifier
                   {
                     lexer.looking_at_return_list = false;
-                    if ($1->validate (tree_parameter_list::out))
-                      $$ = $1;
+
+                    tree_parameter_list *tmp = new tree_parameter_list ($1);
+
+                    // Even though this parameter list can contain only
+                    // a single identifier, we still need to validate it
+                    // to check for varargin or varargout.
+
+                    if (tmp->validate (tree_parameter_list::out))
+                      $$ = tmp;
                     else
                       ABORT_PARSE;
                   }
                 | '[' return_list1 ']'
                   {
                     lexer.looking_at_return_list = false;
+
+                    // Check for duplicate parameter names, varargin,
+                    // or varargout.
+
                     if ($2->validate (tree_parameter_list::out))
                       $$ = $2;
                     else
@@ -2190,6 +2195,7 @@
 tree_command *
 octave_base_parser::make_try_command (token *try_tok,
                                       tree_statement_list *body,
+                                      char catch_sep,
                                       tree_statement_list *cleanup_stmts,
                                       token *end_tok,
                                       octave_comment_list *lc,
@@ -2204,7 +2210,26 @@
       int l = try_tok->line ();
       int c = try_tok->column ();
 
-      retval = new tree_try_catch_command (body, cleanup_stmts,
+      tree_identifier *id = 0;
+
+      if (! catch_sep && cleanup_stmts && ! cleanup_stmts->empty ())
+        {
+          tree_statement *stmt = cleanup_stmts->front ();
+
+          if (stmt)
+            {
+              tree_expression *expr = stmt->expression ();
+
+              if (expr && expr->is_identifier ())
+                {
+                  id = dynamic_cast<tree_identifier *> (expr);
+
+                  cleanup_stmts->pop_front ();
+                }
+            }
+        }
+
+      retval = new tree_try_catch_command (body, cleanup_stmts, id,
                                            lc, mc, tc, l, c);
     }
 
@@ -3521,7 +3546,7 @@
 
 DEFUN (autoload, args, ,
   "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} autoload (@var{function}, @var{file})\n\
+@deftypefn  {Built-in Function} {} autoload (@var{function}, @var{file})\n\
 @deftypefnx {Built-in Function} {} autoload (@dots{}, @asis{\"remove\"})\n\
 Define @var{function} to autoload from @var{file}.\n\
 \n\
@@ -3751,9 +3776,9 @@
 @deftypefnx {Built-in Function} {} mfilename (\"fullpath\")\n\
 @deftypefnx {Built-in Function} {} mfilename (\"fullpathext\")\n\
 Return the name of the currently executing file.  At the top-level,\n\
-return the empty string.  Given the argument @code{\"fullpath\"},\n\
+return the empty string.  Given the argument @qcode{\"fullpath\"},\n\
 include the directory part of the file name, but not the extension.\n\
-Given the argument @code{\"fullpathext\"}, include the directory part\n\
+Given the argument @qcode{\"fullpathext\"}, include the directory part\n\
 of the file name and the extension.\n\
 @end deftypefn")
 {
@@ -4272,7 +4297,7 @@
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} assignin (@var{context}, @var{varname}, @var{value})\n\
 Assign @var{value} to @var{varname} in context @var{context}, which\n\
-may be either @code{\"base\"} or @code{\"caller\"}.\n\
+may be either @qcode{\"base\"} or @qcode{\"caller\"}.\n\
 @seealso{evalin}\n\
 @end deftypefn")
 {
@@ -4326,8 +4351,8 @@
 @deftypefn  {Built-in Function} {} evalin (@var{context}, @var{try})\n\
 @deftypefnx {Built-in Function} {} evalin (@var{context}, @var{try}, @var{catch})\n\
 Like @code{eval}, except that the expressions are evaluated in the\n\
-context @var{context}, which may be either @code{\"caller\"} or\n\
-@code{\"base\"}.\n\
+context @var{context}, which may be either @qcode{\"caller\"} or\n\
+@qcode{\"base\"}.\n\
 @seealso{eval, assignin}\n\
 @end deftypefn")
 {
@@ -4410,3 +4435,54 @@
 
   return retval;
 }
+
+DEFUN (__parse_file__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __parse_file__ (@var{file}, @var{verbose})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1 || nargin == 2)
+    {
+      std::string file = args(0).string_value ();
+      
+      std::string full_file = octave_env::make_absolute (file);
+
+      size_t file_len = file.length ();
+
+      if ((file_len > 4 && file.substr (file_len-4) == ".oct")
+          || (file_len > 4 && file.substr (file_len-4) == ".mex")
+          || (file_len > 2 && file.substr (file_len-2) == ".m"))
+        {
+          file = octave_env::base_pathname (file);
+          file = file.substr (0, file.find_last_of ('.'));
+
+          size_t pos = file.find_last_of (file_ops::dir_sep_str ());
+          if (pos != std::string::npos)
+            file = file.substr (pos+1);
+        }
+
+      if (! error_state)
+        {
+          if (nargin == 2)
+            octave_stdout << "parsing " << full_file << std::endl;
+
+          octave_function *fcn = parse_fcn_file (full_file, file, "",
+                                                 true, false, false,
+                                                 false, "__parse_file__");
+
+          if (fcn)
+            delete fcn;
+        }
+      else
+        error ("__parse_file__: expecting file name as argument");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
--- a/libinterp/parse-tree/parse.h
+++ b/libinterp/parse-tree/parse.h
@@ -201,8 +201,9 @@
   // Build a try-catch command.
   tree_command *
   make_try_command (token *try_tok, tree_statement_list *body,
-                    tree_statement_list *cleanup, token *end_tok,
-                    octave_comment_list *lc, octave_comment_list *mc);
+                    char catch_sep, tree_statement_list *cleanup,
+                    token *end_tok, octave_comment_list *lc,
+                    octave_comment_list *mc);
 
   // Build a while command.
   tree_command *
--- a/libinterp/parse-tree/pt-arg-list.cc
+++ b/libinterp/parse-tree/pt-arg-list.cc
@@ -126,7 +126,7 @@
 static int index_position = 0;
 static int num_indices = 0;
 
-DEFCONSTFUN (__end__, , ,
+DEFCONSTFUN (end, , ,
   "internal function")
 {
   octave_value retval;
--- a/libinterp/parse-tree/pt-binop.cc
+++ b/libinterp/parse-tree/pt-binop.cc
@@ -293,9 +293,9 @@
 To obtain short-circuit behavior for logical expressions in new programs,\n\
 you should always use the @samp{&&} and @samp{||} operators.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (do_braindead_shortcircuit_evaluation);
--- a/libinterp/parse-tree/pt-check.cc
+++ b/libinterp/parse-tree/pt-check.cc
@@ -499,6 +499,15 @@
 {
   tree_statement_list *try_code = cmd.body ();
 
+  tree_identifier *expr_id = cmd.identifier ();
+
+  if (expr_id)
+    {
+      if (! expr_id->lvalue_ok ())
+        gripe ("invalid lvalue used for identifier in try-catch command",
+               cmd.line ());
+    }
+
   if (try_code)
     try_code->accept (*this);
 
--- a/libinterp/parse-tree/pt-eval.cc
+++ b/libinterp/parse-tree/pt-eval.cc
@@ -810,18 +810,18 @@
                 break;
               else
                 {
-                  // Clear preivous values before next statement is
+                  // Clear previous values before next statement is
                   // evaluated so that we aren't holding an extra
                   // reference to a value that may be used next.  For
                   // example, in code like this:
                   //
-                  //   X = rand (N);  ## refcount for X should be 1
-                  //                  ## after this statement
+                  //   X = rand (N);  # refcount for X should be 1
+                  //                  # after this statement
                   //
-                  //   X(idx) = val;  ## no extra copy of X should be
-                  //                  ## needed, but we will be faked
-                  //                  ## out if retval is not cleared
-                  //                  ## between statements here
+                  //   X(idx) = val;  # no extra copy of X should be
+                  //                  # needed, but we will be faked
+                  //                  # out if retval is not cleared
+                  //                  # between statements here
 
                   //              result_values = empty_list;
                 }
@@ -921,6 +921,27 @@
 
           buffer_error_messages--;
 
+          tree_identifier *expr_id = cmd.identifier ();
+          octave_lvalue ult;
+
+          if (expr_id)
+            {
+
+              octave_scalar_map err;
+
+              ult = expr_id->lvalue ();
+
+              if (error_state)
+                return;
+
+              err.assign ("message", last_error_message ());
+              err.assign ("identifier", last_error_id ());
+
+              if (! error_state)
+                ult.assign (octave_value::op_asn_eq, err);
+
+            }
+
           if (catch_code)
             catch_code->accept (*this);
         }
@@ -1243,9 +1264,9 @@
 be called recursively.  If the limit is exceeded, an error message is\n\
 printed and control returns to the top level.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.\n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (max_recursion_depth);
@@ -1273,9 +1294,9 @@
 Octave will display the results produced by evaluating expressions\n\
 within a function body that are not terminated with a semicolon.\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.\n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (silent_functions);
--- a/libinterp/parse-tree/pt-except.cc
+++ b/libinterp/parse-tree/pt-except.cc
@@ -33,6 +33,7 @@
 #include "pt-cmd.h"
 #include "pt-except.h"
 #include "pt-exp.h"
+#include "pt-id.h"
 #include "pt-jump.h"
 #include "pt-stmt.h"
 #include "pt-walk.h"
@@ -43,6 +44,7 @@
 
 tree_try_catch_command::~tree_try_catch_command (void)
 {
+  delete expr_id;
   delete try_code;
   delete catch_code;
   delete lead_comm;
@@ -57,6 +59,7 @@
   return new
     tree_try_catch_command (try_code ? try_code->dup (scope, context) : 0,
                             catch_code ? catch_code->dup (scope, context) : 0,
+                            expr_id ? expr_id->dup (scope, context) : 0,
                             lead_comm ? lead_comm->dup () : 0,
                             mid_comm ? mid_comm->dup () : 0,
                             trail_comm ? trail_comm->dup () : 0,
--- a/libinterp/parse-tree/pt-except.h
+++ b/libinterp/parse-tree/pt-except.h
@@ -29,6 +29,7 @@
 
 #include "comment-list.h"
 #include "pt-cmd.h"
+#include "pt-id.h"
 #include "symtab.h"
 
 // Simple exception handling.
@@ -39,19 +40,22 @@
 public:
 
   tree_try_catch_command (int l = -1, int c = -1)
-    : tree_command (l, c), try_code (0), catch_code (0), lead_comm (0),
+    : tree_command (l, c), try_code (0), catch_code (0), expr_id (0), lead_comm (0),
       mid_comm (0), trail_comm (0) { }
 
   tree_try_catch_command (tree_statement_list *tc, tree_statement_list *cc,
+                          tree_identifier *id,
                           octave_comment_list *cl = 0,
                           octave_comment_list *cm = 0,
                           octave_comment_list *ct = 0,
                           int l = -1, int c = -1)
-    : tree_command (l, c), try_code (tc), catch_code (cc),
+    : tree_command (l, c), try_code (tc), catch_code (cc), expr_id (id),
       lead_comm (cl), mid_comm (cm), trail_comm (ct) { }
 
   ~tree_try_catch_command (void);
 
+  tree_identifier *identifier (void) { return expr_id; }
+
   tree_statement_list *body (void) { return try_code; }
 
   tree_statement_list *cleanup (void) { return catch_code; }
@@ -75,6 +79,9 @@
   // The code to execute if an error occurs in the first block.
   tree_statement_list *catch_code;
 
+  // Identifier to modify.
+  tree_identifier *expr_id;
+
   // Comment preceding TRY token.
   octave_comment_list *lead_comm;
 
--- a/libinterp/parse-tree/pt-id.h
+++ b/libinterp/parse-tree/pt-id.h
@@ -55,7 +55,7 @@
 
   ~tree_identifier (void) { }
 
-  bool has_magic_end (void) const { return (name () == "__end__"); }
+  bool has_magic_end (void) const { return (name () == "end"); }
 
   bool is_identifier (void) const { return true; }
 
--- a/libinterp/parse-tree/pt-idx.cc
+++ b/libinterp/parse-tree/pt-idx.cc
@@ -360,7 +360,7 @@
                   // contains the second (or third, etc.) "end" token,
                   // so we must evaluate everything up to the point of
                   // that argument list so we can pass the appropriate
-                  // value to the built-in __end__ function.
+                  // value to the built-in end function.
 
                   const octave_value_list tmp_list
                     = tmp.subsref (type.substr (tmpi, i - tmpi), idx, nargout);
--- a/libinterp/parse-tree/pt-mat.cc
+++ b/libinterp/parse-tree/pt-mat.cc
@@ -1373,7 +1373,7 @@
 @deftypefnx {Built-in Function} {} string_fill_char (@var{new_val}, \"local\")\n\
 Query or set the internal variable used to pad all rows of a character\n\
 matrix to the same length.  It must be a single character.  The default\n\
-value is @code{\" \"} (a single space).  For example:\n\
+value is @qcode{\" \"} (a single space).  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -1385,9 +1385,9 @@
 @end group\n\
 @end example\n\
 \n\
-When called from inside a function with the \"local\" option, the variable is\n\
-changed locally for the function and any subroutines it calls.  The original\n\
-variable value is restored when exiting the function.\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
   return SET_INTERNAL_VARIABLE (string_fill_char);
--- a/libinterp/parse-tree/pt-misc.h
+++ b/libinterp/parse-tree/pt-misc.h
@@ -59,6 +59,9 @@
   tree_parameter_list (tree_decl_elt *t)
     : marked_for_varargs (0) { append (t); }
 
+  tree_parameter_list (tree_identifier *id)
+    : marked_for_varargs (0) { append (new tree_decl_elt (id)); }
+
   ~tree_parameter_list (void);
 
   void mark_as_formal_parameters (void);
--- a/libinterp/parse-tree/pt-pr-code.cc
+++ b/libinterp/parse-tree/pt-pr-code.cc
@@ -993,6 +993,7 @@
   newline ();
 
   tree_statement_list *try_code = cmd.body ();
+  tree_identifier *expr_id = cmd.identifier ();
 
   if (try_code)
     {
@@ -1009,6 +1010,12 @@
 
   os << "catch";
 
+  if (expr_id)
+    {
+      os << " ";
+      expr_id->accept (*this);
+    }
+
   newline ();
 
   tree_statement_list *catch_code = cmd.cleanup ();
--- a/liboctave/Makefile.am
+++ b/liboctave/Makefile.am
@@ -20,8 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-AUTOMAKE_OPTIONS = subdir-objects
-
 ## Run cruft dir with stand-alone Makefile.
 ## Eventually this will use module.mk syntax.
 SUBDIRS = cruft
@@ -125,7 +123,8 @@
   $(array_libarray_la_SOURCES) \
   $(numeric_libnumeric_la_SOURCES) \
   $(system_libsystem_la_SOURCES) \
-  $(util_libutil_la_SOURCES)
+  $(util_libutil_la_SOURCES) \
+  $(TEMPLATE_SRC)
 
 TST_FILES_SRC := $(shell $(top_srcdir)/build-aux/find-files-with-tests.sh "$(srcdir)" $(LIBOCTAVE_TST_SRC))
 
--- a/liboctave/array/Sparse.cc
+++ b/liboctave/array/Sparse.cc
@@ -2793,6 +2793,23 @@
 %! s(1,:) = [];
 %! assert (s, sparse ([], [], [], 0, 1));
 
+## Test (bug #37321)
+%!test a=sparse (0,0); assert (all (a) == sparse ([1]));
+%!test a=sparse (0,1); assert (all (a) == sparse ([1]));
+%!test a=sparse (1,0); assert (all (a) == sparse ([1]));
+%!test a=sparse (1,0); assert (all (a,2) == sparse ([1]));
+%!test a=sparse (1,0); assert (size (all (a,1)), [1 0]);
+%!test a=sparse (1,1);
+%! assert (all (a) == sparse ([0]));
+%! assert (size (all (a)), [1 1]);
+%!test a=sparse (2,1);
+%! assert (all (a) == sparse ([0]));
+%! assert (size (all (a)), [1 1]);
+%!test a=sparse (1,2);
+%! assert (all (a) == sparse ([0]));
+%! assert (size (all (a)), [1 1]);
+%!test a=sparse (2,2); assert (isequal (all (a), sparse ([0 0])));
+
 */
 
 template <class T>
--- a/liboctave/cruft/Makefile.am
+++ b/liboctave/cruft/Makefile.am
@@ -20,8 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-AUTOMAKE_OPTIONS = subdir-objects
-
 ## Search local directories before those specified by the user.
 AM_CPPFLAGS = \
   -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu
--- a/liboctave/numeric/LSODE-opts.in
+++ b/liboctave/numeric/LSODE-opts.in
@@ -74,11 +74,11 @@
 system.  Valid values are
 
 @table @asis
-@item \"adams\"
+@item  \"adams\"
 @itemx \"non-stiff\"
 No Jacobian used (even if it is available).
 
-@item \"bdf\"
+@item  \"bdf\"
 @itemx \"stiff\"
 Use stiff backward differentiation formula (BDF) method.  If a
 function to compute the Jacobian is not supplied, @code{lsode} will
--- a/liboctave/numeric/oct-rand.cc
+++ b/liboctave/numeric/oct-rand.cc
@@ -663,6 +663,30 @@
   return retval;
 }
 
+// Guarantee reproducible conversion of negative initialization values to
+// random number algorithm.  Note that Matlab employs slightly different rules.
+// 1) Seed saturates at 2^32-1 for any value larger than that.
+// 2) NaN, Inf are translated to 2^32-1.
+// 3) -Inf is translated to 0.
+static uint32_t
+double2uint32 (double d)
+{
+  uint32_t u;
+  static const double TWOUP32 = std::numeric_limits<uint32_t>::max() + 1.0;
+
+  if (! xfinite (d))
+    u = 0;
+  else
+    {
+      d = fmod (d, TWOUP32);
+      if (d < 0)
+        d += TWOUP32;
+      u = static_cast<uint32_t> (d);
+    }
+
+  return u;
+}
+
 void
 octave_rand::set_internal_state (const ColumnVector& s)
 {
@@ -672,7 +696,7 @@
   OCTAVE_LOCAL_BUFFER (uint32_t, tmp, MT_N + 1);
 
   for (octave_idx_type i = 0; i < n; i++)
-    tmp[i] = static_cast<uint32_t> (s.elem (i));
+    tmp[i] = double2uint32 (s.elem (i));
 
   if (len == MT_N + 1 && tmp[MT_N] <= MT_N && tmp[MT_N] > 0)
     oct_set_state (tmp);
--- a/liboctave/numeric/randmtzig.c
+++ b/liboctave/numeric/randmtzig.c
@@ -268,7 +268,7 @@
             unsigned char word[4];
             if (fread (word, 4, 1, urandom) != 1)
               break;
-            entropy[n++] = word[0]+(word[1]<<8)+(word[2]<<16)+(word[3]<<24);
+            entropy[n++] = word[0]+(word[1]<<8)+(word[2]<<16)+((uint32_t)word[3]<<24);
           }
         fclose (urandom);
       }
--- a/liboctave/operators/Sparse-op-defs.h
+++ b/liboctave/operators/Sparse-op-defs.h
@@ -1766,7 +1766,7 @@
           for (octave_idx_type i = 0; i < nc ; i++) \
             { \
               retval.ridx (i) = 0; \
-              retval.cidx (i+1) = i; \
+              retval.cidx (i+1) = i+1; \
               retval.data (i) = MT_RESULT; \
             } \
         } \
--- a/liboctave/system/mach-info.cc
+++ b/liboctave/system/mach-info.cc
@@ -75,14 +75,6 @@
 {
   oct_mach_info::float_format retval = oct_mach_info::flt_fmt_unknown;
 
-#if defined (CRAY)
-
-  // FIXME -- this should be determined automatically.
-
-  native_float_fmt = oct_mach_info::flt_fmt_cray;
-
-#else
-
   float_params fp[5];
 
   INIT_FLT_PAR (fp[0], oct_mach_info::flt_fmt_ieee_big_endian,
@@ -97,18 +89,6 @@
                  0, 1017118720,
                  0, 1018167296);
 
-  INIT_FLT_PAR (fp[2], oct_mach_info::flt_fmt_vax_d,
-                   128,  0,
-                -32769, -1,
-                  9344,  0,
-                  9344,  0);
-
-  INIT_FLT_PAR (fp[3], oct_mach_info::flt_fmt_vax_g,
-                    16,  0,
-                -32769, -1,
-                 15552,  0,
-                 15552,  0);
-
   INIT_FLT_PAR (fp[4], oct_mach_info::flt_fmt_unknown,
                 0, 0,
                 0, 0,
@@ -133,8 +113,6 @@
     }
   while (fp[++i].fp_fmt != oct_mach_info::flt_fmt_unknown);
 
-#endif
-
   return retval;
 }
 
@@ -214,12 +192,6 @@
     retval = oct_mach_info::flt_fmt_ieee_big_endian;
   else if (s == "ieee-le" || s == "l")
     retval = oct_mach_info::flt_fmt_ieee_little_endian;
-  else if (s == "vaxd" || s == "d")
-    retval = oct_mach_info::flt_fmt_vax_d;
-  else if (s == "vaxg" || s == "g")
-    retval = oct_mach_info::flt_fmt_vax_g;
-  else if (s == "cray" || s == "c")
-    retval = oct_mach_info::flt_fmt_cray;
   else if (s == "unknown")
     retval = oct_mach_info::flt_fmt_unknown;
   else
@@ -244,18 +216,6 @@
       retval = "ieee-le";
       break;
 
-    case flt_fmt_vax_d:
-      retval = "vaxd";
-      break;
-
-    case flt_fmt_vax_g:
-      retval = "vaxg";
-      break;
-
-    case flt_fmt_cray:
-      retval = "cray";
-      break;
-
     default:
       break;
     }
--- a/liboctave/system/mach-info.h
+++ b/liboctave/system/mach-info.h
@@ -40,9 +40,6 @@
       flt_fmt_unknown,
       flt_fmt_ieee_little_endian,
       flt_fmt_ieee_big_endian,
-      flt_fmt_vax_d,
-      flt_fmt_vax_g,
-      flt_fmt_cray
     };
 
   static bool instance_ok (void);
--- a/liboctave/util/base-list.h
+++ b/liboctave/util/base-list.h
@@ -49,24 +49,28 @@
   template <class P>
   void remove_if (P pred)
   {
+    lst.remove_if (pred);
+
+    // FIXME: kluge removed 8/7/13.  Eventually this commented
+    //        code should be deleted.
+    //
+    // FIXME: this kluge should be removed at some point.
     // We would like to simply call
     //
     //   lst.remove_if (pred);
     //
     // but the Sun Studio compiler chokes on that.
     //
-    // FIXME -- this kluge should be removed at some point.
-
-    iterator b = lst.begin ();
-    iterator e = lst.end ();
-    while (b != e)
-      {
-        iterator n = b;
-        n++;
-        if (pred (*b))
-          lst.erase (b);
-        b = n;
-      }
+    // iterator b = lst.begin ();
+    // iterator e = lst.end ();
+    // while (b != e)
+    //   {
+    //     iterator n = b;
+    //     n++;
+    //     if (pred (*b))
+    //       lst.erase (b);
+    //     b = n;
+    //   }
   }
 
   void clear (void) { lst.clear (); }
--- a/liboctave/util/byte-swap.h
+++ b/liboctave/util/byte-swap.h
@@ -23,13 +23,10 @@
 #if !defined (octave_byte_swap_h)
 #define octave_byte_swap_h 1
 
-// FIXME -- not sure these volatile qualifiers are really
-// needed or appropriate here.
-
 static inline void
-swap_bytes (volatile void *ptr, unsigned int i, unsigned int j)
+swap_bytes (void *ptr, unsigned int i, unsigned int j)
 {
-  volatile char *t = static_cast<volatile char *> (ptr);
+  char *t = static_cast<char *> (ptr);
 
   char tmp = t[i];
   t[i] = t[j];
@@ -38,7 +35,7 @@
 
 template <int n>
 void
-swap_bytes (volatile void *ptr)
+swap_bytes (void *ptr)
 {
   for (int i = 0; i < n/2; i++)
     swap_bytes (ptr, i, n-1-i);
@@ -46,20 +43,20 @@
 
 template <>
 inline void
-swap_bytes <1> (volatile void *)
+swap_bytes<1> (void *)
 {
 }
 
 template <>
 inline void
-swap_bytes <2> (volatile void *ptr)
+swap_bytes<2> (void *ptr)
 {
   swap_bytes (ptr, 0, 1);
 }
 
 template <>
 inline void
-swap_bytes <4> (volatile void *ptr)
+swap_bytes<4> (void *ptr)
 {
   swap_bytes (ptr, 0, 3);
   swap_bytes (ptr, 1, 2);
@@ -67,7 +64,7 @@
 
 template <>
 inline void
-swap_bytes <8> (volatile void *ptr)
+swap_bytes<8> (void *ptr)
 {
   swap_bytes (ptr, 0, 7);
   swap_bytes (ptr, 1, 6);
@@ -77,9 +74,9 @@
 
 template <int n>
 void
-swap_bytes (volatile void *ptr, int len)
+swap_bytes (void *ptr, int len)
 {
-  volatile char *t = static_cast<volatile char *> (ptr);
+  char *t = static_cast<char *> (ptr);
 
   for (int i = 0; i < len; i++)
     {
@@ -90,7 +87,7 @@
 
 template <>
 inline void
-swap_bytes<1> (volatile void *, int)
+swap_bytes<1> (void *, int)
 {
 }
 
--- a/liboctave/util/cmd-hist.cc
+++ b/liboctave/util/cmd-hist.cc
@@ -65,7 +65,7 @@
 
   std::string do_histcontrol (void) const;
 
-  void do_add (const std::string&);
+  bool do_add (const std::string&);
 
   void do_remove (int);
 
@@ -184,14 +184,14 @@
   return retval;
 }
 
-void
+bool
 gnu_history::do_add (const std::string& s)
 {
   if (! do_ignoring_entries ())
     {
       if (s.empty ()
           || (s.length () == 1 && (s[0] == '\r' || s[0] == '\n')))
-        return;
+        return false;
      
       // Strip newline before adding to list
       std::string stmp = s;
@@ -199,8 +199,11 @@
       if (stmp[stmp_len - 1] == '\n')
         stmp.resize (stmp_len - 1);
 
-      lines_this_session += ::octave_add_history (stmp.c_str (), history_control);
+      int added = ::octave_add_history (stmp.c_str (), history_control);
+      lines_this_session += added;
+      return (added > 0) ? true : false;
     }
+  return false;
 }
 
 void
@@ -587,11 +590,12 @@
     ? instance->do_ignoring_entries () : false;
 }
 
-void
+bool
 command_history::add (const std::string& s)
 {
   if (instance_ok ())
-    instance->do_add (s);
+    return instance->do_add (s);
+  return false;
 }
 
 void
@@ -818,9 +822,10 @@
   return ignoring_additions;
 }
 
-void
+bool
 command_history::do_add (const std::string&)
 {
+  return false;
 }
 
 void
--- a/liboctave/util/cmd-hist.h
+++ b/liboctave/util/cmd-hist.h
@@ -61,7 +61,7 @@
 
   static bool ignoring_entries (void);
 
-  static void add (const std::string&);
+  static bool add (const std::string&);
 
   static void remove (int);
 
@@ -156,7 +156,7 @@
 
   virtual bool do_ignoring_entries (void) const;
 
-  virtual void do_add (const std::string&);
+  virtual bool do_add (const std::string&);
 
   virtual void do_remove (int);
 
--- a/liboctave/util/data-conv.cc
+++ b/liboctave/util/data-conv.cc
@@ -25,10 +25,10 @@
 #endif
 
 #include <cctype>
-#include <climits>
 #include <cstdlib>
 
 #include <iostream>
+#include <limits>
 #include <vector>
 
 #include "byte-swap.h"
@@ -37,15 +37,11 @@
 #include "lo-ieee.h"
 #include "oct-locbuf.h"
 
-template void swap_bytes<2> (volatile void *, int);
-template void swap_bytes<4> (volatile void *, int);
-template void swap_bytes<8> (volatile void *, int);
-
 #if defined HAVE_LONG_LONG_INT
 #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
   do \
     { \
-      int sz = BITS / CHAR_BIT; \
+      int sz = BITS / std::numeric_limits<unsigned char>::digits; \
       if (sizeof (TQ char) == sz) \
         VAL = oct_data_conv::dt_ ## Q ## char; \
       else if (sizeof (TQ short) == sz) \
@@ -64,7 +60,7 @@
 #define FIND_SIZED_INT_TYPE(VAL, BITS, TQ, Q) \
   do \
     { \
-      int sz = BITS / CHAR_BIT; \
+      int sz = BITS / std::numeric_limits<unsigned char>::digits; \
       if (sizeof (TQ char) == sz) \
         VAL = oct_data_conv::dt_ ## Q ## char; \
       else if (sizeof (TQ short) == sz) \
@@ -82,7 +78,7 @@
 #define FIND_SIZED_FLOAT_TYPE(VAL, BITS) \
   do \
     { \
-      int sz = BITS / CHAR_BIT; \
+      int sz = BITS / std::numeric_limits<unsigned char>::digits; \
       if (sizeof (float) == sz) \
         VAL = oct_data_conv::dt_float; \
       else if (sizeof (double) == sz) \
@@ -94,8 +90,9 @@
 
 // I'm not sure it is worth the trouble, but let's use a lookup table
 // for the types that are supposed to be a specific number of bits
-// wide.  Given the macros above, this should work as long as CHAR_BIT
-// is a multiple of 8 and there are types with the right sizes.
+// wide.  Given the macros above, this should work as long as
+// std::numeric_limits<unsigned char>::digits is a multiple of 8 and
+// there are types with the right sizes.
 //
 // The sized data type lookup table has the following format:
 //
@@ -177,6 +174,111 @@
     } \
   while (0)
 
+size_t
+oct_data_conv::data_type_size (data_type dt)
+{
+  size_t retval = -1;
+
+  switch (dt)
+    {
+    case oct_data_conv::dt_int8:
+      retval = sizeof (int8_t);
+      break;
+
+    case oct_data_conv::dt_uint8:
+      retval = sizeof (uint8_t);
+      break;
+
+    case oct_data_conv::dt_int16:
+      retval = sizeof (int16_t);
+      break;
+
+    case oct_data_conv::dt_uint16:
+      retval = sizeof (uint16_t);
+      break;
+
+    case oct_data_conv::dt_int32:
+      retval = sizeof (int32_t);
+      break;
+
+    case oct_data_conv::dt_uint32:
+      retval = sizeof (uint32_t);
+      break;
+
+    case oct_data_conv::dt_int64:
+      retval = sizeof (int64_t);
+      break;
+
+    case oct_data_conv::dt_uint64:
+      retval = sizeof (uint64_t);
+      break;
+
+    case oct_data_conv::dt_float:
+    case oct_data_conv::dt_single:
+      retval = sizeof (float);
+      break;
+
+    case oct_data_conv::dt_double:
+      retval = sizeof (double);
+      break;
+
+    case oct_data_conv::dt_char:
+      retval = sizeof (char);
+      break;
+
+    case oct_data_conv::dt_schar:
+      retval = sizeof (signed char);
+      break;
+
+    case oct_data_conv::dt_uchar:
+      retval = sizeof (unsigned char);
+      break;
+
+    case oct_data_conv::dt_short:
+      retval = sizeof (short);
+      break;
+
+    case oct_data_conv::dt_ushort:
+      retval = sizeof (unsigned short);
+      break;
+
+    case oct_data_conv::dt_int:
+      retval = sizeof (int);
+      break;
+
+    case oct_data_conv::dt_uint:
+      retval = sizeof (unsigned int);
+      break;
+
+    case oct_data_conv::dt_long:
+      retval = sizeof (long);
+      break;
+
+    case oct_data_conv::dt_ulong:
+      retval = sizeof (unsigned long);
+      break;
+
+    case oct_data_conv::dt_longlong:
+      retval = sizeof (long long);
+      break;
+
+    case oct_data_conv::dt_ulonglong:
+      retval = sizeof (unsigned long long);
+      break;
+
+    case oct_data_conv::dt_logical:
+      retval = sizeof (bool);
+      break;
+
+    case oct_data_conv::dt_unknown:
+    default:
+      abort ();
+      break;
+    }
+
+  return retval;
+}
+
 oct_data_conv::data_type
 oct_data_conv::string_to_data_type (const std::string& str)
 {
@@ -429,7 +531,7 @@
       break;
 
     case oct_data_conv::dt_uchar:
-      retval = "usigned char";
+      retval = "unsigned char";
       break;
 
     case oct_data_conv::dt_short:
@@ -445,7 +547,7 @@
       break;
 
     case oct_data_conv::dt_uint:
-      retval = "usigned int";
+      retval = "unsigned int";
       break;
 
     case oct_data_conv::dt_long:
@@ -453,7 +555,7 @@
       break;
 
     case oct_data_conv::dt_ulong:
-      retval = "usigned long";
+      retval = "unsigned long";
       break;
 
     case oct_data_conv::dt_longlong:
@@ -548,191 +650,23 @@
 }
 
 static void
-VAX_D_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "IEEE little endian format");
-}
-
-static void
-VAX_G_double_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "IEEE little endian format");
-}
-
-static void
-Cray_to_IEEE_little_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "IEEE little endian format");
-}
-
-static void
 IEEE_big_float_to_IEEE_little_float (void *d, octave_idx_type len)
 {
   swap_bytes<4> (d, len);
 }
 
 static void
-VAX_D_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "IEEE little endian format");
-}
-
-static void
-VAX_G_float_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "IEEE little endian format");
-}
-
-static void
-Cray_to_IEEE_little_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "IEEE little endian format");
-}
-
-static void
 IEEE_little_double_to_IEEE_big_double (void *d, octave_idx_type len)
 {
   swap_bytes<8> (d, len);
 }
 
 static void
-VAX_D_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "IEEE big endian format");
-}
-
-static void
-VAX_G_double_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "IEEE big endian format");
-}
-
-static void
-Cray_to_IEEE_big_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "IEEE big endian format");
-}
-
-static void
 IEEE_little_float_to_IEEE_big_float (void *d, octave_idx_type len)
 {
   swap_bytes<4> (d, len);
 }
 
-static void
-VAX_D_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "IEEE big endian format");
-}
-
-static void
-VAX_G_float_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "IEEE big endian format");
-}
-
-static void
-Cray_to_IEEE_big_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "IEEE big endian format");
-}
-
-static void
-IEEE_little_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE little endian", "VAX D");
-}
-
-static void
-IEEE_big_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE big endian", "VAX D");
-}
-
-static void
-VAX_G_double_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "VAX D");
-}
-
-static void
-Cray_to_VAX_D_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "VAX D");
-}
-
-static void
-IEEE_little_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE little endian", "VAX D");
-}
-
-static void
-IEEE_big_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE big endian", "VAX D");
-}
-
-static void
-VAX_G_float_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "VAX D");
-}
-
-static void
-Cray_to_VAX_D_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("Cray", "VAX D");
-}
-
-static void
-IEEE_little_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE little endian", "VAX G");
-}
-
-static void
-IEEE_big_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE big endian", "VAX G");
-}
-
-static void
-VAX_D_double_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "VAX G");
-}
-
-static void
-Cray_to_VAX_G_double (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "VAX G");
-}
-
-static void
-IEEE_little_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE little endian", "VAX G");
-}
-
-static void
-IEEE_big_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("IEEE big endian", "VAX G");
-}
-
-static void
-VAX_D_float_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX D float", "VAX G");
-}
-
-static void
-Cray_to_VAX_G_float (void * /* d */, octave_idx_type /* len */)
-{
-  gripe_data_conversion ("VAX G float", "VAX G");
-}
-
 void
 do_double_format_conversion (void *data, octave_idx_type len,
                              oct_mach_info::float_format from_fmt,
@@ -750,18 +684,6 @@
           IEEE_big_double_to_IEEE_little_double (data, len);
           break;
 
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_double_to_IEEE_little_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_double_to_IEEE_little_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_IEEE_little_double (data, len);
-          break;
-
         default:
           gripe_unrecognized_float_fmt ();
           break;
@@ -778,74 +700,6 @@
         case oct_mach_info::flt_fmt_ieee_big_endian:
           break;
 
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_double_to_IEEE_big_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_double_to_IEEE_big_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_IEEE_big_double (data, len);
-          break;
-
-        default:
-          gripe_unrecognized_float_fmt ();
-          break;
-        }
-      break;
-
-    case oct_mach_info::flt_fmt_vax_d:
-      switch (from_fmt)
-        {
-        case oct_mach_info::flt_fmt_ieee_little_endian:
-          IEEE_little_double_to_VAX_D_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_ieee_big_endian:
-          IEEE_big_double_to_VAX_D_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_d:
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_double_to_VAX_D_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_VAX_D_double (data, len);
-          break;
-
-        default:
-          gripe_unrecognized_float_fmt ();
-          break;
-        }
-      break;
-
-    case oct_mach_info::flt_fmt_vax_g:
-      switch (from_fmt)
-        {
-        case oct_mach_info::flt_fmt_ieee_little_endian:
-          IEEE_little_double_to_VAX_G_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_ieee_big_endian:
-          IEEE_big_double_to_VAX_G_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_double_to_VAX_G_double (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_VAX_G_double (data, len);
-          break;
-
         default:
           gripe_unrecognized_float_fmt ();
           break;
@@ -877,18 +731,6 @@
           IEEE_big_float_to_IEEE_little_float (data, len);
           break;
 
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_float_to_IEEE_little_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_float_to_IEEE_little_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_IEEE_little_float (data, len);
-          break;
-
         default:
           gripe_unrecognized_float_fmt ();
           break;
@@ -905,74 +747,6 @@
         case oct_mach_info::flt_fmt_ieee_big_endian:
           break;
 
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_float_to_IEEE_big_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_float_to_IEEE_big_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_IEEE_big_float (data, len);
-          break;
-
-        default:
-          gripe_unrecognized_float_fmt ();
-          break;
-        }
-      break;
-
-    case oct_mach_info::flt_fmt_vax_d:
-      switch (from_fmt)
-        {
-        case oct_mach_info::flt_fmt_ieee_little_endian:
-          IEEE_little_float_to_VAX_D_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_ieee_big_endian:
-          IEEE_big_float_to_VAX_D_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_d:
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          VAX_G_float_to_VAX_D_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_VAX_D_float (data, len);
-          break;
-
-        default:
-          gripe_unrecognized_float_fmt ();
-          break;
-        }
-      break;
-
-    case oct_mach_info::flt_fmt_vax_g:
-      switch (from_fmt)
-        {
-        case oct_mach_info::flt_fmt_ieee_little_endian:
-          IEEE_little_float_to_VAX_G_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_ieee_big_endian:
-          IEEE_big_float_to_VAX_G_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_d:
-          VAX_D_float_to_VAX_G_float (data, len);
-          break;
-
-        case oct_mach_info::flt_fmt_vax_g:
-          break;
-
-        case oct_mach_info::flt_fmt_cray:
-          Cray_to_VAX_G_float (data, len);
-          break;
-
         default:
           gripe_unrecognized_float_fmt ();
           break;
--- a/liboctave/util/data-conv.h
+++ b/liboctave/util/data-conv.h
@@ -26,6 +26,7 @@
 #include <limits>
 
 #include "mach-info.h"
+#include "oct-inttypes.h"
 
 class
 OCTAVE_API
@@ -61,6 +62,8 @@
       dt_unknown   = 23 // Must be last, have largest value!
     };
 
+  static size_t data_type_size (data_type dt);
+
   static data_type string_to_data_type (const std::string& s);
 
   static void string_to_data_type (const std::string& s, int& block_size,
@@ -125,4 +128,137 @@
 write_floats (std::ostream& os, const float *data, save_type type,
               octave_idx_type len);
 
+template <typename T>
+inline bool
+is_equivalent_type (oct_data_conv::data_type)
+{
+  return false;
+}
+
+template <>
+inline bool
+is_equivalent_type<int8_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int8;
+}
+
+template <>
+inline bool
+is_equivalent_type<int16_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int16;
+}
+
+template <>
+inline bool
+is_equivalent_type<int32_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int32;
+}
+
+template <>
+inline bool
+is_equivalent_type<int64_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int64;
+}
+
+template <>
+inline bool
+is_equivalent_type<uint8_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint8;
+}
+
+template <>
+inline bool
+is_equivalent_type<uint16_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint16;
+}
+
+template <>
+inline bool
+is_equivalent_type<uint32_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint32;
+}
+
+template <>
+inline bool
+is_equivalent_type<uint64_t> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint64;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_int8> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int8;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_int16> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int16;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_int32> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int32;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_int64> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_int64;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_uint8> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint8;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_uint16> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint16;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_uint32> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint32;
+}
+
+template <>
+inline bool
+is_equivalent_type<octave_uint64> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_uint64;
+}
+
+template <>
+inline bool
+is_equivalent_type<double> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_double;
+}
+
+template <>
+inline bool
+is_equivalent_type<float> (oct_data_conv::data_type t)
+{
+  return t == oct_data_conv::dt_single || t == oct_data_conv::dt_float;
+}
+
 #endif
--- a/liboctave/util/lo-ieee.cc
+++ b/liboctave/util/lo-ieee.cc
@@ -73,9 +73,6 @@
       }
       break;
 
-    case oct_mach_info::flt_fmt_cray:
-    case oct_mach_info::flt_fmt_vax_d:
-    case oct_mach_info::flt_fmt_vax_g:
     default:
       // If the format is unknown, then you will probably not have a
       // useful system, so we will abort here.  Anyone wishing to
--- a/liboctave/util/lo-regexp.cc
+++ b/liboctave/util/lo-regexp.cc
@@ -550,7 +550,7 @@
 
           const Matrix pairs (p->token_extents ());
           rep.append (&buffer[from], static_cast<size_t> (start - 1) - from);
-          from = static_cast<size_t> (end - 1) + 1;
+          from = static_cast<size_t> (end);
 
           size_t cur_pos = 0;
 
@@ -608,7 +608,7 @@
           OCTAVE_QUIT;
           rep.append (&buffer[from],
                       static_cast<size_t> (p->start () - 1) - from);
-          from = static_cast<size_t> (p->end () - 1) + 1;
+          from = static_cast<size_t> (p->end ());
           rep.append (repstr);
           p++;
         }
--- a/liboctave/util/oct-rl-hist.c
+++ b/liboctave/util/oct-rl-hist.c
@@ -289,12 +289,10 @@
           char *tmp = malloc (len + 64);
 
           if (number_lines)
-            sprintf (tmp, "%5d%c%s", i + history_base,
-                     hlist[i]->data ? '*' : ' ',
+            sprintf (tmp, "%5d %s", i + history_base,
                      line ? line : "");
           else
-            sprintf (tmp, "%c%s", hlist[i]->data ? '*' : ' ',
-                     line ? line : "");
+            strcpy (tmp, line ? line : "");
 
           retval[k++] = tmp;
         }
--- a/m4/acinclude.m4
+++ b/m4/acinclude.m4
@@ -598,6 +598,42 @@
   fi
 ])
 dnl
+dnl Check whether GLPK provides the latest API functions required
+dnl for the glpk function. The glp_iptcp structure was introduced
+dnl in GLPK version 4.38.
+dnl
+AC_DEFUN([OCTAVE_CHECK_LIB_GLPK_OK], [
+  AC_CACHE_CHECK([whether the glpk library has glp_interior(glp_prob*, glp_iptcp*)],
+    [octave_cv_lib_glpk_ok],
+    [AC_LANG_PUSH(C++)
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+        extern "C"
+        {
+        #if defined (HAVE_GLPK_GLPK_H)
+        #include <glpk/glpk.h>
+        #else
+        #include <glpk.h>
+        #endif
+        }
+        ]], [[
+        glp_prob *lp = glp_create_prob ();
+        glp_iptcp iptcp;
+        glp_init_iptcp (&iptcp);
+        int retval = glp_interior (lp, &iptcp);
+        ]])],
+      octave_cv_lib_glpk_ok=yes,
+      octave_cv_lib_glpk_ok=no)
+    AC_LANG_POP(C++)
+  ])
+  if test $octave_cv_lib_glpk_ok = yes; then
+    $1
+    :
+  else
+    $2
+    :
+  fi
+])
+dnl
 dnl Check whether using HDF5 DLL under Windows.  This is done by
 dnl testing for a data symbol in the HDF5 library, which would
 dnl require the definition of _HDF5USEDL_ under MSVC compiler.
@@ -680,7 +716,7 @@
 #endif
     ])
 
-    if test "$have_opengl_incs" = yes; then
+    if test $have_opengl_incs = yes; then
       case $canonical_host_type in
         *-*-mingw32* | *-*-msdosmsvc)
           save_LIBS="$LIBS"
@@ -1431,11 +1467,15 @@
     [octave_cv_callinst_addattribute_arg_is_attributes],
     [AC_LANG_PUSH(C++)
       AC_COMPILE_IFELSE(
-        [AC_LANG_PROGRAM([[
+        [AC_LANG_PROGRAM([
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+          #include <llvm/IR/Instructions.h>
+          #include <llvm/IR/Attributes.h>
+#else
           #include <llvm/Instructions.h>
           #include <llvm/Attributes.h>
-          #include <llvm/LLVMContext.h>
-          ]], [[
+#endif
+          ], [[
           llvm::CallInst *callinst;
           llvm::AttrBuilder attr_builder;
           attr_builder.addAttribute(llvm::Attributes::StructRet);
@@ -1449,41 +1489,6 @@
   if test $octave_cv_callinst_addattribute_arg_is_attributes = yes; then
     AC_DEFINE(CALLINST_ADDATTRIBUTE_ARG_IS_ATTRIBUTES, 1,
       [Define to 1 if llvm::CallInst:addAttribute arg type is llvm::Attributes.])
-  else
-    AC_CACHE_CHECK([check LLVM::CallInst::addAttribute arg type is llvm::Attribute],
-      [octave_cv_callinst_addattribute_arg_is_attribute],
-      [AC_LANG_PUSH(C++)
-        AC_COMPILE_IFELSE(
-          [AC_LANG_PROGRAM([[
-            #include <llvm/Instructions.h>
-            #include <llvm/Attributes.h>
-            ]], [[
-            llvm::CallInst *callinst;
-            callinst->addAttribute (1, llvm::Attribute::StructRet);
-          ]])],
-          octave_cv_callinst_addattribute_arg_is_attribute=yes,
-          octave_cv_callinst_addattribute_arg_is_attribute=no)
-      AC_LANG_POP(C++)
-    ])
-    if test $octave_cv_callinst_addattribute_arg_is_attribute = no; then
-      AC_MSG_ERROR([llvm::CallInst::addAttribute is required.])
-    fi
-  fi
-])
-dnl
-dnl Detect TargetData.h or DataLayout.h.
-dnl
-AC_DEFUN([OCTAVE_LLVM_DATALAYOUT_HEADER], [
-  AC_CHECK_HEADER([llvm/DataLayout.h], [
-    octave_is_datalayout_header=yes], [
-    AC_CHECK_HEADER([llvm/Target/TargetData.h], [
-      octave_is_datalayout_header=no], [
-      AC_MSG_ERROR([DataLayout.h or Target/TargetData.h is required.])
-    ])
-  ])
-  if test $octave_is_datalayout_header = yes; then
-    AC_DEFINE(HAVE_DATALAYOUT, 1,
-      [Define to 1 if DataLayout.h exist.])
   fi
 ])
 dnl
@@ -1495,9 +1500,15 @@
     [AC_LANG_PUSH(C++)
       AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM([[
+#ifdef HAVE_LLVM_IR_FUNCTION_H
+          #include <llvm/IR/Function.h>
+          #include <llvm/IR/Attributes.h>
+          #include <llvm/IR/LLVMContext.h>
+#else
           #include <llvm/Function.h>
           #include <llvm/Attributes.h>
           #include <llvm/LLVMContext.h>
+#endif
           ]], [[
           llvm::Function *llvm_function;
           llvm::AttrBuilder attr_builder;
@@ -1512,25 +1523,6 @@
   if test $octave_cv_function_addattribute_arg_is_attributes = yes; then
     AC_DEFINE(FUNCTION_ADDATTRIBUTE_ARG_IS_ATTRIBUTES, 1,
       [Define to 1 if llvm::Function:addAttribute arg type is llvm::Attributes.])
-  else
-    AC_CACHE_CHECK([check llvm::Function::addAttribute arg type is llvm::Attribute],
-      [octave_cv_function_addattribute_arg_is_attribute],
-      [AC_LANG_PUSH(C++)
-        AC_COMPILE_IFELSE(
-          [AC_LANG_PROGRAM([[
-            #include <llvm/Function.h>
-            #include <llvm/Attributes.h>
-            ]], [[
-            llvm::Function *llvm_function;
-            llvm_function->addAttribute (1, llvm::Attribute::StructRet);
-          ]])],
-          octave_cv_function_addattribute_arg_is_attribute=yes,
-          octave_cv_function_addattribute_arg_is_attribute=no)
-      AC_LANG_POP(C++)
-    ])
-    if test $octave_cv_function_addattribute_arg_is_attribute = no; then
-      AC_MSG_ERROR([llvm::Function::addAttribute is required.])
-    fi
   fi
 ])
 dnl
@@ -1542,8 +1534,13 @@
     [AC_LANG_PUSH(C++)
       AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM([[
+#ifdef LLVM_HAVE_IR_FUNCTION_H
           #include <llvm/Function.h>
           #include <llvm/Attributes.h>
+#else
+          #include <llvm/Function.h>
+          #include <llvm/Attributes.h>
+#endif
           ]], [[
           llvm::Function *llvm_function;
           llvm_function->addFnAttr (llvm::Attributes::AlwaysInline);
@@ -1555,41 +1552,6 @@
   if test $octave_cv_function_addfnattr_arg_is_attributes = yes; then
     AC_DEFINE(FUNCTION_ADDFNATTR_ARG_IS_ATTRIBUTES, 1,
       [Define to 1 if llvm::Function:addFnAttr arg type is llvm::Attributes.])
-  else
-    AC_CACHE_CHECK([check llvm::Function::addFnAttr arg type is llvm::Attribute],
-      [octave_cv_function_addfnattr_arg_is_attribute],
-      [AC_LANG_PUSH(C++)
-        AC_COMPILE_IFELSE(
-          [AC_LANG_PROGRAM([[
-            #include <llvm/Function.h>
-            #include <llvm/Attributes.h>
-            ]], [[
-            llvm::Function *llvm_function;
-            llvm_function->addFnAttr (llvm::Attribute::AlwaysInline);
-          ]])],
-          octave_cv_function_addfnattr_arg_is_attribute=yes,
-          octave_cv_function_addfnattr_arg_is_attribute=no)
-      AC_LANG_POP(C++)
-    ])
-    if test $octave_cv_function_addfnattr_arg_is_attribute = no; then
-      AC_MSG_ERROR([llvm::Function::addFnAttr is required.])
-    fi
-  fi
-])
-dnl
-dnl Check whether IRBuilder.h is in Support directory.
-dnl
-AC_DEFUN([OCTAVE_LLVM_IRBUILDER_HEADER], [
-  AC_CHECK_HEADER([llvm/IRBuilder.h], [
-    octave_irbuilder_header_in_support_dir=no], [
-    AC_CHECK_HEADER([llvm/Support/IRBuilder.h], [
-      octave_irbuilder_header_in_support_dir=yes], [
-      AC_MSG_ERROR([IRBuilder.h is required.])
-    ])
-  ])
-  if test $octave_irbuilder_header_in_support_dir = yes; then
-    AC_DEFINE(IRBUILDER_HEADER_IN_SUPPORT_DIR, 1,
-      [Define to 1 if IRBuilder.h in Support directory.])
   fi
 ])
 dnl
@@ -1613,11 +1575,11 @@
   AC_PROG_YACC
 
   case "`$YACC --version`" in
-    *bison*) tmp_have_bison="yes" ;;
+    *bison*) tmp_have_bison=yes ;;
     *) tmp_have_bison=no ;;
   esac
 
-  if test "$tmp_have_bison" = yes; then
+  if test $tmp_have_bison = yes; then
     AC_CACHE_CHECK([syntax of bison push/pull declaration],
                    [octave_cv_bison_push_pull_decl_style], [
       style="dash underscore"
@@ -1671,7 +1633,7 @@
     OCTAVE_CONFIGURE_WARNING([warn_bison_push_pull_decl_style])
   fi
 
-  if test "$tmp_have_bison" = no; then
+  if test $tmp_have_bison = no; then
     YACC='$(top_srcdir)/build-aux/missing bison'
     warn_bison="
 
--- a/scripts/@ftp/ascii.m
+++ b/scripts/@ftp/ascii.m
@@ -29,3 +29,4 @@
 function ascii (f)
   __ftp_ascii__ (f.curlhandle);
 endfunction
+
--- a/scripts/@ftp/binary.m
+++ b/scripts/@ftp/binary.m
@@ -28,3 +28,4 @@
 function binary (f)
   __ftp_binary__ (f.curlhandle);
 endfunction
+
--- a/scripts/@ftp/cd.m
+++ b/scripts/@ftp/cd.m
@@ -41,3 +41,4 @@
   endif
   path = __ftp_pwd__ (f.curlhandle);
 endfunction
+
--- a/scripts/@ftp/close.m
+++ b/scripts/@ftp/close.m
@@ -26,3 +26,4 @@
 function dir (f)
   __ftp_close__ (f.curlhandle);
 endfunction
+
--- a/scripts/@ftp/delete.m
+++ b/scripts/@ftp/delete.m
@@ -26,3 +26,4 @@
 function delete (f, file)
   __ftp_delete__ (f.curlhandle, file);
 endfunction
+
--- a/scripts/@ftp/dir.m
+++ b/scripts/@ftp/dir.m
@@ -31,3 +31,4 @@
     lst = __ftp_dir__ (f.curlhandle);
   endif
 endfunction
+
--- a/scripts/@ftp/display.m
+++ b/scripts/@ftp/display.m
@@ -22,4 +22,5 @@
   printf (" user: %s\n", obj.username);
   printf ("  dir: %s\n", __ftp_pwd__ (obj.curlhandle));
   printf (" mode: %s\n", __ftp_mode__ (obj.curlhandle));
-endfunction
\ No newline at end of file
+endfunction
+
--- a/scripts/@ftp/ftp.m
+++ b/scripts/@ftp/ftp.m
@@ -20,9 +20,9 @@
 ## @deftypefn  {Function File} {@var{f} =} ftp (@var{host})
 ## @deftypefnx {Function File} {@var{f} =} ftp (@var{host}, @var{username}, @var{password})
 ## Connect to the FTP server @var{host} with @var{username} and @var{password}.
-## If @var{username} and @var{password} are not specified, user "anonymous"
-## with no password is used.  The returned FTP object @var{f} represents the
-## established FTP connection.
+## If @var{username} and @var{password} are not specified, user
+## @qcode{"anonymous"} with no password is used.  The returned FTP object
+## @var{f} represents the established FTP connection.
 ##
 ## The list of actions for an FTP object are shown below.  All functions
 ## require an FTP object as the first argument.
@@ -58,3 +58,4 @@
     obj = class (p, "ftp");
   endif
 endfunction
+
--- a/scripts/@ftp/loadobj.m
+++ b/scripts/@ftp/loadobj.m
@@ -34,3 +34,4 @@
     b = rmfield (b, "remotePwd");
   endif
 endfunction
+
--- a/scripts/@ftp/mget.m
+++ b/scripts/@ftp/mget.m
@@ -35,3 +35,4 @@
 function mget (f, file)
   __ftp_mget__ (f.curlhandle, file);
 endfunction
+
--- a/scripts/@ftp/mkdir.m
+++ b/scripts/@ftp/mkdir.m
@@ -26,3 +26,4 @@
 function mkdir (f, path)
   __ftp_mkdir__ (f.curlhandle, path);
 endfunction
+
--- a/scripts/@ftp/mput.m
+++ b/scripts/@ftp/mput.m
@@ -33,3 +33,4 @@
     retval = __ftp_mput__ (f.curlhandle, file);
   endif
 endfunction
+
--- a/scripts/@ftp/rename.m
+++ b/scripts/@ftp/rename.m
@@ -27,3 +27,4 @@
 function rename (f, oldname, newname)
   __ftp_rename__ (f.curlhandle, oldname, newname);
 endfunction
+
--- a/scripts/@ftp/rmdir.m
+++ b/scripts/@ftp/rmdir.m
@@ -26,3 +26,4 @@
 function rmdir (f, path)
   __ftp_rmdir__ (f.curlhandle, path);
 endfunction
+
--- a/scripts/@ftp/saveobj.m
+++ b/scripts/@ftp/saveobj.m
@@ -21,3 +21,4 @@
   b = rmfield (b, "curlhandle");
   b.dir = __ftp_pwd (a.curlhandle);
 endfunction
+
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -20,8 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-AUTOMAKE_OPTIONS = subdir-objects
-
 EXTRA_DIST =
 
 CLEANFILES =
--- a/scripts/audio/lin2mu.m
+++ b/scripts/audio/lin2mu.m
@@ -74,3 +74,4 @@
   y = 64 * sig - 16 * e - fix (32 * f) + 335;
 
 endfunction
+
--- a/scripts/audio/loadaudio.m
+++ b/scripts/audio/loadaudio.m
@@ -79,3 +79,4 @@
   fclose (num);
 
 endfunction
+
--- a/scripts/audio/mu2lin.m
+++ b/scripts/audio/mu2lin.m
@@ -80,3 +80,4 @@
   endif
 
 endfunction
+
--- a/scripts/audio/record.m
+++ b/scripts/audio/record.m
@@ -63,3 +63,4 @@
   X = Y - 127;
 
 endfunction
+
--- a/scripts/audio/saveaudio.m
+++ b/scripts/audio/saveaudio.m
@@ -86,3 +86,4 @@
   fclose (num);
 
 endfunction
+
--- a/scripts/audio/setaudio.m
+++ b/scripts/audio/setaudio.m
@@ -41,3 +41,4 @@
   endif
 
 endfunction
+
--- a/scripts/audio/wavread.m
+++ b/scripts/audio/wavread.m
@@ -177,8 +177,8 @@
         length = (param(2)-param(1)+1) * channels;
       elseif (nparams == 4 && char (param) == "size")
         ## Size of the file is requested.
-        tmp = idivide (8 * data_size, channels * bits_per_sample);
-        y = [tmp, channels];
+        y = idivide (8 * data_size, channels * bits_per_sample);
+        samples_per_sec = channels;
         return;
       else
         error ("wavread: invalid PARAM argument");
--- a/scripts/audio/wavwrite.m
+++ b/scripts/audio/wavwrite.m
@@ -154,7 +154,7 @@
 %! fname = tmpnam ();
 
 %!test
-%! A = [-1:0.1:1; -1:0.1:1];
+%! A = [-1:0.1:1; -1:0.1:1]';
 %! wavwrite (A, fname);
 %! [B, samples_per_sec, bits_per_sample] = wavread (fname);
 %! unlink (fname);
@@ -163,7 +163,7 @@
 %! assert (bits_per_sample, 16);
 
 %!test
-%! A = [-1:0.1:1; -1:0.1:1];
+%! A = [-1:0.1:1; -1:0.1:1]';
 %! wavwrite (A, 4000, fname);
 %! [B, samples_per_sec, bits_per_sample] = wavread (fname);
 %! unlink (fname);
@@ -172,7 +172,7 @@
 %! assert (bits_per_sample, 16);
 
 %!test
-%! A = [-1:0.1:1; -1:0.1:1];
+%! A = [-1:0.1:1; -1:0.1:1]';
 %! wavwrite (A, 4000, 8, fname);
 %! [B, samples_per_sec, bits_per_sample] = wavread (fname);
 %! unlink (fname);
@@ -197,3 +197,22 @@
 %! assert (samples_per_sec, 8000);
 %! assert (bits_per_sample, 16);
 
+%!test
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! wavwrite (A, fname);
+%! B = wavread (fname, 15);
+%! unlink (fname);
+%! assert (A(1:15,:) ,B, 1/2^15);
+%! wavwrite (A, fname);
+%! B = wavread (fname, [10, 20]);
+%! unlink (fname);
+%! assert (A(10:20,:) ,B, 1/2^15);
+
+%!test
+%! A = [-1:0.1:1; -1:0.1:1]';
+%! wavwrite (A, fname);
+%! [nsamp, nchan] = wavread (fname, "size");
+%! unlink (fname);
+%! assert (nsamp, 21);
+%! assert (nchan, 2);
+
--- a/scripts/deprecated/__error_text__.m
+++ b/scripts/deprecated/__error_text__.m
@@ -34,3 +34,4 @@
   [msg, msgid] = lasterr (varargin{:});
 
 endfunction
+
--- a/scripts/deprecated/cut.m
+++ b/scripts/deprecated/cut.m
@@ -69,3 +69,4 @@
   endif
 
 endfunction
+
--- a/scripts/deprecated/error_text.m
+++ b/scripts/deprecated/error_text.m
@@ -34,3 +34,4 @@
   [msg, msgid] = lasterr (varargin{:});
 
 endfunction
+
--- a/scripts/deprecated/isstr.m
+++ b/scripts/deprecated/isstr.m
@@ -38,3 +38,4 @@
   retval = ischar (varargin{:});
 
 endfunction
+
--- a/scripts/deprecated/java_convert_matrix.m
+++ b/scripts/deprecated/java_convert_matrix.m
@@ -23,9 +23,9 @@
 ## Query or set the internal variable that controls whether Java arrays are
 ## automatically converted to Octave matrices.  The default value is false.
 ## 
-## When called from inside a function with the "local" option, the variable is
-## changed locally for the function and any subroutines it calls.  The original
-## variable value is restored when exiting the function.
+## When called from inside a function with the @qcode{"local"} option, the
+## variable is changed locally for the function and any subroutines it calls.
+##  The original variable value is restored when exiting the function.
 ## @seealso{java_matrix_autoconversion, java_unsigned_conversion, java_debug}
 ## @end deftypefn
 
--- a/scripts/deprecated/java_debug.m
+++ b/scripts/deprecated/java_debug.m
@@ -24,9 +24,9 @@
 ## information regarding the initialization of the JVM and any Java exceptions
 ## is printed.
 ## 
-## When called from inside a function with the "local" option, the variable is
-## changed locally for the function and any subroutines it calls.  The original
-## variable value is restored when exiting the function.
+## When called from inside a function with the @qcode{"local"} option, the
+## variable is changed locally for the function and any subroutines it calls.
+##  The original variable value is restored when exiting the function.
 ## @seealso{debug_java, java_convert_matrix, java_unsigned_conversion}
 ## @end deftypefn
 
--- a/scripts/deprecated/java_unsigned_conversion.m
+++ b/scripts/deprecated/java_unsigned_conversion.m
@@ -25,9 +25,9 @@
 ## arrays of class Byte or Integer are converted to matrices of class uint8 or
 ## uint32 respectively.
 ## 
-## When called from inside a function with the "local" option, the variable is
-## changed locally for the function and any subroutines it calls.  The original
-## variable value is restored when exiting the function.
+## When called from inside a function with the @qcode{"local"} option, the
+## variable is changed locally for the function and any subroutines it calls.
+##  The original variable value is restored when exiting the function.
 ## @seealso{java_unsigned_autoconversion, java_convert_matrix, debug_java}
 ## @end deftypefn
 
--- a/scripts/deprecated/polyderiv.m
+++ b/scripts/deprecated/polyderiv.m
@@ -98,6 +98,7 @@
 
 endfunction
 
+
 %!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2])));
 
 %!assert(polyderiv (13) == 0);
--- a/scripts/deprecated/shell_cmd.m
+++ b/scripts/deprecated/shell_cmd.m
@@ -23,11 +23,11 @@
 ## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@dots{})
 ## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@var{string}, @var{return_output}, @var{type})
 ## Execute a shell command specified by @var{string}.
-## If the optional argument @var{type} is "async", the process
+## If the optional argument @var{type} is @qcode{"async"}, the process
 ## is started in the background and the process id of the child process
 ## is returned immediately.  Otherwise, the process is started and
 ## Octave waits until it exits.  If the @var{type} argument is omitted, it
-## defaults to a value of "sync".
+## defaults to a value of @qcode{"sync"}.
 ## 
 ## If the optional argument @var{return_output} is true and the subprocess
 ## is started synchronously, or if @var{shell_cmd} is called with one input
--- a/scripts/deprecated/studentize.m
+++ b/scripts/deprecated/studentize.m
@@ -78,6 +78,7 @@
 
 endfunction
 
+
 %!assert(studentize ([1,2,3]), [-1,0,1])
 %!assert(studentize (int8 ([1,2,3])), [-1,0,1])
 #%!assert(studentize (ones (3,2,0,2)), zeros (3,2,0,2))
--- a/scripts/deprecated/sylvester_matrix.m
+++ b/scripts/deprecated/sylvester_matrix.m
@@ -57,6 +57,7 @@
 
 endfunction
 
+
 %!assert((sylvester_matrix (1) == [1, 1; 1, -1]
 %! && (sylvester_matrix (2)
 %! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1])));
--- a/scripts/general/accumdim.m
+++ b/scripts/general/accumdim.m
@@ -108,7 +108,7 @@
       subsc{dim} = mask;
       A(subsc{:}) = fillval;
     endif
-    return
+    return;
   endif
 
   ## The general case.
--- a/scripts/general/bicubic.m
+++ b/scripts/general/bicubic.m
@@ -221,6 +221,7 @@
 
 endfunction
 
+
 %!demo
 %! clf;
 %! colormap ("default");
--- a/scripts/general/bitcmp.m
+++ b/scripts/general/bitcmp.m
@@ -49,6 +49,9 @@
   if (isa (A, "double"))
     bmax = bitmax;
     amax = ceil (log2 (bmax));
+  elseif (isa (A, "single"))
+    bmax = bitmax ("single");
+    amax = ceil (log2 (bmax));
   else
     if (isa (A, "uint8"))
       amax = 8;
@@ -93,6 +96,13 @@
 %! assert (bitcmp (A,Amax-1), bitshift (1,Amax-2));
 %! assert (bitcmp (A,Amax-2), 0);
 %!test
+%! Amax = 24;
+%! Bmax = bitmax ("single");
+%! A = bitshift (Bmax,-2);
+%! assert (bitcmp (A,Amax),bitor (bitshift (single (1),Amax-1), bitshift (single (1),Amax-2)));
+%! assert (bitcmp (A,Amax-1), bitshift (single (1),Amax-2));
+%! assert (bitcmp (A,Amax-2), single (0));
+%!test
 %! Amax = 8;
 %! Bmax = intmax ("uint8");
 %! A = bitshift (Bmax,-2);
--- a/scripts/general/bitget.m
+++ b/scripts/general/bitget.m
@@ -39,8 +39,11 @@
   endif
 
   if (isa (A, "double"))
-    Amax = log2 (bitmax) + 1;
+    Amax = ceil (log2 (bitmax));
     _conv = @double;
+  elseif (isa (A, "single"))
+    Amax = ceil (log2 (bitmax ("single")));
+    _conv = @single;
   else
     if (isa (A, "uint8"))
       Amax = 8;
@@ -83,6 +86,7 @@
 
 %!test
 %! assert (bitget ([4, 14], [3, 3]), logical ([1, 1]));
+%! assert (bitget (single ([4, 14]), [3, 3]), logical ([1, 1]));
 %! pfx = {"", "u"};
 %! for i = 1:2
 %!   for prec = [8, 16, 32, 64]
@@ -94,6 +98,9 @@
 %!error bitget (0, 0)
 %!error bitget (0, 55)
 
+%!error bitget (single (0), 0)
+%!error bitget (single (0), 26)
+
 %!error bitget (int8 (0), 9)
 %!error bitget (uint8 (0), 9)
 
--- a/scripts/general/bitset.m
+++ b/scripts/general/bitset.m
@@ -54,10 +54,10 @@
 
   if (isfloat (A) && isreal (A))
     Bmax = bitmax (cl);
-    Amax = log2 (Bmax);
+    Amax = ceil (log2 (Bmax));
   elseif (isinteger (A))
     Bmax = intmax (cl);
-    Amax = round (log2 (Bmax));
+    Amax = ceil (log2 (Bmax));
   else
     error ("bitset: invalid class %s", cl);
   endif
@@ -91,6 +91,7 @@
 
 %!test
 %! assert (bitset ([0, 10], [3, 3]), [4, 14]);
+%! assert (bitset (single ([0, 10]), [3, 3]), single ([4, 14]));
 %! pfx = {"", "u"};
 %! for i = 1:2
 %!   for prec = [8, 16, 32, 64]
@@ -108,6 +109,8 @@
 %!error <invalid class char> bitset ("1", 2)
 %!error <N must be in the range \[1,53\]> bitset (0, 0)
 %!error <N must be in the range \[1,53\]> bitset (0, 55)
+%!error <N must be in the range \[1,24\]> bitset (single (0), 0)
+%!error <N must be in the range \[1,24\]> bitset (single (0), 26)
 %!error <N must be in the range \[1,8\]> bitset (uint8 (0), 0)
 %!error <N must be in the range \[1,8\]> bitset (uint8 (0), 9)
 %!error <N must be in the range \[1,7\]> bitset (int8 (0), 9)
--- a/scripts/general/celldisp.m
+++ b/scripts/general/celldisp.m
@@ -89,3 +89,4 @@
 %!error celldisp ()
 %!error celldisp ({}, "name", 1)
 %!error <C must be a cell array> celldisp (1)
+
--- a/scripts/general/colon.m
+++ b/scripts/general/colon.m
@@ -43,3 +43,4 @@
 %!error colon (1)
 
 ## FIXME -- what does colon () mean since it doesn't set a return value?
+
--- a/scripts/general/cplxpair.m
+++ b/scripts/general/cplxpair.m
@@ -161,6 +161,6 @@
 %!assert (cplxpair ([z(randperm(7)),z(randperm(7))],[],1), [z,z])
 %!assert (cplxpair ([z(randperm(7)).';z(randperm(7)).'],[],2), [z.';z.'])
 
-%!## tolerance test
+## tolerance test
 %!assert (cplxpair ([1i, -1i, 1+(1i*eps)],2*eps), [-1i, 1i, 1+(1i*eps)])
- 
+
--- a/scripts/general/dblquad.m
+++ b/scripts/general/dblquad.m
@@ -40,7 +40,8 @@
 ## is @code{quadcc}.
 ##
 ## Additional arguments, are passed directly to @var{f}.  To use the default
-## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]).
+## value for @var{tol} or @var{quadf} one may pass @qcode{':'} or an empty
+## matrix ([]).
 ## @seealso{triplequad, quad, quadv, quadl, quadgk, quadcc, trapz}
 ## @end deftypefn
 
--- a/scripts/general/del2.m
+++ b/scripts/general/del2.m
@@ -157,3 +157,4 @@
 
   D = D ./ nd;
 endfunction
+
--- a/scripts/general/display.m
+++ b/scripts/general/display.m
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} display (@var{a})
 ## Display the contents of an object.  If @var{a} is an object of the
-## class "myclass", then @code{display} is called in a case like
+## class @qcode{"myclass"}, then @code{display} is called in a case like
 ##
 ## @example
 ## myclass (@dots{})
@@ -27,7 +27,7 @@
 ##
 ## @noindent
 ## where Octave is required to display the contents of a variable of the
-## type "myclass".
+## type @qcode{"myclass"}.
 ##
 ## @seealso{class, subsref, subsasgn}
 ## @end deftypefn
@@ -48,3 +48,4 @@
   endif
 
 endfunction
+
--- a/scripts/general/fieldnames.m
+++ b/scripts/general/fieldnames.m
@@ -31,7 +31,7 @@
 ## properties of the object.
 ##
 ## When the input is a Java object @var{javaobj} or Java classname
-## @var{jclassname}) the name are the public data elements of the object or
+## @var{jclassname} the name are the public data elements of the object or
 ## class.
 ## @seealso{struct, methods}
 ## @end deftypefn
--- a/scripts/general/genvarname.m
+++ b/scripts/general/genvarname.m
@@ -82,14 +82,15 @@
 ## an underscore.  Also, variables may not begin with a digit; in this
 ## case an underscore is added before the variable name.
 ##
-## Variable names beginning and ending with two underscores "__" are valid but
-## they are used internally by octave and should generally be avoided, therefore
-## genvarname will not generate such names.
+## Variable names beginning and ending with two underscores @qcode{"__"} are
+## valid but they are used internally by octave and should generally be
+## avoided, therefore genvarname will not generate such names.
 ##
 ## genvarname will also make sure that returned names do not clash with
-## keywords such as "for" and "if".  A number will be appended if necessary.
-## Note, however, that this does @strong{not} include function names,
-## such as "sin".  Such names should be included in @var{avoid} if necessary.
+## keywords such as @qcode{"for"} and @qcode{"if"}.  A number will be
+## appended if necessary.  Note, however, that this does @strong{not} include
+## function names, such as @qcode{"sin"}.  Such names should be included in
+## @var{avoid} if necessary.
 ## @seealso{isvarname, exist, tmpnam, eval}
 ## @end deftypefn
 
--- a/scripts/general/idivide.m
+++ b/scripts/general/idivide.m
@@ -28,25 +28,25 @@
 ## a string with one of the values:
 ##
 ## @table @asis
-## @item "fix"
+## @item @qcode{"fix"}
 ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
 ## towards zero.
 ##
-## @item "round"
+## @item @qcode{"round"}
 ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
 ## towards the nearest integer.
 ##
-## @item "floor"
+## @item @qcode{"floor"}
 ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
 ## towards negative infinity.
 ##
-## @item "ceil"
+## @item @qcode{"ceil"}
 ## Calculate @code{@var{a} ./ @var{b}} with the fractional part rounded
 ## towards positive infinity.
 ## @end table
 ##
 ## @noindent
-## If @var{op} is not given it defaults to @code{"fix"}.
+## If @var{op} is not given it defaults to @qcode{"fix"}.
 ## An example demonstrating these rounding rules is
 ##
 ## @example
--- a/scripts/general/interp1.m
+++ b/scripts/general/interp1.m
@@ -32,19 +32,19 @@
 ## Method is one of:
 ##
 ## @table @asis
-## @item "nearest"
+## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item "linear"
+## @item @qcode{"linear"}
 ## Linear interpolation from nearest neighbors
 ##
-## @item "pchip"
+## @item @qcode{"pchip"}
 ## Piecewise cubic Hermite interpolating polynomial
 ##
-## @item "cubic"
+## @item @qcode{"cubic"}
 ## Cubic interpolation (same as @code{pchip})
 ##
-## @item "spline"
+## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve
 ## @end table
@@ -52,18 +52,18 @@
 ## Appending '*' to the start of the above method forces @code{interp1}
 ## to assume that @var{x} is uniformly spaced, and only @code{@var{x}(1)}
 ## and @code{@var{x}(2)} are referenced.  This is usually faster,
-## and is never slower.  The default method is "linear".
+## and is never slower.  The default method is @qcode{"linear"}.
 ##
-## If @var{extrap} is the string "extrap", then extrapolate values beyond
-## the endpoints.  If @var{extrap} is a number, replace values beyond the
-## endpoints with that number.  If @var{extrap} is missing, assume NA.
+## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values
+## beyond the endpoints.  If @var{extrap} is a number, replace values beyond
+## the endpoints with that number.  If @var{extrap} is missing, assume NA.
 ##
-## If the string argument "pp" is specified, then @var{xi} should not be
+## If the string argument @qcode{"pp"} is specified, then @var{xi} should not be
 ## supplied and @code{interp1} returns the piecewise polynomial that
 ## can later be used with @code{ppval} to evaluate the interpolation.
 ## There is an equivalence, such that @code{ppval (interp1 (@var{x},
-## @var{y}, @var{method}, "pp"), @var{xi}) == interp1 (@var{x}, @var{y},
-## @var{xi}, @var{method}, "extrap")}.
+## @var{y}, @var{method}, @qcode{"pp"}), @var{xi}) == interp1 (@var{x}, @var{y},
+## @var{xi}, @var{method}, @qcode{"extrap"})}.
 ##
 ## Duplicate points in @var{x} specify a discontinuous interpolant.  There
 ## may be at most 2 consecutive points with the same value.
@@ -71,10 +71,11 @@
 ## right-continuous.  If @var{x} is decreasing, the default discontinuous
 ## interpolant is left-continuous.
 ## The continuity condition of the interpolant may be specified by using
-## the options, "-left" or "-right", to select a left-continuous
+## the options, @qcode{"-left"} or @qcode{"-right"}, to select a left-continuous
 ## or right-continuous interpolant, respectively.
-## Discontinuous interpolation is only allowed for "nearest" and "linear"
-## methods; in all other cases, the @var{x}-values must be unique.
+## Discontinuous interpolation is only allowed for @qcode{"nearest"} and
+## @qcode{"linear"} methods; in all other cases, the @var{x}-values must be
+## unique.
 ##
 ## An example of the use of @code{interp1} is
 ##
@@ -186,15 +187,15 @@
       rightcontinuous = false;
     else
       rightcontinuous = true;
-    end
+    endif
   endif
 
   if ((rightcontinuous && (x(end) < x(1)))
-      || (~ rightcontinuous && (x(end) > x(1))))
+      || (! rightcontinuous && (x(end) > x(1))))
     ## Switch between left-continuous and right-continuous
     x = flipud (x);
     y = flipud (y);
-  end
+  endif
 
   starmethod = method(1) == "*";
 
@@ -216,91 +217,93 @@
 
   ## Proceed with interpolating by all methods.
   switch (method)
-  case "nearest"
-    pp = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)], shiftdim (y, 1), szy(2:end));
-    pp.orient = "first";
+    case "nearest"
+      pp = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)],
+                 shiftdim (y, 1), szy(2:end));
+      pp.orient = "first";
 
-    if (ispp)
-      yi = pp;
-    else
-      yi = ppval (pp, reshape (xi, szx));
-    endif
-  case "*nearest"
-    pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)], shiftdim (y, 1), szy(2:end));
-    pp.orient = "first";
-    if (ispp)
-      yi = pp;
-    else
-      yi = ppval (pp, reshape (xi, szx));
-    endif
-  case "linear"
-    dy = diff (y);
-    dx = diff (x);
-    dx = repmat (dx, [1 size(dy)(2:end)]);
-    coefs = [(dy./dx).'(:), y(1:nx-1, :).'(:)];
-    xx = x;
+      if (ispp)
+        yi = pp;
+      else
+        yi = ppval (pp, reshape (xi, szx));
+      endif
+    case "*nearest"
+      pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)],
+                 shiftdim (y, 1), szy(2:end));
+      pp.orient = "first";
+      if (ispp)
+        yi = pp;
+      else
+        yi = ppval (pp, reshape (xi, szx));
+      endif
+    case "linear"
+      dy = diff (y);
+      dx = diff (x);
+      dx = repmat (dx, [1 size(dy)(2:end)]);
+      coefs = [(dy./dx).'(:), y(1:nx-1, :).'(:)];
+      xx = x;
 
-    if (have_jumps)
-      ## Omit zero-size intervals.
-      coefs(jumps, :) = [];
-      xx(jumps) = [];
-    endif
+      if (have_jumps)
+        ## Omit zero-size intervals.
+        coefs(jumps, :) = [];
+        xx(jumps) = [];
+      endif
 
-    pp = mkpp (xx, coefs, szy(2:end));
-    pp.orient = "first";
+      pp = mkpp (xx, coefs, szy(2:end));
+      pp.orient = "first";
 
-    if (ispp)
-      yi = pp;
-    else
-      yi = ppval (pp, reshape (xi, szx));
-    endif
+      if (ispp)
+        yi = pp;
+      else
+        yi = ppval (pp, reshape (xi, szx));
+      endif
 
-  case "*linear"
-    dy = diff (y);
-    coefs = [(dy/dx).'(:), y(1:nx-1, :).'(:)];
-    pp = mkpp (x, coefs, szy(2:end));
-    pp.orient = "first";
+    case "*linear"
+      dy = diff (y);
+      coefs = [(dy/dx).'(:), y(1:nx-1, :).'(:)];
+      pp = mkpp (x, coefs, szy(2:end));
+      pp.orient = "first";
 
-    if (ispp)
-      yi = pp;
-    else
-      yi = ppval (pp, reshape (xi, szx));
-    endif
+      if (ispp)
+        yi = pp;
+      else
+        yi = ppval (pp, reshape (xi, szx));
+      endif
 
-  case {"pchip", "*pchip", "cubic", "*cubic"}
-    if (nx == 2 || starmethod)
-      x = linspace (x(1), x(nx), ny);
-    endif
+    case {"pchip", "*pchip", "cubic", "*cubic"}
+      if (nx == 2 || starmethod)
+        x = linspace (x(1), x(nx), ny);
+      endif
 
-    if (ispp)
-      y = shiftdim (reshape (y, szy), 1);
-      yi = pchip (x, y);
-      yi.orient = "first";
-    else
-      y = shiftdim (y, 1);
-      yi = pchip (x, y, reshape (xi, szx));
-      if (! isvector (y))
-        yi = shiftdim (yi, 1);
+      if (ispp)
+        y = shiftdim (reshape (y, szy), 1);
+        yi = pchip (x, y);
+        yi.orient = "first";
+      else
+        y = shiftdim (y, 1);
+        yi = pchip (x, y, reshape (xi, szx));
+        if (! isvector (y))
+          yi = shiftdim (yi, 1);
+        endif
+      endif
+    case {"spline", "*spline"}
+      if (nx == 2 || starmethod)
+        x = linspace (x(1), x(nx), ny);
       endif
-    endif
-  case {"spline", "*spline"}
-    if (nx == 2 || starmethod)
-      x = linspace (x(1), x(nx), ny);
-    endif
 
-    if (ispp)
-      y = shiftdim (reshape (y, szy), 1);
-      yi = spline (x, y);
-      yi.orient = "first";
-    else
-      y = shiftdim (y, 1);
-      yi = spline (x, y, reshape (xi, szx));
-      if (! isvector (y))
-        yi = shiftdim (yi, 1);
+      if (ispp)
+        y = shiftdim (reshape (y, szy), 1);
+        yi = spline (x, y);
+        yi.orient = "first";
+      else
+        y = shiftdim (y, 1);
+        yi = spline (x, y, reshape (xi, szx));
+        if (! isvector (y))
+          yi = shiftdim (yi, 1);
+        endif
       endif
-    endif
-  otherwise
-    error ("interp1: invalid method '%s'", method);
+    otherwise
+      error ("interp1: invalid method '%s'", method);
   endswitch
 
   if (! ispp)
--- a/scripts/general/interp2.m
+++ b/scripts/general/interp2.m
@@ -36,8 +36,9 @@
 ## matrices @var{xi}, @var{yi}.
 ##
 ## If the last argument is a string, the interpolation method can
-## be specified.  The method can be "linear", "nearest" or "cubic".
-## If it is omitted "linear" interpolation is assumed.
+## be specified.  The method can be @qcode{"linear"}, @qcode{"nearest"} or
+## @qcode{"cubic"}.  If it is omitted @qcode{"linear"} interpolation is
+## assumed.
 ##
 ## @item interp2 (@var{z}, @var{xi}, @var{yi})
 ## Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} =
@@ -52,19 +53,19 @@
 ## interpolation.  It can take one of the following values
 ##
 ## @table @asis
-## @item "nearest"
+## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item "linear"
+## @item @qcode{"linear"}
 ## Linear interpolation from nearest neighbors.
 ##
-## @item "pchip"
+## @item @qcode{"pchip"}
 ## Piecewise cubic Hermite interpolating polynomial.
 ##
-## @item "cubic"
+## @item @qcode{"cubic"}
 ## Cubic interpolation from four nearest neighbors.
 ##
-## @item "spline"
+## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
--- a/scripts/general/interp3.m
+++ b/scripts/general/interp3.m
@@ -28,9 +28,9 @@
 ## array @var{v} represents a value at a location given by the parameters
 ## @var{x}, @var{y}, and @var{z}.  The parameters @var{x}, @var{x}, and
 ## @var{z} are either 3-dimensional arrays of the same size as the array
-## @var{v} in the "meshgrid" format or vectors.  The parameters @var{xi}, etc.
-## respect a similar format to @var{x}, etc., and they represent the points
-## at which the array @var{vi} is interpolated.
+## @var{v} in the @qcode{"meshgrid"} format or vectors.  The parameters
+## @var{xi}, etc. respect a similar format to @var{x}, etc., and they
+## represent the points at which the array @var{vi} is interpolated.
 ##
 ## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be
 ## @code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and
@@ -42,25 +42,25 @@
 ## Method is one of:
 ##
 ## @table @asis
-## @item "nearest"
+## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item "linear"
+## @item @qcode{"linear"}
 ## Linear interpolation from nearest neighbors.
 ##
-## @item "cubic"
+## @item @qcode{"cubic"}
 ## Cubic interpolation from four nearest neighbors (not implemented yet).
 ##
-## @item "spline"
+## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
 ##
-## The default method is "linear".
+## The default method is @qcode{"linear"}.
 ##
-## If @var{extrap} is the string "extrap", then extrapolate values beyond
-## the endpoints.  If @var{extrap} is a number, replace values beyond the
-## endpoints with that number.  If @var{extrap} is missing, assume NA.
+## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values
+## beyond the endpoints.  If @var{extrap} is a number, replace values beyond
+## the endpoints with that number.  If @var{extrap} is missing, assume NA.
 ## @seealso{interp1, interp2, spline, meshgrid}
 ## @end deftypefn
 
--- a/scripts/general/interpft.m
+++ b/scripts/general/interpft.m
@@ -70,7 +70,7 @@
 
   inc = ceil (m/n);
   y = fft (x) / m;
-  k = floor (m / 2);
+  k = ceil (m / 2);
   sz = size (x);
   sz(1) = n * inc - m;
 
@@ -79,6 +79,18 @@
   z = cat (1, y(idx{:}), zeros (sz));
   idx{1} = k+1:m;
   z = cat (1, z, y(idx{:}));
+
+  ## When m is an even number of rows, the FFT has a single Nyquist bin.
+  ## If zero-padded above, distribute the value of the Nyquist bin evenly
+  ## between the new corresponding positive and negative frequency bins.
+  if (sz(1) > 0 && k == m/2)
+    idx{1} = n * inc - k + 1;
+    tmp = z(idx{:}) / 2;
+    z(idx{:}) = tmp;
+    idx{1} = k + 1;
+    z(idx{:}) = tmp;
+  endif
+
   z = n * ifft (z);
 
   if (inc != 1)
@@ -108,6 +120,18 @@
 %!assert (interpft (y', n), y', 20*eps);
 %!assert (interpft ([y,y],n), [y,y], 20*eps);
 
+%% Test case with complex input from bug #39566
+%!test
+%! x = (1 + j) * [1:4]';
+%! y = ifft ([15 + 15*j; -6; -1.5 - 1.5*j; 0; -1.5 - 1.5*j; -6*j]);
+%! assert (interpft (x, 6), y, 10*eps);
+
+%% Test for correct spectral symmetry with even/odd lengths
+%!assert (max (abs (imag (interpft ([1:8], 20)))), 0, 20*eps);
+%!assert (max (abs (imag (interpft ([1:8], 21)))), 0, 21*eps);
+%!assert (max (abs (imag (interpft ([1:9], 20)))), 0, 20*eps);
+%!assert (max (abs (imag (interpft ([1:9], 21)))), 0, 21*eps);
+
 %% Test input validation
 %!error interpft ()
 %!error interpft (1)
--- a/scripts/general/interpn.m
+++ b/scripts/general/interpn.m
@@ -29,9 +29,9 @@
 ## at a location given by the parameters @var{x1}, @var{x2}, @dots{}, @var{xn}.
 ## The parameters @var{x1}, @var{x2}, @dots{}, @var{xn} are either
 ## @var{n}-dimensional arrays of the same size as the array @var{v} in
-## the "ndgrid" format or vectors.  The parameters @var{y1}, etc. respect a
-## similar format to @var{x1}, etc., and they represent the points at which
-## the array @var{vi} is interpolated.
+## the @qcode{"ndgrid"} format or vectors.  The parameters @var{y1}, etc.
+## respect a similar format to @var{x1}, etc., and they represent the points
+## at which the array @var{vi} is interpolated.
 ##
 ## If @var{x1}, @dots{}, @var{xn} are omitted, they are assumed to be
 ## @code{x1 = 1 : size (@var{v}, 1)}, etc.  If @var{m} is specified, then
@@ -42,21 +42,21 @@
 ## Method is one of:
 ##
 ## @table @asis
-## @item "nearest"
+## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item "linear"
+## @item @qcode{"linear"}
 ## Linear interpolation from nearest neighbors.
 ##
-## @item "cubic"
+## @item @qcode{"cubic"}
 ## Cubic interpolation from four nearest neighbors (not implemented yet).
 ##
-## @item "spline"
+## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
 ##
-## The default method is "linear".
+## The default method is @qcode{"linear"}.
 ##
 ## If @var{extrapval} is the scalar value, use it to replace the values
 ## beyond the endpoints with that number.  If @var{extrapval} is missing,
--- a/scripts/general/isa.m
+++ b/scripts/general/isa.m
@@ -23,13 +23,14 @@
 ## @var{classname} may also be one of the following class categories: 
 ##
 ## @table @asis
-## @item "float"
-## Floating point value comprising classes "double" and "single".
+## @item @qcode{"float"}
+## Floating point value comprising classes @qcode{"double"} and
+## @qcode{"single"}.
 ##
-## @item "integer"
+## @item @qcode{"integer"}
 ## Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64.
 ##
-## @item "numeric"
+## @item @qcode{"numeric"}
 ## Numeric value comprising either a floating point or integer value.
 ## @end table
 ## @seealso{class, typeinfo}
--- a/scripts/general/isdir.m
+++ b/scripts/general/isdir.m
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} isdir (@var{f})
 ## Return true if @var{f} is a directory.
-## @seealso{is_absolute_filename, is_rooted_relative_filename}
+## @seealso{exist, stat, is_absolute_filename, is_rooted_relative_filename}
 ## @end deftypefn
 
 function retval = isdir (f)
@@ -32,6 +32,7 @@
 
 endfunction
 
+
 %!assert (isdir (pwd ()))
 %!assert (! isdir ("this is highly unlikely to be a directory name"))
 
--- a/scripts/general/isequal.m
+++ b/scripts/general/isequal.m
@@ -74,6 +74,11 @@
 ## test for inequality (struct)
 %!assert (isequal (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), false)
 
+## test for sparse matrices
+%!assert (isequal (sparse (0,1), sparse (0,1)), true)
+%!assert (isequal (sparse (0,1), sparse (1,0)), false)
+%!assert (isequal (sparse (2, 2), sparse (2, 2)), true)
+
 ## Input validation
 %!error isequal ()
 %!error isequal (1)
--- a/scripts/general/isequaln.m
+++ b/scripts/general/isequaln.m
@@ -48,3 +48,4 @@
 ## Input validation
 %!error isequaln ()
 %!error isequaln (1)
+
--- a/scripts/general/loadobj.m
+++ b/scripts/general/loadobj.m
@@ -39,3 +39,4 @@
 function b = loadobj (a)
   error ('loadobj: not defined for class "%s"', class (a));
 endfunction
+
--- a/scripts/general/num2str.m
+++ b/scripts/general/num2str.m
@@ -92,10 +92,9 @@
       if (isnumeric (x))
         ## Setup a suitable format string, ignoring inf entries
         dgt = floor (log10 (max (abs (x(!isinf (x(:)))))));
-
-        ## If the whole input array is inf...
         if (isempty (dgt))
-          dgt = 0;
+          ## If the whole input array is inf...
+          dgt = 1;
         endif
 
         if (any (x(:) != fix (x(:))))
@@ -130,8 +129,13 @@
       endif
     else
       ## Setup a suitable format string
-      dgt = floor (log10 (max (max (abs (real (x(:)))),
-                               max (abs (imag (x(:)))))));
+      dgt = floor (log10 (max (max (abs (real (x(!isinf (real (x(:))))))),
+                               max (abs (imag (x(!isinf (imag (x(:))))))))));
+      if (isempty (dgt))
+        ## If the whole input array is inf...
+        dgt = 1;
+      endif
+
       if (any (x(:) != fix (x(:))))
         ## Floating point input
           dgt = max (dgt + 4, 5);   # Keep 4 sig. figures after decimal point
@@ -183,7 +187,16 @@
 %!assert (num2str (2^33+1i), "8589934592+1i")
 %!assert (num2str (-2^33+1i), "-8589934592+1i")
 %!assert (num2str (inf), "Inf")
+%!assert (num2str ([inf -inf]), "Inf -Inf")
+%!assert (num2str ([complex(Inf,0), complex(0,-Inf)]), "Inf+0i   0-Infi")
+%!assert (num2str (complex(Inf,1)), "Inf+1i")
+%!assert (num2str (complex(1,Inf)), "1+Infi")
 %!assert (num2str (nan), "NaN")
+%!assert (num2str (complex (NaN, 1)), "NaN+1i")
+%!assert (num2str (complex (1, NaN)), "1+NaNi")
+%!assert (num2str (NA), "NA")
+%!assert (num2str (complex (NA, 1)), "NA+1i")
+%!assert (num2str (complex (1, NA)), "1+NAi")
 
 ## FIXME: Integers greater than bitmax() should be masked to show just
 ##        16 digits of precision.
--- a/scripts/general/private/__isequal__.m
+++ b/scripts/general/private/__isequal__.m
@@ -48,10 +48,6 @@
 
 function t = __isequal__ (nans_compare_equal, x, varargin)
 
-  if (nargin < 3)
-    print_usage ();
-  endif
-
   l_v = nargin - 2;
 
   ## Generic tests.
@@ -160,7 +156,7 @@
 
         t = (l_f_x == length (f_y)) && all (f_x == f_y);
         if (!t)
-          return;
+          break;
         endif
 
         y = y(f_y);
@@ -172,11 +168,18 @@
         endif
 
         if (!t)
-          return;
+          break;
         endif
       endfor
 
     endif
   endif
 
+  if (!t)
+    t = false;
+  else
+    t = true;
+  endif
+
 endfunction
+
--- a/scripts/general/private/__splinen__.m
+++ b/scripts/general/private/__splinen__.m
@@ -26,14 +26,11 @@
 ## FIXME: Allow arbitrary grids..
 
 function yi = __splinen__ (x, y, xi, extrapval, f)
-  if (nargin != 5)
-    error ("__splinen__: Incorrect number of arguments");
-  endif
   ## ND isvector function.
   isvec = @(x) numel (x) == length (x);
   if (!iscell (x) || length (x) < ndims (y) || any (! cellfun (isvec, x))
       || !iscell (xi) || length (xi) < ndims (y) || any (! cellfun (isvec, xi)))
-    error ("__splinen__: %s: non gridded data or dimensions inconsistent", f);
+    error ("__splinen__: %s: non-gridded data or dimensions inconsistent", f);
   endif
   yi = y;
   for i = length (x):-1:1
@@ -47,3 +44,4 @@
   endfor
   yi(idx) = extrapval;
 endfunction
+
--- a/scripts/general/profexplore.m
+++ b/scripts/general/profexplore.m
@@ -17,13 +17,15 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} profexplore (@var{data})
+## @deftypefn  {Function File} {} profexplore ()
+## @deftypefnx {Function File} {} profexplore (@var{data})
 ## Interactively explore hierarchical profiler output.
 ##
 ## Assuming @var{data} is the structure with profile data returned by
-## @code{profile ("info")}, this command opens an interactive prompt
+## @code{profile (@qcode{"info"})}, this command opens an interactive prompt
 ## that can be used to explore the call-tree.  Type @kbd{help} to get a list
-## of possible commands.
+## of possible commands.  If @var{data} is omitted, @code{profile ("info")}
+## is called and used in its place.
 ## @seealso{profile, profshow}
 ## @end deftypefn
 
@@ -32,7 +34,9 @@
 
 function profexplore (data)
 
-  if (nargin != 1)
+  if (nargin == 0)
+    data = profile ("info");
+  elseif (nargin != 1)
     print_usage ();
   endif
 
@@ -78,12 +82,13 @@
     cmd = input ("profexplore> ", "s");
     option = fix (str2double (cmd));
 
-    if (strcmp (cmd, "exit"))
+    if (strcmp (cmd, "exit") || strcmp (cmd, "quit"))
       rv = 0;
       return;
     elseif (strcmp (cmd, "help"))
       printf ("\nCommands for profile explorer:\n\n");
       printf ("exit   Return to Octave prompt.\n");
+      printf ("quit   Return to Octave prompt.\n");
       printf ("help   Display this help message.\n");
       printf ("up [N] Go up N levels, where N is an integer.  Default is 1.\n");
       printf ("N      Go down a level into option N.\n");
@@ -130,3 +135,4 @@
 
   endwhile
 endfunction
+
--- a/scripts/general/profile.m
+++ b/scripts/general/profile.m
@@ -44,7 +44,7 @@
 ## @item @var{S} = profile ("status")
 ## Return a structure filled with certain information about the current status
 ## of the profiler.  At the moment, the only field is @code{ProfilerStatus}
-## which is either "on" or "off".
+## which is either @qcode{"on"} or @qcode{"off"}.
 ##
 ## @item @var{T} = profile ("info")
 ## Return the collected profiling statistics in the structure @var{T}.
--- a/scripts/general/quadgk.m
+++ b/scripts/general/quadgk.m
@@ -61,7 +61,7 @@
 ## for the integral @var{q}.
 ##
 ## Alternatively, properties of @code{quadgk} can be passed to the function as
-## pairs @code{"@var{prop}", @var{val}}.  Valid properties are
+## pairs @qcode{"@var{prop}", @var{val}}.  Valid properties are
 ##
 ## @table @code
 ## @item AbsTol
@@ -78,12 +78,12 @@
 ## unacceptable error are subdivided and re-evaluated.  If the number of
 ## subintervals exceeds 650 subintervals at any point then a poor
 ## convergence is signaled and the current estimate of the integral is
-## returned.  The property "MaxIntervalCount" can be used to alter the
+## returned.  The property @qcode{"MaxIntervalCount"} can be used to alter the
 ## number of subintervals that can exist before exiting.
 ##
 ## @item WayPoints
 ## Discontinuities in the first derivative of the function to integrate can be
-## flagged with the  @code{"WayPoints"} property.  This forces the ends of
+## flagged with the @qcode{"WayPoints"} property.  This forces the ends of
 ## a subinterval to fall on the breakpoints of the function and can result in
 ## significantly improved estimation of the error in the integral, faster
 ## computation, or both.  For example,
@@ -454,6 +454,7 @@
 %!assert (quadgk (@(x) exp (-x .^ 2),-Inf,Inf), sqrt (pi), 1e-6)
 %!assert (quadgk (@(x) exp (-x .^ 2),-Inf,0), sqrt (pi)/2, 1e-6)
 
-%error (quadgk (@sin))
-%error (quadgk (@sin, -pi))
-%error (quadgk (@sin, -pi, pi, "DummyArg"))
+%!error (quadgk (@sin))
+%!error (quadgk (@sin, -pi))
+%!error (quadgk (@sin, -pi, pi, "DummyArg"))
+
--- a/scripts/general/randi.m
+++ b/scripts/general/randi.m
@@ -34,8 +34,8 @@
 ## with a lower and upper bound in which case the returned integers will be
 ## on the interval @w{[@var{imin}, @var{imax}]}.
 ##
-## The optional argument "@var{class}" will return a matrix of the requested
-## type.  The default is "double".
+## The optional argument @var{class} will return a matrix of the requested
+## type.  The default is @qcode{"double"}.
 ##
 ## The following example returns 150 integers in the range 1-10.
 ##
@@ -44,7 +44,7 @@
 ## @end example
 ##
 ## Implementation Note: @code{randi} relies internally on @code{rand} which
-## uses class "double" to represent numbers.  This limits the maximum
+## uses class @qcode{"double"} to represent numbers.  This limits the maximum
 ## integer (@var{imax}) and range (@var{imax} - @var{imin}) to the value
 ## returned by the @code{bitmax} function.  For IEEE floating point numbers
 ## this value is @w{@math{2^{53} - 1}}.
@@ -111,6 +111,7 @@
 
 endfunction
 
+
 %!test
 %! ri = randi (10, 1000, 1);
 %! assert (ri, fix (ri));
--- a/scripts/general/repmat.m
+++ b/scripts/general/repmat.m
@@ -117,7 +117,7 @@
       cidx{2,i} = ones (1, idx (i));
     endfor
     aaidx = aidx;
-    # add singleton dims
+    ## add singleton dims
     aaidx(2,:) = 1;
     A = reshape (A, aaidx(:));
     x = reshape (A (cidx{:}), idx .* aidx);
@@ -125,6 +125,7 @@
 
 endfunction
 
+
 # Tests for ML compatibility
 %!shared x
 %! x = [1 2 3];
--- a/scripts/general/saveobj.m
+++ b/scripts/general/saveobj.m
@@ -42,3 +42,4 @@
 function b = saveobj (a)
   error ('saveobj: not defined for class "%s"', class (a));
 endfunction
+
--- a/scripts/general/structfun.m
+++ b/scripts/general/structfun.m
@@ -34,12 +34,11 @@
 ## a string value.  If the function returns more than one argument, they are
 ## returned as separate output variables.
 ##
-## If the parameter "UniformOutput" is set to true (the default), then the
-## function
-## must return a single element which will be concatenated into the
-## return value.  If "UniformOutput" is false, the outputs are placed into a
-## structure
-## with the same fieldnames as the input structure.
+## If the parameter @qcode{"UniformOutput"} is set to true (the default),
+## then the function must return a single element which will be concatenated
+## into the return value.  If @qcode{"UniformOutput"} is false, the outputs
+## are placed into a structure with the same fieldnames as the input
+## structure.
 ##
 ## @example
 ## @group
@@ -55,8 +54,9 @@
 ## @end group
 ## @end example
 ##
-## Given the parameter "ErrorHandler", @var{errfunc} defines a function to
-## call in case @var{func} generates an error.  The form of the function is
+## Given the parameter @qcode{"ErrorHandler"}, @var{errfunc} defines a
+## function to call in case @var{func} generates an error.  The form of the
+## function is
 ##
 ## @example
 ## function [@dots{}] = errfunc (@var{se}, @dots{})
@@ -65,10 +65,10 @@
 ## @noindent
 ## where there is an additional input argument to @var{errfunc} relative to
 ## @var{func}, given by @nospell{@var{se}}.  This is a structure with the
-## elements "identifier", "message" and "index", giving respectively the error
-## identifier, the error message, and the index into the input arguments
-## of the element that caused the error.  For an example on how to use
-## an error handler, @pxref{XREFcellfun,,cellfun}.
+## elements @qcode{"identifier"}, @qcode{"message"} and @qcode{"index"},
+## giving respectively the error identifier, the error message, and the index
+## into the input arguments of the element that caused the error.  For an
+## example on how to use an error handler, @pxref{XREFcellfun,,cellfun}.
 ##
 ## @seealso{cellfun, arrayfun, spfun}
 ## @end deftypefn
--- a/scripts/general/subsindex.m
+++ b/scripts/general/subsindex.m
@@ -23,7 +23,7 @@
 ## overloading method that allows the conversion of this class object to
 ## a valid indexing vector.  It is important to note that
 ## @code{subsindex} must return a zero-based real integer vector of the
-## class "double".  For example, if the class constructor
+## class @qcode{"double"}.  For example, if the class constructor
 ##
 ## @example
 ## @group
--- a/scripts/general/triplequad.m
+++ b/scripts/general/triplequad.m
@@ -40,7 +40,8 @@
 ## is @code{quadcc}.
 ##
 ## Additional arguments, are passed directly to @var{f}.  To use the default
-## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]).
+## value for @var{tol} or @var{quadf} one may pass @qcode{':'} or an empty
+## matrix ([]).
 ## @seealso{dblquad, quad, quadv, quadl, quadgk, quadcc, trapz}
 ## @end deftypefn
 
--- a/scripts/geometry/delaunay.m
+++ b/scripts/geometry/delaunay.m
@@ -74,38 +74,38 @@
 
   switch (nargin)
 
-  case 1
-    if (! ismatrix (varargin{1}) || columns (varargin{1}) != 2)
-        error ("delaunay: X must be a matrix with 2 columns");
-    else
-      x = varargin{1}(:,1);
-      y = varargin{1}(:,2);
-    endif
-  
-  case 2
-    if (isnumeric (varargin{2}))
-      x = varargin{1};
-      y = varargin{2};
-    elseif (ischar (varargin{2}) || iscellstr (varargin{2}))
-      options = varargin{2};
-      if (! ismatrix (varargin{1}) && columns (varargin{1}) != 2)
+    case 1
+      if (! ismatrix (varargin{1}) || columns (varargin{1}) != 2)
           error ("delaunay: X must be a matrix with 2 columns");
       else
         x = varargin{1}(:,1);
         y = varargin{1}(:,2);
       endif
-    else
-      error ("delaunay: OPTIONS must be a string or cell array of strings");
-    endif
+    
+    case 2
+      if (isnumeric (varargin{2}))
+        x = varargin{1};
+        y = varargin{2};
+      elseif (ischar (varargin{2}) || iscellstr (varargin{2}))
+        options = varargin{2};
+        if (! ismatrix (varargin{1}) && columns (varargin{1}) != 2)
+            error ("delaunay: X must be a matrix with 2 columns");
+        else
+          x = varargin{1}(:,1);
+          y = varargin{1}(:,2);
+        endif
+      else
+        error ("delaunay: OPTIONS must be a string or cell array of strings");
+      endif
 
-  case 3
-    x = varargin{1};
-    y = varargin{2};
-    options = varargin{3};
+    case 3
+      x = varargin{1};
+      y = varargin{2};
+      options = varargin{3};
 
-    if (! (ischar (options) || iscellstr (options)))
-      error ("delaunay: OPTIONS must be a string or cell array of strings");
-    endif
+      if (! (ischar (options) || iscellstr (options)))
+        error ("delaunay: OPTIONS must be a string or cell array of strings");
+      endif
 
   endswitch
 
@@ -166,3 +166,4 @@
 %! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,4;1,3,4;1,3,5;3,4,6]);
 
 %% FIXME: Need input validation tests
+
--- a/scripts/geometry/griddata.m
+++ b/scripts/geometry/griddata.m
@@ -29,8 +29,8 @@
 ## The interpolation points are all @code{(@var{xi}, @var{yi})}.  If
 ## @var{xi}, @var{yi} are vectors then they are made into a 2-D mesh.
 ##
-## The interpolation method can be @code{"nearest"}, @code{"cubic"} or
-## @code{"linear"}.  If method is omitted it defaults to @code{"linear"}.
+## The interpolation method can be @qcode{"nearest"}, @qcode{"cubic"} or
+## @qcode{"linear"}.  If method is omitted it defaults to @qcode{"linear"}.
 ## @seealso{griddata3, griddatan, delaunay}
 ## @end deftypefn
 
--- a/scripts/geometry/griddata3.m
+++ b/scripts/geometry/griddata3.m
@@ -25,8 +25,8 @@
 ## The function is defined by @code{@var{v} = f (@var{x}, @var{y}, @var{z})}.
 ## The interpolation points are specified by @var{xi}, @var{yi}, @var{zi}.
 ##
-## The interpolation method can be @code{"nearest"} or @code{"linear"}.
-## If method is omitted it defaults to @code{"linear"}.
+## The interpolation method can be @qcode{"nearest"} or @qcode{"linear"}.
+## If method is omitted it defaults to @qcode{"linear"}.
 ##
 ## The optional argument @var{options} is passed directly to Qhull when
 ## computing the Delaunay triangulation used for interpolation.  See
--- a/scripts/geometry/griddatan.m
+++ b/scripts/geometry/griddatan.m
@@ -25,8 +25,8 @@
 ## The function is defined by @code{@var{y} = f (@var{x})}.
 ## The interpolation points are all @var{xi}.
 ##
-## The interpolation method can be @code{"nearest"} or @code{"linear"}.
-## If method is omitted it defaults to @code{"linear"}.
+## The interpolation method can be @qcode{"nearest"} or @qcode{"linear"}.
+## If method is omitted it defaults to @qcode{"linear"}.
 ## 
 ## The optional argument @var{options} is passed directly to Qhull when
 ## computing the Delaunay triangulation used for interpolation.  See
--- a/scripts/geometry/inpolygon.m
+++ b/scripts/geometry/inpolygon.m
@@ -1,5 +1,5 @@
 ## Copyright (C) 2006-2012 Frederick (Rick) A Niles
-##               and S�ren Hauberg
+##               and Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -30,7 +30,7 @@
 ## Author: Frederick (Rick) A Niles <niles@rickniles.com>
 ## Created: 14 November 2006
 
-## Vectorized by S�ren Hauberg <soren@hauberg.org>
+## Vectorized by Søren Hauberg <soren@hauberg.org>
 
 ## The method for determining if a point is in in a polygon is based on
 ## the algorithm shown on
--- a/scripts/geometry/voronoi.m
+++ b/scripts/geometry/voronoi.m
@@ -26,9 +26,10 @@
 ## Plot the Voronoi diagram of points @code{(@var{x}, @var{y})}.
 ## The Voronoi facets with points at infinity are not drawn.
 ## 
-## If "linespec" is given it is used to set the color and line style of the
-## plot.  If an axis graphics handle @var{hax} is supplied then the Voronoi
-## diagram is drawn on the specified axis rather than in a new figure.
+## If @qcode{"linespec"} is given it is used to set the color and line style
+## of the plot.  If an axis graphics handle @var{hax} is supplied then the
+## Voronoi diagram is drawn on the specified axis rather than in a new
+## figure.
 ##
 ## The @var{options} argument, which must be a string or cell array of strings,
 ## contains options passed to the underlying qhull command.
--- a/scripts/help/__makeinfo__.m
+++ b/scripts/help/__makeinfo__.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -72,6 +72,9 @@
     error ("__makeinfo__: second input argument must be a string");
   endif
 
+  ## NOTE: The 3rd argument is used by Octave-Forge function
+  ##       generate_package_html, not by core Octave.  This functionality
+  ##       can only be removed when that function has been updated.
   if (nargin < 3)
     if (strcmpi (output_type, "plain text"))
       fsee_also = @(T) strcat ...
--- a/scripts/help/__unimplemented__.m
+++ b/scripts/help/__unimplemented__.m
@@ -40,72 +40,79 @@
 
   ## Some smarter cases, add more as needed.
   switch (fcn)
-
-  case {"avifile", "aviinfo", "aviread"}
-    txt = ["Basic video file support is provided in the video package. ",...
-    "See @url{http://octave.sf.net/video/}."];
+    case {"avifile", "aviinfo", "aviread"}
+      txt = ["Basic video file support is provided in the video package.  ", ...
+             "See @url{http://octave.sf.net/video/}."];
 
-  case "gsvd"
-    txt = ["gsvd is not currently part of core Octave.  See the ",...
-    "linear-algebra package at ",...
-    "@url{http://octave.sourceforge.net/linear-algebra/}."];
+    case "exifread"
+      txt = ["exifread is deprecated.  " ...
+             "The functionality is available in the imfinfo function."];
+
+    case "gsvd"
+      txt = ["gsvd is not currently part of core Octave.  ", ...
+             "See the linear-algebra package at ", ...
+             "@url{http://octave.sourceforge.net/linear-algebra/}."];
 
-  case "funm"
-    txt = ["funm is not currently part of core Octave.  See the ",...
-    "linear-algebra package at @url{http://octave.sf.net/linear-algebra/}."];
+    case "funm"
+      txt = ["funm is not currently part of core Octave.  ", ...
+             "See the linear-algebra package at ", ...
+             "@url{http://octave.sourceforge.net/linear-algebra/}."];
 
-  case "griddedInterpolant"
-    txt = ["griddedInterpolant is not implemented.  Consider using griddata."];
+    case "griddedInterpolant"
+      txt = ["griddedInterpolant is not implemented.  ", ...
+             "Consider using griddata."];
 
-  case "integral"
-    txt = ["Octave provides many routines for 1-D numerical integration.  ",...
-    "Consider quadcc, quad, quadv, quadl, quadgk."];
+    case "integral"
+      txt = ["Octave provides many routines for 1-D numerical integration.  ", ...
+             "Consider quadcc, quad, quadv, quadl, quadgk."];
 
-  case "integral2"
-    txt = ["integral2 is not implemented.  Consider using dblquad."];
+    case "integral2"
+      txt = ["integral2 is not implemented.  Consider using dblquad."];
 
-  case "integral3"
-    txt = ["integral3 is not implemented.  Consider using triplequad"];
+    case "integral3"
+      txt = ["integral3 is not implemented.  Consider using triplequad"];
 
-  case "linprog"
-    txt = ["Octave does not currently provide linprog.  ",...
-    "Linear programming problems may be solved using @code{glpk}.  ",...
-    "Try @code{help glpk} for more info."];
+    case "linprog"
+      txt = ["Octave does not currently provide linprog.  ", ...
+             "Linear programming problems may be solved using @code{glpk}.  ", ...
+             "Try @code{help glpk} for more info."];
 
-  case "matlabrc"
-    txt = ["matlabrc is not implemented.  ",...
-           'Octave uses the file ".octaverc" instead.'];
+    case "matlabrc"
+      txt = ["matlabrc is not implemented.  ", ...
+             'Octave uses the file ".octaverc" instead.'];
 
-  case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode23tb", "ode45", "odeget", "odeset"}
-    txt = ["Octave provides lsode for solving differential equations.  ",...
-    "For more information try @code{help lsode}.  ",...
-    "Matlab-compatible ODE functions are provided by the odepkg package.  ",...
-    "See @url{http://octave.sourceforge.net/odepkg/}."];
+    case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", ...
+          "ode23tb", "ode45", "odeget", "odeset"}
+      txt = ["Octave provides lsode for solving differential equations.  ", ...
+             "For more information try @code{help lsode}.  ", ...
+             "Matlab-compatible ODE functions are provided by the odepkg ", ...
+             "package.  See @url{http://octave.sourceforge.net/odepkg/}."];
 
-  case "startup"
-    txt = ["startup is not implemented.  ",...
-           'Octave uses the file ".octaverc" instead.'];
+    case "startup"
+      txt = ["startup is not implemented.  ", ...
+             'Octave uses the file ".octaverc" instead.'];
 
-  case "quad2d"
-    txt = ["quad2d is not implemented.  Consider using dblquad."];
+    case "quad2d"
+      txt = ["quad2d is not implemented.  Consider using dblquad."];
 
-  case {"xlsread", "xlsfinfo", "xlswrite", "wk1read", "wk1finfo", "wk1write"}
-    txt = ["Functions for spreadsheet style I/O (.xls .xlsx .sxc .ods .dbf .wk1 etc.) " , ...
-    "are provided in the io package. ",...
-    "See @url{http://octave.sf.net/io/}."];
+    case {"xlsread", "xlsfinfo", "xlswrite", "wk1read", "wk1finfo", "wk1write"}
+      txt = ["Functions for spreadsheet style I/O ", ...
+             "(.xls .xlsx .sxc .ods .dbf .wk1 etc.) " , ...
+             "are provided in the io package. ", ...
+             "See @url{http://octave.sf.net/io/}."];
 
-  otherwise
-    if (ismember (fcn, missing_functions ()))
-      txt = sprintf ("the '%s' function is not yet implemented in Octave", fcn);
-    else
-      is_matlab_function = false;
-      txt = "";
-    endif
+    otherwise
+      if (ismember (fcn, missing_functions ()))
+        txt = ["the '" fcn "' function is not yet implemented in Octave"];
+      else
+        is_matlab_function = false;
+        txt = "";
+      endif
   endswitch
 
   if (is_matlab_function)
-    txt = [txt, "\n\n@noindent\nPlease read ",...
-           "@url{http://www.octave.org/missing.html} to learn how ",...
+    txt = [txt, "\n\n@noindent\nPlease read ", ...
+           "@url{http://www.octave.org/missing.html} to learn how ", ...
            "you can contribute missing functionality."];
     txt = __makeinfo__ (txt);
   endif
@@ -204,7 +211,6 @@
   "dynamicprops",
   "echodemo",
   "evalc",
-  "exifread",
   "export2wsdlg",
   "figurepalette",
   "filebrowser",
@@ -439,3 +445,4 @@
 %! assert (str(1:51), "quad2d is not implemented.  Consider using dblquad.");
 %! str = __unimplemented__ ("MException");
 %! assert (str(1:58), "the 'MException' function is not yet implemented in Octave");
+
--- a/scripts/help/doc.m
+++ b/scripts/help/doc.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2005-2012 Søren Hauberg
+## Copyright (C) 2005-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -53,7 +53,7 @@
       fname = "";
     endif
 
-    # if GUI is running, let it display the function
+    ## if GUI is running, let it display the function
     if isguirunning ()
       __octave_link_show_doc__ (fname);
     else
--- a/scripts/help/doc_cache_create.m
+++ b/scripts/help/doc_cache_create.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -42,7 +42,7 @@
   if (isempty (directory))
     cache = gen_builtin_cache ();
   elseif (iscell (directory))
-    if (all (cellfun (@ischar, directory)))
+    if (all (cellfun ("isclass", directory, "char")))
       cache = gen_doc_cache_in_dir (directory);
     else
       error ("doc_cache_create: cell must contain only strings");
@@ -95,7 +95,7 @@
 
   ## For each function:
   for n = 1:length (list)
-    f = list {n};
+    f = list{n};
 
     ## Get help text
     [text, format] = get_help_text (f);
@@ -108,9 +108,9 @@
     endif
 
     ## Store the help text
-    cache (1, end+1) = f;
-    cache (2, end) = text;
-    cache (3, end) = first_sentence;
+    cache(1, end+1) = f;
+    cache(2, end) = text;
+    cache(3, end) = first_sentence;
   endfor
 endfunction
 
@@ -119,27 +119,27 @@
   ## If 'directory' is not in the current path, add it so we search it
   dir_in_path = ismember (directory, ostrsplit (path (), pathsep ()));
 
-  # dirs not in path
+  ## dirs not in path
   if (! iscell (directory))
     directory = {directory};
   endif
   dirs_notpath = {directory{!dir_in_path}};
 
-  # add them
+  ## add them
   if (! isempty (dirs_notpath))
-    cellfun (@addpath, dirs_notpath);
+    addpath (dirs_notpath{:});
   endif
 
-  # create cache
+  ## create cache
   func = @(s_) create_cache (__list_functions__ (s_));
-  cache = cellfun (func, directory, 'UniformOutput', false);
+  cache = cellfun (func, directory, "UniformOutput", false);
 
-  # concatenate results
+  ## concatenate results
   cache = [cache{:}];
 
-  #remove dirs form path
+  ## remove dirs form path
   if (! isempty (dirs_notpath))
-    cellfun (@rmpath, dirs_notpath);
+    rmpath (dirs_notpath{:});
   endif
 
 endfunction
@@ -157,3 +157,4 @@
 %% No true tests desirable for this function.
 %% Test input validation
 %!error doc_cache_create (1)
+
--- a/scripts/help/get_first_help_sentence.m
+++ b/scripts/help/get_first_help_sentence.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -157,7 +157,8 @@
 endfunction
 
 
-%!assert (get_first_help_sentence ('get_first_help_sentence'), "Return the first sentence of a function's help text.")
+%!assert (get_first_help_sentence ('get_first_help_sentence'), ...
+%!        "Return the first sentence of a function's help text.")
 
 %% Test input validation
 %!error get_first_help_sentence ()
--- a/scripts/help/help.m
+++ b/scripts/help/help.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -20,7 +20,7 @@
 ## @deftypefn  {Command} {} help @var{name}
 ## @deftypefnx {Command} {} help @code{--list}
 ## @deftypefnx {Command} {} help @code{.}
-## Display the help text for @var{name}.   For example, the command
+## Display the help text for @var{name}.  For example, the command
 ## @kbd{help help} prints a short message describing the @code{help}
 ## command.
 ##
@@ -209,4 +209,3 @@
 %!assert (! isempty (strfind (help ("ls"), "List directory contents")))
 %!error <invalid input> help (42)
 
-
--- a/scripts/help/lookfor.m
+++ b/scripts/help/lookfor.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 Søren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -24,7 +24,7 @@
 ## Search for the string @var{str} in all functions found in the current
 ## function search path.  By default, @code{lookfor} searches for @var{str}
 ## in the first sentence of the help string of each function found.  The entire
-## help text of each function can be searched if the "-all" argument is
+## help text of each function can be searched if the @qcode{"-all"} argument is
 ## supplied.  All searches are case insensitive.
 ##
 ## Called with no output arguments, @code{lookfor} prints the list of
@@ -36,8 +36,9 @@
 ## sentence of the help text is dependent on the format of the
 ## function's help.  All Octave core functions are correctly
 ## formatted, but the same can not be guaranteed for external packages and
-## user-supplied functions.  Therefore, the use of the "-all" argument may
-## be necessary to find related functions that are not a part of Octave.
+## user-supplied functions.  Therefore, the use of the @qcode{"-all"}
+## argument may be necessary to find related functions that are not a part of
+## Octave.
 ## @seealso{help, doc, which}
 ## @end deftypefn
 
--- a/scripts/help/print_usage.m
+++ b/scripts/help/print_usage.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -139,3 +139,4 @@
 
 ## Stop reporting function as missing tests.  No good tests possible.
 %!assert (1)
+
--- a/scripts/help/private/__additional_help_message__.m
+++ b/scripts/help/private/__additional_help_message__.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 Søren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -37,3 +37,4 @@
   endif
 
 endfunction
+
--- a/scripts/help/private/__strip_html_tags__.m
+++ b/scripts/help/private/__strip_html_tags__.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 Søren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -79,3 +79,4 @@
   ## Actually remove the elements
   text = text (keep);
 endfunction
+
--- a/scripts/help/type.m
+++ b/scripts/help/type.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2009-2012 S�ren Hauberg
+## Copyright (C) 2009-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -19,24 +19,24 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Command} {} type @var{name} @dots{}
 ## @deftypefnx {Command} {} type -q @var{name} @dots{}
-## @deftypefnx {Function File} {dfns =} type ("@var{name}", @dots{})
-## Display the definition of each @var{name} that refers to a function.
+## @deftypefnx {Function File} {text =} type ("@var{name}", @dots{})
+## Display the contents of @var{name} which may be a file, function (m-file),
+## variable, operator, or keyword.
 ##
-## Normally also displays whether each @var{name} is user-defined or built-in;
-## the @option{-q} option suppresses this behavior.
+## @code{type} normally prepends a header line describing the category
+## of @var{name} such as function or variable;  The @option{-q} option
+## suppresses this behavior.
 ##
-## If an output argument is requested nothing is displayed.  Instead, a cell
-## array of strings is returned, where each element corresponds to the
-## definition of each requested function.
+## If no output variable is used the contents are displayed on screen.
+## Otherwise, a cell array of strings is returned, where each element
+## corresponds to the contents of each requested function.
 ## @end deftypefn
 
-function retval = type (varargin)
-  ## Parse input
+function text = type (varargin)
+
   if (nargin == 0)
-    error ("type: not enough input arguments");
-  endif
-
-  if (!iscellstr (varargin))
+    print_usage ();
+  elseif (! iscellstr (varargin))
     error ("type: input arguments must be strings");
   endif
 
@@ -44,18 +44,18 @@
   idx = strcmpi (varargin, "-q") | strcmpi (varargin, "-quiet");
   if (any (idx))
     quiet = true;
-    varargin (idx) = [];
+    varargin(idx) = [];
   endif
 
   if (nargout > 0)
-    retval = cell (size (varargin));
+    text = cell (size (varargin));
   endif
 
   for n = 1:length (varargin)
-    name = varargin {n};
+    name = varargin{n};
 
     ## Find function and get its code
-    text = "";
+    txt = "";
     cmd = sprintf ("exist ('%s')", name);
     e = evalin ("caller", cmd);
     if (e == 1)
@@ -63,17 +63,20 @@
       cmd = sprintf ("disp (%s);", name);
       desc = evalin ("caller", cmd);
       if (quiet)
-        text = desc;
+        txt = desc;
       else
-        text = sprintf ("%s is a variable\n%s", name, desc);
+        txt = sprintf ("%s is a variable\n%s", name, desc);
       endif
     elseif (e == 2)
       ## m-file or ordinary file
       file = which (name);
-      if (isempty (file))
+      if (length (file) > 2)
+        ext = file(end-1:end);
+      endif
+      if (isempty (file) || ! strcmpi (ext, ".m"))
         ## 'name' is an ordinary file, and not a function name.
-        ## FIXME: Should we just print it anyway?
-        error ("type: '%s' undefined\n", name);
+        file = file_in_loadpath (name);
+        quiet = true;
       endif
 
       ## Read the file
@@ -85,28 +88,27 @@
       fclose (fid);
 
       if (quiet)
-        text = contents;
+        txt = contents;
       else
-        text = sprintf ("%s is the user-defined function defined from: %s\n\n%s",
+        txt = sprintf ("%s is the user-defined function defined from: %s\n\n%s",
                         name, file, contents);
       endif
     elseif (e == 3)
-      text = sprintf ("%s is a dynamically-linked function", name);
+      txt = sprintf ("%s is a dynamically-linked function", name);
     elseif (e == 5)
-      text = sprintf ("%s is a built-in function", name);
+      txt = sprintf ("%s is a built-in function", name);
     elseif (any (strcmp (__operators__ (), name)))
-      text = sprintf ("%s is an operator", name);
+      txt = sprintf ("%s is an operator", name);
     elseif (any (strcmp (__keywords__ (), name)))
-      text = sprintf ("%s is a keyword", name);
+      txt = sprintf ("%s is a keyword", name);
     else
       error ("type: '%s' undefined\n", name);
     endif
 
-    ## Should we return the text or print if
     if (nargout == 0)
-      disp (text);
+      disp (txt);
     else
-      retval {n} = text;
+      text{n} = txt;
     endif
   endfor
 endfunction
@@ -114,13 +116,25 @@
 
 %!test
 %! var = 1;
-%! typestr = type ("var");
-%! typestr = typestr{1}(1:17);
+%! text = type ("var");
+%! typestr = text{1}(1:17);
 %! assert (typestr, "var is a variable");
 
+%!test
+%! text = type ("ls");
+%! typestr = text{1}(1:31);
+%! assert (typestr, "ls is the user-defined function");
+
+%!test
+%! text = type ("ls", "-q");
+%! typestr = text{1}(1:21);
+%! assert (typestr, "## Copyright (C) 2006");
+
 %!assert (type ("amd"){1}, "amd is a dynamically-linked function")
 %!assert (type ("cat"){1}, "cat is a built-in function")
 %!assert (type ("+"){1}, "+ is an operator")
 %!assert (type ("end"){1}, "end is a keyword")
-%!error (type ('NO_NAME'))
+
+%!error type ()
+%!error <'__NO_NAME__' undefined> type ('__NO_NAME__')
  
--- a/scripts/image/cmpermute.m
+++ b/scripts/image/cmpermute.m
@@ -25,7 +25,7 @@
 ## When called with only two arguments, @code{cmpermute} randomly rearranges
 ## the colormap @var{map} and returns a new colormap @var{newmap}.  It also
 ## returns the indexed image @var{Y} which is the equivalent of the original
-## input image @var{X} when displayed using @var{newmap}.  
+## input image @var{X} when displayed using @var{newmap}.
 ##
 ## When called with an optional third argument the order of colors in the
 ## new colormap is defined by @var{index}.
--- a/scripts/image/cmunique.m
+++ b/scripts/image/cmunique.m
@@ -78,12 +78,12 @@
     endif
   else
     switch (size (X,3))
-      case (1)
+      case 1
         ## I case
         [newmap,i,j] = unique (X);               # calculate unique colormap
         newmap = repmat (newmap,1,3);            # get a RGB colormap
         Y = reshape (j, rows (X), columns (X));  # Y is j reshaped
-      case (3)
+      case 3
         ## RGB case
         ## build a map with all values
         map = [X(:,:,1)(:), X(:,:,2)(:), X(:,:,3)(:)];
--- a/scripts/image/colorcube.m
+++ b/scripts/image/colorcube.m
@@ -46,12 +46,12 @@
     return;
   endif
 
-  # Create colorcube of evenly spaced points with side length of n^1/3
+  ## Create colorcube of evenly spaced points with side length of n^1/3
   cubelen = fix (cbrt (n));
   reserve = n - cubelen^3; 
 
   if (reserve == 0)
-    # Steal space from blue to put the gray gradient
+    ## Steal space from blue to put the gray gradient
     [r, g, b] = meshgrid (linspace (0,1,cubelen),
                           linspace (0,1,cubelen),
                           linspace (0,1,cubelen-1));
@@ -61,16 +61,16 @@
                           linspace (0,1,cubelen));
   endif
 
-  # Create map and weed out grays
+  ## Create map and weed out grays
   map = [r(:), g(:), b(:)];
   idx = any (bsxfun (@ne, map(:, 1), map(:, 2:3)), 2);
   map = map(idx, :);
 
-  # Weed out pure colors
+  ## Weed out pure colors
   idx = sum (map == 0, 2);
   map = map(idx != 2, :);
 
-  # Put in remaining gradients of pure red, green, blue, and gray
+  ## Put in remaining gradients of pure red, green, blue, and gray
   reserve = n - rows (map) - 1;
   csteps = fix (reserve/4);
   cstepsz = 1 / csteps;
--- a/scripts/image/colormap.m
+++ b/scripts/image/colormap.m
@@ -21,10 +21,12 @@
 ## @deftypefn  {Function File} {@var{cmap} =} colormap ()
 ## @deftypefnx {Function File} {@var{cmap} =} colormap (@var{map})
 ## @deftypefnx {Function File} {@var{cmap} =} colormap ("default")
-## @deftypefnx {Function File} {@var{cmap} =} colormap ("list")
-## @deftypefnx {Function File} {@var{cmap} =} colormap ("register", "@var{name}")
-## @deftypefnx {Function File} {@var{cmap} =} colormap ("unregister", "@var{name}")
+## @deftypefnx {Function File} {@var{cmap} =} colormap ("@var{map_name}")
+## @deftypefnx {Function File} {@var{cmap} =} colormap (@var{hax}, @dots{})
 ## @deftypefnx {Command} {} colormap @var{map_name}
+## @deftypefnx {Function File} {@var{cmaps} =} colormap ("list")
+## @deftypefnx {Function File} {} colormap ("register", "@var{name}")
+## @deftypefnx {Function File} {} colormap ("unregister", "@var{name}")
 ## Query or set the current colormap.
 ##
 ## With no input arguments, @code{colormap} returns the current color map.
@@ -37,13 +39,18 @@
 ## @code{colormap ("default")} restores the default colormap (the
 ## @code{jet} map with 64 entries).  The default colormap is returned.
 ##
-## @code{colormap ("list")} returns a cell array with all of the available
-## colormaps.  The options "register" and "unregister" will add or remove
-## the colormap @var{name} from this list.
+## The map may also be specified by a string, @qcode{"@var{map_name}"}, where
+## @var{map_name} is the name of a function that returns a colormap.
+##
+## If the first argument @var{hax} is an axes handle, then the colormap for
+## the parent figure of @var{hax} is queried or set.
 ##
 ## For convenience, it is also possible to use this function with the
-## command form, where @var{map_name} must be the name of a function
-## that returns a colormap.
+## command form, @code{colormap @var{map_name}}.
+##
+## @code{colormap ("list")} returns a cell array with all of the available
+## colormaps.  The options @qcode{"register"} and @qcode{"unregister"}
+## add or remove the colormap @var{name} from this list.
 ##
 ## @seealso{jet}
 ## @end deftypefn
@@ -52,16 +59,23 @@
 ## Created: July 1994
 ## Adapted-By: jwe
 
-function cmap = colormap (map, name)
+function cmap = colormap (varargin)
+  persistent map_list = cell ();
+
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("colormap", varargin{:});
 
   if (nargin > 2)
     print_usage ();
   endif
 
-  persistent map_list = cell ();
+  if (! isempty (hax))
+    cf = ancestor (hax, "figure");
+  else
+    cf = get (0, "currentfigure");
+  endif
 
   if (nargin == 1)
-
+    map = varargin{1};
     if (ischar (map))
       if (strcmp (map, "default"))
         map = jet (64);
@@ -81,25 +95,33 @@
       if (any (map(:) < 0) || any (map(:) > 1))
         error ("colormap: all MAP values must be in the range [0,1]");
       endif
+      if (isempty (cf))
+        cf = gcf ();
+      endif
       ## Set the new color map
-      set (gcf (), "colormap", map);
+      set (cf, "colormap", map);
     endif
 
   elseif (nargin == 2)
-    if (! ischar (map) || ! any (strcmp (map, {"register", "unregister"})))
+    opt = varargin{1};
+    name = varargin{2};
+    if (! ischar (opt) || ! any (strcmp (opt, {"register", "unregister"})))
       print_usage ();
     elseif (! ischar (name))
       error ("colormap: to register/unregister a colormap, NAME must be a string");
-    elseif (strcmp (map, "register"))
+    elseif (strcmp (opt, "register"))
       map_list{end+1} = name;
-    elseif (strcmp (map, "unregister"))
+    elseif (strcmp (opt, "unregister"))
       map_list(strcmp (name, map_list)) = [];
     endif
   endif
 
   ## Return current color map.
   if (nargout > 0 || (nargout == 0 && nargin == 0))
-    cmap = get (gcf (), "colormap");
+    if (isempty (cf))
+      cf = gcf ();
+    endif
+    cmap = get (cf, "colormap");
   endif
 
 endfunction
@@ -119,7 +141,7 @@
 %! title "colormap (colorcube (64))"
 
 %!test
-%! figure ("visible", "off");
+%! hf = figure ("visible", "off");
 %! cmaptst = [0 1 0; 1 0 1; 1 1 1];
 %! cmap = colormap (cmaptst);
 %! assert (cmap, cmaptst);
@@ -131,7 +153,7 @@
 %! assert (colormap (), jet (64));
 %! colormap ("ocean");
 %! assert (colormap, ocean (64));
-%! close ();  # done with temp. figure
+%! close (hf);  # done with temp. figure
 
 %!test
 %! cmaplst = colormap ("list");
--- a/scripts/image/hsv2rgb.m
+++ b/scripts/image/hsv2rgb.m
@@ -75,8 +75,8 @@
   ##        are outside range [0, 1].  We could also simply allow those values
   ##        and re-instate this code to produce saturating semantics.
   ## Trim map to range [0, 1]
-  #hsv_map(hsv_map < 0) = 0;
-  #hsv_map(hsv_map > 1) = 1;
+  ## hsv_map(hsv_map < 0) = 0;
+  ## hsv_map(hsv_map > 1) = 1;
 
   h = hsv_map(:,1);
   s = hsv_map(:,2);
--- a/scripts/image/image.m
+++ b/scripts/image/image.m
@@ -39,7 +39,7 @@
 ## upper left.  For ordinary plots, the origin is located in the lower
 ## left.  Octave handles this inversion by plotting the data normally,
 ## and then reversing the direction of the y-axis by setting the
-## @code{ydir} property to "reverse".  This has implications whenever
+## @code{ydir} property to @qcode{"reverse"}.  This has implications whenever
 ## an image and an ordinary plot need to be overlaid.  The recommended
 ## solution is to display the image and then plot the reversed ydata
 ## using, for example, @code{flipud (ydata)}.
@@ -170,7 +170,7 @@
   set (hax, "view", [0, 90]);
 
   if (strcmp (get (hax, "nextplot"), "replace"))
-    # Always reverse y-axis for images, unless hold is on
+    ## Always reverse y-axis for images, unless hold is on
     set (hax, "ydir", "reverse");
   endif
 
--- a/scripts/image/imagesc.m
+++ b/scripts/image/imagesc.m
@@ -25,7 +25,7 @@
 ## Display a scaled version of the matrix @var{img} as a color image.  The
 ## colormap is scaled so that the entries of the matrix occupy the entire
 ## colormap.  If @code{@var{climits} = [@var{lo}, @var{hi}]} is given, then that
-## range is set to the "clim" of the current axes.
+## range is set to the @qcode{"clim"} of the current axes.
 ##
 ## The axis values corresponding to the matrix elements are specified in
 ## @var{x} and @var{y}, either as pairs giving the minimum and maximum
--- a/scripts/image/imfinfo.m
+++ b/scripts/image/imfinfo.m
@@ -33,11 +33,14 @@
 ## @item Filename
 ## The full name of the image file.
 ##
+## @item FileModDate
+## Date of last modification to the file.
+##
 ## @item FileSize
 ## Number of bytes of the image on disk
 ##
-## @item FileModDate
-## Date of last modification to the file.
+## @item Format
+## Image format (e.g., @qcode{"jpeg"}).
 ##
 ## @item Height
 ## Image height in pixels.
@@ -48,11 +51,9 @@
 ## @item BitDepth
 ## Number of bits per channel per pixel.
 ##
-## @item Format
-## Image format (e.g., @code{"jpeg"}).
-##
-## @item LongFormat
-## Long form image format description.
+## @item ColorType
+## Image type.  Value is @qcode{"grayscale"}, @qcode{"indexed"},
+## @qcode{"truecolor"}, @qcode{"CMYK"}, or @qcode{"undefined"}.
 ##
 ## @item XResolution
 ## X resolution of the image.
@@ -60,51 +61,85 @@
 ## @item YResolution
 ## Y resolution of the image.
 ##
-## @item TotalColors
-## Number of unique colors in the image.
+## @item ResolutionUnit
+## Units of image resolution.  Value is @qcode{"Inch"},
+## @qcode{"Centimeter"}, or @qcode{"undefined"}.
 ##
-## @item TileName
-## Tile name.
-##
-## @item AnimationDelay
+## @item DelayTime
 ## Time in 1/100ths of a second (0 to 65535) which must expire before displaying
 ## the next image in an animated sequence.
 ##
-## @item AnimationIterations
-## Number of iterations to loop an animation (e.g., Netscape loop extension)
-## for.
+## @item LoopCount
+## Number of iterations to loop an animation.
 ##
 ## @item ByteOrder
-## Endian option for formats that support it.  Value is @code{"little-endian"},
-## @code{"big-endian"}, or @code{"undefined"}.
+## Endian option for formats that support it.  Value is @qcode{"little-endian"},
+## @qcode{"big-endian"}, or @qcode{"undefined"}.
 ##
 ## @item Gamma
 ## Gamma level of the image.  The same color image displayed on two different
 ## workstations may look different due to differences in the display monitor.
 ##
-## @item Matte
-## @code{true} if the image has transparency.
+## @item Quality
+## JPEG/MIFF/PNG compression level.  Value is an integer in the range [0 100].
+##
+## @item DisposalMethod
+## Only valid for GIF images, control how successive frames are rendered (how
+## the preceding frame is disposed of) when creating a GIF animation.  Values
+## can be @qcode{"doNotSpecify"}, @qcode{"leaveInPlace"}, @qcode{"restoreBG"},
+## or @qcode{"restorePrevious"}.  For non-GIF files, value is an empty string.
+##
+## @item Chromaticities
+## Value is a 1x8 Matrix with the x,y chromaticity values for white, red,
+## green, and blue points, in that order.
 ##
-## @item ModulusDepth
-## Image modulus depth (minimum number of bits required to support
-## red/green/blue components without loss of accuracy).
+## @item Comment
+## Image comment.
 ##
-## @item Quality
-## JPEG/MIFF/PNG compression level.
+## @item Compression
+## Compression type.  Value can be @qcode{"none"}, @qcode{"bzip"},
+## @qcode{"fax3"}, @qcode{"fax4"}, @qcode{"jpeg"}, @qcode{"lzw"},
+## @qcode{"rle"}, @qcode{"deflate"}, @qcode{"lzma"}, @qcode{"jpeg2000"},
+## @qcode{"jbig2"}, @qcode{"jbig2"}, or @qcode{"undefined"}.
+##
+## @item Colormap
+## Colormap for each image.
+##
+## @item Orientation
+## The orientation of the image with respect to the rows and columns.  Value
+## is an integer between 1 and 8 as defined in the TIFF 6 specifications, and
+## for @sc{Matlab} compatibility.
 ##
-## @item QuantizeColors
-## Preferred number of colors in the image.
+## @item Software
+## Name and version of the software or firmware of the camera or image input
+## device used to generate the image.
 ##
-## @item ResolutionUnits
-## Units of image resolution.  Value is @code{"pixels per inch"},
-## @code{"pixels per centimeter"}, or @code{"undefined"}.
+## @item Make
+## The manufacturer of the recording equipment.  This is the manufacture of the
+## DSC, scanner, video digitizer or other equipment that generated the image.
+##
+## @item Model
+## The model name or model number of the recording equipment as mentioned
+## on the field @qcode{"Make"}.
 ##
-## @item ColorType
-## Image type.  Value is @code{"grayscale"}, @code{"indexed"},
-## @code{"truecolor"}, or @code{"undefined"}.
+## @item DateTime
+## The date and time of image creation as defined by the Exif standard, i.e,
+## it is the date and time the file was changed.
+##
+## @item ImageDescription
+## The title of the image as defined by the Exif standard.
 ##
-## @item View
-## FlashPix viewing parameters.
+## @item Artist
+## Name of the camera owner, photographer or image creator.
+##
+## @item Copyright
+## Copyright notice of the person or organization claiming rights to the image.
+##
+## @item DigitalCamera
+## A struct with information retrieved from the Exif tag.
+##
+## @item GPSInfo
+## A struct with geotagging information retrieved from the Exif tag.
 ## @end table
 ##
 ## @seealso{imread, imwrite, imshow, imformats}
@@ -122,3 +157,4 @@
   endif
   info = imageIO (@__imfinfo__, "info", varargin, varargin{:});
 endfunction
+
--- a/scripts/image/imformats.m
+++ b/scripts/image/imformats.m
@@ -34,26 +34,33 @@
 ## @item ext
 ## The name of the file format.  This may match the file extension but Octave
 ## will automatically detect the file format.
+##
 ## @item description
 ## A long description of the file format.
+##
 ## @item @nospell{isa}
 ## A function handle to confirm if a file is of the specified format.
+##
 ## @item write
 ## A function handle to write if a file is of the specified format.
+##
 ## @item read
 ## A function handle to open files the specified format.
+##
 ## @item info
 ## A function handle to obtain image information of the specified format.
+##
 ## @item alpha
 ## Logical value if format supports alpha channel (transparency or matte).
+##
 ## @item multipage
 ## Logical value if format supports multipage (multiple images per file).
 ## @end table
 ##
 ## It is possible to change the way Octave manages file formats with the options
-## @code{"add"}, @code{"remove"}, and @code{"update"}, and supplying a
+## @qcode{"add"}, @qcode{"remove"}, and @qcode{"update"}, and supplying a
 ## structure @var{format} with the required fields.  The option
-## @code{"factory"} resets the configuration to the default.
+## @qcode{"factory"} resets the configuration to the default.
 ##
 ## This can be used by Octave packages to extend the image reading capabilities
 ## Octave, through use of the PKG_ADD and PKG_DEL commands.
@@ -168,7 +175,7 @@
   ## there's no need to go and calculate it all over again if we are
   ## requested to reset back to factory.
   if (! isempty (formats))
-    return
+    return;
   endif
 
   ##      Building the formats info
@@ -253,7 +260,7 @@
   ## the minimal list of fields required in the structure. We don't
   ## require multipage because it doesn't exist in matlab
   min_fields  = {"ext", "read", "isa", "write", "info", "alpha", "description"};
-  fields_mask = cellfun (@(x) isfield (format, x), min_fields);
+  fields_mask = isfield (format, min_fields);
   if (! all (fields_mask))
     error ("imformats: structure has missing field `%s'.", min_fields(! fields_mask){1});
   endif
@@ -270,11 +277,12 @@
 function bool = isa_magick (coder, filename)
   bool = false;
   try
-    info = __imfinfo__ (filename);
+    info = __magick_ping__ (filename, 1);
     bool = strcmp (coder, info.Format);
   end_try_catch
 endfunction
 
+
 ## changing the function to read
 %!testif HAVE_MAGICK
 %! fmt = imformats ("jpg");
--- a/scripts/image/imread.m
+++ b/scripts/image/imread.m
@@ -39,12 +39,17 @@
 ## @nospell{MxNx3} matrix.  Gray-level and black-and-white images are
 ## of size @nospell{MxN}.  Multipage images will have an additional 4th
 ## dimension.
+##
 ## The bit depth of the image determines the
-## class of the output: "uint8" or "uint16" for gray
-## and color, and "logical" for black and white.
+## class of the output: @qcode{"uint8"}, @qcode{"uint16"} or @qcode{"single"}
+## for gray and color, and @qcode{"logical"} for black and white.
 ## Note that indexed images always return the indexes for a colormap,
 ## independent if @var{map} is a requested output.  To obtain the actual
-## RGB image, use @code{ind2rgb}.
+## RGB image, use @code{ind2rgb}.  When more than one indexed image is being
+## read, @var{map} is obtained from the first.  In some rare cases this
+## may be incorrect and @code{imfinfo} can be used to obtain the colormap of
+## each image.
+##
 ## See the Octave manual for more information in representing images.
 ##
 ## Some file formats, such as TIFF and GIF, are able to store multiple
@@ -57,20 +62,20 @@
 ## are supported:
 ##
 ## @table @samp
-## @item "Frames" or "Index"
+## @item @qcode{"Frames"} or @qcode{"Index"}
 ## This is an alternative method to specify @var{idx}.  When specifying it
-## in this way, its value can also be the string "all".
+## in this way, its value can also be the string @qcode{"all"}.
 ##
-## @item "Info"
-## This option exists for @sc{Matlab} compatibility and has no effect.  For
+## @item @qcode{"Info"}
+## This option exists for @sc{matlab} compatibility and has no effect.  For
 ## maximum performance while reading multiple images from a single file,
 ## use the Index option.
 ##
-## @item "PixelRegion"
+## @item @qcode{"PixelRegion"}
 ## Controls the image region that is read.  Takes as value a cell array
 ## with two arrays of 3 elements @code{@{@var{rows} @var{cols}@}}.  The
 ## elements in the array are the start, increment and end pixel to be
-## read.  If the increment value is ommited, defaults to 1.
+## read.  If the increment value is omitted, defaults to 1.
 ## @end table
 ##
 ## @seealso{imwrite, imfinfo, imformats}
@@ -83,7 +88,7 @@
 ## Author: Stefan van der Walt <stefan@sun.ac.za>
 ## Author: Andy Adler
 
-function varargout = imread (varargin)
+function [img, varargout] = imread (varargin)
   if (nargin < 1)
     print_usage ();
   elseif (! ischar (varargin{1}))
@@ -99,9 +104,10 @@
     filename{2} = varargin{2};
   endif
 
-  [varargout{1:nargout}] = imageIO (@__imread__, "read", filename, varargin{:});
+  [img, varargout{1:nargout-1}] = imageIO (@__imread__, "read", filename, varargin{:});
 endfunction
 
+
 %!testif HAVE_MAGICK
 %! vpng = [ ...
 %!  137,  80,  78,  71,  13,  10,  26,  10,   0,   0, ...
--- a/scripts/image/imshow.m
+++ b/scripts/image/imshow.m
@@ -43,7 +43,7 @@
 ## @var{value1}.  @var{string_param1} can be any of the following:
 ##
 ## @table @asis
-## @item "displayrange"
+## @item @qcode{"displayrange"}
 ## @var{value1} is the display range as described above.
 ## @end table
 ##
--- a/scripts/image/imwrite.m
+++ b/scripts/image/imwrite.m
@@ -24,10 +24,10 @@
 ## @deftypefnx {Function File} {} imwrite (@dots{}, @var{param1}, @var{val1}, @dots{})
 ## Write images in various file formats.
 ##
-## The image @var{img} can be a binary, grayscale, RGB, or multidimensional
+## The image @var{img} can be a binary, grayscale, RGB, or multi-dimensional
 ## image.  The size and class of @var{img} should be the same as what should
 ## be expected when reading it with @code{imread}: the 3rd and 4th dimensions
-## reserved for colorspace, and multiple pages respectively.  If it's an
+## reserved for color space, and multiple pages respectively.  If it's an
 ## indexed image, the colormap @var{map} must also be specified.
 ##
 ## If @var{ext} is not supplied, the file extension of @var{filename} is used
@@ -40,22 +40,29 @@
 ## are supported:
 ##
 ## @table @samp
+## @item Alpha
+## Alpha (transparency) channel for the image.  This must be a matrix with
+## same class, and number of rows and columns of @var{img}.  In case of a
+## multipage image, the size of the 4th dimension must also match and the third
+## dimension must be a singleton.  By default, image will be completely
+## opaque.
+##
 ## @item Quality
 ## Set the quality of the compression.  The value should be an
 ## integer between 0 and 100, with larger values indicating higher visual
-## quality and lower compression. Defaults to 75.
+## quality and lower compression.  Defaults to 75.
 ##
 ## @item WriteMode
 ## Some file formats, such as TIFF and GIF, are able to store multiple
 ## images in a single file.  This option specifies if @var{img} should be
 ## appended to the file (if it exists) or if a new file should be created
 ## for it (possibly overwriting an existing file).  The value should be
-## the string "Overwrite" (default), or "Append".
+## the string @qcode{"Overwrite"} (default), or @qcode{"Append"}.
 ##
 ## Despite this option, the most efficient method of writing a multipage
 ## image is to pass a 4 dimensional @var{img} to @code{imwrite}, the
 ## same matrix that could be expected when using @code{imread} with the
-## option "Index" set to "all".
+## option @qcode{"Index"} set to @qcode{"all"}.
 ##
 ## @end table
 ##
@@ -85,6 +92,7 @@
 
 endfunction
 
+
 %% Test input validation
 %!error imwrite ()                            # Wrong # of args
 %!error imwrite (1)                           # Wrong # of args
@@ -96,3 +104,14 @@
 %!error imwrite ([], "filename.jpg")          # Empty img matrix
 %!error imwrite (spones (2), "filename.jpg")  # Invalid sparse img
 
+%!testif HAVE_MAGICK
+%! imw = randi (255, 100, "uint8");
+%! filename = [tmpnam() ".png"];
+%! unwind_protect
+%!   imwrite (imw, filename);
+%!   imr = imread (filename);
+%! unwind_protect_cleanup
+%!   unlink (filename);
+%! end_unwind_protect
+%! assert (imw, imr)
+
--- a/scripts/image/ind2gray.m
+++ b/scripts/image/ind2gray.m
@@ -30,7 +30,7 @@
 ##
 ## Implementation Note: There are several ways of converting colors to
 ## grayscale intensities.  This functions uses the luminance value obtained
-## from @code{rgb2ntsc} which is @code{I = 0.299*R + 0.587*G + 0.114*B}.  
+## from @code{rgb2ntsc} which is @code{I = 0.299*R + 0.587*G + 0.114*B}.
 ## Other possibilities include the value component from @code{rgb2hsv} or
 ## using a single color channel from @code{ind2rgb}.
 ## @seealso{gray2ind, ind2rgb}
--- a/scripts/image/lines.m
+++ b/scripts/image/lines.m
@@ -20,7 +20,7 @@
 ## @deftypefn  {Function File} {@var{map} =} lines ()
 ## @deftypefnx {Function File} {@var{map} =} lines (@var{n})
 ## Create color colormap.  This colormap is composed of the list of colors
-## in the current axes "ColorOrder" property.  The default is blue,
+## in the current axes @qcode{"ColorOrder"} property.  The default is blue,
 ## green, red, cyan, pink, yellow, and gray.
 ## The argument @var{n} must be a scalar.
 ## If unspecified, the length of the current colormap, or 64, is used.
--- a/scripts/image/private/__imfinfo__.m
+++ b/scripts/image/private/__imfinfo__.m
@@ -69,3 +69,4 @@
   end_unwind_protect
 
 endfunction
+
--- a/scripts/image/private/__imread__.m
+++ b/scripts/image/private/__imread__.m
@@ -56,13 +56,16 @@
     error ("imread: cannot find %s", filename);
   endif
 
-  info = imfinfo (fn)(1);
-  ## set default for options
-  options = struct ("index",       1,
-                    "region", {{1:1:info.Height 1:1:info.Width}});
+  ## It is possible for an file with multiple pages to have very different
+  ## images on each page. Specifically, they may have different sizes. Because
+  ## of this, we need to first find out the index of the images to read so
+  ## we can set up defaults for things such as PixelRegion later on.
+  options = struct ("index", 1);  # default image index
 
   ## Index is the only option that can be defined without the parameter/value
   ## pair style. When defining it here, the string "all" is invalid though.
+  ## Also, for matlab compatibility, if index is defined both as an option here
+  ## and parameter/value pair, silently ignore the first.
   if (nargin >= offset + 1 && ! ischar (varargin{offset}))
     if (! is_valid_index_option (options.index))
       error ("imread: IDX must be a numeric vector");
@@ -72,58 +75,70 @@
   endif
 
   if (rem (numel (varargin) - offset + 1, 2) != 0)
-    error ("imread: no pair for all arguments (even number left)");
+    error ("imread: no pair for all arguments (odd number left over)");
+  endif
+
+  ## Check key/value options.
+  indexes = cellfun ("isclass", varargin, "char");
+  indexes(indexes) &= ismember (varargin(indexes), {"frames", "index"});
+  indexes = find (indexes);
+  if (indexes)
+    options.index = varargin{indexes+1};
+    if (! (is_valid_index_option (options.index)) &&
+        ! (ischar (options.index) && strcmpi (options.index, "all")))
+      error ("imread: value for %s must be a vector or the string `all'");
+    endif
   endif
 
-  for idx = offset:2:(numel (varargin) - offset + 1)
-
-    switch (tolower (varargin{idx}))
+  try
+    ## Use information from the first image to be read to set defaults.
+    info = __magick_ping__ (fn, options.index(1));
 
-      case {"frames", "index"},
-        options.index = varargin{idx+1};
-        if (! (is_valid_index_option (options.index)) &&
-            ! (ischar (options.index) && strcmpi (options.index, "all")))
-          error ("imread: value for %s must be a vector or the string `all'");
-        endif
+    ## Set default for options.
+    options.region = {1:1:info.rows 1:1:info.columns};
 
-      case "pixelregion",
-        options.region = varargin{idx+1};
-        if (! iscell (options.region) || numel (options.region) != 2)
-          error ("imread: value for %s must be a 2 element cell array",
-                 varargin{idx});
-        endif
-        for reg_idx = 1:2
-          if (numel (options.region{reg_idx}) == 3)
-            ## do nothing
-          elseif (numel (options.region{reg_idx}) == 2)
-            options.region{reg_idx}(3) = options.region{reg_idx}(2);
-            options.region{reg_idx}(2) = 1;
-          else
-            error ("imread: range for %s must be a 2 or 3 element vector",
+    for idx = offset:2:(numel (varargin) - offset + 1)
+      switch (tolower (varargin{idx}))
+
+        case "pixelregion",
+          options.region = varargin{idx+1};
+          if (! iscell (options.region) || numel (options.region) != 2)
+            error ("imread: value for %s must be a 2 element cell array",
                    varargin{idx});
           endif
-          options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
-                                    floor (options.region{reg_idx}(2)): ...
-                                    floor (options.region{reg_idx}(3));
-        endfor
-        if (options.region{1}(end) > info.Height)
-          error ("imread: end ROWS for PixelRegions option is larger than image height");
-        elseif (options.region{2}(end) > info.Width)
-          error ("imread: end COLS for PixelRegions option is larger than image width");
-        endif
+          for reg_idx = 1:2
+            if (numel (options.region{reg_idx}) == 3)
+              ## do nothing
+            elseif (numel (options.region{reg_idx}) == 2)
+              options.region{reg_idx}(3) = options.region{reg_idx}(2);
+              options.region{reg_idx}(2) = 1;
+            else
+              error ("imread: range for %s must be a 2 or 3 element vector",
+                     varargin{idx});
+            endif
+            options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
+                                      floor (options.region{reg_idx}(2)): ...
+                                      floor (options.region{reg_idx}(3));
+          endfor
+          if (options.region{1}(end) > info.rows)
+            error ("imread: end ROWS for PixelRegions option is larger than image height");
+          elseif (options.region{2}(end) > info.columns)
+            error ("imread: end COLS for PixelRegions option is larger than image width");
+          endif
 
-      case "info",
-        ## We ignore this option. This parameter exists in Matlab to
-        ## speed up the reading of multipage TIFF.  It makes no difference
-        ## for us since we're already quite efficient.
+        case "info",
+          ## We ignore this option. This parameter exists in Matlab to
+          ## speed up the reading of multipage TIFF by passing a structure
+          ## that contains information about the start on the file of each
+          ## page.  We can't control it through GraphicsMagic but at least
+          ## we allow to load multiple pages with one command.
 
-      otherwise
-        error ("imread: invalid PARAMETER `%s'", varargin{idx});
+        otherwise
+          error ("imread: invalid PARAMETER `%s'", varargin{idx});
 
-    endswitch
-  endfor
+      endswitch
+    endfor
 
-  try
     [varargout{1:nargout}] = __magick_read__ (fn, options);
 
   catch
@@ -189,3 +204,4 @@
     bool = true;
   endif
 endfunction
+
--- a/scripts/image/private/__imwrite__.m
+++ b/scripts/image/private/__imwrite__.m
@@ -30,31 +30,53 @@
 
   [filename, ext, map, param_list] = imwrite_filename (varargin{:});
 
+  if (isempty (img))
+    error ("imwrite: invalid empty image");
+  elseif (issparse (img) || issparse (map))
+    error ("imwrite: sparse images are not supported");
+  endif
+
   if (rem (numel (param_list), 2) != 0)
-    error ("imwrite: no pair for all arguments (even number left)");
+    error ("imwrite: no pair for all arguments (odd number left)");
   endif
 
   ## set default for options
-  options        = struct ("writemode", "overwrite",
-                           "quality",   75);
+  options = struct ("writemode", "overwrite",
+                    "quality",   75,
+                    "alpha",     cast ([], class (img)));
 
   for idx = 1:2:numel (param_list)
 
     switch (tolower (param_list{idx}))
 
+      case "alpha"
+        options.alpha = param_list{idx+1};
+        if (! isnumeric (options.alpha))
+          error ("imwrite: value for %s option must be a numeric matrix",
+                 param_list{idx});
+        elseif (size (options.alpha, 3) != 1)
+          error ("imwrite: 3rd dimension of matrix for %s must be singleton",
+                 param_list{idx});
+        elseif (ndims (options.alpha) > 4 ||
+                any (size (options.alpha)([1 2]) != size (img)([1 2])) ||
+                size (options.alpha, 4) != size (img, 4))
+          error ("imwrite: matrix for %s must have same dimension as image",
+                 param_list{idx});
+        endif
+
       case "writemode",
         options.writemode = param_list{idx+1};
-        if (! ischar (options.writemode) ||
-            ! any (strcmpi (options.writemode, {"append", "overwrite"})))
-          error ("imwrite: value for %s option must be \"append\" or \"overwrite\"",
+        if (! ischar (options.writemode)
+            || ! any (strcmpi (options.writemode, {"append", "overwrite"})))
+          error ('imwrite: value for %s option must be "append" or "overwrite"',
                  param_list{idx});
         endif
         options.writemode = tolower (options.writemode);
 
       case "quality",
         options.quality = param_list{idx+1};
-        if (! isnumeric (options.quality) || ! isscalar (options.quality) ||
-            options.quality < 0 || options.quality > 100)
+        if (! isnumeric (options.quality) || ! isscalar (options.quality)
+            || options.quality < 0 || options.quality > 100)
           error ("imwrite: value for %s option must be a scalar between 0 and 100",
                  param_list{idx});
         endif
@@ -66,40 +88,32 @@
     endswitch
   endfor
 
-  if (isempty (img))
-    error ("imwrite: invalid empty image");
-  elseif (issparse (img) || issparse (map))
-    error ("imwrite: sparse images not supported");
-  endif
-
   if (! isempty (map))
     if (! iscolormap (map))
       error ("imwrite: invalid MAP for indexed image");
     elseif (ndims (img) != 2 && ndims (img) != 4)
       error ("imwrite: indexed image must have 2 or 4 dimensions (found %i)", ndims (img));
     endif
-    ## FIXME: we should really be writing indexed images but that needs
-    ##        to be implemented in  __magick_write__(). So we convert
-    ##        them to RGB and write them "normally".
-    warned = false;
-    if (! warned)
-      warning ("imwrite: saving of indexed images is not yet implemented. Will save a RGB image.");
-      warned = true;
+    ## If the image is floating point, then we convert it to integer (makes
+    ## it easier in __magick_write__ since it only handles integers. Also,
+    ## if it's floating point, it has an offset of 1
+    if (isfloat (img))
+      if (rows (map) <= 256)
+        img = uint8 (img - 1);
+      else
+        img = uint16 (img - 1);
+      endif
     endif
-    img = ind2rgb (img, map);
-    map = [];
   endif
 
   if (ndims (img) > 4)
     error ("imwrite: invalid %d-dimensional image data", ndims (img));
-  elseif (all (size (img, 3) != [1 3]))
-    ## This test needs to be adjusted if one day we implement alternative
-    ## colorspaces. In the mean time, we only have grayscale and RGB images,
-    ## but CMYK means length 4 in the 3rd dimension.
-    error ("imwrite: IMG 3rd dimension must be 1 or 3");
+  elseif (all (size (img, 3) != [1 3 4]))
+    ## 1, 3, or 4 for grayscle, RGB, and CMYK respectively
+    error ("imwrite: IMG 3rd dimension must be 1, 3, or 4");
   endif
 
-  ## FIXME: do we need to convert the image class?
   __magick_write__ (filename, ext, img, map, options);
 
 endfunction
+
--- a/scripts/image/private/imageIO.m
+++ b/scripts/image/private/imageIO.m
@@ -66,3 +66,4 @@
     [varargout{1:nargout}] = fmt.(fieldname) (varargin{:});
   endif
 endfunction
+
--- a/scripts/image/private/imwrite_filename.m
+++ b/scripts/image/private/imwrite_filename.m
@@ -66,3 +66,4 @@
   options = varargin(options_idx:end);
 
 endfunction
+
--- a/scripts/image/private/ind2x.m
+++ b/scripts/image/private/ind2x.m
@@ -22,8 +22,8 @@
 function [x, map] = ind2x (caller, x, map)
 
   ## Check if X is an indexed image.
-  ## an indexed image is defined has having only 2D, and that's how matlab
-  ## behaves. But we want to support ND images, so we will allow up to 4D
+  ## an indexed image is defined has having only 2D, and that's how Matlab
+  ## behaves.  But we want to support ND images, so we will allow up to 4D
   ## and check that the 3rd is a singleton
   if (all (ndims (x) != [2 4]) || size (x, 3) != 1 || issparse (x) ||
       (isfloat (x) && ! isindex (x)) ||
@@ -51,9 +51,10 @@
 
   num_colors = rows (map);
   if (num_colors < maxidx)
-    ## Pad with the last color in the map for matlab compatibility
+    ## Pad with the last color in the map for Matlab compatibility
     pad = repmat (map(end,:), maxidx - num_colors, 1);
     map(end+1:maxidx, :) = pad;
   endif
 
 endfunction
+
--- a/scripts/image/rgb2ind.m
+++ b/scripts/image/rgb2ind.m
@@ -37,19 +37,17 @@
 ##
 ## The input image @var{rgb} must be an N-dimensional RGB image
 ## (@nospell{MxNxO}@dots{}x3 array) where M,N,O@dots{} are the image
-## dimensions, and the
-## final dimension contains the values in the red, green and blue
-## channels.  Alternatively, the red, green and blue color channels can
-## be input as separate arrays @var{R}, @var{G} and  @var{B}.
+## dimensions, and the final dimension contains the values in the red, green
+## and blue channels.  Alternatively, the red, green and blue color channels
+## can be input as separate arrays @var{R}, @var{G}, and @var{B}.
 ##
-## The input @var{map} defines the colormap to be used.  Alternatively,
-## @var{n} or @var{tol} may be used to define the maximum number of
-## colors to use in an automatically generated colormap.  @var{n} is
-## related to @var{tol} by:  @var{n} = (floor (1/@var{tol}) + 1)^3;
-## @var{tol} must be >0 and @leq{}1.
+## The input @var{map} defines the colormap to be used.  Alternatively, @var{n}
+## or @var{tol} may be used to define the maximum number of colors to use in an
+## automatically generated colormap.  @var{n} is related to @var{tol} by:
+## @var{n} = (floor (1/@var{tol}) + 1)^3; where 0 < @var{tol} @leq{} 1.
 ##
 ## @var{dither_option} is a string which enables or disables dithering:
-## 'dither' (default) or 'nodither'.
+## @qcode{"dither"} (default) or @qcode{"nodither"}.
 ##
 ## @seealso{ind2rgb, rgb2hsv, rgb2ntsc}
 ## @end deftypefn
@@ -145,7 +143,7 @@
     ## before processing it with Graphicsmagick
     if (numel (sz) > 3)
      rgb = reshape (rgb, [prod(sz(1:end-2)), sz(end-1), 3]);
-    end
+    endif
 
     ## Prepare the Graphicsmagick dithering option
     if (strcmp (dither_option, "nodither"))
@@ -167,7 +165,7 @@
   ## Conversion of rgb image to x,map
   pr = prod (sz(1:end-1));
   x = zeros (sz(1:end-1));
-  [map,~,x(:)] = unique (reshape(rgb, [pr, 3]), "rows");
+  [map,~,x(:)] = unique (reshape (rgb, [pr, 3]), "rows");
 
   ## a colormap is of class double and values between 0 and 1
   switch (class (rgb))
--- a/scripts/image/rgb2ntsc.m
+++ b/scripts/image/rgb2ntsc.m
@@ -98,9 +98,9 @@
 
 
 %% Test pure RED, GREEN, BLUE colors
-%assert (rgb2ntsc ([1 0 0]), [.299  .587  .114])
-%assert (rgb2ntsc ([0 1 0]), [.596 -.274 -.322])
-%assert (rgb2ntsc ([1 0 1]), [.211 -.523  .312])
+%!assert (rgb2ntsc ([1 0 0]), [.299  .596  .211])
+%!assert (rgb2ntsc ([0 1 0]), [.587 -.274 -.523])
+%!assert (rgb2ntsc ([0 0 1]), [.114 -.322  .312])
 
 %!test
 %! rgb_map = rand (64, 3);
--- a/scripts/image/spinmap.m
+++ b/scripts/image/spinmap.m
@@ -23,7 +23,7 @@
 ## @deftypefnx {Function File} {} spinmap ("inf")
 ## Cycle the colormap for @var{t} seconds with a color increment of @var{inc}.
 ## Both parameters are optional.  The default cycle time is 5 seconds and the
-## default increment is 2.  If the option "inf" is given then cycle
+## default increment is 2.  If the option @qcode{"inf"} is given then cycle
 ## continuously until @kbd{Control-C} is pressed.
 ##
 ## When rotating the original color 1 becomes color 2, color 2 becomes
--- a/scripts/io/beep.m
+++ b/scripts/io/beep.m
@@ -36,3 +36,4 @@
 
 
 %!error (beep (1))
+
--- a/scripts/io/dlmwrite.m
+++ b/scripts/io/dlmwrite.m
@@ -35,32 +35,32 @@
 ## The value of @var{c} specifies the number of delimiters to prepend to
 ## each line of data.
 ##
-## If the argument @code{"-append"} is given, append to the end of
+## If the argument @qcode{"-append"} is given, append to the end of
 ## @var{file}.
 ##
 ## In addition, the following keyword value pairs may appear at the end
 ## of the argument list:
 ##
 ## @table @asis
-## @item "append"
-## Either @samp{"on"} or @samp{"off"}.  See @samp{"-append"} above.
+## @item @qcode{"append"}
+## Either @qcode{"on"} or @qcode{"off"}.  See @qcode{"-append"} above.
 ##
-## @item "delimiter"
+## @item @qcode{"delimiter"}
 ## See @var{delim} above.
 ##
-## @item "newline"
+## @item @qcode{"newline"}
 ## The character(s) to use to separate each row.  Three special cases
-## exist for this option.  @samp{"unix"} is changed into "\n",
-## @samp{"pc"} is changed into "\r\n", and @samp{"mac"} is changed
-## into "\r".  Other values for this option are kept as is.
+## exist for this option.  @qcode{"unix"} is changed into @qcode{"\n"},
+## @qcode{"pc"} is changed into @qcode{"\r\n"}, and @qcode{"mac"} is changed
+## into @qcode{"\r"}.  Other values for this option are kept as is.
 ##
-## @item "roffset"
+## @item @qcode{"roffset"}
 ## See @var{r} above.
 ##
-## @item "coffset"
+## @item @qcode{"coffset"}
 ## See @var{c} above.
 ##
-## @item "precision"
+## @item @qcode{"precision"}
 ## The precision to use when writing the file.  It can either be a
 ## format string (as used by fprintf) or a number of significant digits.
 ## @end table
--- a/scripts/io/importdata.m
+++ b/scripts/io/importdata.m
@@ -22,22 +22,21 @@
 ## @deftypefnx {Function File} {@var{A} =} importdata (@var{fname}, @var{delimiter}, @var{header_rows})
 ## @deftypefnx {Function File} {[@var{A}, @var{delimiter}] =} importdata (@dots{})
 ## @deftypefnx {Function File} {[@var{A}, @var{delimiter}, @var{header_rows}] =} importdata (@dots{})
-## Importing data from file.
-##
-## Importing the contents of file @var{fname} into workspace.
+## Import data from the file @var{fname}.
 ##
 ## Input parameters:
 ##
 ## @itemize
 ## @item @var{fname}
-## The file name for the file to import.
+## The name of the file containing data.
 ## 
 ## @item @var{delimiter}
 ## The character separating columns of data.  Use @code{\t} for tab.
-## (Only valid for ascii files)
+## (Only valid for ASCII files)
 ##
 ## @item @var{header_rows}
-## Number of header rows before the data begins.  (Only valid for ascii files)
+## The number of header rows before the data begins.  (Only valid for ASCII
+## files)
 ## @end itemize
 ##
 ## Different file types are supported:
@@ -45,7 +44,7 @@
 ## @itemize
 ## @item ASCII table
 ##
-## Importing ASCII table using the specified number of header rows and
+## Import ASCII table using the specified number of header rows and
 ## the specified delimiter.
 ##
 ## @item Image file
@@ -63,79 +62,57 @@
 
 ## Author: Erik Kjellson <erikiiofph7@users.sourceforge.net>
 
-function [output, delimiter, header_rows] = importdata (varargin)
+function [output, delimiter, header_rows] = importdata (fname, delimiter = "", header_rows = -1)
 
-  ## Default values
-  fname   = "";
-  delimiter  = "";
-  header_rows = -1;
-
-  ##########
-
-  ## Check input arguments
-
-  if (nargin < 1)
+  if (nargin < 1 || nargin > 3)
     print_usage ();
   endif
 
-  fname = varargin{1};
-  ## Check that the file name really is a string
   if (! ischar (fname))
-    error ("importdata: file name needs to be a string");
-  endif
-  if ( strcmpi (fname, "-pastespecial"))
+    error ("importdata: FNAME must be a string");
+  elseif (strcmpi (fname, "-pastespecial"))
     error ("importdata: option -pastespecial not implemented");
   endif
 
   if (nargin > 1)
-    delimiter = varargin{2};
-    ## Check that the delimiter really is a string
-    if (!ischar (delimiter))
-      error("importdata: delimiter needs to be a character");
+    if (! ischar (delimiter)
+        || (length (delimiter) > 1 && ! strcmp (delimiter, '\t')))
+      error("importdata: DELIMITER must be a single character");
     endif
-    if (length (delimiter) > 1 && !strcmpi (delimiter, "\\t"))
-      error("importdata: delimiter cannot be longer than 1 character");
-    endif
-    if (strcmpi (delimiter, "\\"))
-      delimiter = "\\\\";
+    if (strcmp (delimiter, '\t'))
+      delimiter = "\t";
     endif
   endif
 
   if (nargin > 2)
-    header_rows = varargin{3};
-    if (!isnumeric (header_rows) || header_rows < 0)
-      error ("importdata: number of header rows needs to be an integer number >= 0");
+    if (! isnumeric (header_rows) || header_rows < 0
+        || header_rows != fix (header_rows))
+      error ("importdata: HEADER_ROWS must be an integer >= 0");
     endif
   endif
 
-  if (nargin > 3)
-    error ("importdata: too many input arguments");
-  endif
-
-  ##########
-
   ## Check file format
   ## Get the extension from the file name.
-  [d n fileExt v] = fileparts (fname);
-  ## Make sure file extension is in lower case.
-  fileExt = lower (fileExt);
+  [~, ~, ext, ~] = fileparts (fname);
+  ext = lower (ext);
 
-  switch (fileExt)
-    case {".au", ".snd"}
-      error ("importdata: not implemented for file format %s", fileExt);
-    case ".avi"
-      error ("importdata: not implemented for file format %s", fileExt);
-    case {".bmp", ".cur", ".gif", ".hdf", ".ico", ".jpe", ".jpeg", ".jpg", \
-          ".pbm", ".pcx", ".pgm", ".png", ".pnm", ".ppm", ".ras", \
-          ".tif", ".tiff", ".xwd"}
-      delimiter  = NaN;
+  switch (ext)
+    case {".au", ".snd", ".flac", ".ogg"}
+      error ("importdata: not implemented for file format %s", ext);
+    case {".avi", ".mj2", ".mpg", ".asf", ".asx", ".wmv", ".mp4", ".m4v", ...
+          ".mov"} 
+      error ("importdata: not implemented for file format %s", ext);
+    case {".bmp", ".cur", ".gif", ".hdf", ".ico", ".jpe", ".jpeg", ".jpg", ...
+          ".jp2", ".jpf", ".jpx", ".j2c", ".j2k", ".pbm", ".pcx", ".pgm", ...
+          ".png", ".pnm", ".ppm", ".ras", ".tif", ".tiff", ".xwd"}
+      delimiter = NaN;
       header_rows = 0;
       [output.cdata, output.colormap, output.alpha] = imread (fname);
     case ".mat"
-      delimiter  = NaN;
+      delimiter = NaN;
       header_rows = 0;
       output = load (fname);
-    case {".wk1", ".xls", ".xlsx", ".dbf", ".pxl"}
+    case {".xls", ".xlsx", ".wk1", ".dbf", ".pxl"}
       ## If there's no Excel file support simply fall back to unimplemented.m
       output = xlsread (fname);
     case {".ods", ".sxc", ".fods", ".uos", ".xml"}
@@ -147,228 +124,285 @@
         output = xlsread (fname);
       end_try_catch
     case {".wav", ".wave"}
-      delimiter  = NaN;
+      delimiter = NaN;
       header_rows = 0;
       [output.data, output.fs] = wavread (fname);
     otherwise
-      ## Assume the file is in ascii format.
-      [output, delimiter, header_rows]  = \
+      ## Assume the file is in ASCII format.
+      [output, delimiter, header_rows]  = ...
           importdata_ascii (fname, delimiter, header_rows);
   endswitch
 
   ## If there are any empty fields in the output structure, then remove them
-  if (isstruct (output) && length (output) == 1)
+  if (isstruct (output) && numel (output) == 1)
     fields = fieldnames (output);
     for i=1:length (fields)
-      if (isempty (getfield (output, fields{i})))
+      if (isempty (output.(fields{i})))
         output = rmfield (output, fields{i});
       endif
     endfor
 
     ## If only one field is left, replace the structure with the field,
-    ## i.e. output = output.onlyFieldLeft
+    ## i.e., output = output.onlyFieldLeft
 
     ## Update the list of fields
     fields = fieldnames (output);
-    if (length (fields) == 1)
-      output = getfield (output, fields{1});
+    if (numel (fields) == 1)
+      output = output.(fields{1});
     endif
   endif
-endfunction
-
-
-########################################
-
-function [output, delimiter, header_rows] = \
-      importdata_ascii (fname, delimiter, header_rows)
-
-  ## Define the fields in the output structure so that the order will be
-  ## correct.
-
-  output.data       = [];
-  output.textdata   = [];
-  output.rowheaders = [];
-  output.colheaders = [];
-
-  ## Read file into string and count the number of header rows
-  file_content = fileread (fname);
-
-  ## Split the file into rows (using \n and/or \r as delimiters between rows).
-  file_content_rows = regexp (file_content, "\n|\n\r|\r|\r\n", "split");
-
-  ## FIXME: guess delimiter, if it isn't defined
-  if (isempty (delimiter))
-    error ("importdata: Guessing delimiter is not implemented yet, you have to specify it.");
-  endif
 
-  ## FIXME: A more intelligent way to count number of header rows. This
-  ## is needed e.g. when delimiter=' ' and the header contains spaces...
+endfunction
+
+function [output, delimiter, header_rows] = importdata_ascii (fname, delimiter, num_header_rows)
 
-  ## If number of header rows is undefined, then count the number of
-  ## header rows by step through row by row and look for the delimiter.
-  ## Assume that the header can't contain any delimiter.
-  if (header_rows < 0)
-    header_rows = 0;
-    for i=1:length (file_content_rows)
-      if (isempty (regexp(file_content_rows{i}, delimiter, "once")))
-        header_rows++;
-      else
-        ## Data part has begun and therefore no more header rows can be
-        ## found
-        break;
-      endif
-    endfor
-  endif
+  ## Define fields in the output structure so that the order will be correct.
+  output.data       = [];
+  output.textdata   = {};
+  output.rowheaders = {};
+  output.colheaders = {};
 
-  ## Put the header rows in output.textdata.
-  if (header_rows > 0)
-    output.textdata   = file_content_rows (1:header_rows)';
-  endif
-
-  ## If space is the delimiter, then remove spaces in the beginning of
-  ## each data row.
-  if (strcmpi (delimiter, " "))
-    for i=(header_rows+1):length (file_content_rows)
-      ## strtrim does not only remove the leading spaces but also the
-      ## tailing spaces, but that doesn't really matter.
-      file_content_rows{i} = strtrim (file_content_rows{i});
-    endfor
+  [fid, msg] = fopen (fname, "r");
+  if (fid == -1)
+    error (msg);
   endif
 
-  ## Remove empty data rows. Go through them backwards so that you wont
-  ## get out of bounds.
-  for i=length (file_content_rows):-1:(header_rows + 1)
-    if (length (file_content_rows{i}) < 1)
-      file_content_rows = [file_content_rows(1:i-1), \
-                           file_content_rows(i+1:length(file_content_rows))];
-    endif
-  endfor
+  header_rows = 0;
+  header_cols = 0;
+    
+  ## Work through first few rows line by line until a delimiter is found.
+  while (ischar (row = fgetl (fid)))
 
-  ## Count the number of data columns. If there are different number of
-  ## columns, use the greatest value.
-  data_columns = 0;
-  delimiter_pattern = delimiter;
-  ## If space is the delimiter, then multiple spaces should count as ONE
-  ## delimiter. Also ignore leading spaces.
-  if (strcmpi (delimiter, " "))
-    delimiter_pattern = ' +';
-  endif
-  for i=(header_rows+1):length(file_content_rows)
-    data_columns = max (data_columns,
-                        length (regexp (file_content_rows{i},
-                                        delimiter_pattern, "split")));
-  endfor
+    ## If no delimiter determined yet, make a guess.
+    if (isempty (delimiter))
+      ## This pattern can be fooled, but mostly does the job just fine.
+      delim = regexp (row, '[+-\d.eE\*ij ]+([^+-\d.ij])[+-\d.ij]',
+                           'tokens', 'once');
+      if (! isempty (delim))
+        delimiter = delim{1};
+      endif
+    endif
 
-  ## FIXME: Make it behave like Matlab when importing a table where a whole
-  ## column is text only. E.g.
-  ##    abc  12  34
-  ##    def  56  78
-  ## This would give a 3x2 data matrix with the left column = nan(2,1), and 
-  ## the text would end up in textdata.
-  ## In Matlab the data matrix would only be a 2x2 matrix, see example at:
-  ## http://www.mathworks.se/help/matlab/import_export/import-numeric-data-and-header-text-from-a-text-file.html
-
-  ## Go through the data and put it in either output.data or
-  ## output.textdata depending on if it is numeric or not.
-  output.data = NaN (length (file_content_rows) - header_rows, data_columns);
-  for i=(header_rows+1):length(file_content_rows)
-    ## Only use the row if it contains anything other than white-space
-    ## characters.
-    if (any (file_content_rows{i} != " "))
-      row_data = regexp (file_content_rows{i}, delimiter_pattern, "split");
+    if (delimiter == " ")
+      row_entries = regexp (strtrim (row), ' +', 'split');
+    else
+      row_entries = ostrsplit (row, delimiter);
+    endif
+    row_data = str2double (row_entries);
+    if (all (isnan (row_data)) || header_rows < num_header_rows)
+      header_rows++;
+      output.textdata{end+1, 1} = row;
+    else
+      if (! isempty (output.textdata))
+        if (delimiter == " ")
+          output.colheaders = regexp (strtrim (output.textdata{end}),
+                                      ' +', 'split');
+        else
+          output.colheaders = ostrsplit (output.textdata{end}, delimiter);
+        endif
+      endif
+      header_cols = find (! isnan (row_data), 1) - 1;
+      ## The number of header rows and header columns is now known.
+      break;
+    endif
 
-      for j=1:length(row_data)
-        ## Try to convert the column to a number, if it works put it in
-        ## output.data, otherwise in output.textdata
-        if (!isempty (row_data{j}))
-          data_numeric = str2double (row_data{j});
-          if (!isnan (data_numeric))
-            output.data(i-header_rows, j) = data_numeric;
-          else
-            output.textdata{i,j} = row_data{j};
-          endif
-        endif
-      endfor
+  endwhile
+
+  fclose (fid);
 
-    endif
-  endfor
-
-  ## Check wether rowheaders or colheaders should be used
-  if ((header_rows == data_columns) && (size (output.textdata, 2) == 1))
-    output.rowheaders = output.textdata;
-  elseif (size (output.textdata, 2) == data_columns)
-    output.colheaders = output.textdata(end,:);
+  if (row == -1)
+    error ("importdata: Unable to determine delimiter");
+  endif
+  if (num_header_rows >= 0)
+    header_rows = num_header_rows;
   endif
 
-  ## When delimiter = "\\t" convert it to a tab, done for Matlab compatibility.
-  if (strcmp (delimiter, '\t'))
-    delimiter = "\t";
+  ## Now, let the efficient built-in routine do the bulk of the work.
+  if (delimiter == " ")
+    output.data = dlmread (fname, "", header_rows, header_cols,
+                           "emptyvalue", NA);
+  else
+    output.data = dlmread (fname, delimiter, header_rows, header_cols,
+                           "emptyvalue", NA);
+  endif
+
+  ## Go back and correct any individual values that did not convert.
+  na_idx = isna (output.data);
+  if (header_cols > 0)
+    na_idx = [(true (rows (na_idx), header_cols)), na_idx];
+  endif
+  if (any (na_idx(:)))
+
+    file_content = ostrsplit (fileread (fname), "\n");
+
+    na_rows = find (any (na_idx, 2));
+    for ridx = na_rows(:)'
+      row = file_content{ridx+header_rows};
+      if (delimiter == " ")
+        fields = regexp (strtrim (row), ' +', 'split');
+      else
+        fields = ostrsplit (row, delimiter);
+      endif
+      
+      text = fields(na_idx(ridx,:));
+      text = text(! strcmpi (text, "NA"));  #  Remove valid "NA" entries
+      if (! isempty (text))
+        output.textdata(end+1:end+numel (text), 1) = text;
+      endif
+      if (header_cols)
+        output.rowheaders(end+1, :) = fields(1:header_cols);
+      endif
+    endfor
+
+  endif
+
+  ## Final cleanup to satisfy output configuration
+  if (all (cellfun ("isempty", output.textdata)))
+    output = output.data;
+  elseif (! isempty (output.rowheaders) && ! isempty (output.colheaders))
+    output = struct ("data", {output.data}, "textdata", {output.textdata});
   endif
 
 endfunction
 
 
-########################################
-
 %!test
-%! # Comma separated values
+%! ## Comma separated values
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1,-7.2,0\n0.012,6.5,128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, ",");
+%! [a1,d1,h1] = importdata (fn, ",");
+%! [a2,d2,h2] = importdata (fn);
 %! unlink (fn);
-%! assert (a, A);
-%! assert (d, ",");
-%! assert (h, 0);
+%! assert (a1, A);
+%! assert (d1, ",");
+%! assert (h1, 0);
+%! assert (a2, A);
+%! assert (d2, ",");
+%! assert (h2, 0);
 
 %!test
-%! # Tab separated values
+%! ## Tab separated values
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a1,d1,h1] = importdata (fn, "\t");
+%! [a2,d2,h2] = importdata (fn);
+%! unlink (fn);
+%! assert (a1, A);
+%! assert (d1, "\t");
+%! assert (h1, 0);
+%! assert (a2, A);
+%! assert (d2, "\t");
+%! assert (h2, 0);
+
+%!test
+%! ## Space separated values, using multiple spaces to align in columns.
+%! A = [3.1 -7.2 0; 0.012 6.5 128];
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A');
+%! fclose (fid);
+%! [a1,d1,h1] = importdata (fn, " ");
+%! [a2,d2,h2] = importdata (fn);
+%! unlink (fn);
+%! assert (a1, A);
+%! assert (d1, " ");
+%! assert (h1, 0);
+%! assert (a2, A);
+%! assert (d2, " ");
+%! assert (h2, 0);
+
+%!test
+%! ## No separator, 1 column of data only
+%! A = [3.1;-7.2;0;0.012;6.5;128];
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fprintf (fid, "%f\n", A);
+%! fclose (fid);
+%! [a1,d1,h1] = importdata (fn, "");
+%! [a2,d2,h2] = importdata (fn);
+%! unlink (fn);
+%! assert (a1, A);
+%! assert (d1, "");
+%! assert (h1, 0);
+%! assert (a2, A);
+%! assert (d2, "");
+%! assert (h2, 0);
+
+%!test
+%! ## Header text
+%! A.data = [3.1 -7.2 0; 0.012 6.5 128];
+%! A.textdata = {"This is a header row."; ...
+%!               "this row does not contain any data, but the next one does."};
+%! A.colheaders = A.textdata (2);
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fprintf (fid, "%s\n", A.textdata{:});
+%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
+%! fclose (fid);
+%! [a,d,h] = importdata (fn, '\t');
+%! unlink (fn);
+%! assert (a, A);
+%! assert (d, "\t");
+%! assert (h, 2);
+
+%!test
+%! ## Column headers, only last row is returned in colheaders
+%! A.data = [3.1 -7.2 0; 0.012 6.5 128];
+%! A.textdata = {"Label1\tLabel2\tLabel3";
+%!               "col 1\tcol 2\tcol 3"};
+%! A.colheaders = {"col 1", "col 2", "col 3"};
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fprintf (fid, "%s\n", A.textdata{:});
+%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
+%! fclose (fid);
+%! [a,d,h] = importdata (fn, '\t');
+%! unlink (fn);
+%! assert (a, A);
+%! assert (d, "\t");
+%! assert (h, 2);
+
+%!test
+%! ## Row headers
+%! A.data = [3.1 -7.2 0; 0.012 6.5 128];
+%! A.textdata = {"row1"; "row2"};
+%! A.rowheaders = A.textdata;
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128");
+%! fclose (fid);
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
 %!test
-%! # Space separated values, using multiple spaces to align in columns.
-%! A = [3.1 -7.2 0; 0.012 6.5 128];
+%! ## Row/Column headers and Header Text
+%! A.data = [3.1 -7.2 0; 0.012 6.5 128];
+%! A.textdata = {"This is introductory header text"
+%!               "      col1 col2 col3"
+%!               "row1"
+%!               "row2"};
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
-%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(1,:));
-%! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(2,:));
+%! fprintf (fid, "%s\n", A.textdata{1:2});
+%! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, " ");
-%! unlink (fn);
-%! assert (a, A);
-%! assert (d, " ");
-%! assert (h, 0);
-
-%!test
-%! # Header
-%! A.data = [3.1 -7.2 0; 0.012 6.5 128];
-%! A.textdata = {"This is a header row."; \
-%!               "this row does not contain any data, but the next one does."};
-%! fn  = tmpnam ();
-%! fid = fopen (fn, "w");
-%! fputs (fid, [A.textdata{1} "\n"]);
-%! fputs (fid, [A.textdata{2} "\n"]);
-%! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
-%! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 2);
 
 %!test
-%! # Ignore empty rows containing only spaces
+%! ## Ignore empty rows containing only spaces
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
@@ -383,67 +417,93 @@
 %! assert (h, 0);
 
 %!test
-%! # Exponentials
+%! ## Exponentials
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "+3.1e0\t-72E-1\t0\n12e-3\t6.5\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
 %!test
-%! # Complex numbers
+%! ## Complex numbers
 %! A = [3.1 -7.2 0-3.4i; 0.012 -6.5+7.2i 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0-3.4i\n0.012\t-6.5+7.2i\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
+%! unlink (fn);
+%! assert (a, A);
+%! assert (d, "\t");
+%! assert (h, 0);
+
+%!test
+%! ## Exceptional values (Inf, NaN, NA)
+%! A = [3.1 Inf NA; -Inf NaN 128];
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fputs (fid, "3.1\tInf\tNA\n-Inf\tNaN\t128");
+%! fclose (fid);
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
 %!test
-%! # Missing values
-%! A = [3.1 NaN 0; 0.012 6.5 128];
+%! ## Missing values and Text Values
+%! A.data = [3.1 NA 0; 0.012 NA 128];
+%! A.textdata = {char(zeros(1,0))
+%!               "NO DATA"};
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
-%! fputs (fid, "3.1\t\t0\n0.012\t6.5\t128");
+%! fputs (fid, "3.1\t\t0\n0.012\tNO DATA\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
-%!test
-%! # CRLF for line breaks
+%!#test
+%! ## CRLF for line breaks
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\r\n0.012\t6.5\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
-%!test
-%! # CR for line breaks
+%!#test
+%! ## CR for line breaks
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
 %! fn  = tmpnam ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\r0.012\t6.5\t128");
 %! fclose (fid);
-%! [a,d,h] = importdata (fn, "\\t");
+%! [a,d,h] = importdata (fn, '\t');
 %! unlink (fn);
 %! assert (a, A);
 %! assert (d, "\t");
 %! assert (h, 0);
 
+%!error importdata ()
+%!error importdata (1,2,3,4)
+%!error <FNAME must be a string> importdata (1)
+%!error <option -pastespecial not implemented> importdata ("-pastespecial")
+%!error <DELIMITER must be a single character> importdata ("foo", 1)
+%!error <DELIMITER must be a single character> importdata ("foo", "ab")
+%!error <HEADER_ROWS must be an integer> importdata ("foo", " ", "1")
+%!error <HEADER_ROWS must be an integer> importdata ("foo", " ", 1.5)
+%!error <not implemented for file format .au> importdata ("foo.au")
+%!error <not implemented for file format .avi> importdata ("foo.avi")
+
--- a/scripts/io/strread.m
+++ b/scripts/io/strread.m
@@ -99,21 +99,21 @@
 ## pairs.  The following properties are recognized:
 ##
 ## @table @asis
-## @item "commentstyle"
+## @item @qcode{"commentstyle"}
 ## Parts of @var{str} are considered comments and will be skipped.
 ## @var{value} is the comment style and can be any of the following.
 ##
 ## @itemize
-## @item "shell"
+## @item @qcode{"shell"}
 ## Everything from @code{#} characters to the nearest end-of-line is skipped.
 ##
-## @item "c"
+## @item @qcode{"c"}
 ## Everything between @code{/*} and @code{*/} is skipped.
 ##
-## @item "c++"
+## @item @qcode{"c++"}
 ## Everything from @code{//} characters to the nearest end-of-line is skipped.
 ##
-## @item "matlab"
+## @item @qcode{"matlab"}
 ## Everything from @code{%} characters to the nearest end-of-line is skipped.
 ##
 ## @item user-supplied.  Two options:
@@ -122,34 +122,34 @@
 ## is skipped.
 ## @end itemize
 ##
-## @item "delimiter"
+## @item @qcode{"delimiter"}
 ## Any character in @var{value} will be used to split @var{str} into words
 ## (default value = any whitespace).
 ##
-## @item "emptyvalue":
+## @item @qcode{"emptyvalue"}:
 ## Value to return for empty numeric values in non-whitespace delimited data.
 ## The default is NaN@.  When the data type does not support NaN
 ## (int32 for example), then default is zero.
 ##
-## @item "multipledelimsasone"
+## @item @qcode{"multipledelimsasone"}
 ## Treat a series of consecutive delimiters, without whitespace in between,
 ## as a single delimiter.  Consecutive delimiter series need not be vertically
-## "aligned".
+## @qcode{"aligned"}.
 ##
-## @item "treatasempty"
+## @item @qcode{"treatasempty"}
 ## Treat single occurrences (surrounded by delimiters or whitespace) of the
 ## string(s) in @var{value} as missing values.
 ##
-## @item "returnonerror"
+## @item @qcode{"returnonerror"}
 ## If @var{value} true (1, default), ignore read errors and return normally.
 ## If false (0), return an error.
 ##
-## @item "whitespace"
+## @item @qcode{"whitespace"}
 ## Any character in @var{value} will be interpreted as whitespace and
 ## trimmed; the string defining whitespace must be enclosed in double
 ## quotes for proper processing of special characters like \t.
-## The default value for whitespace = " \b\r\n\t" (note the space).
-## Unless whitespace is set to '' (empty) AND at least one "%s" format
+## The default value for whitespace = @qcode{" \b\r\n\t"} (note the space).
+## Unless whitespace is set to '' (empty) AND at least one @qcode{"%s"} format
 ## conversion specifier is supplied, a space is always part of whitespace.
 ##
 ## @end table
@@ -159,11 +159,11 @@
 ## depends on the last character of @var{str}:
 ##
 ## @table @asis
-## @item last character = "\n"
+## @item last character = @qcode{"\n"}
 ## Data columns are padded with empty fields or Nan so that all columns
 ## have equal length 
 ##
-## @item last character is not "\n"
+## @item last character is not @qcode{"\n"}
 ## Data columns are not padded; strread returns columns of unequal length
 ##
 ## @end table
@@ -840,14 +840,14 @@
 %! assert (a, {"a b c"; "d e"; ""; "f"});
 
 %!test
-%! # Bug #33536
+%! ## Bug #33536
 %! [a, b, c] = strread ("1,,2", "%s%s%s", "delimiter", ",");
 %! assert (a{1}, "1");
 %! assert (b{1}, "");
 %! assert (c{1}, "2");
 
 %!test
-%! # Bug #33536
+%! ## Bug #33536
 %! a = strread ("[SomeText]", "[%s", "delimiter", "]");
 %! assert (a{1}, "SomeText");
 
@@ -868,7 +868,7 @@
 %! assert (d, int32 ([0; 0]));
 
 %!test
-%! # Default format (= %f)
+%! ## Default format (= %f)
 %1 [a, b, c] = strread ("0.12 0.234 0.3567");
 %1 assert (a, 0.12);
 %1 assert (b, 0.234);
@@ -879,13 +879,13 @@
 %1 assert (a, [0.41; 3.57]);
 
 %!test
-%! # TreatAsEmpty
+%! ## TreatAsEmpty
 %! [a, b, c, d] = strread ("1,2,3,NN,5,6\n", "%d%d%d%f", "delimiter", ",", "TreatAsEmpty", "NN");
 %! assert (c, int32 ([3; 0]));
 %! assert (d, [NaN; NaN]);
 
 %!test
-%! # No delimiters at all besides EOL.  Plain reading numbers & strings
+%! ## No delimiters at all besides EOL.  Plain reading numbers & strings
 %! str = "Text1Text2Text\nText398Text4Text\nText57Text";
 %! [a, b] = strread (str, "Text%dText%1sText");
 %! assert (a, int32 ([1; 398; 57]));
@@ -958,14 +958,14 @@
 %! assert (b, NaN);
 
 %!test
-%! # Bug #35999
+%! ## Bug #35999
 %! [a, b, c] = strread ("", "%f");
 %! assert (isempty (a));
 %! assert (isempty (b));
 %! assert (isempty (c));
 
-%% bug #37023
 %!test
+%! ## bug #37023
 %! [a, b] = strread (" 1. 1 \n  2 3 \n", "%f %f", "endofline", "\n");
 %! assert (a, [1; 2], 1e-15);
 %! assert (b, [1; 3], 1e-15);
@@ -994,3 +994,4 @@
 %% Illegal format specifiers
 %!test
 %!error <unknown format specifier> strread ("1.0", "%z")
+
--- a/scripts/io/textread.m
+++ b/scripts/io/textread.m
@@ -32,13 +32,13 @@
 ## supports two more:
 ##
 ## @itemize
-## @item "headerlines":
+## @item @qcode{"headerlines"}:
 ## The first @var{value} number of lines of @var{filename} are skipped.
 ##
-## @item "endofline":
-## Specify a single character or "\r\n".  If no value is given, it will be
-## inferred from the file.  If set to "" (empty string) EOLs are ignored as
-## delimiters.
+## @item @qcode{"endofline"}:
+## Specify a single character or @qcode{"\r\n"}.  If no value is given, it
+## will be inferred from the file.  If set to "" (empty string) EOLs are
+## ignored as delimiters.
 ## @end itemize
 ##
 ## The optional input @var{n} specifies the number of data lines to read; in
@@ -73,7 +73,7 @@
   if (nlines < 1)
     printf ("textread: N = 0, no data read\n");
     varargout = cell (1, nargout);
-    return
+    return;
   endif
 
   ## Read file
@@ -219,6 +219,7 @@
 
 endfunction
 
+
 %!test
 %! f = tmpnam ();
 %! d = rand (5, 3);
@@ -315,3 +316,4 @@
 %!error <missing or illegal value for> textread (file_in_loadpath ("textread.m"), "", "headerlines")
 %!error <missing or illegal value for> textread (file_in_loadpath ("textread.m"), "", "headerlines", 'hh')
 %!error <character value required for> textread (file_in_loadpath ("textread.m"), "%s", "endofline", true)
+
--- a/scripts/io/textscan.m
+++ b/scripts/io/textscan.m
@@ -34,20 +34,21 @@
 ## supports a few more:
 ##
 ## @itemize
-## @item "collectoutput":
+## @item @qcode{"collectoutput"}:
 ## A value of 1 or true instructs textscan to concatenate consecutive columns
 ## of the same class in the output cell array.  A value of 0 or false (default)
 ## leaves output in distinct columns.
 ##
-## @item "endofline":
-## Specify "\r", "\n" or "\r\n" (for CR, LF, or CRLF).  If no value is given,
-## it will be inferred from the file.  If set to "" (empty string) EOLs are
-## ignored as delimiters and added to whitespace.
+## @item @qcode{"endofline"}:
+## Specify @qcode{"\r"}, @qcode{"\n"} or @qcode{"\r\n"} (for CR, LF, or
+## CRLF).  If no value is given, it will be inferred from the file.  If set
+## to "" (empty string) EOLs are ignored as delimiters and added to
+## whitespace.
 ##
-## @item "headerlines":
+## @item @qcode{"headerlines"}:
 ## The first @var{value} number of lines of @var{fid} are skipped.
 ##
-## @item "returnonerror":
+## @item @qcode{"returnonerror"}:
 ## If set to numerical 1 or true (default), return normally when read errors
 ## have been encountered.  If set to 0 or false, return an error and no data.
 ## As the string or file is read by columns rather than by rows, and because
@@ -79,8 +80,8 @@
 
 function [C, position] = textscan (fid, format = "%f", varargin)
 
-  BUFLENGTH = 4096;               ## Read buffer
-  emptfmt = 0;                    ## Signals deliberately empty format string
+  BUFLENGTH = 4096;               # Read buffer
+  emptfmt = 0;                    # Signals deliberately empty format string
 
   ## Check input
   if (nargin < 1)
@@ -112,8 +113,7 @@
   endif
   if (nlines < 1)
     printf ("textscan: N = 0, no data read\n");
-    return
-  endif
+    return;  endif
 
   if (! any (strcmpi (args, "emptyvalue")))
     ## Matlab returns NaNs for missing values
@@ -276,7 +276,7 @@
         data_size = nblks * BUFLENGTH + count;
       else
         ## Compute data size to read incl complete EOL
-        data_size = (nblks * BUFLENGTH) + eoi(end + min (nlines, n_eoi) - n_eoi) \
+        data_size = (nblks * BUFLENGTH) + eoi(end + min (nlines, n_eoi) - n_eoi) ...
                     + l_eol_char - 1;
       endif
       fseek (fid, st_pos, "bof");
@@ -439,7 +439,7 @@
 %! assert (int8 (c{:}{:}), int8 ([ 76,  49,  10,  76,  50 ]));
 
 %!test
-%! # No delimiters at all besides EOL.  Skip fields, even empty fields
+%! ## No delimiters at all besides EOL.  Skip fields, even empty fields
 %! str = "Text1Text2Text\nTextText4Text\nText57Text";
 %! c = textscan (str, "Text%*dText%dText");
 %! assert (c{1}, int32 ([2; 4; 0]));
@@ -660,3 +660,4 @@
 %! fclose (fid);
 %! unlink (f);
 %! assert (msg1, lasterr);
+
--- a/scripts/java/javaclasspath.m
+++ b/scripts/java/javaclasspath.m
@@ -42,13 +42,13 @@
 ## If called with a single input parameter @var{what}:
 ##
 ## @table @asis
-## @item "-dynamic"
+## @item @qcode{"-dynamic"}
 ## Return the dynamic classpath.
 ##
-## @item "-static"
+## @item @qcode{"-static"}
 ## Return the static classpath.
 ##
-## @item "-all"
+## @item @qcode{"-all"}
 ## Return both the static and dynamic classpath in a single cellstr.
 ## @end table
 ## @seealso{javaaddpath, javarmpath}
--- a/scripts/java/usejava.m
+++ b/scripts/java/usejava.m
@@ -24,25 +24,25 @@
 ## Possible features are:
 ##
 ## @table @asis
-## @item "awt"
+## @item @qcode{"awt"}
 ## Abstract Window Toolkit for GUIs.
 ##
-## @item "desktop"
+## @item @qcode{"desktop"}
 ## Interactive desktop is running.
 ##
-## @item "jvm"
+## @item @qcode{"jvm"}
 ## Java Virtual Machine.
 ##
-## @item "swing"
+## @item @qcode{"swing"}
 ## Swing components for lightweight GUIs.
 ## @end table
 ##
 ## @code{usejava} determines if specific Java features are available in an
 ## Octave session.  This function is provided for scripts which may alter
-## their behavior based on the availability of Java.  The feature "desktop"
-## always returns @code{false} as Octave has no Java-based desktop.  Other
-## features may be available if Octave was compiled with the Java Interface
-## and Java is installed.
+## their behavior based on the availability of Java.  The feature
+## @qcode{"desktop"} always returns @code{false} as Octave has no Java-based
+## desktop.  Other features may be available if Octave was compiled with the
+## Java Interface and Java is installed.
 ## @end deftypefn
 
 ## Author: Rik Wehbring
--- a/scripts/linear-algebra/cond.m
+++ b/scripts/linear-algebra/cond.m
@@ -37,7 +37,7 @@
 ## The condition number of a matrix quantifies the sensitivity of the matrix
 ## inversion operation when small changes are made to matrix elements.  Ideally
 ## the condition number will be close to 1.  When the number is large this
-## indicates small changes (such as underflow or roundoff error) will produce
+## indicates small changes (such as underflow or round-off error) will produce
 ## large changes in the resulting output.  In such cases the solution results
 ## from numerical computing are not likely to be accurate.
 ## @seealso{condest, rcond, norm, svd}
--- a/scripts/linear-algebra/expm.m
+++ b/scripts/linear-algebra/expm.m
@@ -83,10 +83,10 @@
 
   if (isscalar (A))
     r = exp (A);
-    return
+    return;
   elseif (strfind (typeinfo (A), "diagonal matrix"))
     r = diag (exp (diag (A)));
-    return
+    return;
   endif
 
   n = rows (A);
--- a/scripts/linear-algebra/krylov.m
+++ b/scripts/linear-algebra/krylov.m
@@ -28,8 +28,8 @@
 ## Using Householder reflections to guard against loss of orthogonality.
 ##
 ## If @var{V} is a vector, then @var{h} contains the Hessenberg matrix
-## such that @nospell{@xcode{a*u == u*h+rk*ek'}}, in which @code{rk =
-## a*u(:,k)-u*h(:,k)}, and @nospell{@xcode{ek'}} is the vector
+## such that @nospell{@tcode{a*u == u*h+rk*ek'}}, in which @code{rk =
+## a*u(:,k)-u*h(:,k)}, and @nospell{@tcode{ek'}} is the vector
 ## @code{[0, 0, @dots{}, 1]} of length @code{k}.  Otherwise, @var{h} is
 ## meaningless.
 ##
@@ -244,3 +244,4 @@
   b1 = a;
 
 endfunction
+
--- a/scripts/linear-algebra/subspace.m
+++ b/scripts/linear-algebra/subspace.m
@@ -59,3 +59,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/bug_report.m
+++ b/scripts/miscellaneous/bug_report.m
@@ -47,3 +47,4 @@
 
 ## Mark file as being tested.  No real test needed for this function.
 %!assert (1)
+
--- a/scripts/miscellaneous/bunzip2.m
+++ b/scripts/miscellaneous/bunzip2.m
@@ -40,3 +40,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/bzip2.m
+++ b/scripts/miscellaneous/bzip2.m
@@ -21,10 +21,10 @@
 ## @deftypefn  {Function File} {@var{entries} =} bzip2 (@var{files})
 ## @deftypefnx {Function File} {@var{entries} =} bzip2 (@var{files}, @var{outdir})
 ## Compress the list of files specified in @var{files}.
-## Each file is compressed separately and a new file with a ".bz2" extension
-## is created.  The original files are not modified.  Existing compressed files
-## are silently overwritten.  If @var{outdir} is defined the compressed
-## files are placed in this directory.
+## Each file is compressed separately and a new file with a @file{".bz2"}
+## extension is created.  The original files are not modified.  Existing
+## compressed files are silently overwritten.  If @var{outdir} is defined the
+## compressed files are placed in this directory.
 ## @seealso{bunzip2, gzip, zip, tar}
 ## @end deftypefn
 
@@ -44,7 +44,7 @@
 
 
 %!xtest
-%! # test for correct cleanup of temporary files
+%! ## test for correct cleanup of temporary files
 %! unwind_protect
 %!   filename = tmpnam;
 %!   dummy    = 1;
--- a/scripts/miscellaneous/cast.m
+++ b/scripts/miscellaneous/cast.m
@@ -43,3 +43,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/compare_versions.m
+++ b/scripts/miscellaneous/compare_versions.m
@@ -22,51 +22,51 @@
 ##
 ## This function assumes that versions @var{v1} and @var{v2} are
 ## arbitrarily long strings made of numeric and period characters
-## possibly followed by an arbitrary string (e.g., "1.2.3", "0.3",
-## "0.1.2+", or "1.2.3.4-test1").
+## possibly followed by an arbitrary string (e.g., @qcode{"1.2.3"},
+## @qcode{"0.3"}, @qcode{"0.1.2+"}, or @qcode{"1.2.3.4-test1"}).
 ##
 ## The version is first split into numeric and character portions
-## and then the parts are padded to be the same length (i.e., "1.1" would be
-## padded to be "1.1.0" when being compared with "1.1.1", and
-## separately, the character parts of the strings are padded with
-## nulls).
+## and then the parts are padded to be the same length (i.e., @qcode{"1.1"}
+## would be padded to be @qcode{"1.1.0"} when being compared with
+## @qcode{"1.1.1"}, and separately, the character parts of the strings are
+## padded with nulls).
 ##
 ## The operator can be any logical operator from the set
 ##
 ## @itemize @bullet
 ## @item
-## "=="
+## @qcode{"=="}
 ## equal
 ##
 ## @item
-## "<"
+## @qcode{"<"}
 ## less than
 ##
 ## @item
-## "<="
+## @qcode{"<="}
 ## less than or equal to
 ##
 ## @item
-## ">"
+## @qcode{">"}
 ## greater than
 ##
 ## @item
-## ">="
+## @qcode{">="}
 ## greater than or equal to
 ##
 ## @item
-## "!="
+## @qcode{"!="}
 ## not equal
 ##
 ## @item
-## "~="
+## @qcode{"~="}
 ## not equal
 ## @end itemize
 ##
-## Note that version "1.1-test2" will compare as greater than
-## "1.1-test10".  Also, since the numeric part is compared first, "a"
-## compares less than "1a" because the second string starts with a
-## numeric part even though @code{double ("a")} is greater than
+## Note that version @qcode{"1.1-test2"} will compare as greater than
+## @qcode{"1.1-test10"}.  Also, since the numeric part is compared first,
+## @qcode{"a"} compares less than @qcode{"1a"} because the second string
+## starts with a numeric part even though @code{double ("a")} is greater than
 ## @code{double ("1").}
 ## @end deftypefn
 
--- a/scripts/miscellaneous/computer.m
+++ b/scripts/miscellaneous/computer.m
@@ -38,10 +38,10 @@
 ## of elements for an array.
 ##
 ## If three output arguments are requested, also return the byte order
-## of the current system as a character (@code{"B"} for big-endian or
-## @code{"L"} for little-endian).
+## of the current system as a character (@qcode{"B"} for big-endian or
+## @qcode{"L"} for little-endian).
 ##
-## If the argument @code{"arch"} is specified, return a string
+## If the argument @qcode{"arch"} is specified, return a string
 ## indicating the architecture of the computer on which Octave is
 ## running.
 ## @end deftypefn
--- a/scripts/miscellaneous/copyfile.m
+++ b/scripts/miscellaneous/copyfile.m
@@ -19,26 +19,33 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2})
 ## @deftypefnx {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2}, 'f')
-## Copy the file @var{f1} to the new name @var{f2}.  The name @var{f1}
-## may contain globbing patterns.  If @var{f1} expands to multiple file
-## names, @var{f2} must be a directory.  If the force flag 'f' is given then
-## existing destination files will be overwritten without prompting.
+## Copy the file @var{f1} to the destination @var{f2}.
+##
+## The name @var{f1} may contain globbing patterns.  If @var{f1} expands to
+## multiple file names, @var{f2} must be a directory.
+## when the force flag @qcode{'f'} is given any existing files will be
+## overwritten without prompting.
 ##
-## If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
-## character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
-## system-dependent error message, and @var{msgid} contains a unique
-## message identifier.
-## @seealso{movefile}
+## If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty
+## character strings ("").  Otherwise, @var{status} is 0, @var{msg} contains a
+## system-dependent error message, and @var{msgid} contains a unique message
+## identifier.  Note that the status code is exacly opposite that of the
+## @code{system} command.
+## @seealso{movefile, rename, unlink, delete, glob}
 ## @end deftypefn
 
 function [status, msg, msgid] = copyfile (f1, f2, force)
 
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
   max_cmd_line = 1024;
   status = true;
   msg = "";
   msgid = "";
 
-  ## FIXME -- maybe use the same method as in ls to allow users control
+  ## FIXME: maybe use the same method as in ls to allow users control
   ## over the command that is executed.
 
   if (ispc () && ! isunix ()
@@ -51,80 +58,77 @@
     cmd_force_flag = "-f";
   endif
 
-  if (nargin == 2 || nargin == 3)
-    ## Input type check.
-    if (! (ischar (f1) || iscellstr (f1)))
-      error ("copyfile: first argument must be a character string or a cell array of character strings");
-    endif
+  ## Input type check.
+  if (! (ischar (f1) || iscellstr (f1)))
+    error ("copyfile: F1 must be a character string or a cell array of character strings");
+  endif
 
-    if (! ischar (f2))
-      error ("copyfile: second argument must be a character string");
-    endif
+  if (! ischar (f2))
+    error ("copyfile: F2 must be a character string");
+  endif
 
-    if (nargin == 3 && strcmp (force, "f"))
-      cmd = [cmd " " cmd_force_flag];
-    endif
+  if (nargin == 3 && strcmp (force, "f"))
+    cmd = [cmd " " cmd_force_flag];
+  endif
 
-    ## If f1 isn't a cellstr convert it to one.
-    if (ischar (f1))
-      f1 = cellstr (f1);
-    endif
-
-    ## If f1 has more than 1 element f2 must be a directory
-    isdir = (exist (f2, "dir") != 0);
-    if (length (f1) > 1 && ! isdir)
-      error ("copyfile: when copying multiple files, second argument must be a directory");
-    endif
+  ## If f1 isn't a cellstr convert it to one.
+  if (ischar (f1))
+    f1 = cellstr (f1);
+  endif
 
-    ## Protect the file name(s).
-    f1 = glob (f1);
-    if (isempty (f1))
-      error ("copyfile: no files to move");
-    endif
-    p1 = sprintf ("\"%s\" ", f1{:});
-    p2 = tilde_expand (f2);
+  ## If f1 has more than 1 element f2 must be a directory
+  isdir = (exist (f2, "dir") != 0);
+  if (length (f1) > 1 && ! isdir)
+    error ("copyfile: when copying multiple files, F2 must be a directory");
+  endif
 
-    if (isdir && length (p1) > max_cmd_line)
-      l2 = length (p2) + length (cmd) + 6;
-      while (! isempty (f1))
-        p1 = sprintf ("\"%s\" ", f1{1});
+  ## Protect the file name(s).
+  f1 = glob (f1);
+  if (isempty (f1))
+    error ("copyfile: no files to move");
+  endif
+  p1 = sprintf ('"%s" ', f1{:});
+  p2 = tilde_expand (f2);
+
+  if (isdir && length (p1) > max_cmd_line)
+    l2 = length (p2) + length (cmd) + 6;
+    while (! isempty (f1))
+      p1 = sprintf ('"%s" ', f1{1});
+      f1(1) = [];
+      while (! isempty (f1)
+             && (length (p1) + length (f1{1}) + l2 < max_cmd_line))
+        p1 = sprintf ('%s"%s" ', p1, f1{1});
         f1(1) = [];
-        while (!isempty (f1) && (length (p1) + length (f1{1}) + l2 <
-                                 max_cmd_line))
-          p1 = sprintf ("%s\"%s\" ", p1, f1{1});
-          f1(1) = [];
-        endwhile
+      endwhile
 
-        if (ispc () && ! isunix ()
-            && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
-          p1 = strrep (p1, "\\", "/");
-          p2 = strrep (p2, "\\", "/");
-        endif
-
-        ## Copy the files.
-        [err, msg] = system (sprintf ("%s %s\"%s\"", cmd, p1, p2));
-        if (err < 0)
-          status = false;
-          msgid = "copyfile";
-          break;
-        endif
-      endwhile
-    else
       if (ispc () && ! isunix ()
           && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
-        p1 = strrep (p1, "\\", "/");
-        p2 = strrep (p2, "\\", "/");
+        p1 = strrep (p1, '\', '/');
+        p2 = strrep (p2, '\', '/');
       endif
 
       ## Copy the files.
-      [err, msg] = system (sprintf ("%s %s\"%s\"", cmd, p1, p2));
-      if (err < 0)
+      [err, msg] = system (sprintf ('%s %s"%s"', cmd, p1, p2));
+      if (err != 0)
         status = false;
         msgid = "copyfile";
+        break;
       endif
+    endwhile
+  else
+    if (ispc () && ! isunix ()
+        && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
+      p1 = strrep (p1, '\', '/');
+      p2 = strrep (p2, '\', '/');
     endif
-  else
-    print_usage ();
+
+    ## Copy the files.
+    [err, msg] = system (sprintf ('%s %s"%s"', cmd, p1, p2));
+    if (err != 0)
+      status = false;
+      msgid = "copyfile";
+    endif
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/debug.m
+++ b/scripts/miscellaneous/debug.m
@@ -79,15 +79,16 @@
 ##
 ## @noindent
 ## When Octave encounters a breakpoint, or other reason to enter debug
-## mode, the prompt changes to @code{"debug>"}.  The workspace of the function
+## mode, the prompt changes to @qcode{"debug>"}.  The workspace of the function
 ## where the breakpoint was encountered becomes available and any Octave
 ## command that is valid in that workspace context may be executed.
 ##
 ## @seealso{dbstop, dbclear, dbstatus, dbwhere, dbtype, dbcont, dbquit,
-##          dbstack, dbup, dbdown, keyboard, debug_on_error, debug_on_warning,
-##          debug_on_interrupt, isdebugmode}
+## dbstack, dbup, dbdown, keyboard, debug_on_error, debug_on_warning,
+## debug_on_interrupt, isdebugmode}
 ## @end deftypefn
 
 function debug ()
   help ("debug");
 endfunction
+
new file mode 100644
--- /dev/null
+++ b/scripts/miscellaneous/desktop.m
@@ -0,0 +1,50 @@
+## Copyright (C) 2013 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} @var{used} = desktop ("-inuse")
+## Return true if the desktop (GUI) is currently in use.
+## @seealso{isguirunning}
+## @end deftypefn
+
+function retval = desktop (arg)
+
+  if (nargin == 0)
+    if (isguirunning ())
+      return;  # desktop() is a NOP when GUI running
+    else
+      print_usage ();
+    endif
+  elseif (nargin > 1)
+    error ('desktop: only one argument, "-inuse", is allowed');
+  endif
+  
+  switch (tolower (arg))
+    case "-inuse"
+      retval = isguirunning ();
+    otherwise
+      print_usage ();
+  endswitch
+
+endfunction
+
+
+## Test input validation
+%!error <only one argument, "-inuse", is allowed> desktop (1,2)
+%!error desktop ("-invalid_option")
+
--- a/scripts/miscellaneous/dir.m
+++ b/scripts/miscellaneous/dir.m
@@ -17,40 +17,46 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} dir (@var{directory})
+## @deftypefn  {Function File} {} dir
+## @deftypefnx {Function File} {} dir (@var{directory})
 ## @deftypefnx {Function File} {[@var{list}] =} dir (@var{directory})
-## Display file listing for directory @var{directory}.  If a return
-## value is requested, return a structure array with the fields
+## Display file listing for directory @var{directory}.
+##
+## If @var{directory} is not specified then list the present working directory.
+##
+## If a return value is requested, return a structure array with the fields
 ##
-## @example
-## @group
-## name
-## bytes
-## date
-## isdir
-## statinfo
-## @end group
-## @end example
+## @table @asis
+## @item name
+## File or directory name. 
+## @item date
+## Timestamp of file modification (string value).
+## @item bytes
+## File size in bytes.
+## @item isdir
+## True if name is a directory. 
+## @item datenum
+## Timestamp of file modification as serial date number (double).
+## @item statinfo
+## Information structure returned from @code{stat}.
+## @end table
 ##
-## @noindent
-## where @code{statinfo} is the structure returned from @code{stat}.
-##
-## If @var{directory} is not a directory, return information about the
-## named @var{filename}.  @var{directory} may be a list of directories
-## specified either by name or with wildcard characters (like * and ?)
-## which will be expanded with glob.
+## If @var{directory} is a filename, rather than a directory, then return
+## information about the named file.  @var{directory} may be a list of
+## directories specified either by name or with wildcard characters (like *
+## and ?) which will be expanded with @code{glob}.
 ##
 ## Note that for symbolic links, @code{dir} returns information about
-## the file that the symbolic link points to instead of the link itself.
+## the file that the symbolic link points to rather than the link itself.
 ## However, if the link points to a nonexistent file, @code{dir} returns
 ## information about the link.
-## @seealso{ls, stat, lstat, readdir, glob, filesep}
+## @seealso{ls, readdir, glob, what, stat}
 ## @end deftypefn
 
 ## Author: jwe
 
-## FIXME -- this is quite slow for large directories, so perhaps
-## it should be converted to C++.
+## FIXME: This is quite slow for large directories, so perhaps
+##        it should be converted to C++.
 
 function retval = dir (directory)
 
@@ -140,3 +146,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/dos.m
+++ b/scripts/miscellaneous/dos.m
@@ -24,7 +24,7 @@
 ## Execute a system command if running under a Windows-like operating
 ## system, otherwise do nothing.  Return the exit status of the program
 ## in @var{status} and any output from the command in @var{text}.
-## When called with no output argument, or the "-echo" argument is
+## When called with no output argument, or the @qcode{"-echo"} argument is
 ## given, then @var{text} is also sent to standard output.
 ## @seealso{unix, system, isunix, ispc}
 ## @end deftypefn
--- a/scripts/miscellaneous/dump_prefs.m
+++ b/scripts/miscellaneous/dump_prefs.m
@@ -96,3 +96,4 @@
   endfor
 
 endfunction
+
--- a/scripts/miscellaneous/edit.m
+++ b/scripts/miscellaneous/edit.m
@@ -80,14 +80,15 @@
 ## @item @code{[EDITOR, " %s"]}
 ## Use the editor which Octave uses for @code{edit_history}.
 ##
-## @item "xedit %s &"
+## @item @nospell{"xedit %s &"}
 ## pop up simple X11 editor in a separate window
 ##
-## @item "gnudoit -q \"(find-file \\\"%s\\\")\""
+## @item @nospell{"gnudoit -q \"(find-file \\\"%s\\\")\""}
 ## Send it to current Emacs; must have @code{(gnuserv-start)} in @file{.emacs}.
 ## @end table
 ##
-## See also field 'mode', which controls how the editor is run by Octave.
+## See also field @qcode{"mode"}, which controls how the editor is run by
+## Octave.
 ##
 ## On Cygwin, you will need to convert the Cygwin path to a Windows
 ## path if you are using a native Windows editor.  For example:
@@ -133,8 +134,9 @@
 ## @item mode
 ## This value determines whether the editor should be started in async mode
 ## (editor is started in the background and Octave continues) or sync mode
-## (Octave waits until the editor exits).  Set it to "sync" to start the editor
-## in sync mode.  The default is "async" (@pxref{XREFsystem,,system}).
+## (Octave waits until the editor exits).  Set it to @qcode{"sync"} to start
+## the editor in sync mode.  The default is @qcode{"async"}
+## (@pxref{XREFsystem,,system}).
 ##
 ## @item editinplace
 ## Determines whether files should be edited in place, without regard to
@@ -159,7 +161,7 @@
                                 "MODE", "async",
                                 "EDITINPLACE", false);
   ## Make sure the stateval variables survive "clear functions".
-  #mlock;
+  mlock;
 
   if (nargin == 1)
     ## User has supplied one arg, this can be a single file name
@@ -182,54 +184,54 @@
     statevar = varargin{1};
     stateval = varargin{2};
     switch (toupper (statevar))
-    case "EDITOR"
-      FUNCTION.EDITOR = stateval;
-      return;
-    case "HOME"
-      if (! isempty (stateval) && stateval(1) == "~")
-        stateval = [ default_home, stateval(2:end) ];
-      endif
-      FUNCTION.HOME = stateval;
-      return;
-    case "AUTHOR"
-      FUNCTION.AUTHOR = stateval;
-      return;
-    case "EMAIL"
-      FUNCTION.EMAIL = stateval;
-      return;
-    case "LICENSE"
-      FUNCTION.LICENSE = stateval;
-      return;
-    case "MODE"
-      if (strcmp (stateval, "sync") || strcmp (stateval, "async"))
-        FUNCTION.MODE = stateval;
-      else
-        error ('edit: expected "edit MODE sync|async"');
-      endif
-      return
-    case "EDITINPLACE"
-      if (ischar (stateval))
-        if (strcmpi (stateval, "true"))
-          stateval = true;
-        elseif (strcmpi (stateval, "false"))
-          stateval = false;
+      case "EDITOR"
+        FUNCTION.EDITOR = stateval;
+        return;
+      case "HOME"
+        if (! isempty (stateval) && stateval(1) == "~")
+          stateval = [ default_home, stateval(2:end) ];
+        endif
+        FUNCTION.HOME = stateval;
+        return;
+      case "AUTHOR"
+        FUNCTION.AUTHOR = stateval;
+        return;
+      case "EMAIL"
+        FUNCTION.EMAIL = stateval;
+        return;
+      case "LICENSE"
+        FUNCTION.LICENSE = stateval;
+        return;
+      case "MODE"
+        if (strcmp (stateval, "sync") || strcmp (stateval, "async"))
+          FUNCTION.MODE = stateval;
         else
-          stateval = eval (stateval);
+          error ('edit: expected "edit MODE sync|async"');
+        endif
+        return;
+      case "EDITINPLACE"
+        if (ischar (stateval))
+          if (strcmpi (stateval, "true"))
+            stateval = true;
+          elseif (strcmpi (stateval, "false"))
+            stateval = false;
+          else
+            stateval = eval (stateval);
+          endif
         endif
-      endif
-      FUNCTION.EDITINPLACE = stateval;
-      return
-    case "GET"
-      if (isfield (FUNCTION, toupper (stateval)))
-        ret = FUNCTION.(toupper (stateval));
-      else
-        ret = FUNCTION;
-      endif
-      return
-    otherwise
-      ## If none of the states match, assume both inputs are
-      ## actually both file names to be opened
-      editfilelist = varargin;
+        FUNCTION.EDITINPLACE = stateval;
+        return;
+      case "GET"
+        if (isfield (FUNCTION, toupper (stateval)))
+          ret = FUNCTION.(toupper (stateval));
+        else
+          ret = FUNCTION;
+        endif
+        return;
+      otherwise
+        ## If none of the states match, assume both inputs are
+        ## actually both file names to be opened
+        editfilelist = varargin;
     endswitch
   elseif (nargin > 2)
     if (iscellstr (varargin))
@@ -373,7 +375,7 @@
         host = getenv ("COMPUTERNAME");
       endif
       if (isempty (host))
-        [status, host] = system ("uname -n");
+        [~, host] = system ("uname -n");
         ## trim newline from end of hostname
         if (! isempty (host))
           host = host(1:end-1);
@@ -468,11 +470,11 @@
         else
           code = " ";
         endif
-        body = ["#include <octave/oct.h>\n\n",               \
-                "DEFUN_DLD(" name ", args, nargout, \"\\\n", \
-                name, "\\n\\\n\")\n{\n",                     \
-                "  octave_value_list retval;\n",             \
-                "  int nargin = args.length ();\n\n",        \
+        body = ["#include <octave/oct.h>\n\n",               ...
+                "DEFUN_DLD(" name ", args, nargout, \"\\\n", ...
+                name, "\\n\\\n\")\n{\n",                     ...
+                "  octave_value_list retval;\n",             ...
+                "  int nargin = args.length ();\n\n",        ...
                 code, "\n  return retval;\n}\n"];
 
         text = [comment, body];
@@ -484,15 +486,15 @@
           body = ["function [retval] = " name " ()\n\nendfunction\n"];
         endif
         if (isempty (head))
-          comment = ["## -*- texinfo -*- \n## @deftypefn {Function File} " \
-                     "{@var{retval} =} " name " (@var{x}, @var{y})\n##\n"  \
-                     "## @seealso{}\n## @end deftypefn\n\n"                \
+          comment = ["## -*- texinfo -*- \n## @deftypefn {Function File} " ...
+                     "{@var{retval} =} " name " (@var{x}, @var{y})\n##\n"  ...
+                     "## @seealso{}\n## @end deftypefn\n\n"                ...
                      "## " strrep(tail, "\n", "\n## ") "\n\n"];
         else
-          comment = ["## " strrep(head,"\n","\n## ") "\n\n"                \
-                     "## -*- texinfo -*- \n## @deftypefn {Function File} " \
-                     "{@var{retval} =} " name " (@var{x} @var{y})\n##\n"   \
-                     "## @seealso{}\n## @end deftypefn\n\n"                \
+          comment = ["## " strrep(head,"\n","\n## ") "\n\n"                ...
+                     "## -*- texinfo -*- \n## @deftypefn {Function File} " ...
+                     "{@var{retval} =} " name " (@var{x} @var{y})\n##\n"   ...
+                     "## @seealso{}\n## @end deftypefn\n\n"                ...
                      "## " strrep(tail, "\n", "\n## ") "\n\n"];
         endif
         text = [comment, body];
--- a/scripts/miscellaneous/error_ids.m
+++ b/scripts/miscellaneous/error_ids.m
@@ -44,6 +44,7 @@
 ## exist but Octave is unable to find it in the search path.
 ##
 ## @end table
+##
 
 
 function error_ids ()
@@ -53,3 +54,4 @@
 
 ## Remove from test statistics.  No real tests possible
 %!assert (1)
+
--- a/scripts/miscellaneous/fileattrib.m
+++ b/scripts/miscellaneous/fileattrib.m
@@ -39,19 +39,19 @@
 ## @item directory
 ## True if @var{file} is a directory.
 ##
-## @item UserRead
+## @item  UserRead
 ## @itemx GroupRead
 ## @itemx OtherRead
 ## True if the user (group; other users) has read permission for
 ## @var{file}.
 ##
-## @item UserWrite
+## @item  UserWrite
 ## @itemx GroupWrite
 ## @itemx OtherWrite
 ## True if the user (group; other users) has write permission for
 ## @var{file}.
 ##
-## @item UserExecute
+## @item  UserExecute
 ## @itemx GroupExecute
 ## @itemx OtherExecute
 ## True if the user (group; other users) has execute permission for
@@ -143,3 +143,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/fileparts.m
+++ b/scripts/miscellaneous/fileparts.m
@@ -25,38 +25,38 @@
 
 function [directory, name, extension, version] = fileparts (filename)
 
-  if (nargin == 1)
-    if (ischar (filename))
-      ds = strchr (filename, filesep ("all"), 1, "last");
-      if (isempty (ds))
-        ds = 0;
-      endif
-      es = rindex (filename, ".");
-      ## These can be the same if they are both 0 (no dir or ext).
-      if (es <= ds)
-        es = length (filename)+1;
-      endif
-      if (ds == 0)
-        directory = "";
-      elseif (ds == 1)
-        directory = filename(1);
-      else
-        directory = filename(1:ds-1);
-      endif
-      name = filename(ds+1:es-1);
-      if (es > 0 && es <= length (filename))
-        extension = filename(es:end);
-      else
-        extension = "";
-      endif
-      version = "";
-    else
-      error ("fileparts: expecting FILENAME argument to be a string");
-    endif
-  else
+  if (nargin != 1)
     print_usage ();
   endif
 
+  if (! ischar (filename) || rows (filename) > 1)
+    error ("fileparts: FILENAME must be a single string");
+  endif
+
+  ds = strchr (filename, filesep ("all"), 1, "last");
+  if (isempty (ds))
+    ds = 0;
+  endif
+  es = rindex (filename, ".");
+  ## These can be the same if they are both 0 (no dir or ext).
+  if (es <= ds)
+    es = length (filename)+1;
+  endif
+  if (ds == 0)
+    directory = "";
+  elseif (ds == 1)
+    directory = filename(1);
+  else
+    directory = filename(1:ds-1);
+  endif
+  name = filename(ds+1:es-1);
+  if (es > 0 && es <= length (filename))
+    extension = filename(es:end);
+  else
+    extension = "";
+  endif
+  version = "";
+
 endfunction
 
 
@@ -96,3 +96,9 @@
 %! [d, n, e] = fileparts (".ext");
 %! assert (strcmp (d, "") && strcmp (n, char (zeros (1, 0))) && strcmp (e, ".ext"));
 
+%% Test input validation
+%!error fileparts ()
+%!error fileparts (1,2)
+%!error <FILENAME must be a single string> fileparts (1)
+%!error <FILENAME must be a single string> fileparts (["a"; "b"])
+
--- a/scripts/miscellaneous/gunzip.m
+++ b/scripts/miscellaneous/gunzip.m
@@ -41,3 +41,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/gzip.m
+++ b/scripts/miscellaneous/gzip.m
@@ -20,10 +20,10 @@
 ## @deftypefn  {Function File} {@var{entries} =} gzip (@var{files})
 ## @deftypefnx {Function File} {@var{entries} =} gzip (@var{files}, @var{outdir})
 ## Compress the list of files and/or directories specified in @var{files}.
-## Each file is compressed separately and a new file with a ".gz" extension
-## is created.  The original files are not modified.  Existing compressed
-## files are silently overwritten.  If @var{outdir} is defined the compressed
-## files are placed in this directory.
+## Each file is compressed separately and a new file with a @file{".gz"}
+## extension is created.  The original files are not modified.  Existing
+## compressed files are silently overwritten.  If @var{outdir} is defined the
+## compressed files are placed in this directory.
 ## @seealso{gunzip, bzip2, zip, tar}
 ## @end deftypefn
 
@@ -42,7 +42,7 @@
 
 
 %!xtest
-%! # test gzip together with gunzip
+%! ## test gzip together with gunzip
 %! unwind_protect
 %!   filename = tmpnam;
 %!   dummy    = 1;
--- a/scripts/miscellaneous/isdeployed.m
+++ b/scripts/miscellaneous/isdeployed.m
@@ -30,3 +30,4 @@
 
 
 %!assert (isdeployed (), false)
+
--- a/scripts/miscellaneous/ismac.m
+++ b/scripts/miscellaneous/ismac.m
@@ -36,3 +36,4 @@
 %!assert (islogical (ismac ()))
 
 %!error ismac (1)
+
--- a/scripts/miscellaneous/license.m
+++ b/scripts/miscellaneous/license.m
@@ -46,11 +46,11 @@
 ## @var{toggle}, which may be one of:
 ##
 ## @table @asis
-## @item "enable"
+## @item @qcode{"enable"}
 ## Future tests for the specified license of @var{feature} are conducted
 ## as usual.
 ##
-## @item "disable"
+## @item @qcode{"disable"}
 ## Future tests for the specified license of @var{feature} return 0.
 ## @end table
 ##
--- a/scripts/miscellaneous/ls.m
+++ b/scripts/miscellaneous/ls.m
@@ -32,7 +32,7 @@
 ## The @code{dir} and @code{ls} commands are implemented by calling your
 ## system's directory listing command, so the available options may vary
 ## from system to system.
-## @seealso{dir, stat, readdir, glob, filesep, ls_command}
+## @seealso{dir, readdir, glob, what, stat, filesep, ls_command}
 ## @end deftypefn
 
 ## Author: jwe
--- a/scripts/miscellaneous/mex.m
+++ b/scripts/miscellaneous/mex.m
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} mex [options] file @dots{}
+## @deftypefn {Command} {} mex [options] file @dots{}
 ## Compile source code written in C, C++, or Fortran, to a MEX file.
 ## This is equivalent to @code{mkoctfile --mex [options] file}.
 ## @seealso{mkoctfile}
@@ -27,3 +27,4 @@
   args = {"--mex", varargin{:}};
   mkoctfile (args{:});
 endfunction
+
--- a/scripts/miscellaneous/mexext.m
+++ b/scripts/miscellaneous/mexext.m
@@ -28,3 +28,4 @@
 
 
 %!assert (mexext (), "mex")
+
--- a/scripts/miscellaneous/mkoctfile.m
+++ b/scripts/miscellaneous/mkoctfile.m
@@ -46,7 +46,7 @@
 ## @item -L DIR
 ## Add the library directory DIR to the link command.
 ##
-## @item -M
+## @item  -M
 ## @itemx --depend
 ## Generate dependency files (.d) for C and C++ source files.
 ##
@@ -67,13 +67,13 @@
 ## @item -g
 ## Enable debugging options for compilers.
 ##
-## @item -o FILE
+## @item  -o FILE
 ## @itemx --output FILE
 ## Output file name.  Default extension is .oct
 ## (or .mex if @samp{--mex} is specified) unless linking
 ## a stand-alone executable.
 ##
-## @item -p VAR
+## @item  -p VAR
 ## @itemx --print VAR
 ## Print the configuration variable VAR@.  Recognized variables are:
 ##
@@ -87,18 +87,18 @@
 ##    CFLAGS                    LD_CXX
 ##    CPICFLAG                  LD_STATIC_FLAG
 ##    CPPFLAGS                  LFLAGS
-##    CXX                       LIBOCTAVE       
-##    CXXFLAGS                  LIBOCTINTERP    
-##    CXXPICFLAG                LIBS            
-##    DEPEND_EXTRA_SED_PATTERN  OCTAVE_LIBS     
+##    CXX                       LIBOCTAVE
+##    CXXFLAGS                  LIBOCTINTERP
+##    CXXPICFLAG                LIBS
+##    DEPEND_EXTRA_SED_PATTERN  OCTAVE_LIBS
 ##    DEPEND_FLAGS              OCTAVE_LINK_DEPS
-##    DL_LD                     OCT_LINK_DEPS   
-##    DL_LDFLAGS                RDYNAMIC_FLAG   
-##    EXEEXT                    READLINE_LIBS   
-##    F77                       SED             
-##    F77_INTEGER_8_FLAG        XTRA_CFLAGS     
-##    FFLAGS                    XTRA_CXXFLAGS   
-##    FFTW3_LDFLAGS             
+##    DL_LD                     OCT_LINK_DEPS
+##    DL_LDFLAGS                RDYNAMIC_FLAG
+##    EXEEXT                    READLINE_LIBS
+##    F77                       SED
+##    F77_INTEGER_8_FLAG        XTRA_CFLAGS
+##    FFLAGS                    XTRA_CXXFLAGS
+##    FFTW3_LDFLAGS
 ##    FFTW3_LIBS
 ##    FFTW3F_LDFLAGS
 ##
@@ -111,11 +111,11 @@
 ## Assume we are creating a MEX file.  Set the default output extension
 ## to ".mex".
 ##
-## @item -s
+## @item  -s
 ## @itemx --strip
 ## Strip the output file.
 ##
-## @item -v
+## @item  -v
 ## @itemx --verbose
 ## Echo commands as they are executed.
 ##
@@ -167,3 +167,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/module.mk
+++ b/scripts/miscellaneous/module.mk
@@ -18,6 +18,7 @@
   miscellaneous/copyfile.m \
   miscellaneous/debug.m \
   miscellaneous/delete.m \
+  miscellaneous/desktop.m \
   miscellaneous/dir.m \
   miscellaneous/dos.m \
   miscellaneous/dump_prefs.m \
--- a/scripts/miscellaneous/movefile.m
+++ b/scripts/miscellaneous/movefile.m
@@ -17,28 +17,39 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@var{f1}, @var{f2})
-## @deftypefnx {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@var{f1}, @var{f2}, 'f')
-## Move the file @var{f1} to the new name @var{f2}.  The name @var{f1}
-## may contain globbing patterns.  If @var{f1} expands to multiple file
-## names, @var{f2} must be a directory.  If the force flag 'f' is given
-## then any existing files will be overwritten without prompting.
+## @deftypefn  {Function File} {} movefile (@var{f1})
+## @deftypefnx {Function File} {} movefile (@var{f1}, @var{f2})
+## @deftypefnx {Function File} {} movefile (@var{f1}, @var{f2}, 'f')
+## @deftypefnx {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@dots{})
+## Move the file @var{f1} to the destination @var{f2}.
 ##
-## If successful, @var{status} is 1, with @var{msg} and @var{msgid} empty
-## character strings.  Otherwise, @var{status} is 0, @var{msg} contains a
-## system-dependent error message, and @var{msgid} contains a unique
-## message identifier.
-## @seealso{rename, copyfile}
+## The name @var{f1} may contain globbing patterns.  If @var{f1} expands to
+## multiple file names, @var{f2} must be a directory.  If no destination
+## @var{f2} is specified then the destination is the present working directory.
+## If @var{f2} is a file name then @var{f1} is renamed to @var{f2}.
+## When the force flag @qcode{'f'} is given any existing files will be
+## overwritten without prompting.
+##
+## If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty
+## character strings ("").  Otherwise, @var{status} is 0, @var{msg} contains a
+## system-dependent error message, and @var{msgid} contains a unique message
+## identifier.  Note that the status code is exacly opposite that of the
+## @code{system} command.
+## @seealso{rename, copyfile, unlink, delete, glob}
 ## @end deftypefn
 
 function [status, msg, msgid] = movefile (f1, f2, force)
 
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
   max_cmd_line = 1024;
   status = true;
   msg = "";
   msgid = "";
 
-  ## FIXME -- maybe use the same method as in ls to allow users control
+  ## FIXME: maybe use the same method as in ls to allow users control
   ## over the command that is executed.
 
   if (ispc () && ! isunix ()
@@ -51,78 +62,78 @@
     cmd_force_flag = "-f";
   endif
 
-  if (nargin == 2 || nargin == 3)
-    ## Input type check.
-    if (! (ischar (f1) || iscellstr (f1)))
-      error ("movefile: first argument must be a character string or a cell array of character strings");
-    endif
-
-    if (! ischar (f2))
-      error ("movefile: second argument must be a character string");
-    endif
+  ## Input type check.
+  if (! (ischar (f1) || iscellstr (f1)))
+    error ("movefile: F1 must be a character string or a cell array of character strings");
+  endif
 
-    if (nargin == 3 && strcmp (force, "f"))
-      cmd = [cmd " " cmd_force_flag];
-    endif
+  if (nargin == 1)
+    f2 = pwd ();
+  elseif (! ischar (f2))
+    error ("movefile: F2 must be a character string");
+  endif
 
-    ## If f1 isn't a cellstr convert it to one.
-    if (ischar (f1))
-      f1 = cellstr (f1);
-    endif
+  if (nargin == 3 && strcmp (force, "f"))
+    cmd = [cmd " " cmd_force_flag];
+  endif
 
-    ## If f1 has more than 1 element f2 must be a directory
-    isdir = (exist (f2, "dir") != 0);
-    if (length (f1) > 1 && ! isdir)
-      error ("movefile: when moving multiple files, second argument must be a directory");
-    endif
+  ## If f1 isn't a cellstr convert it to one.
+  if (ischar (f1))
+    f1 = cellstr (f1);
+  endif
 
-    ## Protect the file name(s).
-    f1 = glob (f1);
-    if (isempty (f1))
-      error ("movefile: no files to move");
-    endif
-    p1 = sprintf ("\"%s\" ", f1{:});
-    p2 = tilde_expand (f2);
+  ## If f1 has more than 1 element f2 must be a directory
+  isdir = (exist (f2, "dir") != 0);
+  if (length (f1) > 1 && ! isdir)
+    error ("movefile: when moving multiple files, F2 must be a directory");
+  endif
 
-    if (isdir && length (p1) > max_cmd_line)
-      l2 = length (p2) + length (cmd) + 6;
-      while (! isempty (f1))
-        p1 = sprintf ("\"%s\" ", f1{1});
+  ## Protect the file name(s).
+  f1 = glob (f1);
+  if (isempty (f1))
+    error ("movefile: no files to move");
+  endif
+  p1 = sprintf ('"%s" ', f1{:});
+  p2 = tilde_expand (f2);
+
+  if (isdir && length (p1) > max_cmd_line)
+    l2 = length (p2) + length (cmd) + 6;
+    while (! isempty (f1))
+      p1 = sprintf ('"%s" ', f1{1});
+      f1(1) = [];
+      while (! isempty (f1)
+             && (length (p1) + length (f1{1}) + l2 < max_cmd_line))
+        p1 = sprintf ('%s"%s" ', p1, f1{1});
         f1(1) = [];
-        while (!isempty (f1) && (length (p1) + length (f1{1}) + l2 <
-                                 max_cmd_line))
-          p1 = sprintf ("%s\"%s\" ", p1, f1{1});
-          f1(1) = [];
-        endwhile
+      endwhile
 
-        if (ispc () && ! isunix ()
-            && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
-          p1 = strrep (p1, "\\", "/");
-          p2 = strrep (p2, "\\", "/");
-        endif
-
-        ## Move the file(s).
-        [err, msg] = system (sprintf ("%s %s \"%s\"", cmd, p1, p2));
-        if (err < 0)
-          status = false;
-          msgid = "movefile";
-        endif
-      endwhile
-    else
       if (ispc () && ! isunix ()
           && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
-        p1 = strrep (p1, "\\", "/");
-        p2 = strrep (p2, "\\", "/");
+        p1 = strrep (p1, '\', '/');
+        p2 = strrep (p2, '\', '/');
       endif
 
       ## Move the file(s).
-      [err, msg] = system (sprintf ("%s %s \"%s\"", cmd, p1, p2));
-      if (err < 0)
+      [err, msg] = system (sprintf ('%s %s "%s"', cmd, p1, p2));
+      if (err != 0)
         status = false;
         msgid = "movefile";
       endif
-    endif
+    endwhile
   else
-    print_usage ();
+    if (ispc () && ! isunix ()
+        && ! isempty (file_in_path (getenv ("PATH"), "cp.exe")))
+      p1 = strrep (p1, '\', '/');
+      p2 = strrep (p2, '\', '/');
+    endif
+
+    ## Move the file(s).
+    [err, msg] = system (sprintf ('%s %s "%s"', cmd, p1, p2));
+    if (err != 0)
+      status = false;
+      msgid = "movefile";
+    endif
   endif
+
 endfunction
+
--- a/scripts/miscellaneous/namelengthmax.m
+++ b/scripts/miscellaneous/namelengthmax.m
@@ -32,3 +32,4 @@
 
 
 %!assert (namelengthmax (), 63)
+
--- a/scripts/miscellaneous/news.m
+++ b/scripts/miscellaneous/news.m
@@ -40,3 +40,4 @@
 %!error news (1, 2)
 %!error <news: PACKAGE must be a string> news (1)
 %!error <news: package .* is not installed> news ("__NOT_A_VALID_PKG_NAME__")
+
--- a/scripts/miscellaneous/pack.m
+++ b/scripts/miscellaneous/pack.m
@@ -27,3 +27,4 @@
 function pack ()
 
 endfunction
+
--- a/scripts/miscellaneous/parseparams.m
+++ b/scripts/miscellaneous/parseparams.m
@@ -40,8 +40,8 @@
 ## @end group
 ## @end example
 ##
-## The parseparams function may be used to separate "regular"
-## arguments and additional arguments given as property/value pairs of
+## The parseparams function may be used to separate regular numeric
+## arguments from additional arguments given as property/value pairs of
 ## the @var{varargin} cell array.
 ##
 ## In the second form of the call, available options are specified directly
--- a/scripts/miscellaneous/perl.m
+++ b/scripts/miscellaneous/perl.m
@@ -48,3 +48,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/private/__xzip__.m
+++ b/scripts/miscellaneous/private/__xzip__.m
@@ -33,14 +33,6 @@
 function entries = __xzip__ (commandname, extension,
                              commandtemplate, files, outdir)
 
-  if (nargin != 4 && nargin != 5)
-    print_usage ();
-  endif
-
-  if (! ischar (extension) || length (extension) == 0)
-    error ("__xzip__: EXTENSION must be a string with finite length");
-  endif
-
   if (nargin == 5 && ! exist (outdir, "dir"))
     error ("__xzip__: OUTDIR output directory does not exist");
   endif
@@ -116,6 +108,7 @@
   f(idx) = files(idx);
 endfunction
 
+
 ## FIXME -- reinstate these tests if we invent a way to test private
 ## functions directly.
 ##
@@ -137,3 +130,4 @@
 ## %!    delete (filename);
 ## %!    rmdir (dirname);
 ## %!  end_unwind_protect
+
--- a/scripts/miscellaneous/private/display_info_file.m
+++ b/scripts/miscellaneous/private/display_info_file.m
@@ -21,10 +21,6 @@
 
 function display_info_file (func, package, file)
 
-  if (nargin != 3)
-    print_usage ();
-  endif
-
   if (! ischar (package))
     error ("%s: PACKAGE must be a string", func);
   endif
@@ -57,3 +53,4 @@
   fclose (fid);
 
 endfunction
+
--- a/scripts/miscellaneous/python.m
+++ b/scripts/miscellaneous/python.m
@@ -47,3 +47,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/rmappdata.m
+++ b/scripts/miscellaneous/rmappdata.m
@@ -45,6 +45,7 @@
 
 endfunction
 
+
 %!test
 %! setappdata (0, "hello", "world");
 %! rmappdata (0, "hello");
--- a/scripts/miscellaneous/run.m
+++ b/scripts/miscellaneous/run.m
@@ -59,3 +59,4 @@
     endif
   endif
 endfunction
+
--- a/scripts/miscellaneous/tar.m
+++ b/scripts/miscellaneous/tar.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2005-2012 Søren Hauberg
+## Copyright (C) 2005-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -30,7 +30,7 @@
 ## @seealso{untar, bzip2, gzip, zip}
 ## @end deftypefn
 
-## Author: Søren Hauberg <hauberg@gmail.com>
+## Author: Søren Hauberg <hauberg@gmail.com>
 
 function entries = tar (tarfile, files, root = ".")
 
@@ -64,3 +64,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/tempname.m
+++ b/scripts/miscellaneous/tempname.m
@@ -33,3 +33,4 @@
 
 %% No tests needed for alias.
 %!assert (1)
+
--- a/scripts/miscellaneous/unix.m
+++ b/scripts/miscellaneous/unix.m
@@ -24,7 +24,7 @@
 ## Execute a system command if running under a Unix-like operating
 ## system, otherwise do nothing.  Return the exit status of the program
 ## in @var{status} and any output from the command in @var{text}.
-## When called with no output argument, or the "-echo" argument is
+## When called with no output argument, or the @qcode{"-echo"} argument is
 ## given, then @var{text} is also sent to standard output.
 ## @seealso{dos, system, isunix, ispc}
 ## @end deftypefn
--- a/scripts/miscellaneous/untar.m
+++ b/scripts/miscellaneous/untar.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2005-2012 Søren Hauberg
+## Copyright (C) 2005-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -24,7 +24,7 @@
 ## @seealso{tar, unpack, bunzip2, gunzip, unzip}
 ## @end deftypefn
 
-## Author: Søren Hauberg <hauberg@gmail.com>
+## Author: Søren Hauberg <hauberg@gmail.com>
 ## Adapted-By: jwe, Bill Denney
 
 function varargout = untar (tarfile, dir = ".")
@@ -41,3 +41,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/unzip.m
+++ b/scripts/miscellaneous/unzip.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2005-2012 Søren Hauberg
+## Copyright (C) 2005-2012 Søren Hauberg
 ##
 ## This file is part of Octave.
 ##
@@ -24,7 +24,7 @@
 ## @seealso{zip, unpack, bunzip2, gunzip, untar}
 ## @end deftypefn
 
-## Author: Søren Hauberg <hauberg@gmail.com>
+## Author: Søren Hauberg <hauberg@gmail.com>
 ## Adapted-By: jwe, Bill Denney
 
 function varargout = unzip (zipfile, dir = ".")
@@ -41,3 +41,4 @@
   endif
 
 endfunction
+
--- a/scripts/miscellaneous/warning_ids.m
+++ b/scripts/miscellaneous/warning_ids.m
@@ -333,6 +333,8 @@
 ## expression.
 ## By default, the @code{Octave:variable-switch-label} warning is disabled.
 ## @end table
+##
+
 
 function warning_ids ()
   help ("warning_ids");
--- a/scripts/miscellaneous/what.m
+++ b/scripts/miscellaneous/what.m
@@ -63,13 +63,13 @@
       [dummy, f, e] = fileparts (n);
       if (strcmp (e, ".m"))
         w.m{end+1} = n;
-      elseif (strcmp (e, mexext ()))
-        w.mex{end+1} = n;
       elseif (strcmp (e, ".oct"))
         w.oct{end+1} = n;
+      elseif (strcmp (e, mexext ()))
+        w.mex{end+1} = n;
       elseif (strcmp (e, ".mat"))
         w.mat{end+1} = n;
-      elseif(strcmp (n(1), "@"))
+      elseif (strcmp (n(1), "@"))
         w.classes{end+1} = n;
       endif
     endif
@@ -108,3 +108,4 @@
     endfor
   endif
 endfunction
+
--- a/scripts/miscellaneous/zip.m
+++ b/scripts/miscellaneous/zip.m
@@ -66,3 +66,4 @@
   endif
 
 endfunction
+
--- a/scripts/mkdoc.pl
+++ b/scripts/mkdoc.pl
@@ -52,7 +52,7 @@
   @help_txt = gethelp ($fcn, $full_fname);
   next MFILE if ($help_txt[0] eq "");
 
-  print "$fcn\n";
+  print "\x{1d}$fcn\n";
   print "\@c $fcn scripts/$m_fname\n";
 
   foreach $_ (@help_txt)
deleted file mode 100755
--- a/scripts/mkinstalldirs
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@gnu.org>
-# Created: 1993-05-16
-# Last modified: Wed Jan 25 09:35:21 1995
-# Public domain
-
-errstatus=0
-
-dirmode=0755
-
-for file in ${1+"$@"} ; do 
-   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
-   shift
-
-   pathcomp=
-   for d in ${1+"$@"} ; do
-     pathcomp="$pathcomp$d"
-     case "$pathcomp" in
-       -* ) pathcomp=./$pathcomp ;;
-     esac
-
-     if test ! -d "$pathcomp"; then
-        echo "mkdir $pathcomp" 1>&2
-        mkdir "$pathcomp" || errstatus=$?
-        echo "chmod $dirmode $pathcomp" 1>&2
-        chmod $dirmode "$pathcomp" || errstatus=$?
-     fi
-
-     pathcomp="$pathcomp/"
-   done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here
--- a/scripts/optimization/__all_opts__.m
+++ b/scripts/optimization/__all_opts__.m
@@ -49,7 +49,7 @@
         fn = fieldnames (opts).';
         names = [names, fn];
       catch
-        # throw the error as a warning.
+        ## throw the error as a warning.
         warning (lasterr ());
       end_try_catch
     endfor
--- a/scripts/optimization/fminbnd.m
+++ b/scripts/optimization/fminbnd.m
@@ -25,8 +25,9 @@
 ## @var{fun} should be a function handle or name.  @var{a}, @var{b} specify a
 ## starting interval.  @var{options} is a structure specifying additional
 ## options.  Currently, @code{fminbnd} recognizes these options:
-## "FunValCheck", "OutputFcn", "TolX", "MaxIter", "MaxFunEvals".  For a
-## description of these options, see @ref{XREFoptimset,,optimset}.
+## @qcode{"FunValCheck"}, @qcode{"OutputFcn"}, @qcode{"TolX"},
+## @qcode{"MaxIter"}, @qcode{"MaxFunEvals"}.  For a description of these
+## options, see @ref{XREFoptimset,,optimset}.
 ##
 ## On exit, the function returns @var{x}, the approximate minimum point
 ## and @var{fval}, the function value thereof.
@@ -268,7 +269,7 @@
       printf ("         - increase MaxIter option.\n");
       printf ("         Current function value: %.6f\n", opt.fx);
     case -1
-      "FIXME"; ## FIXME: what's the message MATLAB prints for this case?
+      "FIXME"; # FIXME: what's the message MATLAB prints for this case?
     otherwise
       error ("internal error - fminbnd() is bug, sorry!");
   endswitch
--- a/scripts/optimization/fminsearch.m
+++ b/scripts/optimization/fminsearch.m
@@ -30,8 +30,9 @@
 ##
 ## Options for the search are provided in the parameter @var{options} using 
 ## the function @code{optimset}.  Currently, @code{fminsearch} accepts the
-## options: "TolX", "MaxFunEvals", "MaxIter", "Display".  For a description of
-## these options, see @code{optimset}.
+## options: @qcode{"TolX"}, @qcode{"MaxFunEvals"}, @qcode{"MaxIter"},
+## @qcode{"Display"}.  For a description of these options, see
+## @code{optimset}.
 ##
 ## On exit, the function returns @var{x}, the minimum point,
 ## and @var{fval}, the function value thereof.
--- a/scripts/optimization/fminunc.m
+++ b/scripts/optimization/fminunc.m
@@ -33,17 +33,17 @@
 ## in all calls to @var{fcn}, but otherwise is treated as a column vector.
 ## @var{options} is a structure specifying additional options.
 ## Currently, @code{fminunc} recognizes these options:
-## @code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
-## @code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"},
-## @code{"GradObj"}, @code{"FinDiffType"},
-## @code{"TypicalX"}, @code{"AutoScaling"}.
+## @qcode{"FunValCheck"}, @qcode{"OutputFcn"}, @qcode{"TolX"},
+## @qcode{"TolFun"}, @qcode{"MaxIter"}, @qcode{"MaxFunEvals"},
+## @qcode{"GradObj"}, @qcode{"FinDiffType"},
+## @qcode{"TypicalX"}, @qcode{"AutoScaling"}.
 ##
-## If @code{"GradObj"} is @code{"on"}, it specifies that @var{fcn},
+## If @qcode{"GradObj"} is @qcode{"on"}, it specifies that @var{fcn},
 ## called with 2 output arguments, also returns the Jacobian matrix
-## of right-hand sides at the requested point.  @code{"TolX"} specifies
+## of right-hand sides at the requested point.  @qcode{"TolX"} specifies
 ## the termination tolerance in the unknown variables, while
-## @code{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
-## for both @code{"TolX"} and @code{"TolFun"}.
+## @qcode{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
+## for both @qcode{"TolX"} and @qcode{"TolFun"}.
 ##
 ## For description of the other options, see @code{optimset}.
 ##
@@ -427,3 +427,4 @@
     x = alpha * x + ((1-alpha) * min (snm, delta)) * s;
   endif
 endfunction
+
--- a/scripts/optimization/fsolve.m
+++ b/scripts/optimization/fsolve.m
@@ -31,31 +31,30 @@
 ## in all calls to @var{fcn}, but otherwise it is treated as a column vector.
 ## @var{options} is a structure specifying additional options.
 ## Currently, @code{fsolve} recognizes these options:
-## @code{"FunValCheck"}, @code{"OutputFcn"}, @code{"TolX"},
-## @code{"TolFun"}, @code{"MaxIter"}, @code{"MaxFunEvals"},
-## @code{"Jacobian"}, @code{"Updating"}, @code{"ComplexEqn"}
-## @code{"TypicalX"}, @code{"AutoScaling"} and @code{"FinDiffType"}.
+## @qcode{"FunValCheck"}, @qcode{"OutputFcn"}, @qcode{"TolX"},
+## @qcode{"TolFun"}, @qcode{"MaxIter"}, @qcode{"MaxFunEvals"},
+## @qcode{"Jacobian"}, @qcode{"Updating"}, @qcode{"ComplexEqn"}
+## @qcode{"TypicalX"}, @qcode{"AutoScaling"} and @qcode{"FinDiffType"}.
 ##
-## If @code{"Jacobian"} is @code{"on"}, it specifies that @var{fcn},
+## If @qcode{"Jacobian"} is @qcode{"on"}, it specifies that @var{fcn},
 ## called with 2 output arguments, also returns the Jacobian matrix
-## of right-hand sides at the requested point.  @code{"TolX"} specifies
+## of right-hand sides at the requested point.  @qcode{"TolX"} specifies
 ## the termination tolerance in the unknown variables, while
-## @code{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
-## for both @code{"TolX"} and @code{"TolFun"}.
+## @qcode{"TolFun"} is a tolerance for equations.  Default is @code{1e-7}
+## for both @qcode{"TolX"} and @qcode{"TolFun"}.
 ##
-## If @code{"AutoScaling"} is on, the variables will be automatically scaled
+## If @qcode{"AutoScaling"} is on, the variables will be automatically scaled
 ## according to the column norms of the (estimated) Jacobian.  As a result,
 ## TolF becomes scaling-independent.  By default, this option is off, because
 ## it may sometimes deliver unexpected (though mathematically correct) results.
 ##
-## If @code{"Updating"} is "on", the function will attempt to use Broyden
-## updates to update the Jacobian, in order to reduce the amount of Jacobian
-## calculations.
-## If your user function always calculates the Jacobian (regardless of number
-## of output arguments), this option provides no advantage and should be set to
-## false.
+## If @qcode{"Updating"} is @qcode{"on"}, the function will attempt to use
+## @nospell{Broyden} updates to update the Jacobian, in order to reduce the
+## amount of Jacobian calculations.  If your user function always calculates the
+## Jacobian (regardless of number of output arguments), this option provides
+## no advantage and should be set to false.
 ##
-## @code{"ComplexEqn"} is @code{"on"}, @code{fsolve} will attempt to solve
+## @qcode{"ComplexEqn"} is @qcode{"on"}, @code{fsolve} will attempt to solve
 ## complex equations in complex variables, assuming that the equations possess a
 ## complex derivative (i.e., are holomorphic).  If this is not what you want,
 ## should unpack the real and imaginary parts of the system to get a real
@@ -134,7 +133,7 @@
 
   ## Get default options if requested.
   if (nargin == 1 && ischar (fcn) && strcmp (fcn, 'defaults'))
-    x = optimset ("MaxIter", 400, "MaxFunEvals", Inf, \
+    x = optimset ("MaxIter", 400, "MaxFunEvals", Inf, ...
     "Jacobian", "off", "TolX", 1e-7, "TolFun", 1e-7,
     "OutputFcn", [], "Updating", "on", "FunValCheck", "off",
     "ComplexEqn", "off", "FinDiffType", "central",
@@ -462,6 +461,7 @@
   endif
 endfunction
 
+
 %!function retval = __f (p)
 %!  x = p(1);
 %!  y = p(2);
--- a/scripts/optimization/fzero.m
+++ b/scripts/optimization/fzero.m
@@ -40,8 +40,8 @@
 ## is not successful, the function fails.
 ## @var{options} is a structure specifying additional options.
 ## Currently, @code{fzero}
-## recognizes these options: @code{"FunValCheck"}, @code{"OutputFcn"},
-## @code{"TolX"}, @code{"MaxIter"}, @code{"MaxFunEvals"}.
+## recognizes these options: @qcode{"FunValCheck"}, @qcode{"OutputFcn"},
+## @qcode{"TolX"}, @qcode{"MaxIter"}, @qcode{"MaxFunEvals"}.
 ## For a description of these options, see @ref{XREFoptimset,,optimset}.
 ##
 ## On exit, the function returns @var{x}, the approximate zero point
@@ -196,70 +196,70 @@
   mba = mu*(b - a);
   while (niter < maxiter && nfev < maxfev)
     switch (itype)
-    case 1
-      ## The initial test.
-      if (b - a <= 2*(2 * abs (u) * eps + tolx))
-        x = u; fval = fu;
-        info = 1;
-        break;
-      endif
-      if (abs (fa) <= 1e3*abs (fb) && abs (fb) <= 1e3*abs (fa))
-        ## Secant step.
-        c = u - (a - b) / (fa - fb) * fu;
-      else
+      case 1
+        ## The initial test.
+        if (b - a <= 2*(2 * abs (u) * eps + tolx))
+          x = u; fval = fu;
+          info = 1;
+          break;
+        endif
+        if (abs (fa) <= 1e3*abs (fb) && abs (fb) <= 1e3*abs (fa))
+          ## Secant step.
+          c = u - (a - b) / (fa - fb) * fu;
+        else
+          ## Bisection step.
+          c = 0.5*(a + b);
+        endif
+        d = u; fd = fu;
+        itype = 5;
+      case {2, 3}
+        l = length (unique ([fa, fb, fd, fe]));
+        if (l == 4)
+          ## Inverse cubic interpolation.
+          q11 = (d - e) * fd / (fe - fd);
+          q21 = (b - d) * fb / (fd - fb);
+          q31 = (a - b) * fa / (fb - fa);
+          d21 = (b - d) * fd / (fd - fb);
+          d31 = (a - b) * fb / (fb - fa);
+          q22 = (d21 - q11) * fb / (fe - fb);
+          q32 = (d31 - q21) * fa / (fd - fa);
+          d32 = (d31 - q21) * fd / (fd - fa);
+          q33 = (d32 - q22) * fa / (fe - fa);
+          c = a + q31 + q32 + q33;
+        endif
+        if (l < 4 || sign (c - a) * sign (c - b) > 0)
+          ## Quadratic interpolation + newton.
+          a0 = fa;
+          a1 = (fb - fa)/(b - a);
+          a2 = ((fd - fb)/(d - b) - a1) / (d - a);
+          ## Modification 1: this is simpler and does not seem to be worse.
+          c = a - a0/a1;
+          if (a2 != 0)
+            c = a - a0/a1;
+            for i = 1:itype
+              pc = a0 + (a1 + a2*(c - b))*(c - a);
+              pdc = a1 + a2*(2*c - a - b);
+              if (pdc == 0)
+                c = a - a0/a1;
+                break;
+              endif
+              c -= pc/pdc;
+            endfor
+          endif
+        endif
+        itype += 1;
+      case 4
+        ## Double secant step.
+        c = u - 2*(b - a)/(fb - fa)*fu;
+        ## Bisect if too far.
+        if (abs (c - u) > 0.5*(b - a))
+          c = 0.5 * (b + a);
+        endif
+        itype = 5;
+      case 5
         ## Bisection step.
-        c = 0.5*(a + b);
-      endif
-      d = u; fd = fu;
-      itype = 5;
-    case {2, 3}
-      l = length (unique ([fa, fb, fd, fe]));
-      if (l == 4)
-        ## Inverse cubic interpolation.
-        q11 = (d - e) * fd / (fe - fd);
-        q21 = (b - d) * fb / (fd - fb);
-        q31 = (a - b) * fa / (fb - fa);
-        d21 = (b - d) * fd / (fd - fb);
-        d31 = (a - b) * fb / (fb - fa);
-        q22 = (d21 - q11) * fb / (fe - fb);
-        q32 = (d31 - q21) * fa / (fd - fa);
-        d32 = (d31 - q21) * fd / (fd - fa);
-        q33 = (d32 - q22) * fa / (fe - fa);
-        c = a + q31 + q32 + q33;
-      endif
-      if (l < 4 || sign (c - a) * sign (c - b) > 0)
-        ## Quadratic interpolation + newton.
-        a0 = fa;
-        a1 = (fb - fa)/(b - a);
-        a2 = ((fd - fb)/(d - b) - a1) / (d - a);
-        ## Modification 1: this is simpler and does not seem to be worse.
-        c = a - a0/a1;
-        if (a2 != 0)
-          c = a - a0/a1;
-          for i = 1:itype
-            pc = a0 + (a1 + a2*(c - b))*(c - a);
-            pdc = a1 + a2*(2*c - a - b);
-            if (pdc == 0)
-              c = a - a0/a1;
-              break;
-            endif
-            c -= pc/pdc;
-          endfor
-        endif
-      endif
-      itype += 1;
-    case 4
-      ## Double secant step.
-      c = u - 2*(b - a)/(fb - fa)*fu;
-      ## Bisect if too far.
-      if (abs (c - u) > 0.5*(b - a))
         c = 0.5 * (b + a);
-      endif
-      itype = 5;
-    case 5
-      ## Bisection step.
-      c = 0.5 * (b + a);
-      itype = 2;
+        itype = 2;
     endswitch
 
     ## Don't let c come too close to a or b.
@@ -357,6 +357,7 @@
   endif
 endfunction
 
+
 %!shared opt0
 %! opt0 = optimset ("tolx", 0);
 %!assert (fzero (@cos, [0, 3], opt0), pi/2, 10*eps)
--- a/scripts/optimization/glpk.m
+++ b/scripts/optimization/glpk.m
@@ -1,4 +1,5 @@
 ## Copyright (C) 2005-2012 Nicolo' Giorgetti
+## Copyright (C) 2013 Sébastien Villemot <sebastien@debian.org>
 ##
 ## This file is part of Octave.
 ##
@@ -17,7 +18,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{status}, @var{extra}] =} glpk (@var{c}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{ctype}, @var{vartype}, @var{sense}, @var{param})
+## @deftypefn {Function File} {[@var{xopt}, @var{fmin}, @var{errnum}, @var{extra}] =} glpk (@var{c}, @var{A}, @var{b}, @var{lb}, @var{ub}, @var{ctype}, @var{vartype}, @var{sense}, @var{param})
 ## Solve a linear program using the GNU @sc{glpk} library.  Given three
 ## arguments, @code{glpk} solves the following standard LP:
 ## @tex
@@ -108,19 +109,19 @@
 ## following values
 ##
 ## @table @asis
-## @item "F"
+## @item @qcode{"F"}
 ## A free (unbounded) constraint (the constraint is ignored).
 ##
-## @item "U"
+## @item @qcode{"U"}
 ## An inequality constraint with an upper bound (@code{A(i,:)*x <= b(i)}).
 ##
-## @item "S"
+## @item @qcode{"S"}
 ## An equality constraint (@code{A(i,:)*x = b(i)}).
 ##
-## @item "L"
+## @item @qcode{"L"}
 ## An inequality with a lower bound (@code{A(i,:)*x >= b(i)}).
 ##
-## @item "D"
+## @item @qcode{"D"}
 ## An inequality constraint with both upper and lower bounds
 ## (@code{A(i,:)*x >= -b(i)} @emph{and} (@code{A(i,:)*x <= b(i)}).
 ## @end table
@@ -129,10 +130,10 @@
 ## A column array containing the types of the variables.
 ##
 ## @table @asis
-## @item "C"
+## @item @qcode{"C"}
 ## A continuous variable.
 ##
-## @item "I"
+## @item @qcode{"I"}
 ## An integer variable.
 ## @end table
 ##
@@ -149,112 +150,120 @@
 ## Integer parameters:
 ##
 ## @table @code
-## @item msglev (@w{@code{LPX_K_MSGLEV}}, default: 1)
+## @item msglev (default: 1)
 ## Level of messages output by solver routines:
 ##
 ## @table @asis
-## @item 0
+## @item 0 (@w{@code{GLP_MSG_OFF}})
 ## No output.
 ##
-## @item 1
-## Error messages only.
+## @item 1 (@w{@code{GLP_MSG_ERR}})
+## Error and warning messages only.
 ##
-## @item 2
+## @item 2 (@w{@code{GLP_MSG_ON}})
 ## Normal output.
 ##
-## @item 3
+## @item 3 (@w{@code{GLP_MSG_ALL}})
 ## Full output (includes informational messages).
 ## @end table
 ##
-## @item scale (@w{@code{LPX_K_SCALE}}, default: 1)
-## Scaling option:
+## @item scale (default: 16)
+## Scaling option.  The values can be combined with the bitwise OR operator and
+## may be the following:
 ##
 ## @table @asis
-## @item 0
-## No scaling.
+## @item 1 (@w{@code{GLP_SF_GM}})
+## Geometric mean scaling.
 ##
-## @item 1
+## @item 16 (@w{@code{GLP_SF_EQ}})
 ## Equilibration scaling.
 ##
-## @item 2
-## Geometric mean scaling, then equilibration scaling.
+## @item 32 (@w{@code{GLP_SF_2N}})
+## Round scale factors to power of two.
+##
+## @item 64 (@w{@code{GLP_SF_SKIP}})
+## Skip if problem is well scaled.
 ## @end table
 ##
-## @item dual    (@w{@code{LPX_K_DUAL}}, default: 0)
-## Dual simplex option:
+## Alternatively, a value of 128 (@w{@env{GLP_SF_AUTO}}) may be also
+## specified, in which case the routine chooses the scaling options
+## automatically.
+##
+## @item dual (default: 1)
+## Simplex method option:
 ##
 ## @table @asis
-## @item 0
-## Do not use the dual simplex.
+## @item 1 (@w{@code{GLP_PRIMAL}})
+## Use two-phase primal simplex.
 ##
-## @item 1
-## If initial basic solution is dual feasible, use the dual simplex.
+## @item 2 (@w{@code{GLP_DUALP}})
+## Use two-phase dual simplex, and if it fails, switch to the primal simplex.
+##
+## @item 3 (@w{@code{GLP_DUAL}})
+## Use two-phase dual simplex.
 ## @end table
 ##
-## @item price   (@w{@code{LPX_K_PRICE}}, default: 1)
+## @item price (default: 34)
 ## Pricing option (for both primal and dual simplex):
 ##
 ## @table @asis
-## @item 0
+## @item 17 (@w{@code{GLP_PT_STD}})
 ## Textbook pricing.
 ##
-## @item 1
+## @item 34 (@w{@code{GLP_PT_PSE}})
 ## Steepest edge pricing.
 ## @end table
 ##
-## @item round   (@w{@code{LPX_K_ROUND}}, default: 0)
-## Solution rounding option:
-##
-## @table @asis
-## @item 0
-## Report all primal and dual values "as is".
+## @item itlim (default: intmax)
+## Simplex iterations limit.  It is decreased by one each time when one simplex
+## iteration has been performed, and reaching zero value signals the solver to
+## stop the search.
 ##
-## @item 1
-## Replace tiny primal and dual values by exact zero.
-## @end table
-##
-## @item itlim   (@w{@code{LPX_K_ITLIM}}, default: -1)
-## Simplex iterations limit.  If this value is positive, it is decreased by
-## one each time when one simplex iteration has been performed, and
-## reaching zero value signals the solver to stop the search.  Negative
-## value means no iterations limit.
-##
-## @item itcnt (@w{@code{LPX_K_OUTFRQ}}, default: 200)
+## @item outfrq (default: 200)
 ## Output frequency, in iterations.  This parameter specifies how
 ## frequently the solver sends information about the solution to the
 ## standard output.
 ##
-## @item branch (@w{@code{LPX_K_BRANCH}}, default: 2)
-## Branching heuristic option (for MIP only):
+## @item branch (default: 4)
+## Branching technique option (for MIP only):
 ##
 ## @table @asis
-## @item 0
-## Branch on the first variable.
+## @item 1 (@w{@code{GLP_BR_FFV}})
+## First fractional variable.
+##
+## @item 2 (@w{@code{GLP_BR_LFV}})
+## Last fractional variable.
 ##
-## @item 1
-## Branch on the last variable.
+## @item 3 (@w{@code{GLP_BR_MFV}})
+## Most fractional variable.
 ##
-## @item 2
-## Branch using a heuristic by Driebeck and Tomlin.
+## @item 4 (@w{@code{GLP_BR_DTH}})
+## Heuristic by Driebeck and Tomlin.
+##
+## @item 5 (@w{@code{GLP_BR_PCH}})
+## Hybrid @nospell{pseudocost} heuristic.
 ## @end table
 ##
-## @item btrack (@w{@code{LPX_K_BTRACK}}, default: 2)
-## Backtracking heuristic option (for MIP only):
+## @item btrack (default: 4)
+## Backtracking technique option (for MIP only):
 ##
 ## @table @asis
-## @item 0
+## @item 1 (@w{@code{GLP_BT_DFS}})
 ## Depth first search.
 ##
-## @item 1
+## @item 2 (@w{@code{GLP_BT_BFS}})
 ## Breadth first search.
 ##
-## @item 2
-## Backtrack using the best projection heuristic.
+## @item 3 (@w{@code{GLP_BT_BLB}})
+## Best local bound.
+##
+## @item 4 (@w{@code{GLP_BT_BPH}})
+## Best projection heuristic.
 ## @end table
 ##
-## @item presol (@w{@code{LPX_K_PRESOL}}, default: 1)
-## If this flag is set, the routine lpx_simplex solves the problem using
-## the built-in LP presolver.  Otherwise the LP presolver is not used.
+## @item presol (default: 1)
+## If this flag is set, the simplex solver uses the built-in LP presolver.
+## Otherwise the LP presolver is not used.
 ##
 ## @item lpsolver (default: 1)
 ## Select which solver to use.  If the problem is a MIP problem this flag
@@ -268,6 +277,25 @@
 ## Interior point method.
 ## @end table
 ##
+## @item rtest (default: 34)
+## Ratio test technique:
+##
+## @table @asis
+## @item 17 (@w{@code{GLP_RT_STD}})
+## Standard ("textbook").
+##
+## @item 34 (@w{@code{GLP_RT_HAR}})
+## Harris' two-pass ratio test.
+## @end table
+##
+## @item tmlim (default: intmax)
+## Searching time limit, in milliseconds.
+##
+## @item outdly (default: 0)
+## Output delay, in seconds.  This parameter specifies how long the solver
+## should delay sending information about the solution to the standard
+## output.
+##
 ## @item save (default: 0)
 ## If this parameter is nonzero, save a copy of the problem in
 ## CPLEX LP format to the file @file{"outpb.lp"}.  There is currently no
@@ -277,58 +305,37 @@
 ## Real parameters:
 ##
 ## @table @code
-## @item relax (@w{@code{LPX_K_RELAX}}, default: 0.07)
-## Relaxation parameter used in the ratio test.  If it is zero, the textbook
-## ratio test is used.  If it is non-zero (should be positive), Harris'
-## two-pass ratio test is used.  In the latter case on the first pass of the
-## ratio test basic variables (in the case of primal simplex) or reduced
-## costs of non-basic variables (in the case of dual simplex) are allowed
-## to slightly violate their bounds, but not more than
-## @code{relax*tolbnd} or @code{relax*toldj (thus, @code{relax} is a
-## percentage of @code{tolbnd} or @code{toldj}}.
-##
-## @item tolbnd (@w{@code{LPX_K_TOLBND}}, default: 10e-7)
+## @item tolbnd (default: 1e-7)
 ## Relative tolerance used to check if the current basic solution is primal
 ## feasible.  It is not recommended that you change this parameter unless you
 ## have a detailed understanding of its purpose.
 ##
-## @item toldj (@w{@code{LPX_K_TOLDJ}}, default: 10e-7)
+## @item toldj (default: 1e-7)
 ## Absolute tolerance used to check if the current basic solution is dual
 ## feasible.  It is not recommended that you change this parameter unless you
 ## have a detailed understanding of its purpose.
 ##
-## @item tolpiv (@w{@code{LPX_K_TOLPIV}}, default: 10e-9)
+## @item tolpiv (default: 1e-10)
 ## Relative tolerance used to choose eligible pivotal elements of the
 ## simplex table.  It is not recommended that you change this parameter unless
 ## you have a detailed understanding of its purpose.
 ##
-## @item objll (@w{@code{LPX_K_OBJLL}}, default: -DBL_MAX)
-## Lower limit of the objective function.  If on the phase II the objective
+## @item objll (default: -DBL_MAX)
+## Lower limit of the objective function.  If the objective
 ## function reaches this limit and continues decreasing, the solver stops
 ## the search.  This parameter is used in the dual simplex method only.
 ##
-## @item objul (@w{@code{LPX_K_OBJUL}}, default: +DBL_MAX)
-## Upper limit of the objective function.  If on the phase II the objective
+## @item objul (default: +DBL_MAX)
+## Upper limit of the objective function.  If the objective
 ## function reaches this limit and continues increasing, the solver stops
 ## the search.  This parameter is used in the dual simplex only.
 ##
-## @item tmlim (@w{@code{LPX_K_TMLIM}}, default: -1.0)
-## Searching time limit, in seconds.  If this value is positive, it is
-## decreased each time when one simplex iteration has been performed by the
-## amount of time spent for the iteration, and reaching zero value signals
-## the solver to stop the search.  Negative value means no time limit.
-##
-## @item outdly (@w{@code{LPX_K_OUTDLY}}, default: 0.0)
-## Output delay, in seconds.  This parameter specifies how long the solver
-## should delay sending information about the solution to the standard
-## output.  Non-positive value means no delay.
-##
-## @item tolint (@w{@code{LPX_K_TOLINT}}, default: 10e-5)
+## @item tolint (default: 1e-5)
 ## Relative tolerance used to check if the current basic solution is integer
 ## feasible.  It is not recommended that you change this parameter unless
 ## you have a detailed understanding of its purpose.
 ##
-## @item tolobj (@w{@code{LPX_K_TOLOBJ}}, default: 10e-7)
+## @item tolobj (default: 1e-7)
 ## Relative tolerance used to check if the value of the objective function
 ## is not better than in the best known integer feasible solution.  It is
 ## not recommended that you change this parameter unless you have a
@@ -345,94 +352,69 @@
 ## @item fopt
 ## The optimum value of the objective function.
 ##
-## @item status
-## Status of the optimization.
-##
-## Simplex Method:
-##
-## @table @asis
-## @item 180 (@w{@code{LPX_OPT}})
-## Solution is optimal.
-##
-## @item 181 (@w{@code{LPX_FEAS}})
-## Solution is feasible.
-##
-## @item 182 (@w{@code{LPX_INFEAS}})
-## Solution is infeasible.
-##
-## @item 183 (@w{@code{LPX_NOFEAS}})
-## Problem has no feasible solution.
-##
-## @item 184 (@w{@code{LPX_UNBND}})
-## Problem has no unbounded solution.
-##
-## @item 185 (@w{@code{LPX_UNDEF}})
-## Solution status is undefined.
-## @end table
-##
-## Interior Point Method:
-##
-## @table @asis
-## @item 150 (@w{@code{LPX_T_UNDEF}})
-## The interior point method is undefined.
-##
-## @item 151 (@w{@code{LPX_T_OPT}})
-## The interior point method is optimal.
-## @end table
-##
-## Mixed Integer Method:
+## @item errnum
+## Error code.
 ##
 ## @table @asis
-## @item 170 (@w{@code{LPX_I_UNDEF}})
-## The status is undefined.
+## @item 0
+## No error.
 ##
-## @item 171 (@w{@code{LPX_I_OPT}})
-## The solution is integer optimal.
+## @item 1 (@w{@code{GLP_EBADB}})
+## Invalid basis.
 ##
-## @item 172 (@w{@code{LPX_I_FEAS}})
-## Solution integer feasible but its optimality has not been proven
+## @item 2 (@w{@code{GLP_ESING}})
+## Singular matrix.
 ##
-## @item 173 (@w{@code{LPX_I_NOFEAS}})
-## No integer feasible solution.
-## @end table
+## @item 3 (@w{@code{GLP_ECOND}})
+## Ill-conditioned matrix.
 ##
-## @noindent
-## If an error occurs, @var{status} will contain one of the following
-## codes:
+## @item 4 (@w{@code{GLP_EBOUND}})
+## Invalid bounds.
 ##
-## @table @asis
-## @item 204 (@w{@code{LPX_E_FAULT}})
-## Unable to start the search.
+## @item 5 (@w{@code{GLP_EFAIL}})
+## Solver failed.
 ##
-## @item 205 (@w{@code{LPX_E_OBJLL}})
+## @item 6 (@w{@code{GLP_EOBJLL}})
 ## Objective function lower limit reached.
 ##
-## @item 206 (@w{@code{LPX_E_OBJUL}})
+## @item 7 (@w{@code{GLP_EOBJUL}})
 ## Objective function upper limit reached.
 ##
-## @item 207 (@w{@code{LPX_E_ITLIM}})
+## @item 8 (@w{@code{GLP_EITLIM}})
 ## Iterations limit exhausted.
 ##
-## @item 208 (@w{@code{LPX_E_TMLIM}})
+## @item 9 (@w{@code{GLP_ETMLIM}})
 ## Time limit exhausted.
 ##
-## @item 209 (@w{@code{LPX_E_NOFEAS}})
-## No feasible solution.
+## @item 10 (@w{@code{GLP_ENOPFS}})
+## No primal feasible solution.
+##
+## @item 11 (@w{@code{GLP_ENODFS}})
+## No dual feasible solution.
+##
+## @item 12 (@w{@code{GLP_EROOT}})
+## Root LP optimum not provided.
 ##
-## @item 210 (@w{@code{LPX_E_INSTAB}})
+## @item 13 (@w{@code{GLP_ESTOP}})
+## Search terminated by application.
+##
+## @item 14 (@w{@code{GLP_EMIPGAP}})
+## Relative MIP gap tolerance reached.
+##
+## @item 15 (@w{@code{GLP_ENOFEAS}})
+## No primal/dual feasible solution.
+##
+## @item 16 (@w{@code{GLP_ENOCVG}})
+## No convergence.
+##
+## @item 17 (@w{@code{GLP_EINSTAB}})
 ## Numerical instability.
 ##
-## @item 211 (@w{@code{LPX_E_SING}})
-## Problems with basis matrix.
-##
-## @item 212 (@w{@code{LPX_E_NOCONV}})
-## No convergence (interior).
+## @item 18 (@w{@code{GLP_EDATA}})
+## Invalid data.
 ##
-## @item 213 (@w{@code{LPX_E_NOPFS}})
-## No primal feasible solution (LP presolver).
-##
-## @item 214 (@w{@code{LPX_E_NODFS}})
-## No dual feasible solution (LP presolver).
+## @item 19 (@w{@code{GLP_ERANGE}})
+## Result out of range.
 ## @end table
 ##
 ## @item extra
@@ -448,9 +430,28 @@
 ## @item time
 ## Time (in seconds) used for solving LP/MIP problem.
 ##
-## @item mem
-## Memory (in bytes) used for solving LP/MIP problem (this is not
-## available if the version of @sc{glpk} is 4.15 or later).
+## @item status
+## Status of the optimization.
+##
+## @table @asis
+## @item 1 (@w{@code{GLP_UNDEF}})
+## Solution status is undefined.
+##
+## @item 2 (@w{@code{GLP_FEAS}})
+## Solution is feasible.
+##
+## @item 3 (@w{@code{GLP_INFEAS}})
+## Solution is infeasible.
+##
+## @item 4 (@w{@code{GLP_NOFEAS}})
+## Problem has no feasible solution.
+##
+## @item 5 (@w{@code{GLP_OPT}})
+## Solution is optimal.
+##
+## @item 6 (@w{@code{GLP_UNBND}})
+## Problem has no unbounded solution.
+## @end table
 ## @end table
 ## @end table
 ##
@@ -481,7 +482,7 @@
 ## Author: Nicolo' Giorgetti <giorgetti@dii.unisi.it>
 ## Adapted-by: jwe
 
-function [xopt, fmin, status, extra] = glpk (c, A, b, lb, ub, ctype, vartype, sense, param)
+function [xopt, fmin, errnum, extra] = glpk (c, A, b, lb, ub, ctype, vartype, sense, param)
 
   ## If there is no input output the version and syntax
   if (nargin < 3 || nargin > 9)
@@ -608,7 +609,8 @@
     param = struct ();
   endif
 
-  [xopt, fmin, status, extra] = ...
+  [xopt, fmin, errnum, extra] = ...
     __glpk__ (c, A, b, lb, ub, ctype, vartype, sense, param);
 
 endfunction
+
--- a/scripts/optimization/lsqnonneg.m
+++ b/scripts/optimization/lsqnonneg.m
@@ -31,7 +31,7 @@
 ## @code{@var{x} >= 0}.  @var{c} and @var{d} must be real.  @var{x0} is an
 ## optional initial guess for @var{x}.
 ## Currently, @code{lsqnonneg}
-## recognizes these options: @code{"MaxIter"}, @code{"TolX"}.
+## recognizes these options: @qcode{"MaxIter"}, @qcode{"TolX"}.
 ## For a description of these options, see @ref{XREFoptimset,,optimset}.
 ##
 ## Outputs:
@@ -57,9 +57,9 @@
 ## A structure with two fields:
 ##
 ## @itemize @bullet
-## @item "algorithm": The algorithm used ("nnls")
+## @item @qcode{"algorithm"}: The algorithm used (@qcode{"nnls"})
 ##
-## @item "iterations": The number of iterations taken.
+## @item @qcode{"iterations"}: The number of iterations taken.
 ## @end itemize
 ##
 ## @item lambda
@@ -79,7 +79,7 @@
 
   if (nargin == 1 && ischar (c) && strcmp (c, 'defaults'))
     x = optimset ("MaxIter", 1e5);
-    return
+    return;
   endif
 
   if (! (nargin >= 2 && nargin <= 4 && ismatrix (c) && ismatrix (d) && isstruct (options)))
--- a/scripts/optimization/optimget.m
+++ b/scripts/optimization/optimget.m
@@ -33,7 +33,7 @@
   endif
 
   opts = __all_opts__ ();
-  idx = strncmpi (opts, parname, numel (parname));
+  idx = strncmpi (opts, parname, length (parname));
 
   nmatch = sum (idx);
 
@@ -56,6 +56,7 @@
 
 endfunction
 
+
 %!error optimget ()
 
 %!shared opts
@@ -65,3 +66,4 @@
 %!assert (optimget (opts, "MaxITer"), 100);
 %!warning (optimget (opts, "Max"));
 %!warning (optimget (opts, "foobar"));
+
--- a/scripts/optimization/optimset.m
+++ b/scripts/optimization/optimset.m
@@ -35,16 +35,16 @@
 ## Request verbose display of results from optimizations.  Values are:
 ##
 ## @table @asis
-## @item "off" [default]
+## @item @qcode{"off"} [default]
 ## No display.
 ##
-## @item "iter"
+## @item @qcode{"iter"}
 ## Display intermediate results for every loop iteration.
 ##
-## @item "final"
+## @item @qcode{"final"}
 ## Display the result of the final loop iteration.
 ##
-## @item "notify"
+## @item @qcode{"notify"}
 ## Display the result of the final loop iteration if the function has
 ## failed to converge.
 ## @end table
@@ -53,22 +53,22 @@
 ##
 ## @item FunValCheck
 ## When enabled, display an error if the objective function returns an invalid
-## value (a complex number, NaN, or Inf).  Must be set to "on" or "off"
-## [default].  Note: the functions @code{fzero} and @code{fminbnd} correctly
-## handle Inf values and only complex values or NaN will cause an error in this
-## case. 
+## value (a complex number, NaN, or Inf).  Must be set to @qcode{"on"} or
+## @qcode{"off"} [default].  Note: the functions @code{fzero} and
+## @code{fminbnd} correctly handle Inf values and only complex values or NaN
+## will cause an error in this case. 
 ##
 ## @item GradObj
-## When set to "on", the function to be minimized must return a second argument
-## which is the gradient, or first derivative, of the function at the point
-## @var{x}.  If set to "off" [default], the gradient is computed via finite
-## differences.
+## When set to @qcode{"on"}, the function to be minimized must return a
+## second argument which is the gradient, or first derivative, of the
+## function at the point @var{x}.  If set to @qcode{"off"} [default], the
+## gradient is computed via finite differences.
 ##
 ## @item Jacobian
-## When set to "on", the function to be minimized must return a second argument
-## which is the Jacobian, or first derivative, of the function at the point
-## @var{x}.  If set to "off" [default], the Jacobian is computed via finite
-## differences.
+## When set to @qcode{"on"}, the function to be minimized must return a
+## second argument which is the Jacobian, or first derivative, of the
+## function at the point @var{x}.  If set to @qcode{"off"} [default], the
+## Jacobian is computed via finite differences.
 ##
 ## @item MaxFunEvals
 ## Maximum number of function evaluations before optimization stops.
@@ -172,3 +172,4 @@
 %!warning (optimset ("foobar", 13));
 
 %!error (optimset ("%NOT_A_REAL_FUNCTION_NAME%"))
+
--- a/scripts/optimization/pqpnonneg.m
+++ b/scripts/optimization/pqpnonneg.m
@@ -48,9 +48,9 @@
 ## A structure with two fields:
 ##
 ## @itemize @bullet
-## @item "algorithm": The algorithm used ("nnls")
+## @item @qcode{"algorithm"}: The algorithm used (@qcode{"nnls"})
 ##
-## @item "iterations": The number of iterations taken.
+## @item @qcode{"iterations"}: The number of iterations taken.
 ## @end itemize
 ##
 ## @item lambda
@@ -72,7 +72,7 @@
 
   if (nargin == 1 && ischar (c) && strcmp (c, 'defaults'))
     x = optimset ("MaxIter", 1e5);
-    return
+    return;
   endif
 
   if (! (nargin >= 2 && nargin <= 4 && ismatrix (c) && ismatrix (d) && isstruct (options)))
--- a/scripts/optimization/qp.m
+++ b/scripts/optimization/qp.m
@@ -405,3 +405,4 @@
   endif
 
 endfunction
+
--- a/scripts/optimization/sqp.m
+++ b/scripts/optimization/sqp.m
@@ -186,8 +186,7 @@
 
 function [x, obj, info, iter, nf, lambda] = sqp (x0, objf, cef, cif, lb, ub, maxiter, tolerance)
 
-  globals = struct (); # data and handles, needed and changed by
-                       # subfunctions
+  globals = struct (); # data and handles, needed and changed by subfunctions
 
   if (nargin < 2 || nargin > 8 || nargin == 5)
     print_usage ();
@@ -203,19 +202,19 @@
   have_hess = 0;
   if (iscell (objf))
     switch (numel (objf))
-     case 1
-       obj_fun = objf{1};
-       obj_grd = @ (x) fd_obj_grd (x, obj_fun);
-     case 2
-       obj_fun = objf{1};
-       obj_grd = objf{2};
-     case 3
-       obj_fun = objf{1};
-       obj_grd = objf{2};
-       obj_hess = objf{3};
-       have_hess = 1;
-     otherwise
-      error ("sqp: invalid objective function specification");
+      case 1
+        obj_fun = objf{1};
+        obj_grd = @ (x) fd_obj_grd (x, obj_fun);
+      case 2
+        obj_fun = objf{1};
+        obj_grd = objf{2};
+      case 3
+        obj_fun = objf{1};
+        obj_grd = objf{2};
+        obj_hess = objf{3};
+        have_hess = 1;
+      otherwise
+        error ("sqp: invalid objective function specification");
     endswitch
   else
     obj_fun = objf;   # No cell array, only obj_fun set
@@ -227,14 +226,14 @@
   if (nargin > 2)
     if (iscell (cef))
       switch (numel (cef))
-       case 1
-         ce_fun = cef{1};
-         ce_grd = @ (x) fd_ce_jac (x, ce_fun);
-       case 2
-         ce_fun = cef{1};
-         ce_grd = cef{2};
-       otherwise
-         error ("sqp: invalid equality constraint function specification");
+        case 1
+          ce_fun = cef{1};
+          ce_grd = @ (x) fd_ce_jac (x, ce_fun);
+        case 2
+          ce_fun = cef{1};
+          ce_grd = cef{2};
+        otherwise
+          error ("sqp: invalid equality constraint function specification");
       endswitch
     elseif (! isempty (cef))
       ce_fun = cef;   # No cell array, only constraint equality function set
@@ -262,13 +261,13 @@
       ci_grd = @ (x) fd_ci_jac (x, globals.cifcn);
       if (iscell (cif))
         switch (length (cif))
-         case {1}
-           ci_fun = cif{1};
-         case {2}
-           ci_fun = cif{1};
-           ci_grd = cif{2};
-        otherwise
-          error ("sqp: invalid inequality constraint function specification");
+          case 1
+            ci_fun = cif{1};
+          case 2
+            ci_fun = cif{1};
+            ci_grd = cif{2};
+          otherwise
+           error ("sqp: invalid inequality constraint function specification");
         endswitch
       elseif (! isempty (cif))
         ci_fun = cif;   # No cell array, only constraint inequality function set
@@ -425,8 +424,8 @@
 
     ## Choose mu such that p is a descent direction for the chosen
     ## merit function phi.
-    [x_new, alpha, obj_new, globals] = \
-        linesearch_L1 (x, p, obj_fun, obj_grd, ce_fun, ci_fun, lambda, \
+    [x_new, alpha, obj_new, globals] = ...
+        linesearch_L1 (x, p, obj_fun, obj_grd, ce_fun, ci_fun, lambda, ...
                        obj, globals);
 
     ## Evaluate objective function, constraints, and gradients at x_new.
@@ -520,7 +519,7 @@
 endfunction
 
 
-function [merit, obj, globals] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, \
+function [merit, obj, globals] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, ...
                                          x, mu, globals)
 
   ce = feval (ce_fun, x);
@@ -545,8 +544,8 @@
 endfunction
 
 
-function [x_new, alpha, obj, globals] = \
-      linesearch_L1 (x, p, obj_fun, obj_grd, ce_fun, ci_fun, lambda, \
+function [x_new, alpha, obj, globals] = ...
+      linesearch_L1 (x, p, obj_fun, obj_grd, ce_fun, ci_fun, lambda, ...
                      obj, globals)
 
   ## Choose parameters
@@ -570,7 +569,7 @@
   c = feval (obj_grd, x);
   ce = feval (ce_fun, x);
 
-  [phi_x_mu, obj, globals] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, \
+  [phi_x_mu, obj, globals] = phi_L1 (obj, obj_fun, ce_fun, ci_fun, x, ...
                                      mu, globals);
 
   D_phi_x_mu = c' * p;
@@ -584,7 +583,7 @@
   endif
 
   while (1)
-    [p1, obj, globals] = phi_L1 ([], obj_fun, ce_fun, ci_fun, \
+    [p1, obj, globals] = phi_L1 ([], obj_fun, ce_fun, ci_fun, ...
                                  x+alpha*p, mu, globals);
     p2 = phi_x_mu+eta*alpha*D_phi_x_mu;
     if (p1 > p2)
@@ -768,3 +767,4 @@
 %!error sqp (1, cell (3,1), cell (2,1), cell (2,1),[],[],1.5)
 %!error sqp (1, cell (3,1), cell (2,1), cell (2,1),[],[],[], ones (2,2))
 %!error sqp (1, cell (3,1), cell (2,1), cell (2,1),[],[],[],-1)
+
--- a/scripts/path/pathdef.m
+++ b/scripts/path/pathdef.m
@@ -124,3 +124,4 @@
   endif
 
 endfunction
+
--- a/scripts/pkg/pkg.m
+++ b/scripts/pkg/pkg.m
@@ -1,4 +1,4 @@
-## Copyright (C) 2005-2012 S�ren Hauberg
+## Copyright (C) 2005-2012 Søren Hauberg
 ## Copyright (C) 2010 VZLU Prague, a.s.
 ## Copyright (C) 2012 Carlo de Falco
 ##
@@ -137,8 +137,9 @@
 ## [user_packages, system_packages] = pkg ("list")
 ## @end example
 ##
-## The option "-forge" lists packages available at the Octave-Forge repository.
-## This requires an internet connection and the cURL library.  For example:
+## The option @qcode{"-forge"} lists packages available at the Octave-Forge
+## repository.  This requires an internet connection and the cURL library. 
+## For example:
 ##
 ## @example
 ## oct_forge_pkgs = pkg ("list", "-forge")
@@ -146,7 +147,7 @@
 ##
 ## @item describe
 ## Show a short description of the named installed packages, with the option
-## "-verbose" also list functions provided by the package.  For example,
+## @qcode{"-verbose"} also list functions provided by the package.  For example,
 ##
 ## @example
 ## pkg describe -verbose all
@@ -171,8 +172,9 @@
 ## @end example
 ##
 ## @noindent
-## @var{flag} will take one of the values "Not installed", "Loaded" or
-## "Not loaded" for each of the named packages.
+## @var{flag} will take one of the values @qcode{"Not installed"},
+## @qcode{"Loaded"}, or
+## @qcode{"Not loaded"} for each of the named packages.
 ##
 ## @item prefix
 ## Set the installation prefix directory.  For example,
@@ -554,3 +556,4 @@
       error ("you must specify a valid action for 'pkg'. See 'help pkg' for details");
   endswitch
 endfunction
+
--- a/scripts/pkg/private/build.m
+++ b/scripts/pkg/private/build.m
@@ -61,3 +61,4 @@
     endif
   end_unwind_protect
 endfunction
+
--- a/scripts/pkg/private/describe.m
+++ b/scripts/pkg/private/describe.m
@@ -29,7 +29,6 @@
   installed_pkgs_lst = installed_packages(local_list, global_list);
   num_packages = length (installed_pkgs_lst);
 
-
   describe_all = false;
   if (any (strcmp ("all", pkgnames)))
     describe_all = true;
@@ -85,3 +84,4 @@
   endif
 
 endfunction
+
--- a/scripts/pkg/private/dirempty.m
+++ b/scripts/pkg/private/dirempty.m
@@ -40,7 +40,7 @@
       endfor
       if (! found)
         emp = false;
-        return
+        return;
       endif
     endfor
     emp = true;
@@ -48,3 +48,4 @@
     emp = true;
   endif
 endfunction
+
--- a/scripts/pkg/private/get_forge_download.m
+++ b/scripts/pkg/private/get_forge_download.m
@@ -26,3 +26,4 @@
   [ver, url] = get_forge_pkg (name);
   local_file = [name, "-", ver, ".tar.gz"];
 endfunction
+
--- a/scripts/pkg/private/get_forge_pkg.m
+++ b/scripts/pkg/private/get_forge_pkg.m
@@ -26,9 +26,7 @@
 ## @end deftypefn
 
 function [ver, url] = get_forge_pkg (name)
-  if (nargin != 1)
-    print_usage ();
-  endif
+
   ## Verify that name is valid.
   if (! (ischar (name) && rows (name) == 1 && ndims (name) == 2))
     error ("get_forge_pkg: package NAME must be a string");
@@ -51,7 +49,7 @@
     else
       ver = t{1}{1};
       if (nargout > 1)
-        # Build download string.
+        ## Build download string.
         pkg_file = sprintf ("%s-%s.tar.gz", name, ver);
         url = ["http://packages.octave.org/download/" pkg_file];
         ## Verify that the package string exists on the page.
@@ -80,3 +78,4 @@
   endif
 
 endfunction
+
--- a/scripts/pkg/private/get_unsatisfied_deps.m
+++ b/scripts/pkg/private/get_unsatisfied_deps.m
@@ -52,3 +52,4 @@
     endif
   endfor
 endfunction
+
--- a/scripts/pkg/private/install.m
+++ b/scripts/pkg/private/install.m
@@ -341,3 +341,4 @@
   endif
 
 endfunction
+
--- a/scripts/pkg/private/is_architecture_dependent.m
+++ b/scripts/pkg/private/is_architecture_dependent.m
@@ -44,3 +44,4 @@
     endif
   endfor
 endfunction
+
--- a/scripts/pkg/private/list_forge_packages.m
+++ b/scripts/pkg/private/list_forge_packages.m
@@ -42,3 +42,4 @@
     endfor
   endif
 endfunction
+
--- a/scripts/pkg/private/rebuild.m
+++ b/scripts/pkg/private/rebuild.m
@@ -35,7 +35,7 @@
     wd = pwd ();
     unwind_protect
       cd (prefix);
-      dirlist = glob (cellfun(@(x) [x '-*'], files, 'uniformoutput', 0));
+      dirlist = glob (strcat (files, '-*'));
     unwind_protect_cleanup
       cd (wd);
     end_unwind_protect
@@ -97,3 +97,4 @@
     endif
   endif
 endfunction
+
--- a/scripts/pkg/private/shell.m
+++ b/scripts/pkg/private/shell.m
@@ -54,3 +54,4 @@
     [status, output] = system (cmd);
   endif
 endfunction
+
--- a/scripts/pkg/private/uninstall.m
+++ b/scripts/pkg/private/uninstall.m
@@ -144,3 +144,4 @@
   endif
 
 endfunction
+
--- a/scripts/pkg/private/unload_packages.m
+++ b/scripts/pkg/private/unload_packages.m
@@ -73,8 +73,7 @@
     idx = strcmp (p, d);
     if (any (idx))
       rmpath (d);
-      ## FIXME: We should also check if we need to remove items from
-      ## EXEC_PATH.
+      ## FIXME: We should also check if we need to remove items from EXEC_PATH.
     endif
   endfor
 endfunction
--- a/scripts/plot/__gnuplot_drawnow__.m
+++ b/scripts/plot/__gnuplot_drawnow__.m
@@ -209,11 +209,11 @@
               size_str = sprintf ("size %gin,%gin", gnuplot_size);
             case "dumb"
               new_stream = 1;
-              if (! isempty (getenv ("COLUMNS")) && ! isempty (getenv ("LINES")))
+              if (!isempty (getenv ("COLUMNS")) && !isempty (getenv ("LINES")))
                 ## Let dumb use full text screen size (minus prompt lines).
                 n = sprintf ("%i", -2 - length (find (sprintf ("%s", PS1) == "\n")));
                 ## n = the number of times \n appears in PS1
-                size_str = ["size ", getenv("COLUMNS"), ",", getenv("LINES"), n];
+                size_str = ["size " getenv("COLUMNS") "," getenv("LINES") n];
               else
                 ## Use the gnuplot default.
                 size_str = "";
@@ -225,7 +225,7 @@
             otherwise
               size_str = "";
           endswitch
-          if ((strncmpi (term, "x11", 3)
+          if ((strcmp (term, "x11")
                && __gnuplot_has_feature__ ("x11_figure_position"))
               || (strcmpi (term, "windows")
                   && __gnuplot_has_feature__ ("windows_figure_position")))
@@ -296,13 +296,13 @@
     if (! __gnuplot_has_feature__ ("has_termoption_dashed"))
       ## If "set termoption dashed" isn't available add "dashed" option
       ## to the "set terminal ..." command, if it is supported.
-      if (any (strcmp (term, {"aqua", "cgm", "eepic", "emf", "epslatex", \
-                              "fig", "pcl5", "mp", "next", "openstep", "pdf", \
-                              "pdfcairo", "pngcairo", "postscript", \
+      if (any (strcmp (term, {"aqua", "cgm", "eepic", "emf", "epslatex", ...
+                              "fig", "pcl5", "mp", "next", "openstep", "pdf", ...
+                              "pdfcairo", "pngcairo", "postscript", ...
                               "pslatex", "pstext", "svg", "tgif", "x11"})))
         term_str = [term_str " dashed"];
       endif
-    end
+    endif
     if (any (strcmp (term, {"aqua", "wxt"})))
       term_str = [term_str, " ", "dashlength 1"];
     elseif (any (strcmp (term, {"epslatex", "postscript", "pslatex"})))
--- a/scripts/plot/allchild.m
+++ b/scripts/plot/allchild.m
@@ -21,9 +21,10 @@
 ## Find all children, including hidden children, of a graphics object.
 ##
 ## This function is similar to @code{get (h, "children")}, but also returns
-## hidden objects ("HandleVisibility" = "off").  If @var{handles} is a scalar,
-## @var{h} will be a vector.  Otherwise, @var{h} will be a cell matrix of the
-## same size as @var{handles} and each cell will contain a vector of handles.
+## hidden objects (HandleVisibility = @qcode{"off"}).  If @var{handles} is a
+## scalar, @var{h} will be a vector.  Otherwise, @var{h} will be a cell
+## matrix of the same size as @var{handles} and each cell will contain a
+## vector of handles.
 ## @seealso{findall, findobj, get, set}
 ## @end deftypefn
 
--- a/scripts/plot/ancestor.m
+++ b/scripts/plot/ancestor.m
@@ -26,7 +26,7 @@
 ##
 ## If the handle object @var{h} itself is of type @var{type}, return @var{h}.
 ##
-## If @code{"toplevel"} is given as a third argument, return the highest
+## If @qcode{"toplevel"} is given as a third argument, return the highest
 ## parent in the object hierarchy that matches the condition, instead
 ## of the first (nearest) one.
 ## @seealso{findobj, findall, allchild}
--- a/scripts/plot/area.m
+++ b/scripts/plot/area.m
@@ -41,7 +41,7 @@
 ## rather than the current axes returned by @code{gca}.
 ##
 ## The optional return value @var{h} is a graphics handle to the hggroup
-## object comprising the area patch objects.  The "BaseValue" property
+## object comprising the area patch objects.  The @qcode{"BaseValue"} property
 ## of the hggroup can be used to adjust the level where shading begins.
 ##
 ## Example: Verify identity sin^2 + cos^2 = 1
@@ -51,7 +51,7 @@
 ## t = linspace (0, 2*pi, 100)';
 ## y = [sin(t).^2, cos(t).^2)];
 ## area (t, y);
-## legend ("sin^2", "cos^2", "location", "NorthEastOutside");  
+## legend ("sin^2", "cos^2", "location", "NorthEastOutside");
 ## @end group
 ## @end example
 ## @seealso{plot, patch}
@@ -65,35 +65,40 @@
     print_usage ();
   endif
 
-  idx = 1;
   x = y = [];
   bv = 0;
-  args = {};
-  ## Check for (X) or (X,Y) arguments and possible base value.
-  if (nargin >= idx && ismatrix (varargin{idx}))
-    y = varargin{idx};
-    idx++;
-    if (nargin >= idx)
-      if (isscalar (varargin{idx}))
-        bv = varargin{idx};
-        idx++;
-      elseif (ismatrix (varargin{idx}))
-        x = y;
-        y = varargin{idx};
-        idx++;
-        if (nargin >= idx && isscalar (varargin{idx}))
-          bv = varargin{idx};
-          idx++;
-        endif
+
+  num_numeric = find (cellfun ("isclass", varargin, "char"), 1) - 1;
+  if (isempty (num_numeric))
+    num_numeric = nargin;     
+  endif
+
+  switch (num_numeric)
+    case 1
+      y = varargin{1};
+    case 2
+      if (isscalar (varargin{2})) 
+        y = varargin{1};
+        bv = varargin{2};
+      else
+        x = varargin{1};
+        y = varargin{2};
       endif
-    endif
-  else
-    print_usage ();
+    case 3
+      x = varargin{1};
+      y = varargin{2};
+      bv = varargin{3};
+    otherwise
+      print_usage ();
+  endswitch
+
+  if (! isreal (x) || ! isreal (y))
+    error ("area: X and Y must be real vectors or matrices");
   endif
-  ## Check for additional args.
-  if (nargin >= idx)
-    args = {varargin{idx:end}};
+  if (! isreal (bv) || ! isscalar (bv))
+    error ("area: LVL must be a real scalar");
   endif
+
   if (isvector (y))
     y = y(:);
   endif
@@ -103,10 +108,13 @@
     x = repmat (x(:), 1, columns (y));
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
-    htmp = __area__ (hax, x, y, bv, args{:});
+    htmp = __area__ (hax, x, y, bv, varargin{num_numeric+1:end});
   unwind_protect_cleanup
     if (! isempty (oldfig))
       set (0, "currentfigure", oldfig);
@@ -125,12 +133,16 @@
   y0 = zeros (1, rows (y));
   retval = [];
   for i = 1: columns (y);
+
+    lc = __next_line_color__ ();
+
+    ## Must occur after __next_line_color__ in order to work correctly.
     hg = hggroup ();
     retval = [retval; hg];
     args = __add_datasource__ ("area", hg, {"x", "y"}, varargin{:});
 
-    x1 = x(:, 1).';
-    y1 = y (:, i).';
+    x1 = x(:, 1)';
+    y1 = y(:, i)';
     addproperty ("xdata", hg, "data", x1);
     addproperty ("ydata", hg, "data", y1);
 
@@ -139,11 +151,11 @@
 
     if (i == 1)
       h = patch (ax, [x1(1), x1, fliplr(x1)], [bv, y1, bv*ones(1, length(y1))],
-                 __next_line_color__ (), "parent", hg);
+                     lc, "parent", hg);
     else
       y1 = y0 + y1;
       h = patch (ax, [x1(1), x1, fliplr(x1)], [y0(1), y1, fliplr(y0)],
-                 __next_line_color__ (), "parent", hg);
+                     lc, "parent", hg);
     endif
 
     y0 = y1;
@@ -152,14 +164,14 @@
     addlistener (hg, "basevalue", @move_baseline);
 
     addproperty ("edgecolor", hg, "patchedgecolor", get (h, "edgecolor"));
-    addproperty ("linewidth", hg, "patchlinewidth", get (h, "linewidth"));
+    addproperty ("facecolor", hg, "patchfacecolor", get (h, "facecolor"));
     addproperty ("linestyle", hg, "patchlinestyle", get (h, "linestyle"));
-    addproperty ("facecolor", hg, "patchfacecolor", get (h, "facecolor"));
+    addproperty ("linewidth", hg, "patchlinewidth", get (h, "linewidth"));
 
     addlistener (hg, "edgecolor", @update_props);
-    addlistener (hg, "linewidth", @update_props);
+    addlistener (hg, "facecolor", @update_props);
     addlistener (hg, "linestyle", @update_props);
-    addlistener (hg, "facecolor", @update_props);
+    addlistener (hg, "linewidth", @update_props);
 
     addproperty ("areagroup", hg, "data");
     set (retval, "areagroup", retval);
@@ -174,9 +186,9 @@
 function update_props (h, d)
   kids = get (h, "children");
   set (kids, "edgecolor", get (h, "edgecolor"),
-             "linewidth", get (h, "linewidth"),
+             "facecolor", get (h, "facecolor"),
              "linestyle", get (h, "linestyle"),
-             "facecolor", get (h, "facecolor"));
+             "linewidth", get (h, "linewidth"));
 endfunction
 
 function move_baseline (h, d)
@@ -226,16 +238,17 @@
 
 
 %!demo
-%! # Verify identity sin^2 + cos^2 = 1
+%! ## Verify identity sin^2 + cos^2 = 1
 %! clf;
 %! t = linspace (0, 2*pi, 100)';
 %! y = [sin(t).^2, cos(t).^2];
 %! area (t, y);
 %! axis tight
 %! legend ('sin^2', 'cos^2', 'location', 'NorthEastOutside');  
+%! title ('area() plot');
 
 %!demo
-%! # Show effects of setting BaseValue
+%! ## Show effects of setting BaseValue
 %! clf;
 %! x = [-2:0.1:2]';
 %! y = x.^2 - 1;
@@ -248,7 +261,20 @@
 %! title ({'Parabola y = x^2 -1';'BaseValue = -1'});
 
 %!demo
+%! clf;
 %! x = 0:10;
 %! y = rand (size (x));
 %! h = area (x, y);
 %! set (h, 'ydata', sort (get (h, 'ydata')))
+%! title ('area() plot of sorted data');
+
+%% Test input validation
+%!error area ()
+%!error area (1,2,3,4)
+%!error <X and Y must be real vectors or matrices> area ({1})
+%!error <X and Y must be real vectors or matrices> area (1+i)
+%!error <X and Y must be real vectors or matrices> area (1:2, {1, 2})
+%!error <X and Y must be real vectors or matrices> area (1:2, [1 1+i])
+%!error <LVL must be a real scalar> area (1, i)
+%!error <LVL must be a real scalar> area (1, 2, ones (2,2))
+
--- a/scripts/plot/axes.m
+++ b/scripts/plot/axes.m
@@ -79,3 +79,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/axis.m
+++ b/scripts/plot/axis.m
@@ -60,13 +60,13 @@
 ## The following options control the aspect ratio of the axes.
 ##
 ## @table @asis
-## @item "square"
+## @item @qcode{"square"}
 ## Force a square aspect ratio.
 ##
-## @item "equal"
+## @item @qcode{"equal"}
 ## Force x distance to equal y-distance.
 ##
-## @item "normal"
+## @item @qcode{"normal"}
 ## Restore default aspect ratio.
 ## @end table
 ##
@@ -74,39 +74,39 @@
 ## The following options control the way axis limits are interpreted.
 ##
 ## @table @asis
-## @item "auto"
+## @item @qcode{"auto"}
 ## Set the specified axes to have nice limits around the data
 ## or all if no axes are specified.
 ##
-## @item "manual"
+## @item @qcode{"manual"}
 ## Fix the current axes limits.
 ##
-## @item "tight"
+## @item @qcode{"tight"}
 ## Fix axes to the limits of the data.
 ##
-## @item "image"
-## Equivalent to "tight" and "equal".
+## @item @qcode{"image"}
+## Equivalent to @qcode{"tight"} and @qcode{"equal"}.
 ## @end table
 ##
 ## @noindent
 ## The following options affect the appearance of tic marks.
 ##
 ## @table @asis
-## @item "on"
+## @item @qcode{"on"}
 ## Turn tic marks and labels on for all axes.
 ##
-## @item "off"
+## @item @qcode{"off"}
 ## Turn tic marks off for all axes.
 ##
-## @item "tic[xyz]"
+## @item @qcode{"tic[xyz]"}
 ## Turn tic marks on for all axes, or turn them on for the
 ## specified axes and off for the remainder.
 ##
-## @item "label[xyz]"
+## @item @qcode{"label[xyz]"}
 ## Turn tic labels on for all axes, or turn them on for the
 ## specified axes and off for the remainder.
 ##
-## @item "nolabel"
+## @item @qcode{"nolabel"}
 ## Turn tic labels off for all axes.
 ## @end table
 ##
@@ -116,10 +116,10 @@
 ## The following options affect the direction of increasing values on the axes.
 ##
 ## @table @asis
-## @item "ij"
+## @item @qcode{"ij"}
 ## Reverse y-axis, so lower values are nearer the top.
 ##
-## @item "xy"
+## @item @qcode{"xy"}
 ## Restore y-axis, so higher values are nearer the top.
 ## @end table
 ##
@@ -135,7 +135,10 @@
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("axis", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     if (isempty (hax))
       hax = gca ();
@@ -330,15 +333,15 @@
     if (strcmp (scale, "log"))
       tmp = data;
       data = cellfun (@(x) x(x>0), tmp, "uniformoutput", false);
-      n = cellfun (@isempty, data);
+      n = cellfun ("isempty", data);
       data(n) = cellfun (@(x) x(x<0), tmp(n), "uniformoutput", false);
     endif
     data = cellfun (@(x) x(isfinite (x)), data, "uniformoutput", false);
     data = data(! cellfun ("isempty", data));
     if (! isempty (data))
-      lims_min = min (cellfun (@(x) min (x(:)), data(:)));
-      lims_max = max (cellfun (@(x) max (x(:)), data(:)));
-      lims = [lims_min, lims_max];
+      ## Change data from cell array of various sizes to a single column vector
+      data = cat (1, cellindexmat (data, ":"){:});
+      lims = [min(data), max(data)];
     else
       lims = [0, 1];
     endif
@@ -538,20 +541,20 @@
 %! x = -10:0.1:10;
 %! y = sin (x)./(1 + abs (x)) + 0.1*x - 0.4;
 %! plot (x, y);
-%! title ('no plot box');
 %! set (gca, 'xaxislocation', 'zero');
 %! set (gca, 'yaxislocation', 'zero');
 %! box off;
+%! title ({'no plot box', 'xaxislocation = zero, yaxislocation = zero'});
 
 %!demo
 %! clf;
 %! x = -10:0.1:10;
 %! y = sin (x)./(1+abs (x)) + 0.1*x - 0.4;
 %! plot (x, y);
-%! title ('no plot box');
 %! set (gca, 'xaxislocation', 'zero');
 %! set (gca, 'yaxislocation', 'left');
 %! box off;
+%! title ({'no plot box', 'xaxislocation = zero, yaxislocation = left'});
 
 %!demo
 %! clf;
@@ -562,26 +565,27 @@
 %! set (gca, 'xaxislocation', 'zero');
 %! set (gca, 'yaxislocation', 'right');
 %! box off;
+%! title ({'no plot box', 'xaxislocation = zero, yaxislocation = right'});
 
 %!demo
 %! clf;
 %! x = -10:0.1:10;
 %! y = sin (x)./(1+abs (x)) + 0.1*x - 0.4;
 %! plot (x, y);
-%! title ('no plot box');
 %! set (gca, 'xaxislocation', 'bottom');
 %! set (gca, 'yaxislocation', 'zero');
 %! box off;
+%! title ({'no plot box', 'xaxislocation = bottom, yaxislocation = zero'});
 
 %!demo
 %! clf;
 %! x = -10:0.1:10;
 %! y = sin (x)./(1+abs (x)) + 0.1*x - 0.4;
 %! plot (x, y);
-%! title ('no plot box');
 %! set (gca, 'xaxislocation', 'top');
 %! set (gca, 'yaxislocation', 'zero');
 %! box off;
+%! title ({'no plot box', 'xaxislocation = top, yaxislocation = zero'});
 
 %!test
 %! hf = figure ("visible", "off");
@@ -606,3 +610,16 @@
 %!   close (hf);
 %! end_unwind_protect
 
+## Test 'axis tight' with differently oriented, differently numbered data vecs
+## Bug #40036.
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   Z = peaks (linspace (-3, 3, 49), linspace (-2, 2, 29));
+%!   surf (Z);
+%!   axis tight;
+%!   assert (axis (), [1 49 1 29 min(Z(:)) max(Z(:))]);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/bar.m
+++ b/scripts/plot/bar.m
@@ -36,8 +36,8 @@
 ## If @var{y} is a matrix, then each column of @var{y} is taken to be a
 ## separate bar graph plotted on the same graph.  By default the columns
 ## are plotted side-by-side.  This behavior can be changed by the @var{style}
-## argument, which can take the values @code{"grouped"} (the default),
-## or @code{"stacked"}.
+## argument, which can take the values @qcode{"grouped"} (the default),
+## or @qcode{"stacked"}.
 ##
 ## Optional property/value pairs are passed directly to the underlying patch
 ## objects.
@@ -80,7 +80,7 @@
 ##
 ## @noindent
 ## will change the colors used for the bars.  The color of bars can also be set
-## manually using the "facecolor" property as shown below.
+## manually using the @qcode{"facecolor"} property as shown below.
 ##
 ## @example
 ## @group
@@ -107,6 +107,7 @@
 %! y = rand (11, 1);
 %! h = bar (y);
 %! set (h, 'ydata', sort (rand (11, 1)));
+%! title ('bar() graph')
 
 %!demo
 %! clf;
@@ -114,4 +115,5 @@
 %! set (h(1), 'facecolor', 'r')
 %! set (h(2), 'facecolor', 'g')
 %! set (h(3), 'facecolor', 'b')
+%! title ('bar() graph w/multiple bars')
 
--- a/scripts/plot/barh.m
+++ b/scripts/plot/barh.m
@@ -36,8 +36,8 @@
 ## If @var{y} is a matrix, then each column of @var{y} is taken to be a
 ## separate bar graph plotted on the same graph.  By default the columns
 ## are plotted side-by-side.  This behavior can be changed by the @var{style}
-## argument, which can take the values @code{"grouped"} (the default),
-## or @code{"stacked"}.
+## argument, which can take the values @qcode{"grouped"} (the default),
+## or @qcode{"stacked"}.
 ##
 ## Optional property/value pairs are passed directly to the underlying patch
 ## objects.
@@ -63,6 +63,7 @@
 %! clf;
 %! x = rand (10, 1);
 %! barh (x);
+%! title ('barh() graph')
 
 %!demo
 %! clf;
@@ -70,4 +71,5 @@
 %! set (h(1), 'facecolor', 'r')
 %! set (h(2), 'facecolor', 'g')
 %! set (h(3), 'facecolor', 'b')
+%! title ('barh() graph w/multiple bars')
 
--- a/scripts/plot/box.m
+++ b/scripts/plot/box.m
@@ -23,8 +23,8 @@
 ## @deftypefnx {Function File} {} box (@var{hax}, @dots{})
 ## Control display of the axis border.
 ##
-## The argument may be either "on" or "off".  If it is omitted, the current
-## box state is toggled.
+## The argument may be either @qcode{"on"} or @qcode{"off"}.  If it is
+## omitted, the current box state is toggled.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
@@ -68,3 +68,4 @@
   set (hax, "box", box_state);
 
 endfunction
+
--- a/scripts/plot/caxis.m
+++ b/scripts/plot/caxis.m
@@ -17,20 +17,23 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} caxis (@var{limits})
+## @deftypefn  {Function File} {} caxis ([cmin cmax])
 ## @deftypefnx {Function File} {} caxis ("auto")
 ## @deftypefnx {Function File} {} caxis ("manual")
 ## @deftypefnx {Function File} {} caxis (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {@var{limits} =} caxis ()
 ## Query or set color axis limits for plots.
 ##
-## The argument @var{limits} should be a 2-element vector specifying the
+## The limits argument should be a 2-element vector specifying the
 ## lower and upper limits to assign to the first and last value in the
-## colormap.  Values outside this range are clamped to the first and last
+## colormap.  Data values outside this range are clamped to the first and last
 ## colormap entries.
 ##
-## If @var{limits} is "auto", then automatic colormap scaling is applied,
-## whereas if @var{limits} is "manual" the colormap scaling is set to manual.
+## If the @qcode{"auto"} option is given then automatic colormap limits are
+## applied.  The automatic algorithm sets @var{cmin} to the minimum data value
+## and @var{cmax} to the maximum data value.  If @qcode{"manual"} is specified
+## then the @qcode{"climmode"} property is set to @qcode{"manual"} and the
+## numeric values in the @qcode{"clim"} property are used for limits.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
@@ -43,7 +46,10 @@
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("caxis", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     if (isempty (hax))
       hax = gca ();
--- a/scripts/plot/cla.m
+++ b/scripts/plot/cla.m
@@ -24,16 +24,16 @@
 ## Clear the current axes.
 ##
 ## @code{cla} operates by deleting child graphic objects with visible
-## handles (HandleVisibility = "on").
+## handles (HandleVisibility = @qcode{"on"}).
 ##
-## If the optional argument "reset" is specified, delete all child objects
-## including those with hidden handles and reset all axis properties to
-## their defaults.  However, the following properties are not reset:
+## If the optional argument @qcode{"reset"} is specified, delete all child
+## objects including those with hidden handles and reset all axis properties
+## to their defaults.  However, the following properties are not reset:
 ## Position, Units.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
-## @seealso{clf}
+## @seealso{clf, delete, reset}
 ## @end deftypefn
 
 ## Author: Ben Abbott <bpabbott@mac.com>
--- a/scripts/plot/clabel.m
+++ b/scripts/plot/clabel.m
@@ -35,19 +35,19 @@
 ## this plot rather than the one in the current axes returned by @code{gca}.
 ##
 ## By default, all contours are labeled.  However, the contours to label can be
-## specified by the vector @var{v}.  If the "manual" argument is given then
-## the contours to label can be selected with the mouse.
+## specified by the vector @var{v}.  If the @qcode{"manual"} argument is
+## given then the contours to label can be selected with the mouse.
 ##
 ## Additional property/value pairs that are valid properties of text objects
 ## can be given and are passed to the underlying text objects.  Moreover,
-## the contour group property "LabelSpacing" is available which determines
-## the spacing between labels on a contour to be specified.  The default is
-## 144 points, or 2 inches.
+## the contour group property @qcode{"LabelSpacing"} is available which
+## determines the spacing between labels on a contour to be specified.  The
+## default is 144 points, or 2 inches.
 ##
 ## The optional return value @var{h} is a vector of graphics handles to
-## the text objects representing each label.  
-## The "userdata" property of the text objects contains the numerical value of
-## the contour label.
+## the text objects representing each label.
+## The @qcode{"userdata"} property of the text objects contains the numerical
+## value of the contour label.
 ##
 ## An example of the use of @code{clabel} is
 ##
@@ -142,10 +142,12 @@
 %! colormap ('default');
 %! [c, h] = contour (peaks (), -4:6);
 %! clabel (c, h, -4:2:6, 'fontsize', 12);
+%! title ('clabel() labeling every other contour');
 
 %!demo
 %! clf;
 %! colormap ('default');
 %! [c, h] = contourf (peaks (), -7:6);
 %! clabel (c, h, -6:2:6, 'fontsize', 12);
+%! title ('clabel() labeling every other contour');
 
--- a/scripts/plot/clf.m
+++ b/scripts/plot/clf.m
@@ -25,19 +25,19 @@
 ## Clear the current figure window.
 ## 
 ## @code{clf} operates by deleting child graphics objects with visible
-## handles (HandleVisibility = "on").
+## handles (HandleVisibility = @qcode{"on"}).
 ##
-## If the optional argument "reset" is specified, delete all child objects
-## including those with hidden handles and reset all figure properties to
-## their defaults.  However, the following properties are not reset:
-## Position, Units, PaperPosition, PaperUnits.
+## If the optional argument @qcode{"reset"} is specified, delete all child
+## objects including those with hidden handles and reset all figure
+## properties to their defaults.  However, the following properties are not
+## reset: Position, Units, PaperPosition, PaperUnits.
 ##
 ## If the first argument @var{hfig} is a figure handle, then operate on
 ## this figure rather than the current figure returned by @code{gcf}.
 ## 
 ## The optional return value @var{h} is the graphics handle of the figure
 ## window that was cleared.
-## @seealso{cla, close, delete}
+## @seealso{cla, close, delete, reset}
 ## @end deftypefn
 
 ## Author: jwe
--- a/scripts/plot/close.m
+++ b/scripts/plot/close.m
@@ -23,24 +23,22 @@
 ## @deftypefnx {Command} {} close all hidden
 ## Close figure window(s).
 ##
-## @code{close} operates by calling the function specified by the
-## "closerequestfcn" property for each figure.  By default, the function
-## @code{closereq} is used.
-##
 ## When called with no arguments, close the current figure.  This is equivalent
 ## to @code{close (gcf)}.  If the input @var{h} is a graphic handle, or vector
 ## of graphics handles, then close each figure in @var{h}.
 ##
-## If the argument "all" is given then all figures with visible handles
-## (HandleVisibility = "on") are closed.
+## If the argument @qcode{"all"} is given then all figures with visible handles
+## (HandleVisibility = @qcode{"on"}) are closed.
+##
+## If the argument @qcode{"all hidden"} is given then all figures, including
+## hidden ones, are closed.
 ##
-## If the argument "all hidden" is given then all figures, including hidden
-## ones, are closed.
-##
-## Implementation Note: @code{close} calls a function to dispose of the figure.
-## It is possible that the function will delay or abort removing the figure.
-## To remove a figure without executing any callback functions use
-## @code{delete}.
+## Implementation Note: @code{close} operates by calling the function specified
+## by the @qcode{"closerequestfcn"} property for each figure.  By default, the
+## function @code{closereq} is used.  It is possible that the function invoked
+## will delay or abort removing the figure.  To remove a figure without
+## executing any callback functions use @code{delete}.  When writing a callback
+## function to close a window do not use @code{close} to avoid recursion.
 ##
 ## @seealso{closereq, delete}
 ## @end deftypefn
--- a/scripts/plot/closereq.m
+++ b/scripts/plot/closereq.m
@@ -19,6 +19,9 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} closereq ()
 ## Close the current figure and delete all graphics objects associated with it.
+##
+## By default, the @qcode{"closerequestfcn"} property of a new plot figure
+## points to this function.
 ## @seealso{close, delete}
 ## @end deftypefn
 
@@ -26,17 +29,18 @@
 
 function closereq ()
 
-  if (nargin == 0)
-    cf = gcbf ();
-    if (isempty (cf))
-      warning ("closereq: calling closereq from octave prompt is not supported, use 'close' instead");
-      cf = get (0, "currentfigure");
-    endif
-    if (! isempty (cf) && isfigure (cf))
-      delete (cf);
-    endif
-  else
+  if (nargin != 0)
     print_usage ();
   endif
 
+  cf = gcbf ();
+  if (isempty (cf))
+    warning ("closereq: calling closereq from octave prompt is not supported, use 'close' instead");
+    cf = get (0, "currentfigure");
+  endif
+  if (! isempty (cf) && isfigure (cf))
+    delete (cf);
+  endif
+
 endfunction
+
--- a/scripts/plot/colorbar.m
+++ b/scripts/plot/colorbar.m
@@ -35,36 +35,36 @@
 ## Valid values for @var{loc} are
 ##
 ## @table @asis
-## @item "EastOutside"
+## @item @qcode{"EastOutside"}
 ## Place the colorbar outside the plot to the right.  This is the default.
 ##
-## @item "East"
+## @item @qcode{"East"}
 ## Place the colorbar inside the plot to the right.
 ##
-## @item "WestOutside"
+## @item @qcode{"WestOutside"}
 ## Place the colorbar outside the plot to the left.
 ##
-## @item "West"
+## @item @qcode{"West"}
 ## Place the colorbar inside the plot to the left.
 ##
-## @item "NorthOutside"
+## @item @qcode{"NorthOutside"}
 ## Place the colorbar above the plot.
 ##
-## @item "North"
+## @item @qcode{"North"}
 ## Place the colorbar at the top of the plot.
 ##
-## @item "SouthOutside"
+## @item @qcode{"SouthOutside"}
 ## Place the colorbar under the plot.
 ##
-## @item "South"
+## @item @qcode{"South"}
 ## Place the colorbar at the bottom of the plot.
 ## @end table
 ##
 ## To remove a colorbar from a plot use any one of the following keywords for
-## the @var{delete_option}: "delete", "hide", "off".
+## the @var{delete_option}: @qcode{"delete"}, @qcode{"hide"}, @qcode{"off"}.
 ## 
-## If the argument "peer" is given, then the following argument is treated
-## as the axes handle in which to add the colorbar.  Alternatively, 
+## If the argument @qcode{"peer"} is given, then the following argument is
+## treated as the axes handle in which to add the colorbar.  Alternatively,
 ## If the first argument @var{hax} is an axes handle, then the colorbar is
 ## added to this axis, rather than the current axes returned by @code{gca}.
 ##
@@ -78,9 +78,9 @@
 ## colorbar object.
 ##
 ## Implementation Note: A colorbar is created as an additional axes to the
-## current figure with the "tag" property set to "colorbar".  The created
-## axes object has the extra property "location" which controls the positioning
-## of the colorbar.
+## current figure with the @qcode{"tag"} property set to @qcode{"colorbar"}. 
+## The created axes object has the extra property @qcode{"location"} which
+## controls the positioning of the colorbar.
 ## @seealso{colormap}
 ## @end deftypefn
 
@@ -299,13 +299,32 @@
     cmin = cext(1) + cdiff;
     cmax = cext(2) - cdiff;
 
+    hiax = get (hi, "parent");
     if (vert)
       set (hi, "ydata", [cmin, cmax]);
-      set (get (hi, "parent"), "ylim", cext);
+      set (hiax, "ylim", cext);
     else
       set (hi, "xdata", [cmin, cmax]);
-      set (get (hi, "parent"), "xlim", cext);
+      set (hiax, "xlim", cext);
     endif
+
+    ## FIXME: Setting xlim or ylim from within a listener callback
+    ##        causes the axis to change size rather than change limits.
+    ##        Workaround it by jiggling the position property which forces
+    ##        a redraw of the axis object.
+    ##
+    ## Debug Example:
+    ## Uncomment the line below.
+    ##   keyboard;
+    ## Now run the the following code.
+    ##   clf; colorbar (); contour (peaks ())
+    ## Once the keyboard command has been hit in the debugger try
+    ##   set (hiax, "ylim", [0 0.5]) 
+    pos = get (hiax, "position");
+    pos(1) += eps;
+    set (hiax, "position", pos);
+    pos(1) -= eps;
+    set (hiax, "position", pos);
   endif
 endfunction
 
@@ -329,7 +348,6 @@
 endfunction
 
 function update_colorbar_axis (h, d, cax, orig_props)
-
   if (isaxes (cax)
       && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off")))
     loc = get (cax, "location");
@@ -473,6 +491,7 @@
 %! n = 64; x = kron (1:n, ones (n,1)); x = abs (x - x.');
 %! imagesc (x);
 %! colorbar ();
+%! title ('colorbar() example');
 
 %!demo
 %! clf;
--- a/scripts/plot/comet.m
+++ b/scripts/plot/comet.m
@@ -57,21 +57,32 @@
     p = varargin{3};
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     limits = [min(x), max(x), min(y), max(y)];
     num = numel (y);
     dn = round (num/10);
-    for n = 1:(num+dn);
+
+    hl = plot (x(1), y(1), "color", "r", "marker", "none",
+               x(1), y(1), "color", "g", "marker", "none",
+               x(1), y(1), "color", "b", "marker", "o");
+    axis (limits);  # set manual limits to speed up plotting
+
+    for n = 2:(num+dn);
       m = n - dn;
       m = max ([m, 1]);
       k = min ([n, num]);
-      plot (x(1:m), y(1:m), "r", x(m:k), y(m:k), "g", x(k), y(k), "ob");
-      axis (limits);
+      set (hl(1), "xdata", x(1:m), "ydata", y(1:m));
+      set (hl(2), "xdata", x(m:k), "ydata", y(m:k));
+      set (hl(3), "xdata", x(k),   "ydata", y(k));
       drawnow ();
       pause (p);
     endfor
+
   unwind_protect_cleanup
     if (! isempty (oldfig))
       set (0, "currentfigure", oldfig);
@@ -83,8 +94,11 @@
 
 %!demo
 %! clf;
+%! title ('comet() animation');
+%! hold on;
 %! t = 0:.1:2*pi;
 %! x = cos (2*t) .* (cos (t).^2);
 %! y = sin (2*t) .* (sin (t).^2);
-%! comet (x, y);
+%! comet (x, y, 0.05);
+%! hold off;
 
--- a/scripts/plot/comet3.m
+++ b/scripts/plot/comet3.m
@@ -59,20 +59,28 @@
     p = varargin{4};
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     limits = [min(x), max(x), min(y), max(y), min(z), max(z)];
     num = numel (y);
     dn = round (num/10);
-    for n = 1:(num+dn);
+
+    hl = plot3 (x(1), y(1), z(1), "color", "r", "marker", "none",
+                x(1), y(1), z(1), "color", "g", "marker", "none",
+                x(1), y(1), z(1), "color", "b", "marker", "o");
+    axis (limits);  # set manual limits to speed up plotting
+
+    for n = 2:(num+dn);
       m = n - dn;
       m = max ([m, 1]);
       k = min ([n, num]);
-      htmp = plot3 (x(1:m), y(1:m), z(1:m), "r",
-                    x(m:k), y(m:k), z(m:k), "g",
-                    x(k), y(k), z(k), "ob");
-      axis (limits);
+      set (hl(1), "xdata", x(1:m), "ydata", y(1:m), "zdata", z(1:m));
+      set (hl(2), "xdata", x(m:k), "ydata", y(m:k), "zdata", z(m:k));
+      set (hl(3), "xdata", x(k)  , "ydata", y(k)  , "zdata", z(k));
       drawnow ();
       pause (p);
     endfor
@@ -87,6 +95,9 @@
 
 %!demo
 %! clf;
+%! title ('comet3() animation');
+%! view (3); hold on;
 %! t = 0:pi/20:5*pi;
-%! comet3 (cos (t), sin (t), t, 0.01);
+%! comet3 (cos (t), sin (t), t, 0.05);
+%! hold off;
 
--- a/scripts/plot/compass.m
+++ b/scripts/plot/compass.m
@@ -46,60 +46,65 @@
 ## @end group
 ## @end example
 ##
-## @seealso{polar, quiver, feather, plot}
+## @seealso{polar, feather, quiver, rose, plot}
 ## @end deftypefn
 
 function h = compass (varargin)
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("compass", varargin{:});
 
-  if (nargin == 0)
+  if (nargin == 0 || nargin > 3)
     print_usage ();
-  elseif (nargin == 1 || (nargin == 2 && ! isnumeric (varargin{2})))
-    ioff = 2;
+  endif
+
+  if (nargin == 1 || (nargin == 2 && ! isnumeric (varargin{2})))
     z = varargin{1}(:).';
     u = real (z);
     v = imag (z);
-  elseif (nargin > 1 && isnumeric (varargin{2}))
-    ioff = 3;
+    have_line_spec = (nargin == 2);
+  elseif (nargin >= 2 && isnumeric (varargin{2}))
     u = varargin{1}(:).';
     v = varargin{2}(:).';
+    have_line_spec = (nargin == 3);
+  else
+    print_usage ();
   endif
 
-  arrowsize = 0.25;
-  line_spec = "b-";
-  have_line_spec = false;
-  while (ioff <= nargin)
-    arg = varargin{ioff++};
-    if ((ischar (arg) || iscell (arg)) && ! have_line_spec)
-      [linespec, valid] = __pltopt__ ("compass", arg, false);
+  arrowsize = 0.20;
+  line_spec = "-b";
+
+  if (have_line_spec)
+    arg = varargin{end};
+    if (ischar (arg) || iscellstr (arg))
+      [~, valid] = __pltopt__ ("compass", arg, false);
       if (valid)
         line_spec = arg;
-        have_line_spec = true;
-        break;
       else
-        error ("compass: invalid linespec");
+        error ("compass: invalid linestyle STYLE");
       endif
     else
-      error ("compass: unrecognized argument");
+      error ("compass: invalid linestyle STYLE");
     endif
-  endwhile
+  endif
 
-  ## Matlab draws compass plots, with the arrow head as one continous
-  ## line, and each arrow separately. This is completely different than
-  ## quiver and quite ugly.
+  ## Matlab draws compass plots with the arrow head as one continous line,
+  ## and each arrow separately.  This is completely different than quiver
+  ## and quite ugly.
   n = length (u);
   xend = u;
   xtmp = u .* (1 - arrowsize);
   yend = v;
   ytmp = v .* (1 - arrowsize);
-  x = [zeros(1, n); xend; xtmp  - v * arrowsize / 3; xend; ...
+  x = [zeros(1, n); xend; xtmp - v * arrowsize / 3; xend; ...
        xtmp + v * arrowsize / 3];
-  y = [zeros(1, n); yend; ytmp  + u * arrowsize / 3; yend; ...
+  y = [zeros(1, n); yend; ytmp + u * arrowsize / 3; yend; ...
        ytmp - u * arrowsize / 3];
   [r, p] = cart2pol (x, y);
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     hlist = polar (r, p, line_spec);
--- a/scripts/plot/contour.m
+++ b/scripts/plot/contour.m
@@ -63,7 +63,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("contour", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     
@@ -87,6 +90,8 @@
 %! colormap ('default');
 %! [x, y, z] = peaks ();
 %! contour (x, y, z);
+%! title ('contour() plot of peaks() function');
+%! title ({'contour() plot (isolines of constant Z)'; 'Z = peaks()'});
 
 %!demo
 %! clf;
@@ -95,15 +100,7 @@
 %! [X, Y] = pol2cart (theta, r);
 %! Z = sin (2*theta) .* (1-r);
 %! contour (X, Y, abs (Z), 10);
-
-%!demo
-%! clf;
-%! colormap ('default');
-%! x = linspace (-2, 2);
-%! [x, y] = meshgrid (x);
-%! z = sqrt (x.^2 + y.^2) ./ (x.^2 + y.^2 + 1);
-%! contourf (x, y, z, [0.4, 0.4]);
-%! title ('The hole should be filled with the background color');
+%! title ({'contour() plot'; 'polar fcn: Z = sin (2*theta) * (1-r)'});
 
 %!test
 %! hf = figure ("visible", "off");
--- a/scripts/plot/contour3.m
+++ b/scripts/plot/contour3.m
@@ -52,9 +52,9 @@
 ## @example
 ## @group
 ## contour3 (peaks (19));
+## colormap cool;
 ## hold on;
-## surface (peaks (19), "facecolor", "none", "EdgeColor", "black");
-## colormap hot;
+## surf (peaks (19), "facecolor", "none", "edgecolor", "black");
 ## @end group
 ## @end example
 ##
@@ -65,7 +65,10 @@
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("contour3", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     
@@ -77,7 +80,7 @@
   end_unwind_protect
 
   if (! ishold ())
-    set (hax, "view", [-37.5, 30],
+    set (hax, "view", [-37.5, 30], "box", "off",
               "xgrid", "on", "ygrid", "on", "zgrid", "on");
   endif
 
@@ -91,12 +94,13 @@
 
 %!demo
 %! clf;
-%! contour3 (peaks (19));
+%! colormap (cool (64));
+%! surf (peaks (19), 'facecolor', 'none', 'edgecolor', [0.85 0.85 0.85]);
 %! hold on;
-%! surface (peaks (19), 'facecolor', 'none', 'edgecolor', 'black');
-%! colormap (hot (64));
+%! contour3 (peaks (19));
+%! hold off;
 %! axis tight;
 %! zlim auto;
-%! box off;
-%! hold off;
+%! view (315, 17);
+%! title ({'contour3 of peaks() function', 'gray surf() shows peaks function'});
 
--- a/scripts/plot/contourc.m
+++ b/scripts/plot/contourc.m
@@ -69,36 +69,36 @@
 
 ## Author: Shai Ayal <shaiay@users.sourceforge.net>
 
-function [cout, lev] = contourc (varargin)
+function [c, lev] = contourc (varargin)
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
 
   if (nargin == 1)
-    vn = 10;
     z = varargin{1};
-    [nr, nc] = size (z);
-    x = 1:nc;
-    y = 1:nr;
+    x = 1:columns (z);
+    y = 1:rows (z);
+    vn = 10;
   elseif (nargin == 2)
+    z = varargin{1};
+    x = 1:columns (z);
+    y = 1:rows (z);
     vn = varargin{2};
-    z = varargin{1};
-    [nr, nc] = size (z);
-    x = 1:nc;
-    y = 1:nr;
   elseif (nargin == 3)
-    vn = 10;
     x = varargin{1};
     y = varargin{2};
     z = varargin{3};
+    vn = 10;
   elseif (nargin == 4)
-    vn = varargin{4};
     x = varargin{1};
     y = varargin{2};
     z = varargin{3};
-  else
-    print_usage ();
+    vn = varargin{4};
   endif
 
-  if (!ismatrix (z) || isvector (z) || isscalar (z))
-    error ("contourc: Z argument must be a matrix");
+  if (! ismatrix (z) || ! ismatrix (x) || ! ismatrix (y))
+    error ("contourc: X, Y, and Z must be matrices");
   endif
 
   if (isscalar (vn))
@@ -108,43 +108,51 @@
   endif
 
   if (isvector (x) && isvector (y))
-    c = __contourc__ (x(:)', y(:)', z, vv);
+    cdat = __contourc__ (x(:)', y(:)', z, vv);
+  elseif (! any (bsxfun (@minus, x, x(1,:))(:))
+          && ! any (bsxfun (@minus, y, y(:,1))(:)))
+    ## x,y are uniform grid (such as from meshgrid)
+    cdat = __contourc__ (x(1,:), y(:,1)', z, vv);
   else
-    ## Indexes x,y for the purpose of __contourc__.
-    ii = 1:columns (z);
-    jj = 1:rows (z);
+    ## Data is sampled over non-uniform mesh.
+    ## Algorithm calculates contours for uniform grid
+    ## and then interpolates values back to the non-uniform mesh.
 
-    ## Now call __contourc__ for the real work...
-    c = __contourc__ (ii, jj, z, vv);
+    ## Uniform grid for __contourc__.
+    [nr, nc] = size (z);
+    ii = 1:nc;
+    jj = 1:nr;
 
-    ## Map the contour lines from index space (i,j) back
-    ## to the original grid (x,y)
+    cdat = __contourc__ (ii, jj, z, vv);
+
+    ## Map the contour lines from index space (i,j)
+    ## back to the original grid (x,y)
     i = 1;
 
-    while (i < columns (c))
-      clen = c(2, i);
-      ind = i + [1 : clen];
+    while (i < columns (cdat))
+      clen = cdat(2, i);
+      idx = i + (1:clen);
 
-      ci = c(1, ind);
-      cj = c(2,ind);
+      ci = cdat(1, idx);
+      cj = cdat(2, idx);
 
-      ## due to rounding errors some elements of ci and cj
-      ## can fall out of the range of ii and jj and interp2 would
-      ## return NA for those values.
+      ## Due to rounding errors, some elements of ci and cj
+      ## can fall out of the range of ii and jj and
+      ## interp2 would return NA for those values.
       ## The permitted range is enforced here:
 
-      ci = max (ci, 1); ci = min (ci, columns (z));
-      cj = max (cj, 1); cj = min (cj, rows (z));
+      ci = max (ci, 1); ci = min (ci, nc);
+      cj = max (cj, 1); cj = min (cj, nr);
 
-      c(1, ind) = interp2 (ii, jj, x, ci, cj);
-      c(2, ind) = interp2 (ii, jj, y, ci, cj);
+      cdat(1, idx) = interp2 (ii, jj, x, ci, cj);
+      cdat(2, idx) = interp2 (ii, jj, y, ci, cj);
 
-      i = i + clen + 1;
+      i += clen + 1;
     endwhile
   endif
 
   if (nargout > 0)
-    cout = c;
+    c = cdat;
     lev = vv;
   endif
 
@@ -155,9 +163,9 @@
 %! x = 0:2;
 %! y = x;
 %! z = x' * y;
-%! [c_actual, lev_actual]= contourc (x, y, z, 2:3);
-%! c_expected = [2, 1, 1, 2, 2, 3, 1.5, 2; 4, 2, 2, 1, 1, 2, 2, 1.5];
-%! lev_expected = [2 3];
-%! assert (c_actual, c_expected, eps);
-%! assert (lev_actual, lev_expected, eps);
+%! c_exp = [2, 1, 1, 2, 2, 3, 1.5, 2; 4, 2, 2, 1, 1, 2, 2, 1.5];
+%! lev_exp = [2 3];
+%! [c_obs, lev_obs] = contourc (x, y, z, 2:3);
+%! assert (c_obs, c_exp, eps);
+%! assert (lev_obs, lev_exp, eps);
 
--- a/scripts/plot/contourf.m
+++ b/scripts/plot/contourf.m
@@ -64,7 +64,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("contour", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     
@@ -89,6 +92,7 @@
 %! colormap ('default');
 %! [x, y, z] = peaks (50);
 %! contourf (x, y, z, -7:9);
+%! title ({'contourf() plot (filled contour lines)'; 'Z = peaks()'});
 
 %!demo
 %! clf;
@@ -97,4 +101,14 @@
 %! [X, Y] = pol2cart (theta, r);
 %! Z = sin (2*theta) .* (1-r);
 %! contourf (X, Y, abs (Z), 10);
+%! title ({'contourf() plot'; 'polar fcn: Z = sin (2*theta) * (1-r)'});
 
+%!demo
+%! clf;
+%! colormap ('default');
+%! x = linspace (-2, 2);
+%! [x, y] = meshgrid (x);
+%! z = sqrt (x.^2 + y.^2) ./ (x.^2 + y.^2 + 1);
+%! contourf (x, y, z, [0.4, 0.4]);
+%! title ('Hole should be filled with the background color');
+
--- a/scripts/plot/copyobj.m
+++ b/scripts/plot/copyobj.m
@@ -87,59 +87,67 @@
 %!demo
 %! ## FIXME: This demo fails occasionally for an obscure reason.
 %! ## It appears that there is something wrong with Octave code for patches.
-%! try
+%! unwind_protect
 %!   hdl = figure (1234);
 %!   clf;
 %!   subplot (2,2,1);
 %!   hold on;
 %!   contourf (rand (10, 10));
-%!   colorbar;
+%!   colorbar ();
 %!   subplot (2,2,2);
 %!   quiver (rand (10, 10), rand (10, 10));
 %!   subplot (2,2,3);
 %!   colormap (jet (64));
 %!   hold on;
-%!   sombrero;
+%!   sombrero ();
 %!   colorbar ('peer', gca, 'NorthOutside');
 %!   subplot (2,2,4);
 %!   imagesc (rand (30, 30));
 %!   text (15, 15, 'Rotated text', ...
-%!        'HorizontAlalignment', 'Center', 'Rotation', 30);
+%!         'HorizontAlalignment', 'Center', 'Rotation', 30);
 %!   hnew = copyobj (hdl);
-%! catch
-%!   close all
-%! end
+%! unwind_protect_cleanup
+%!   close all;
+%! end_unwind_protect
 
 %!testif HAVE_MAGICK
-%! h1 = figure ();
-%! set (h1, "visible", "off");
-%! x = 0:0.1:2*pi;
-%! y1 = sin (x);
-%! y2 = exp (x - 1);
-%! ax = plotyy (x,y1, x-1,y2, @plot, @semilogy);
-%! xlabel ("X");
-%! ylabel (ax(1), "Axis 1");
-%! ylabel (ax(2), "Axis 2");
-%! axes (ax(1));
-%! text (0.5, 0.5, "Left Axis", ...
-%!       "color", [0 0 1], "horizontalalignment", "center");
-%! axes (ax(2));
-%! text (4.5, 80, "Right Axis", ...
-%!       "color", [0 0.5 0], "horizontalalignment", "center");
-%! s1 = hdl2struct (h1);
-%! h2 = struct2hdl (s1);
-%! s2 = hdl2struct (h2);
-%! png1 = strcat (tmpnam (), ".png");
-%! png2 = strcat (tmpnam (), ".png");
+%! toolkit = graphics_toolkit ();
+%! graphics_toolkit ("gnuplot");
 %! unwind_protect
-%!   print (h1, png1);
-%!   [img1, map1, alpha1] = imread (png1);
-%!   print (h2, png2);
-%!   [img2, map2, alpha2] = imread (png2);
+%!   h1 = figure ("visible", "off");
+%!   x = 0:0.1:2*pi;
+%!   y1 = sin (x);
+%!   y2 = exp (x - 1);
+%!   ax = plotyy (x,y1, x-1,y2, @plot, @semilogy);
+%!   xlabel ("X");
+%!   ylabel (ax(1), "Axis 1");
+%!   ylabel (ax(2), "Axis 2");
+%!   axes (ax(1));
+%!   text (0.5, 0.5, "Left Axis", ...
+%!         "color", [0 0 1], "horizontalalignment", "center");
+%!   axes (ax(2));
+%!   text (4.5, 80, "Right Axis", ...
+%!         "color", [0 0.5 0], "horizontalalignment", "center");
+%!   s1 = hdl2struct (h1);
+%!   h2 = struct2hdl (s1);
+%!   s2 = hdl2struct (h2);
+%!   png1 = strcat (tmpnam (), ".png");
+%!   png2 = strcat (tmpnam (), ".png");
+%!   unwind_protect
+%!     print (h1, png1);
+%!     [img1, map1, alpha1] = imread (png1);
+%!     print (h2, png2);
+%!     [img2, map2, alpha2] = imread (png2);
+%!   unwind_protect_cleanup
+%!     unlink (png1);
+%!     unlink (png2);
+%!   end_unwind_protect
+%!   assert (img1, img2);
+%!   assert (map1, map2);
+%!   assert (alpha1, alpha2);
 %! unwind_protect_cleanup
-%!   unlink (png1);
-%!   unlink (png2);
+%!   close (h1);
+%!   close (h2);
+%!   graphics_toolkit (toolkit);
 %! end_unwind_protect
-%! assert (img1, img2);
-%! assert (map1, map2);
-%! assert (alpha1, alpha2);
+
--- a/scripts/plot/cylinder.m
+++ b/scripts/plot/cylinder.m
@@ -83,7 +83,10 @@
     yy = y;
     zz = z;
   else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
     
@@ -101,7 +104,7 @@
 %!demo
 %! clf;
 %! colormap ('default');
-%! [x, y, z] = cylinder (10:-1:0,50);
+%! [x, y, z] = cylinder (10:-1:0, 50);
 %! surf (x, y, z);
-%! title ('a cone');
+%! title ('cylinder() with linearly shrinking radius produces a cone');
 
--- a/scripts/plot/daspect.m
+++ b/scripts/plot/daspect.m
@@ -30,9 +30,9 @@
 ## @code{(daspect (@var{mode}))}
 ##
 ## Set the data aspect ratio mode of the current axes.  @var{mode} is
-## either "auto" or "manual".
+## either @qcode{"auto"} or @qcode{"manual"}.
 ## 
-## @code{daspect ("mode")}
+## @code{daspect (@qcode{"mode"})}
 ##
 ## Return the data aspect ratio mode of the current axes.
 ## 
@@ -46,51 +46,52 @@
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Created: 2010-01-26
 
-function varargout = daspect (varargin)
+function daratio = daspect (varargin)
 
-  hax = gca ();
-
+  ## Grab axes handle if present
   if (nargin > 0)
-    if (isscalar (varargin{1}) && ishandle (varargin{1}))
+    if (isscalar (varargin{1}) && isaxes (varargin{1}))
       hax = varargin{1};
       varargin = varargin(2:end);
+    else
+      hax = gca ();
     endif
+  else
+    hax = gca ();
   endif
-  if (numel (varargin) > 0)
-    if (numel (varargin) == 1)
-      if (ischar (varargin{1})
-          && any (strcmpi (varargin{1}, {"mode", "manual", "auto"})))
-        switch (varargin{1})
-        case "mode"
-          if (nargout < 2)
-            varargout{1} = get (hax, "dataaspectratiomode");
-            return
-          else
-            error ("daspect: only one output is allowed");
-          endif
-        case "manual"
-          set (hax, "dataaspectratiomode", "manual");
-        case "auto"
-          set (hax, "dataaspectratiomode", "auto");
-        endswitch
-      elseif (isreal (varargin{1}) && numel (varargin{1}) == 2)
-        set (hax, "dataaspectratio", [varargin{1}, 1]);
-      elseif (isreal (varargin{1}) && numel (varargin{1}) == 3)
-        set (hax, "dataaspectratio", varargin{1});
-      else
-        error ("daspect: invalid input");
-      endif
-    elseif (numel (varargin) > 1)
-      error ("daspect: too many inputs");
-    endif
-  elseif (nargout == 0)
+
+  nargin = numel (varargin);
+  if (nargin > 1)
     print_usage ();
   endif
 
-  if (nargout == 1)
-    varargout{1} = get (hax, "dataaspectratio");
-  elseif (nargout > 1)
-    error ("daspect: only one output is allowed");
+  if (nargin == 0)
+    daratio = get (hax, "dataaspectratio");
+  else
+    arg = varargin{1};
+    if (isreal (arg))
+      if (numel (arg) == 2)
+        set (hax, "dataaspectratio", [arg, 1]);
+      elseif (numel (arg) == 3)
+        set (hax, "dataaspectratio", arg);
+      else
+        error ("daspect: DATA_ASPECT_RATIO must be a 2 or 3 element vector");
+      endif
+    elseif (ischar (arg))
+      arg = tolower (arg);
+      switch (arg)
+        case "auto"
+          set (hax, "dataaspectratiomode", "auto");
+        case "manual"
+          set (hax, "dataaspectratiomode", "manual");
+        case "mode"
+          daratio = get (hax, "dataaspectratiomode");
+        otherwise
+          error ("daspect: Invalid mode <%s>", arg);
+      endswitch
+    else
+      print_usage ();
+    endif
   endif
 
 endfunction
@@ -138,3 +139,5 @@
 %! daspect ([2 1 1]);
 %! title ('square plot-box with axis limits [0, 4, -1, 1]');
 
+## FIXME: need some input validation tests
+
--- a/scripts/plot/diffuse.m
+++ b/scripts/plot/diffuse.m
@@ -56,3 +56,4 @@
   retval(retval < 0) = 0;
 
 endfunction
+
--- a/scripts/plot/ellipsoid.m
+++ b/scripts/plot/ellipsoid.m
@@ -74,7 +74,10 @@
     yy = y;
     zz = z;
   else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
     
@@ -92,4 +95,5 @@
 %!demo
 %! clf;
 %! ellipsoid (0, 0, 1, 2, 3, 4, 20);
+%! title ('ellipsoid()');
 
--- a/scripts/plot/errorbar.m
+++ b/scripts/plot/errorbar.m
@@ -130,7 +130,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("errorbar", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -153,12 +156,25 @@
 %! rand_1x11_data1 = [0.82712, 0.50325, 0.35613, 0.77089, 0.20474, 0.69160, 0.30858, 0.88225, 0.35187, 0.14168, 0.54270];
 %! rand_1x11_data2 = [0.506375, 0.330106, 0.017982, 0.859270, 0.140641, 0.327839, 0.275886, 0.162453, 0.807592, 0.318509, 0.921112];
 %! errorbar (0:10, rand_1x11_data1, 0.25*rand_1x11_data2);
+%! title ('errorbar() with Y errorbars');
 
 %!demo
 %! clf;
 %! rand_1x11_data3 = [0.423650, 0.142331, 0.213195, 0.129301, 0.975891, 0.012872, 0.635327, 0.338829, 0.764997, 0.401798, 0.551850];
 %! rand_1x11_data4 = [0.682566, 0.456342, 0.132390, 0.341292, 0.108633, 0.601553, 0.040455, 0.146665, 0.309187, 0.586291, 0.540149];
 %! errorbar (0:10, rand_1x11_data3, rand_1x11_data4, '>');
+%! title ('errorbar() with X errorbars');
+
+%!demo
+%! clf;
+%! x = 0:0.5:2*pi;
+%! err = x/30;
+%! y1 = sin (x);
+%! y2 = cos (x);
+%! errorbar (x, y1, err, '~', x, y2, err, '>');
+%! legend ("Y errbar", "X errbar");
+%! title ('errorbar() with 2 datasets');
+
 
 %!demo
 %! clf;
@@ -166,7 +182,9 @@
 %! err = x/30;
 %! y1 = sin (x);
 %! y2 = cos (x);
-%! hg = errorbar (x, y1, err, '~', x, y2, err, '>');
+%! errorbar (x, y1, err, err, '#r', x, y2, err, err, '#~');
+%! legend ("X errbox", "Y errbox");
+%! title ('errorbar() with error boxes');
 
 %!demo
 %! clf;
@@ -174,14 +192,29 @@
 %! err = x/30;
 %! y1 = sin (x);
 %! y2 = cos (x);
-%! hg = errorbar (x, y1, err, err, '#r', x, y2, err, err, '#~');
+%! errorbar (x, y1, err, err, err, err, '~>', ...
+%!           x, y2, err, err, err, err, '#~>-*');
+%! legend ("X-Y errbars", "X-Y errboxes");
+%! title ('errorbar() with X-Y errorbars and error boxes');
+
+## Invisible figure used for tests
+%!shared hf, hax
+%! hf = figure ("visible", "off");
+%! hax = axes;
 
-%!demo
-%! clf;
-%! x = 0:0.5:2*pi;
-%! err = x/30;
-%! y1 = sin (x);
-%! y2 = cos (x);
-%! hg = errorbar (x, y1, err, err, err, err, '~>', ...
-%!                x, y2, err, err, err, err, '#~>-*');
+%!error errorbar ()
+%!error errorbar (1)
+%!error <data argument 1 must be numeric> errorbar (hax, {1}, 2)
+%!error <data argument 2 must be numeric> errorbar (hax, 1, {2})
+%!error <size of argument 2 does not match others> errorbar (hax, 1, 1:2)
+%!error <size of argument 3 does not match others> errorbar (hax, 1, 2, 3:4)
+%!error <too many arguments to plot> errorbar (1,2,3,4,5,6,7)
 
+%!error <2 column errorplot is only valid for xerr> errorbar (1,2, "~>")
+%!error <6 columns only valid for xyerr and boxxy> errorbar (1,2,3,4,5,6, "~")
+%!error <error plot requires 2, 3, 4, or 6 arguments> errorbar (1,2,3,4,5)
+
+## Close figure used for testing
+%!test
+%! close (hf);
+
--- a/scripts/plot/ezmesh.m
+++ b/scripts/plot/ezmesh.m
@@ -41,8 +41,8 @@
 ##
 ## @var{n} is a scalar defining the number of points to use in each dimension.
 ##
-## If the argument "circ" is given, then the function is plotted over a disk
-## centered on the middle of the domain @var{dom}.
+## If the argument @qcode{"circ"} is given, then the function is plotted over
+## a disk centered on the middle of the domain @var{dom}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
--- a/scripts/plot/ezmeshc.m
+++ b/scripts/plot/ezmeshc.m
@@ -41,8 +41,8 @@
 ##
 ## @var{n} is a scalar defining the number of points to use in each dimension.
 ##
-## If the argument "circ" is given, then the function is plotted over a disk
-## centered on the middle of the domain @var{dom}.
+## If the argument @qcode{"circ"} is given, then the function is plotted over
+## a disk centered on the middle of the domain @var{dom}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
--- a/scripts/plot/ezplot.m
+++ b/scripts/plot/ezplot.m
@@ -87,22 +87,22 @@
 
 
 %!demo
-%! ## sinc function using function handle
+%! %% sinc function using function handle
 %! f = @(x) sin (pi*x) ./ (pi*x);
 %! ezplot (f);
 
 %!demo
-%! ## example of a function string and explicit limits
+%! %% example of a function string and explicit limits
 %! clf;
 %! ezplot ('1/x', [-2 2]);
 
 %!demo
-%! ## parameterized function example over -2*pi <= t <= +2*pi
+%! %% parameterized function example over -2*pi <= t <= +2*pi
 %! clf;
 %! ezplot (@cos, @sin);
 
 %!demo
-%! ## implicit function of 2 variables
+%! %% implicit function of 2 variables
 %! clf;
 %! ezplot (inline ('x^2 - y^2 - 1'));
 
--- a/scripts/plot/ezplot3.m
+++ b/scripts/plot/ezplot3.m
@@ -80,5 +80,5 @@
 %! fx = @(t) cos (t);
 %! fy = @(t) sin (t);
 %! fz = @(t) t;
-%! ezplot3 (fx, fy, fz, [0, 10*pi], 100, 'animate');
+%! ezplot3 (fx, fy, fz, [0, 5*pi], 100, 'animate');
 
--- a/scripts/plot/ezpolar.m
+++ b/scripts/plot/ezpolar.m
@@ -45,7 +45,7 @@
 ## Example:
 ##
 ## @example
-## ezpolar (@@(t) 1 + sin (t));
+## ezpolar (@@(t) sin (5/4 * t), [0, 8*pi]);
 ## @end example
 ##
 ## @seealso{polar, ezplot}
@@ -68,5 +68,5 @@
 
 %!demo
 %! clf;
-%! ezpolar (@(t) 1 + sin (t));
+%! ezpolar (@(t) sin (5/4 * t), [0, 8*pi]);
 
--- a/scripts/plot/ezsurf.m
+++ b/scripts/plot/ezsurf.m
@@ -41,8 +41,8 @@
 ##
 ## @var{n} is a scalar defining the number of points to use in each dimension.
 ##
-## If the argument "circ" is given, then the function is plotted over a disk
-## centered on the middle of the domain @var{dom}.
+## If the argument @qcode{"circ"} is given, then the function is plotted over
+## a disk centered on the middle of the domain @var{dom}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
--- a/scripts/plot/ezsurfc.m
+++ b/scripts/plot/ezsurfc.m
@@ -41,8 +41,8 @@
 ##
 ## @var{n} is a scalar defining the number of points to use in each dimension.
 ##
-## If the argument "circ" is given, then the function is plotted over a disk
-## centered on the middle of the domain @var{dom}.
+## If the argument @qcode{"circ"} is given, then the function is plotted over
+## a disk centered on the middle of the domain @var{dom}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
--- a/scripts/plot/feather.m
+++ b/scripts/plot/feather.m
@@ -20,7 +20,7 @@
 ## @deftypefn  {Function File} {} feather (@var{u}, @var{v})
 ## @deftypefnx {Function File} {} feather (@var{z})
 ## @deftypefnx {Function File} {} feather (@dots{}, @var{style})
-## @deftypefnx {Function File} {} feather (@var{h}, @dots{})
+## @deftypefnx {Function File} {} feather (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {@var{h} =} feather (@dots{})
 ##
 ## Plot the @code{(@var{u}, @var{v})} components of a vector field emanating
@@ -32,6 +32,9 @@
 ## The style to use for the plot can be defined with a line style @var{style}
 ## of the same format as the @code{plot} command.
 ##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## The optional return value @var{h} is a vector of graphics handles to the
 ## line objects representing the drawn vectors.
 ##
@@ -95,7 +98,10 @@
   y = [zeros(1, n); yend; ytmp  + u * arrowsize / 3; yend; ...
        ytmp - u * arrowsize / 3];
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     hlist = plot (x, y, line_spec, [1, n], [0, 0], line_spec);
@@ -116,4 +122,6 @@
 %! clf;
 %! phi = [0 : 15 : 360] * pi/180;
 %! feather (sin (phi), cos (phi));
+%! axis tight;
+%! title ('feather plot');
 
--- a/scripts/plot/fill.m
+++ b/scripts/plot/fill.m
@@ -72,7 +72,10 @@
   hlist = [];
   iargs = __find_patches__ (varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     old_nxtplt = get (hax, "nextplot");
@@ -91,7 +94,7 @@
       hlist(end + 1, 1) = htmp;
     endfor
 
-    if (strncmp (old_nxtplt, "replace", 7))
+    if (strcmp (old_nxtplt, "replace"))
       set (hax, "nextplot", old_nxtplt);
     endif
 
--- a/scripts/plot/findall.m
+++ b/scripts/plot/findall.m
@@ -30,7 +30,7 @@
 ## The return value @var{h} is a list of handles to the found graphic objects.
 ##
 ## @code{findall} performs the same search as @code{findobj}, but it
-## includes hidden objects ("HandleVisibility" = "off").  For full
+## includes hidden objects (HandleVisibility = @qcode{"off"}).  For full
 ## documentation, @pxref{XREFfindobj,,findobj}.
 ## @seealso{findobj, allchild, get, set}
 ## @end deftypefn
@@ -55,8 +55,8 @@
 %! hf = figure ("visible", "off");
 %! unwind_protect
 %!   h = findall (hf);
-%!   all_handles(1:13,1) = {"uimenu"};
-%!   all_handles(14) = {"figure"};
+%!   all_handles(1) = {"figure"};
+%!   all_handles(2:14,1) = {"uimenu"};
 %!   assert (get (h, "type"), all_handles);
 %! unwind_protect_cleanup
 %!   close (hf);
--- a/scripts/plot/findfigs.m
+++ b/scripts/plot/findfigs.m
@@ -79,3 +79,4 @@
     endif
   endfor
 endfunction
+
--- a/scripts/plot/findobj.m
+++ b/scripts/plot/findobj.m
@@ -43,30 +43,32 @@
 ## descendants, by passing a handle or set of handles @var{hlist} as the first
 ## argument.
 ##
-## The depth of the object hierarchy to search can be limited with the "-depth"
-## argument.  An example of searching only three generations of children is:
+## The depth of the object hierarchy to search can be limited with the
+## @qcode{"-depth"} argument.  An example of searching only three generations
+## of children is:
 ##
 ## @example
 ## findobj (@var{hlist}, "-depth", @var{d}, @var{prop_name}, @var{prop_value})
 ## @end example
 ##
 ## Specifying a depth @var{d} of 0, limits the search to the set of objects
-## passed in @var{hlist}.  A depth @var{d} of 0 is equivalent to the "flat"
-## argument.
+## passed in @var{hlist}.  A depth @var{d} of 0 is equivalent to the
+## @qcode{"flat"} argument.
 ##
 ## A specified logical operator may be applied to the pairs of @var{prop_name}
-## and @var{prop_value}.  The supported logical operators are: "-and", "-or",
-## "-xor", "-not".
+## and @var{prop_value}.  The supported logical operators are:
+## @qcode{"-and"}, @qcode{"-or"},
+## @qcode{"-xor"}, @qcode{"-not"}.
 ##
 ## Objects may also be matched by comparing a regular expression to the
 ## property values, where property values that match
 ## @code{regexp (@var{prop_value}, @var{pattern})} are returned.
 ##
 ## Finally, objects may be matched by property name only by using the
-## "-property" option.
+## @qcode{"-property"} option.
 ##
 ## Implementation Note: The search only includes objects with visible
-## handles ("HandleVisibility" = "on").  @xref{XREFfindall,,findall}, to
+## handles (HandleVisibility = @qcode{"on"}).  @xref{XREFfindall,,findall}, to
 ## search for all objects including hidden ones.
 ## @seealso{findall, allchild, get, set}
 ## @end deftypefn
@@ -178,7 +180,7 @@
         ## This is sloppy ... but works like Matlab.
         if (strcmpi (args{na}, "-not"))
           h = [];
-          return
+          return;
         endif
         na = na + 1;
       endif
@@ -188,7 +190,7 @@
   endwhile
 
   numpairs = np - 1;
-  if (~ isempty (logicaloperator))
+  if (! isempty (logicaloperator))
     logicaloperator = shift (logicaloperator, 1);
   endif
 
@@ -198,10 +200,10 @@
   while (numel (handles) && ! (idepth >= depth))
     children = [];
     for n = 1 : numel (handles)
-      children = union (children, get (handles(n), "children"));
+      children = [children; get(handles(n), "children")];
     endfor
     handles = children;
-    h = union (h, children);
+    h = [h; children];
     idepth = idepth + 1;
   endwhile
 
@@ -274,12 +276,12 @@
   h = h(:);
 endfunction
 
+
 %!test
 %! hf = figure ("visible", "off");
-%! clf (hf);
 %! unwind_protect
 %!   h = findobj (gca (), "-property", "foo");
-%!   assert (h, zeros (0, 1))
+%!   assert (isempty (h));
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
@@ -288,9 +290,9 @@
 %! hf = figure ("visible", "off");
 %! unwind_protect
 %!   h = plot (1:10);
-%!   set (h, "tag", "foobar")
+%!   set (h, "tag", "foobar");
 %!   g = findobj (gcf (), "tag", "foobar", "type", "line", "color", [0 0 1]);
-%!   assert (g, h)
+%!   assert (g, h);
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
@@ -311,103 +313,108 @@
 %!test
 %! hf = figure ("visible", "off");
 %! unwind_protect
-%!   subplot (2, 2, 1)
-%!   imagesc (rand (10))
-%!   subplot (2, 2, 2)
-%!   surf (peaks)
-%!   subplot (2, 2, 3)
-%!   contour (peaks)
-%!   subplot (2, 2, 4)
-%!   plot (peaks)
+%!   subplot (2,2,1);
+%!    imagesc (rand (10));
+%!   subplot (2,2,2);
+%!    surf (peaks);
+%!   subplot (2,2,3);
+%!    contour (peaks);
+%!   subplot (2,2,4);
+%!    plot (peaks);
 %!   h1 = findobj (gcf (), "-regexp", "Type", "image|surface|hggroup");
-%!   h2 = findobj (gcf (), "Type", "image", "-or", "Type", "surface", "-or", "Type", "hggroup");
+%!   h2 = findobj (gcf (), "Type", "image",
+%!                  "-or", "Type", "surface",
+%!                  "-or", "Type", "hggroup");
+%!   assert (h2, h1);
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
-%! assert (h2, h1)
 
 %!test
 %! toolkit = graphics_toolkit ("gnuplot");
 %! hf = figure ("visible", "off");
 %! unwind_protect
-%!   h1 = subplot (2, 2, 1);
-%!   h2 = subplot (2, 2, 2);
-%!   h3 = subplot (2, 2, 3);
-%!   h4 = subplot (2, 2, 4);
-%!   userdata = struct ("foo", "bar");
-%!   set (h3, "userdata", userdata);
-%!   h = findobj (hf, "userdata", userdata);
+%!   h1 = subplot (2,2,1);
+%!   h2 = subplot (2,2,2);
+%!   h3 = subplot (2,2,3, "userdata", struct ("foo", "bar"));
+%!   h4 = subplot (2,2,4);
+%!   h = findobj (hf, "userdata", struct ("foo", "bar"));
+%!   assert (h, h3);
 %! unwind_protect_cleanup
 %!   close (hf);
 %!   graphics_toolkit (toolkit);
 %! end_unwind_protect
-%! assert (h, h3)
 
 %!test
 %! toolkit = graphics_toolkit ("gnuplot");
 %! hf = figure ("visible", "off");
 %! unwind_protect
-%!   h1 = subplot (2, 2, 1);
-%!   set (h1, 'tag', '1')
-%!   h2 = subplot (2, 2, 2);
-%!   set (h2, 'tag', '2')
-%!   h3 = subplot (2, 2, 3);
-%!   set (h3, 'tag', '3')
-%!   h4 = subplot (2, 2, 4);
-%!   set (h4, 'tag', '4')
-%!   h = findobj (hf, 'type', 'axes', '-not', 'tag', '1');
+%!   h1 = subplot (2,2,1, "tag", "1");
+%!   h2 = subplot (2,2,2, "tag", "2");
+%!   h3 = subplot (2,2,3, "tag", "3");
+%!   h4 = subplot (2,2,4, "tag", "4");
+%!   h = findobj (hf, "type", "axes", "-not", "tag", "1");
+%!   assert (h, [h4; h3; h2])
 %! unwind_protect_cleanup
 %!   close (hf);
 %!   graphics_toolkit (toolkit);
 %! end_unwind_protect
-%! assert (h, [h2; h3; h4])
 
 %!test
 %! hf = figure ("visible", "off");
 %! unwind_protect
 %!   h1 = subplot (2, 2, 1);
-%!   set (h1, 'userdata', struct ('column', 1, 'row', 1));
+%!   set (h1, "userdata", struct ("column", 1, "row", 1));
 %!   h2 = subplot (2, 2, 2);
-%!   set (h2, 'userdata', struct ('column', 2, 'row', 1));
+%!   set (h2, "userdata", struct ("column", 2, "row", 1));
 %!   h3 = subplot (2, 2, 3);
-%!   set (h3, 'userdata', struct ('column', 1, 'row', 2));
+%!   set (h3, "userdata", struct ("column", 1, "row", 2));
 %!   h4 = subplot (2, 2, 4);
-%!   set (h4, 'userdata', struct ('column', 2, 'row', 2));
-%!   h = findobj (hf, 'type', 'axes', '-not', 'userdata', ...
-%!                struct ('column', 1, 'row', 1));
+%!   set (h4, "userdata", struct ("column", 2, "row", 2));
+%!   h = findobj (hf, "type", "axes",
+%!                "-not", "userdata", struct ("column", 1, "row", 1));
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
-%! assert (h, [h2; h3; h4])
+%! assert (h, [h4; h3; h2])
 
 %!test
 %! hf = figure ("visible", "off");
 %! unwind_protect
 %!   ha = axes ();
 %!   plot (1:10);
-%!   h = findobj (hf, 'type', 'figure', ...
-%!                '-or', 'parent', hf, ...
-%!                '-and', 'type', 'axes');
+%!   h = findobj (hf, "type", "figure",
+%!                "-or", "parent", hf,
+%!                "-and", "type", "axes");
 %! unwind_protect_cleanup
 %!   close (hf)
 %! end_unwind_protect
-%! assert (h, [ha; hf])
+%! assert (h, [hf; ha])
 
 %!test
 %! hf = figure ("visible", "off");
-%! set (hf, 'tag', 'foo');
 %! unwind_protect
-%!   h1 = subplot (2, 2, 1);
-%!   set (h1, 'tag', 'foo');
-%!   h2 = subplot (2, 2, 2);
-%!   set (h2, 'tag', 'bar');
-%!   h3 = subplot (2, 2, 3);
-%!   set (h3, 'tag', 'foo');
-%!   h4 = subplot (2, 2, 4);
-%!   set (h4, 'tag', 'bar')
-%!   h = findobj (hf, 'type', 'axes', '-xor', ...
-%!                'tag', 'foo');
+%!   set (hf, "tag", "foo");
+%!   h1 = subplot (2,2,1, "tag", "foo");
+%!   h2 = subplot (2,2,2, "tag", "bar");
+%!   h3 = subplot (2,2,3, "tag", "foo");
+%!   h4 = subplot (2,2,4, "tag", "bar");
+%!   h = findobj (hf, "type", "axes", "-xor", "tag", "foo");
+%!   assert (h, [hf; h4; h2]);
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
-%! assert (h, [h2; h4; hf])
+
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   hax1 = subplot (2,1,1);
+%!    hl1 = plot (rand (10,1));
+%!   hax2 = subplot (2,1,2);
+%!    hl2 = plot (rand (10,1));
+%!   hobj = findobj (hf);
+%!   assert (hobj, [hf; hax2; hax1; hl2; hl1]);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/fplot.m
+++ b/scripts/plot/fplot.m
@@ -40,6 +40,9 @@
 ## The @var{fmt} argument specifies the linestyle to be used by the plot
 ## command.
 ##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## With no output arguments the results are immediately plotted.  With two
 ## output arguments the 2-D plot data is returned.  The data can subsequently
 ## be plotted manually with @code{plot (@var{x}, @var{y})}.
@@ -61,12 +64,18 @@
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 
-function [X, Y] = fplot (fn, limits, varargin)
+function [X, Y] = fplot (varargin)
+
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("fplot", varargin{:});
 
   if (nargin < 2 || nargin > 5)
     print_usage ();
   endif
 
+  fn = varargin{1};
+  limits = varargin{2};
+  varargin = varargin(3:end);
+
   if (strcmp (typeinfo (fn), "inline function"))
     fn = vectorize (fn);
     nam = formula (fn);
@@ -154,15 +163,18 @@
     X = x;
     Y = y;
   else
-    plot (x, y, fmt);
-    axis (limits);
+    if (isempty (hax))
+      hax = gca ();
+    endif
+    plot (hax, x, y, fmt);
+    axis (hax, limits);
     if (isvector (y))
-      legend (nam);
+      legend (hax, nam);
     else
       for i = 1:columns (y)
         nams{i} = sprintf ("%s(:,%i)", nam, i);
       endfor
-      legend (nams{:});
+      legend (hax, nams{:});
     endif
   endif
 
@@ -172,16 +184,19 @@
 %!demo
 %! clf;
 %! fplot (@cos, [0, 2*pi]);
+%! title ('fplot() single function');
 
 %!demo
 %! clf;
 %! fplot ('[cos(x), sin(x)]', [0, 2*pi]);
+%! title ('fplot() multiple functions');
 
 %!demo
 %! clf;
-%! ## sinc function
+%! %% sinc function
 %! fh = @(x) sin (pi*x) ./ (pi*x);
 %! fplot (fh, [-5, 5]);
+%! title ('fplot() sinc function');
 
 %!test
 %! [x, y] = fplot ("[cos(x), sin(x)]", [0, 2*pi]);
--- a/scripts/plot/gcbo.m
+++ b/scripts/plot/gcbo.m
@@ -22,7 +22,7 @@
 ## Return a handle to the object whose callback is currently executing.
 ## 
 ## If no callback is executing, this function returns the empty matrix.  This
-## handle is obtained from the root object property "CallbackObject".
+## handle is obtained from the root object property @qcode{"CallbackObject"}.
 ##
 ## When called with a second output argument, return the handle of the figure
 ## containing the object whose callback is currently executing.  If no callback
--- a/scripts/plot/gcf.m
+++ b/scripts/plot/gcf.m
@@ -34,7 +34,7 @@
 ## @noindent
 ## plots a sine wave, finds the handle of the current figure, and then
 ## makes that figure invisible.  Setting the visible property of the
-## figure to "on" will cause it to be displayed again.
+## figure to @qcode{"on"} will cause it to be displayed again.
 ## @seealso{gca, gco, gcbf, gcbo, get, set}
 ## @end deftypefn
 
--- a/scripts/plot/gco.m
+++ b/scripts/plot/gco.m
@@ -23,7 +23,7 @@
 ## to the current object of the figure with handle @var{fig}.
 ##
 ## The current object of a figure is the object that was last clicked on.  It
-## is stored in the "CurrentObject" property of the target figure.
+## is stored in the @qcode{"CurrentObject"} property of the target figure.
 ##
 ## If the last mouse click did not occur on any child object of the figure,
 ## then the current object is the figure itself.
@@ -44,3 +44,4 @@
   h = get (get (0, "currentfigure"), "currentobject");
 
 endfunction
+
--- a/scripts/plot/gnuplot_binary.in
+++ b/scripts/plot/gnuplot_binary.in
@@ -22,7 +22,7 @@
 ## Query or set the name of the program invoked by the plot command
 ## when the graphics toolkit is set to "gnuplot".  Additional arguments to
 ## pass to the external plotting program may also be given.
-## The default value is @code{"gnuplot"} with no additional arguments.
+## The default value is @qcode{"gnuplot"} with no additional arguments.
 ## @xref{Installation}.
 ## @seealso{graphics_toolkit}
 ## @end deftypefn
--- a/scripts/plot/graphics_toolkit.m
+++ b/scripts/plot/graphics_toolkit.m
@@ -53,7 +53,7 @@
     if (all (isfigure (name)))
       hlist = name;
       retval = get (hlist, "__graphics_toolkit__");
-      return
+      return;
     elseif (! ischar (name))
       error ("graphics_toolkit: invalid graphics toolkit NAME");
     endif
--- a/scripts/plot/grid.m
+++ b/scripts/plot/grid.m
@@ -26,10 +26,10 @@
 ## @deftypefnx {Function File} {} grid (@var{hax}, @dots{})
 ## Control the display of plot grid lines.
 ##
-## The function state input may be either "on" or "off".
+## The function state input may be either @qcode{"on"} or @qcode{"off"}.
 ## If it is omitted, the current grid state is toggled.
 ##
-## When the first argument is "minor" all subsequent commands
+## When the first argument is @qcode{"minor"} all subsequent commands
 ## modify the minor grid rather than the major grid.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
--- a/scripts/plot/guidata.m
+++ b/scripts/plot/guidata.m
@@ -59,3 +59,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/guihandles.m
+++ b/scripts/plot/guihandles.m
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{hdata} =} guihandles (@var{handle})
 ## @deftypefnx {Function File} {@var{hdata} =} guihandles
-##   
+##
 ## @seealso{guidata, getappdata, setappdata}
 ## @end deftypefn
 
@@ -70,3 +70,4 @@
   endfor
 
 endfunction
+
--- a/scripts/plot/hdl2struct.m
+++ b/scripts/plot/hdl2struct.m
@@ -19,8 +19,8 @@
 ## Return a structure, @var{s}, whose fields describe the properties
 ## of the object, and its children, associated with the handle, @var{h}.
 ##
-## The fields of the structure @var{s} are "type", "handle", "properties",
-## "children", and "special".
+## The fields of the structure @var{s} are @qcode{"type"}, @qcode{"handle"},
+## @qcode{"properties"}, @qcode{"children"}, and @qcode{"special"}.
 ## @seealso{struct2hdl, findobj}
 ## @end deftypefn
 
@@ -169,3 +169,4 @@
 
 
 ## FIXME: need validation tests
+
--- a/scripts/plot/hggroup.m
+++ b/scripts/plot/hggroup.m
@@ -25,7 +25,7 @@
 ##
 ## If no parent is specified, the group is created in the current axes.
 ##
-## Multiple property-value pairs may be specified for the hggroup, but they
+## Multiple property/value pairs may be specified for the hggroup, but they
 ## must appear in pairs.
 ##
 ## The optional return value @var{h} is a graphics handle to the created
--- a/scripts/plot/hidden.m
+++ b/scripts/plot/hidden.m
@@ -24,7 +24,8 @@
 ## Control mesh hidden line removal.
 ##
 ## When called with no argument the hidden line removal state is toggled.
-## When called with one of the modes "on" or "off" the state is set accordingly.
+## When called with one of the modes @qcode{"on"} or @qcode{"off"} the state
+## is set accordingly.
 ##
 ## The optional output argument @var{mode} is the current state.
 ##
@@ -56,18 +57,18 @@
       if ((! ischar (fc) && is_white (fc))
           || (ischar (fc) && strcmp (fc, "none")))
         switch (mode)
-        case "on"
-          set (h, "facecolor", "w");
-        case "off"
-          set (h, "facecolor", "none");
-        case "toggle"
-          if (ischar (fc))
+          case "on"
             set (h, "facecolor", "w");
-            mode = "on";
-          else
+          case "off"
             set (h, "facecolor", "none");
-            mode = "off";
-          endif
+          case "toggle"
+            if (ischar (fc))
+              set (h, "facecolor", "w");
+              mode = "on";
+            else
+              set (h, "facecolor", "none");
+              mode = "off";
+            endif
         endswitch
       endif
     endif
--- a/scripts/plot/hist.m
+++ b/scripts/plot/hist.m
@@ -21,8 +21,9 @@
 ## @deftypefnx {Function File} {} hist (@var{y}, @var{x})
 ## @deftypefnx {Function File} {} hist (@var{y}, @var{nbins})
 ## @deftypefnx {Function File} {} hist (@var{y}, @var{x}, @var{norm})
+## @deftypefnx {Function File} {} hist (@dots{}, @var{prop}, @var{val}, @dots{})
+## @deftypefnx {Function File} {} hist (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {[@var{nn}, @var{xx}] =} hist (@dots{})
-## @deftypefnx {Function File} {[@dots{}] =} hist (@dots{}, @var{prop}, @var{val})
 ## Produce histogram counts or plots.
 ##
 ## With one vector input argument, @var{y}, plot a histogram of the values
@@ -41,12 +42,8 @@
 ##
 ## Extreme values are lumped in the first and last bins.
 ##
-## With two output arguments, produce the values @var{nn} and @var{xx} such
-## that @code{bar (@var{xx}, @var{nn})} will plot the histogram.
-##
 ## The histogram's appearance may be modified by specifying property/value
-## pairs, @var{prop} and @var{val} pairs.  For example the face and edge
-## color may be modified.
+## pairs.  For example the face and edge color may be modified.
 ##
 ## @example
 ## @group
@@ -55,7 +52,7 @@
 ## @end example
 ##
 ## @noindent
-## The histograms colors also depend upon the colormap.
+## The histogram's colors also depend upon the current colormap.
 ##
 ## @example
 ## @group
@@ -64,16 +61,27 @@
 ## @end group
 ## @end example
 ##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
+## With two output arguments, produce the values @var{nn} and @var{xx} such
+## that @code{bar (@var{xx}, @var{nn})} will plot the histogram.
+##
 ## @seealso{histc, bar, pie, rose}
 ## @end deftypefn
 
 ## Author: jwe
 
-function [nn, xx] = hist (y, varargin)
+function [nn, xx] = hist (varargin)
+
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("hist", varargin{:});
 
   if (nargin < 1)
     print_usage ();
   endif
+  
+  y = varargin{1};
+  varargin = varargin(2:end);
 
   arg_is_vector = isvector (y);
 
@@ -159,10 +167,15 @@
       nn = freq;
       xx = x;
     endif
-  elseif (columns (freq) != 1)
-    bar (x, freq, 0.8, varargin{iarg:end});
   else
-    bar (x, freq, 1.0, varargin{iarg:end});
+    if (isempty (hax))
+      hax = gca ();
+    endif
+    if (columns (freq) != 1)
+      bar (hax, x, freq, 0.8, varargin{iarg:end});
+    else
+      bar (hax, x, freq, 1.0, varargin{iarg:end});
+    endif
   endif
 
 endfunction
--- a/scripts/plot/hold.m
+++ b/scripts/plot/hold.m
@@ -22,9 +22,9 @@
 ## @deftypefnx {Command} {} hold off
 ## @deftypefnx {Command} {} hold all
 ## @deftypefnx {Function File} {} hold (@var{hax}, @dots{})
-## Toggle or set the "hold" state of the plotting engine which determines
-## whether new graphic objects are added to the plot or replace the existing
-## objects.
+## Toggle or set the @qcode{"hold"} state of the plotting engine which
+## determines whether new graphic objects are added to the plot or replace
+## the existing objects.
 ##
 ## @table @code
 ## @item hold on
@@ -54,7 +54,7 @@
 function hold (varargin)
 
   if (nargin > 0 && isscalar (varargin{1}) && isaxes (varargin{1}))
-    hax = vargin{1};
+    hax = varargin{1};
     varargin(1) = [];
     nargs = numel (varargin);
     ## FIXME: Should this be ancestor (hax, "parent")?
@@ -119,11 +119,12 @@
 %!demo
 %! clf;
 %! A = rand (100);
-%! [X, Y] = find (A > 0.9);
+%! [X, Y] = find (A > 0.95);
 %! imshow (A);
 %! hold on;
 %! plot (X, Y, 'o');
 %! hold off;
+%! title ('hold with image and plot');
 
 %!demo
 %! clf;
--- a/scripts/plot/ishghandle.m
+++ b/scripts/plot/ishghandle.m
@@ -52,7 +52,7 @@
 %!   t = text;
 %!   assert (ishghandle (t));
 %!   assert (! ishghandle (-t));
-%!   i = image;
+%!   i = image ([1]);
 %!   assert (ishghandle (i));
 %!   assert (! ishghandle (-i));
 %!   hg = hggroup;
--- a/scripts/plot/isonormals.m
+++ b/scripts/plot/isonormals.m
@@ -38,7 +38,7 @@
 ## vertices data @var{v} a patch handle @var{p} can be passed to this
 ## function.
 ##
-## If given the string input argument "negate" as last input argument
+## If given the string input argument @qcode{"negate"} as last input argument
 ## then compute the reverse vector normals of an isosurface geometry.
 ##
 ## If no output argument is given then directly redraw the patch that is
--- a/scripts/plot/isosurface.m
+++ b/scripts/plot/isosurface.m
@@ -38,9 +38,9 @@
 ## which are three--dimensional arrays with the same size than @var{val}
 ## then the volume data is taken at those given points.
 ##
-## The string input argument "noshare" is only for compatibility and
+## The string input argument @qcode{"noshare"} is only for compatibility and
 ## has no effect.  If given the string input argument
-## "verbose" then print messages to the command line interface about the
+## @qcode{"verbose"} then print messages to the command line interface about the
 ## current progress.
 ##
 ## If called with the input argument @var{col} which is a
@@ -195,6 +195,7 @@
 %! [x,y,z] = meshgrid (-2:0.5:2, -2:0.5:2, -2:0.5:2);
 %! v = x.^2 + y.^2 + z.^2;
 %! isosurface (x, y, z, v, 1);
+%! title ('isosurface of a sphere');
 
 %!shared x, y, z, val
 %! [x, y, z]  = meshgrid (0:1, 0:1, 0:1); # Points for single
--- a/scripts/plot/legend.m
+++ b/scripts/plot/legend.m
@@ -43,69 +43,48 @@
 ## as follows:
 ##
 ## @multitable @columnfractions 0.06 0.14 0.80
-##
-## @headitem @tab @var{pos} @tab
-##   location of the legend
-##
-## @item @tab north @tab
-##   center top
-##
-## @item @tab south @tab
-##   center bottom
-##
-## @item @tab east @tab
-##   right center
-##
-## @item @tab west @tab
-##   left center
-##
-## @item @tab northeast @tab
-##   right top (default)
-##
-## @item @tab northwest @tab
-##   left top
-##
-## @item @tab southeast @tab
-##   right bottom
-##
-## @item @tab southwest @tab
-##   left bottom
-##
+## @headitem @tab pos @tab location of the legend
+## @item @tab north @tab center top
+## @item @tab south @tab center bottom
+## @item @tab east @tab right center
+## @item @tab west @tab left center
+## @item @tab northeast @tab right top (default)
+## @item @tab northwest @tab left top
+## @item @tab southeast @tab right bottom
+## @item @tab southwest @tab left bottom
 ## @item
-##
-## @item @tab outside @tab
-##   can be appended to any location string
+## @item @tab outside @tab can be appended to any location string
 ## @end multitable
 ##
 ## The optional parameter @var{orient} determines if the key elements
 ## are placed vertically or horizontally.  The allowed values are
-## "vertical" (default) or "horizontal".
+## @qcode{"vertical"} (default) or @qcode{"horizontal"}.
 ##
 ## The following customizations are available using @var{option}:
 ##
 ## @table @asis
-## @item "show"
+## @item @qcode{"show"}
 ##   Show legend on the plot
 ##
-## @item "hide"
+## @item @qcode{"hide"}
 ##   Hide legend on the plot
 ##
-## @item "toggle"
-##   Toggles between "hide" and "show"
+## @item @qcode{"toggle"}
+##   Toggles between @qcode{"hide"} and @qcode{"show"}
 ##
-## @item "boxon"
+## @item @qcode{"boxon"}
 ##   Show a box around legend
 ##
-## @item "boxoff"
+## @item @qcode{"boxoff"}
 ##   Hide the box around legend
 ##
-## @item "left"
+## @item @qcode{"left"}
 ##   Place label text to the left of the keys
 ##
-## @item "right"
+## @item @qcode{"right"}
 ##   Place label text to the right of the keys
 ##
-## @item "off"
+## @item @qcode{"off"}
 ##   Delete the legend object
 ## @end table
 ##
@@ -128,11 +107,12 @@
 ## The legend label text is either provided in the call to @code{legend} or
 ## is taken from the DisplayName property of graphics objects.  If no
 ## labels or DisplayNames are available, then the label text is simply
-## "data1", "data2", @dots{}, @nospell{"dataN"}.
+## @qcode{"data1"}, @qcode{"data2"}, @dots{}, @nospell{@qcode{"dataN"}}.
 ##
 ## Implementation Note: A legend is implemented as an additional axes object
-## of the current figure with the "tag" set to "legend".  Properties of the
-## legend object may be manipulated directly by using @code{set}.
+## of the current figure with the @qcode{"tag"} set to @qcode{"legend"}. 
+## Properties of the legend object may be manipulated directly by using
+## @code{set}.
 ## @end deftypefn
 
 function [hlegend2, hobjects2, hplot2, text_strings2] = legend (varargin)
@@ -595,7 +575,7 @@
       linelength = 15;
 
       ## Create the axis first
-      ## FIXME hlegend should inherit properties from "ca"
+      ## FIXME: hlegend should inherit properties from "ca"
       curaxes = get (fig, "currentaxes");
       unwind_protect
         ud = ancestor (hplots, "axes");
@@ -706,7 +686,7 @@
             gnuplot_offset = unmodified_axes_position(1) ...
                          - unmodified_axes_outerposition(1);
           endif
-          ## FIXME - the "fontsize" is added to match the behavior of OpenGL.
+          ## FIXME: The "fontsize" is added to match the behavior of OpenGL.
           ## This implies that a change in fontsize should trigger a listener
           ## to update the legend.  The "2" was determined using a long legend
           ## key in the absence of any subplots.
@@ -828,56 +808,56 @@
         for k = 1 : numel (hplots)
           hobjects = [hobjects, texthandle(k)];
           switch (get (hplots(k), "type"))
-          case "line"
-            color = get (hplots(k), "color");
-            style = get (hplots(k), "linestyle");
-            if (! strcmp (style, "none"))
-              l1 = line ("xdata", ([xoffset, xoffset + linelength] + xk * xstep) / lpos(3),
-                         "ydata", [1, 1] .* (lpos(4) - yoffset - yk * ystep) / lpos(4),
-                         "color", color, "linestyle", style, "marker", "none",
-                         "userdata", hplots (k));
-              hobjects = [hobjects, l1];
-            endif
-            marker = get (hplots(k), "marker");
-            if (! strcmp (marker, "none"))
-              l1 = line ("xdata", (xoffset + 0.5 * linelength  + xk * xstep) / lpos(3),
-                         "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4),
-                         "color", color, "linestyle", "none", "marker", marker,
-                         "markeredgecolor", get (hplots (k), "markeredgecolor"),
-                         "markerfacecolor", get (hplots (k), "markerfacecolor"),
-                         "markersize", get (hplots (k), "markersize"),
-                         "userdata", hplots (k));
-              hobjects = [hobjects, l1];
-            endif
+            case "line"
+              color = get (hplots(k), "color");
+              style = get (hplots(k), "linestyle");
+              if (! strcmp (style, "none"))
+                l1 = line ("xdata", ([xoffset, xoffset + linelength] + xk * xstep) / lpos(3),
+                           "ydata", [1, 1] .* (lpos(4) - yoffset - yk * ystep) / lpos(4),
+                           "color", color, "linestyle", style, "marker", "none",
+                           "userdata", hplots (k));
+                hobjects = [hobjects, l1];
+              endif
+              marker = get (hplots(k), "marker");
+              if (! strcmp (marker, "none"))
+                l1 = line ("xdata", (xoffset + 0.5 * linelength  + xk * xstep) / lpos(3),
+                           "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4),
+                           "color", color, "linestyle", "none", "marker", marker,
+                           "markeredgecolor", get (hplots (k), "markeredgecolor"),
+                           "markerfacecolor", get (hplots (k), "markerfacecolor"),
+                           "markersize", get (hplots (k), "markersize"),
+                           "userdata", hplots (k));
+                hobjects = [hobjects, l1];
+              endif
 
-            addlistener (hplots(k), "color",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "linestyle",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "marker",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "markeredgecolor",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "markerfacecolor",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "markersize",
-                         {@updateline, hlegend, linelength});
-            addlistener (hplots(k), "displayname",
-                         {@updateline, hlegend, linelength});
-          case "patch"
-            facecolor = get (hplots(k), "facecolor");
-            edgecolor = get (hplots(k), "edgecolor");
-            cdata = get (hplots(k), "cdata");
-            if (! strcmp (facecolor, "none") || ! strcmp (edgecolor, "none"))
-              p1 = patch ("xdata", ([0, linelength, linelength, 0] +
-                                   xoffset + xk * xstep) / lpos(3),
-                         "ydata", (lpos(4) - yoffset -
-                                   [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4),
-                         "facecolor", facecolor, "edgecolor", edgecolor,
-                         "cdata", cdata, "userdata", hplots(k));
-              hobjects = [hobjects, p1];
-            endif
-          case "surface"
+              addlistener (hplots(k), "color",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "linestyle",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "marker",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "markeredgecolor",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "markerfacecolor",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "markersize",
+                           {@updateline, hlegend, linelength});
+              addlistener (hplots(k), "displayname",
+                           {@updateline, hlegend, linelength});
+            case "patch"
+              facecolor = get (hplots(k), "facecolor");
+              edgecolor = get (hplots(k), "edgecolor");
+              cdata = get (hplots(k), "cdata");
+              if (! strcmp (facecolor, "none") || ! strcmp (edgecolor, "none"))
+                p1 = patch ("xdata", ([0, linelength, linelength, 0] +
+                                     xoffset + xk * xstep) / lpos(3),
+                           "ydata", (lpos(4) - yoffset -
+                                     [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4),
+                           "facecolor", facecolor, "edgecolor", edgecolor,
+                           "cdata", cdata, "userdata", hplots(k));
+                hobjects = [hobjects, p1];
+              endif
+            case "surface"
           endswitch
           set (texthandle (k), "position", [(txoffset + xk * xstep) / lpos(3), ...
                                             (lpos(4) - yoffset - yk * ystep) / lpos(4)]);
@@ -986,7 +966,7 @@
           addlistener (hlegend, "orientation", @updatelegend);
           addlistener (hlegend, "string", @updatelegend);
           addlistener (hlegend, "textposition", @updatelegend);
-          ## TODO - need to add listeners for tighinset and position
+          ## FIXME: need to add listeners for tighinset and position
           ##        addlistener (ca, "tightinset", @update????);
           ##        addlistener (ca, "position", @update????);
         endif
@@ -1018,12 +998,12 @@
       units = get (hax, "units");
       set (hax, "units", "points");
       switch (get (hax, "activepositionproperty"))
-      case "position"
-        set (hax, "outerposition", outerposition);
-        set (hax, "position", position);
-      case "outerposition"
-        set (hax, "position", position);
-        set (hax, "outerposition", outerposition);
+        case "position"
+          set (hax, "outerposition", outerposition);
+          set (hax, "position", position);
+        case "outerposition"
+          set (hax, "position", position);
+          set (hax, "outerposition", outerposition);
       endswitch
       set (hax, "units", units);
       h = legend (hax, hplots, get (h, "string"));
@@ -1337,7 +1317,7 @@
 %! rand_2x3_data1 = [0.341447, 0.171220, 0.284370; 0.039773, 0.731725, 0.779382];
 %! bar (rand_2x3_data1);
 %! ylim ([0 1.0]);
-%! title ('legend() works for bar graphs (hgobjects)');
+%! title ('legend() works for bar graphs (hggroups)');
 %! legend ({'1st Bar', '2nd Bar', '3rd Bar'});
 
 %!demo
@@ -1345,7 +1325,7 @@
 %! rand_2x3_data2 = [0.44804, 0.84368, 0.23012; 0.72311, 0.58335, 0.90531];
 %! bar (rand_2x3_data2);
 %! ylim ([0 1.2]);
-%! title ('legend() works for bar graphs (hgobjects)');
+%! title ('legend() works for bar graphs (hggroups)');
 %! legend ('1st Bar', '2nd Bar', '3rd Bar');
 %! legend right;
 
@@ -1553,6 +1533,12 @@
 %!  legend ({'12345678901234567890'}, 'location', 'southwestoutside');
 %!  legend (option);
 
+%!demo % bug 39697
+%! clf;
+%! plot (1:10);
+%! legend ("Legend Text");
+%! title ({"Multi-line", "titles", "are a", "problem"});
+
 %!test
 %! toolkit = graphics_toolkit ("gnuplot");
 %! h = figure ("visible", "off");
--- a/scripts/plot/linkprop.m
+++ b/scripts/plot/linkprop.m
@@ -99,3 +99,4 @@
     warning ("linkprop: can not remove linked properties");
   endif
 endfunction
+
--- a/scripts/plot/loglog.m
+++ b/scripts/plot/loglog.m
@@ -45,7 +45,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -75,6 +78,7 @@
 %! x = sort ((t .* (1 + rand (size (t)))) .^ 2);
 %! y = (t .* (1 + rand (size (t)))) .^ 2;
 %! loglog (x, y);
+%! title ({'loglog() plot', 'Both axes are logarithmic'});
 
 %!demo
 %! clf;
--- a/scripts/plot/loglogerr.m
+++ b/scripts/plot/loglogerr.m
@@ -34,6 +34,9 @@
 ## with errors in the @var{y}-scale defined by @var{ey} and the plot
 ## format defined by @var{fmt}.  @xref{XREFerrorbar,,errorbar}, for available
 ## formats and additional information.
+##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
 ## @seealso{errorbar, semilogxerr, semilogyerr}
 ## @end deftypefn
 
@@ -45,7 +48,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("loglogerr", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -76,4 +82,6 @@
 %! eyl = 0.5*rand (size (y)) .* y;
 %! loglogerr (x, y, eyl, eyu, '#~x-');
 %! xlim (x([1, end]));
+%! title ({'loglogerr(): loglog() plot with errorbars', ...
+%!         'Both axes are logarithmic'});
 
--- a/scripts/plot/mesh.m
+++ b/scripts/plot/mesh.m
@@ -32,9 +32,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The color of the mesh is computed by linearly scaling the @var{Z} values
+## The color of the mesh is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -63,7 +63,10 @@
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("mesh", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -92,10 +95,21 @@
 %! clf;
 %! x = logspace (0,1,11);
 %! z = x'*x;
+%! mesh (x, x, z);
+%! xlabel 'X-axis';
+%! ylabel 'Y-axis';
+%! zlabel 'Z-axis';
+%! title ('mesh() with color proportional to height');
+
+%!demo
+%! clf;
+%! x = logspace (0,1,11);
+%! z = x'*x;
 %! mesh (x, x, z, z.^2);
 %! xlabel 'X-axis';
 %! ylabel 'Y-axis';
 %! zlabel 'linear scale';
+%! title ('mesh() with color proportional to Z^2');
 
 %!demo
 %! clf;
@@ -106,6 +120,7 @@
 %! xlabel 'X-axis';
 %! ylabel 'Y-axis';
 %! zlabel 'log scale';
+%! title ({'mesh() with color proportional to Z^2', 'Z-axis is log scale'});
 %! if (strcmp (get (gcf, '__graphics_toolkit__'), 'gnuplot'))
 %!   title ({'Gnuplot: mesh color is wrong', 'This is a Gnuplot bug'});
 %! endif
--- a/scripts/plot/meshc.m
+++ b/scripts/plot/meshc.m
@@ -32,9 +32,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ## 
-## The color of the mesh is computed by linearly scaling the @var{Z} values
+## The color of the mesh is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -61,7 +61,10 @@
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("meshc", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -74,7 +77,8 @@
     set (htmp, "edgecolor", "flat");
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
-                "xgrid", "on", "ygrid", "on", "zgrid", "on");
+                "xgrid", "on", "ygrid", "on", "zgrid", "on",
+                "xlimmode", "manual", "ylimmode", "manual");
     endif
 
     drawnow ();
@@ -96,3 +100,12 @@
 
 endfunction
 
+
+%!demo
+%! clf;
+%! colormap ('default');
+%! [X, Y] = meshgrid (linspace (-3, 3, 40));
+%! Z = sqrt (abs (X .* Y)) ./ (1 + X.^2 + Y.^2);
+%! meshc (X, Y, Z);
+%! title ('meshc() combines mesh/contour plots');
+
--- a/scripts/plot/meshz.m
+++ b/scripts/plot/meshz.m
@@ -32,9 +32,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The color of the mesh is computed by linearly scaling the @var{Z} values
+## The color of the mesh is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -64,8 +64,10 @@
   ## Find where property/value pairs start
   charidx = find (cellfun ("isclass", varargin, "char"), 1);
 
+  have_c = false;
   if (isempty (charidx))
     if (nargin == 2 || nargin == 4) 
+      have_c = true;
       charidx = nargin;   # bundle C matrix back into varargin 
     else
       charidx = nargin + 1;
@@ -100,7 +102,19 @@
        zref .* ones(rows(z), 1), z, zref .* ones(rows(z), 1);
        zref .* ones(1, columns(z) + 2)];
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  if (have_c)
+    c = varargin{charidx};
+    cref = min (c(isfinite (c)));
+    c = [cref .* ones(1, columns(c) + 2);
+         cref .* ones(rows(c), 1), c, cref .* ones(rows(c), 1);
+         cref .* ones(1, columns(c) + 2)];
+    varargin(charidx) = c;
+  endif
+    
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     htmp = mesh (x, y, z, varargin{charidx:end});
@@ -116,3 +130,33 @@
 
 endfunction
 
+
+%!demo
+%! clf;
+%! colormap ('default');
+%! Z = peaks ();
+%! meshz (Z);
+%! title ('meshz() plot of peaks() function');
+
+%!demo
+%! clf;
+%! colormap ('default');
+%! Z = peaks ();
+%! subplot (1,2,1)
+%!  mesh (Z);
+%!  daspect ([2.5, 2.5, 1]);
+%!  title ('mesh() plot');
+%! subplot (1,2,2)
+%!  meshz (Z);
+%!  daspect ([2.5, 2.5, 1]);
+%!  title ('meshz() plot');
+
+%!demo
+%! clf;
+%! colormap ('default');
+%! [X,Y,Z] = peaks ();
+%! [fx, fy] = gradient (Z); 
+%! C = sqrt (fx.^2 + fy.^2);
+%! meshz (X,Y,Z,C);
+%! title ('meshz() plot with color determined by gradient');
+
--- a/scripts/plot/module.mk
+++ b/scripts/plot/module.mk
@@ -13,7 +13,6 @@
   plot/private/__axis_label__.m \
   plot/private/__bar__.m \
   plot/private/__clabel__.m \
-  plot/private/__color_str_rgb__.m \
   plot/private/__contour__.m \
   plot/private/__default_plot_options__.m \
   plot/private/__errcomm__.m \
--- a/scripts/plot/newplot.m
+++ b/scripts/plot/newplot.m
@@ -25,43 +25,41 @@
 ##
 ## This function is called at the beginning of all high-level plotting
 ## functions.  It is not normally required in user programs.  @code{newplot}
-## queries the "NextPlot" field of the current figure and axis to determine
-## what to do.
+## queries the @qcode{"NextPlot"} field of the current figure and axis to
+## determine what to do.
 ##
 ## @multitable @columnfractions .25 .75
 ## @headitem Figure NextPlot @tab Action
-## @item "new" @tab Create a new figure and make it the current figure.
+## @item @qcode{"new"} @tab Create a new figure and make it the current figure.
 ##
-## @item "add" (default) @tab Add new graphic objects to the current figure.
+## @item @qcode{"add"} (default) @tab Add new graphic objects to the current figure.
 ##
-## @item "replacechildren" @tab Delete child objects whose HandleVisibility is
-## set to "on".  Set NextPlot property to "add".  This typically clears a
-## figure, but leaves in place hidden objects such as menubars.  This is
-## equivalent to @code{clf}.
+## @item @qcode{"replacechildren"} @tab Delete child objects whose HandleVisibility is
+## set to @qcode{"on"}.  Set NextPlot property to @qcode{"add"}.  This
+## typically clears a figure, but leaves in place hidden objects such as
+## menubars.  This is equivalent to @code{clf}.
 ##
-## @item "replace" @tab Delete all child objects of the figure and reset all
-## figure properties to their defaults.  However, the following four properties
-## are not reset: Position, Units, PaperPosition, PaperUnits.  This is
-## equivalent to @code{clf reset}.
-##
-## @end multitable    
+## @item @qcode{"replace"} @tab Delete all child objects of the figure and
+## reset all figure properties to their defaults.  However, the following
+## four properties are not reset: Position, Units, PaperPosition, PaperUnits.
+##  This is equivalent to @code{clf reset}.
+## @end multitable
 ##
 ## @multitable @columnfractions .25 .75
 ## @headitem Axis NextPlot @tab Action
-## @item "add" @tab Add new graphic objects to the current axes.  This is
+## @item @qcode{"add"} @tab Add new graphic objects to the current axes.  This is
 ## equivalent to @code{hold on}.
 ##
-## @item "replacechildren" @tab Delete child objects whose HandleVisibility is
-## set to "on", but leave axis properties unmodified.  This typically clears a
-## plot, but preserves special settings such as log scaling for axes.
-## This is equivalent to @code{cla}.
+## @item @qcode{"replacechildren"} @tab Delete child objects whose HandleVisibility is
+## set to @qcode{"on"}, but leave axis properties unmodified.  This typically
+## clears a plot, but preserves special settings such as log scaling for
+## axes.  This is equivalent to @code{cla}.
 ##
-## @item "replace" (default) @tab Delete all child objects of the axis and
-## reset all axis properties to their defaults.  However, the following
-## properties are not reset: Position, Units.  This is equivalent to
-## @code{cla reset}.
-##
-## @end multitable    
+## @item @qcode{"replace"} (default) @tab Delete all child objects of the
+## axis and reset all axis properties to their defaults.  However, the
+## following properties are not reset: Position, Units.  This is equivalent
+## to @code{cla reset}.
+## @end multitable
 ##
 ## If the optional input @var{hfig} or @var{hax} is given then prepare the
 ## specified figure or axes rather than the current figure and axes.
--- a/scripts/plot/orient.m
+++ b/scripts/plot/orient.m
@@ -23,9 +23,10 @@
 ## @deftypefnx {Function File} {@var{orientation} =} orient (@var{hfig})
 ## Query or set the default print orientation.
 ##
-## Valid values for @var{orientation} are "landscape", "portrait", and "tall".
+## Valid values for @var{orientation} are @qcode{"landscape"},
+## @qcode{"portrait"}, and @qcode{"tall"}.
 ##
-## The "tall" option sets the orientation to portait and fills
+## The @qcode{"tall"} option sets the orientation to portrait and fills
 ## the page with the plot, while leaving a 0.25 inch border.
 ##
 ## When called with no arguments, return the default print orientation.
@@ -82,37 +83,44 @@
 %! papersize = [8.5, 11];
 %! paperposition = [0.25, 2.5, 8, 6];
 %! tallpaperposition = [0.25, 0.25, (papersize-0.5)];
-%! hfig = figure ();
-%! set (hfig, "visible", "off");
+%! hfig = figure ("visible", "off");
 %! set (hfig, "paperorientation", "portrait");
 %! set (hfig, "papersize", papersize);
 %! set (hfig, "paperposition", paperposition);
+
 %!test
 %! orient portrait;
 %! assert (orient, "portrait")   # default
 %! assert (get (hfig, "papersize"), papersize);
 %! assert (get (hfig, "paperposition"), paperposition);
+
 %!test
 %! orient landscape;
 %! assert (orient,"landscape")   # change to landscape
 %! assert (get (hfig, "papersize"), papersize([2, 1]));
 %! assert (get (hfig, "paperposition"), paperposition([2, 1, 4, 3]));
+
 %!test
 %! orient portrait   # change back to portrait
 %! assert (orient, "portrait");
 %! assert (get (hfig, "papersize"), papersize);
 %! assert (get (hfig, "paperposition"), paperposition);
+
 %!test
 %! orient landscape;
 %! orient tall;
 %! assert (orient, "portrait");
 %! assert (get (hfig, "papersize"), papersize);
 %! assert (get (hfig, "paperposition"), tallpaperposition);
+
 %!fail ("orient ('nobody')", "unknown ORIENTATION")
+
 %!test
 %! orient portrait   # errors don't change the state
 %! assert (orient, "portrait");
 %! assert (get (hfig, "papersize"), papersize);
 %! assert (get (hfig, "paperposition"), tallpaperposition);
+
+%!test
 %! close (hfig);
 
--- a/scripts/plot/pareto.m
+++ b/scripts/plot/pareto.m
@@ -25,7 +25,7 @@
 ## Draw a Pareto chart.
 ##
 ## A Pareto chart is a bar graph that arranges information in such a way
-## that priorities for process improvement can be established;  It organizes
+## that priorities for process improvement can be established; It organizes
 ## and displays information to show the relative importance of data.  The chart
 ## is similar to the histogram or bar chart, except that the bars are arranged
 ## in decreasing magnitude from left to right along the x-axis.
@@ -64,43 +64,50 @@
 
 function h = pareto (varargin)
 
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("pareto", varargin{:});
+
   if (nargin != 1 && nargin != 2)
     print_usage ();
   endif
 
-  x = varargin {1}(:).';
+  x = varargin{1}(:).';
   if (nargin == 2)
-    y = varargin {2}(:).';
+    y = varargin{2}(:).';
     if (! iscell (y))
       if (ischar (y))
         y = cellstr (y);
       else
-        y = cellfun ("num2str", num2cell (y), "uniformoutput", false);
+        y = cellstr (num2str (y(:)));
       endif
     endif
   else
-    y = cellfun ("int2str", num2cell (1 : numel (x)),
-                 "uniformoutput", false);
+    y = cellstr (int2str ([1:numel(x)]'));
   endif
 
   [x, idx] = sort (x, "descend");
-  y = y (idx);
+  y = y(idx);
   cdf = cumsum (x);
   maxcdf = max (cdf);
   cdf = cdf ./ maxcdf;
   cdf95 = cdf - 0.95;
   idx95 = find (sign (cdf95(1:end-1)) != sign (cdf95(2:end)))(1);
 
-  [ax, hbar, hline] = plotyy (1 : idx95, x (1 : idx95),
-                              1 : length (cdf), 100 .* cdf,
-                              @bar, @plot);
+  if (isempty (hax))
+    [ax, hbar, hline] = plotyy (1 : idx95, x (1 : idx95),
+                                1 : length (cdf), 100 .* cdf,
+                                @bar, @plot);
+  else
+    [ax, hbar, hline] = plotyy (hax, 1 : idx95, x (1 : idx95),
+                                     1 : length (cdf), 100 .* cdf,
+                                     @bar, @plot);
+  endif
 
   axis (ax(1), [1 - 0.6, idx95 + 0.6, 0, maxcdf]);
   axis (ax(2), [1 - 0.6, idx95 + 0.6, 0, 100]);
   set (ax(2), "ytick", [0, 20, 40, 60, 80, 100],
-       "yticklabel", {"0%", "20%", "40%", "60%", "80%", "100%"});
-  set (ax(1), "xtick", 1 : idx95, "xticklabel", y (1: idx95));
-  set (ax(2), "xtick", 1 : idx95, "xticklabel", y (1: idx95));
+              "yticklabel", {"0%", "20%", "40%", "60%", "80%", "100%"});
+  set (ax(1), "xtick", 1:idx95, "xticklabel", y(1:idx95));
+  set (ax(2), "xtick", 1:idx95, "xticklabel", y(1:idx95));
 
   if (nargout > 0)
     h = [hbar; hline];
--- a/scripts/plot/patch.m
+++ b/scripts/plot/patch.m
@@ -34,7 +34,7 @@
 ## input is present then 3-D patches will be created.
 ##
 ## The color argument @var{c} can take many forms.  To create polygons
-## which all share a single color use a string value (e.g., "r" for
+## which all share a single color use a string value (e.g., @qcode{"r"} for
 ## red), a scalar value which is scaled by @code{caxis} and indexed into the
 ## current colormap, or a 3-element RGB vector with the precise TrueColor.
 ##
@@ -45,16 +45,19 @@
 ##
 ## Instead of specifying polygons by matrices @var{x} and @var{y}, it is
 ## possible to present a unique list of vertices and then a list of polygon
-## faces created from those vertices.  In this case the "Vertices" matrix will
-## be an @nospell{Nx2} (2-D patch) or @nospell{Nx3} (3-D path).  The
-## @nospell{MxN} "Faces" matrix describes M polygons having N vertices---each
-## row describes a single polygon and each column entry is an index into the
-## "Vertices" matrix to identify a vertex.  The patch object can be created by
-## directly passing the property/value pairs "Vertices"/@var{verts},
-## "Faces"/@var{faces} as inputs.
+## faces created from those vertices.  In this case the
+## @qcode{"Vertices"} matrix will be an @nospell{Nx2} (2-D patch) or
+## @nospell{Nx3} (3-D path).  The @nospell{MxN} @qcode{"Faces"} matrix
+## describes M polygons having N vertices---each row describes a
+## single polygon and each column entry is an index into the
+## @qcode{"Vertices"} matrix to identify a vertex.  The patch object
+## can be created by directly passing the property/value pairs
+## @qcode{"Vertices"}/@var{verts}, @qcode{"Faces"}/@var{faces} as
+## inputs.
 ##
 ## A third input form is to create a structure @var{fv} with the fields
-## "vertices", "faces", and optionally "facevertexcdata".
+## @qcode{"vertices"}, @qcode{"faces"}, and optionally
+## @qcode{"facevertexcdata"}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
@@ -64,9 +67,8 @@
 ##
 ## Implementation Note: Patches are highly configurable objects.  To truly
 ## customize them requires setting patch properties directly.  Useful patch
-## properties are: "cdata", "edgecolor", "facecolor", "faces",
-## "facevertexcdata",
-##
+## properties are: @qcode{"cdata"}, @qcode{"edgecolor"},
+## @qcode{"facecolor"}, @qcode{"faces"}, @qcode{"facevertexcdata"}.
 ## @seealso{fill, get, set}
 ## @end deftypefn
 
@@ -222,7 +224,6 @@
 %! x = [ 0 0; 1 1; 1 0 ];
 %! y = [ 0 0; 0 1; 1 1 ];
 %! p = patch (x, y, 'facecolor', 'b');
-%! title ('Two blue triangles');
 %! set (p, 'cdatamapping', 'direct', 'facecolor', 'flat', 'cdata', [1 32]);
 %! title ('Direct mapping of colors: Light-Green UL and Blue LR triangles');
 
--- a/scripts/plot/pbaspect.m
+++ b/scripts/plot/pbaspect.m
@@ -23,14 +23,15 @@
 ## @deftypefnx {Function File} {@var{plot_box_aspect_ratio_mode} =} pbaspect ("mode")
 ## @deftypefnx {Function File} {} pbaspect (@var{hax}, @dots{})
 ##
-## Query or set the plot box aspect ratio of the current axes.  The aspect
-## ratio is a normalized 3-element vector representing the rendered lengths of
-## the x, y, and z axes.
+## Query or set the plot box aspect ratio of the current axes.
+##
+## The aspect ratio is a normalized 3-element vector representing the rendered
+## lengths of the x, y, and z axes.
 ##
 ## @code{pbaspect(@var{mode})}
 ##
 ## Set the plot box aspect ratio mode of the current axes.  @var{mode} is
-## either "auto" or "manual".
+## either @qcode{"auto"} or @qcode{"manual"}.
 ##
 ## @code{pbaspect ("mode")}
 ##
@@ -46,51 +47,52 @@
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Created: 2010-01-26
 
-function varargout = pbaspect (varargin)
+function pbratio = pbaspect (varargin)
 
-  hax = gca ();
-
+  ## Grab axes handle if present
   if (nargin > 0)
-    if (isscalar (varargin{1}) && ishandle (varargin{1}))
+    if (isscalar (varargin{1}) && isaxes (varargin{1}))
       hax = varargin{1};
       varargin = varargin(2:end);
+    else
+      hax = gca ();
     endif
+  else
+    hax = gca ();
   endif
-  if (numel (varargin) > 0)
-    if (numel (varargin) == 1)
-      if (ischar (varargin{1})
-          && any (strcmpi (varargin{1}, {"mode", "manual", "auto"})))
-        switch (varargin{1})
-        case "mode"
-          if (nargout < 2)
-            varargout{1} = get (hax, "plotboxaspectratiomode");
-            return
-          else
-            error ("pbaspect: only one output is allowed");
-          endif
-        case "manual"
-          set (hax, "plotboxaspectratiomode", "manual");
-        case "auto"
-          set (hax, "plotboxaspectratiomode", "auto");
-        endswitch
-      elseif (isreal (varargin{1}) && numel (varargin{1}) == 2)
-        set (hax, "plotboxaspectratio", [varargin{1}, 1]);
-      elseif (isreal (varargin{1}) && numel (varargin{1}) == 3)
-        set (hax, "plotboxaspectratio", varargin{1});
-      else
-        error ("pbaspect: invalid input");
-      endif
-    elseif (numel (varargin) > 1)
-      error ("pbaspect: too many inputs");
-    endif
-  elseif (nargout == 0)
+
+  nargin = numel (varargin);
+  if (nargin > 1)
     print_usage ();
   endif
 
-  if (nargout == 1)
-    varargout{1} = get (hax, "plotboxaspectratio");
-  elseif (nargout > 1)
-    error ("pbaspect: only one output is allowed");
+  if (nargin == 0)
+    pbratio = get (hax, "plotboxaspectratio");
+  else
+    arg = varargin{1};
+    if (isreal (arg))
+      if (numel (arg) == 2)
+        set (hax, "plotboxaspectratio", [arg, 1]);
+      elseif (numel (arg) == 3)
+        set (hax, "plotboxaspectratio", arg);
+      else
+        error ("pbaspect: PLOT_BOX_ASPECT_RATIO must be a 2 or 3 element vector");
+      endif
+    elseif (ischar (arg))
+      arg = tolower (arg);
+      switch (arg)
+        case "auto"
+          set (hax, "plotboxaspectratiomode", "auto");
+        case "manual"
+          set (hax, "plotboxaspectratiomode", "manual");
+        case "mode"
+          pbratio = get (hax, "plotboxaspectratiomode");
+        otherwise
+          error ("pbaspect: Invalid mode <%s>", arg);
+      endswitch
+    else
+      print_usage ();
+    endif
   endif
 
 endfunction
--- a/scripts/plot/pcolor.m
+++ b/scripts/plot/pcolor.m
@@ -42,8 +42,8 @@
 ## @code{shading} modifies an attribute determining the manner by which the
 ## face color of each cell is interpolated from the values of @var{c},
 ## and the visibility of the cells' edges.  By default the attribute is
-## "faceted", which renders a single color for each cell's face with the edge
-## visible.
+## @qcode{"faceted"}, which renders a single color for each cell's face with
+## the edge visible.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
@@ -74,7 +74,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     htmp = surface (x, y, z, c);
@@ -103,6 +106,7 @@
 %! colormap ('default');
 %! Z = peaks ();
 %! pcolor (Z);
+%! title ('pcolor() of peaks with facet shading');
 
 %!demo
 %! clf;
@@ -112,4 +116,5 @@
 %! pcolor (X,Y,Fx+Fy);
 %! shading interp;
 %! axis tight;
+%! title ('pcolor() of peaks with interp shading');
 
--- a/scripts/plot/peaks.m
+++ b/scripts/plot/peaks.m
@@ -92,3 +92,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/pie.m
+++ b/scripts/plot/pie.m
@@ -60,7 +60,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     htmp = __pie__ ("pie", hax, varargin{:});
@@ -81,17 +84,20 @@
 %! clf;
 %! pie ([3, 2, 1], [0, 0, 1]);
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
+%! title ('pie() with exploded wedge');
 
 %!demo
 %! clf;
 %! pie ([3, 2, 1], [0, 0, 1], {'Cheddar', 'Swiss', 'Camembert'});
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
 %! axis ([-2,2,-2,2]);
+%! title ('pie() with labels');
+
 
 %!demo
 %! clf;
 %! pie ([0.17, 0.34, 0.41], {'Cheddar', 'Swiss', 'Camembert'});
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
 %! axis ([-2,2,-2,2]);
-%! title ('missing slice');
+%! title ('pie() with missing slice');
 
--- a/scripts/plot/pie3.m
+++ b/scripts/plot/pie3.m
@@ -61,7 +61,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     htmp = __pie__ ("pie3", hax, varargin{:});
@@ -82,17 +85,19 @@
 %! clf;
 %! pie3 ([5:-1:1], [0, 0, 1, 0, 0]);
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
+%! title ('pie3() with exploded wedge');
 
 %!demo
 %! clf;
 %! pie3 ([3, 2, 1], [0, 0, 1], {'Cheddar', 'Swiss', 'Camembert'});
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
 %! axis ([-2,2,-2,2]);
+%! title ('pie3() with labels');
 
 %!demo
 %! clf;
 %! pie3 ([0.17, 0.34, 0.41], {'Cheddar', 'Swiss', 'Camembert'});
 %! colormap ([1,0,0;0,1,0;0,0,1;1,1,0;1,0,1;0,1,1]);
 %! axis ([-2,2,-2,2]);
-%! title ('missing slice');
+%! title ('pie3() with missing slice');
 
--- a/scripts/plot/plot.m
+++ b/scripts/plot/plot.m
@@ -19,8 +19,9 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} plot (@var{y})
 ## @deftypefnx {Function File} {} plot (@var{x}, @var{y})
-## @deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{property}, @var{value}, @dots{})
 ## @deftypefnx {Function File} {} plot (@var{x}, @var{y}, @var{fmt})
+## @deftypefnx {Function File} {} plot (@dots{}, @var{property}, @var{value}, @dots{})
+## @deftypefnx {Function File} {} plot (@var{x1}, @var{y1}, @dots{}, @var{xn}, @var{yn})
 ## @deftypefnx {Function File} {} plot (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {@var{h} =} plot (@dots{})
 ## Produce 2-D plots.
@@ -34,11 +35,7 @@
 ##
 ## @noindent
 ## where the argument is taken as the set of @var{y} coordinates and the
-## @var{x} coordinates are taken to be the indices of the elements
-## starting with 1.
-##
-## To save a plot, in one of several image formats such as PostScript
-## or PNG, use the @code{print} command.
+## @var{x} coordinates are taken to be the range @code{1:numel (@var{y})}.
 ##
 ## If more than one argument is given, they are interpreted as
 ##
@@ -71,7 +68,18 @@
 ## the elements, starting with 1.
 ##
 ## @item
-## If the @var{x} is a vector and @var{y} is a matrix, then
+## If @var{x} and @var{y} are scalars, a single point is plotted.
+##
+## @item
+## @code{squeeze()} is applied to arguments with more than two dimensions,
+## but no more than two singleton dimensions.
+## 
+## @item
+## If both arguments are vectors, the elements of @var{y} are plotted versus
+## the elements of @var{x}.
+##
+## @item
+## If @var{x} is a vector and @var{y} is a matrix, then
 ## the columns (or rows) of @var{y} are plotted versus @var{x}.
 ## (using whichever combination matches, with columns tried first.)
 ##
@@ -81,94 +89,105 @@
 ## (using whichever combination matches, with columns tried first.)
 ##
 ## @item
-## If both arguments are vectors, the elements of @var{y} are plotted versus
-## the elements of @var{x}.
-##
-## @item
 ## If both arguments are matrices, the columns of @var{y} are plotted
 ## versus the columns of @var{x}.  In this case, both matrices must have
 ## the same number of rows and columns and no attempt is made to transpose
 ## the arguments to make the number of rows match.
-##
-## If both arguments are scalars, a single point is plotted.
 ## @end itemize
 ##
 ## Multiple property-value pairs may be specified, but they must appear
 ## in pairs.  These arguments are applied to the line objects drawn by
-## @code{plot}.
+## @code{plot}.  Useful properties to modify are @qcode{"linestyle"},
+## @qcode{"linewidth"}, @qcode{"color"}, @qcode{"marker"},
+## @qcode{"markersize"}, @qcode{"markeredgecolor"}, @qcode{"markerfacecolor"}.
 ##
-## If the @var{fmt} argument is supplied, it is interpreted as
-## follows.  If @var{fmt} is missing, the default gnuplot line style
-## is assumed.
+## The @var{fmt} format argument can also be used to control the plot style.
+## The format is composed of three parts: linestyle, markerstyle, color. 
+## When a markerstyle is specified, but no linestyle, only the markers are
+## plotted.  Similarly, if a linestyle is specified, but no markerstyle, then
+## only lines are drawn.  If both are specified then lines and markers will
+## be plotted.  If no @var{fmt} and no @var{property}/@var{value} pairs are
+## given, then the default plot style is solid lines with no markers and the
+## color determined by the @qcode{"colororder"} property of the current axes.
 ##
-## @table @samp
-## @item -
-## Set lines plot style (default).
+## Format arguments:
+##
+## @table @asis
+## @item linestyle
 ##
-## @item .
-## Set dots plot style.
+## @multitable @columnfractions 0.06 0.94
+## @item @samp{-}  @tab Use solid lines (default).
+## @item @samp{--} @tab Use dashed lines.
+## @item @samp{:}  @tab Use dotted lines.
+## @item @samp{-.} @tab Use dash-dotted lines.
+## @end multitable
 ##
-## @item @var{n}
-## Interpreted as the plot color if @var{n} is an integer in the range 1 to
-## 6.
+## @item markerstyle
 ##
-## @item @var{nm}
-## If @var{nm} is a two digit integer and @var{m} is an integer in the
-## range 1 to 6, @var{m} is interpreted as the point style.  This is only
-## valid in combination with the @code{@@} or @code{-@@} specifiers.
-##
-## @item @var{c}
-## If @var{c} is one of @code{"k"} (black), @code{"r"} (red), @code{"g"}
-## (green), @code{"b"} (blue), @code{"m"} (magenta), @code{"c"} (cyan),
-## or @code{"w"} (white), it is interpreted as the line plot color.
+## @multitable @columnfractions 0.06 0.94
+## @item @samp{+} @tab crosshair
+## @item @samp{o} @tab circle
+## @item @samp{*} @tab star
+## @item @samp{.} @tab point
+## @item @samp{x} @tab cross
+## @item @samp{s} @tab square
+## @item @samp{d} @tab diamond
+## @item @samp{^} @tab upward-facing triangle
+## @item @samp{v} @tab downward-facing triangle
+## @item @samp{>} @tab right-facing triangle
+## @item @samp{<} @tab left-facing triangle
+## @item @samp{p} @tab pentagram
+## @item @samp{h} @tab hexagram
+## @end multitable
 ##
-## @item ";title;"
-## Here @code{"title"} is the label for the key.
+## @item color
 ##
-## @item  +
-## @itemx *
-## @itemx o
-## @itemx x
-## @itemx ^
-## Used in combination with the points or linespoints styles, set the point
-## style.
+## @multitable @columnfractions 0.06 0.94
+## @item @samp{k} @tab blacK
+## @item @samp{r} @tab Red
+## @item @samp{g} @tab Green
+## @item @samp{b} @tab Blue
+## @item @samp{m} @tab Magenta
+## @item @samp{c} @tab Cyan
+## @item @samp{w} @tab White
+## @end multitable
 ##
-## @item @@
-## Select the next unused point style.
+## @item @qcode{";key;"}
+## Here @qcode{"key"} is the label to use for the plot legend.
 ## @end table
 ##
-## The @var{fmt} argument may also be used to assign key titles.
-## To do so, include the desired title between semi-colons after the
-## formatting sequence described above, e.g., "+3;Key Title;"
-## Note that the last semi-colon is required and will generate an error if
-## it is left out.
+## The @var{fmt} argument may also be used to assign legend keys.
+## To do so, include the desired label between semicolons after the
+## formatting sequence described above, e.g., @qcode{"+b;Key Title;"}.
+## Note that the last semicolon is required and Octave will generate
+## an error if it is left out.
 ##
 ## Here are some plot examples:
 ##
 ## @example
-## plot (x, y, "@@12", x, y2, x, y3, "4", x, y4, "+")
+## plot (x, y, "or", x, y2, x, y3, "m", x, y4, "+")
 ## @end example
 ##
-## This command will plot @code{y} with points of type 2 (displayed as
-## @samp{+}) and color 1 (red), @code{y2} with lines, @code{y3} with lines of
-## color 4 (magenta) and @code{y4} with points displayed as @samp{+}.
+## This command will plot @code{y} with red circles, @code{y2} with solid
+## lines, @code{y3} with solid magenta lines, and @code{y4} with points
+## displayed as @samp{+}.
 ##
 ## @example
-## plot (b, "*", "markersize", 3)
+## plot (b, "*", "markersize", 10)
 ## @end example
 ##
 ## This command will plot the data in the variable @code{b},
-## with points displayed as @samp{*} with a marker size of 3.
+## with points displayed as @samp{*} and a marker size of 10.
 ##
 ## @example
 ## @group
 ## t = 0:0.1:6.3;
-## plot (t, cos(t), "-;cos(t);", t, sin(t), "+3;sin(t);");
+## plot (t, cos(t), "-;cos(t);", t, sin(t), "-b;sin(t);");
 ## @end group
 ## @end example
 ##
 ## This will plot the cosine and sine functions and label them accordingly
-## in the key.
+## in the legend.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
@@ -176,6 +195,9 @@
 ## The optional return value @var{h} is a vector of graphics handles to
 ## the created line objects.
 ##
+## To save a plot, in one of several image formats such as PostScript
+## or PNG, use the @code{print} command.
+##
 ## @seealso{axis, box, grid, hold, legend, title, xlabel, ylabel, xlim, ylim, ezplot, errorbar, fplot, line, plot3, polar, loglog, semilogx, semilogy, subplot}
 ## @end deftypefn
 
@@ -189,7 +211,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     htmp = __plt__ ("plot", hax, varargin{:});
@@ -209,17 +234,52 @@
 %!demo
 %! x = 1:5;  y = 1:5;
 %! plot (x,y,'g');
-%! title ('plot of green line at 45 degrees');
+%! title ('plot() of green line at 45 degrees');
 
 %!demo
 %! x = 1:5;  y = 1:5;
 %! plot (x,y,'g*');
-%! title ('plot of green stars along a line at 45 degrees');
+%! title ('plot() of green stars along a line at 45 degrees');
 
 %!demo
 %! x1 = 1:5;  y1 = 1:5;
 %! x2 = 5:9; y2 = 5:-1:1;
 %! plot (x1,y1,'bo-', x2,y2,'rs-');
 %! axis ('tight');
-%! title ('plot of blue circles ascending and red squares descending with connecting lines drawn'); 
+%! title ({'plot() of blue circles ascending and red squares descending';
+%!         'connecting lines drawn'}); 
+
+%!demo
+%! x = 0:10;
+%! plot (x, rand (numel (x), 3))
+%! axis ([0 10 0 1])
+%! title ({'Three random variables', 'x[1x11], y[11x3]'})
+
+%!demo
+%! x = 0:10;
+%! plot (x, rand (3, numel (x)))
+%! axis ([0 10 0 1])
+%! title ({'Three random variables', 'x[1x11], y[3x11]'})
 
+%!demo
+%! x = 0:10;
+%! plot (repmat (x, 2, 1), rand (2, numel (x)), '-s')
+%! axis ([0 10 0 1])
+%! title ({'Vertical lines with random height and lenths', ...
+%!         'x[2x11], y[2,11]'})
+
+%!demo
+%! x = 0:10;
+%! plot (repmat (x(:), 1, 2), rand (numel (x), 2))
+%! axis ([0 10 0 1])
+%! title ({'Two random variables', 'x[11x2], y[11x2]'})
+
+%!demo
+%! x = 0:10;
+%! shape = [1, 1, numel(x), 2];
+%! x = reshape (repmat (x(:), 1, 2), shape);
+%! y = rand (shape);
+%! plot (x, y)
+%! axis ([0 10 0 1])
+%! title ({'Two random variables', 'squeezed from 4-d arrays'})
+
--- a/scripts/plot/plot3.m
+++ b/scripts/plot/plot3.m
@@ -109,7 +109,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -375,9 +378,11 @@
 %! clf;
 %! z = [0:0.05:5];
 %! plot3 (cos (2*pi*z), sin (2*pi*z), z, ';helix;');
+%! title ('plot3() of a helix');
 
 %!demo
 %! clf;
 %! z = [0:0.05:5];
 %! plot3 (z, exp (2i*pi*z), ';complex sinusoid;');
+%! title ('plot3() with complex input');
 
--- a/scripts/plot/plotmatrix.m
+++ b/scripts/plot/plotmatrix.m
@@ -72,19 +72,15 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (bigax2), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (bigax2))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     bigax2 = newplot (bigax2);
 
     [h2, ax2, p2, pax2] = __plotmatrix__ (bigax2, varargin{:});
 
-    if (nargout > 0)
-      h = h2;
-      ax = ax2;
-      bigax = bigax2;
-      p = p2;
-      pax = pax2;
-    endif
     axes (bigax2);
     ctext = text (0, 0, "", "visible", "off",
                   "handlevisibility", "off", "xliminclude", "off",
@@ -98,6 +94,14 @@
     endif
   end_unwind_protect
 
+  if (nargout > 0)
+    h = h2;
+    ax = ax2;
+    bigax = bigax2;
+    p = p2;
+    pax = pax2;
+  endif
+
 endfunction
 
 
--- a/scripts/plot/polar.m
+++ b/scripts/plot/polar.m
@@ -49,7 +49,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -196,16 +199,19 @@
 %! theta = linspace (0,2*pi,1000);
 %! rho = sin (7*theta);
 %! polar (theta, rho);
+%! title ('polar() plot');
 
 %!demo
 %! clf;
 %! theta = linspace (0,2*pi,1000);
 %! cplx = theta + i*sin (7*theta);
 %! polar (cplx, 'g');
+%! title ('polar() plot of complex data');
 
 %!demo
 %! clf;
-%! theta = linspace (0,10*pi,1000);
+%! theta = linspace (0,8*pi,1000);
 %! rho = sin (5/4*theta);
 %! polar (theta, rho);
+%! title ('polar() plot');
 
--- a/scripts/plot/print.m
+++ b/scripts/plot/print.m
@@ -57,7 +57,7 @@
 ##
 ## @item -G@var{ghostscript_command}
 ##   Specify the command for calling Ghostscript.  For Unix and Windows
-## the defaults are 'gs' and 'gswin32c', respectively.
+## the defaults are @qcode{"gs"} and @qcode{"gswin32c"}, respectively.
 ##
 ## @item  -color
 ## @itemx -mono
@@ -71,9 +71,9 @@
 ## @itemx -landscape
 ##   Specify the orientation of the plot for printed output.  For
 ## non-printed output the aspect ratio of the output corresponds to
-## the plot area defined by the "paperposition" property in the
+## the plot area defined by the @qcode{"paperposition"} property in the
 ## orientation specified.  This option is equivalent to changing
-## the figure's "paperorientation" property.
+## the figure's @qcode{"paperorientation"} property.
 ##
 ## @item  -TextAlphaBits=@var{n}
 ## @itemx -GraphicsAlphaBits=@var{n}
@@ -204,9 +204,9 @@
 ## and devices are available.
 ##
 ##   When Ghostscript output is sent to a printer the size is determined
-## by the figure's "papersize" property.  When the output
+## by the figure's @qcode{"papersize"} property.  When the output
 ## is sent to a file the size is determined by the plot box defined by
-## the figure's "paperposition" property.
+## the figure's @qcode{"paperposition"} property.
 ##
 ## @item -append
 ##   Append PostScript or PDF output to a pre-existing file of the same type.
@@ -214,7 +214,7 @@
 ## @item -r@var{NUM}
 ##   Resolution of bitmaps in pixels per inch.  For both metafiles and
 ## SVG the default is the screen resolution; for other formats it is 150 dpi.
-## To specify screen resolution, use "-r0".
+## To specify screen resolution, use @qcode{"-r0"}.
 ##
 ## @item  -loose
 ## @itemx -tight
@@ -241,9 +241,9 @@
 ##   Plot size in pixels for EMF, GIF, JPEG, PBM, PNG, and SVG@.  For
 ## PS, EPS, PDF, and other vector formats the plot size is in points.
 ## This option is equivalent to changing the size of the plot box
-## associated with the "paperposition" property.  When using the command form
-## of the print function you must quote the @var{xsize},@var{ysize}
-## option.  For example, by writing @w{"-S640,480"}.
+## associated with the @qcode{"paperposition"} property.  When using the
+## command form of the print function you must quote the
+## @var{xsize},@var{ysize} option.  For example, by writing @w{"-S640,480"}.
 ##
 ## @item  -F@var{fontname}
 ## @itemx -F@var{fontname}:@var{size}
@@ -411,10 +411,10 @@
 
     ## call the graphcis toolkit print script
     switch (get (opts.figure, "__graphics_toolkit__"))
-    case "gnuplot"
-      opts = __gnuplot_print__ (opts);
-    otherwise
-      opts = __fltk_print__ (opts);
+      case "gnuplot"
+        opts = __gnuplot_print__ (opts);
+      otherwise
+        opts = __fltk_print__ (opts);
     endswitch
 
   unwind_protect_cleanup
@@ -497,18 +497,18 @@
         cmd = "--copy --bbox";
       elseif (! isempty (opts.preview))
         switch (opts.preview)
-        case "tiff"
-          cmd = sprintf ("--add-%s-preview --device tiffg3", opts.preview);
-        case {"tiff6u", "tiff6p", "metafile"}
-          cmd = sprintf ("--add-%s-preview --device bmpgray", opts.preview);
-        case {"tiff4", "interchange"}
-          cmd = sprintf ("--add-%s-preview", opts.preview);
-        case "pict"
-          cmd = sprintf ("--add-%s-preview --mac-single", opts.preview);
-        otherwise
-          error ("print:invalidpreview",
-                 "print.m: epstool cannot include preview for format '%s'",
-                 opts.preview);
+          case "tiff"
+            cmd = sprintf ("--add-%s-preview --device tiffg3", opts.preview);
+          case {"tiff6u", "tiff6p", "metafile"}
+            cmd = sprintf ("--add-%s-preview --device bmpgray", opts.preview);
+          case {"tiff4", "interchange"}
+            cmd = sprintf ("--add-%s-preview", opts.preview);
+          case "pict"
+            cmd = sprintf ("--add-%s-preview --mac-single", opts.preview);
+          otherwise
+            error ("print:invalidpreview",
+                   "print.m: epstool cannot include preview for format '%s'",
+                   opts.preview);
         endswitch
         if (! isempty (opts.ghostscript.resolution))
           cmd = sprintf ("%s --dpi %d", cmd, opts.ghostscript.resolution);
@@ -619,15 +619,15 @@
   endif
   latexfile = strcat (opts.name, ".tex");
   switch (opts.devopt)
-  case {"pdflatexstandalone"}
-    packages = "\\usepackage{graphicx,color}";
-    graphicsfile = strcat (opts.name, "-inc.pdf");
-  case {"pslatexstandalone"}
-    packages = "\\usepackage{epsfig,color}";
-    graphicsfile = strcat (opts.name, "-inc.ps");
-  otherwise
-    packages = "\\usepackage{epsfig,color}";
-    graphicsfile = strcat (opts.name, "-inc.eps");
+    case {"pdflatexstandalone"}
+      packages = "\\usepackage{graphicx,color}";
+      graphicsfile = strcat (opts.name, "-inc.pdf");
+    case {"pslatexstandalone"}
+      packages = "\\usepackage{epsfig,color}";
+      graphicsfile = strcat (opts.name, "-inc.ps");
+    otherwise
+      packages = "\\usepackage{epsfig,color}";
+      graphicsfile = strcat (opts.name, "-inc.eps");
   endswitch
   papersize = sprintf ("\\usepackage[papersize={%.2fbp,%.2fbp},text={%.2fbp,%.2fbp}]{geometry}",
                        opts.canvas_size, opts.canvas_size);
@@ -708,4 +708,3 @@
   endif
 endfunction
 
-
--- a/scripts/plot/printd.m
+++ b/scripts/plot/printd.m
@@ -52,25 +52,25 @@
   ## are badly rendered.
   opt = lower (opt);
   switch (opt)
-    case {"pdf"}
+    case "pdf"
       enscr = sprintf (
                        "enscript --no-header -o %s.ps %s ; ps2pdf %s.ps %s.pdf; mv %s.pdf %s;exit",...
                        tempf, tempf, tempf, tempf, tempf, filename);
       system (enscr);
       delete ([tempf ".ps"]);
-    case {"ps"}
+    case "ps"
       enscr = sprintf ("enscript --no-header -o %s %s ; exit", filename, tempf);
       system (enscr);
-    case {"eps"}
+    case "eps"
       enscr = sprintf (
                        "enscript --no-header -o %s.ps %s ; ps2eps --ignoreBB %s.ps; mv %s.eps %s; exit",...
                        tempf, tempf, tempf, tempf, filename);
       system (enscr);
       delete ([tempf ".ps"]);
-    case {"txt"}
+    case "txt"
       enscr = sprintf ("cp %s %s", tempf, filename);
       system (enscr);
-    case {"jpg" "jpeg"}
+    case {"jpg", "jpeg"}
       enscr = sprintf ("convert -trim txt:%s  jpg:%s", tempf, filename);
       system (enscr);
     otherwise
--- a/scripts/plot/private/__actual_axis_position__.m
+++ b/scripts/plot/private/__actual_axis_position__.m
@@ -60,8 +60,8 @@
     if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
       aspect_ratio_2d = axis_obj.plotboxaspectratio(1:2);
     else
-      ## FIXME -- this works for "axis square", but has not been
-      ##          thoroughly tested for other aspect ratios.
+      ## FIXME: This works for "axis square", but has not been
+      ##        thoroughly tested for other aspect ratios.
       aspect_ratio_2d = [max(axis_obj.plotboxaspectratio(1:2)), ...
                              axis_obj.plotboxaspectratio(3)/sqrt(2)];
     endif
--- a/scripts/plot/private/__add_datasource__.m
+++ b/scripts/plot/private/__add_datasource__.m
@@ -23,10 +23,6 @@
 
 function newargs = __add_datasource__ (fcn, h, data, varargin)
 
-  if (nargin < 3)
-    error ("__add_datasource__: a minimum of 3 inputs are required");
-  endif
-
   if (ischar (data))
     data = {data};
   endif
@@ -53,3 +49,4 @@
     endif
   endwhile
 endfunction
+
--- a/scripts/plot/private/__add_default_menu__.m
+++ b/scripts/plot/private/__add_default_menu__.m
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} __add_default_menu__ (@var{fig})
 ## Add default menu to figure.  All uimenu handles have
-## their "HandleVisibility" property set to "off".
+## their @qcode{"HandleVisibility"} property set to @qcode{"off"}.
 ## @end deftypefn
 
 ## Author: Kai Habel
@@ -38,7 +38,6 @@
     ##        on and then off to force figure to hide menubar.
     menubar_state = get (fig, "menubar");
     set (fig, "menubar", "figure");
-    drawnow ();
 
     __f = uimenu (fig, "label", "&File", "handlevisibility", "off",
                        "tag", "__default_menu__");
@@ -59,6 +58,11 @@
                        "tag", "__default_menu__");
       uimenu (__h, "label", "A&bout", "enable", "off");
 
+    ## FIXME: This drawnow () must occur after at least one menu item has
+    ##        been defined to avoid sizing issues in new figures.
+    ##        This may lead to flicker.  The real fix must be in the C++ code. 
+    drawnow ();
+
     set (fig, "menubar", menubar_state);
   endif
 
--- a/scripts/plot/private/__axes_limits__.m
+++ b/scripts/plot/private/__axes_limits__.m
@@ -23,10 +23,6 @@
 
 function retval = __axes_limits__ (fcn, varargin)
 
-  retval = [];
-
-  fcnmode = sprintf ("%smode", fcn);
-
   [hax, varargin, nargin] = __plt_get_axis_arg__ (fcn, varargin{:});
 
   if (isempty (hax))
@@ -36,17 +32,18 @@
   if (nargin == 0)
     retval = get (hax, fcn);
   else
+    retval = [];
+    fcnmode = [fcn "mode"];
     arg = varargin{1};
-
     if (ischar (arg))
       if (strcmpi (arg, "mode"))
         retval = get (hax, fcnmode);
-      elseif (strcmpi (arg, "auto") || strcmpi (arg, "manual"))
+      elseif (any (strcmpi (arg, {"auto", "manual"})))
         set (hax, fcnmode, arg);
       endif
     else
       if (!isnumeric (arg) && any (size (arg(:)) != [2, 1]))
-        error ("%s: argument must be a 2 element vector", fcn);
+        error ("%s: LIMITS must be a 2-element vector", fcn);
       else
         if (arg(1) >= arg(2))
           error ("%s: axis limits must be increasing", fcn);
@@ -58,3 +55,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__axis_label__.m
+++ b/scripts/plot/private/__axis_label__.m
@@ -40,3 +40,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__bar__.m
+++ b/scripts/plot/private/__bar__.m
@@ -149,7 +149,10 @@
   yb = reshape (yb, [4, numel(yb) / 4 / ycols, ycols]);
 
   if (nargout < 2)
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
 
--- a/scripts/plot/private/__clabel__.m
+++ b/scripts/plot/private/__clabel__.m
@@ -22,7 +22,8 @@
 ## @end deftypefn
 
 function h = __clabel__ (c, v, hparent, label_spacing, z, varargin)
-  ## FIXME
+
+  ## FIXME: Why assume?  Can get position in points directly from axis.
   ## Assume that the plot size is 4 by 3 inches.
   lims = axis ();
   xspacing = 72 * 4 / abs (lims(1) - lims(2));
@@ -89,8 +90,8 @@
       endwhile
       tpos = sum (c(:,i1+j1-1:i1+j1), 2) ./ 2;
 
-      if (tpos(1) != xmin &&  tpos(1) != xmax
-          && tpos(2) != ymin &&  tpos(2) != ymax)
+      if (   tpos(1) != xmin && tpos(1) != xmax
+          && tpos(2) != ymin && tpos(2) != ymax)
         trot = 180 / pi * atan2 (diff (c(2,i1+j1-1:i1+j1)),
                                  diff (c(1,i1+j1-1:i1+j1)));
 
@@ -113,3 +114,4 @@
     i1 += clen+1;
   endwhile
 endfunction
+
deleted file mode 100644
--- a/scripts/plot/private/__color_str_rgb__.m
+++ /dev/null
@@ -1,50 +0,0 @@
-## Copyright (C) 2010-2012 David Bateman
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{rgb} =} __color_str_rgb__ (@var{str})
-## Undocumented internal function.
-## @end deftypefn
-
-function rgb = __color_str_rgb__ (str)
-
-  if (ischar (str))
-    if (strncmpi (str, "black", 5))
-      rgb = [0, 0, 0];
-    elseif (strncmpi (str, "red", 3))
-      rgb = [1, 0, 0];
-    elseif (strncmpi (str, "green", 5))
-      rgb = [0, 1, 0];
-    elseif (strncmpi (str, "blue", 4))
-      rgb = [0, 0, 1];
-
-    elseif (strncmpi (str, "yellow", 6))
-      rgb = [1, 1, 0];
-    elseif (strncmpi (str, "magenta", 7))
-      rgb = [1, 0, 1];
-    elseif (strncmpi (str, "cyan", 4))
-      rgb = [0, 1, 1];
-    elseif (strncmpi (str, "white", 5))
-      rgb = [1, 1, 1];
-    else
-      rgb = [0, 0, 0];
-    endif
-  else
-    error ("__color_str_rgb__: expecting a string argument");
-  endif
-endfunction
--- a/scripts/plot/private/__contour__.m
+++ b/scripts/plot/private/__contour__.m
@@ -140,9 +140,8 @@
 
   addproperty ("fill", hg, "radio", "on|{off}", filled);
 
-  ## The properties zlevel and zlevelmode don't exist in matlab, but
-  ## allow the use of contourgroups with the contour3, meshc and surfc
-  ## functions.
+  ## The properties zlevel and zlevelmode don't exist in matlab, but allow the
+  ## use of contourgroups with the contour3, meshc, and surfc functions.
   if (isnumeric (zlevel))
     addproperty ("zlevelmode", hg, "radio", "{none}|auto|manual", "manual");
     addproperty ("zlevel", hg, "data", zlevel);
@@ -183,8 +182,8 @@
   addproperty ("linestyle", hg, "linelinestyle", linespec.linestyle);
   addproperty ("linewidth", hg, "linelinewidth", 0.5);
 
-  ## FIXME It would be good to hide this property which is just an undocumented
-  ## alias for linecolor
+  ## FIXME: It would be good to hide this property which is just an
+  ##        undocumented alias for linecolor
   addproperty ("edgecolor", hg, "color", edgecolor, "{flat}|none");
 
   addlistener (hg, "fill", @update_data);
@@ -210,13 +209,18 @@
 
   addlistener (hg, "edgecolor", @update_edgecolor);
 
+  ## Set axis before adding patches so that each new patch does not trigger
+  ## new axis calculation.  No need if mode is already "manual".
+  if (all (strcmp (get (gca (), {"xlimmode", "ylimmode"}), "auto")))
+    axis ([min(x1(:)) max(x1(:)) min(y1(:)) max(y1(:))]);
+  endif
+
   add_patch_children (hg);
 
-  axis ("tight");
-
-  if (!isempty (opts))
+  if (! isempty (opts))
     set (hg, opts{:});
   endif
+
 endfunction
 
 function add_patch_children (hg)
@@ -231,6 +235,10 @@
   filled = get (hg, "fill");
   ca = gca ();
 
+  ## Turn off automatic updating of clim while adding patches
+  climmode = get (ca, "climmode");
+  set (ca, "climmode", "manual"); 
+
   if (strcmpi (lc, "auto"))
     lc = "flat";
   endif
@@ -389,9 +397,12 @@
     endwhile
   endif
 
+  set (ca, "climmode", climmode);
+
 endfunction
 
 function update_zlevel (h, d)
+
   z = get (h, "zlevel");
   zmode = get (h, "zlevelmode");
   kids = get (h, "children");
@@ -445,10 +456,10 @@
     delete (get (h, "children"));
 
     switch (prop)
-    case "levellist"
-      set (h, "levellistmode", "manual")
-    case "levelstep"
-      set (h, "levelstepmode", "manual")
+      case "levellist"
+        set (h, "levellistmode", "manual")
+      case "levelstep"
+        set (h, "levelstepmode", "manual")
     endswitch
 
     if (strcmpi (get (h, "levellistmode"), "manual")
@@ -554,7 +565,7 @@
 endfunction
 
 function lvl_eps = get_lvl_eps (lev)
-  ## FIXME -- is this the right thing to do for this tolerance?  Should
+  ## FIXME: is this the right thing to do for this tolerance?  Should
   ## it be an absolute or relative tolerance, or switch from one to the
   ## other depending on the value of lev?
   if (isscalar (lev))
@@ -568,3 +579,4 @@
     endif
   endif
 endfunction
+
--- a/scripts/plot/private/__default_plot_options__.m
+++ b/scripts/plot/private/__default_plot_options__.m
@@ -32,3 +32,4 @@
   options.errorstyle = [];
 
 endfunction
+
--- a/scripts/plot/private/__errcomm__.m
+++ b/scripts/plot/private/__errcomm__.m
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} __errcomm__ (@var{caller}, @var{p}, @dots{})
+## @deftypefn {Function File} {} __errcomm__ (@var{caller}, @var{hax}, @dots{})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -25,54 +25,55 @@
 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
 ## Keywords: errorbar, plotting
 
-function retval = __errcomm__ (caller, p, varargin)
+function retval = __errcomm__ (caller, hax, varargin)
 
   if (nargin < 4)
-    print_usage ();
+    print_usage (caller);
   endif
 
-  nargs = length (varargin);
   retval = [];
+  data = cell (6,1);
+  nargs = numel (varargin);
   k = 1;
-  data = cell (6,1);
   while (k <= nargs)
-    a = varargin{k++};
-    if (isvector (a))
-      a = a(:);
-    elseif (ismatrix (a))
-      ;
-    else
-      usage ("%s (...)", caller);
+    arg = varargin{k++};
+    if (! ismatrix (arg))
+      error ("%s: data argument %d must be numeric", caller, k-1);
     endif
-    sz = size (a);
+    if (isvector (arg))
+      arg = arg(:);
+    endif
+    sz = size (arg);
     ndata = 1;
-    data{ndata} = a;
+    data{ndata} = arg;
     while (k <= nargs)
-      a = varargin{k++};
-      if (ischar (a) || iscellstr (a))
-        retval = [retval; __errplot__(a, p, data{1:ndata})];
+      arg = varargin{k++};
+      if (ischar (arg) || iscellstr (arg))
+        retval(end+1,1) = __errplot__(arg, hax, data{1:ndata});
         break;
-      elseif (isvector (a))
-        a = a(:);
-      elseif (ismatrix (a))
-        ;
-      else
-        error ("wrong argument types");
+      endif
+      if (! ismatrix (arg))
+        error ("%s: data argument %d must be numeric", caller, k-1);
+      endif
+      if (isvector (arg))
+        arg = arg(:);
       endif
-      if (size (a) != sz)
-        error ("argument sizes do not match");
+      if (any (size (arg) != sz))
+        error ("%s: size of argument %d does not match others", caller, k-1);
       endif
-      data{++ndata} = a;
+      data{++ndata} = arg;
       if (ndata > 6)
-        error ("too many arguments to a plot");
+        error ("%s: too many arguments to plot", caller);
       endif
     endwhile
   endwhile
 
-  if (! (ischar (a) || iscellstr (a)))
-    retval = [retval; __errplot__("~", p, data{1:ndata})];
+  ## No format code found, use yerrorbar
+  if (! (ischar (arg) || iscellstr (arg)))
+    retval = [retval; __errplot__("~", hax, data{1:ndata})];
   endif
 
   drawnow ();
 
 endfunction
+
--- a/scripts/plot/private/__errplot__.m
+++ b/scripts/plot/private/__errplot__.m
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{p}, @dots{})
+## @deftypefn {Function File} {@var{h} =} __errplot__ (@var{fstr}, @var{hax}, @dots{})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -25,125 +25,126 @@
 ## Author: Teemu Ikonen <tpikonen@pcu.helsinki.fi>
 ## Keywords: errorbar, plotting
 
-function h = __errplot__ (fstr, p, varargin)
-
-  if (nargin < 4 || nargin > 8) # at least two data arguments needed
-    print_usage ();
-  endif
+function h = __errplot__ (fstr, hax, varargin)
 
-  [fmt, valid] = __pltopt__ ("__errplot__", fstr);
-
-  [len, nplots] = size (varargin{1});
-  h = [];
-
-  for i = 1:nplots
-    ## Set the plot type based on linestyle.
+  fmt = __pltopt__ ("__errplot__", fstr);
 
-    if (strcmp (fmt.errorstyle, "~"))
+  ## Set the plot type based on linestyle.
+  switch (fmt.errorstyle) 
+    case "~"
       ifmt = "yerr";
-    elseif (strcmp (fmt.errorstyle, ">"))
+    case ">"
       ifmt = "xerr";
-    elseif (strcmp (fmt.errorstyle, "~>"))
+    case "~>"
       ifmt = "xyerr";
-    elseif (strcmp (fmt.errorstyle, "#"))
+    case "#"
       ifmt = "box";
-    elseif (strcmp (fmt.errorstyle, "#~"))
+    case "#~"
       ifmt = "boxy";
-    elseif (strcmp (fmt.errorstyle, "#~>"))
+    case "#~>"
       ifmt = "boxxy";
+    otherwise
+      ifmt = "yerr";
+  endswitch
+
+  h = [];
+  nplots = columns (varargin{1});
+  for i = 1:nplots
+
+    if (isempty (fmt.color))
+      lc = __next_line_color__ ();
     else
-      ifmt = "yerr";
+      lc = fmt.color ();
+    endif
+    if (isempty (fmt.marker) && isempty (fmt.linestyle))
+      [ls, mk] = __next_line_style__ ();
+    else
+      ls = fmt.linestyle;
+      mk = fmt.marker;
     endif
 
-    hg = hggroup ("parent", p);
+    ## Must occur after __next_line_color__ in order to work correctly.
+    hg = hggroup ("parent", hax);
     h = [h; hg];
     args = __add_datasource__ ("__errplot__", hg,
                                {"x", "y", "l", "u", "xl", "xu"});
 
-    if (isempty (fmt.color))
-      fmt.color = __next_line_color__ ();
-    endif
-    if (isempty (fmt.marker) && isempty (fmt.linestyle))
-      [fmt.linestyle, fmt.marker] = __next_line_style__ ();
-    endif
-    hl = [(__line__ (hg, "linestyle", fmt.linestyle, "marker", fmt.marker,
-                   "color", fmt.color)),
-          (__line__ (hg, "linestyle", "-", "marker", "none",
-                   "color", fmt.color))];
+    hl = [(__line__ (hg, "color", lc, "linestyle", ls, "marker", mk)),
+          (__line__ (hg, "color", lc, "linestyle", "-", "marker", "none"))];
 
     switch (numel (varargin))
       case 2
         ydata = varargin{1}(:,i);
         xdata = 1:numel (ydata);
-        if (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
+        if (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
+          ldata  = varargin{2}(:,i);
+          udata  = ldata;
+          xldata = [];
+          xudata = [];
+        elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
           xldata = varargin{2}(:,i);
           xudata = ldata;
-          ldata = [];
-          udata = [];
-        elseif (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
-          ldata = varargin{2}(:,i);
-          udata = ldata;
-          xldata = [];
-          xudata = [];
+          ldata  = [];
+          udata  = [];
         else
           error ("errorbar: 2 column errorplot is only valid for xerr or yerr");
         endif
       case 3
-        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
-          ydata = varargin{1}(:,i);
-          xdata = 1:numel (ydata);
+        if (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
+          ldata  = varargin{3}(:,i);
+          udata  = ldata;
+          xldata = [];
+          xudata = [];
+        elseif (strcmp (ifmt, "xyerr") || strcmp (ifmt, "boxxy"))
+          ydata  = varargin{1}(:,i);
+          xdata  = 1:numel (ydata);
           xldata = varargin{2}(:,i);
           xudata = xldata;
-          ldata = varargin{3}(:,i);
-          udata = ldata;
-        elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
-          xldata = varargin{3}(:,i);
-          xudata = xldata;
-          ldata = [];
-          udata = [];
-        else # yerr or boxy
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
-          ldata = varargin{3}(:,i);
-          udata = ldata;
-          xldata = [];
-          xudata = [];
-        endif
-      case 4
-        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
+          ldata  = varargin{3}(:,i);
+          udata  = ldata;
+        else  # xerr or box
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
           xldata = varargin{3}(:,i);
           xudata = xldata;
-          ldata = varargin{4}(:,i);
-          udata = ldata;
-        elseif (strcmp (ifmt, "xerr") || strcmp (ifmt, "box"))
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
+          ldata  = [];
+          udata  = [];
+        endif
+      case 4
+        if (strcmp (ifmt, "yerr") || strcmp (ifmt, "boxy"))
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
+          ldata  = varargin{3}(:,i);
+          udata  = varargin{4}(:,i);
+          xldata = [];
+          xudata = [];
+        elseif (strcmp (ifmt, "xyerr") || strcmp (ifmt, "boxxy"))
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
+          xldata = varargin{3}(:,i);
+          xudata = xldata;
+          ldata  = varargin{4}(:,i);
+          udata  = ldata;
+        else  # xerr or box
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
           xldata = varargin{3}(:,i);
           xudata = varargin{4}(:,i);
-          ldata = [];
-          udata = [];
-        else # yerr or boxy
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
-          ldata = varargin{3}(:,i);
-          udata = varargin{4}(:,i);
-          xldata = [];
-          xudata = [];
+          ldata  = [];
+          udata  = [];
         endif
-      case 6 # boxxy, xyerr
-        if (strcmp (ifmt, "boxxy") || strcmp (ifmt, "xyerr"))
-          xdata = varargin{1}(:,i);
-          ydata = varargin{2}(:,i);
+      case 6  # xyerr, boxxy
+        if (strcmp (ifmt, "xyerr") || strcmp (ifmt, "boxxy"))
+          xdata  = varargin{1}(:,i);
+          ydata  = varargin{2}(:,i);
           xldata = varargin{3}(:,i);
           xudata = varargin{4}(:,i);
-          ldata = varargin{5}(:,i);
-          udata = varargin{6}(:,i);
+          ldata  = varargin{5}(:,i);
+          udata  = varargin{6}(:,i);
         else
-          error ("errorbar: error plot with 6 columns only valid for boxxy and xyerr");
+          error ("errorbar: error plot with 6 columns only valid for xyerr and boxxy");
         endif
       otherwise
         error ("errorbar: error plot requires 2, 3, 4, or 6 arguments");
@@ -158,21 +159,22 @@
     addproperty ("format", hg, "string", ifmt);
 
     addproperty ("color", hg, "linecolor", get (hl(1), "color"));
+    addproperty ("linestyle", hg, "linelinestyle", get (hl(1), "linestyle"));
     addproperty ("linewidth", hg, "linelinewidth", get (hl(1), "linewidth"));
-    addproperty ("linestyle", hg, "linelinestyle", get (hl(1), "linestyle"));
     addproperty ("marker", hg, "linemarker", get (hl(1), "marker"));
+    addproperty ("markeredgecolor", hg, "linemarkerfacecolor",
+                 get (hl(1), "markeredgecolor"));
     addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
                  get (hl(1), "markerfacecolor"));
-    addproperty ("markeredgecolor", hg, "linemarkerfacecolor",
-                 get (hl(1), "markeredgecolor"));
     addproperty ("markersize", hg, "linemarkersize",
                  get (hl(1), "markersize"));
 
     fcn = {@update_props, hl};
     addlistener (hg, "color", fcn);
+    addlistener (hg, "linestyle", fcn);
     addlistener (hg, "linewidth", fcn);
-    addlistener (hg, "linestyle", fcn);
     addlistener (hg, "marker", fcn);
+    addlistener (hg, "markeredgecolor", fcn);
     addlistener (hg, "markerfacecolor", fcn);
     addlistener (hg, "markersize", fcn);
 
@@ -232,7 +234,11 @@
     xhi = xdata + dx;
   else
     n = xdata > 0;
-    rx = exp (0.01 * (max (log (xdata(n))) - min (log (xdata(n)))));
+    if (! any (n))
+      n = xdata < 0;
+    endif
+    logdata = log (abs (xdata(n)));
+    rx = exp (0.01 * (max (logdata) - min (logdata)));
     xlo = xdata/rx;
     xhi = xdata*rx;
   endif
@@ -242,11 +248,15 @@
     yhi = ydata + dy;
   else
     n = ydata > 0;
-    ry = exp (0.01 * (max (log (ydata(n))) - min (log (ydata(n)))));
+    if (! any (n))
+      n = ydata < 0;
+    endif
+    logdata = log (abs (ydata(n)));
+    ry = exp (0.01 * (max (logdata) - min (logdata)));
     ylo = ydata/ry;
     yhi = ydata*ry;
   endif
-  nans = NaN + xdata(:);
+  nans = NaN + xdata(:);  # fast way to do NaN (size (xdata(:)))
   if (strcmp (ifmt, "yerr"))
     xdata = [xdata, xdata, nans, ...
              xlo, xhi, nans, ...
@@ -283,9 +293,9 @@
                               xldata, xudata, "yerr", xscale, yscale);
     xdata = [x1; x2];
     ydata = [y1; y2];
-    return
+    return;
   else
-    error ("errorbar: valid error bar types are xerr, yerr, boxxy, and xyerr");
+    error ("errorbar: valid error bar types are xerr, yerr, xyerr, box, boxy, boxxy");
   endif
 
   xdata = xdata.'(:);
@@ -293,17 +303,17 @@
 
 endfunction
 
-function update_props (hg, dummy, hl)
+function update_props (hg, ~, hl)
   set (hl, "color", get (hg, "color"),
-           "linewidth", get (hg, "linewidth"));,
+           "linewidth", get (hg, "linewidth"));
   set (hl(1), "linestyle", get (hg, "linestyle"),
               "marker", get (hg, "marker"),
-              "markersize", get (hg, "markersize"),
+              "markeredgecolor", get (hg, "markeredgecolor"),
               "markerfacecolor", get (hg, "markerfacecolor"),
-              "markeredgecolor", get (hg, "markeredgecolor"));
+              "markersize", get (hg, "markersize"));
 endfunction
 
-function update_data (hg, dummy, hl)
+function update_data (hg, ~, hl)
 
   if (strcmp (get (hg, "type"), "axes"))
     hax = hg;
@@ -314,10 +324,10 @@
   xscale = get (hax, "xscale");
   yscale = get (hax, "yscale");
 
-  xdata = get (hg, "xdata");
-  ydata = get (hg, "ydata");
-  ldata = get (hg, "ldata");
-  udata = get (hg, "udata");
+  xdata  = get (hg, "xdata");
+  ydata  = get (hg, "ydata");
+  ldata  = get (hg, "ldata");
+  udata  = get (hg, "udata");
   xldata = get (hg, "xldata");
   xudata = get (hg, "xudata");
   ifmt = get (hg, "format");
--- a/scripts/plot/private/__ezplot__.m
+++ b/scripts/plot/private/__ezplot__.m
@@ -420,21 +420,21 @@
             if (! auto_domain_done)
               domain = find_valid_domain (X, Y, Z);
             endif
-          end
+          endif
         endif
       endif
     endif
   until (domain_ok)
 
   ## Now, actually call the correct plot function with valid data and domain.
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     if (iscontour)
       [~, h] = feval (pltfunc, hax, X, Y, Z);
-      ## FIXME: Work around contour setting axis tight.
-      ##        Fix should really be in __countour__.
-      axis (hax, domain);
     elseif (isplot && nargs == 2)
       h = zeros (length (XX), 1);
       hold_state = get (hax, "nextplot");
--- a/scripts/plot/private/__file_filter__.m
+++ b/scripts/plot/private/__file_filter__.m
@@ -91,3 +91,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__fltk_file_filter__.m
+++ b/scripts/plot/private/__fltk_file_filter__.m
@@ -62,3 +62,4 @@
   retval = fltk_str;
 
 endfunction
+
--- a/scripts/plot/private/__fltk_print__.m
+++ b/scripts/plot/private/__fltk_print__.m
@@ -39,111 +39,111 @@
   gl2ps_device = {};
   pipeline = {};
   switch (lower (opts.devopt))
-  case {"eps", "eps2", "epsc", "epsc2"}
-    ## format GL2PS_EPS
-    gl2ps_device = {"eps"};
-    ## FIXME - use epstool to tighten bbox and provide preview.
-    pipeline = {opts.epstool_cmd(opts, "-", opts.name)};
-  case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ...
-        "pslatexstandalone", "pdflatexstandalone"}
-    ## format GL2PS_TEX
-    n = find (opts.devopt == "l", 1);
-    suffix = opts.devopt(1:n-1);
-    dot = find (opts.name == ".", 1, "last");
-    if ((! isempty (dot))
-        && any (strcmpi (opts.name(dot:end), ...
-                {strcat(".", suffix), ".tex", "."})))
-      name = opts.name(1:dot-1);
-      if (dot < numel (opts.name)
-          && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"})))
-        ## If user provides eps/ps/pdf suffix, use it.
-        suffix = opts.name(dot+1:end);
+    case {"eps", "eps2", "epsc", "epsc2"}
+      ## format GL2PS_EPS
+      gl2ps_device = {"eps"};
+      ## FIXME: use epstool to tighten bbox and provide preview.
+      pipeline = {opts.epstool_cmd(opts, "-", opts.name)};
+    case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ...
+          "pslatexstandalone", "pdflatexstandalone"}
+      ## format GL2PS_TEX
+      n = find (opts.devopt == "l", 1);
+      suffix = opts.devopt(1:n-1);
+      dot = find (opts.name == ".", 1, "last");
+      if ((! isempty (dot))
+          && any (strcmpi (opts.name(dot:end), ...
+                  {strcat(".", suffix), ".tex", "."})))
+        name = opts.name(1:dot-1);
+        if (dot < numel (opts.name)
+            && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"})))
+          ## If user provides eps/ps/pdf suffix, use it.
+          suffix = opts.name(dot+1:end);
+        endif
+      else
+        error ("print:invalid-suffix", 
+               "invalid suffix '%s' for device '%s'.",
+               opts.name(dot:end), lower (opts.devopt));
       endif
-    else
-      error ("print:invalid-suffix", 
-             "invalid suffix '%s' for device '%s'.",
-             opts.name(dot:end), lower (opts.devopt));
-    endif
-    gl2ps_device = {sprintf("%snotxt", lower (suffix))};
-    gl2ps_device{2} = "tex";
-    if (dos_shell)
-      ## FIXME - this will only work on MinGW with the MSYS shell
-      pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
-      pipeline{2} = sprintf ("cat > %s.tex", name);
-    else
-      pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
-      pipeline{2} = sprintf ("cat > %s.tex", name);
-    endif
-  case "tikz"
-    ## format GL2PS_PGF
-    gl2ps_device = {"pgf"};
-    pipeline = {sprintf("cat > %s", opts.name)};
-  case "svg"
-    ## format GL2PS_SVG
-    gl2ps_device = {"svg"};
-    pipeline = {sprintf("cat > %s", opts.name)};
-  case fig2dev_devices
-    cmd_pstoedit = opts.pstoedit_cmd (opts, "fig");
-    cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt);
-    if (strcmp (opts.devopt, "pstex"))
-      [~, ~, ext] = fileparts (opts.name);
-      if (any (strcmpi (ext, {".ps", ".tex", "."})))
-        opts.name = opts.name(1:end-numel(ext));
+      gl2ps_device = {sprintf("%snotxt", lower (suffix))};
+      gl2ps_device{2} = "tex";
+      if (dos_shell)
+        ## FIXME: this will only work on MinGW with the MSYS shell
+        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
+        pipeline{2} = sprintf ("cat > %s.tex", name);
+      else
+        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
+        pipeline{2} = sprintf ("cat > %s.tex", name);
       endif
-      opts.name = strcat (opts.name, ".ps");
-      cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
-      gl2ps_device = {"eps"};
-      pipeline = {cmd};
-      cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t");
-      gl2ps_device{2} = "eps";
-      pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit,
-                             cmd_fig2dev, strrep(opts.name, ".ps", ".tex"));
-    else
-      cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
+    case "tikz"
+      ## format GL2PS_PGF
+      gl2ps_device = {"pgf"};
+      pipeline = {sprintf("cat > %s", opts.name)};
+    case "svg"
+      ## format GL2PS_SVG
+      gl2ps_device = {"svg"};
+      pipeline = {sprintf("cat > %s", opts.name)};
+    case fig2dev_devices
+      cmd_pstoedit = opts.pstoedit_cmd (opts, "fig");
+      cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt);
+      if (strcmp (opts.devopt, "pstex"))
+        [~, ~, ext] = fileparts (opts.name);
+        if (any (strcmpi (ext, {".ps", ".tex", "."})))
+          opts.name = opts.name(1:end-numel(ext));
+        endif
+        opts.name = strcat (opts.name, ".ps");
+        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+        cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t");
+        gl2ps_device{2} = "eps";
+        pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit,
+                               cmd_fig2dev, strrep(opts.name, ".ps", ".tex"));
+      else
+        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+      endif
+    case "aifm"
+      cmd = opts.pstoedit_cmd (opts, "ps2ai");
       gl2ps_device = {"eps"};
-      pipeline = {cmd};
-    endif
-  case "aifm"
-    cmd = opts.pstoedit_cmd (opts, "ps2ai");
-    gl2ps_device = {"eps"};
-    pipeline = {sprintf("%s > %s", cmd, opts.name)};
-  case {"dxf", "emf", "fig", "hpgl"}
-    cmd = opts.pstoedit_cmd (opts);
-    gl2ps_device = {"eps"};
-    pipeline = {sprintf("%s > %s", cmd, opts.name)};
-  case {"corel", "gif"}
-    error ("print:unsupporteddevice",
-           "print.m: %s output is not available for the FLTK graphics toolkit",
-           upper (opts.devopt));
-  case opts.ghostscript.device
-    opts.ghostscript.source = "-";
-    opts.ghostscript.output = opts.name;
-    if (opts.send_to_printer)
-      opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = [];
-      opts.ghostscript.output = "-";
-    endif
-    [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
-    if (opts.send_to_printer || isempty (opts.name))
-      cmd_lpr = opts.lpr_cmd (opts);
-      cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr);
-    else
-      cmd = sprintf ("%s", cmd_gs);
-    endif
-    if (! isempty (cmd_cleanup))
+      pipeline = {sprintf("%s > %s", cmd, opts.name)};
+    case {"dxf", "emf", "fig", "hpgl"}
+      cmd = opts.pstoedit_cmd (opts);
       gl2ps_device = {"eps"};
-      if (dos_shell)
-        pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)};
-      else
-        pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)};
+      pipeline = {sprintf("%s > %s", cmd, opts.name)};
+    case {"corel", "gif"}
+      error ("print:unsupporteddevice",
+             "print.m: %s output is not available for the FLTK graphics toolkit",
+             upper (opts.devopt));
+    case opts.ghostscript.device
+      opts.ghostscript.source = "-";
+      opts.ghostscript.output = opts.name;
+      if (opts.send_to_printer)
+        opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = [];
+        opts.ghostscript.output = "-";
       endif
-    else
-      gl2ps_device = {"eps"};
-      pipeline = {cmd};
-    endif
-  otherwise
-    error (sprintf ("print:no%soutput", opts.devopt),
-           "print.m: %s output is not available for GL2PS output",
-           upper (opts.devopt));
+      [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
+      if (opts.send_to_printer || isempty (opts.name))
+        cmd_lpr = opts.lpr_cmd (opts);
+        cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr);
+      else
+        cmd = sprintf ("%s", cmd_gs);
+      endif
+      if (! isempty (cmd_cleanup))
+        gl2ps_device = {"eps"};
+        if (dos_shell)
+          pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)};
+        else
+          pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)};
+        endif
+      else
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+      endif
+    otherwise
+      error (sprintf ("print:no%soutput", opts.devopt),
+             "print.m: %s output is not available for GL2PS output",
+             upper (opts.devopt));
   endswitch
 
   opts.pipeline = pipeline;
--- a/scripts/plot/private/__getlegenddata__.m
+++ b/scripts/plot/private/__getlegenddata__.m
@@ -56,3 +56,4 @@
   endfor
 
 endfunction
+
--- a/scripts/plot/private/__gnuplot_get_var__.m
+++ b/scripts/plot/private/__gnuplot_get_var__.m
@@ -26,10 +26,6 @@
 
 function gp_var_value = __gnuplot_get_var__ (h, gp_var_name, fmt = "")
 
-  if (nargin < 2)
-    print_usage ();
-  endif
-
   if (numel (h) == 1 && isfigure (h))
     if (isempty (get (gcf, "__plot_stream__")))
       ostream = __gnuplot_open_stream__ (2, h);
@@ -56,7 +52,7 @@
   if (use_mkfifo)
     gpin_name = tmpnam ();
 
-    ## Mode: 6*8*8 ==  0600
+    ## Mode: 0600 == 6*8*8
     [err, msg] = mkfifo (gpin_name, 6*8*8);
 
     if (err)
--- a/scripts/plot/private/__gnuplot_open_stream__.m
+++ b/scripts/plot/private/__gnuplot_open_stream__.m
@@ -43,3 +43,4 @@
     set (h, "__plot_stream__", plot_stream);
   endif
 endfunction
+
--- a/scripts/plot/private/__gnuplot_print__.m
+++ b/scripts/plot/private/__gnuplot_print__.m
@@ -49,103 +49,104 @@
   pipeline = "";
 
   switch (lower (opts.devopt))
-  case {"eps", "eps2", "epsc", "epsc2"}
-    if (any (strcmp (opts.devopt, {"eps", "epsc"})))
-      gp_opts = [gp_opts " level1"];
-    endif
-    if (opts.tight_flag || ! isempty (opts.preview))
-      tmp_file = strcat (tmpnam (), ".eps");
-      eps_drawnow (opts, tmp_file, gp_opts);
-      if (dos_shell)
-        cleanup = [" & del " strrep(tmp_file, '/', '\')];
+    case {"eps", "eps2", "epsc", "epsc2"}
+      if (any (strcmp (opts.devopt, {"eps", "epsc"})))
+        gp_opts = [gp_opts " level1"];
+      endif
+      if (opts.tight_flag || ! isempty (opts.preview))
+        tmp_file = strcat (tmpnam (), ".eps");
+        eps_drawnow (opts, tmp_file, gp_opts);
+        if (dos_shell)
+          cleanup = [" & del " strrep(tmp_file, '/', '\')];
+        else
+          cleanup = [" ; rm " tmp_file];
+        endif
+        pipeline = {sprintf("%s %s",
+                            opts.epstool_cmd (opts, tmp_file, opts.name),
+                            cleanup)};
       else
-        cleanup = [" ; rm " tmp_file];
+        eps_drawnow (opts, opts.name, gp_opts);
       endif
-      pipeline = {sprintf("%s %s",
-                          opts.epstool_cmd (opts, tmp_file, opts.name),
-                          cleanup)};
-    else
-      eps_drawnow (opts, opts.name, gp_opts);
-    endif
-  case {"epslatex", "pslatex", "pstex", "epslatexstandalone"}
-    dot = find (opts.name == ".", 1, "last");
-    n = find (opts.devopt == "l", 1);
-    suffix = opts.devopt(1:n-1);
-    if (! isempty (dot))
-      if (any (strcmpi (opts.name(dot:end), {strcat(".", suffix), ".tex", "."})))
-        name = opts.name(1:dot-1);
+    case {"epslatex", "pslatex", "pstex", "epslatexstandalone"}
+      dot = find (opts.name == ".", 1, "last");
+      n = find (opts.devopt == "l", 1);
+      suffix = opts.devopt(1:n-1);
+      if (! isempty (dot))
+        if (any (strcmpi (opts.name(dot:end), {["." suffix], ".tex", "."})))
+          name = opts.name(1:dot-1);
+        else
+          error ("print:invalid-suffix", 
+                 "invalid suffix '%s' for device '%s'.",
+                 opts.name(dot:end), lower (opts.devopt));
+        endif
+      endif
+      if (strfind (opts.devopt, "standalone"))
+        term = sprintf ("%s ",
+                        strrep (opts.devopt, "standalone", " standalone"));
       else
-        error ("print:invalid-suffix", 
-               "invalid suffix '%s' for device '%s'.",
-               opts.name(dot:end), lower (opts.devopt));
+        term = sprintf ("%s ", opts.devopt);
+      endif
+      if (__gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix"))
+        suffix = "tex";
+      else
+        ## Gnuplot 4.0 wants a ".eps" suffix.
+        suffix = "eps";
       endif
-    endif
-    if (strfind (opts.devopt, "standalone"))
-      term = sprintf ("%s ",
-                      strrep (opts.devopt, "standalone", " standalone"));
-    else
-      term = sprintf ("%s ", opts.devopt);
-    endif
-    if (__gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix"))
-      suffix = "tex";
-    else
-      ## Gnuplot 4.0 wants a ".eps" suffix.
-      suffix = "eps";
-    endif
-    local_drawnow ([term " " gp_opts],
-                   strcat (name, ".", suffix), opts);
-  case "tikz"
-    if (__gnuplot_has_terminal__ ("tikz"))
-      local_drawnow (["lua tikz " gp_opts], opts.name, opts);
-    else
-      error (sprintf ("print:no%soutput", opts.devopt),
-             "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 {"aifm", "corel", "eepic", "emf", "fig"}
-    local_drawnow ([opts.devopt " " gp_opts], opts.name, opts);
-  case {"pdfcairo", "pngcairo"}
-    if (__gnuplot_has_terminal__ (opts.devopt))
+      local_drawnow ([term " " gp_opts],
+                     strcat (name, ".", suffix), opts);
+    case "tikz"
+      if (__gnuplot_has_terminal__ ("tikz"))
+        local_drawnow (["lua tikz " gp_opts], opts.name, opts);
+      else
+        error (sprintf ("print:no%soutput", opts.devopt),
+               "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 {"aifm", "corel", "eepic", "emf", "fig"}
+      local_drawnow ([opts.devopt " " gp_opts], opts.name, opts);
+    case {"pdfcairo", "pngcairo"}
+      if (__gnuplot_has_terminal__ (opts.devopt))
+        local_drawnow ([opts.devopt " " gp_opts], opts.name, opts);
+      else
+        error (sprintf ("print:no%soutput", opts.devopt),
+               "print.m: '%s' output is not available for gnuplot-%s",
+               upper (opts.devopt), __gnuplot_version__ ());
+      endif
+    case {"canvas", "dxf", "hpgl", "mf", "gif", "pstricks", "texdraw"}
       local_drawnow ([opts.devopt " " gp_opts], opts.name, opts);
-    else
+    case opts.ghostscript.device
+      gp_opts = font_spec (opts, "devopt", "eps");
+      opts.ghostscript.output = opts.name;
+      opts.ghostscript.source = strcat (tmpnam (), ".eps");
+      eps_drawnow (opts, opts.ghostscript.source, gp_opts);
+      [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
+      if (opts.send_to_printer || isempty (opts.name))
+        cmd_lpr = opts.lpr_cmd (opts);
+        cmd = [cmd_gs " | " cmd_lpr];
+      else
+        cmd = cmd_gs;
+      endif
+      if (dos_shell)
+        cmd = sprintf ("%s & del %s", cmd,
+                       strrep (opts.ghostscript.source, '/', '\'));
+      else
+        cmd = sprintf ("%s ; rm %s", cmd, opts.ghostscript.source);
+      endif
+      if (! isempty (cmd_cleanup))
+        if (dos_shell)
+          pipeline = {[cmd " & " cmd_cleanup]};
+        else
+          pipeline = {[cmd " ; " cmd_cleanup]};
+        endif
+      else
+        pipeline = {cmd};
+      endif
+    otherwise
       error (sprintf ("print:no%soutput", opts.devopt),
-             "print.m: '%s' output is not available for gnuplot-%s",
-             upper (opts.devopt), __gnuplot_version__ ());
-    endif
-  case {"canvas", "dxf", "hpgl", "mf", "gif", "pstricks", "texdraw"}
-    local_drawnow ([opts.devopt " " gp_opts], opts.name, opts);
-  case opts.ghostscript.device
-    gp_opts = font_spec (opts, "devopt", "eps");
-    opts.ghostscript.output = opts.name;
-    opts.ghostscript.source = strcat (tmpnam (), ".eps");
-    eps_drawnow (opts, opts.ghostscript.source, gp_opts);
-    [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
-    if (opts.send_to_printer || isempty (opts.name))
-      cmd_lpr = opts.lpr_cmd (opts);
-      cmd = [cmd_gs " | " cmd_lpr];
-    else
-      cmd = cmd_gs;
-    endif
-    if (dos_shell)
-      cmd = sprintf ("%s & del %s", cmd, strrep (opts.ghostscript.source, '/', '\'));
-    else
-      cmd = sprintf ("%s ; rm %s", cmd, opts.ghostscript.source);
-    endif
-    if (! isempty (cmd_cleanup))
-      if (dos_shell)
-        pipeline = {[cmd " & " cmd_cleanup]};
-      else
-        pipeline = {[cmd " ; " cmd_cleanup]};
-      endif
-    else
-      pipeline = {cmd};
-    endif
-  otherwise
-    error (sprintf ("print:no%soutput", opts.devopt),
-           "print.m: %s output is not available for the Gnuplot graphics toolkit",
-           upper (opts.devopt));
+             "print.m: %s output is not available for the Gnuplot graphics toolkit",
+             upper (opts.devopt));
   endswitch
 
 
@@ -170,7 +171,7 @@
 function eps_drawnow (opts, epsfile, gp_opts)
   [h, fontsize] = get_figure_text_objs (opts);
   unwind_protect
-    fontsize_2x = cellfun (@(x) 2*x, fontsize, "uniformoutput", false);
+    fontsize_2x = cellfun (@times, {2}, fontsize, "uniformoutput", false);
     set (h, {"fontsize"}, fontsize_2x);
     local_drawnow (["postscript eps " gp_opts], epsfile, opts);
   unwind_protect_cleanup
@@ -198,96 +199,96 @@
   endfor
   f = "";
   switch (opts.devopt)
-  case "cgm"
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("%d", opts.fontsize);
-    endif
-  case {"eps", "eps2", "epsc", "epsc2"}
-    ## Gnuplot renders fonts as half their specification, which
-    ## results in a tight spacing for the axes-labels and tick-labels.
-    ## Compensate for the half scale. This will produce the proper
-    ## spacing for the requested fontsize.
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('font "%s,%d"', opts.font, 2 * opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("%d", 2 * opts.fontsize);
-    endif
-  case "svg"
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      fontsize = round (opts.fontsize * 0.75);
-      f = sprintf ('fname "%s" fsize %d', opts.font, fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('fname "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      fontsize = round (opts.fontsize * 0.75);
-      f = sprintf ("%s fsize %d", f, fontsize);
-    endif
-  case "pdf"
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("fsize %d", f, opts.fontsize);
-    endif
-  case {"pdfcairo", "pngcairo"}
-    if (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    endif
-  case {"epslatex", "epslatexstandalone"}
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("%d", opts.fontsize);
-    endif
-  case "pslatex"
-    if (! isempty (opts.fontsize))
-      f = sprintf ("%d", opts.fontsize);
-    endif
-  case {"gif", "jpeg", "png"}
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('font "%s ,%d"', opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('font "%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ('font "%d"', opts.fontsize);
-    endif
-  case "emf"
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ('"%s" %d', opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ('"%s"', opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("%d", opts.fontsize);
-    endif
-  case "canvas"
-    if (! isempty (opts.fontsize))
-      f = sprintf ("fsize %d", opts.fontsize);
-    endif
-  case {"aifm", "corel"}
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ("%s %d", opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ("%s", opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("%d", opts.fontsize);
-    endif
-  case "fig"
-    if (! isempty (opts.font) && ! isempty (opts.fontsize))
-      f = sprintf ("font %s fontsize %d", opts.font, opts.fontsize);
-    elseif (! isempty (opts.font))
-      f = sprintf ("font %s", opts.font);
-    elseif (! isempty (opts.fontsize))
-      f = sprintf ("fontsize %d", opts.fontsize);
-    endif
+    case "cgm"
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("%d", opts.fontsize);
+      endif
+    case {"eps", "eps2", "epsc", "epsc2"}
+      ## Gnuplot renders fonts as half their specification, which
+      ## results in a tight spacing for the axes-labels and tick-labels.
+      ## Compensate for the half scale. This will produce the proper
+      ## spacing for the requested fontsize.
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('font "%s,%d"', opts.font, 2 * opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("%d", 2 * opts.fontsize);
+      endif
+    case "svg"
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        fontsize = round (opts.fontsize * 0.75);
+        f = sprintf ('fname "%s" fsize %d', opts.font, fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('fname "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        fontsize = round (opts.fontsize * 0.75);
+        f = sprintf ("%s fsize %d", f, fontsize);
+      endif
+    case "pdf"
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("fsize %d", f, opts.fontsize);
+      endif
+    case {"pdfcairo", "pngcairo"}
+      if (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      endif
+    case {"epslatex", "epslatexstandalone"}
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('font "%s,%d"', opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("%d", opts.fontsize);
+      endif
+    case "pslatex"
+      if (! isempty (opts.fontsize))
+        f = sprintf ("%d", opts.fontsize);
+      endif
+    case {"gif", "jpeg", "png"}
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('font "%s ,%d"', opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('font "%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ('font "%d"', opts.fontsize);
+      endif
+    case "emf"
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ('"%s" %d', opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ('"%s"', opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("%d", opts.fontsize);
+      endif
+    case "canvas"
+      if (! isempty (opts.fontsize))
+        f = sprintf ("fsize %d", opts.fontsize);
+      endif
+    case {"aifm", "corel"}
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ("%s %d", opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ("%s", opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("%d", opts.fontsize);
+      endif
+    case "fig"
+      if (! isempty (opts.font) && ! isempty (opts.fontsize))
+        f = sprintf ("font %s fontsize %d", opts.font, opts.fontsize);
+      elseif (! isempty (opts.font))
+        f = sprintf ("font %s", opts.font);
+      elseif (! isempty (opts.fontsize))
+        f = sprintf ("fontsize %d", opts.fontsize);
+      endif
   endswitch
 endfunction
 
@@ -306,9 +307,10 @@
   h(is_legend_key_string) = [];
   fontsize = get (h, "fontsize");
   switch (numel (fontsize))
-  case 0
-    fontsize = {};
-  case 1
-    fontsize = {fontsize};
+    case 0
+      fontsize = {};
+    case 1
+      fontsize = {fontsize};
   endswitch
 endfunction
+
--- a/scripts/plot/private/__go_draw_axes__.m
+++ b/scripts/plot/private/__go_draw_axes__.m
@@ -26,800 +26,666 @@
 function __go_draw_axes__ (h, plot_stream, enhanced, mono,
                            bg_is_set, fg_is_set, hlgnd)
 
-  if (nargin >= 4 && nargin <= 7)
+  showhiddenhandles = get (0, "showhiddenhandles");
+  unwind_protect
+    set (0, "showhiddenhandles", "on");
+    axis_obj = __get__ (h);
+  unwind_protect_cleanup
+    set (0, "showhiddenhandles", showhiddenhandles);
+  end_unwind_protect
+
+  parent_figure_obj = get (axis_obj.parent);
+  gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM");
+
+  ## Set to false for plotyy axes.
+  ymirror = true;
+  if (isfield (axis_obj, "__plotyy_axes__"))
+    if (all (ishandle (axis_obj.__plotyy_axes__)))
+      ymirror = false;
+    else
+      h = axis_obj.__plotyy_axes__;
+      h = h(ishandle (h));
+      h = h(isprop (h, "__plotyy_axes__"));
+      rmappdata (h, "__plotyy_axes__");
+    endif
+  endif
+
+  nd = __calc_dimensions__ (h);
+
+  if (strcmp (axis_obj.dataaspectratiomode, "manual")
+      && strcmp (axis_obj.xlimmode, "manual")
+      && strcmp (axis_obj.ylimmode, "manual"))
+    ## All can't be "manual"
+    axis_obj.plotboxaspectratiomode = "auto";
+  endif
 
-    showhiddenhandles = get (0, "showhiddenhandles");
-    unwind_protect
-      set (0, "showhiddenhandles", "on");
-      axis_obj = __get__ (h);
-    unwind_protect_cleanup
-      set (0, "showhiddenhandles", showhiddenhandles);
-    end_unwind_protect
+  if (strcmp (axis_obj.dataaspectratiomode, "manual")
+      && strcmp (axis_obj.xlimmode, "manual")
+      && strcmp (axis_obj.ylimmode, "manual")
+      && (nd == 2 || all (mod (axis_obj.view, 90) == 0)))
+    ## FIXME - adjust plotboxaspectratio to respect other
+    fpos = get (axis_obj.parent, "position");
+    apos = axis_obj.position;
+  endif
+
+  pos = __actual_axis_position__ (h);
+
+  if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
+    dr = axis_obj.dataaspectratio;
+    if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
+      dr = dr(1) / dr(2);
+    else
+      ## FIXME - need to properly implement 3D
+      dr = mean (dr(1:2)) / dr(3);
+    endif
+  else
+    dr = 1;
+  endif
+
+  if (strcmp (axis_obj.activepositionproperty, "position"))
+    if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
+      if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
+        x = [1, 1];
+      else
+        ## 3D plots need to be sized down to fit in the window.
+        x = 1.0 ./ sqrt ([2, 2.5]);
+      endif
+      fprintf (plot_stream, "set tmargin screen %.15g;\n",
+               pos(2)+pos(4)/2+x(2)*pos(4)/2);
+      fprintf (plot_stream, "set bmargin screen %.15g;\n",
+               pos(2)+pos(4)/2-x(2)*pos(4)/2);
+      fprintf (plot_stream, "set lmargin screen %.15g;\n",
+               pos(1)+pos(3)/2-x(1)*pos(3)/2);
+      fprintf (plot_stream, "set rmargin screen %.15g;\n",
+               pos(1)+pos(3)/2+x(1)*pos(3)/2);
+      sz_str = "";
+    else
+      fprintf (plot_stream, "set tmargin 0;\n");
+      fprintf (plot_stream, "set bmargin 0;\n");
+      fprintf (plot_stream, "set lmargin 0;\n");
+      fprintf (plot_stream, "set rmargin 0;\n");
 
-    parent_figure_obj = get (axis_obj.parent);
-    gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM");
+      if (nd == 3 && all (axis_obj.view == [0, 90]))
+        ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot
+        pos(3:4) = pos(3:4) * 1.4;
+        pos(1:2) = pos(1:2) - pos(3:4) * 0.125;
+      endif
+
+      fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2));
+
+      if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
+        sz_str = sprintf ("set size ratio %.15g", -dr);
+      else
+        sz_str = "set size noratio";
+      endif
+      sz_str = sprintf ("%s %.15g, %.15g;\n", sz_str, pos(3), pos(4));
+    endif
+  else ## activepositionproperty == outerposition
+    fprintf (plot_stream, "unset tmargin;\n");
+    fprintf (plot_stream, "unset bmargin;\n");
+    fprintf (plot_stream, "unset lmargin;\n");
+    fprintf (plot_stream, "unset rmargin;\n");
+    fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2));
+    sz_str = "";
+    if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
+      sz_str = sprintf ("ratio %g", -dr);
+    else
+      sz_str = "noratio";
+    endif
+    sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4));
+  endif
+  if (! isempty (sz_str))
+    fputs (plot_stream, sz_str);
+  endif
 
-    ## Set to false for plotyy axes.
-    ymirror = true;
-    if (isfield (axis_obj, "__plotyy_axes__"))
-      if (all (ishandle (axis_obj.__plotyy_axes__)))
-        ymirror = false;
+  ## Reset all labels, axis-labels, tick-labels, and title
+  ## FIXME - We should have an function to initialize the axis.
+  ##         Presently, this is dispersed in this function.
+  fputs (plot_stream, "unset label;\n");
+  fputs (plot_stream, "unset xtics;\n");
+  fputs (plot_stream, "unset ytics;\n");
+  fputs (plot_stream, "unset ztics;\n");
+  fputs (plot_stream, "unset x2tics;\n");
+  fputs (plot_stream, "unset x2tics;\n");
+
+  if (! isempty (axis_obj.title))
+    t = get (axis_obj.title);
+    if (isempty (t.string))
+      fputs (plot_stream, "unset title;\n");
+    else
+      [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+      fontspec = create_fontspec (f, s, gnuplot_term);
+      fprintf (plot_stream, "set title \"%s\" %s %s;\n",
+               undo_string_escapes (tt), fontspec,
+               __do_enhanced_option__ (enhanced, t));
+    endif
+  endif
+
+  if (! isempty (axis_obj.xlabel))
+    t = get (axis_obj.xlabel);
+    angle = t.rotation;
+    colorspec = get_text_colorspec (axis_obj.xcolor, mono);
+    if (isempty (t.string))
+      fprintf (plot_stream, "unset xlabel;\n");
+      fprintf (plot_stream, "unset x2label;\n");
+    else
+      [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+      fontspec = create_fontspec (f, s, gnuplot_term);
+      if (strcmpi (axis_obj.xaxislocation, "top"))
+        fprintf (plot_stream, "set x2label \"%s\" %s %s %s",
+                 undo_string_escapes (tt), colorspec, fontspec,
+                 __do_enhanced_option__ (enhanced, t));
       else
-        h = axis_obj.__plotyy_axes__;
-        h = h(ishandle (h));
-        h = h(isprop (h, "__plotyy_axes__"));
-        rmappdata (h, "__plotyy_axes__");
+        fprintf (plot_stream, "set xlabel \"%s\" %s %s %s",
+                 undo_string_escapes (tt), colorspec, fontspec,
+                 __do_enhanced_option__ (enhanced, t));
+      endif
+      fprintf (plot_stream, " rotate by %f;\n", angle);
+      if (strcmpi (axis_obj.xaxislocation, "top"))
+        fprintf (plot_stream, "unset xlabel;\n");
+      else
+        fprintf (plot_stream, "unset x2label;\n");
       endif
     endif
-
-    nd = __calc_dimensions__ (h);
-
-    if (strcmp (axis_obj.dataaspectratiomode, "manual")
-        && strcmp (axis_obj.xlimmode, "manual")
-        && strcmp (axis_obj.ylimmode, "manual"))
-      ## All can't be "manual"
-      axis_obj.plotboxaspectratiomode = "auto";
-    endif
-
-    if (strcmp (axis_obj.dataaspectratiomode, "manual")
-        && strcmp (axis_obj.xlimmode, "manual")
-        && strcmp (axis_obj.ylimmode, "manual")
-        && (nd == 2 || all (mod (axis_obj.view, 90) == 0)))
-      ## FIXME - adjust plotboxaspectratio to respect other
-      fpos = get (axis_obj.parent, "position");
-      apos = axis_obj.position;
-    endif
-
-    pos = __actual_axis_position__ (h);
+  endif
 
-    if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
-      dr = axis_obj.dataaspectratio;
-      if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
-        dr = dr(1) / dr(2);
-      else
-        ## FIXME - need to properly implement 3D
-        dr = mean (dr(1:2)) / dr(3);
-      endif
+  if (! isempty (axis_obj.ylabel))
+    t = get (axis_obj.ylabel);
+    angle = t.rotation;
+    colorspec = get_text_colorspec (axis_obj.ycolor, mono);
+    if (isempty (t.string))
+      fprintf (plot_stream, "unset ylabel;\n");
+      fprintf (plot_stream, "unset y2label;\n");
     else
-      dr = 1;
-    endif
-
-    if (strcmp (axis_obj.activepositionproperty, "position"))
-      if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin"))
-        if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
-          x = [1, 1];
-        else
-          ## 3D plots need to be sized down to fit in the window.
-          x = 1.0 ./ sqrt ([2, 2.5]);
-        endif
-        fprintf (plot_stream, "set tmargin screen %.15g;\n",
-                 pos(2)+pos(4)/2+x(2)*pos(4)/2);
-        fprintf (plot_stream, "set bmargin screen %.15g;\n",
-                 pos(2)+pos(4)/2-x(2)*pos(4)/2);
-        fprintf (plot_stream, "set lmargin screen %.15g;\n",
-                 pos(1)+pos(3)/2-x(1)*pos(3)/2);
-        fprintf (plot_stream, "set rmargin screen %.15g;\n",
-                 pos(1)+pos(3)/2+x(1)*pos(3)/2);
-        sz_str = "";
+      [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+      fontspec = create_fontspec (f, s, gnuplot_term);
+      if (strcmpi (axis_obj.yaxislocation, "right"))
+        fprintf (plot_stream, "set y2label \"%s\" %s %s %s",
+                 undo_string_escapes (tt), colorspec, fontspec,
+                 __do_enhanced_option__ (enhanced, t));
       else
-        fprintf (plot_stream, "set tmargin 0;\n");
-        fprintf (plot_stream, "set bmargin 0;\n");
-        fprintf (plot_stream, "set lmargin 0;\n");
-        fprintf (plot_stream, "set rmargin 0;\n");
-
-        if (nd == 3 && all (axis_obj.view == [0, 90]))
-          ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot
-          pos(3:4) = pos(3:4) * 1.4;
-          pos(1:2) = pos(1:2) - pos(3:4) * 0.125;
-        endif
-
-        fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2));
-
-        if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
-          sz_str = sprintf ("set size ratio %.15g", -dr);
-        else
-          sz_str = "set size noratio";
-        endif
-        sz_str = sprintf ("%s %.15g, %.15g;\n", sz_str, pos(3), pos(4));
-      endif
-    else ## activepositionproperty == outerposition
-      fprintf (plot_stream, "unset tmargin;\n");
-      fprintf (plot_stream, "unset bmargin;\n");
-      fprintf (plot_stream, "unset lmargin;\n");
-      fprintf (plot_stream, "unset rmargin;\n");
-      fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2));
-      sz_str = "";
-      if (strcmpi (axis_obj.dataaspectratiomode, "manual"))
-        sz_str = sprintf ("ratio %g", -dr);
-      else
-        sz_str = "noratio";
-      endif
-      sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4));
-    endif
-    if (! isempty (sz_str))
-      fputs (plot_stream, sz_str);
-    endif
-
-    ## Reset all labels, axis-labels, tick-labels, and title
-    ## FIXME - We should have an function to initialize the axis.
-    ##         Presently, this is dispersed in this function.
-    fputs (plot_stream, "unset label;\n");
-    fputs (plot_stream, "unset xtics;\n");
-    fputs (plot_stream, "unset ytics;\n");
-    fputs (plot_stream, "unset ztics;\n");
-    fputs (plot_stream, "unset x2tics;\n");
-    fputs (plot_stream, "unset x2tics;\n");
-
-    if (! isempty (axis_obj.title))
-      t = get (axis_obj.title);
-      if (isempty (t.string))
-        fputs (plot_stream, "unset title;\n");
-      else
-        [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
-        fontspec = create_fontspec (f, s, gnuplot_term);
-        fprintf (plot_stream, "set title \"%s\" %s %s;\n",
-                 undo_string_escapes (tt), fontspec,
+        fprintf (plot_stream, "set ylabel \"%s\" %s %s %s",
+                 undo_string_escapes (tt), colorspec, fontspec,
                  __do_enhanced_option__ (enhanced, t));
       endif
-    endif
-
-    if (! isempty (axis_obj.xlabel))
-      t = get (axis_obj.xlabel);
-      angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.xcolor, mono);
-      if (isempty (t.string))
-        fprintf (plot_stream, "unset xlabel;\n");
-        fprintf (plot_stream, "unset x2label;\n");
+      fprintf (plot_stream, " rotate by %f;\n", angle);
+      if (strcmpi (axis_obj.yaxislocation, "right"))
+        fprintf (plot_stream, "unset ylabel;\n");
       else
-        [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
-        fontspec = create_fontspec (f, s, gnuplot_term);
-        if (strcmpi (axis_obj.xaxislocation, "top"))
-          fprintf (plot_stream, "set x2label \"%s\" %s %s %s",
-                   undo_string_escapes (tt), colorspec, fontspec,
-                   __do_enhanced_option__ (enhanced, t));
-        else
-          fprintf (plot_stream, "set xlabel \"%s\" %s %s %s",
-                   undo_string_escapes (tt), colorspec, fontspec,
-                   __do_enhanced_option__ (enhanced, t));
-        endif
-        fprintf (plot_stream, " rotate by %f;\n", angle);
-        if (strcmpi (axis_obj.xaxislocation, "top"))
-          fprintf (plot_stream, "unset xlabel;\n");
-        else
-          fprintf (plot_stream, "unset x2label;\n");
-        endif
+        fprintf (plot_stream, "unset y2label;\n");
       endif
     endif
+  endif
 
-    if (! isempty (axis_obj.ylabel))
-      t = get (axis_obj.ylabel);
-      angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.ycolor, mono);
-      if (isempty (t.string))
-        fprintf (plot_stream, "unset ylabel;\n");
-        fprintf (plot_stream, "unset y2label;\n");
-      else
-        [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
-        fontspec = create_fontspec (f, s, gnuplot_term);
-        if (strcmpi (axis_obj.yaxislocation, "right"))
-          fprintf (plot_stream, "set y2label \"%s\" %s %s %s",
-                   undo_string_escapes (tt), colorspec, fontspec,
-                   __do_enhanced_option__ (enhanced, t));
-        else
-          fprintf (plot_stream, "set ylabel \"%s\" %s %s %s",
-                   undo_string_escapes (tt), colorspec, fontspec,
-                   __do_enhanced_option__ (enhanced, t));
-        endif
-        fprintf (plot_stream, " rotate by %f;\n", angle);
-        if (strcmpi (axis_obj.yaxislocation, "right"))
-          fprintf (plot_stream, "unset ylabel;\n");
-        else
-          fprintf (plot_stream, "unset y2label;\n");
-        endif
-      endif
-    endif
-
-    if (! isempty (axis_obj.zlabel))
-      t = get (axis_obj.zlabel);
-      angle = t.rotation;
-      colorspec = get_text_colorspec (axis_obj.zcolor, mono);
-      if (isempty (t.string))
-        fputs (plot_stream, "unset zlabel;\n");
-      else
-        [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
-        fontspec = create_fontspec (f, s, gnuplot_term);
-        fprintf (plot_stream, "set zlabel \"%s\" %s %s %s",
-                 undo_string_escapes (tt), colorspec, fontspec,
-                 __do_enhanced_option__ (enhanced, t));
-        fprintf (plot_stream, " rotate by %f;\n", angle);
-      endif
-    endif
-
-    if (strcmpi (axis_obj.xaxislocation, "top"))
-      xaxisloc = "x2";
-      xaxisloc_using = "x2";
+  if (! isempty (axis_obj.zlabel))
+    t = get (axis_obj.zlabel);
+    angle = t.rotation;
+    colorspec = get_text_colorspec (axis_obj.zcolor, mono);
+    if (isempty (t.string))
+      fputs (plot_stream, "unset zlabel;\n");
     else
-      xaxisloc = "x";
-      xaxisloc_using = "x1";
-      if (strcmpi (axis_obj.xaxislocation, "zero"))
-        fputs (plot_stream, "set xzeroaxis;\n");
-      endif
+      [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
+      fontspec = create_fontspec (f, s, gnuplot_term);
+      fprintf (plot_stream, "set zlabel \"%s\" %s %s %s",
+               undo_string_escapes (tt), colorspec, fontspec,
+               __do_enhanced_option__ (enhanced, t));
+      fprintf (plot_stream, " rotate by %f;\n", angle);
+    endif
+  endif
+
+  if (strcmpi (axis_obj.xaxislocation, "top"))
+    xaxisloc = "x2";
+    xaxisloc_using = "x2";
+  else
+    xaxisloc = "x";
+    xaxisloc_using = "x1";
+    if (strcmpi (axis_obj.xaxislocation, "zero"))
+      fputs (plot_stream, "set xzeroaxis;\n");
     endif
-    if (strcmpi (axis_obj.yaxislocation, "right"))
-      yaxisloc = "y2";
-      yaxisloc_using = "y2";
-    else
-      yaxisloc = "y";
-      yaxisloc_using = "y1";
-      if (strcmpi (axis_obj.yaxislocation, "zero"))
-        fputs (plot_stream, "set yzeroaxis;\n");
-      endif
+  endif
+  if (strcmpi (axis_obj.yaxislocation, "right"))
+    yaxisloc = "y2";
+    yaxisloc_using = "y2";
+  else
+    yaxisloc = "y";
+    yaxisloc_using = "y1";
+    if (strcmpi (axis_obj.yaxislocation, "zero"))
+      fputs (plot_stream, "set yzeroaxis;\n");
     endif
+  endif
 
-    have_grid = false;
+  have_grid = false;
+
+  if (strcmpi (axis_obj.xgrid, "on"))
+    have_grid = true;
+    fprintf (plot_stream, "set grid %stics;\n", xaxisloc);
+  else
+    fprintf (plot_stream, "set grid no%stics;\n", xaxisloc);
+  endif
 
-    if (strcmpi (axis_obj.xgrid, "on"))
-      have_grid = true;
-      fprintf (plot_stream, "set grid %stics;\n", xaxisloc);
-    else
-      fprintf (plot_stream, "set grid no%stics;\n", xaxisloc);
-    endif
+  if (strcmpi (axis_obj.ygrid, "on"))
+    have_grid = true;
+    fprintf (plot_stream, "set grid %stics;\n", yaxisloc);
+  else
+    fprintf (plot_stream, "set grid no%stics;\n", yaxisloc);
+  endif
+
+  if (strcmpi (axis_obj.zgrid, "on"))
+    have_grid = true;
+    fputs (plot_stream, "set grid ztics;\n");
+  else
+    fputs (plot_stream, "set grid noztics;\n");
+  endif
 
-    if (strcmpi (axis_obj.ygrid, "on"))
-      have_grid = true;
-      fprintf (plot_stream, "set grid %stics;\n", yaxisloc);
+  if (strcmpi (axis_obj.xminorgrid, "on"))
+    have_grid = true;
+    if (strcmp (axis_obj.xscale, "log"))
+      m = 10;
     else
-      fprintf (plot_stream, "set grid no%stics;\n", yaxisloc);
+      m = 5;
     endif
+    fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m);
+    fprintf (plot_stream, "set grid m%stics;\n", xaxisloc);
+  else
+    fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc);
+  endif
 
-    if (strcmpi (axis_obj.zgrid, "on"))
-      have_grid = true;
-      fputs (plot_stream, "set grid ztics;\n");
+  if (strcmpi (axis_obj.yminorgrid, "on"))
+    have_grid = true;
+    if (strcmp (axis_obj.yscale, "log"))
+      m = 10;
     else
-      fputs (plot_stream, "set grid noztics;\n");
+      m = 5;
     endif
+    fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m);
+    fprintf (plot_stream, "set grid m%stics;\n", yaxisloc);
+  else
+    fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc);
+  endif
 
-    if (strcmpi (axis_obj.xminorgrid, "on"))
-      have_grid = true;
-      if (strcmp (axis_obj.xscale, "log"))
-        m = 10;
-      else
-        m = 5;
-      endif
-      fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m);
-      fprintf (plot_stream, "set grid m%stics;\n", xaxisloc);
+  if (strcmpi (axis_obj.zminorgrid, "on"))
+    have_grid = true;
+    if (strcmp (axis_obj.zscale, "log"))
+      m = 10;
     else
-      fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc);
+      m = 5;
     endif
+    fprintf (plot_stream, "set mztics %d;\n", m);
+    fputs (plot_stream, "set grid mztics;\n");
+  else
+    fputs (plot_stream, "set grid nomztics;\n");
+  endif
+
+  ## The grid front/back/layerdefault option also controls the
+  ## appearance of tics, so it is used even if the grid is absent.
+  if (strcmpi (axis_obj.layer, "top"))
+    fputs (plot_stream, "set grid front;\n");
+    fputs (plot_stream, "set border front;\n");
+  else
+    fputs (plot_stream, "set grid layerdefault;\n");
+    ## FIXME -- the gnuplot help says that "layerdefault" should work
+    ## for set border too, but it fails for me with gnuplot 4.2.5.  So
+    ## use "back" instead.
+    fputs (plot_stream, "set border back;\n");
+  endif
+
+  fprintf (plot_stream, "set grid linewidth %f, linewidth %f;\n",
+           axis_obj.linewidth, axis_obj.linewidth);
 
-    if (strcmpi (axis_obj.yminorgrid, "on"))
-      have_grid = true;
-      if (strcmp (axis_obj.yscale, "log"))
-        m = 10;
-      else
-        m = 5;
-      endif
-      fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m);
-      fprintf (plot_stream, "set grid m%stics;\n", yaxisloc);
-    else
-      fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc);
-    endif
+  if (! have_grid)
+    fputs (plot_stream, "unset grid;\n");
+  endif
+
+  xlogscale = strcmpi (axis_obj.xscale, "log");
+  ylogscale = strcmpi (axis_obj.yscale, "log");
+  zlogscale = strcmpi (axis_obj.zscale, "log");
 
-    if (strcmpi (axis_obj.zminorgrid, "on"))
-      have_grid = true;
-      if (strcmp (axis_obj.zscale, "log"))
-        m = 10;
-      else
-        m = 5;
-      endif
-      fprintf (plot_stream, "set mztics %d;\n", m);
-      fputs (plot_stream, "set grid mztics;\n");
-    else
-      fputs (plot_stream, "set grid nomztics;\n");
+  ## Detect logscale and negative lims
+  if (xlogscale && all (axis_obj.xlim < 0))
+    axis_obj.xsgn = -1;
+    if (strcmp (axis_obj.xdir, "reverse"))
+      axis_obj.xdir = "normal";
+    elseif (strcmp (axis_obj.xdir, "normal"))
+      axis_obj.xdir = "reverse";
     endif
+    axis_obj.xtick = -flip (axis_obj.xtick);
+    axis_obj.xticklabel = flip (axis_obj.xticklabel);
+    axis_obj.xlim = -flip (axis_obj.xlim);
+  else
+    axis_obj.xsgn = 1;
+  endif
+  if (ylogscale && all (axis_obj.ylim < 0))
+    axis_obj.ysgn = -1;
+    if (strcmp (axis_obj.ydir, "reverse"))
+      axis_obj.ydir = "normal";
+    elseif (strcmp (axis_obj.ydir, "normal"))
+      axis_obj.ydir = "reverse";
+    endif
+    axis_obj.ytick = -flip (axis_obj.ytick);
+    axis_obj.yticklabel = flip (axis_obj.yticklabel);
+    axis_obj.ylim = -flip (axis_obj.ylim);
+  else
+    axis_obj.ysgn = 1;
+  endif
+  if (zlogscale && all (axis_obj.zlim < 0))
+    axis_obj.zsgn = -1;
+    if (strcmp (axis_obj.zdir, "reverse"))
+      axis_obj.zdir = "normal";
+    elseif (strcmp (axis_obj.zdir, "normal"))
+      axis_obj.zdir = "reverse";
+    endif
+    axis_obj.ztick = -flip (axis_obj.ztick);
+    axis_obj.zticklabel = flip (axis_obj.zticklabel);
+    axis_obj.zlim = -flip (axis_obj.zlim);
+  else
+    axis_obj.zsgn = 1;
+  endif
 
-    ## The grid front/back/layerdefault option also controls the
-    ## appearance of tics, so it is used even if the grid is absent.
-    if (strcmpi (axis_obj.layer, "top"))
-      fputs (plot_stream, "set grid front;\n");
-      fputs (plot_stream, "set border front;\n");
-    else
-      fputs (plot_stream, "set grid layerdefault;\n");
-      ## FIXME -- the gnuplot help says that "layerdefault" should work
-      ## for set border too, but it fails for me with gnuplot 4.2.5.  So
-      ## use "back" instead.
-      fputs (plot_stream, "set border back;\n");
-    endif
+  xlim = axis_obj.xlim;
+  ylim = axis_obj.ylim;
+  zlim = axis_obj.zlim;
+  clim = axis_obj.clim;
 
-    fprintf (plot_stream, "set grid linewidth %f, linewidth %f;\n",
-             axis_obj.linewidth, axis_obj.linewidth);
-
-    if (! have_grid)
-      fputs (plot_stream, "unset grid;\n");
-    endif
-
-    xlogscale = strcmpi (axis_obj.xscale, "log");
-    ylogscale = strcmpi (axis_obj.yscale, "log");
-    zlogscale = strcmpi (axis_obj.zscale, "log");
+  do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term);
 
-    ## Detect logscale and negative lims
-    if (xlogscale && all (axis_obj.xlim < 0))
-      axis_obj.xsgn = -1;
-      if (strcmp (axis_obj.xdir, "reverse"))
-        axis_obj.xdir = "normal";
-      elseif (strcmp (axis_obj.xdir, "normal"))
-        axis_obj.xdir = "reverse";
-      endif
-      axis_obj.xtick = -flip (axis_obj.xtick);
-      axis_obj.xticklabel = flip (axis_obj.xticklabel);
-      axis_obj.xlim = -flip (axis_obj.xlim);
-    else
-      axis_obj.xsgn = 1;
-    endif
-    if (ylogscale && all (axis_obj.ylim < 0))
-      axis_obj.ysgn = -1;
-      if (strcmp (axis_obj.ydir, "reverse"))
-        axis_obj.ydir = "normal";
-      elseif (strcmp (axis_obj.ydir, "normal"))
-        axis_obj.ydir = "reverse";
-      endif
-      axis_obj.ytick = -flip (axis_obj.ytick);
-      axis_obj.yticklabel = flip (axis_obj.yticklabel);
-      axis_obj.ylim = -flip (axis_obj.ylim);
-    else
-      axis_obj.ysgn = 1;
+  fputs (plot_stream, "unset logscale;\n");
+  if (xlogscale)
+    fprintf (plot_stream, "set logscale %s;\n", xaxisloc);
+  endif
+  if (ylogscale)
+    fprintf (plot_stream, "set logscale %s;\n", yaxisloc);
+  endif
+  if (zlogscale)
+    fputs (plot_stream, "set logscale z;\n");
+  endif
+
+  xautoscale = strcmpi (axis_obj.xlimmode, "auto");
+  yautoscale = strcmpi (axis_obj.ylimmode, "auto");
+  zautoscale = strcmpi (axis_obj.zlimmode, "auto");
+  cautoscale = strcmpi (axis_obj.climmode, "auto");
+  cdatadirect = false;
+  truecolor = false;
+
+  fputs (plot_stream, "set clip two;\n");
+
+  kids = axis_obj.children;
+  ## Remove the axis labels and title from the children, and
+  ## preserved the original order.
+  [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ...
+                             axis_obj.zlabel; axis_obj.title]);
+  kids = kids (sort (k));
+
+  if (nd == 3)
+    fputs (plot_stream, "set parametric;\n");
+    fputs (plot_stream, "set style data lines;\n");
+    fputs (plot_stream, "set surface;\n");
+    fputs (plot_stream, "unset contour;\n");
+  endif
+
+  data_idx = 0;
+  data = cell ();
+  is_image_data = [];
+  hidden_removal = NaN;
+  view_map = false;
+
+  if (! cautoscale && clim(1) == clim(2))
+    clim(2)++;
+  endif
+  addedcmap = [];
+
+  ximg_data = {};
+  ximg_data_idx = 0;
+
+  while (! isempty (kids))
+
+    obj = get (kids(end));
+
+    if (isfield (obj, "xdata"))
+      obj.xdata = double (obj.xdata);
     endif
-    if (zlogscale && all (axis_obj.zlim < 0))
-      axis_obj.zsgn = -1;
-      if (strcmp (axis_obj.zdir, "reverse"))
-        axis_obj.zdir = "normal";
-      elseif (strcmp (axis_obj.zdir, "normal"))
-        axis_obj.zdir = "reverse";
-      endif
-      axis_obj.ztick = -flip (axis_obj.ztick);
-      axis_obj.zticklabel = flip (axis_obj.zticklabel);
-      axis_obj.zlim = -flip (axis_obj.zlim);
-    else
-      axis_obj.zsgn = 1;
+    if (isfield (obj, "ydata"))
+      obj.ydata = double (obj.ydata);
     endif
-
-    xlim = axis_obj.xlim;
-    ylim = axis_obj.ylim;
-    zlim = axis_obj.zlim;
-    clim = axis_obj.clim;
-
-    do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term);
-
-    fputs (plot_stream, "unset logscale;\n");
-    if (xlogscale)
-      fprintf (plot_stream, "set logscale %s;\n", xaxisloc);
-    endif
-    if (ylogscale)
-      fprintf (plot_stream, "set logscale %s;\n", yaxisloc);
-    endif
-    if (zlogscale)
-      fputs (plot_stream, "set logscale z;\n");
+    if (isfield (obj, "zdata"))
+      obj.zdata = double (obj.zdata);
     endif
 
-    xautoscale = strcmpi (axis_obj.xlimmode, "auto");
-    yautoscale = strcmpi (axis_obj.ylimmode, "auto");
-    zautoscale = strcmpi (axis_obj.zlimmode, "auto");
-    cautoscale = strcmpi (axis_obj.climmode, "auto");
-    cdatadirect = false;
-    truecolor = false;
-
-    fputs (plot_stream, "set clip two;\n");
+    if (isfield (obj, "units"))
+      units = obj.units;
+      unwind_protect
+        set (kids(end), "units", "data");
+        obj = get (kids(end));
+      unwind_protect_cleanup
+        set (kids(end), "units", units);
+      end_unwind_protect
+    endif
+    kids = kids(1:(end-1));
 
-    kids = axis_obj.children;
-    ## Remove the axis labels and title from the children, and
-    ## preserved the original order.
-    [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ...
-                               axis_obj.zlabel; axis_obj.title]);
-    kids = kids (sort (k));
+    if (strcmp (obj.visible, "off"))
+      continue;
+    endif
 
-    if (nd == 3)
-      fputs (plot_stream, "set parametric;\n");
-      fputs (plot_stream, "set style data lines;\n");
-      fputs (plot_stream, "set surface;\n");
-      fputs (plot_stream, "unset contour;\n");
+    if (xlogscale && isfield (obj, "xdata"))
+      obj.xdata = axis_obj.xsgn * obj.xdata;
+      obj.xdata(obj.xdata<=0) = NaN;
+    endif
+    if (ylogscale && isfield (obj, "ydata"))
+      obj.ydata = axis_obj.ysgn * obj.ydata;
+      obj.ydata(obj.ydata<=0) = NaN;
+    endif
+    if (zlogscale && isfield (obj, "zdata"))
+      obj.zdata = axis_obj.zsgn * obj.zdata;
+      obj.zdata(obj.zdata<=0) = NaN;
     endif
 
-    data_idx = 0;
-    data = cell ();
-    is_image_data = [];
-    hidden_removal = NaN;
-    view_map = false;
+    ## Check for facecolor interpolation for surfaces.
+    doing_interp_color = ...
+       isfield (obj, "facecolor") && strcmp (obj.facecolor, "interp");
 
-    if (! cautoscale && clim(1) == clim(2))
-      clim(2)++;
-    endif
-    addedcmap = [];
-
-    ximg_data = {};
-    ximg_data_idx = 0;
-
-    while (! isempty (kids))
-
-      obj = get (kids(end));
+    switch (obj.type)
+      case "image"
+        img_data = obj.cdata;
+        img_xdata = obj.xdata;
+        img_ydata = obj.ydata;
 
-      if (isfield (obj, "xdata"))
-        obj.xdata = double (obj.xdata);
-      end
-      if (isfield (obj, "ydata"))
-        obj.ydata = double (obj.ydata);
-      end
-      if (isfield (obj, "zdata"))
-        obj.zdata = double (obj.zdata);
-      end
+        if (ndims (img_data) == 3)
+          truecolor = true;
+        elseif (strcmpi (obj.cdatamapping, "direct"))
+          cdatadirect = true;
+        endif
+        data_idx++;
+        is_image_data(data_idx) = true;
+        parametric(data_idx) = false;
+        have_cdata(data_idx) = false;
+        have_3d_patch(data_idx) = false;
 
-      if (isfield (obj, "units"))
-        units = obj.units;
-        unwind_protect
-          set (kids(end), "units", "data");
-          obj = get (kids(end));
-        unwind_protect_cleanup
-          set (kids(end), "units", units);
-        end_unwind_protect
-      endif
-      kids = kids(1:(end-1));
-
-      if (strcmp (obj.visible, "off"))
-        continue;
-      endif
+        if (img_xdata(2) < img_xdata(1))
+          img_xdata = img_xdata(2:-1:1);
+          img_data = img_data(:,end:-1:1,:);
+        elseif (img_xdata(1) == img_xdata(2))
+          img_xdata = img_xdata(1) + [0, columns(img_data)-1];
+        endif
+        if (img_ydata(2) < img_ydata(1))
+          img_ydata = img_ydata(2:-1:1);
+          img_data = img_data(end:-1:1,:,:);
+        elseif (img_ydata(1) == img_ydata(2))
+          img_ydata = img_ydata(1) + [0, rows(img_data)-1];
+        endif
 
-      if (xlogscale && isfield (obj, "xdata"))
-        obj.xdata = axis_obj.xsgn * obj.xdata;
-        obj.xdata(obj.xdata<=0) = NaN;
-      endif
-      if (ylogscale && isfield (obj, "ydata"))
-        obj.ydata = axis_obj.ysgn * obj.ydata;
-        obj.ydata(obj.ydata<=0) = NaN;
-      endif
-      if (zlogscale && isfield (obj, "zdata"))
-        obj.zdata = axis_obj.zsgn * obj.zdata;
-        obj.zdata(obj.zdata<=0) = NaN;
-      endif
+        [y_dim, x_dim] = size (img_data(:,:,1));
+        if (x_dim > 1)
+          dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1);
+        else
+          x_dim = 2;
+          img_data = [img_data, img_data];
+          dx = abs (img_xdata(2)-img_xdata(1));
+        endif
+        if (y_dim > 1)
+          dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1);
+        else
+          y_dim = 2;
+          img_data = [img_data; img_data];
+          dy = abs (img_ydata(2)-img_ydata(1));
+        endif
 
-      ## Check for facecolor interpolation for surfaces.
-      doing_interp_color = ...
-         isfield (obj, "facecolor") && strncmp (obj.facecolor, "interp", 6);
+        x_origin = min (img_xdata);
+        y_origin = min (img_ydata);
 
-      switch (obj.type)
-        case "image"
-          img_data = obj.cdata;
-          img_xdata = obj.xdata;
-          img_ydata = obj.ydata;
+        if (ndims (img_data) == 3)
+          data{data_idx} = permute (img_data, [3, 1, 2])(:);
+          format = "1:2:3";
+          imagetype = "rgbimage";
+        else
+          data{data_idx} = img_data(:);
+          format = "1";
+          imagetype = "image";
+        endif
 
-          if (ndims (img_data) == 3)
-            truecolor = true;
-          elseif (strcmpi (obj.cdatamapping, "direct"))
-            cdatadirect = true;
-          endif
-          data_idx++;
-          is_image_data(data_idx) = true;
-          parametric(data_idx) = false;
-          have_cdata(data_idx) = false;
-          have_3d_patch(data_idx) = false;
+        titlespec{data_idx} = "title \"\"";
+        usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s",
+            x_dim, y_dim, x_origin, y_origin, dx, dy, format);
+        withclause{data_idx} = sprintf ("with %s;", imagetype);
 
-          if (img_xdata(2) < img_xdata(1))
-            img_xdata = img_xdata(2:-1:1);
-            img_data = img_data(:,end:-1:1,:);
-          elseif (img_xdata(1) == img_xdata(2))
-            img_xdata = img_xdata(1) + [0, columns(img_data)-1];
-          endif
-          if (img_ydata(2) < img_ydata(1))
-            img_ydata = img_ydata(2:-1:1);
-            img_data = img_data(end:-1:1,:,:);
-          elseif (img_ydata(1) == img_ydata(2))
-            img_ydata = img_ydata(1) + [0, rows(img_data)-1];
-          endif
-
-          [y_dim, x_dim] = size (img_data(:,:,1));
-          if (x_dim > 1)
-            dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1);
-          else
-            x_dim = 2;
-            img_data = [img_data, img_data];
-            dx = abs (img_xdata(2)-img_xdata(1));
-          endif
-          if (y_dim > 1)
-            dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1);
+      case "line"
+        if (strcmp (obj.linestyle, "none")
+            && (! isfield (obj, "marker")
+                || (isfield (obj, "marker")
+                    && strcmp (obj.marker, "none"))))
+          continue;
+        endif
+        data_idx++;
+        is_image_data(data_idx) = false;
+        parametric(data_idx) = true;
+        have_cdata(data_idx) = false;
+        have_3d_patch(data_idx) = false;
+        if (isempty (obj.displayname))
+          titlespec{data_idx} = "title \"\"";
+        else
+          tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+          titlespec{data_idx} = ['title "' tmp '"'];
+        endif
+        usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
+        errbars = "";
+        if (nd == 3)
+          xdat = obj.xdata(:);
+          ydat = obj.ydata(:);
+          if (! isempty (obj.zdata))
+            zdat = obj.zdata(:);
           else
-            y_dim = 2;
-            img_data = [img_data; img_data];
-            dy = abs (img_ydata(2)-img_ydata(1));
-          endif
-
-          x_origin = min (img_xdata);
-          y_origin = min (img_ydata);
-
-          if (ndims (img_data) == 3)
-            data{data_idx} = permute (img_data, [3, 1, 2])(:);
-            format = "1:2:3";
-            imagetype = "rgbimage";
-          else
-            data{data_idx} = img_data(:);
-            format = "1";
-            imagetype = "image";
-          endif
-
-          titlespec{data_idx} = "title \"\"";
-          usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s",
-              x_dim, y_dim, x_origin, y_origin, dx, dy, format);
-          withclause{data_idx} = sprintf ("with %s;", imagetype);
-
-        case "line"
-          if (strncmp (obj.linestyle, "none", 4)
-              && (! isfield (obj, "marker")
-                  || (isfield (obj, "marker")
-                      && strncmp (obj.marker, "none", 4))))
-            continue;
-          endif
-          data_idx++;
-          is_image_data(data_idx) = false;
-          parametric(data_idx) = true;
-          have_cdata(data_idx) = false;
-          have_3d_patch(data_idx) = false;
-          if (isempty (obj.displayname))
-            titlespec{data_idx} = "title \"\"";
-          else
-            tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
-            titlespec{data_idx} = ['title "' tmp '"'];
+            zdat = zeros (size (xdat));
           endif
-          usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
-          errbars = "";
-          if (nd == 3)
-            xdat = obj.xdata(:);
-            ydat = obj.ydata(:);
-            if (! isempty (obj.zdata))
-              zdat = obj.zdata(:);
-            else
-              zdat = zeros (size (xdat));
-            endif
-            data{data_idx} = [xdat, ydat, zdat]';
-            usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat));
-            ## fputs (plot_stream, "set parametric;\n");
-          else
-            xdat = obj.xdata(:);
-            ydat = obj.ydata(:);
-            data{data_idx} = [xdat, ydat]';
-            usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s",
-                                            rows (xdat), xaxisloc_using, yaxisloc_using);
-          endif
+          data{data_idx} = [xdat, ydat, zdat]';
+          usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat));
+          ## fputs (plot_stream, "set parametric;\n");
+        else
+          xdat = obj.xdata(:);
+          ydat = obj.ydata(:);
+          data{data_idx} = [xdat, ydat]';
+          usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s",
+                                          rows (xdat), xaxisloc_using, yaxisloc_using);
+        endif
 
-          style = do_linestyle_command (obj, obj.color, data_idx, mono,
-                                        plot_stream, errbars);
+        style = do_linestyle_command (obj, obj.color, data_idx, mono,
+                                      plot_stream, errbars);
 
-          withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                          style{1}, data_idx);
+        withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                        style{1}, data_idx);
 
-          if (length (style) > 1)
-            data_idx++;
-            is_image_data(data_idx) = is_image_data(data_idx - 1);
-            parametric(data_idx) = parametric(data_idx - 1);
-            have_cdata(data_idx) = have_cdata(data_idx - 1);
-            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-            titlespec{data_idx} = "title \"\"";
-            usingclause{data_idx} = usingclause{data_idx - 1};
-            data{data_idx} = data{data_idx - 1};
-            withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                          style{2}, data_idx);
-          endif
-          if (length (style) > 2)
-            data_idx++;
-            is_image_data(data_idx) = is_image_data(data_idx - 1);
-            parametric(data_idx) = parametric(data_idx - 1);
-            have_cdata(data_idx) = have_cdata(data_idx - 1);
-            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-            titlespec{data_idx} = "title \"\"";
-            usingclause{data_idx} = usingclause{data_idx - 1};
-            data{data_idx} = data{data_idx - 1};
-            withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                          style{3}, data_idx);
-          endif
+        if (length (style) > 1)
+          data_idx++;
+          is_image_data(data_idx) = is_image_data(data_idx - 1);
+          parametric(data_idx) = parametric(data_idx - 1);
+          have_cdata(data_idx) = have_cdata(data_idx - 1);
+          have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+          titlespec{data_idx} = "title \"\"";
+          usingclause{data_idx} = usingclause{data_idx - 1};
+          data{data_idx} = data{data_idx - 1};
+          withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                        style{2}, data_idx);
+        endif
+        if (length (style) > 2)
+          data_idx++;
+          is_image_data(data_idx) = is_image_data(data_idx - 1);
+          parametric(data_idx) = parametric(data_idx - 1);
+          have_cdata(data_idx) = have_cdata(data_idx - 1);
+          have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+          titlespec{data_idx} = "title \"\"";
+          usingclause{data_idx} = usingclause{data_idx - 1};
+          data{data_idx} = data{data_idx - 1};
+          withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                        style{3}, data_idx);
+        endif
 
-       case "patch"
-         cmap = parent_figure_obj.colormap;
-         [nr, nc] = size (obj.xdata);
+     case "patch"
+       cmap = parent_figure_obj.colormap;
+       [nr, nc] = size (obj.xdata);
 
-         if (! isempty (obj.cdata))
-           cdat = obj.cdata;
-           if (strcmpi (obj.cdatamapping, "direct"))
-             cdatadirect = true;
+       if (! isempty (obj.cdata))
+         cdat = obj.cdata;
+         if (strcmpi (obj.cdatamapping, "direct"))
+           cdatadirect = true;
+         endif
+       else
+         cdat = [];
+       endif
+
+       data_3d_idx = NaN;
+       for i = 1:nc
+         xcol = obj.xdata(:,i);
+         ycol = obj.ydata(:,i);
+         if (nd == 3)
+           if (! isempty (obj.zdata))
+             zcol = obj.zdata(:,i);
+           else
+             zcol = zeros (size (xcol));
            endif
-         else
-           cdat = [];
          endif
 
-         data_3d_idx = NaN;
-         for i = 1:nc
-           xcol = obj.xdata(:,i);
-           ycol = obj.ydata(:,i);
-           if (nd == 3)
-             if (! isempty (obj.zdata))
-               zcol = obj.zdata(:,i);
-             else
-               zcol = zeros (size (xcol));
-             endif
-           endif
-
-           if (! isnan (xcol) && ! isnan (ycol))
-             ## Is the patch closed or not
-             if (strncmp (obj.facecolor, "none", 4))
-               hidden_removal = false;
-             else
+         if (! isnan (xcol) && ! isnan (ycol))
+           ## Is the patch closed or not
+           if (strcmp (obj.facecolor, "none"))
+             hidden_removal = false;
+           else
 
-               if (isnan (hidden_removal))
-                 hidden_removal = true;
-               endif
-               if (nd == 3)
-                 if (numel (xcol) > 3)
-                   error ("__go_draw_axes__: gnuplot (as of v4.2) only supports 3D filled triangular patches");
-                 else
-                   if (isnan (data_3d_idx))
-                     data_idx++;
-                     data_3d_idx = data_idx;
-                     is_image_data(data_idx) = false;
-                     parametric(data_idx) = false;
-                     have_cdata(data_idx) = true;
-                     have_3d_patch(data_idx) = true;
-                     withclause{data_3d_idx} = sprintf ("with pm3d");
-                     usingclause{data_3d_idx} =  "using 1:2:3:4";
-                     data{data_3d_idx} = [];
-                   endif
-                   local_idx = data_3d_idx;
-                   ccdat = NaN;
+             if (isnan (hidden_removal))
+               hidden_removal = true;
+             endif
+             if (nd == 3)
+               if (numel (xcol) > 3)
+                 error ("__go_draw_axes__: gnuplot (as of v4.2) only supports 3-D filled triangular patches");
+               else
+                 if (isnan (data_3d_idx))
+                   data_idx++;
+                   data_3d_idx = data_idx;
+                   is_image_data(data_idx) = false;
+                   parametric(data_idx) = false;
+                   have_cdata(data_idx) = true;
+                   have_3d_patch(data_idx) = true;
+                   withclause{data_3d_idx} = sprintf ("with pm3d");
+                   usingclause{data_3d_idx} =  "using 1:2:3:4";
+                   data{data_3d_idx} = [];
                  endif
-               else
-                 data_idx++;
-                 local_idx = data_idx;
-                 is_image_data(data_idx) = false;
-                 parametric(data_idx) = false;
-                 have_cdata(data_idx) = false;
-                 have_3d_patch(data_idx) = false;
-               endif
-
-               if (i > 1 || isempty (obj.displayname))
-                 titlespec{local_idx} = "title \"\"";
-               else
-                 tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
-                 titlespec{local_idx} = ['title "' tmp '"'];
+                 local_idx = data_3d_idx;
+                 ccdat = NaN;
                endif
-               if (isfield (obj, "facecolor"))
-                 if ((strncmp (obj.facecolor, "flat", 4)
-                     || strncmp (obj.facecolor, "interp", 6))
-                     && isfield (obj, "cdata"))
-                   if (ndims (obj.cdata) == 2
-                       && (columns (obj.cdata) == nc
-                           && (rows (obj.cdata) == 1
-                               || rows (obj.cdata) == 3)))
-                     ccol = cdat (:, i);
-                   elseif (ndims (obj.cdata) == 2
-                       && (rows (obj.cdata) == nc
-                           && (columns (obj.cdata) == 1
-                               || columns (obj.cdata) == 3)))
-                     ccol = cdat (i, :);
-                   elseif (ndims (obj.cdata) == 3)
-                     ccol = permute (cdat (:, i, :), [1, 3, 2]);
-                   else
-                     ccol = cdat;
-                   endif
-                   if (strncmp (obj.facecolor, "flat", 4))
-                     if (isequal (size (ccol), [1, 3]))
-                       ## RGB Triplet
-                       color = ccol;
-                     elseif (nd == 3 && numel (xcol) == 3)
-                       ccdat = ccol;
-                     else
-                       if (cdatadirect)
-                         r = round (ccol);
-                       else
-                         r = 1 + round ((rows (cmap) - 1)
-                                        * (ccol - clim(1))/(clim(2) - clim(1)));
-                       endif
-                       r = max (1, min (r, rows (cmap)));
-                       color = cmap(r, :);
-                     endif
-                   elseif (strncmp (obj.facecolor, "interp", 6))
-                     if (nd == 3 && numel (xcol) == 3)
-                       ccdat = ccol;
-                       if (! isvector (ccdat))
-                         tmp = rows (cmap) + rows (addedcmap) + ...
-                              [1 : rows(ccdat)];
-                         addedcmap = [addedcmap; ccdat];
-                         ccdat = tmp(:);
-                       else
-                         ccdat = ccdat(:);
-                       endif
-                     else
-                       if (sum (diff (ccol)))
-                         warning ("\"interp\" not supported, using 1st entry of cdata");
-                       endif
-                       if (cdatadirect)
-                         r = round (ccol);
-                       else
-                         r = 1 + round ((rows (cmap) - 1)
-                                        * (ccol - clim(1))/(clim(2) - clim(1)));
-                       endif
-                       r = max (1, min (r, rows (cmap)));
-                       color = cmap(r(1),:);
-                     endif
-                   endif
-                 elseif (isnumeric (obj.facecolor))
-                   color = obj.facecolor;
-                 else
-                   color = [0, 1, 0];
-                 endif
-               else
-                 color = [0, 1, 0];
-               endif
-
-               if (nd == 3 && numel (xcol) == 3)
-                 if (isnan (ccdat))
-                   ccdat = (rows (cmap) + rows (addedcmap) + 1) * ones(3, 1);
-                   addedcmap = [addedcmap; reshape(color, 1, 3)];
-                 endif
-                 data{data_3d_idx} = [data{data_3d_idx}, ...
-                                      [[xcol; xcol(end)], [ycol; ycol(end)], ...
-                                      [zcol; zcol(end)], [ccdat; ccdat(end)]]'];
-               else
-                 if (mono)
-                   colorspec = "";
-                 elseif (__gnuplot_has_feature__ ("transparent_patches")
-                         && isscalar (obj.facealpha))
-                   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f",
-                                      round (255*color), obj.facealpha);
-                 else
-                   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
-                                        round (255*color));
-                 endif
-
-                 withclause{data_idx} = sprintf ("with filledcurve %s",
-                                               colorspec);
-                 data{data_idx} = [xcol, ycol]';
-                 usingclause{data_idx} = sprintf ("record=%d using ($1):($2)",
-                                                  numel (xcol));
-               endif
-             endif
-           endif
-
-           ## patch outline
-           if (!(strncmp (obj.edgecolor, "none", 4)
-                  && (strncmp (obj.marker, "none", 4)
-                      || (strncmp (obj.markeredgecolor, "none", 4)
-                          && strncmp (obj.markerfacecolor, "none", 4)))))
-
-             data_idx++;
-             is_image_data(data_idx) = false;
-             parametric(data_idx) = false;
-             have_cdata(data_idx) = false;
-             have_3d_patch(data_idx) = false;
-             titlespec{data_idx} = "title \"\"";
-             usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
-
-             if (isfield (obj, "markersize"))
-               mdat = obj.markersize / 3;
+             else
+               data_idx++;
+               local_idx = data_idx;
+               is_image_data(data_idx) = false;
+               parametric(data_idx) = false;
+               have_cdata(data_idx) = false;
+               have_3d_patch(data_idx) = false;
              endif
 
-             if (isfield (obj, "edgecolor"))
-               ## FIXME
-               ## This is the wrong thing to do as edgecolor, markeredgecolor
-               ## and markerfacecolor can have different values and we should
-               ## treat them seperately. However, the below allow the scatter
-               ## functions to work as expected, where only one of these values
-               ## is set
-               if (strncmp (obj.edgecolor, "none", 4))
-                 if (strncmp (obj.markeredgecolor, "none", 4))
-                   ec = obj.markerfacecolor;
-                 else
-                   ec = obj.markeredgecolor;
-                 endif
-               else
-                 ec = obj.edgecolor;
-               endif
-
-               if ((strncmp (ec, "flat", 4)
-                    || strncmp (ec, "interp", 6))
+             if (i > 1 || isempty (obj.displayname))
+               titlespec{local_idx} = "title \"\"";
+             else
+               tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+               titlespec{local_idx} = ['title "' tmp '"'];
+             endif
+             if (isfield (obj, "facecolor"))
+               if ((strcmp (obj.facecolor, "flat")
+                   || strcmp (obj.facecolor, "interp"))
                    && isfield (obj, "cdata"))
                  if (ndims (obj.cdata) == 2
                      && (columns (obj.cdata) == nc
@@ -827,105 +693,291 @@
                              || rows (obj.cdata) == 3)))
                    ccol = cdat (:, i);
                  elseif (ndims (obj.cdata) == 2
-                         && (rows (obj.cdata) == nc
-                             && (columns (obj.cdata) == 1
-                                 || columns (obj.cdata) == 3)))
+                     && (rows (obj.cdata) == nc
+                         && (columns (obj.cdata) == 1
+                             || columns (obj.cdata) == 3)))
                    ccol = cdat (i, :);
                  elseif (ndims (obj.cdata) == 3)
                    ccol = permute (cdat (:, i, :), [1, 3, 2]);
                  else
                    ccol = cdat;
                  endif
-                 if (strncmp (ec, "flat", 4))
-                   if (numel (ccol) == 3)
+                 if (strcmp (obj.facecolor, "flat"))
+                   if (isequal (size (ccol), [1, 3]))
+                     ## RGB Triplet
                      color = ccol;
+                   elseif (nd == 3 && numel (xcol) == 3)
+                     ccdat = ccol;
                    else
-                     if (isscalar (ccol))
-                       ccol = repmat (ccol, numel (xcol), 1);
+                     if (cdatadirect)
+                       r = round (ccol);
+                     else
+                       r = 1 + round ((rows (cmap) - 1)
+                                      * (ccol - clim(1))/(clim(2) - clim(1)));
                      endif
-                     color = "flat";
-                     have_cdata(data_idx) = true;
+                     r = max (1, min (r, rows (cmap)));
+                     color = cmap(r, :);
                    endif
-                 elseif (strncmp (ec, "interp", 6))
-                   if (numel (ccol) == 3)
-                     warning ("\"interp\" not supported, using 1st entry of cdata");
-                     color = ccol(1,:);
+                 elseif (strcmp (obj.facecolor, "interp"))
+                   if (nd == 3 && numel (xcol) == 3)
+                     ccdat = ccol;
+                     if (! isvector (ccdat))
+                       tmp = rows (cmap) + rows (addedcmap) + ...
+                            [1 : rows(ccdat)];
+                       addedcmap = [addedcmap; ccdat];
+                       ccdat = tmp(:);
+                     else
+                       ccdat = ccdat(:);
+                     endif
                    else
-                     if (isscalar (ccol))
-                       ccol = repmat (ccol, numel (xcol), 1);
+                     if (sum (diff (ccol)))
+                       warning ("\"interp\" not supported, using 1st entry of cdata");
                      endif
-                     color = "interp";
-                     have_cdata(data_idx) = true;
+                     if (cdatadirect)
+                       r = round (ccol);
+                     else
+                       r = 1 + round ((rows (cmap) - 1)
+                                      * (ccol - clim(1))/(clim(2) - clim(1)));
+                     endif
+                     r = max (1, min (r, rows (cmap)));
+                     color = cmap(r(1),:);
                    endif
                  endif
-               elseif (isnumeric (ec))
-                 color = ec;
+               elseif (isnumeric (obj.facecolor))
+                 color = obj.facecolor;
                else
-                 color = [0, 0, 0];
+                 color = [0, 1, 0];
                endif
              else
-               color = [0, 0, 0];
+               color = [0, 1, 0];
              endif
 
-             if (isfield (obj, "linestyle"))
-               switch (obj.linestyle)
-                 case "-"
-                   lt = "lt 1";
-                 case "--"
-                   lt = "lt 2";
-                 case ":"
-                   lt = "lt 3";
-                 case "-."
-                   lt = "lt 6";
-                 case "none"
-                   lt = "";
-                 otherwise
-                   lt = "";
-               endswitch
+             if (nd == 3 && numel (xcol) == 3)
+               if (isnan (ccdat))
+                 ccdat = (rows (cmap) + rows (addedcmap) + 1) * ones(3, 1);
+                 addedcmap = [addedcmap; reshape(color, 1, 3)];
+               endif
+               data{data_3d_idx} = [data{data_3d_idx}, ...
+                                    [[xcol; xcol(end)], [ycol; ycol(end)], ...
+                                    [zcol; zcol(end)], [ccdat; ccdat(end)]]'];
              else
-               lt = "";
-             endif
-
-             if (isfield (obj, "linewidth"))
-               lw = sprintf ("linewidth %f", obj.linewidth);
-             else
-               lw  = "";
-             endif
-
-             [pt, pt2, obj] = gnuplot_pointtype (obj);
-             if (! isempty (pt))
-               pt = sprintf ("pointtype %s", pt);
-             endif
-             if (! isempty (pt2))
-               pt2 = sprintf ("pointtype %s", pt2);
-             endif
-
-             if (mono)
-               colorspec = "";
-             else
-               if (ischar (color))
-                 colorspec = "palette";
+               if (mono)
+                 colorspec = "";
+               elseif (__gnuplot_has_feature__ ("transparent_patches")
+                       && isscalar (obj.facealpha))
+                 colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f",
+                                    round (255*color), obj.facealpha);
                else
                  colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
                                       round (255*color));
                endif
+
+               withclause{data_idx} = sprintf ("with filledcurve %s",
+                                             colorspec);
+               data{data_idx} = [xcol, ycol]';
+               usingclause{data_idx} = sprintf ("record=%d using ($1):($2)",
+                                                numel (xcol));
+             endif
+           endif
+         endif
+
+         ## patch outline
+         if (!(strcmp (obj.edgecolor, "none")
+                && (strcmp (obj.marker, "none")
+                    || (strcmp (obj.markeredgecolor, "none")
+                        && strcmp (obj.markerfacecolor, "none")))))
+
+           data_idx++;
+           is_image_data(data_idx) = false;
+           parametric(data_idx) = false;
+           have_cdata(data_idx) = false;
+           have_3d_patch(data_idx) = false;
+           titlespec{data_idx} = "title \"\"";
+           usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
+
+           if (isfield (obj, "markersize"))
+             mdat = obj.markersize / 3;
+           endif
+
+           if (isfield (obj, "edgecolor"))
+             ## FIXME
+             ## This is the wrong thing to do as edgecolor, markeredgecolor
+             ## and markerfacecolor can have different values and we should
+             ## treat them seperately. However, the below allow the scatter
+             ## functions to work as expected, where only one of these values
+             ## is set
+             if (strcmp (obj.edgecolor, "none"))
+               if (strcmp (obj.markeredgecolor, "none"))
+                 ec = obj.markerfacecolor;
+               else
+                 ec = obj.markeredgecolor;
+               endif
+             else
+               ec = obj.edgecolor;
              endif
 
-             sidx = 1;
-             if (isempty (lt))
-               style = "";
+             if ((strcmp (ec, "flat")
+                  || strcmp (ec, "interp"))
+                 && isfield (obj, "cdata"))
+               if (ndims (obj.cdata) == 2
+                   && (columns (obj.cdata) == nc
+                       && (rows (obj.cdata) == 1
+                           || rows (obj.cdata) == 3)))
+                 ccol = cdat (:, i);
+               elseif (ndims (obj.cdata) == 2
+                       && (rows (obj.cdata) == nc
+                           && (columns (obj.cdata) == 1
+                               || columns (obj.cdata) == 3)))
+                 ccol = cdat (i, :);
+               elseif (ndims (obj.cdata) == 3)
+                 ccol = permute (cdat (:, i, :), [1, 3, 2]);
+               else
+                 ccol = cdat;
+               endif
+               if (strcmp (ec, "flat"))
+                 if (numel (ccol) == 3)
+                   color = ccol;
+                 else
+                   if (isscalar (ccol))
+                     ccol = repmat (ccol, numel (xcol), 1);
+                   endif
+                   color = "flat";
+                   have_cdata(data_idx) = true;
+                 endif
+               elseif (strcmp (ec, "interp"))
+                 if (numel (ccol) == 3)
+                   warning ("\"interp\" not supported, using 1st entry of cdata");
+                   color = ccol(1,:);
+                 else
+                   if (isscalar (ccol))
+                     ccol = repmat (ccol, numel (xcol), 1);
+                   endif
+                   color = "interp";
+                   have_cdata(data_idx) = true;
+                 endif
+               endif
+             elseif (isnumeric (ec))
+               color = ec;
              else
-               style = "lines";
+               color = [0, 0, 0];
              endif
-             tmpwith = {};
+           else
+             color = [0, 0, 0];
+           endif
+
+           if (isfield (obj, "linestyle"))
+             switch (obj.linestyle)
+               case "-"
+                 lt = "lt 1";
+               case "--"
+                 lt = "lt 2";
+               case ":"
+                 lt = "lt 3";
+               case "-."
+                 lt = "lt 6";
+               case "none"
+                 lt = "";
+               otherwise
+                 lt = "";
+             endswitch
+           else
+             lt = "";
+           endif
+
+           if (isfield (obj, "linewidth"))
+             lw = sprintf ("linewidth %f", obj.linewidth);
+           else
+             lw  = "";
+           endif
 
-             facesame = true;
-             if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
-                 && !strncmp (obj.markerfacecolor, "none", 4))
-               if (strncmp (obj.markerfacecolor, "auto", 4)
-                   || ! isnumeric (obj.markerfacecolor)
-                   || (isnumeric (obj.markerfacecolor)
-                       && isequal (color, obj.markerfacecolor)))
+           [pt, pt2, obj] = gnuplot_pointtype (obj);
+           if (! isempty (pt))
+             pt = sprintf ("pointtype %s", pt);
+           endif
+           if (! isempty (pt2))
+             pt2 = sprintf ("pointtype %s", pt2);
+           endif
+
+           if (mono)
+             colorspec = "";
+           else
+             if (ischar (color))
+               colorspec = "palette";
+             else
+               colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+                                    round (255*color));
+             endif
+           endif
+
+           sidx = 1;
+           if (isempty (lt))
+             style = "";
+           else
+             style = "lines";
+           endif
+           tmpwith = {};
+
+           facesame = true;
+           if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
+               && !strcmp (obj.markerfacecolor, "none"))
+             if (strcmp (obj.markerfacecolor, "auto")
+                 || ! isnumeric (obj.markerfacecolor)
+                 || (isnumeric (obj.markerfacecolor)
+                     && isequal (color, obj.markerfacecolor)))
+               style = strcat (style, "points");
+               if (isfield (obj, "markersize"))
+                 if (length (mdat) == nc)
+                   m = mdat(i);
+                 else
+                   m = mdat;
+                 endif
+                 ps = sprintf ("pointsize %f", m / 3);
+               else
+                 ps = "";
+               endif
+
+               tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
+                                        style, lw, pt2, lt, ps,
+                                        colorspec);
+             else
+               facesame = false;
+               if (! isempty (style))
+                 tmpwith{sidx} = sprintf ("with %s %s %s %s",
+                                          style, lw, lt,
+                                          colorspec);
+                 sidx ++;
+               endif
+               if (isnumeric (obj.markerfacecolor) && ! mono)
+                 colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+                                      round (255*obj.markerfacecolor));
+               endif
+               style = "points";
+               if (isfield (obj, "markersize"))
+                 if (length (mdat) == nc)
+                   m = mdat(i);
+                 else
+                   m = mdat;
+                 endif
+                 ps = sprintf ("pointsize %f", m / 3);
+               else
+                 ps = "";
+               endif
+               tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
+                                        style, lw, pt2, lt, ps,
+                                        colorspec);
+             endif
+           endif
+
+           if (isfield (obj, "markeredgecolor")
+               && !strcmp (obj.markeredgecolor, "none"))
+             if (facesame && !isempty (pt)
+                 && (strcmp (obj.markeredgecolor, "auto")
+                     || ! isnumeric (obj.markeredgecolor)
+                     || (isnumeric (obj.markeredgecolor)
+                         && isequal (color, obj.markeredgecolor))))
+               if (sidx == 1 && ((length (style) == 5
+                        && strncmp (style, "lines", 5))
+                       || isempty (style)))
                  style = strcat (style, "points");
                  if (isfield (obj, "markersize"))
                    if (length (mdat) == nc)
@@ -937,21 +989,29 @@
                  else
                    ps = "";
                  endif
-
                  tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
-                                          style, lw, pt2, lt, ps,
+                                          style, lw, pt, lt, ps,
                                           colorspec);
-               else
-                 facesame = false;
-                 if (! isempty (style))
+               endif
+             else
+               if (!isempty (style))
+                 if (length (tmpwith) < sidx || isempty (tmpwith{sidx}))
                    tmpwith{sidx} = sprintf ("with %s %s %s %s",
                                             style, lw, lt,
                                             colorspec);
-                   sidx ++;
                  endif
-                 if (isnumeric (obj.markerfacecolor) && ! mono)
-                   colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
-                                        round (255*obj.markerfacecolor));
+                 sidx ++;
+               endif
+
+               if (!isempty (pt))
+                 if (! mono)
+                   if (strcmp (obj.markeredgecolor, "auto"))
+                     colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+                                          round (255*color));
+                   elseif (isnumeric (obj.markeredgecolor) && ! mono)
+                     colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
+                                          round (255*obj.markeredgecolor));
+                   endif
                  endif
                  style = "points";
                  if (isfield (obj, "markersize"))
@@ -965,282 +1025,257 @@
                    ps = "";
                  endif
                  tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
-                                          style, lw, pt2, lt, ps,
+                                          style, lw, pt, lt, ps,
                                           colorspec);
                endif
              endif
-
-             if (isfield (obj, "markeredgecolor")
-                 && !strncmp (obj.markeredgecolor, "none", 4))
-               if (facesame && !isempty (pt)
-                   && (strncmp (obj.markeredgecolor, "auto", 4)
-                       || ! isnumeric (obj.markeredgecolor)
-                       || (isnumeric (obj.markeredgecolor)
-                           && isequal (color, obj.markeredgecolor))))
-                 if (sidx == 1 && ((length (style) == 5
-                          && strncmp (style, "lines", 5))
-                         || isempty (style)))
-                   style = strcat (style, "points");
-                   if (isfield (obj, "markersize"))
-                     if (length (mdat) == nc)
-                       m = mdat(i);
-                     else
-                       m = mdat;
-                     endif
-                     ps = sprintf ("pointsize %f", m / 3);
-                   else
-                     ps = "";
-                   endif
-                   tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
-                                            style, lw, pt, lt, ps,
-                                            colorspec);
-                 endif
-               else
-                 if (!isempty (style))
-                   if (length (tmpwith) < sidx || isempty (tmpwith{sidx}))
-                     tmpwith{sidx} = sprintf ("with %s %s %s %s",
-                                              style, lw, lt,
-                                              colorspec);
-                   endif
-                   sidx ++;
-                 endif
-
-                 if (!isempty (pt))
-                   if (! mono)
-                     if (strncmp (obj.markeredgecolor, "auto", 4))
-                       colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
-                                            round (255*color));
-                     elseif (isnumeric (obj.markeredgecolor) && ! mono)
-                       colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
-                                            round (255*obj.markeredgecolor));
-                     endif
-                   endif
-                   style = "points";
-                   if (isfield (obj, "markersize"))
-                     if (length (mdat) == nc)
-                       m = mdat(i);
-                     else
-                       m = mdat;
-                     endif
-                     ps = sprintf ("pointsize %f", m / 3);
-                   else
-                     ps = "";
-                   endif
-                   tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s",
-                                            style, lw, pt, lt, ps,
-                                            colorspec);
-                 endif
-               endif
-             endif
+           endif
 
-             if (isempty (tmpwith))
-               withclause{data_idx} = sprintf ("with %s %s %s %s %s",
-                                               style, lw, pt, lt,
-                                               colorspec);
-             else
-               withclause{data_idx} = tmpwith{1};
-             endif
-             if (nd == 3)
-               if (ischar (color))
-                 if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
-                   data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
-                                     [zcol; zcol(1)], [ccol; ccol(1)]]';
-                 else
-                   data{data_idx} = [xcol, ycol, zcol, ccol]';
-                 endif
-                 usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx}));
+           if (isempty (tmpwith))
+             withclause{data_idx} = sprintf ("with %s %s %s %s %s",
+                                             style, lw, pt, lt,
+                                             colorspec);
+           else
+             withclause{data_idx} = tmpwith{1};
+           endif
+           if (nd == 3)
+             if (ischar (color))
+               if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
+                 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
+                                   [zcol; zcol(1)], [ccol; ccol(1)]]';
                else
-                 if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
-                   data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
-                                     [zcol; zcol(1)]]';
-                 else
-                   data{data_idx} = [xcol, ycol, zcol]';
-                 endif
-                 usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
+                 data{data_idx} = [xcol, ycol, zcol, ccol]';
                endif
+               usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx}));
              else
-               if (ischar (color))
-                 if (! isnan (xcol) && ! isnan (ycol))
-                   data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
-                                     [ccol; ccol(1)]]';
-                 else
-                   data{data_idx} = [xcol, ycol, ccol]';
-                 endif
-                 usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
+               if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol))
+                 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
+                                   [zcol; zcol(1)]]';
                else
-                 if (! isnan (xcol) && ! isnan (ycol))
-                   data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
-                 else
-                   data{data_idx} = [xcol, ycol]';
-                 endif
-                 usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx}));
+                 data{data_idx} = [xcol, ycol, zcol]';
                endif
+               usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
              endif
-
-             if (length (tmpwith) > 1)
-               data_idx++;
-               is_image_data(data_idx) = is_image_data(data_idx - 1);
-               parametric(data_idx) = parametric(data_idx - 1);
-               have_cdata(data_idx) = have_cdata(data_idx - 1);
-               have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-               titlespec{data_idx} = "title \"\"";
-               usingclause{data_idx} = usingclause{data_idx - 1};
-               data{data_idx} = data{data_idx - 1};
-               withclause{data_idx} = tmpwith{2};
-             endif
-             if (length (tmpwith) > 2)
-               data_idx++;
-               is_image_data(data_idx) = is_image_data(data_idx - 1);
-               parametric(data_idx) = parametric(data_idx - 1);
-               have_cdata(data_idx) = have_cdata(data_idx - 1);
-               have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-               titlespec{data_idx} = "title \"\"";
-               usingclause{data_idx} = usingclause{data_idx - 1};
-               data{data_idx} = data{data_idx - 1};
-               withclause{data_idx} = tmpwith{3};
+           else
+             if (ischar (color))
+               if (! isnan (xcol) && ! isnan (ycol))
+                 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ...
+                                   [ccol; ccol(1)]]';
+               else
+                 data{data_idx} = [xcol, ycol, ccol]';
+               endif
+               usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx}));
+             else
+               if (! isnan (xcol) && ! isnan (ycol))
+                 data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]';
+               else
+                 data{data_idx} = [xcol, ycol]';
+               endif
+               usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx}));
              endif
            endif
-         endfor
 
-        case "surface"
-          view_map = true;
-          if (! (strncmp (obj.edgecolor, "none", 4)
-                 && strncmp (obj.facecolor, "none", 4)))
-            data_idx++;
-            is_image_data(data_idx) = false;
-            parametric(data_idx) = false;
-            have_cdata(data_idx) = true;
-            have_3d_patch(data_idx) = false;
-            style = do_linestyle_command (obj, obj.edgecolor,
-                                          data_idx, mono,
-                                          plot_stream);
+           if (length (tmpwith) > 1)
+             data_idx++;
+             is_image_data(data_idx) = is_image_data(data_idx - 1);
+             parametric(data_idx) = parametric(data_idx - 1);
+             have_cdata(data_idx) = have_cdata(data_idx - 1);
+             have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+             titlespec{data_idx} = "title \"\"";
+             usingclause{data_idx} = usingclause{data_idx - 1};
+             data{data_idx} = data{data_idx - 1};
+             withclause{data_idx} = tmpwith{2};
+           endif
+           if (length (tmpwith) > 2)
+             data_idx++;
+             is_image_data(data_idx) = is_image_data(data_idx - 1);
+             parametric(data_idx) = parametric(data_idx - 1);
+             have_cdata(data_idx) = have_cdata(data_idx - 1);
+             have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+             titlespec{data_idx} = "title \"\"";
+             usingclause{data_idx} = usingclause{data_idx - 1};
+             data{data_idx} = data{data_idx - 1};
+             withclause{data_idx} = tmpwith{3};
+           endif
+         endif
+       endfor
 
-            if (isempty (obj.displayname))
-              titlespec{data_idx} = "title \"\"";
-            else
-              tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
-              titlespec{data_idx} = ['title "' tmp '"'];
-            endif
-            withclause{data_idx} = sprintf ("with pm3d linestyle %d",
-                                            data_idx);
-            withpm3d = true;
-            pm3didx = data_idx;
-
-            xdat = obj.xdata;
-            ydat = obj.ydata;
-            zdat = obj.zdata;
-            cdat = obj.cdata;
+      case "surface"
+        view_map = true;
+        if (! (strcmp (obj.edgecolor, "none")
+               && strcmp (obj.facecolor, "none")))
+          data_idx++;
+          is_image_data(data_idx) = false;
+          parametric(data_idx) = false;
+          have_cdata(data_idx) = true;
+          have_3d_patch(data_idx) = false;
+          style = do_linestyle_command (obj, obj.edgecolor,
+                                        data_idx, mono,
+                                        plot_stream);
 
-            err = false;
-            if (! size_equal (zdat, cdat))
-              err = true;
-            endif
-            if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
-              if (rows (zdat) == length (ydat)
-                  && columns (zdat) == length (xdat))
-                [xdat, ydat] = meshgrid (xdat, ydat);
-              else
-                err = true;
-              endif
-            elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
-              if (! size_equal (xdat, ydat, zdat))
-                err = true;
-              endif
+          if (isempty (obj.displayname))
+            titlespec{data_idx} = "title \"\"";
+          else
+            tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+            titlespec{data_idx} = ['title "' tmp '"'];
+          endif
+          withclause{data_idx} = sprintf ("with pm3d linestyle %d",
+                                          data_idx);
+          withpm3d = true;
+          pm3didx = data_idx;
+
+          xdat = obj.xdata;
+          ydat = obj.ydata;
+          zdat = obj.zdata;
+          cdat = obj.cdata;
+
+          err = false;
+          if (! size_equal (zdat, cdat))
+            err = true;
+          endif
+          if (isvector (xdat) && isvector (ydat) && ismatrix (zdat))
+            if (rows (zdat) == length (ydat)
+                && columns (zdat) == length (xdat))
+              [xdat, ydat] = meshgrid (xdat, ydat);
             else
               err = true;
             endif
-            if (err)
-              error ("__go_draw_axes__: invalid grid data");
+          elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat))
+            if (! size_equal (xdat, ydat, zdat))
+              err = true;
             endif
-            xlen = columns (zdat);
-            ylen = rows (zdat);
-            if (xlen == columns (xdat) && xlen == columns (ydat)
-                && ylen == rows (xdat) && ylen == rows (ydat))
-              len = 4 * xlen;
-              zz = zeros (ylen, len);
-              k = 1;
-              for kk = 1:4:len
-                zz(:,kk)   = xdat(:,k);
-                zz(:,kk+1) = ydat(:,k);
-                zz(:,kk+2) = zdat(:,k);
-                zz(:,kk+3) = cdat(:,k);
-                k++;
-              endfor
-              data{data_idx} = zz.';
-            endif
+          else
+            err = true;
+          endif
+          if (err)
+            error ("__go_draw_axes__: invalid grid data");
+          endif
+          xlen = columns (zdat);
+          ylen = rows (zdat);
+          if (xlen == columns (xdat) && xlen == columns (ydat)
+              && ylen == rows (xdat) && ylen == rows (ydat))
+            len = 4 * xlen;
+            zz = zeros (ylen, len);
+            k = 1;
+            for kk = 1:4:len
+              zz(:,kk)   = xdat(:,k);
+              zz(:,kk+1) = ydat(:,k);
+              zz(:,kk+2) = zdat(:,k);
+              zz(:,kk+3) = cdat(:,k);
+              k++;
+            endfor
+            data{data_idx} = zz.';
+          endif
 
-            if (doing_interp_color)
-              interp_str = "interpolate 0, 0";
-            else
-              ## No interpolation of facecolors.
-              interp_str = "";
-            endif
-            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen);
+          if (doing_interp_color)
+            interp_str = "interpolate 0, 0";
+          else
+            ## No interpolation of facecolors.
+            interp_str = "";
+          endif
+          usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen);
 
-            flat_interp_face = (strncmp (obj.facecolor, "flat", 4)
-                                || strncmp (obj.facecolor, "interp", 6));
-            flat_interp_edge = (strncmp (obj.edgecolor, "flat", 4)
-                                || strncmp (obj.edgecolor, "interp", 6));
+          flat_interp_face = (strcmp (obj.facecolor, "flat")
+                              || strcmp (obj.facecolor, "interp"));
+          flat_interp_edge = (strcmp (obj.edgecolor, "flat")
+                              || strcmp (obj.edgecolor, "interp"));
 
-            facecolor_none_or_white = (strncmp (obj.facecolor, "none", 4)
-                                       || (isnumeric (obj.facecolor)
-                                           && all (obj.facecolor == 1)));
-            hidden_removal = false;
-            fputs (plot_stream, "set style increment default;\n");
-            if (flat_interp_edge && facecolor_none_or_white)
-              withpm3d = false;
-              withclause{data_idx} = sprintf ("with %s palette", style {1});
-              fputs (plot_stream, "unset pm3d\n");
-              if (all (obj.facecolor == 1))
-                hidden_removal = true;
-              endif
-            elseif (facecolor_none_or_white)
-              if (all (obj.facecolor == 1))
-                hidden_removal = true;
-              endif
-              fputs (plot_stream,"unset pm3d;\n");
-              fputs (plot_stream,"set style increment user;\n");
-              withpm3d = false;
-              withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                              style{1}, data_idx);
-              fputs (plot_stream, "unset pm3d\n");
+          facecolor_none_or_white = (strcmp (obj.facecolor, "none")
+                                     || (isnumeric (obj.facecolor)
+                                         && all (obj.facecolor == 1)));
+          hidden_removal = false;
+          fputs (plot_stream, "set style increment default;\n");
+          if (flat_interp_edge && facecolor_none_or_white)
+            withpm3d = false;
+            withclause{data_idx} = sprintf ("with %s palette", style {1});
+            fputs (plot_stream, "unset pm3d\n");
+            if (all (obj.facecolor == 1))
+              hidden_removal = true;
             endif
+          elseif (facecolor_none_or_white)
+            if (all (obj.facecolor == 1))
+              hidden_removal = true;
+            endif
+            fputs (plot_stream,"unset pm3d;\n");
+            fputs (plot_stream,"set style increment user;\n");
+            withpm3d = false;
+            withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                            style{1}, data_idx);
+            fputs (plot_stream, "unset pm3d\n");
+          endif
 
-            if (doing_interp_color)
-              ## "depthorder" interferes with interpolation of colors.
-              dord = "scansautomatic";
-            else
-              dord = "depthorder";
-            endif
+          if (doing_interp_color)
+            ## "depthorder" interferes with interpolation of colors.
+            dord = "scansautomatic";
+          else
+            dord = "depthorder";
+          endif
 
-            if (flat_interp_face && strncmp (obj.edgecolor, "flat", 4))
-              fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n",
+          if (flat_interp_face && strcmp (obj.edgecolor, "flat"))
+            fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n",
+                     interp_str, dord);
+          elseif (!facecolor_none_or_white)
+            if (strcmp (obj.edgecolor, "none"))
+              if (__gnuplot_has_feature__ ("transparent_surface")
+                  && isscalar (obj.facealpha))
+                fprintf (plot_stream,
+                         "set style fill transparent solid %f;\n",
+                         obj.facealpha);
+              endif
+              fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n",
                        interp_str, dord);
-            elseif (!facecolor_none_or_white)
-              if (strncmp (obj.edgecolor, "none", 4))
-                if (__gnuplot_has_feature__ ("transparent_surface")
-                    && isscalar (obj.facealpha))
-                  fprintf (plot_stream,
-                           "set style fill transparent solid %f;\n",
-                           obj.facealpha);
-                endif
-                fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n",
-                         interp_str, dord);
-              else
-                fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
-                         data_idx, interp_str, dord);
+            else
+              fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
+                       data_idx, interp_str, dord);
 
-                if (__gnuplot_has_feature__ ("transparent_surface")
-                    && isscalar (obj.facealpha))
-                  fprintf (plot_stream,
-                           "set style fill transparent solid %f;\n",
-                           obj.facealpha);
-                endif
+              if (__gnuplot_has_feature__ ("transparent_surface")
+                  && isscalar (obj.facealpha))
+                fprintf (plot_stream,
+                         "set style fill transparent solid %f;\n",
+                         obj.facealpha);
               endif
             endif
+          endif
 
-            zz = [];
-            if (length (style) > 1)
+          zz = [];
+          if (length (style) > 1)
+            len = 3 * xlen;
+            zz = zeros (ylen, len);
+            k = 1;
+            for kk = 1:3:len
+              zz(:,kk)   = xdat(:,k);
+              zz(:,kk+1) = ydat(:,k);
+              zz(:,kk+2) = zdat(:,k);
+              k++;
+            endfor
+            zz = zz.';
+
+            data_idx++;
+            is_image_data(data_idx) = is_image_data(data_idx - 1);
+            parametric(data_idx) = parametric(data_idx - 1);
+            have_cdata(data_idx) = false;
+            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+            titlespec{data_idx} = "title \"\"";
+            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
+            data{data_idx} = zz;
+            withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                            style{2}, data_idx);
+
+          endif
+          if (length (style) > 2)
+            data_idx++;
+            is_image_data(data_idx) = is_image_data(data_idx - 1);
+            parametric(data_idx) = parametric(data_idx - 1);
+            have_cdata(data_idx) = false;
+            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+            titlespec{data_idx} = "title \"\"";
+            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
+            data{data_idx} = zz;
+            withclause{data_idx} = sprintf ("with %s linestyle %d",
+                                            style{3}, data_idx);
+          endif
+          if (withpm3d && strcmp (style{1}, "linespoints"))
+            if (isempty (zz))
               len = 3 * xlen;
               zz = zeros (ylen, len);
               k = 1;
@@ -1251,446 +1286,388 @@
                 k++;
               endfor
               zz = zz.';
-
-              data_idx++;
-              is_image_data(data_idx) = is_image_data(data_idx - 1);
-              parametric(data_idx) = parametric(data_idx - 1);
-              have_cdata(data_idx) = false;
-              have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-              titlespec{data_idx} = "title \"\"";
-              usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
-              data{data_idx} = zz;
-              withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                              style{2}, data_idx);
+            endif
+            data_idx++;
+            is_image_data(data_idx) = is_image_data(data_idx - 1);
+            parametric(data_idx) = parametric(data_idx - 1);
+            have_cdata(data_idx) = false;
+            have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
+            titlespec{data_idx} = "title \"\"";
+            usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
+            data{data_idx} = zz;
+            withclause{data_idx} = sprintf ("with points linestyle %d",
+                                            pm3didx);
+          endif
+        endif
 
-            endif
-            if (length (style) > 2)
-              data_idx++;
-              is_image_data(data_idx) = is_image_data(data_idx - 1);
-              parametric(data_idx) = parametric(data_idx - 1);
-              have_cdata(data_idx) = false;
-              have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-              titlespec{data_idx} = "title \"\"";
-              usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
-              data{data_idx} = zz;
-              withclause{data_idx} = sprintf ("with %s linestyle %d",
-                                              style{3}, data_idx);
-            endif
-            if (withpm3d && strncmp (style {1}, "linespoints", 11))
-              if (isempty (zz))
-                len = 3 * xlen;
-                zz = zeros (ylen, len);
-                k = 1;
-                for kk = 1:3:len
-                  zz(:,kk)   = xdat(:,k);
-                  zz(:,kk+1) = ydat(:,k);
-                  zz(:,kk+2) = zdat(:,k);
-                  k++;
-                endfor
-                zz = zz.';
-              endif
-              data_idx++;
-              is_image_data(data_idx) = is_image_data(data_idx - 1);
-              parametric(data_idx) = parametric(data_idx - 1);
-              have_cdata(data_idx) = false;
-              have_3d_patch(data_idx) = have_3d_patch(data_idx - 1);
-              titlespec{data_idx} = "title \"\"";
-              usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen);
-              data{data_idx} = zz;
-              withclause{data_idx} = sprintf ("with points linestyle %d",
-                                              pm3didx);
-            endif
-          endif
+      case "text"
+        [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string");
+        fontspec = create_fontspec (f, s, gnuplot_term);
+        lpos = obj.position;
+        halign = obj.horizontalalignment;
+        valign = obj.verticalalignment;
+        angle = obj.rotation;
+        units = obj.units;
+        color = obj.color;
+        if (strcmpi (units, "normalized"))
+          units = "graph";
+        elseif (strcmp (axis_obj.yaxislocation, "right")
+                && strcmp (units, "data"))
+          units = "second";
+        else
+          units = "";
+        endif
+
+        if (isnumeric (color))
+          colorspec = get_text_colorspec (color, mono);
+        endif
 
-        case "text"
-          [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string");
-          fontspec = create_fontspec (f, s, gnuplot_term);
-          lpos = obj.position;
-          halign = obj.horizontalalignment;
-          valign = obj.verticalalignment;
-          angle = obj.rotation;
-          units = obj.units;
-          color = obj.color;
-          if (strcmpi (units, "normalized"))
-            units = "graph";
-          elseif (strcmp (axis_obj.yaxislocation, "right")
-                  && strcmp (units, "data"))
-            units = "second";
-          else
-            units = "";
-          endif
-
-          if (isnumeric (color))
-            colorspec = get_text_colorspec (color, mono);
-          endif
+        if (ischar (obj.string))
+          num_lines = rows (obj.string);
+        else
+          num_lines = numel (obj.string);
+        endif
+        switch (valign)
+          ## Text offset in characters. Relies on gnuplot for font metrics.
+          case "top"
+            dy = -0.5;
+          case "cap"
+            dy = -0.5;
+          case "middle"
+            dy = 0.5 * (num_lines - 1);
+          case "baseline"
+            dy = 0.5 + (num_lines - 1);
+          case "bottom"
+            dy = 0.5 + (num_lines - 1);
+        endswitch
+        ## Gnuplot's Character units are different for x/y and vary with
+        ## fontsize. The aspect ratio of 1:1.7 was determined by experiment
+        ## to work for eps/ps/etc. For the MacOS aqua terminal a value of 2.5
+        ## is needed. However, the difference is barely noticable.
+        dx_and_dy = [(-dy * sind (angle)), (dy * cosd (angle))] .* [1.7 1];
 
-          if (ischar (obj.string))
-            num_lines = rows (obj.string);
-          else
-            num_lines = numel (obj.string);
-          endif
-          switch (valign)
-            ## Text offset in characters. This relies on gnuplot for font metrics.
-            case "top"
-              dy = -0.5;
-            case "cap"
-              dy = -0.5;
-            case "middle"
-              dy = 0.5 * (num_lines - 1);
-            case "baseline"
-              dy = 0.5 + (num_lines - 1);
-            case "bottom"
-              dy = 0.5 + (num_lines - 1);
-          endswitch
-          ## Gnuplot's Character units are different for x/y and vary with fontsize. The aspect ratio
-          ## of 1:1.7 was determined by experiment to work for eps/ps/etc. For the MacOS aqua terminal
-          ## a value of 2.5 is needed. However, the difference is barely noticable.
-          dx_and_dy = [(-dy * sind (angle)), (dy * cosd (angle))] .* [1.7 1];
+        ## FIXME: Multiline text produced the gnuplot
+        ##        "warning: ft_render: skipping glyph"
+        if (nd == 3)
+          ## This produces the desired vertical alignment in 3D.
+          fprintf (plot_stream,
+                   "set label \"%s\" at %s %.15e,%.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
+                   undo_string_escapes (label), units, lpos(1),
+                   lpos(2), lpos(3), halign, angle, dx_and_dy, fontspec,
+                   __do_enhanced_option__ (enhanced, obj), colorspec);
+        else
+          fprintf (plot_stream,
+                   "set label \"%s\" at %s %.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
+                   undo_string_escapes (label), units,
+                   lpos(1), lpos(2), halign, angle, dx_and_dy, fontspec,
+                   __do_enhanced_option__ (enhanced, obj), colorspec);
+        endif
+
+      case "hggroup"
+        ## Push group children into the kid list.
+        if (isempty (kids))
+          kids = obj.children;
+        elseif (! isempty (obj.children))
+          kids = [kids; obj.children];
+        endif
+
+      otherwise
+        error ("__go_draw_axes__: unknown object class, %s",
+               obj.type);
+    endswitch
+
+  endwhile
 
-          ## FIXME - Multiline text produced the gnuplot "warning: ft_render: skipping glyph"
-          if (nd == 3)
-            ## This produces the desired vertical alignment in 3D.
-            fprintf (plot_stream,
-                     "set label \"%s\" at %s %.15e,%.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
-                     undo_string_escapes (label), units, lpos(1),
-                     lpos(2), lpos(3), halign, angle, dx_and_dy, fontspec,
-                     __do_enhanced_option__ (enhanced, obj), colorspec);
-          else
-            fprintf (plot_stream,
-                     "set label \"%s\" at %s %.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n",
-                     undo_string_escapes (label), units,
-                     lpos(1), lpos(2), halign, angle, dx_and_dy, fontspec,
-                     __do_enhanced_option__ (enhanced, obj), colorspec);
-          endif
+  ## This is need to prevent warnings for rotations in 3D plots, while
+  ## allowing colorbars with contours.
+  if (nd == 2 || (data_idx > 1 && !view_map))
+    fputs (plot_stream, "set pm3d implicit;\n");
+  else
+    fputs (plot_stream, "set pm3d explicit;\n");
+  endif
 
-        case "hggroup"
-          ## Push group children into the kid list.
-          if (isempty (kids))
-            kids = obj.children;
-          elseif (! isempty (obj.children))
-            kids = [kids; obj.children];
-          endif
+  if (isnan (hidden_removal) || hidden_removal)
+    fputs (plot_stream, "set hidden3d;\n");
+  else
+    fputs (plot_stream, "unset hidden3d;\n");
+  endif
+
+  have_data = (! (isempty (data) || all (cellfun ("isempty", data))));
 
-        otherwise
-          error ("__go_draw_axes__: unknown object class, %s",
-                 obj.type);
-      endswitch
-
-    endwhile
+  ## Note we don't use the [xy]2range of gnuplot as we don't use the
+  ## dual axis plotting features of gnuplot.
+  if (isempty (xlim))
+    return;
+  endif
+  if (strcmpi (axis_obj.xdir, "reverse"))
+    xdir = "reverse";
+  else
+    xdir = "noreverse";
+  endif
+  fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir);
+  if (strcmpi (axis_obj.xaxislocation, "top"))
+    fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir);
+  endif
 
-    ## This is need to prevent warnings for rotations in 3D plots, while
-    ## allowing colorbars with contours.
-    if (nd == 2 || (data_idx > 1 && !view_map))
-      fputs (plot_stream, "set pm3d implicit;\n");
-    else
-      fputs (plot_stream, "set pm3d explicit;\n");
-    endif
+  if (isempty (ylim))
+    return;
+  endif
+  if (strcmpi (axis_obj.ydir, "reverse"))
+    ydir = "reverse";
+  else
+    ydir = "noreverse";
+  endif
+  fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir);
+  if (strcmpi (axis_obj.yaxislocation, "right"))
+    fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir);
+  endif
 
-    if (isnan (hidden_removal) || hidden_removal)
-      fputs (plot_stream, "set hidden3d;\n");
-    else
-      fputs (plot_stream, "unset hidden3d;\n");
-    endif
-
-    have_data = (! (isempty (data) || all (cellfun ("isempty", data))));
-
-    ## Note we don't use the [xy]2range of gnuplot as we don't use the
-    ## dual axis plotting features of gnuplot.
-    if (isempty (xlim))
+  if (nd == 3)
+    if (isempty (zlim))
       return;
     endif
-    if (strcmpi (axis_obj.xdir, "reverse"))
-      xdir = "reverse";
+    if (strcmpi (axis_obj.zdir, "reverse"))
+      zdir = "reverse";
     else
-      xdir = "noreverse";
-    endif
-    fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir);
-    if (strcmpi (axis_obj.xaxislocation, "top"))
-      fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir);
-    endif
-
-    if (isempty (ylim))
-      return;
+      zdir = "noreverse";
     endif
-    if (strcmpi (axis_obj.ydir, "reverse"))
-      ydir = "reverse";
-    else
-      ydir = "noreverse";
-    endif
-    fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir);
-    if (strcmpi (axis_obj.yaxislocation, "right"))
-      fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir);
-    endif
+    fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir);
+  endif
 
-    if (nd == 3)
-      if (isempty (zlim))
-        return;
-      endif
-      if (strcmpi (axis_obj.zdir, "reverse"))
-        zdir = "reverse";
+  cmap = parent_figure_obj.colormap;
+  cmap_sz = rows (cmap);
+  if (! any (isinf (clim)))
+    if (truecolor || ! cdatadirect)
+      if (rows (addedcmap) > 0)
+        for i = 1:data_idx
+          if (have_3d_patch(i))
+            data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
+           endif
+        endfor
+        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim(1), clim(2) *
+                 (cmap_sz + rows (addedcmap)) / cmap_sz);
       else
-        zdir = "noreverse";
-      endif
-      fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir);
-    endif
-
-    cmap = parent_figure_obj.colormap;
-    cmap_sz = rows (cmap);
-    if (! any (isinf (clim)))
-      if (truecolor || ! cdatadirect)
-        if (rows (addedcmap) > 0)
-          for i = 1:data_idx
-            if (have_3d_patch(i))
-              data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
-             endif
-          endfor
-          fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim(1), clim(2) *
-                   (cmap_sz + rows (addedcmap)) / cmap_sz);
-        else
-          fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim);
-        endif
-      else
-        fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz +
-                 rows (addedcmap));
-      endif
-    endif
-
-    if (strcmpi (axis_obj.box, "on"))
-      if (nd == 3)
-        fputs (plot_stream, "set border 4095;\n");
-      else
-        fputs (plot_stream, "set border 431;\n");
+        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim);
       endif
     else
-      if (nd == 3)
-        fputs (plot_stream, "set border 895;\n");
-      elseif (! isempty (axis_obj.ytick))
-        if (strcmpi (axis_obj.yaxislocation, "right"))
-          fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
+      fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz +
+               rows (addedcmap));
+    endif
+  endif
+
+  if (strcmpi (axis_obj.box, "on"))
+    if (nd == 3)
+      fputs (plot_stream, "set border 4095;\n");
+    else
+      fputs (plot_stream, "set border 431;\n");
+    endif
+  else
+    if (nd == 3)
+      fputs (plot_stream, "set border 895;\n");
+    elseif (! isempty (axis_obj.ytick))
+      if (strcmpi (axis_obj.yaxislocation, "right"))
+        fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
+                 axis_obj.tickdir);
+        if (strcmpi (axis_obj.xaxislocation, "top"))
+          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 12;\n");
+        elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 9;\n");
+        else # xaxislocation == zero
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
                    axis_obj.tickdir);
-          if (strcmpi (axis_obj.xaxislocation, "top"))
-            fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 12;\n");
-          elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 9;\n");
-          else # xaxislocation == zero
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 8;\n");
-            fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
-                     axis_obj.linewidth);
-          endif
-        elseif (strcmpi (axis_obj.yaxislocation, "left"))
-          fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
+          fputs (plot_stream, "set border 8;\n");
+          fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
+                   axis_obj.linewidth);
+        endif
+      elseif (strcmpi (axis_obj.yaxislocation, "left"))
+        fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
+                 axis_obj.tickdir);
+        if (strcmpi (axis_obj.xaxislocation, "top"))
+          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 6;\n");
+        elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
                    axis_obj.tickdir);
-          if (strcmpi (axis_obj.xaxislocation, "top"))
-            fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 6;\n");
-          elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 3;\n");
-          else # xaxislocation == zero
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 2;\n");
-            fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
-                     axis_obj.linewidth);
-          endif
-        else # yaxislocation == zero
+          fputs (plot_stream, "set border 3;\n");
+        else # xaxislocation == zero
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 2;\n");
+          fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
+                   axis_obj.linewidth);
+        endif
+      else # yaxislocation == zero
+        fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
+                 axis_obj.tickdir);
+        if (strcmpi (axis_obj.xaxislocation, "top"))
+          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 4;\n");
+        elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "set border 1;\n");
+        else # xaxislocation == zero
           fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
                    axis_obj.tickdir);
-          if (strcmpi (axis_obj.xaxislocation, "top"))
-            fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 4;\n");
-          elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "set border 1;\n");
-          else # xaxislocation == zero
-            fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
-                     axis_obj.tickdir);
-            fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                     axis_obj.tickdir);
-            fputs (plot_stream, "unset border;\n");
-            fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
-                     axis_obj.linewidth);
-          endif
-          fprintf (plot_stream, "set yzeroaxis lt -1 lw %f;\n",
+          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+                   axis_obj.tickdir);
+          fputs (plot_stream, "unset border;\n");
+          fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
                    axis_obj.linewidth);
         endif
+        fprintf (plot_stream, "set yzeroaxis lt -1 lw %f;\n",
+                 axis_obj.linewidth);
+      endif
+    endif
+  endif
+
+  if (strcmpi (axis_obj.visible, "off"))
+    fputs (plot_stream, "unset border; unset tics\n");
+  else
+    fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth);
+  endif
+
+  if (! isempty (hlgnd) && ! isempty (hlgnd.children)
+      && any (strcmpi (get (hlgnd.children, "visible"), "on")))
+    if (strcmpi (hlgnd.box, "on"))
+      box = "box";
+    else
+      box = "nobox";
+    endif
+    if (strcmpi (hlgnd.orientation, "vertical"))
+      horzvert = "vertical";
+    else
+      horzvert = "horizontal";
+    endif
+    if (strcmpi (hlgnd.textposition, "right"))
+      reverse = "reverse";
+    else
+      reverse = "noreverse";
+    endif
+    inout = "inside";
+    keypos = hlgnd.location;
+    if (ischar (keypos))
+      keypos = lower (keypos);
+      keyout = strfind (keypos, "outside");
+      if (! isempty (keyout))
+        inout = "outside";
+        keypos = keypos(1:keyout-1);
       endif
     endif
-
-    if (strcmpi (axis_obj.visible, "off"))
-      fputs (plot_stream, "unset border; unset tics\n");
+    switch (keypos)
+      case "north"
+        pos = "center top";
+      case "south"
+        pos = "center bottom";
+      case "east"
+        pos = "right center";
+      case "west"
+        pos = "left center";
+      case "northeast"
+        pos = "right top";
+      case "northwest"
+        pos = "left top";
+      case "southeast"
+        pos = "right bottom";
+      case "southwest"
+        pos = "left bottom";
+      case "best"
+        pos = "";
+        warning ("legend: 'Best' not yet implemented for location specifier.\n");
+        ## Least conflict with data in plot.
+        ## Least unused space outside plot.
+      otherwise
+        pos = "";
+    endswitch
+    if (__gnuplot_has_feature__ ("key_has_font_properties"))
+      [fontname, fontsize] = get_fontname_and_size (hlgnd);
+      fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
     else
-      fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth);
+      fontspec = "";
+    endif
+    textcolors = get (findobj (hlgnd.children, "type", "text"), "color");
+    if (iscell (textcolors))
+      textcolors = cell2mat (textcolors);
+      textcolors = unique (textcolors, "rows");
     endif
+    if (rows (textcolors) > 1)
+      ## Gnuplot is unable to assign arbitrary colors to each text entry
+      ## for the key/legend.  But, the text color can be set to match the
+      ## color of the plot object.
+      colorspec = "textcolor variable";
+    else
+      colorspec = get_text_colorspec (textcolors, mono);
+    endif
+    fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s %s;\n",
+             inout, pos, box, reverse, horzvert, fontspec, colorspec);
+  else
+    fputs (plot_stream, "unset key;\n");
+  endif
+  fputs (plot_stream, "set style data lines;\n");
 
-    if (! isempty (hlgnd) && ! isempty (hlgnd.children)
-        && any (strcmpi (get (hlgnd.children, "visible"), "on")))
-      if (strcmpi (hlgnd.box, "on"))
-        box = "box";
+  cmap = [cmap; addedcmap];
+  cmap_sz = cmap_sz + rows (addedcmap);
+  if (length (cmap) > 0)
+    fprintf (plot_stream,
+             "set palette positive color model RGB maxcolors %i;\n",
+             cmap_sz);
+    fprintf (plot_stream,
+             "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
+             cmap_sz);
+    fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32");
+    fwrite (plot_stream, "\n");
+  endif
+
+  fputs (plot_stream, "unset colorbox;\n");
+
+  if (have_data)
+    if (nd == 2)
+      plot_cmd = "plot";
+    else
+      plot_cmd = "splot";
+      rot_x = 90 - axis_obj.view(2);
+      rot_z = axis_obj.view(1);
+      while (rot_z < 0)
+        rot_z += 360;
+      endwhile
+      fputs (plot_stream, "set ticslevel 0;\n");
+      if (view_map && rot_x == 0 && rot_z == 0)
+        fputs (plot_stream, "set view map;\n");
       else
-        box = "nobox";
+        fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z);
       endif
-      if (strcmpi (hlgnd.orientation, "vertical"))
-        horzvert = "vertical";
-      else
-        horzvert = "horizontal";
-      endif
-      if (strcmpi (hlgnd.textposition, "right"))
-        reverse = "reverse";
-      else
-        reverse = "noreverse";
-      endif
-      inout = "inside";
-      keypos = hlgnd.location;
-      if (ischar (keypos))
-        keypos = lower (keypos);
-        keyout = strfind (keypos, "outside");
-        if (! isempty (keyout))
-          inout = "outside";
-          keypos = keypos(1:keyout-1);
+    endif
+    if (have_3d_patch (1))
+      fputs (plot_stream, "set pm3d depthorder\n");
+      fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
+               usingclause{1}, titlespec{1}, withclause{1});
+    elseif (is_image_data (1))
+      if (numel (is_image_data) > 1 && is_image_data(2))
+        ## Remove terminating semicolon
+        n = max (strfind (withclause{1}, ";"));
+        if (! isempty (n))
+          withclause{1} = withclause{1}(1:n-1);
         endif
       endif
-      switch (keypos)
-        case "north"
-          pos = "center top";
-        case "south"
-          pos = "center bottom";
-        case "east"
-          pos = "right center";
-        case "west"
-          pos = "left center";
-        case "northeast"
-          pos = "right top";
-        case "northwest"
-          pos = "left top";
-        case "southeast"
-          pos = "right bottom";
-        case "southwest"
-          pos = "left bottom";
-        case "best"
-          pos = "";
-          warning ("legend: 'Best' not yet implemented for location specifier.\n");
-          ## Least conflict with data in plot.
-          ## Least unused space outside plot.
-        otherwise
-          pos = "";
-      endswitch
-      if (__gnuplot_has_feature__ ("key_has_font_properties"))
-        [fontname, fontsize] = get_fontname_and_size (hlgnd);
-        fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
-      else
-        fontspec = "";
-      endif
-      textcolors = get (findobj (hlgnd.children, "type", "text"), "color");
-      if (iscell (textcolors))
-        textcolors = cell2mat (textcolors);
-        textcolors = unique (textcolors, "rows");
-      endif
-      if (rows (textcolors) > 1)
-        ## Gnuplot is unable to assign arbitrary colors to each text entry
-        ## for the key/legend.  But, the text color can be set to match the
-        ## color of the plot object.
-        colorspec = "textcolor variable";
-      else
-        colorspec = get_text_colorspec (textcolors, mono);
-      endif
-      fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s %s;\n",
-               inout, pos, box, reverse, horzvert, fontspec, colorspec);
+      fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
+               usingclause{1}, titlespec{1}, withclause{1});
     else
-      fputs (plot_stream, "unset key;\n");
-    endif
-    fputs (plot_stream, "set style data lines;\n");
-
-    cmap = [cmap; addedcmap];
-    cmap_sz = cmap_sz + rows (addedcmap);
-    if (length (cmap) > 0)
-      fprintf (plot_stream,
-               "set palette positive color model RGB maxcolors %i;\n",
-               cmap_sz);
-      fprintf (plot_stream,
-               "set palette file \"-\" binary record=%d using 1:2:3:4;\n",
-               cmap_sz);
-      fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32");
-      fwrite (plot_stream, "\n");
+      fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
+               usingclause{1}, titlespec{1}, withclause{1});
     endif
-
-    fputs (plot_stream, "unset colorbox;\n");
-
-    if (have_data)
-      if (nd == 2)
-        plot_cmd = "plot";
-      else
-        plot_cmd = "splot";
-        rot_x = 90 - axis_obj.view(2);
-        rot_z = axis_obj.view(1);
-        while (rot_z < 0)
-          rot_z += 360;
-        endwhile
-        fputs (plot_stream, "set ticslevel 0;\n");
-        if (view_map && rot_x == 0 && rot_z == 0)
-          fputs (plot_stream, "set view map;\n");
-        else
-          fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z);
-        endif
-      endif
-      if (have_3d_patch (1))
-        fputs (plot_stream, "set pm3d depthorder\n");
-        fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
-                 usingclause{1}, titlespec{1}, withclause{1});
-      elseif (is_image_data (1))
-        if (numel (is_image_data) > 1 && is_image_data(2))
-          ## Remove terminating semicolon
-          n = max (strfind (withclause{1}, ";"));
-          if (! isempty (n))
-            withclause{1} = withclause{1}(1:n-1);
-          endif
-        endif
-        fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
-                 usingclause{1}, titlespec{1}, withclause{1});
-      else
-        fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
-                 usingclause{1}, titlespec{1}, withclause{1});
-      endif
-      for i = 2:data_idx
-        if (have_3d_patch (i))
-          fprintf (plot_stream, ", \"-\" %s %s %s \\\n",
-                   usingclause{i}, titlespec{i}, withclause{i});
-        elseif (is_image_data (i))
-          if (! is_image_data (i-1))
-            fputs (plot_stream, "; ");
-            if (bg_is_set)
-              fputs (plot_stream, "unset obj 1; \\\n");
-              bg_is_set = false;
-            endif
-            if (fg_is_set)
-              fputs (plot_stream, "unset obj 2; \\\n");
-              fg_is_set = false;
-            endif
-            if (numel (is_image_data) > i && is_image_data(i+1))
-              ## Remove terminating semicolon
-              n = max (strfind (withclause{i}, ";"));
-              if (! isempty (n))
-                withclause{i} = withclause{i}(1:n-1);
-              endif
-            endif
-            fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
-                     usingclause{i}, titlespec{i}, withclause{i});
-          else
-            ## For consecutive images continue with the same plot command
-            fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", ",",
-                     usingclause{i}, titlespec{i}, withclause{i});
-          endif
-        elseif (is_image_data (i-1))
+    for i = 2:data_idx
+      if (have_3d_patch (i))
+        fprintf (plot_stream, ", \"-\" %s %s %s \\\n",
+                 usingclause{i}, titlespec{i}, withclause{i});
+      elseif (is_image_data (i))
+        if (! is_image_data (i-1))
+          fputs (plot_stream, "; ");
           if (bg_is_set)
             fputs (plot_stream, "unset obj 1; \\\n");
             bg_is_set = false;
@@ -1699,55 +1676,74 @@
             fputs (plot_stream, "unset obj 2; \\\n");
             fg_is_set = false;
           endif
-          fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
+          if (numel (is_image_data) > i && is_image_data(i+1))
+            ## Remove terminating semicolon
+            n = max (strfind (withclause{i}, ";"));
+            if (! isempty (n))
+              withclause{i} = withclause{i}(1:n-1);
+            endif
+          endif
+          fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
                    usingclause{i}, titlespec{i}, withclause{i});
         else
-          fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n",
+          ## For consecutive images continue with the same plot command
+          fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", ",",
                    usingclause{i}, titlespec{i}, withclause{i});
         endif
-      endfor
-      fputs (plot_stream, ";\n");
-      for i = 1:data_idx
-        if (have_3d_patch (i))
-          ## Can't write 3d patch data as binary as can't plot more than
-          ## a single patch at a time and have to plot all patches together
-          ## so that the gnuplot depth ordering is done correctly
-          for j = 1 : 4 : columns (data{i})
-            if (j != 1)
-              fputs (plot_stream, "\n\n");
-            endif
-            fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).');
-            fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).');
-            fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).');
-            fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).');
-          endfor
-          fputs (plot_stream, "e\n");
-        elseif (is_image_data(i))
-          fwrite (plot_stream, data{i}, "float32");
-        else
-          __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i),
-                                  have_cdata(i));
+      elseif (is_image_data (i-1))
+        if (bg_is_set)
+          fputs (plot_stream, "unset obj 1; \\\n");
+          bg_is_set = false;
+        endif
+        if (fg_is_set)
+          fputs (plot_stream, "unset obj 2; \\\n");
+          fg_is_set = false;
         endif
-      endfor
-    else
-      fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
-    endif
-
-    ## Needed to allow mouse rotation with pcolor.
-    if (view_map)
-      fputs (plot_stream, "unset view;\n");
-    endif
+        fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
+                 usingclause{i}, titlespec{i}, withclause{i});
+      else
+        fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n",
+                 usingclause{i}, titlespec{i}, withclause{i});
+      endif
+    endfor
+    fputs (plot_stream, ";\n");
+    for i = 1:data_idx
+      if (have_3d_patch (i))
+        ## Can't write 3d patch data as binary as can't plot more than
+        ## a single patch at a time and have to plot all patches together
+        ## so that the gnuplot depth ordering is done correctly
+        for j = 1 : 4 : columns (data{i})
+          if (j != 1)
+            fputs (plot_stream, "\n\n");
+          endif
+          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).');
+          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).');
+          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).');
+          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).');
+        endfor
+        fputs (plot_stream, "e\n");
+      elseif (is_image_data(i))
+        fwrite (plot_stream, data{i}, "float32");
+      else
+        __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i),
+                                have_cdata(i));
+      endif
+    endfor
+  else
+    fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n");
+  endif
 
-    if (bg_is_set)
-      fputs (plot_stream, "unset obj 1;\n");
-      bg_is_set = false;
-    endif
+  ## Needed to allow mouse rotation with pcolor.
+  if (view_map)
+    fputs (plot_stream, "unset view;\n");
+  endif
 
-    fflush (plot_stream);
+  if (bg_is_set)
+    fputs (plot_stream, "unset obj 1;\n");
+    bg_is_set = false;
+  endif
 
-  else
-    print_usage ();
-  endif
+  fflush (plot_stream);
 
 endfunction
 
@@ -1835,8 +1831,8 @@
 
     facesame = true;
     if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor")
-        && !strncmp (obj.markerfacecolor, "none", 4))
-      if (strncmp (obj.markerfacecolor, "auto", 4)
+        && !strcmp (obj.markerfacecolor, "none"))
+      if (strcmp (obj.markerfacecolor, "auto")
           || ! isnumeric (obj.markerfacecolor)
           || (isnumeric (obj.markerfacecolor)
               && isequal (color, obj.markerfacecolor)))
@@ -1875,14 +1871,14 @@
       endif
     endif
     if (isfield (obj, "markeredgecolor")
-        && !strncmp (obj.markeredgecolor, "none", 4))
+        && !strcmp (obj.markeredgecolor, "none"))
       if (facesame && !isempty (pt)
-          && (strncmp (obj.markeredgecolor, "auto", 4)
+          && (strcmp (obj.markeredgecolor, "auto")
               || ! isnumeric (obj.markeredgecolor)
               || (isnumeric (obj.markeredgecolor)
                   && isequal (color, obj.markeredgecolor))))
         if (sidx == 1 && ((length (style {sidx}) == 5
-            && strncmp (style {sidx}, "lines", 5)) || isempty (style {sidx})))
+            && strncmp (style{sidx}, "lines", 5)) || isempty (style {sidx})))
           if (! isempty (pt))
             style {sidx} = strcat (style{sidx}, "points");
             fprintf (plot_stream, " pointtype %s", pt);
@@ -1905,7 +1901,7 @@
         fprintf (plot_stream, "set style line %d default;\n", idx);
         fprintf (plot_stream, "set style line %d", idx);
         if (! mono)
-          if (strncmp (obj.markeredgecolor, "auto", 4))
+          if (strcmp (obj.markeredgecolor, "auto"))
             fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"",
                      round (255*color));
           elseif (isnumeric (obj.markeredgecolor) && ! mono)
@@ -1949,7 +1945,7 @@
         pt = "6";
         pt2 = "7";
         if (isfield (obj, "markerfacecolor")
-            || strncmp (obj.markerfacecolor, "none", 4))
+            || strcmp (obj.markerfacecolor, "none"))
           obj.markerfacecolor = "auto";
         endif
         if (isfield (obj, "markersize"))
@@ -1972,19 +1968,19 @@
         pt = "10";
         pt2 = "11";
       case ">"
-        ## FIXME -- should be triangle pointing right, use triangle pointing up
+        ## FIXME: should be triangle pointing right, use triangle pointing up
         pt = "8";
         pt2 = "9";
       case "<"
-        ## FIXME -- should be triangle pointing left, use triangle pointing down
+        ## FIXME: should be triangle pointing left, use triangle pointing down
         pt = "10";
         pt2 = "11";
       case {"pentagram", "p"}
-        ## FIXME -- should be pentagram, using pentagon
+        ## FIXME: should be pentagram, using pentagon
         pt = "14";
         pt2 = "15";
       case {"hexagram", "h"}
-        ## FIXME -- should be 6 pt start, using "*" instead
+        ## FIXME: should be 6 pt start, using "*" instead
         pt = pt2 = "3";
       case "none"
         pt = pt2 = "";
@@ -2663,3 +2659,4 @@
     endif
   endif
 endfunction
+
--- a/scripts/plot/private/__go_draw_figure__.m
+++ b/scripts/plot/private/__go_draw_figure__.m
@@ -25,185 +25,181 @@
 
 function __go_draw_figure__ (h, plot_stream, enhanced, mono)
 
-  if (nargin == 4)
-    htype = get (h, "type");
-    if (strcmp (htype, "figure"))
-      ## Get complete list of children.
-      kids = allchild (h);
-      nkids = length (kids);
+  htype = get (h, "type");
+  if (strcmp (htype, "figure"))
+    ## Get complete list of children.
+    kids = allchild (h);
+    nkids = length (kids);
 
-      if (nkids > 0)
-        fputs (plot_stream, "\nreset;\n");
-        fputs (plot_stream, "set autoscale keepfix;\n");
-        fputs (plot_stream, "set origin 0, 0\n");
-        fputs (plot_stream, "set size 1, 1\n");
-        bg = get (h, "color");
-        if (isnumeric (bg))
-          fprintf (plot_stream, "set obj 1 rectangle from screen 0,0 to screen 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * bg);
-          bg_is_set = true;
-        else
-          bg_is_set = false;
-        endif
-        fg_was_set = false;
+    if (nkids > 0)
+      fputs (plot_stream, "\nreset;\n");
+      fputs (plot_stream, "set autoscale keepfix;\n");
+      fputs (plot_stream, "set origin 0, 0\n");
+      fputs (plot_stream, "set size 1, 1\n");
+      bg = get (h, "color");
+      if (isnumeric (bg))
+        fprintf (plot_stream, "set obj 1 rectangle from screen 0,0 to screen 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * bg);
+        bg_is_set = true;
+      else
+        bg_is_set = false;
+      endif
+      fg_was_set = false;
 
-        for i = nkids:-1:1
-          type = get (kids(i), "type");
-          switch (type)
-            case "axes"
-              if (strcmpi (get (kids (i), "tag"), "legend"))
-                ## This is so ugly. If there was a way of getting
-                ## gnuplot to give us the text extents of strings
-                ## then we could get rid of this mess.
-                lh = getfield (get (kids(i), "userdata"), "handle");
-                if (isscalar (lh))
-                  ## We have a legend with a single parent. It'll be handled
-                  ## below as a gnuplot key to the axis it corresponds to
-                  continue;
-                else
-                  ca = lh(1);
-                  ## Rely upon listener to convert axes position
-                  ## to "normalized" units.
-                  legend_axes_units = get (kids(i), "units");
-                  legend_axes_position = get (kids(i), "position");
-                  legend_axes_outerposition = get (kids(i), "outerposition");
-                  legend_axes_box = get (kids(i), "box");
-                  legend_axes_ylim = get (kids(i), "ylim");
-                  orig_axes_units = get (ca, "units");
-                  hlgnd = get (kids(i));
+      for i = nkids:-1:1
+        type = get (kids(i), "type");
+        switch (type)
+          case "axes"
+            if (strcmpi (get (kids (i), "tag"), "legend"))
+              ## This is so ugly. If there was a way of getting
+              ## gnuplot to give us the text extents of strings
+              ## then we could get rid of this mess.
+              lh = getfield (get (kids(i), "userdata"), "handle");
+              if (isscalar (lh))
+                ## We have a legend with a single parent. It'll be handled
+                ## below as a gnuplot key to the axis it corresponds to
+                continue;
+              else
+                ca = lh(1);
+                ## Rely upon listener to convert axes position
+                ## to "normalized" units.
+                legend_axes_units = get (kids(i), "units");
+                legend_axes_position = get (kids(i), "position");
+                legend_axes_outerposition = get (kids(i), "outerposition");
+                legend_axes_box = get (kids(i), "box");
+                legend_axes_ylim = get (kids(i), "ylim");
+                orig_axes_units = get (ca, "units");
+                hlgnd = get (kids(i));
 
-                  unwind_protect
-                    set (ca, "units", "normalized");
-                    set (kids(i), "units", "normalized", "box", "off",
-                         "ylim", [-2, -1], "position", get (ca(1), "position"),
-                         "outerposition", get (ca(1), "outerposition"));
+                unwind_protect
+                  set (ca, "units", "normalized");
+                  set (kids(i), "units", "normalized", "box", "off",
+                       "ylim", [-2, -1], "position", get (ca(1), "position"),
+                       "outerposition", get (ca(1), "outerposition"));
 
-                    ## Create a new set of lines with the appropriate
-                    ## displaynames, etc
-                    toberm = [];
-                    hobj = get (kids(i), "children");
-                    for j = numel (hobj) : -1 : 1
-                      if (! strcmp (get (hobj(j), "type"), "text"))
+                  ## Create a new set of lines with the appropriate
+                  ## displaynames, etc
+                  toberm = [];
+                  hobj = get (kids(i), "children");
+                  for j = numel (hobj) : -1 : 1
+                    if (! strcmp (get (hobj(j), "type"), "text"))
+                      continue;
+                    endif
+                    displayname = get (hobj(j), "string");
+                    ll = [];
+                    lm = [];
+                    for k = numel (hobj) : -1 : 1
+                      if (! strcmp (get (hobj(k), "type"), "line"))
                         continue;
                       endif
-                      displayname = get (hobj(j), "string");
-                      ll = [];
-                      lm = [];
-                      for k = numel (hobj) : -1 : 1
-                        if (! strcmp (get (hobj(k), "type"), "line"))
-                          continue;
-                        endif
-                        if (get (hobj(j), "userdata")
-                            != get (hobj(k), "userdata"))
-                          continue;
-                        endif
-                        if (! strcmp (get (hobj(k), "linestyle"), "none"))
-                          ll = hobj(k);
-                        endif
-                        if (! strcmp (get (hobj(k), "marker"), "none"))
-                          lm = hobj(k);
-                        endif
-                      endfor
-
-                      if (! isempty (ll))
-                        if (!isempty (lm))
-                          toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", get(ll,"linestyle"), "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))];
-                        else
-                          toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(ll,"color"), "linestyle", get(ll,"linestyle"), "marker", "none", "displayname", displayname, "parent", kids(i))];
-                        endif
-                      elseif (! isempty (lm))
-                        toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", "none", "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))];
+                      if (get (hobj(j), "userdata")
+                          != get (hobj(k), "userdata"))
+                        continue;
+                      endif
+                      if (! strcmp (get (hobj(k), "linestyle"), "none"))
+                        ll = hobj(k);
+                      endif
+                      if (! strcmp (get (hobj(k), "marker"), "none"))
+                        lm = hobj(k);
                       endif
                     endfor
-                    if (bg_is_set)
-                      fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg));
+
+                    if (! isempty (ll))
+                      if (!isempty (lm))
+                        toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", get(ll,"linestyle"), "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))];
+                      else
+                        toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(ll,"color"), "linestyle", get(ll,"linestyle"), "marker", "none", "displayname", displayname, "parent", kids(i))];
+                      endif
+                    elseif (! isempty (lm))
+                      toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", "none", "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))];
                     endif
-                    __go_draw_axes__ (kids(i), plot_stream, enhanced, mono,
-                                      bg_is_set, false, hlgnd);
-                  unwind_protect_cleanup
-                    ## Return axes "units" and "position" back to
-                    ## their original values.
-                    set (ca, "units", orig_axes_units);
-                    set (kids(i), "units", legend_axes_units,
-                         "box", legend_axes_box,
-                         "ylim", legend_axes_ylim,
-                         "position", legend_axes_position,
-                         "outerposition", legend_axes_outerposition);
-                    delete (toberm);
-                    bg_is_set = false;
-                  end_unwind_protect
-                endif
-              else
-                ## Rely upon listener to convert axes position
-                ## to "normalized" units.
-                orig_axes_units = get (kids(i), "units");
-                orig_axes_position = get (kids(i), "position");
-                unwind_protect
-                  set (kids(i), "units", "normalized");
-                  fg = get (kids(i), "color");
-                  if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on"))
-                    fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg);
-                    fg_is_set = true;
-                    fg_was_set = true;
-                  elseif (fg_was_set)
-                    fprintf (plot_stream, "unset obj 2\n");
-                    fg_is_set = false;
-                    fg_was_set = false;
-                  else
-                    fg_is_set = false;
-                  endif
+                  endfor
                   if (bg_is_set)
                     fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg));
                   endif
-                  ## Find if this axes has an associated legend axes and pass it
-                  ## to __go_draw_axes__
-                  hlegend = [];
-                  fkids = get (h, "children");
-                  for j = 1 : numel (fkids)
-                    if (ishandle (fkids (j))
-                        && strcmp (get (fkids (j), "type"), "axes")
-                        && (strcmp (get (fkids (j), "tag"), "legend")))
-                      udata = get (fkids (j), "userdata");
-                      if (isscalar (udata.handle)
-                          && ! isempty (intersect (udata.handle, kids (i))))
-                        hlegend = get (fkids (j));
-                        break;
-                      endif
-                    endif
-                  endfor
                   __go_draw_axes__ (kids(i), plot_stream, enhanced, mono,
-                                    bg_is_set, fg_is_set, hlegend);
+                                    bg_is_set, false, hlgnd);
                 unwind_protect_cleanup
                   ## Return axes "units" and "position" back to
                   ## their original values.
-                  set (kids(i), "units", orig_axes_units);
-                  set (kids(i), "position", orig_axes_position);
+                  set (ca, "units", orig_axes_units);
+                  set (kids(i), "units", legend_axes_units,
+                       "box", legend_axes_box,
+                       "ylim", legend_axes_ylim,
+                       "position", legend_axes_position,
+                       "outerposition", legend_axes_outerposition);
+                  delete (toberm);
                   bg_is_set = false;
-                  fg_is_set = false;
                 end_unwind_protect
               endif
-            case "uimenu"
-              ## ignore uimenu objects
-              kids(i) = [];
-            otherwise
-              error ("__go_draw_figure__: unknown object class, %s", type);
-          endswitch
-        endfor
-        if (isempty (kids))
-          fputs (plot_stream, "\nreset; clear;\n");
-          fflush (plot_stream);
-        else
-          fputs (plot_stream, "\nunset multiplot;\n");
-        endif
-      else
+            else
+              ## Rely upon listener to convert axes position
+              ## to "normalized" units.
+              orig_axes_units = get (kids(i), "units");
+              orig_axes_position = get (kids(i), "position");
+              unwind_protect
+                set (kids(i), "units", "normalized");
+                fg = get (kids(i), "color");
+                if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on"))
+                  fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg);
+                  fg_is_set = true;
+                  fg_was_set = true;
+                elseif (fg_was_set)
+                  fprintf (plot_stream, "unset obj 2\n");
+                  fg_is_set = false;
+                  fg_was_set = false;
+                else
+                  fg_is_set = false;
+                endif
+                if (bg_is_set)
+                  fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg));
+                endif
+                ## Find if this axes has an associated legend axes and pass it
+                ## to __go_draw_axes__
+                hlegend = [];
+                fkids = get (h, "children");
+                for j = 1 : numel (fkids)
+                  if (ishandle (fkids (j))
+                      && strcmp (get (fkids (j), "type"), "axes")
+                      && (strcmp (get (fkids (j), "tag"), "legend")))
+                    udata = get (fkids (j), "userdata");
+                    if (isscalar (udata.handle)
+                        && ! isempty (intersect (udata.handle, kids (i))))
+                      hlegend = get (fkids (j));
+                      break;
+                    endif
+                  endif
+                endfor
+                __go_draw_axes__ (kids(i), plot_stream, enhanced, mono,
+                                  bg_is_set, fg_is_set, hlegend);
+              unwind_protect_cleanup
+                ## Return axes "units" and "position" back to
+                ## their original values.
+                set (kids(i), "units", orig_axes_units);
+                set (kids(i), "position", orig_axes_position);
+                bg_is_set = false;
+                fg_is_set = false;
+              end_unwind_protect
+            endif
+          case "uimenu"
+            ## ignore uimenu objects
+            kids(i) = [];
+          otherwise
+            error ("__go_draw_figure__: unknown object class, %s", type);
+        endswitch
+      endfor
+      if (isempty (kids))
         fputs (plot_stream, "\nreset; clear;\n");
         fflush (plot_stream);
+      else
+        fputs (plot_stream, "\nunset multiplot;\n");
       endif
     else
-      error ("__go_draw_figure__: expecting figure object, found '%s'",
-             htype);
+      fputs (plot_stream, "\nreset; clear;\n");
+      fflush (plot_stream);
     endif
   else
-    print_usage ();
+    error ("__go_draw_figure__: expecting figure object, found '%s'",
+           htype);
   endif
 
 endfunction
--- a/scripts/plot/private/__interp_cube__.m
+++ b/scripts/plot/private/__interp_cube__.m
@@ -24,12 +24,12 @@
 ## @end deftypefn
 
 function [Vxyz, idx, frac] = __interp_cube__ (x, y, z, val, v, req = "values" )
-  if (ismatrix (x) && ndims (x) == 3 && ismatrix (y) && ndims (y) == 3 ...
+  if (ismatrix (x) && ndims (x) == 3 && ismatrix (y) && ndims (y) == 3
        && ismatrix (z) && ndims (z) == 3 && size_equal (x, y, z, val))
     x = squeeze (x(1,:,1))(:);
     y = squeeze (y(:,1,1))(:);
     z = squeeze (z(1,1,:))(:);
-  elseif (isvector (x) && isvector (y) && isvector (z) )
+  elseif (isvector (x) && isvector (y) && isvector (z))
     x = x(:);
     y = y(:);
     z = z(:);
@@ -40,19 +40,17 @@
     error ("__interp_cube__: VAL has wrong dimensions");
   endif
   if (columns (v) != 3)
-    error ( "v has to be N*3 matrix");
+    error ( "V has to be Nx3 matrix");
   endif
-  if (!ischar (req))
-   error ("__interp_cube__: Invalid request parameter use 'values', 'normals' or 'normals8'");
-  endif
+  ##if (!ischar (req))
+  ## error ('__interp_cube__: Invalid request parameter use "values", "normals" or "normals8"');
+  ##endif
   if (isempty (v))
     Vxyz = idx = frac = [];
-    return
+    return;
   endif
 
   switch (req)
-    case "values"
-      [Vxyz, idx, frac] = interp_cube_trilin (x, y, z, val, v);
     case "normals"
       [idx, frac] = cube_idx (x, y, z, v);
 
@@ -96,8 +94,10 @@
       dz = [dz;dz(end)](idx(:,3));
       [Dx, Dy, Dz, idx, frac] = interp_cube_trilin_grad (x, y, z, val, v);
       Vxyz = [Dx./dx, Dy./dy, Dz./dz];
+    case "values"
+      [Vxyz, idx, frac] = interp_cube_trilin (x, y, z, val, v);
    otherwise
-     error ("__interp_cube__: Invalid request type '%s', use 'values', 'normals' or 'normals8'", req);
+     error ('__interp_cube__: Invalid request type "%s", use "values", "normals" or "normals8"', req);
   endswitch
 endfunction
 
@@ -182,3 +182,4 @@
   frac(:, 3) = (v(:, 3) - z(idx(:, 3))) ...
       ./ (z(idx(:, 3)+1) - z(idx(:, 3)));
 endfunction
+
--- a/scripts/plot/private/__is_function__.m
+++ b/scripts/plot/private/__is_function__.m
@@ -29,3 +29,4 @@
   result = (existval == 2 || existval == 3 || existval == 5 || existval == 6);
 
 endfunction
+
--- a/scripts/plot/private/__line__.m
+++ b/scripts/plot/private/__line__.m
@@ -29,10 +29,6 @@
 
 function h = __line__ (p, varargin)
 
-  if (nargin < 1)
-    print_usage ();
-  endif
-
   nvargs = numel (varargin);
 
   if (nvargs > 1 && ! ischar (varargin{1}) && ! ischar (varargin{2}))
@@ -117,7 +113,6 @@
         || (nvecpts != 0 && any (nvecpts != cellfun ("size", tmp, 1))))
       error ("line: data size_mismatch");
     endif
-
     data_args(mask) = cellfun (@(x) x(:,i), data(ismat),
                                "uniformoutput", false);
 
@@ -130,3 +125,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__marching_cube__.m
+++ b/scripts/plot/private/__marching_cube__.m
@@ -66,7 +66,7 @@
 ## @example
 ## @group
 ## figure (); view (-38, 20);
-## pa = patch ("Faces", t, "Vertices", p, "FaceVertexCData", p, \
+## pa = patch ("Faces", t, "Vertices", p, "FaceVertexCData", p, ...
 ##             "FaceColor", "interp", "EdgeColor", "none");
 ##
 ## ## Revert normals
@@ -149,7 +149,7 @@
   id =  find (cedge); # select only voxels which are intersected
   if (isempty (id))
     T = p = col = [];
-    return
+    return;
   endif
 
   ## phase II: calculate the list of intersection points
@@ -528,3 +528,4 @@
   0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + 1;
 endfunction
+
--- a/scripts/plot/private/__next_line_color__.m
+++ b/scripts/plot/private/__next_line_color__.m
@@ -31,27 +31,23 @@
 
   persistent reset_colors = true;
 
-  if (nargin > 1)
-    print_usage ();
-  endif
-
   if (nargin == 1)
     ## Indicates whether the next call will increment or not
     reset_colors = reset;
   else
     ## Find and return the next line color
     ca = gca ();
-    colorOrder = get (ca, "ColorOrder");
+    colororder = get (ca, "colororder");
     if (reset_colors)
       color_index = 1;
       reset_colors = false;
     else
       ## Executed when "hold all" is active
-      nChildren = length (get (ca, "Children"));
-      nColors = rows (colorOrder);
-      color_index = mod (nChildren, nColors) + 1;
+      n_kids = length (get (ca, "children"));
+      n_colors = rows (colororder);
+      color_index = mod (n_kids, n_colors) + 1;
     endif
-    rgb = colorOrder(color_index,:);
+    rgb = colororder(color_index,:);
   endif
 
 endfunction
--- a/scripts/plot/private/__next_line_style__.m
+++ b/scripts/plot/private/__next_line_style__.m
@@ -28,10 +28,6 @@
 
   persistent reset_style = true;
 
-  if (nargin > 1)
-    print_usage ();
-  endif
-
   if (nargin == 1)
     ## Indicates whether the next call will increment or not
     reset_style = reset;
@@ -49,7 +45,7 @@
     else
       ## Executed when "hold all" is active
       nChildren = length (get (ca, "Children"));
-      nColors = length (get (ca, "ColorOrder"));
+      nColors = rows (get (ca, "ColorOrder"));
       style_index = mod (floor (nChildren/nColors), nStyles) + 1;
     endif
     options = __pltopt__ ("__next_line_style__",
@@ -59,3 +55,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__patch__.m
+++ b/scripts/plot/private/__patch__.m
@@ -148,7 +148,7 @@
             args{7} = "facecolor";
             args{8} = "interp";
             args{9} = "cdata";
-            agrs{10} = c;
+            args{10} = c;
           else
             error ("patch: color value not valid");
           endif
@@ -210,13 +210,14 @@
 endfunction
 
 function args = delfields (args, flds)
-  idx = cellfun (@(x) any (strcmpi (x, flds)), args);
+  idx = cellfun ("isclass", args, "char");
+  idx(idx) = ismember (args(idx), flds);
   if (rows (idx) == 1)
-    idx = idx | [false, idx(1:end-1)];
+    idx |= [false, idx(1:end-1)];
   else
-    idx = idx | [false; idx(1:end-1)];
+    idx |= [false; idx(1:end-1)];
   endif
-  args (idx) = [];
+  args(idx) = [];
 endfunction
 
 function args = setdata (args)
@@ -366,3 +367,4 @@
     recursive = false;
   endif
 endfunction
+
--- a/scripts/plot/private/__pie__.m
+++ b/scripts/plot/private/__pie__.m
@@ -114,7 +114,7 @@
       set (h, "clim", [1, len]);
     endif
 
-    if (strncmp (caller, "pie3", 4))
+    if (strcmp (caller, "pie3"))
       ln = length (xn);
       zlvl = 0.35;
       sx = repmat (xoff + [0, -sind(xn), 0], [2, 1]);
@@ -128,7 +128,7 @@
         patch(xoff + [0, -sind(xn)], yoff + [0, cosd(xn)], zlvl * ones (1, ln + 1), i);
         text(xt, yt, zlvl, labels{i})];
 
-    elseif (strncmp (caller, "pie", 3))
+    elseif (strcmp (caller, "pie"))
       if (xt > 0)
         align = "left";
       else
@@ -145,10 +145,10 @@
 
   addlistener (gca, "view", {@update_text_pos, hlist});
 
-  if (strncmp (caller, "pie3", 4))
+  if (strcmp (caller, "pie3"))
     axis ([-1.25, 1.25, -1.25, 1.25, -0.05, 0.4], "equal", "off");
     view (-37.5, 30);
-  elseif (strncmp (caller, "pie", 3))
+  elseif (strcmp (caller, "pie"))
     axis ([-1.5, 1.5, -1.5, 1.5], "square", "off");
   endif
 endfunction
@@ -198,3 +198,4 @@
     endfor
   endif
 endfunction
+
--- a/scripts/plot/private/__plt__.m
+++ b/scripts/plot/private/__plt__.m
@@ -25,6 +25,7 @@
 
 function retval = __plt__ (caller, h, varargin)
 
+  persistent warned_callers = {};
   nargs = nargin - 2;
 
   if (nargs > 0)
@@ -72,6 +73,19 @@
         next_arg = varargin{k++};
       endif
 
+      if (isnumeric (next_arg) && ndims (next_arg) > 2
+          && any (size (next_arg) == 1))
+        next_arg = squeeze (next_arg);
+        if (! any (strcmp (caller, warned_callers)) && ndims (next_arg) < 3)
+          warning (["%s: N-d inputs have been squeezed to less than " ...
+                    "three dimensions"], caller)
+          warned_callers(end+1) = caller;
+        endif
+      endif
+      if (isnumeric (next_arg) && ndims (next_arg) > 2)
+        error ("%s: plot arrays must have less than 2 dimensions", caller)
+      endif
+
       nargs--;
 
       if (ischar (next_arg) || iscellstr (next_arg))
@@ -147,7 +161,7 @@
   endif
 
   for i = 1 : n
-    key = options.key;
+    key = options(i).key;
     if (! isempty (key))
       hlgnd = [hlgnd(:); h(i)];
       tlgnd = {tlgnd{:}, key};
@@ -158,10 +172,6 @@
 
 function retval = __plt1__ (h, x1, options, properties = {})
 
-  if (nargin < 2 || nargin > 4)
-    print_usage ();
-  endif
-
   if (nargin < 3 || isempty (options))
     options = __default_plot_options__ ();
   endif
@@ -195,10 +205,6 @@
 
 function retval = __plt2__ (h, x1, x2, options, properties = {})
 
-  if (nargin < 3 || nargin > 5)
-    print_usage ();
-  endif
-
   if (nargin < 4 || isempty (options))
     options = __default_plot_options__ ();
   endif
@@ -489,8 +495,8 @@
   endif
 
   retval = line (x, y, "color", color,
-            "linestyle", linestyle,
-            "marker", marker, properties{:});
+                 "linestyle", linestyle,
+                 "marker", marker, properties{:});
 
 endfunction
 
--- a/scripts/plot/private/__pltopt__.m
+++ b/scripts/plot/private/__pltopt__.m
@@ -94,29 +94,25 @@
   valid = true;
   options =  __default_plot_options__ ();
 
-  if ((nargin == 2 || nargin == 3) && (nargout == 1 || nargout == 2))
-    if (nargin == 2)
-      err_on_invalid = true;
-    endif
-    if (ischar (opt))
-      nel = rows (opt);
-    elseif (iscellstr (opt))
-      nel = numel (opt);
-    else
-      error ("__pltopt__: expecting argument to be character string or cell array of character strings");
+  if (nargin == 2)
+    err_on_invalid = true;
+  endif
+  if (ischar (opt))
+    nel = rows (opt);
+  elseif (iscellstr (opt))
+    nel = numel (opt);
+  else
+    error ("__pltopt__: argument must be a character string or cell array of character strings");
+  endif
+  if (ischar (opt))
+    opt = cellstr (opt);
+  endif
+  for i = nel:-1:1
+    [options(i), valid] = __pltopt1__ (caller, opt{i}, err_on_invalid);
+    if (! err_on_invalid && ! valid)
+      return;
     endif
-    if (ischar (opt))
-      opt = cellstr (opt);
-    endif
-    for i = nel:-1:1
-      [options(i), valid] = __pltopt1__ (caller, opt{i}, err_on_invalid);
-      if (! err_on_invalid && ! valid)
-        return;
-      endif
-    endfor
-  else
-    print_usage ();
-  endif
+  endfor
 
 endfunction
 
@@ -133,10 +129,6 @@
 
   more_opts = 1;
 
-  if (nargin != 2 && nargin != 3)
-    print_usage ();
-  endif
-
   if (! ischar (opt))
     return;
   endif
@@ -184,7 +176,7 @@
           topt = "+";
         endif
         options.marker = topt;
-### Numeric color specs for backward compatibility.  Leave undocumented.
+      ## Numeric color specs for backward compatibility.  Leave undocumented.
       elseif (topt == "k" || topt == "0")
         options.color = [0, 0, 0];
       elseif (topt == "r" || topt == "1")
@@ -239,3 +231,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__print_parse_opts__.m
+++ b/scripts/plot/private/__print_parse_opts__.m
@@ -90,9 +90,9 @@
         arg_st.force_solid = 1;
       elseif (strcmp (arg, "-dashed"))
         arg_st.force_solid = -1;
-      elseif (strncmp (arg, "-portrait", numel (arg)))
+      elseif (strncmp (arg, "-portrait", length (arg)))
         arg_st.orientation = "portrait";
-      elseif (strncmp (arg, "-landscape", numel (arg)))
+      elseif (strncmp (arg, "-landscape", length (arg)))
         arg_st.orientation = "landscape";
       elseif (strcmp (arg, "-loose"))
         arg_st.loose = true;
@@ -122,14 +122,14 @@
         arg_st.pstoedit_binary = arg{10:end};
       elseif (strncmpi (arg, "-textalphabits=", 15))
         n = find (arg == "=");
-        if (! isempty (n) && n == numel (arg) - 1 && ismember (arg(end), "124"))
+        if (! isempty (n) && n == numel (arg) - 1 && any (arg(end) == "124"))
           arg_st.ghostscript.antialiasing_textalphabits = str2num (arg(end));
         else
           error ("print: improper syntax, or value, for TextAlphaBits");
         endif
       elseif (strncmpi (arg, "-graphicsalphabits=", 19))
         n = find (arg == "=");
-        if (! isempty (n) && n == numel (arg) - 1 && ismember (arg(end), "124"))
+        if (! isempty (n) && n == numel (arg) - 1 && any (arg(end) == "124"))
           arg_st.ghostscript.antialiasing_graphicsalphabits = str2num (arg(end));
         else
           error ("print: improper syntax, or value, for GraphicsAlphaBits");
@@ -327,6 +327,22 @@
     arg_st.ghostscript.epscrop = ! arg_st.loose;
   endif
 
+  if (arg_st.send_to_printer)
+    if (isempty (arg_st.name))
+      ## Pipe the ghostscript output 
+      arg_st.name = "-";
+    else
+      error ("print: a file name may not specified when spooling to a printer")
+    endif
+    if (! any (strcmp (arg_st.devopt, gs_device_list))
+      || ! any (strcmp (arg_st.devopt, {"pswrite", "ps2write"})))
+      ## Only postscript and supported ghostscript devices
+      error ("print: invalid format for spooling to a printer")
+    endif
+  elseif (isempty (arg_st.name))
+    error ("print: an output file name must be specified")
+  endif
+
   if (isempty (arg_st.canvas_size))
     if (isfigure (arg_st.figure))
       [arg_st.ghostscript.papersize, paperposition] = ...
@@ -579,12 +595,12 @@
     papersize(papersize=="-") = "";
     papersize = strrep (papersize, "us", "");
     switch (papersize)
-    case "a"
-      papersize = "letter";
-    case {"b", "tabloid"}
-      papersize = "11x17";
-    case {"c", "d", "e"}
-      papersize = strcat ("arch", papersize);
+      case "a"
+        papersize = "letter";
+      case {"b", "tabloid"}
+        papersize = "11x17";
+      case {"c", "d", "e"}
+        papersize = strcat ("arch", papersize);
     endswitch
     if (strncmp (papersize, "arch", 4))
       papersize(end) = upper (papersize(end));
@@ -594,7 +610,7 @@
 endfunction
 
 function value = convert2points (value, units)
-    switch (units)
+  switch (units)
     case "inches"
       value = value * 72;
     case "centimeters"
@@ -602,7 +618,7 @@
     case "normalized"
       error ("print:customnormalized",
              "print.m: papersize=='<custom>' and paperunits='normalized' may not be combined");
-    endswitch
+  endswitch
 endfunction
 
 function device_list = gs_device_list ();
--- a/scripts/plot/private/__quiver__.m
+++ b/scripts/plot/private/__quiver__.m
@@ -81,14 +81,14 @@
   args = {};
   while (ioff <= nargin)
     arg = varargin{ioff++};
-    if (ischar (arg) && strncmpi (arg, "filled", 6))
+    if (ischar (arg) && strcmpi (arg, "filled"))
       have_filled = true;
     elseif ((ischar (arg) || iscell (arg))
             && ! have_line_spec)
       [linespec, valid] = __pltopt__ ("quiver", arg, false);
       if (valid)
         have_line_spec = true;
-        if (strncmp (linespec.linestyle, "none", 4))
+        if (strcmp (linespec.linestyle, "none"))
           linespec.linestyle = "-";
         endif
       else
@@ -228,7 +228,7 @@
 
     if (have_line_spec)
       if (isfield (linespec, "marker")
-          && ! strncmp (linespec.marker, "none", 4))
+          && ! strcmp (linespec.marker, "none"))
         if (is3d)
           h2 = plot3 ([xarrw1.'; xend.'; xarrw2.'; NaN(1, length (x))](:),
                       [yarrw1.'; yend.'; yarrw2.'; NaN(1, length (y))](:),
@@ -266,7 +266,7 @@
 
     if (! have_line_spec
         || (isfield (linespec, "marker")
-            && strncmp (linespec.marker, "none", 4)))
+            && strcmp (linespec.marker, "none")))
       if (is3d)
         h3 = plot3 (x, y, z, "linestyle", "none", "marker", "none",
                     "parent", hg);
@@ -442,3 +442,4 @@
        "markerfacecolor", get (h, "markerfacecolor"),
        "markersize", get (h, "markersize"));
 endfunction
+
--- a/scripts/plot/private/__scatter__.m
+++ b/scripts/plot/private/__scatter__.m
@@ -23,37 +23,21 @@
 
 function hg = __scatter__ (varargin)
 
-  h = varargin{1};
-  nd = varargin{2};
+  hax = varargin{1};  # We don't do anything with this.  Could remove it.
+  nd  = varargin{2};
   fcn = varargin{3};
-  x = varargin{4}(:);
-  y = varargin{5}(:);
-  istart = 6;
+  x   = varargin{4}(:);
+  y   = varargin{5}(:);
 
-  if (nd == 3)
+  if (nd == 2)
+    istart = 6;
+  else
     z = varargin{6}(:);
-    idx = isnan (x) | isnan (y) | isnan (z);
-    x (idx) = [];
-    y (idx) = [];
-    z (idx) = [];
     istart = 7;
-  else
-    idx = isnan (x) | isnan (y);
-    x (idx) = [];
-    y (idx) = [];
-    z = zeros (length (x), 0);
   endif
 
-  firstnonnumeric = Inf;
-  for i = istart:nargin
-    if (! isnumeric (varargin{i}))
-      firstnonnumeric = i;
-      break;
-    endif
-  endfor
-
   if (istart <= nargin)
-    s = varargin{istart};
+    s = varargin{istart}(:);
     if (isempty (s) || ischar (s))
       s = 6;
     endif
@@ -64,15 +48,36 @@
     s = 6;
   endif
 
+  ## Remove NaNs
+  idx = isnan (x) | isnan (y) | isnan (s);
+  if (nd == 3)
+    idx |= isnan (z);
+    z(idx) = [];
+  endif
+  x(idx) = [];
+  y(idx) = [];
+  if (nd == 2)
+    z = zeros (length (x), 0);
+  endif
+  if (numel (s) > 1)
+    s(idx) = [];
+  endif
+
+  firstnonnumeric = find (! cellfun ("isnumeric", varargin(istart:nargin)), 1);
+  if (isempty (firstnonnumeric))
+    firstnonnumeric = Inf;
+  else
+    firstnonnumeric += istart - 1;
+  endif
+
   if (istart <= nargin && firstnonnumeric > istart)
     c = varargin{istart};
-    if (isvector (c))
-      if (columns (c) != 3)
-        c = c(:);
-      endif
+    if (isvector (c) && columns (c) != 3)
+      c = c(:);
     endif
   elseif (firstnonnumeric == istart && ischar (varargin{istart})
-          && ! strcmpi (varargin{istart}, "filled"))
+          && ! (   strcmpi (varargin{istart}, "filled")
+                || strcmpi (varargin{istart}, "fill")))
     c = varargin{istart};
     firstnonnumeric++;
   else
@@ -86,18 +91,18 @@
   iarg = firstnonnumeric;
   while (iarg <= nargin)
     arg = varargin{iarg++};
-    if (ischar (arg) && strncmpi (arg, "filled", 6))
+    if (ischar (arg) && (strcmpi (arg, "filled") || strcmpi (arg, "fill")))
       filled = true;
     elseif ((ischar (arg) || iscell (arg)) && ! have_marker)
       [linespec, valid] = __pltopt__ (fcn, arg, false);
       if (valid)
         have_marker = true;
         marker = linespec.marker;
-        if (strncmp (marker, "none", 4))
+        if (strcmp (marker, "none"))
           marker = "o";
         elseif (isempty (marker))
           have_marker = false;
-          [dummy, marker] = __next_line_style__ ();
+          [~, marker] = __next_line_style__ ();
         endif
       else
         error ("%s: invalid linespec", fcn);
@@ -114,15 +119,17 @@
     c = __next_line_color__ ();
   endif
 
+  ## Must occur after __next_line_color__ in order to work correctly.
   hg = hggroup ();
   newargs = __add_datasource__ (fcn, hg, {"x", "y", "z", "c", "size"},
-                             newargs{:});
+                                newargs{:});
 
   addproperty ("xdata", hg, "data", x);
   addproperty ("ydata", hg, "data", y);
   addproperty ("zdata", hg, "data", z);
   if (ischar (c))
-    addproperty ("cdata", hg, "data", __color_str_rgb__ (c));
+    ## For single explicit color, cdata is unused
+    addproperty ("cdata", hg, "data", []);
   else
     addproperty ("cdata", hg, "data", c);
   endif
@@ -146,45 +153,44 @@
     if (one_explicit_color)
       for i = 1 : numel (x)
         if (filled)
-          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                            "faces", 1, "vertices", [x(i), y(i), z(i,:)],
-                            "facecolor", "none", "edgecolor", "none",
-                            "marker", marker,  "markersize", s(i),
-                            "markeredgecolor", c, "markerfacecolor", c,
-                            "linestyle", "none");
+          __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                        "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                        "facecolor", "none", "edgecolor", "none",
+                        "marker", marker,  "markersize", s(i),
+                        "markeredgecolor", c, "markerfacecolor", c,
+                        "linestyle", "none");
         else
-          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                            "faces", 1, "vertices", [x(i), y(i), z(i,:)],
-                            "facecolor", "none", "edgecolor", "none",
-                            "marker", marker,  "markersize", s(i),
-                            "markeredgecolor", c, "markerfacecolor", "none",
-                            "linestyle", "none");
+          __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                        "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                        "facecolor", "none", "edgecolor", "none",
+                        "marker", marker,  "markersize", s(i),
+                        "markeredgecolor", c, "markerfacecolor", "none",
+                        "linestyle", "none");
         endif
       endfor
     else
       if (rows (c) == 1)
-        c = ones (rows (x), 1) * c;
+        c = repmat (c, rows (x), 1);
       endif
       for i = 1 : numel (x)
         if (filled)
-          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                            "faces", 1, "vertices", [x(i), y(i), z(i,:)],
-                            "facecolor", "none", "edgecolor", "none",
-                            "marker", marker, "markersize", s(i),
-                            "markeredgecolor", "none",
-                            "markerfacecolor", "flat",
-                            "cdata", c(i,:), "facevertexcdata", c(i,:),
-                            "linestyle", "none");
+          __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                        "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                        "facecolor", "none", "edgecolor", "none",
+                        "marker", marker, "markersize", s(i),
+                        "markeredgecolor", "none",
+                        "markerfacecolor", "flat",
+                        "cdata", c(i,:), "facevertexcdata", c(i,:),
+                        "linestyle", "none");
         else
-          h = __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
-                            "faces", 1, "vertices", [x(i), y(i), z(i,:)],
-                            "facecolor", "none", "edgecolor", "none",
-                            "marker", marker, "markersize", s(i),
-                            "markeredgecolor", "flat",
-                            "markerfacecolor", "none",
-                            "cdata", c(i,:), "facevertexcdata", c(i,:),
-                            "linestyle", "none");
-
+          __go_patch__ (hg, "xdata", x(i), "ydata", y(i), "zdata", z(i,:),
+                        "faces", 1, "vertices", [x(i), y(i), z(i,:)],
+                        "facecolor", "none", "edgecolor", "none",
+                        "marker", marker, "markersize", s(i),
+                        "markeredgecolor", "flat",
+                        "markerfacecolor", "none",
+                        "cdata", c(i,:), "facevertexcdata", c(i,:),
+                        "linestyle", "none");
         endif
       endfor
     endif
@@ -195,23 +201,23 @@
 
     vert = [x, y, z];
     if (one_explicit_color)
-      h = render_size_color (hg, vert, s, c, marker, filled, true);
+      render_size_color (hg, vert, s, c, marker, filled, true);
     else
       if (rows (c) == 1)
-        c = ones (rows (x), 1) * c;
+        c = repmat (c, rows (x), 1);
       endif
-      ## We want to group points by colour. So first get all the unique colours
+      ## We want to group points by color.  So first get all the unique colors
       [cc, ~, c_to_cc] = unique (c, "rows");
 
-      for i = 1:rows (cc)
-        ## Now for each possible unique colour, get the logical index of
-        ## points that correspond to that colour
+      for i = 1 : rows (cc)
+        ## Now for each possible unique color, get the logical index of
+        ## points that correspond to that color
         idx = (i == c_to_cc);
         if (isscalar (s))
-          h = render_size_color (hg, vert(idx, :), s, c(idx,:),
+          render_size_color (hg, vert(idx, :), s, c(idx,:),
                                  marker, filled, true);
         else
-          h = render_size_color (hg, vert(idx, :), s(idx), c(idx,:),
+          render_size_color (hg, vert(idx, :), s(idx), c(idx,:),
                                  marker, filled, true);
         endif
       endfor
@@ -259,20 +265,20 @@
 
 endfunction
 
-function h = render_size_color (hg, vert, s, c, marker, filled, isflat)
+function render_size_color (hg, vert, s, c, marker, filled, isflat)
   if (isscalar (s))
     x = vert(:,1);
     y = vert(:,2);
     z = vert(:,3:end);
     toolkit = get (ancestor (hg, "figure"), "__graphics_toolkit__");
     ## Does gnuplot only support triangles with different vertex colors ?
-    ## TODO - Verify gnuplot can only support one color. If RGB triplets
-    ##        can be assigned to each vertex, then fix __go_draw_axe__.m
+    ## TODO: Verify gnuplot can only support one color.  If RGB triplets
+    ##       can be assigned to each vertex, then fix __go_draw_axes__.m
     gnuplot_hack = (numel (x) > 1 && columns (c) == 3
                     && strcmp (toolkit, "gnuplot"));
     if (ischar (c) || ! isflat || gnuplot_hack)
       if (filled)
-        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+        __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
                           "faces", 1:numel (x), "vertices", vert,
                           "facecolor", "none", "edgecolor", "none",
                           "marker", marker,
@@ -280,7 +286,7 @@
                           "markerfacecolor", c(1,:),
                           "markersize", s, "linestyle", "none");
       else
-        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+        __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
                           "faces", 1:numel (x), "vertices", vert,
                           "facecolor", "none", "edgecolor", "none",
                           "marker", marker,
@@ -290,7 +296,7 @@
       endif
     else
       if (filled)
-        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+        __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
                           "faces", 1:numel (x), "vertices", vert,
                           "facecolor", "none", "edgecolor", "none",
                           "marker", marker, "markersize", s,
@@ -299,7 +305,7 @@
                           "cdata", c, "facevertexcdata", c,
                           "linestyle", "none");
       else
-        h = __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
+        __go_patch__ (hg, "xdata", x, "ydata", y, "zdata", z,
                           "faces", 1:numel (x), "vertices", vert,
                           "facecolor", "none", "edgecolor", "none",
                           "marker", marker, "markersize", s,
@@ -310,11 +316,11 @@
       endif
     endif
   else
-    ## FIXME: round the size to one decimal place. It's not quite right, though.
+    ## Round size to one decimal place.
     [ss, ~, s_to_ss] = unique (ceil (s*10) / 10);
     for i = 1:rows (ss)
       idx = (i == s_to_ss);
-      h = render_size_color (hg, vert(idx,:), ss(i), c,
+      render_size_color (hg, vert(idx,:), ss(i), c,
                              marker, filled, isflat);
     endfor
   endif
@@ -322,57 +328,44 @@
 
 function update_props (h, d)
   lw = get (h, "linewidth");
-  m = get (h, "marker");
+  m  = get (h, "marker");
   fc = get (h, "markerfacecolor");
   ec = get (h, "markeredgecolor");
   kids = get (h, "children");
 
-  for i = 1 : numel (kids)
-    set (kids (i), "linewidth", lw, "marker", m, "markerfacecolor", fc,
-         "edgecolor", ec);
-  endfor
+  set (kids, "linewidth", lw, "marker", m,
+             "markerfacecolor", fc, "markeredgecolor", ec);
 endfunction
 
 function update_data (h, d)
-  x1 = get (h, "xdata");
-  y1 = get (h, "ydata");
-  z1 = get (h, "zdata");
-  c1 = get (h, "cdata");
-  if (!ischar (c1) && rows (c1) == 1)
-    c1 = repmat (c1, numel (x1), 1);
+  x = get (h, "xdata");
+  y = get (h, "ydata");
+  z = get (h, "zdata");
+  c = get (h, "cdata");
+  if (rows (c) == 1)
+    c = repmat (c, numel (x), 1);
   endif
-  size1 = get (h, "sizedata");
-  if (numel (size1) == 1)
-    size1 = repmat (size1, numel (x1), 1);
+  s = get (h, "sizedata");
+  if (numel (s) == 1)
+    s = repmat (s, numel (x), 1);
   endif
   hlist = get (h, "children");
-  if (ischar (c1))
-    if (isempty (z1))
-      for i = 1 : length (hlist)
-        set (hlist(i), "vertices", [x1(i), y1(i)], "cdata", c1,
-             "markersize", size1(i));
-      endfor
-    else
-      for i = 1 : length (hlist)
-        set (hlist(i), "vertices", [x1(i), y1(i), z1(i)], "cdata", c1,
-             "markersize", size1(i));
-      endfor
-    endif
+
+  if (isempty (z))
+    for i = 1 : length (hlist)
+      set (hlist(i), "vertices", [x(i), y(i)],
+                     "cdata", reshape (c(i,:),[1, size(c)(2:end)]),
+                     "facevertexcdata", c(i,:),
+                     "markersize", s(i));
+    endfor
   else
-    if (isempty (z1))
-      for i = 1 : length (hlist)
-        set (hlist(i), "vertices", [x1(i), y1(i)], "cdata",
-             reshape (c1(i,:),[1, size(c1)(2:end)]),
-             "facevertexcdata", c1(i,:),
-             "markersize", size1(i));
-      endfor
-    else
-      for i = 1 : length (hlist)
-        set (hlist(i), "vertices", [x1(i), y1(i), z1(i)], "cdata",
-             reshape (c1(i,:),[1, size(c1)(2:end)]),
-             "facevertexcdata", c1(i,:),
-             "markersize", size1(i));
-      endfor
-    endif
+    for i = 1 : length (hlist)
+      set (hlist(i), "vertices", [x(i), y(i), z(i)],
+                     "cdata", reshape (cd(i,:),[1, size(cd)(2:end)]),
+                     "facevertexcdata", cd(i,:),
+                     "markersize", s(i));
+    endfor
   endif
+
 endfunction
+
--- a/scripts/plot/private/__stem__.m
+++ b/scripts/plot/private/__stem__.m
@@ -35,9 +35,12 @@
   [hax, varargin, nargin] = __plt_get_axis_arg__ (caller, varargin{:});
 
   [x, y, z, dofill, llc, ls, mmc, ms, varargin] = ...
-      check_stem_arg (have_z, varargin{:});
+                                           check_stem_arg (have_z, varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     hold_state = get (hax, "nextplot");
@@ -60,10 +63,6 @@
         yt = [zeros(1, nx); yt; NaN(1, nx)](:);
       endif
 
-      hg = hggroup ();
-      h = [h; hg];
-      args = __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:});
-
       if (isempty (llc))
         lc = __next_line_color__ ();
       else
@@ -82,32 +81,34 @@
         fc = "none";
       endif
 
+      ## Must occur after __next_line_color__ in order to work correctly.
+      hg = hggroup ();
+      h = [h; hg];
+      args = __add_datasource__ (caller, hg, {"x", "y", "z"}, varargin{:});
+
       if (have_z)
-        h_stems = plot3 (hax, xt, yt, zt, "color", lc, "linestyle", ls,
-                         "parent", hg, x, y, z, "color", mc,
-                         "marker", ms, "linestyle", "none",
-                         "markerfacecolor", fc, "parent", hg);
-
+        __line__ (hax, xt, yt, zt, "color", lc, "linestyle", ls, "parent", hg);
+        __line__ (hax, x, y, z, "color", mc, "linestyle", "none",
+                       "marker", ms, "markerfacecolor", fc, "parent", hg);
         h_baseline = [];
       else
-        h_stems = plot (hax, xt, yt, "color", lc, "linestyle", ls,
-                        "parent", hg, x(:,i), y(:, i), "color", mc, "marker",
-                        ms, "linestyle", "none", "markerfacecolor",
-                        fc, "parent", hg);
-
+        __line__ (hax, xt, yt, "color", lc, "linestyle", ls, "parent", hg);
+        __line__ (hax, x(:,i), y(:, i), "color", mc, "linestyle", "none",
+                       "marker", ms, "markerfacecolor", fc, "parent", hg);
         x_axis_range = get (hax, "xlim");
         h_baseline = line (hax, x_axis_range, [0, 0], "color", [0, 0, 0]);
-        set (h_baseline, "handlevisibility", "off");
-        set (h_baseline, "xliminclude", "off");
+        set (h_baseline, "handlevisibility", "off", "xliminclude", "off");
         addlistener (hax, "xlim", @update_xlim);
-        addlistener (h_baseline, "ydata", @update_baseline);
-        addlistener (h_baseline, "visible", @update_baseline);
+        addproperty ("basevalue", h_baseline, "data", 0);
+        addlistener (h_baseline, "basevalue", {@update_baseline, 0});
+        addlistener (h_baseline, "ydata", {@update_baseline, 1});
+        addlistener (h_baseline, "visible", {@update_baseline, 2});
       endif
 
       ## Setup the hggroup and listeners.
       addproperty ("showbaseline", hg, "radio", "{on}|off");
+      addproperty ("baseline", hg, "data", h_baseline);
       addproperty ("basevalue", hg, "data", 0);
-      addproperty ("baseline", hg, "data", h_baseline);
 
       if (! have_z)
         addlistener (hg, "showbaseline", @show_baseline);
@@ -115,16 +116,18 @@
       endif
 
       addproperty ("color", hg, "linecolor", lc);
+      addproperty ("linestyle", hg, "linelinestyle", ls);
       addproperty ("linewidth", hg, "linelinewidth", 0.5);
-      addproperty ("linestyle", hg, "linelinestyle", ls);
       addproperty ("marker", hg, "linemarker", ms);
+      addproperty ("markeredgecolor", hg, "linemarkerfacecolor", mc);
       addproperty ("markerfacecolor", hg, "linemarkerfacecolor", fc);
       addproperty ("markersize", hg, "linemarkersize", 6);
 
       addlistener (hg, "color", @update_props);
+      addlistener (hg, "linestyle", @update_props);
       addlistener (hg, "linewidth", @update_props);
-      addlistener (hg, "linestyle", @update_props);
       addlistener (hg, "marker", @update_props);
+      addlistener (hg, "markeredgecolor", @update_props);
       addlistener (hg, "markerfacecolor", @update_props);
       addlistener (hg, "markersize", @update_props);
 
@@ -149,7 +152,8 @@
     endfor
 
     if (! strcmp (hold_state, "add") && have_z)
-      set (hax, "view", [-37.5 30]);  # 3D view
+      set (hax, "view", [-37.5 30],
+                "xgrid", "on", "ygrid", "on", "zgrid", "on");
     endif
     set (hax, "nextplot", hold_state);
 
@@ -161,315 +165,171 @@
 
 endfunction
 
-function [x, y, z, dofill, lc, ls, mc, ms, newargs] = check_stem_arg (have_z, varargin)
-
-  ## FIXME -- there seems to be a lot of duplicated code in this
-  ## function.  It seems like it should be possible to simplify things
-  ## by combining some of the nearly identical code sections into
-  ## additional subfunctions.
+function [x, y, z, dofill, lc, ls, mc, ms, args] = check_stem_arg (have_z, varargin)
 
   if (have_z)
     caller = "stem3";
   else
     caller = "stem";
   endif
+  nargin = nargin - 1;  # account for have_z argument 
 
-  ## Remove prop/val pairs from data to consider.
-  i = 2;
-  newargs = {};
-  while (i < length (varargin))
-    if (ischar (varargin{i}) && !(strcmpi ("fill", varargin{i})
-                                  || strcmpi ("filled", varargin{i})))
-      newargs{end + 1} = varargin{i};
-      newargs{end + 1} = varargin{i + 1};
-      nargin = nargin - 2;
-      varargin(i:i+1) = [];
-    else
-      i++;
-    endif
-  endwhile
+  num_numeric = find (cellfun ("isclass", varargin, "char"), 1) - 1;
+  if (isempty (num_numeric))
+    num_numeric = nargin;     
+  endif
 
-  ## set specifiers to default values.
-  [lc, ls, mc, ms] = set_default_values ();
-  dofill = 0;
-  fill_2 = 0;
-  linespec_2 = 0;
-  z = [];
+  if (num_numeric < 1 || num_numeric > 3)
+    print_usage (caller);
+  endif
 
-  ## Check input arguments.
-  if (nargin == 2)
+  x = y = z = [];
+  if (num_numeric == 1)
     if (have_z)
       z = varargin{1};
-      x = 1:rows (z);
-      y = 1:columns (z);
     else
       y = varargin{1};
+    endif
+  elseif (num_numeric == 2)
+    if (have_z)
+      error ("stem3: must define X, Y, and Z");
+    else
+      x = varargin{1};
+      y = varargin{2};
+    endif
+  else  # nun_numeric == 3
+    if (have_z)
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+    else
+      error ("stem: can not define Z for 2-D stem plot");
+    endif
+  endif
+
+  ## Validate numeric data
+  if (have_z)
+    if (isempty (x))
+      [nr, nc] = size (z);
+      if (nr >= nc)
+        x = repmat ([1:nc], nr, 1);
+        y = repmat ([1:nr]', 1, nc);
+      else
+        x = repmat ([1:nc], nr, 1);
+        y = repmat ([1:nr]', 1, nc);
+      endif
+    endif
+    if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
+      error ("stem3: X, Y, and Z must be numeric");
+    endif
+  else
+    if (isempty (x))
       if (isvector (y))
         x = 1:length (y);
       elseif (ismatrix (y))
         x = 1:rows (y);
-      else
-        error ("stem: Y must be a matrix");
-      endif # in each case, x & y will be defined
-    endif
-  elseif (nargin == 3)
-    ## Several possibilities
-    ##
-    ## 1. the real y data
-    ## 2. 'filled'
-    ## 3. line spec
-    if (ischar (varargin{2}))
-      ## Only 2. or 3. possible.
-      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
-        dofill = 1;
-      else
-        ## Parse the linespec.
-        [lc, ls, mc, ms] = stem_line_spec (caller, varargin{2});
-      endif
-      if (have_z)
-        z = varargin{1};
-        x = 1:rows (z);
-        y = 1:columns (z);
-      else
-        y = varargin{1};
-        if (isvector (y))
-          x = 1:length (y);
-        elseif (ismatrix (y))
-          x = 1:rows (y);
-        else
-          error ("stem: Y must be a matrix");
-        endif # in each case, x & y will be defined
-      endif
-    else
-      if (have_z)
-        error ("stem3: must define X, Y and Z");
-      else
-        ## Must be the real y data.
-        x = varargin{1};
-        y = varargin{2};
-        if (! (ismatrix (x) && ismatrix (y)))
-          error ("stem: X and Y must be matrices");
-        endif
       endif
     endif
-  elseif (nargin == 4)
-    ## Again, several possibilities:
-    ##
-    ## arg2 1. real y
-    ## arg2 2. 'filled' or linespec
-    ## arg3 1. real z
-    ## arg3 2. 'filled' or linespec
-    if (ischar (varargin{2}))
-      ## Only arg2 2. / arg3 1. & arg3 3. are possible.
-      if (strcmpi ("fill", varargin{2}) || strcmpi ("filled", varargin{2}))
-        dofill = 1;
-        fill_2 = 1; # Be sure, no second "fill" is in the arguments.
-      else
-        ## Must be a linespec.
-        [lc, ls, mc, ms] = stem_line_spec (caller, varargin{2});
-        linespec_2 = 1;
-      endif
-      if (have_z)
-        z = varargin{1};
-        x = 1:rows (z);
-        y = 1:columns (z);
-      else
-        y = varargin{1};
-        if (isvector (y))
-          x = 1:length (y);
-        elseif (ismatrix (y))
-          x = 1:rows (y);
-        else
-          error ("stem: Y must be a matrix");
-        endif # in each case, x & y will be defined
-      endif
-    else
-      if (have_z)
-        x = varargin{1};
-        y = varargin{2};
-        z = varargin{3};
-        if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
-          error ("stem3: X, Y and Z must be matrices");
-        endif
-      else
-        ## must be the real y data.
-        x = varargin{1};
-        y = varargin{2};
-        if (! (ismatrix (x) && ismatrix (y)))
-          error ("stem: X and Y must be matrices");
-        endif
-      endif
-    endif # if ischar (varargin{2})
-    if (! have_z)
-      ## varargin{3} must be char.
-      ## Check for "fill.
-      if ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
-          && fill_2)
-        error ("stem: duplicate fill argument");
-      elseif (strcmpi ("fill", varargin{3}) && linespec_2)
-        ## Must be "fill".
-        dofill = 1;
-        fill_2 = 1;
-      elseif ((strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
-          && !linespec_2)
-        ## Must be "fill".
-        dofill = 1;
-        fill_2 = 1;
-      elseif (! linespec_2)
-        ## Must be linespec.
-        [lc, ls, mc, ms] = stem_line_spec (caller, varargin{3});
-        linespec_2 = 1;
-      endif
+    if (! (ismatrix (x) && ismatrix (y)))
+      error ("stem: X and Y must be numeric");
     endif
-  elseif (nargin == 5)
-    if (have_z)
-      x = varargin{1};
-      y = varargin{2};
-      z = varargin{3};
-      if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
-        error ("stem3: X, Y and Z must be matrices");
-      endif
-    else
-      x = varargin{1};
-      y = varargin{2};
-      if (! (ismatrix (x) && ismatrix (y)))
-        error ("stem: X and Y must be matrices");
-      endif
-    endif
-
-    if (! have_z)
-      if (strcmpi (varargin{3}, "fill") || strcmpi (varargin{3}, "filled"))
-        dofill = 1;
-        fill_2 = 1; # Be sure, no second "fill" is in the arguments.
-      else
-        ## Must be a linespec.
-        [lc, ls, mc, ms] = stem_line_spec (caller, varargin{3});
-        linespec_2 = 1;
-      endif
-    endif
-
-    ## Check for "fill".
-    if ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
-        && fill_2)
-      error ("%s: duplicate fill argument", caller);
-    elseif ((strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
-        && linespec_2)
-      ## Must be "fill".
-      dofill = 1;
-      fill_2 = 1;
-    elseif (!strcmpi (varargin{4}, "fill") && !strcmpi (varargin{4}, "filled")
-        && !linespec_2)
-      ## Must be linespec.
-      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4});
-      linespec_2 = 1;
-    endif
-  elseif (nargin == 6 && have_z)
-    x = varargin{1};
-    y = varargin{2};
-    z = varargin{3};
-    if (! (ismatrix (x) && ismatrix (y) && ismatrix (z)))
-      error ("stem3: X, Y and Z must be matrices");
-    endif
-
-    if (strcmpi (varargin{4}, "fill") || strcmpi (varargin{4}, "filled"))
-      dofill = 1;
-      fill_2 = 1; # be sure, no second "fill" is in the arguments
-    else
-      ## Must be a linespec.
-      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{4});
-      linespec_2 = 1;
-    endif
-
-    ## check for "fill" ..
-    if ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled"))
-        && fill_2)
-      error ("stem3: duplicate fill argument");
-    elseif ((strcmpi (varargin{5}, "fill") || strcmpi (varargin{5}, "filled"))
-        && linespec_2)
-      ## Must be "fill".
-      dofill = 1;
-      fill_2 = 1;
-    elseif (!strcmpi (varargin{5}, "fill") && !strcmpi (varargin{5}, "filled")
-            && !linespec_2)
-      ## Must be linespec.
-      [lc, ls, mc, ms] = stem_line_spec (caller, varargin{5});
-      linespec_2 = 1;
-    endif
-  else
-    error ("%s: incorrect number of arguments", caller);
   endif
 
   ## Check sizes of x, y and z.
   if (have_z)
-    if (!size_equal (x, y, z))
-      error ("stem3: inconsistent size of x, y and z");
-    else
-      x = x(:);
-      y = y(:);
-      z = z(:);
+    if (! size_equal (x, y, z))
+      error ("stem3: inconsistent sizes for X, Y, and Z");
     endif
+    x = x(:);
+    y = y(:);
+    z = z(:);
   else
     if (isvector (x))
       x = x(:);
       if (isvector (y))
         if (length (x) != length (y))
-          error ("stem: inconsistent size of x and y");
-        else
-          y = y(:);
+          error ("stem: inconsistent sizes for X and Y");
         endif
+        y = y(:);
       else
         if (length (x) == rows (y))
           x = repmat (x(:), 1, columns (y));
         else
-          error ("stem: inconsistent size of x and y");
+          error ("stem: inconsistent sizes for X and Y");
         endif
       endif
-    elseif (!size_equal (x, y))
-      error ("stem: inconsistent size of x and y");
+    elseif (! size_equal (x, y))
+      error ("stem: inconsistent sizes for X and Y");
     endif
   endif
 
+  dofill = false;
+  have_line_spec = false;
+  ## set specifiers to default values.
+  [lc, ls, mc, ms] = set_default_values ();
+
+  args = {};
+  ioff = num_numeric + 1;
+  while (ioff <= nargin)
+    arg = varargin{ioff++};
+    if (ischar (arg) && any (strcmpi (arg, {"fill", "filled"})))
+      dofill = true;
+    elseif ((ischar (arg) || iscell (arg)) && ! have_line_spec)
+      [linespec, valid] = __pltopt__ (caller, arg, false);
+      if (valid)
+        have_line_spec = true;
+        [lc, ls, mc, ms] = stem_line_spec (linespec);
+      else
+        args{end+1} = arg;
+        if (ioff <= nargin)
+          args{end+1} = varargin{ioff++};
+        else
+          error ('%s: No value specified for property "%s"', caller, arg);
+        endif
+      endif
+    else
+      args{end+1} = arg;
+      if (ioff <= nargin)
+        args{end+1} = varargin{ioff++};
+      else
+        error ('%s: No value specified for property "%s"', caller, arg);
+      endif
+    endif
+  endwhile
+
+endfunction
+
+function [lc, ls, mc, ms] = stem_line_spec (lspec)
+
+  [lc, ls, mc, ms] = set_default_values ();
+
+  if (! isempty (lspec.color))
+    lc = mc = lspec.color;
+  endif
+
+  if (! isempty (lspec.linestyle) && ! strcmp (lspec.linestyle, "none"))
+    ls = lspec.linestyle;
+  endif
+
+  if (! isempty (lspec.marker) && ! strcmp (lspec.marker, "none"))
+    ms = lspec.marker;
+  endif
+
 endfunction
 
-function [lc, ls, mc, ms] = stem_line_spec (caller, str)
-  if (! ischar (str))
-    error ("%s: expecting argument to be \"fill\" or a string of specifiers",
-           caller);
-  endif
-  [lc, ls, mc, ms] = set_default_values ();
-  ## Parse the line specifier string.
-  cur_props = __pltopt__ ("stem", str, false);
-  for i = 1:length (cur_props)
-    if (isfield (cur_props(i), "color") && ! isempty (cur_props(i).color)); # means line color
-      mc = lc = cur_props(i).color;
-    elseif (isfield (cur_props(i), "linestyle"))
-      ls = cur_props(i).linestyle;
-      if (isempty (ls))
-        ls = __next_line_style__ ();
-      endif
-    elseif (isfield (cur_props(i), "marker") && ! strcmpi (cur_props(i).marker, "none"))
-      ms = cur_props(i).marker;
-      if (isempty (ms))
-        [dummy, ms] = __next_line_style__ ();
-      endif
-    endif
-  endfor
-endfunction
-
 function [lc, ls, mc, ms] = set_default_values ()
-  ## set default values
   mc = [];
   lc = [];
   ls = "-";
   ms = "o";
 endfunction
 
-function update_xlim (h, d)
+function update_xlim (h, ~)
   kids = get (h, "children");
   xlim = get (h, "xlim");
 
   for i = 1 : length (kids)
-    obj = get (kids (i));
+    obj = get (kids(i));
     if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline"))
       if (any (get (obj.baseline, "xdata") != xlim))
         set (obj.baseline, "xdata", xlim);
@@ -478,37 +338,39 @@
   endfor
 endfunction
 
-function update_baseline (h, d)
+function update_baseline (h, ~, src)
   visible = get (h, "visible");
-  ydata = get (h, "ydata")(1);
+  if (src == 0)
+    basevalue = get (h, "basevalue");
+  else
+    basevalue = get (h, "ydata")(1);
+  endif
 
   kids = get (get (h, "parent"), "children");
   for i = 1 : length (kids)
-    obj = get (kids (i));
+    obj = get (kids(i));
     if (strcmp (obj.type, "hggroup") && isfield (obj, "baseline")
         && obj.baseline == h)
-      ## Only alter if changed to avoid recursion of the listener functions
-      if (! strcmpi (get (kids(i), "showbaseline"), visible))
-        set (kids (i), "showbaseline", visible);
+      ## Avoid lots of unnecessary listener updates
+      if (! strcmp (get (kids(i), "showbaseline"), visible))
+        set (kids(i), "showbaseline", visible);
       endif
-      if (! strcmpi (get (kids(i), "basevalue"), visible))
-        set (kids (i), "basevalue", ydata);
+      if (get (kids(i), "basevalue") != basevalue)
+        set (kids(i), "basevalue", basevalue);
       endif
     endif
   endfor
 endfunction
 
-function show_baseline (h, d)
+function show_baseline (h, ~)
   set (get (h, "baseline"), "visible", get (h, "showbaseline"));
 endfunction
 
-function move_baseline (h, d)
+function move_baseline (h, ~)
   b0 = get (h, "basevalue");
   bl = get (h, "baseline");
 
-  if (get (bl, "ydata") != [b0, b0])
-    set (bl, "ydata", [b0, b0]);
-  endif
+  set (bl, "ydata", [b0, b0]);
 
   kids = get (h, "children");
   yt = get (h, "ydata")(:)';
@@ -517,18 +379,18 @@
   set (kids(2), "ydata", yt);
 endfunction
 
-function update_props (h, d)
+function update_props (h, ~)
   kids = get (h, "children");
   set (kids(2), "color", get (h, "color"),
-       "linewidth", get (h, "linewidth"),
-       "linestyle", get (h, "linestyle"));
-  set (kids(1), "color", get (h, "color"),
-       "marker", get (h, "marker"),
-       "markerfacecolor", get (h, "markerfacecolor"),
-       "markersize", get (h, "markersize"));
+                "linestyle", get (h, "linestyle"),
+                "linewidth", get (h, "linewidth"));
+  set (kids(1), "color", get (h, "markeredgecolor"),
+                "marker", get (h, "marker"),
+                "markerfacecolor", get (h, "markerfacecolor"),
+                "markersize", get (h, "markersize"));
 endfunction
 
-function update_data (h, d)
+function update_data (h, ~)
   x = get (h, "xdata");
   y = get (h, "ydata");
   z = get (h, "zdata");
@@ -562,3 +424,4 @@
   set (kids(2), "xdata", xt, "ydata", yt, "zdata", zt);
   set (kids(1), "xdata", x, "ydata", y, "zdata", z);
 endfunction
+
--- a/scripts/plot/private/__tight_eps_bbox__.m
+++ b/scripts/plot/private/__tight_eps_bbox__.m
@@ -58,7 +58,7 @@
     looking_for_bbox = true;
     while (looking_for_bbox)
       current_line = fgetl (fid);
-      if (strncmpi (current_line, box_string, numel (box_string)))
+      if (strncmpi (current_line, box_string, length (box_string)))
         line_length = numel (current_line);
         num_spaces = line_length - numel (tight_bbox_line);
         if (numel (current_line) >= numel (tight_bbox_line))
--- a/scripts/plot/private/__uigetdir_fltk__.m
+++ b/scripts/plot/private/__uigetdir_fltk__.m
@@ -32,3 +32,4 @@
   dirname = __fltk_uigetfile__ ("", dialog_title, start_path, [240, 120], "dir");
 
 endfunction
+
--- a/scripts/plot/private/__uigetfile_fltk__.m
+++ b/scripts/plot/private/__uigetfile_fltk__.m
@@ -36,3 +36,4 @@
   [retval, retpath, retindex] = __fltk_uigetfile__ (filters, title, defval, position, multiselect);
 
 endfunction
+
--- a/scripts/plot/private/__uiobject_split_args__.m
+++ b/scripts/plot/private/__uiobject_split_args__.m
@@ -64,3 +64,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/private/__uiputfile_fltk__.m
+++ b/scripts/plot/private/__uiputfile_fltk__.m
@@ -36,3 +36,4 @@
   [retval, retpath, retindex] = __fltk_uigetfile__ (filters, title, defval, position, tag);
 
 endfunction
+
--- a/scripts/plot/quiver.m
+++ b/scripts/plot/quiver.m
@@ -22,7 +22,7 @@
 ## @deftypefnx {Function File} {} quiver (@dots{}, @var{s})
 ## @deftypefnx {Function File} {} quiver (@dots{}, @var{style})
 ## @deftypefnx {Function File} {} quiver (@dots{}, "filled")
-## @deftypefnx {Function File} {} quiver (@var{h}, @dots{})
+## @deftypefnx {Function File} {} quiver (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {@var{h} =} quiver (@dots{})
 ##
 ## Plot the (@var{u}, @var{v}) components of a vector field in
@@ -40,9 +40,12 @@
 ## The style to use for the plot can be defined with a line style @var{style}
 ## of the same format as the @code{plot} command.
 ## If a marker is specified then markers at the grid points of the vectors are
-## drawn rather than arrows.  If the argument "filled" is given then the
+## drawn rather than arrows.  If the argument @qcode{"filled"} is given then the
 ## markers are filled.
 ##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## The optional return value @var{h} is a graphics handle to a quiver object.
 ## A quiver object regroups the components of the quiver plot (body, arrow,
 ## and marker), and allows them to be changed together.
@@ -65,7 +68,10 @@
   if (nargin < 2)
     print_usage ();
   else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
       htmp = __quiver__ (hax, false, varargin{:});
--- a/scripts/plot/quiver3.m
+++ b/scripts/plot/quiver3.m
@@ -40,9 +40,12 @@
 ## The style to use for the plot can be defined with a line style @var{style}
 ## of the same format as the @code{plot} command.
 ## If a marker is specified then markers at the grid points of the vectors are
-## drawn rather than arrows.  If the argument "filled" is given then the
+## drawn rather than arrows.  If the argument @qcode{"filled"} is given then the
 ## markers are filled.
 ##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## The optional return value @var{h} is a graphics handle to a quiver object.
 ## A quiver object regroups the components of the quiver plot (body, arrow,
 ## and marker), and allows them to be changed together.
@@ -68,7 +71,10 @@
   if (nargin < 2)
     print_usage ();
   else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
       htmp = __quiver__ (hax, true, varargin{:});
--- a/scripts/plot/rectangle.m
+++ b/scripts/plot/rectangle.m
@@ -60,7 +60,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("rectangle", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -222,15 +225,18 @@
 %! clf;
 %! axis equal;
 %! rectangle ('Position', [0.05, 0.05, 0.9, 0.9], 'Curvature', [0.5, 0.5]);
+%! title ('rectangle() with corners curved');
 
 %!demo
 %! clf;
 %! axis equal;
 %! rectangle ('Position', [0.05, 0.05, 0.9, 0.4], 'Curvature', 1.0);
+%! title ('rectangle() with sides as complete arcs');
 
 %!demo
 %! clf;
 %! axis equal;
 %! h = rectangle ('Position', [0.05, 0.05, 0.9, 0.4], 'Curvature', 1.0);
 %! set (h, 'FaceColor', [0, 1, 0]);
+%! title ('rectangle() with FaceColor = green');
 
--- a/scripts/plot/refresh.m
+++ b/scripts/plot/refresh.m
@@ -42,3 +42,4 @@
   drawnow ();
 
 endfunction
+
--- a/scripts/plot/refreshdata.m
+++ b/scripts/plot/refreshdata.m
@@ -29,10 +29,10 @@
 ## The optional second argument @var{workspace} can take the following values:
 ##
 ## @table @asis
-## @item "base"
+## @item @qcode{"base"}
 ## Evaluate the datasource properties in the base workspace.  (default).
 ##
-## @item "caller"
+## @item @qcode{"caller"}
 ## Evaluate the datasource properties in the workspace of the function
 ## that called @code{refreshdata}.
 ## @end table
@@ -62,19 +62,19 @@
     if (iscell (h))
       h = [h{:}];
     endif
-    if (!all (ishandle (h)) || !all (strcmp (get (h, "type"), "figure")))
-      error ("refreshdata: expecting a list of figure handles");
+    if (! all (isfigure (h)))
+      error ("refreshdata: H must be a list of figure handles");
     endif
-    if (nargin < 2)
+    if (nargin == 1)
       workspace = "base";
+    elseif (nargin == 2)
+      if (! ischar (workspace)
+          || ! any (strcmpi (workspace, {"base", "caller"})))
+        error ('refreshdata: WORKSPACE must be "base" or "caller"');
+      endif
+      workspace = tolower (workspace);
     else
-      if (   !ischar (workspace)
-          || !(strcmpi (workspace, "base")
-          || strcmpi (workspace, "caller")))
-        error ("refreshdata: expecting WORKSPACE to be \"base\" or ""caller\"");
-      else
-        workspace = tolower (workspace);
-      endif
+      print_usage ();
     endif
   endif
 
@@ -83,30 +83,24 @@
   props = {};
 
   for i = 1 : numel (h)
-    obj = get (h (i));
-    fldnames = fieldnames (obj);
-    m = regexpi (fieldnames (obj), '^.+datasource$', "match");
-    idx = ! cellfun ("isempty", m);
-    if (any (idx))
-      tmp = m(idx);
-      props = [props; {vertcat(tmp{:})}];
-      objs  = [objs ; h(i)];
-    endif
-  endfor
-
-  for i = 1 : length (objs)
-    for j = 1 : length (props {i})
-      expr = get (objs(i), props{i}{j});
-      if (!isempty (expr))
-        val = evalin (workspace, expr);
-        prop =  props{i}{j}(1:end-6);
-        if (! isequal (get (objs(i), prop), val))
-          set (objs(i), props{i}{j}(1:end-6), val);
-        endif
+    obj = get (h(i));
+    flds = fieldnames (obj);
+    ## regexp() is proper way to do searching, but is 3X slower.
+    ## Pretty unlikely that people are going to be adding datasource
+    ## properties that are not, in fact, datasources.
+    ## m = regexp (flds, '^.+datasource$');
+    m = strfind (flds, "datasource");
+    m = flds(!cellfun (@isempty, m));
+    for j = 1 : numel (m)
+      if (isempty (obj.(m{j})))
+        continue;  # datasource field doesn't point to anything
       endif
+      expr = obj.(m{j});       # datasource field
+      val = evalin (workspace, expr);
+      pdname = m{j}(1:end-6);  # property data name without "source"
+      set (h(i), pdname, val); 
     endfor
   endfor
-
 endfunction
 
 
@@ -115,8 +109,10 @@
 %! x = 0:0.1:10;
 %! y = sin (x);
 %! plot (x, y, 'ydatasource', 'y');
+%! title ('refreshdata() showing moving sine curve');
+%! axis manual;
 %! for i = 1 : 100
-%!   pause (0.1);
+%!   pause (0);
 %!   y = sin (x + 0.1 * i);
 %!   refreshdata (gcf, 'caller');
 %! end
--- a/scripts/plot/ribbon.m
+++ b/scripts/plot/ribbon.m
@@ -76,7 +76,10 @@
     endif
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -116,6 +119,7 @@
 %! [x, y, z] = sombrero ();
 %! [~, y] = meshgrid (x, y);
 %! ribbon (y, z);
+%! title ('ribbon() plot of sombrero()');
 
 %!FIXME: Could have some input validation tests here
 
--- a/scripts/plot/rose.m
+++ b/scripts/plot/rose.m
@@ -90,7 +90,10 @@
   r(3:4:end, :) = nn;
 
   if (nargout < 2)
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
       htmp = polar (th, r);
@@ -114,4 +117,5 @@
 %!demo
 %! clf;
 %! rose ([2*randn(1e5, 1), pi + 2*randn(1e5, 1)]);
+%! title ('rose() angular histogram plot');
 
--- a/scripts/plot/saveas.m
+++ b/scripts/plot/saveas.m
@@ -46,7 +46,7 @@
 ##
 ## All device formats specified in @code{print} may also be used.  If
 ## @var{fmt} is omitted it is extracted from the extension of @var{filename}.
-## The default format is "pdf".
+## The default format is @qcode{"pdf"}.
 ##
 ## @example
 ## @group
@@ -105,3 +105,4 @@
   print (fig, filename, prt_opt);
 
 endfunction
+
--- a/scripts/plot/scatter.m
+++ b/scripts/plot/scatter.m
@@ -28,7 +28,7 @@
 ## Draw a 2-D scatter plot.
 ##
 ## A marker is plotted at each point defined by the coordinates in the vectors
-## @var{x} and  @var{y}.
+## @var{x} and @var{y}.
 ##
 ## The size of the markers is determined by @var{s}, which can be a scalar
 ## or a vector of the same length as @var{x} and @var{y}.  If @var{s}
@@ -43,8 +43,8 @@
 ##
 ## The marker to use can be changed with the @var{style} argument, that is a
 ## string defining a marker in the same manner as the @code{plot} command.
-## If no marker is specified it defaults to 'o' or circles.
-## If the argument "filled" is given then the markers are filled.
+## If no marker is specified it defaults to @qcode{"o"} or circles.
+## If the argument @qcode{"filled"} is given then the markers are filled.
 ##
 ## Additional property/value pairs are passed directly to the underlying
 ## patch object.
@@ -74,18 +74,21 @@
 
   if (nargin < 2)
     print_usage ();
-  else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
-    unwind_protect
-      hax = newplot (hax);
-      
-      htmp = __scatter__ (hax, 2, "scatter", varargin{:});
-    unwind_protect_cleanup
+  endif
+
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
+  unwind_protect
+    hax = newplot (hax);
+    
+    htmp = __scatter__ (hax, 2, "scatter", varargin{:});
+  unwind_protect_cleanup
     if (! isempty (oldfig))
       set (0, "currentfigure", oldfig);
     endif
-    end_unwind_protect
-  endif
+  end_unwind_protect
 
   if (nargout > 0)
     retval = htmp;
@@ -99,7 +102,7 @@
 %! x = randn (100, 1);
 %! y = randn (100, 1);
 %! scatter (x, y, 'r');
-%! title ('Scatter plot with red bubbles');
+%! title ('scatter() plot with red bubbles');
 
 %!demo
 %! clf;
@@ -107,14 +110,37 @@
 %! y = randn (100, 1);
 %! c = x .* y;
 %! scatter (x, y, 20, c, 'filled');
-%! title ('Scatter with colors');
+%! title ('scatter() with colored filled bubbles');
 
 %!demo
 %! clf;
 %! x = randn (100, 1);
 %! y = randn (100, 1);
 %! scatter (x, y, [], sqrt (x.^2 + y.^2));
-%! title ('Scatter plot with bubble color determined by distance from origin');
+%! title ({'scatter() plot'; ...
+%!         'bubble color determined by distance from origin'});
+
+%!demo
+%! clf;
+%! rand_10x1_data5 = [0.777753, 0.093848, 0.183162, 0.399499, 0.337997, 0.686724, 0.073906, 0.651808, 0.869273, 0.137949];
+%! rand_10x1_data6 = [0.37460, 0.25027, 0.19510, 0.51182, 0.54704, 0.56087, 0.24853, 0.75443, 0.42712, 0.44273];
+%! x = rand_10x1_data5;
+%! y = rand_10x1_data6;
+%! s = 10 - 10*log (x.^2 + y.^2);
+%! h = scatter (x, y, [], 'r', 's');
+%! title ({'scatter() plot'; ...
+%!         'marker is square, color is red'});
+
+%!demo
+%! clf;
+%! rand_10x1_data3 = [0.42262, 0.51623, 0.65992, 0.14999, 0.68385, 0.55929, 0.52251, 0.92204, 0.19762, 0.93726];
+%! rand_10x1_data4 = [0.020207, 0.527193, 0.443472, 0.061683, 0.370277, 0.947349, 0.249591, 0.666304, 0.134247, 0.920356];
+%! x = rand_10x1_data3;
+%! y = rand_10x1_data4;
+%! s = 10 - 10*log (x.^2 + y.^2);
+%! h = scatter (x, y, [], 'r', 's', 'filled');
+%! title ({'scatter() plot'; ...
+%!         'marker is square, marker is filled, color is red'});
 
 %!demo
 %! clf;
@@ -124,29 +150,11 @@
 %! y = rand_10x1_data2;
 %! s = 10 - 10*log (x.^2 + y.^2);
 %! h = scatter (x, y, s, s, 's', 'filled');
-%! title ({'Scatter plot with filled square markers', ...
+%! title ({'scatter() plot with filled square markers', ...
 %!         'size and color of markers determined by algorithm'});
 
 %!demo
 %! clf;
-%! rand_10x1_data3 = [0.42262, 0.51623, 0.65992, 0.14999, 0.68385, 0.55929, 0.52251, 0.92204, 0.19762, 0.93726];
-%! rand_10x1_data4 = [0.020207, 0.527193, 0.443472, 0.061683, 0.370277, 0.947349, 0.249591, 0.666304, 0.134247, 0.920356];
-%! x = rand_10x1_data3;
-%! y = rand_10x1_data4;
-%! s = 10 - 10*log (x.^2 + y.^2);
-%! h = scatter (x, y, [], 'r', 's', 'filled');
-
-%!demo
-%! clf;
-%! rand_10x1_data5 = [0.777753, 0.093848, 0.183162, 0.399499, 0.337997, 0.686724, 0.073906, 0.651808, 0.869273, 0.137949];
-%! rand_10x1_data6 = [0.37460, 0.25027, 0.19510, 0.51182, 0.54704, 0.56087, 0.24853, 0.75443, 0.42712, 0.44273];
-%! x = rand_10x1_data5;
-%! y = rand_10x1_data6;
-%! s = 10 - 10*log (x.^2 + y.^2);
-%! h = scatter (x, y, [], 'r', 's');
-
-%!demo
-%! clf;
 %! k = 1;
 %! for m = [1, 3]
 %!   for n = [101, 50, 1]
--- a/scripts/plot/scatter3.m
+++ b/scripts/plot/scatter3.m
@@ -43,8 +43,8 @@
 ##
 ## The marker to use can be changed with the @var{style} argument, that is a
 ## string defining a marker in the same manner as the @code{plot} command.
-## If no marker is specified it defaults to 'o' or circles.
-## If the argument "filled" is given then the markers are filled.
+## If no marker is specified it defaults to @qcode{"o"} or circles.
+## If the argument @qcode{"filled"} is given then the markers are filled.
 ##
 ## Additional property/value pairs are passed directly to the underlying
 ## patch object.
@@ -71,26 +71,29 @@
 
   if (nargin < 2)
     print_usage ();
-  else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
-    unwind_protect
-      hax = newplot (hax);
-      
-      tmp = __scatter__ (hax, 3, "scatter3", varargin{:});
-
-      if (! ishold (hax))
-        set (hax, "view", [-37.5, 30],
-                  "xgrid", "on", "ygrid", "on", "zgrid", "on");
-      endif
-    unwind_protect_cleanup
-      if (! isempty (oldfig))
-        set (0, "currentfigure", oldfig);
-      endif
-    end_unwind_protect
   endif
 
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
+  unwind_protect
+    hax = newplot (hax);
+    
+    htmp = __scatter__ (hax, 3, "scatter3", varargin{:});
+
+    if (! ishold (hax))
+      set (hax, "view", [-37.5, 30],
+                "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    endif
+  unwind_protect_cleanup
+    if (! isempty (oldfig))
+      set (0, "currentfigure", oldfig);
+    endif
+  end_unwind_protect
+
   if (nargout > 0)
-    retval = tmp;
+    retval = htmp;
   endif
 
 endfunction
@@ -100,24 +103,27 @@
 %! clf;
 %! [x, y, z] = peaks (20);
 %! scatter3 (x(:), y(:), z(:), [], z(:));
-%! %% Default scatter3 with constant size bubbles and color determined by Z
+%! title ({'Default scatter3() plot', ...
+%!         'constant size bubbles and color determined by Z'});
 
 %!demo
 %! clf;
 %! x = rand (20,1);  y = rand (20,1);  z = rand (20,1);
 %! scatter3 (x(:), y(:), z(:), 10, z(:), 's');
-%! %% scatter3 using a square marker of size 10 and color determined by Z
+%! title ({'scatter3() plot', ...
+%!         'marker is square, size is 10, color determined by Z'});
 
 %!demo
 %! clf;
 %! x = rand (20,1);  y = rand (20,1);  z = rand (20,1);
 %! scatter3 (x(:), y(:), z(:), 20*z(:), [], 's');
-%! %% scatter3 using a square marker whose size is determined by Z
+%! title ({'scatter3() plot', ...
+%!         'marker is square, size is determined by Z'});
 
 %!demo
 %! clf;
 %! x = rand (20,1);  y = rand (20,1);  z = rand (20,1);
 %! scatter3 (x(:), y(:), z(:), 20*z(:), z(:), 's');
-%! %% scatter3 using a square marker.
-%! %% Size and color of marker are determined by Z
+%! title ({'scatter3() plot', ...
+%!         'marker is square, size and color determined by Z'});
 
--- a/scripts/plot/semilogx.m
+++ b/scripts/plot/semilogx.m
@@ -45,7 +45,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -74,6 +77,7 @@
 %! x = 1:0.01:10;
 %! y = (x .* (1 + rand (size (x)))) .^ 2;
 %! semilogx (y, x);
+%! title ({'semilogx() plot', 'X-axis is logarithmic'});
 
 %!demo
 %! clf;
--- a/scripts/plot/semilogxerr.m
+++ b/scripts/plot/semilogxerr.m
@@ -35,6 +35,10 @@
 ## with errors in the @var{y}-scale defined by @var{ey} and the plot
 ## format defined by @var{fmt}.  @xref{XREFerrorbar,,errorbar}, for available
 ## formats and additional information.
+##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## @seealso{errorbar, semilogyerr, loglogerr}
 ## @end deftypefn
 
@@ -46,7 +50,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("semilogxerr", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -77,4 +84,6 @@
 %! ey = 0.5*rand (size (y)) .* y;
 %! semilogxerr (x, y, ey, '#~x-');
 %! xlim (x([1, end]));
+%! title ({'semilogxerr(): semilogx() plot with errorbars', ...
+%!         'X-axis is logarithmic'});
 
--- a/scripts/plot/semilogy.m
+++ b/scripts/plot/semilogy.m
@@ -45,7 +45,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -74,6 +77,7 @@
 %! x = 1:0.01:10;
 %! y = (x .* (1 + rand (size (x)))) .^ 2;
 %! semilogy (x, y);
+%! title ({'semilogx() plot', 'Y-axis is logarithmic'});
 
 %!demo
 %! clf;
--- a/scripts/plot/semilogyerr.m
+++ b/scripts/plot/semilogyerr.m
@@ -35,6 +35,10 @@
 ## with errors in the @var{y}-scale defined by @var{ey} and the plot
 ## format defined by @var{fmt}.  @xref{XREFerrorbar,,errorbar}, for available
 ## formats and additional information.
+##
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
 ## @seealso{errorbar, semilogxerr, loglogerr}
 ## @end deftypefn
 
@@ -46,7 +50,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("semilogyerr", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -78,4 +85,6 @@
 %! eyl = 1.0 - 1./(1+eyu);
 %! semilogyerr (x, y, eyl.*y, eyu.*y, '~-d');
 %! xlim ([0 10]);
+%! title ({'semilogyerr(): semilogy() plot with errorbars', ...
+%!         'Y-axis is logarithmic'});
 
--- a/scripts/plot/shading.m
+++ b/scripts/plot/shading.m
@@ -24,13 +24,13 @@
 ## Valid arguments for @var{type} are
 ##
 ## @table @asis
-## @item "flat"
+## @item @qcode{"flat"}
 ## Single colored patches with invisible edges.
 ##
-## @item "faceted"
+## @item @qcode{"faceted"}
 ## Single colored patches with visible edges.
 ##
-## @item "interp"
+## @item @qcode{"interp"}
 ## Color between patch vertices are interpolated and the patch edges are
 ## invisible.
 ## @end table
--- a/scripts/plot/shg.m
+++ b/scripts/plot/shg.m
@@ -35,3 +35,4 @@
   drawnow ();
 
 endfunction
+
--- a/scripts/plot/shrinkfaces.m
+++ b/scripts/plot/shrinkfaces.m
@@ -25,17 +25,17 @@
 ##
 ## Reduce the faces area for a given patch, structure or explicit faces
 ## and points matrices by a scale factor @var{sf}.  The structure
-## @var{fv} must contain the fields 'faces' and 'vertices'.  If the
-## factor @var{sf} is omitted then a default of 0.3 is used.
+## @var{fv} must contain the fields @qcode{"faces"} and @qcode{"vertices"}. 
+## If the factor @var{sf} is omitted then a default of 0.3 is used.
 ##
 ## Given a patch handle as the first input argument and no output
 ## parameters, perform the shrinking of the patch faces in place and
 ## redraw the patch.
 ##
 ## If called with one output argument, return a structure with fields
-## 'faces', 'vertices', and 'facevertexcdata' containing the data after
-## shrinking which can then directly be used as an input argument for the
-## @command{patch} function.
+## @qcode{"faces"}, @qcode{"vertices"}, and @qcode{"facevertexcdata"}
+## containing the data after shrinking which can then directly be used as an
+## input argument for the @code{patch} function.
 ##
 ## Performing the shrinking on faces which are not convex can lead to
 ## undesired results.
--- a/scripts/plot/slice.m
+++ b/scripts/plot/slice.m
@@ -29,11 +29,11 @@
 ## Each element of the 3-dimensional array @var{v} represents a scalar value at
 ## a location given by the parameters @var{x}, @var{y}, and @var{z}.  The
 ## parameters @var{x}, @var{x}, and @var{z} are either 3-dimensional arrays of
-## the same size as the array @var{v} in the "meshgrid" format or vectors.  The
-## parameters @var{xi}, etc. respect a similar format to @var{x}, etc., and
-## they represent the points at which the array @var{vi} is interpolated using
-## interp3.  The vectors @var{sx}, @var{sy}, and @var{sz} contain points of
-## orthogonal slices of the respective axes.
+## the same size as the array @var{v} in the @qcode{"meshgrid"} format or
+## vectors.  The parameters @var{xi}, etc. respect a similar format to
+## @var{x}, etc., and they represent the points at which the array @var{vi}
+## is interpolated using interp3.  The vectors @var{sx}, @var{sy}, and
+## @var{sz} contain points of orthogonal slices of the respective axes.
 ##
 ## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be
 ## @code{x = 1:size (@var{v}, 2)}, @code{y = 1:size (@var{v}, 1)} and
@@ -42,21 +42,21 @@
 ## @var{method} is one of:
 ##
 ## @table @asis
-## @item "nearest"
+## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item "linear"
+## @item @qcode{"linear"}
 ## Linear interpolation from nearest neighbors.
 ##
-## @item "cubic"
+## @item @qcode{"cubic"}
 ## Cubic interpolation from four nearest neighbors (not implemented yet).
 ##
-## @item "spline"
+## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
 ##
-## The default method is "linear".
+## The default method is @qcode{"linear"}.
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
@@ -133,7 +133,10 @@
     error ("slice: dimensional mismatch for (XI, YI, ZI) or (SX, SY, SZ)");
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
--- a/scripts/plot/sombrero.m
+++ b/scripts/plot/sombrero.m
@@ -80,6 +80,7 @@
 %! clf;
 %! colormap ('default');
 %! sombrero ();
+%! title ('sombrero() function');
 
 ## Test input validation
 %!error sombrero (1,2,3)
--- a/scripts/plot/specular.m
+++ b/scripts/plot/specular.m
@@ -23,7 +23,7 @@
 ## vector elements @var{sx}, @var{sy}, @var{sz} using Phong's approximation.
 ##
 ## The light source location and viewer location vectors can be specified using
-## parameter @var{lv} and  @var{vv} respectively.  The location vectors can
+## parameter @var{lv} and @var{vv} respectively.  The location vectors can
 ## given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
 ## vectors [x, y, z].
 ##
@@ -91,3 +91,4 @@
   retval = retval .^ se;
 
 endfunction
+
--- a/scripts/plot/sphere.m
+++ b/scripts/plot/sphere.m
@@ -71,7 +71,10 @@
     yy = y;
     zz = z;
   else
-    oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
     unwind_protect
       hax = newplot (hax);
     
@@ -84,3 +87,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/stairs.m
+++ b/scripts/plot/stairs.m
@@ -70,24 +70,28 @@
 
   if (nargin < 1)
     print_usage ();
+  endif
+
+  if (nargout < 2)
+    oldfig = [];
+    if (! isempty (hax))
+      oldfig = get (0, "currentfigure");
+    endif
+    unwind_protect
+      hax = newplot (hax);
+      [htmp, xxs, yys] = __stairs__ (true, varargin{:});
+    unwind_protect_cleanup
+      if (! isempty (oldfig))
+        set (0, "currentfigure", oldfig);
+      endif
+    end_unwind_protect
+    if (nargout == 1)
+      xs = htmp;
+    endif
   else
-    if (nargout > 1)
-      [h, xs, ys] = __stairs__ (false, varargin{:});
-    else
-      oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
-      unwind_protect
-        hax = newplot (hax);
-        [htmp, xxs, yys] = __stairs__ (true, varargin{:});
-      unwind_protect_cleanup
-        if (! isempty (oldfig))
-          set (0, "currentfigure", oldfig);
-        endif
-      end_unwind_protect
-      if (nargout == 1)
-        xs = htmp;
-      endif
-    endif
+    [~, xs, ys] = __stairs__ (false, varargin{:});
   endif
+
 endfunction
 
 function [h, xs, ys] = __stairs__ (doplot, varargin)
@@ -95,42 +99,35 @@
   if (nargin == 2 || ischar (varargin{2}))
     y = varargin{1};
     varargin(1) = [];
-    if (ismatrix (y))
-      if (isvector (y))
-        y = y(:);
-      endif
-      x = 1:rows (y);
+    if (! ismatrix (y) || ndims (y) > 2)
+      error ("stairs: Y must be a numeric 2-D vector or matrix");
     endif
+    if (isvector (y))
+      y = y(:);
+    endif
+    x = 1:rows (y);
   else
     x = varargin{1};
     y = varargin{2};
     varargin(1:2) = [];
-  endif
-
-  if (ndims (x) > 2 || ndims (y) > 2)
-    error ("stairs: X and Y must be 2-D objects");
+    if (! ismatrix (x) || ! ismatrix (y) || ndims (x) > 2 || ndims (y) > 2)
+      error ("stairs: X and Y must be numeric 2-D vectors or matrices");
+    endif
   endif
 
   vec_x = isvector (x);
-
   if (vec_x)
     x = x(:);
   endif
 
   if (isvector (y))
     y = y(:);
+  elseif (ismatrix (y) && vec_x)
+    x = repmat (x, [1, columns(y)]);
   endif
 
-  if (ismatrix (y))
-    [nr, nc] = size (y);
-    if (vec_x)
-      x = repmat (x, [1, nc]);
-    else
-      [x_nr, x_nc] = size (x);
-      if (x_nr != nr || x_nc != nc)
-        error ("stairs: argument size mismatch");
-      endif
-    endif
+  if (! size_equal (x, y))
+    error ("stairs: X and Y sizes must match");
   endif
 
   len = 2*nr - 1;
@@ -150,9 +147,9 @@
   ys(ridx,:) = y(2:nr,:);
 
   have_line_spec = false;
-  for i = 1 : length (varargin)
+  for i = 1:2:numel (varargin)
     arg = varargin{i};
-    if ((ischar (arg) || iscell (arg)) && ! have_line_spec)
+    if (ischar (arg) || iscell (arg))
       [linespec, valid] = __pltopt__ ("stairs", arg, false);
       if (valid)
         have_line_spec = true;
@@ -167,6 +164,27 @@
     hold_state = get (gca (), "nextplot");
     unwind_protect
       for i = 1 : columns (y)
+
+        if (have_line_spec)
+          lc = linespec.color;
+          if (isempty (lc))
+            lc = __next_line_color__ ();
+          endif
+          ls = linespec.linestyle;
+          if (isempty (ls))
+            ls = "-";
+          endif
+          mk = linespec.marker;
+          if (isempty (mk))
+            mk = "none";
+          endif
+        else
+          lc = __next_line_color__ ();
+          ls = "-";
+          mk = "none";
+        endif
+
+        ## Must occur after __next_line_color__ in order to work correctly.
         hg = hggroup ();
         h = [h; hg];
         args = __add_datasource__ ("stairs", hg, {"x", "y"}, varargin{:});
@@ -177,32 +195,27 @@
         addlistener (hg, "xdata", @update_data);
         addlistener (hg, "ydata", @update_data);
 
-        if (have_line_spec)
-          htmp = line (xs(:,i).', ys(:,i).', "color", linespec.color,
-                       "parent", hg);
-        else
-          htmp = line (xs(:,i).', ys(:,i).', "color", __next_line_color__ (),
-                       "parent", hg);
-        endif
+        htmp = line (xs(:,i).', ys(:,i).', "color", lc, "linestyle", ls,
+                                           "marker", mk, "parent", hg);
 
         addproperty ("color", hg, "linecolor", get (htmp, "color"));
+        addproperty ("linestyle", hg, "linelinestyle", get (htmp, "linestyle"));
         addproperty ("linewidth", hg, "linelinewidth", get (htmp, "linewidth"));
-        addproperty ("linestyle", hg, "linelinestyle", get (htmp, "linestyle"));
 
         addproperty ("marker", hg, "linemarker", get (htmp, "marker"));
+        addproperty ("markeredgecolor", hg, "linemarkeredgecolor",
+                     get (htmp, "markeredgecolor"));
         addproperty ("markerfacecolor", hg, "linemarkerfacecolor",
                      get (htmp, "markerfacecolor"));
-        addproperty ("markeredgecolor", hg, "linemarkeredgecolor",
-                     get (htmp, "markeredgecolor"));
         addproperty ("markersize", hg, "linemarkersize",
                      get (htmp, "markersize"));
 
         addlistener (hg, "color", @update_props);
+        addlistener (hg, "linestyle", @update_props);
         addlistener (hg, "linewidth", @update_props);
-        addlistener (hg, "linestyle", @update_props);
         addlistener (hg, "marker", @update_props);
+        addlistener (hg, "markeredgecolor", @update_props);
         addlistener (hg, "markerfacecolor", @update_props);
-        addlistener (hg, "markeredgecolor", @update_props);
         addlistener (hg, "markersize", @update_props);
 
         if (! isempty (args))
@@ -218,57 +231,18 @@
 
 endfunction
 
-
-%!demo
-%! clf;
-%! x = 1:10;
-%! rand_1x10_data1 = [0.073, 0.455, 0.837, 0.124, 0.426, 0.781, 0.004, 0.024, 0.519, 0.698];
-%! y = rand_1x10_data1;
-%! stairs (x, y);
-
-%!demo
-%! clf;
-%! x = 1:10;
-%! rand_1x10_data2 = [0.014, 0.460, 0.622, 0.394, 0.531, 0.378, 0.466, 0.788, 0.342, 0.893];
-%! y = rand_1x10_data2;
-%! [xs, ys] = stairs (x, y);
-%! plot (xs, ys);
-
-%!demo
-%! clf;
-%! stairs (1:9);
-
-%!demo
-%! clf;
-%! [xs, ys] = stairs (9:-1:1);
-%! plot (xs, ys);
-
-%!demo
-%! clf;
-%! N = 11;
-%! x = 0:(N-1);
-%! y = rand (1, N);
-%! hs = stairs (x(1), y(1));
-%! axis ([1, N-1 0, 1]);
-%! for k=2:N
-%!   set (hs, 'xdata', x(1:k), 'ydata', y(1:k));
-%!   drawnow ();
-%!   pause (0.2);
-%! end
-
-
-function update_props (h, d)
+function update_props (h, ~)
   set (get (h, "children"),
        "color", get (h, "color"),
+       "linestyle", get (h, "linestyle"),
        "linewidth", get (h, "linewidth"),
-       "linestyle", get (h, "linestyle"),
        "marker", get (h, "marker"),
+       "markeredgecolor", get (h, "markeredgecolor"),
        "markerfacecolor", get (h, "markerfacecolor"),
-       "markeredgecolor", get (h, "markeredgecolor"),
        "markersize", get (h, "markersize"));
 endfunction
 
-function update_data (h, d)
+function update_data (h, ~)
   x = get (h, "xdata");
   y = get (h, "ydata");
 
@@ -295,3 +269,62 @@
   set (get (h, "children"), "xdata", xs, "ydata", ys);
 endfunction
 
+
+%!demo
+%! clf;
+%! rand_1x10_data1 = [0.073, 0.455, 0.837, 0.124, 0.426, 0.781, 0.004, 0.024, 0.519, 0.698];
+%! y = rand_1x10_data1;
+%! stairs (y);
+%! title ('stairs() plot of y-data');
+
+%!demo
+%! clf;
+%! x = 1:10;
+%! rand_1x10_data2 = [0.014, 0.460, 0.622, 0.394, 0.531, 0.378, 0.466, 0.788, 0.342, 0.893];
+%! y = rand_1x10_data2;
+%! [xs, ys] = stairs (x, y);
+%! plot (xs, ys);
+%! title ('plot() of stairs() generated data');
+
+%!demo
+%! clf;
+%! stairs (1:9, '-o');
+%! title ('stairs() plot with linespec to modify marker');
+
+%!demo
+%! clf;
+%! stairs (9:-1:1, 'marker', 's', 'markersize', 10, 'markerfacecolor', 'm');
+%! title ('stairs() plot with prop/val pairs to modify appearance');
+
+%!demo
+%! clf;
+%! N = 11;
+%! x = 0:(N-1);
+%! y = rand (1, N);
+%! hs = stairs (x(1), y(1));
+%! axis ([1, N-1 0, 1]);
+%! title ('stairs plot data modified through handle');
+%! for k = 2:N
+%!   set (hs, 'xdata', x(1:k), 'ydata', y(1:k));
+%!   drawnow ();
+%!   pause (0.2);
+%! end
+
+## Invisible figure used for tests
+%!shared hf, hax
+%! hf = figure ("visible", "off");
+%! hax = axes;
+
+%!error stairs ()
+%!error <Y must be a numeric 2-D vector> stairs (hax, {1})
+%!error <Y must be a numeric 2-D vector> stairs (ones (2,2,2))
+%!error <X and Y must be numeric 2-D vector> stairs ({1}, 1)
+%!error <X and Y must be numeric 2-D vector> stairs (1, {1})
+%!error <X and Y must be numeric 2-D vector> stairs (ones (2,2,2), 1)
+%!error <X and Y must be numeric 2-D vector> stairs (1, ones (2,2,2))
+%!error <X and Y sizes must match> stairs (1:2, 1:3)
+
+## Close figure used for testing
+%!test
+%! close (hf);
+
--- a/scripts/plot/stem.m
+++ b/scripts/plot/stem.m
@@ -34,11 +34,11 @@
 ## the same length as the number of rows in @var{y}, or it can be a
 ## matrix of the same size as @var{y}.
 ##
-## The default color is @code{"b"} (blue), the default line style is
-## @code{"-"}, and the default marker is @code{"o"}.  The line style can
+## The default color is @qcode{"b"} (blue), the default line style is
+## @qcode{"-"}, and the default marker is @qcode{"o"}.  The line style can
 ## be altered by the @code{linespec} argument in the same manner as the
-## @code{plot} command.  If the "filled" argument is present the markers at
-## the top of the stems will be filled in.  For example,
+## @code{plot} command.  If the @qcode{"filled"} argument is present the
+## markers at the top of the stems will be filled in.  For example,
 ##
 ## @example
 ## @group
@@ -57,11 +57,13 @@
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
 ##
-## The optional return value @var{h} is a vector of "stem series" graphics
-## handles with one handle per column of the variable @var{y}.  The
-## handle regroups the elements of the stem graph together as the
-## children of the "stem series" handle, allowing them to be altered
-## together.  For example,
+## The optional return value @var{h} is a handle to a "stem series" hggroup.
+## The single hggroup handle has all of the graphical elements comprising the
+## plot as its children; This allows the properties of multiple graphics
+## objects to be changed by modifying just a single property of the
+## "stem series" hggroup.
+##
+## For example,
 ##
 ## @example
 ## @group
@@ -76,6 +78,40 @@
 ## @noindent
 ## changes the color of the second "stem series" and moves the base line
 ## of the first.
+##
+## Stem Series Properties
+##
+## @table @asis
+## @item linestyle
+## The linestyle of the stem.  (Default: @qcode{"-"})
+##
+## @item linewidth
+## The width of the stem.  (Default: 0.5)
+##
+## @item color
+## The color of the stem, and if not separately specified, the marker.
+## (Default: "b" [blue])
+##
+## @item marker
+## The marker symbol to use at the top of each stem.  (Default: @qcode{"o"})
+##
+## @item markeredgecolor
+## The edge color of the marker.  (Default: @qcode{"color"} property)
+##
+## @item markerfacecolor
+## The color to use for "filling" the marker.  (Default: @qcode{"none"}
+## [unfilled])
+##
+## @item markersize
+## The size of the marker.  (Default: 6)
+##
+## @item baseline
+## The handle of the line object which implements the baseline.  Use @code{set}
+## with the returned handle to change graphic properties of the baseline.
+##
+## @item basevalue
+## The y-value where the baseline is drawn.  (Default: 0)
+## @end table
 ## @seealso{stem3, bar, hist, plot, stairs}
 ## @end deftypefn
 
@@ -99,38 +135,51 @@
 
 %!demo
 %! clf;
-%! x = 1:10;
-%! stem (x);
+%! y = 1:10;
+%! stem (y);
+%! title ('stem plot of y-values only');
 
 %!demo
 %! clf;
 %! x = 1:10;
 %! y = 2*x;
 %! stem (x, y);
+%! title ('stem plot of x and y-values');
 
 %!demo
 %! clf;
 %! x = 1:10;
 %! y = 2*x;
 %! h = stem (x, y, 'r');
+%! title ('stem plot with modified color');
 
 %!demo
 %! clf;
 %! x = 1:10;
 %! y = 2*x;
 %! h = stem (x, y, '-.k');
+%! title ('stem plot with modified line style and color');
 
 %!demo
 %! clf;
 %! x = 1:10;
 %! y = 2*x;
-%! h = stem (x, y, '-.k.');
+%! h = stem (x, y, '-.ks');
+%! title ('stem plot with modified line style, color, and marker');
 
 %!demo
 %! clf;
 %! x = 1:10;
 %! y = 2*x;
 %! h = stem (x, y, 'filled');
+%! title ('stem plot with "filled" markers');
+
+%!demo
+%! clf;
+%! x = 1:10;
+%! y = 2*x;
+%! h = stem (x, y, 'markerfacecolor', [1 0 1]);
+%! title ('stem plot modified with property/value pair');
 
 %!demo
 %! clf;
@@ -139,6 +188,7 @@
 %! h = stem (x, y);
 %! set (h(2), 'color', 'g');
 %! set (h(1), 'basevalue', -1);
+%! title ('stem plots modified through hggroup handle');
 
 %!demo
 %! clf;
@@ -147,9 +197,19 @@
 %! y = rand (1, N);
 %! hs = stem (x(1), y(1));
 %! set (gca (), 'xlim', [1, N-1], 'ylim', [0, 1]);
+%! title ('stem plot data modified through hggroup handle');
 %! for k=2:N
 %!   set (hs, 'xdata', x(1:k), 'ydata', y(1:k))
 %!   drawnow ();
 %!   pause (0.2);
 %! end
 
+%!error stem ()
+%!error <can not define Z for 2-D stem plot> stem (1,2,3)
+%!error <X and Y must be numeric> stem ({1})
+%!error <X and Y must be numeric> stem (1, {1})
+%!error <inconsistent sizes for X and Y> stem (1:2, 1:3)
+%!error <inconsistent sizes for X and Y> stem (1:2, ones (3,3))
+%!error <inconsistent sizes for X and Y> stem (ones (2,2), ones (3,3))
+%!error <No value specified for property "FOO"> stem (1, "FOO")
+
--- a/scripts/plot/stem3.m
+++ b/scripts/plot/stem3.m
@@ -26,12 +26,12 @@
 ## Plot a 3-D stem graph.
 ##
 ## Stems are drawn from the height @var{z} to the location in the x-y plane
-## determined by @var{x} and @var{y}.  The default color is @code{"b"} (blue),
-## the default line style is @code{"-"}, and the default marker is @code{"o"}.
+## determined by @var{x} and @var{y}.  The default color is @qcode{"b"} (blue),
+## the default line style is @qcode{"-"}, and the default marker is @qcode{"o"}.
 ##
 ## The line style can be altered by the @code{linespec} argument in the same
-## manner as the @code{plot} command.  If the "filled" argument is present
-## the markers at the top of the stems will be filled in.
+## manner as the @code{plot} command.  If the @qcode{"filled"} argument is
+## present the markers at the top of the stems will be filled in.
 ##
 ## Optional property/value pairs may be specified to control the appearance
 ## of the plot.
@@ -39,8 +39,9 @@
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
 ## rather than the current axes returned by @code{gca}.
 ##
-## The optional return value @var{h} is a vector with the handles of the line
-## and marker objects used to draw the stems as a "stem series" object.
+## The optional return value @var{h} is a handle to the "stem series" hggroup
+## containing the line and marker objects used for the plot.
+## @xref{XREFstem,,stem}, for a description of the "stem series" object.
 ##
 ## Example:
 ##
@@ -60,7 +61,7 @@
 
 function h = stem3 (varargin)
 
-  if (nargin < 1 || nargin > 4)
+  if (nargin < 1)
     print_usage ();
   endif
 
@@ -77,4 +78,14 @@
 %! clf;
 %! theta = 0:0.2:6;
 %! stem3 (cos (theta), sin (theta), theta);
+%! title ('stem3() plot');
 
+%!error stem3 ()
+%!error <must define X, Y, and Z> stem3 (1,2)
+%!error <X, Y, and Z must be numeric> stem3 ({1}, 1, 1)
+%!error <X, Y, and Z must be numeric> stem3 (1, {1}, 1)
+%!error <X, Y, and Z must be numeric> stem3 (1, 1, {1})
+%!error <inconsistent sizes for X, Y, and Z> stem3 (ones (2,2), 1, 1);
+%!error <inconsistent sizes for X, Y, and Z> stem3 (1, ones (2,2), 1);
+%!error <inconsistent sizes for X, Y, and Z> stem3 (1, 1, ones (2,2));
+%!error <No value specified for property "FOO"> stem3 (1, "FOO")
--- a/scripts/plot/stemleaf.m
+++ b/scripts/plot/stemleaf.m
@@ -195,7 +195,7 @@
   n_far_l   = sum (x<o_fence_l);
   n_far_h   = sum (x>o_fence_h);
 
-  # display table similar to that on pg. 33
+  ## display table similar to that on pg. 33
   plot_out = sprintf ("       Data: %s", caption);
   plot_out = [plot_out; sprintf(" ")];
   plot_out = [plot_out; sprintf("         Fenced Letter Display")];
@@ -336,12 +336,12 @@
 
 %!test
 %! ## test minus to plus
-%! x = [-22 12 -28 52  39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127  \
-%!      36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 \
-%!      23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58  \
-%!      114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31  \
-%!      115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57\
-%!      122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 \
+%! x = [-22 12 -28 52  39 -2 12 10 11 11 42 38 44 18 44 37 113 124 37 48 127   ...
+%!      36 29 31 125 139 131 115 105 132 104 123 35 113 122 42 117 119 58 109  ...
+%!      23 105 63 27 44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58   ...
+%!      114 126 53 114 96 25 109 7 31 141 46 -13 71 43 117 116 27 7 68 40 31   ...
+%!      115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 ...
+%!      122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30  ...
 %!      127 31 116 146 21 23 30 10 20 21 30 0 100 110 1 20 0];
 %! x = sort (x);
 %! rexp = char (
--- a/scripts/plot/struct2hdl.m
+++ b/scripts/plot/struct2hdl.m
@@ -20,11 +20,12 @@
 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}, @var{hilev})
 ## Construct a graphics handle object @var{h} from the structure @var{s}.
 ##
-## The structure must contain the fields "handle", "type", "children",
-## "properties", and "special".  If the handle of an existing figure or axes
-## is specified, @var{p}, the new object will be created as a child of that
-## object.  If no parent handle is provided then a new figure and the necessary
-## children will be constructed using the default values from the root figure.
+## The structure must contain the fields @qcode{"handle"}, @qcode{"type"},
+## @qcode{"children"}, @qcode{"properties"}, and @qcode{"special"}.  If the
+## handle of an existing figure or axes is specified, @var{p}, the new object
+## will be created as a child of that object.  If no parent handle is provided
+## then a new figure and the necessary children will be constructed using the
+## default values from the root figure.
 ##
 ## A third boolean argument @var{hilev} can be passed to specify whether
 ## the function should preserve listeners/callbacks, e.g., for legends or
@@ -92,7 +93,7 @@
     p = p(1:2, 1:(tst(end)-1));
   endif
 
-  ## Place the "*mode" properties as the end to avoid having the updaters
+  ## Place the "*mode" properties at the end to avoid having the updaters
   ## change the mode to "manual" when the value is "auto".
   names = fieldnames (s.properties);
   n = strncmp (cellfun (@fliplr, names, "uniformoutput", false), "edom", 4);
@@ -190,7 +191,7 @@
       plty = s.properties.__plotyy_axes__;
       addproperty ("__plotyy_axes__", h, "any");
       tmp = [p [s.handle; h]];
-      tst = arrayfun (@(x) any (plty == x), tmp(1:2:end));
+      tst = ismember (tmp(1:2:end), plty);
       if (sum (tst) == numel (plty))
         for ii = 1:numel (plty)
           plty(ii) = tmp(find (tmp == plty(ii)) + 1);
@@ -305,7 +306,7 @@
 endfunction
 
 function h = createimage (s, par)
-  h = image ("parent", par);
+  h = image (1, "parent", par);
   addmissingprops (h, s.properties);
 endfunction
 
@@ -452,7 +453,8 @@
     bargroup = s.properties.bargroup;
     oldh = s.handle;
 
-    temp = arrayfun (@(x) any(x == bargroup), [p(1:2:end) oldh]);
+    temp = ismember ([p(1:2:end) oldh], bargroup);
+
     tst = sum (temp) == length (bargroup);
 
     if (isscalar (bargroup) || !tst)
@@ -546,7 +548,11 @@
   more off;
   if (strcmpi (s.properties.tag, ""))
     specs = s.children(s.special);
-    hdls = arrayfun (@(x) x.handle, specs);
+    if (isempty (specs))
+      hdls = [];
+    else
+      hdls = [specs.handle];
+    endif
     nh = length (hdls);
     msg = "";
     if (! nh)
@@ -624,7 +630,7 @@
   hid = {"autopos_tag", "looseinset"};
   oldfields = fieldnames (props);
   curfields = fieldnames (get (h));
-  missing = cellfun (@(x) !any (strcmp (x, curfields)), oldfields);
+  missing = ! ismember (oldfields, curfields);
   idx = find (missing);
   for ii = 1:length (idx)
     prop = oldfields{idx(ii)};
@@ -636,3 +642,4 @@
 
 
 ## FIXME: Need validation tests
+
--- a/scripts/plot/subplot.m
+++ b/scripts/plot/subplot.m
@@ -19,21 +19,23 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} subplot (@var{rows}, @var{cols}, @var{index})
 ## @deftypefnx {Function File} {} subplot (@var{rcn})
+## @deftypefnx {Function File} {} subplot (@var{hax})
 ## @deftypefnx {Function File} {} subplot (@dots{}, "align")
-## @deftypefnx {Function File} {@var{hax} =} subplot (@dots{})
+## @deftypefnx {Function File} {} subplot (@dots{}, "replace")
+## @deftypefnx {Function File} {} subplot (@dots{}, "position", @var{pos})
+## @deftypefnx {Function File} {} subplot (@dots{}, @var{prop}, @var{val}, @dots{})
 ## @deftypefnx {Function File} {@var{hax} =} subplot (@dots{})
 ## Set up a plot grid with @var{rows} by @var{cols} subwindows and set the
-## current axes for plotting to the location given by @var{index}.
+## current axes for plotting (@code{gca}) to the location given by @var{index}.
 ##
 ## If only one numeric argument is supplied, then it must be a three digit
-## value specifying the location in digits 1 (rows) and 2 (columns) and the
-## plot index in digit 3.
+## value specifying the the number of rows in in digit 1, the number of
+## columns in digit 2, and the plot index in digit 3.
 ##
-## The plot index runs row-wise.  First all the columns in a row are numbered
+## The plot index runs row-wise; First, all columns in a row are numbered
 ## and then the next row is filled.
 ##
-## For example, a plot with 2 by 3 grid will have plot indices running as
-## follows:
+## For example, a plot with 2x3 grid will have plot indices running as follows:
 ## @tex
 ## \vskip 10pt
 ## \hfil\vbox{\offinterlineskip\hrule
@@ -58,18 +60,33 @@
 ## @end ifnottex
 ##
 ## @var{index} may also be a vector.  In this case, the new axis will enclose
-## the grid locations specified.  The first demo illustrates an example:
+## the grid locations specified.  The first demo illustrates this:
 ##
 ## @example
 ## demo ("subplot", 1)
 ## @end example
 ##
-## If the option "align" is given then the plot boxes of the subwindows
+## The index of the subplot to make active may also be specified by its axes
+## handle, @var{hax}, returned from a previous @code{subplot} command.
+##
+## If the option @qcode{"align"} is given then the plot boxes of the subwindows
 ## will align, but this may leave no room for axis tick marks or labels.
 ##
+## If the option @qcode{"replace"} is given then the subplot axis will be
+## reset, rather than just switching the current axis for plotting to the
+## requested subplot.
+##
+## The @qcode{"position"} property can be used to exactly position the subplot
+## axes within the current figure.  The option @var{pos} is a 4-element vector
+## [x, y, width, height] that determines the location and size of the axes.
+## The values in @var{pos} are normalized in the range [0,1].
+##
+## Any property/value pairs are passed directly to the underlying axes object.
+##
 ## If the output @var{hax} is requested, subplot returns the axis handle for
-## the subplot.  This is useful for modifying the properties of a subplot.
-## @seealso{axes, plot}
+## the subplot.  This is useful for modifying the properties of a subplot
+## using @code{set}.
+## @seealso{axes, plot, gca, set}
 ## @end deftypefn
 
 ## Author: Vinayak Dutt <Dutt.Vinayak@mayo.EDU>
@@ -82,23 +99,24 @@
   have_position = false;
   initial_args_decoded = false;
 
-  if (nargin > 2)
+  if (nargin >= 3)
     ## R, C, N?
     arg1 = varargin{1};
     arg2 = varargin{2};
     arg3 = varargin{3};
-    if (isnumeric (arg1) && isscalar (arg1) && isnumeric (arg2)
-        && isscalar (arg2) && isnumeric (arg3))
+    if (   isnumeric (arg1) && isscalar (arg1)
+        && isnumeric (arg2) && isscalar (arg2)
+        && isnumeric (arg3))
       rows = arg1;
       cols = arg2;
       index = arg3;
-      varargin(1:3)= [];
+      varargin(1:3) = [];
       initial_args_decoded = true;
     endif
   endif
 
   if (! initial_args_decoded && nargin > 1)
-    ## check for 'position', pos, ...
+    ## check for "position", pos, ...
     if (strcmpi (varargin{1}, "position"))
       arg = varargin{2};
       if (isnumeric (arg) && numel (arg) == 4)
@@ -107,15 +125,15 @@
         have_position = true;
         initial_args_decoded = true;
       else
-        error ("expecting position to be a 4-element numeric array");
+        error ("subplot: POSITION must be a 4-element numeric array");
       endif
     endif
   endif
     
   if (! initial_args_decoded && nargin > 0)
     arg = varargin{1};
-    if (nargin == 1 && ishandle (arg))
-      ## Axes handle?
+    if (nargin == 1 && isaxes (arg))
+      ## Axes handle
       axes (arg);
       cf = get (0, "currentfigure");
       set (cf, "nextplot", "add");
@@ -144,34 +162,32 @@
     index = round (index);
 
     if (any (index < 1) || any (index > rows*cols))
-      error ("subplot: INDEX value must be greater than 1 and less than ROWS*COLS");
+      error ("subplot: INDEX value must be >= 1 and <= ROWS*COLS");
     endif
 
-    if (cols < 1 || rows < 1 || index < 1)
-      error ("subplot: COLS, ROWS, and INDEX must be be positive");
+    if (rows < 1 || cols < 1 || index < 1)
+      error ("subplot: ROWS, COLS, and INDEX must be be positive");
     endif
   endif
 
-  nargs = numel (varargin);
-  while (nargs > 0)
-    arg = varargin{1};
-    if (strcmpi (arg, "align"))
-      align_axes = true;
-    elseif (strcmpi (arg, "replace"))
-      replace_axes = true;
-    else
-      break;
-    endif
-    varargin(1) = [];
-    nargs--;
-  endwhile
+  ## Process "align" and "replace" options
+  idx = strcmpi (varargin, "align");
+  if (any (idx))
+    align_axes = true;
+    varargin(idx) = [];
+  endif
+
+  idx = strcmpi (varargin, "replace");
+  if (any (idx))
+    replace_axes = true;
+    varargin(idx) = [];
+  endif
 
   axesunits = get (0, "defaultaxesunits");
   cf = gcf ();
   figureunits = get (cf, "units");
   unwind_protect
-    units = "normalized";
-    set (0, "defaultaxesunits", units);
+    set (0, "defaultaxesunits", "normalized");
     set (cf, "units", "pixels");
 
     ## FIXME: At the moment we force gnuplot to use the aligned mode
@@ -199,7 +215,7 @@
 
     found = false;
     kids = get (cf, "children");
-    for child = reshape (kids, 1, numel (kids))
+    for child = kids(:)'
       ## Check whether this child is still valid; this might not be the
       ## case anymore due to the deletion of previous children (due to
       ## "deletefcn" callback or for legends/colorbars that are deleted
@@ -209,23 +225,20 @@
       endif
       if (strcmp (get (child, "type"), "axes"))
         ## Skip legend and colorbar objects.
-        if (strcmp (get (child, "tag"), "legend")
-            || strcmp (get (child, "tag"), "colorbar"))
+        if (any (strcmp (get (child, "tag"), {"legend", "colorbar"})))
           continue;
         endif
-        if (align_axes)
-          objpos = get (child, "position");
-        else
-          objpos = get (child, "outerposition");
-        endif
-        if (all (abs (objpos - pos) < eps) && ! replace_axes)
-          ## If the new axes are in exactly the same position as an
-          ## existing axes object, use the existing axes.
+        objpos = get (child, "outerposition");
+        if (all (abs (objpos - outerpos) < eps) && ! replace_axes)
+          ## If the new axes are in exactly the same position
+          ## as an existing axes object, use the existing axes.
           found = true;
           hsubplot = child;
         else
-          ## If the new axes overlap an old axes object, delete the old
-          ## axes.
+          ## If the new axes overlap an old axes object, delete the old axes.
+          if (align_axes)
+            objpos = get (child, "position");
+          endif
           x0 = pos(1);
           x1 = x0 + pos(3);
           y0 = pos(2);
@@ -242,6 +255,7 @@
     endfor
 
     if (found)
+      ## Switch to existing subplot
       set (cf, "currentaxes", hsubplot);
     else
       hsubplot = axes ("box", "off",
@@ -277,22 +291,16 @@
     else
       pos = get (0, "defaultaxesouterposition");
     endif
-    return
+    return;
   endif
 
-  if (strcmp (position_property, "outerposition")
-      || strcmp (position_property, "outerpositiontight"))
+  if (strcmp (position_property, "outerposition"))
     margins.left   = 0.05;
     margins.bottom = 0.05;
     margins.right  = 0.05;
     margins.top    = 0.05;
-    if (strcmp (position_property, "outerpositiontight"))
-      margins.column = 0.;
-      margins.row = 0.;
-    else
-      margins.column = 0.04 / cols;
-      margins.row = 0.04 / rows;
-    endif
+    margins.column = 0.04 / cols;
+    margins.row    = 0.04 / rows;
     width = 1 - margins.left - margins.right - (cols-1)*margins.column;
     width = width / cols;
     height = 1 - margins.top - margins.bottom - (rows-1)*margins.row;
@@ -326,7 +334,7 @@
   xi = index(:) - yi*cols - 1;
   yi = (rows - 1) - yi;
 
-  ## Lower left corner of the subplot, i.e. position(1:2)
+  ## Lower left corner of the subplot, i.e., position(1:2)
   x0 = xi .* (width + margins.column) + margins.left;
   y0 = yi .* (height + margins.row) + margins.bottom;
 
@@ -345,30 +353,33 @@
 endfunction
 
 function subplot_align (h, varargin)
-  persistent updating = false
+  persistent updating = false;
+
   if (! updating)
     unwind_protect
       updating = true;
       hfig = ancestor (h, "figure");
-      hsubplots = findall (hfig, 'type', 'axes', 'subplot_align', 'off');
+      hsubplots = findall (hfig, "type", "axes", "subplot_align", "off");
       if (! isempty (hsubplots))
-        tightinset = get (hsubplots, 'tightinset');
+        tightinset = get (hsubplots, "tightinset");
         if (iscell (tightinset))
           tightinset = max (cell2mat (tightinset));
         endif
-        looseinset = get (hsubplots, 'looseinset');
+        looseinset = get (hsubplots, "looseinset");
         if (iscell (looseinset))
           looseinset = max (cell2mat (looseinset));
         endif
         looseinset = max (tightinset, looseinset);
-        set (hsubplots, 'looseinset', looseinset);
+        set (hsubplots, "looseinset", looseinset);
       endif
     unwind_protect_cleanup
       updating = false;
     end_unwind_protect
   endif
+
 endfunction
 
+
 %!demo
 %! clf;
 %! r = 3;
--- a/scripts/plot/surf.m
+++ b/scripts/plot/surf.m
@@ -32,9 +32,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The color of the surface is computed by linearly scaling the @var{Z} values
+## The color of the surface is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -62,7 +62,10 @@
 
   [hax, varargin] = __plt_get_axis_arg__ ("surf", varargin{:});
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     
@@ -91,6 +94,7 @@
 %! colormap ('default');
 %! Z = peaks ();
 %! surf (Z);
+%! title ({'surf() plot of peaks() function'; 'color determined by height Z'});
 
 %!demo
 %! clf;
@@ -99,6 +103,8 @@
 %! [Fx,Fy] = gradient (Z);
 %! surf (Z, Fx+Fy);
 %! shading interp;
+%! title ({'surf() plot of peaks() function'; ...
+%!         'facecolor is interpolated, color determined by gradient of Z'});
 
 %!demo
 %! clf;
@@ -107,4 +113,6 @@
 %! [~,Fy] = gradient (Z);
 %! surf (X, Y, Z, Fy);
 %! shading interp;
+%! title ({'surf() plot of peaks() function'; ...
+%!         'facecolor is interpolated, color determined by Y-gradient of Z'});
 
--- a/scripts/plot/surfc.m
+++ b/scripts/plot/surfc.m
@@ -32,9 +32,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The color of the surface is computed by linearly scaling the @var{Z} values
+## The color of the surface is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -64,7 +64,10 @@
     print_usage ();
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
     
@@ -73,12 +76,13 @@
     set (htmp, "facecolor", "flat");
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
-                "xgrid", "on", "ygrid", "on", "zgrid", "on");
+                "xgrid", "on", "ygrid", "on", "zgrid", "on",
+                "xlimmode", "manual", "ylimmode", "manual");
     endif
 
     drawnow ();
 
-    # don't pass string arguments to __contour__()
+    ## don't pass string arguments to __contour__()
     stop_idx = find (cellfun ("isclass", varargin, "char"), 1);
     if (isempty (stop_idx))
       stop_idx = nargin;
@@ -114,6 +118,7 @@
 %! colormap ('default');
 %! Z = peaks ();
 %! surfc (Z);
+%! title ('surfc() combines surf/contour plots');
 
 %!demo
 %! clf;
@@ -122,6 +127,8 @@
 %! [Fx,Fy] = gradient (Z);
 %! surfc (Z, Fx+Fy);
 %! shading interp;
+%! title ({'surfc() plot of sombrero() function'; ...
+%!         'facecolor is interpolated, color determined by gradient of Z'});
 
 %!demo
 %! clf;
@@ -130,4 +137,6 @@
 %! [~,Fy] = gradient (Z);
 %! surfc (X,Y,Z,Fy);
 %! shading interp;
+%! title ({'surfc() plot of peaks() function'; ...
+%!         'facecolor is interpolated, color determined by Y-gradient of Z'});
 
--- a/scripts/plot/surfl.m
+++ b/scripts/plot/surfl.m
@@ -34,11 +34,11 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The default lighting mode "cdata", changes the cdata property of the
+## The default lighting mode @qcode{"cdata"}, changes the cdata property of the
 ## surface object to give the impression of a lighted surface.
-## @strong{Warning:} The alternative mode "light" mode which creates a light
+## @strong{Warning:} The alternative mode @qcode{"light"} mode which creates a light
 ## object to illuminate the surface is not implemented (yet).
 ##
 ## The light source location can be specified using @var{L}.  It can be given
@@ -51,13 +51,13 @@
 ## @var{p} = [0.55 0.6 0.4 10].
 ##
 ## @table @asis
-## @item "AM" strength of ambient light
+## @item @qcode{"AM"} strength of ambient light
 ##
-## @item "D" strength of diffuse reflection
+## @item @qcode{"D"} strength of diffuse reflection
 ##
-## @item "SP" strength of specular reflection
+## @item @qcode{"SP"} strength of specular reflection
 ##
-## @item "EXP" specular exponent
+## @item @qcode{"EXP"} specular exponent
 ## @end table
 ##
 ## If the first argument @var{hax} is an axes handle, then plot into this axis,
@@ -136,7 +136,10 @@
     endif
   endif
 
-  oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
     hax = newplot (hax);
 
@@ -195,7 +198,7 @@
 %! colormap (copper (64));
 %! surfl (X,Y,Z);
 %! shading interp;
-%! title ('surfl with defaults');
+%! title ('surfl() with defaults');
 
 %!demo
 %! clf;
@@ -204,5 +207,5 @@
 %! [az, el] = view ();
 %! surfl (X,Y,Z, [az+225,el], [0.2 0.6 0.4 25]);
 %! shading interp;
-%! title ('surfl with lighting vector and material properties');
+%! title ('surfl() with lighting vector and material properties');
 
--- a/scripts/plot/surfnorm.m
+++ b/scripts/plot/surfnorm.m
@@ -114,7 +114,10 @@
   nz = nz ./ len;
 
   if (nargout == 0)
-   oldfig = ifelse (isempty (hax), [], get (0, "currentfigure"));
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
    unwind_protect
      hax = newplot (hax);
      
--- a/scripts/plot/tetramesh.m
+++ b/scripts/plot/tetramesh.m
@@ -39,8 +39,8 @@
 ##
 ## The optional return value @var{h} is a vector of patch handles where each
 ## handle represents one tetrahedron in the order given by @var{T}. 
-## A typical use case for @var{h} is to turn the respective patch "visible"
-## property "on" or "off".
+## A typical use case for @var{h} is to turn the respective patch
+## @qcode{"visible"} property @qcode{"on"} or @qcode{"off"}.
 ##
 ## Type @code{demo tetramesh} to see examples on using @code{tetramesh}.
 ## @seealso{trimesh, delaunay3, delaunayn, patch}
--- a/scripts/plot/title.m
+++ b/scripts/plot/title.m
@@ -61,24 +61,38 @@
 %! clf;
 %! ax = axes ();
 %! h = get (ax, 'title');
-%! title ('Testing title');
-%! assert (get (h, 'string'), 'Testing title');
+%! title ('Test Title Text');
+
+%!demo
+%! clf;
+%! ax = axes ();
+%! h = get (ax, 'title');
+%! title ({'Multi-line'; 'Title'; 'Text'});
 
 %!demo
 %! clf;
 %! plot3 ([0,1], [0,1], [0,1]);
 %! h = get (gca, 'title');
-%! title ('Testing title', 'fontsize', 16);
-%! assert (get (h, 'string'), 'Testing title');
-%! assert (get (h, 'fontsize'), 16);
+%! title ('Test FontSize Property', 'fontsize', 16);
 
 %!test
 %! hf = figure ("visible", "off");
 %! unwind_protect
 %!   ax = axes ();
 %!   h = get (ax, "title");
-%!   title ("Testing title");
-%!   assert (get (h, "string"), "Testing title");
+%!   title ("Test Title Text");
+%!   assert (get (h, "string"), "Test Title Text");
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   ax = axes ();
+%!   h = get (ax, "title");
+%!   title ({'Multi-line'; 'Title'; 'Text'});
+%!   assert (get (h, "string"), {'Multi-line'; 'Title'; 'Text'});
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
@@ -88,8 +102,10 @@
 %! unwind_protect
 %!   plot3 ([0,1], [0,1], [0,1]);
 %!   h = get (gca, "title");
-%!   title ("Testing title");
-%!   assert (get (h, "string"), "Testing title");
+%!   title ("Test FontSize Property", "fontsize", 16);
+%!   assert (get (h, "string"), "Test FontSize Property");
+%!   assert (get (h, "fontsize"), 16);
+
 %! unwind_protect_cleanup
 %!   close (hf);
 %! end_unwind_protect
--- a/scripts/plot/trimesh.m
+++ b/scripts/plot/trimesh.m
@@ -39,7 +39,9 @@
 ## change the colormap to control the appearance.
 ##
 ## Optionally, the color of the mesh can be specified independently of @var{z}
-## by supplying a color matrix, @var{c}.
+## by supplying a color matrix, @var{c}.  If @var{z} has N elements, then
+## @var{c} should be an Nx1 vector for colormap data or an Nx3 matrix for
+## RGB data.
 ##
 ## Any property/value pairs are passed directly to the underlying patch object.
 ##
@@ -55,21 +57,39 @@
   endif
 
   if (nargin == 3)
-    triplot (tri, x, y);
+    htmp = triplot (tri, x, y);
   elseif (ischar (z))
-    triplot (tri, x, y, z, varargin{:});
+    htmp = triplot (tri, x, y, z, varargin{:});
   else
+    ## Process color argument
+    if (nargin > 4 && isnumeric (varargin{1}))
+      c = varargin{1};
+      varargin(1) = [];
+      if (isvector (c))
+        if (numel (c) != numel (z))
+          error ("trimesh: C must have 'numel (Z)' elements");
+        endif
+        c = c(:);
+      elseif (rows (c) != numel (z) || columns (c) != 3)
+        error ("trimesh: TrueColor C matrix must be 'numel (Z)' rows by 3 columns");
+      endif
+    else
+      c = z(:);
+    endif
+
     hax = newplot ();
-    handle = patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri,
-                    "FaceColor", "none", "EdgeColor", __next_line_color__ (),
-                    varargin{:});
+
+    htmp = patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri,
+                  "FaceVertexCdata", c, "EdgeColor", "flat", "FaceColor", "w",
+                  varargin{:});
     if (! ishold ())
-      set (hax, "view", [-37.5, 30],
+      set (hax, "view", [-37.5, 30], "box", "off",
                 "xgrid", "on", "ygrid", "on", "zgrid", "on");
     endif
-    if (nargout > 0)
-      h = handle;
-    endif
+  endif
+
+  if (nargout > 0)
+    h = htmp;
   endif
 
 endfunction
@@ -87,3 +107,12 @@
 %! tri = delaunay (x(:), y(:));
 %! trimesh (tri, x(:), y(:), z(:));
 
+%% Test input validation
+%!error trimesh ()
+%!error trimesh (1)
+%!error trimesh (1,2)
+%!error <C must have 'numel \(Z\)' elements> trimesh (1,2,3,4,[5 6])
+%!error <C must have 'numel \(Z\)' elements> trimesh (1,2,3,4,[5 6]')
+%!error <TrueColor C matrix must> trimesh ([1;1],[2;2],[3;3],[4;4],zeros(3,3))
+%!error <TrueColor C matrix must> trimesh ([1;1],[2;2],[3;3],[4;4],zeros(2,2))
+
--- a/scripts/plot/trisurf.m
+++ b/scripts/plot/trisurf.m
@@ -37,7 +37,9 @@
 ## change the colormap to control the appearance.
 ##
 ## Optionally, the color of the mesh can be specified independently of @var{z}
-## by supplying a color matrix, @var{c}.
+## by supplying a color matrix, @var{c}.  If @var{z} has N elements, then
+## @var{c} should be an Nx1 vector for colormap data or an Nx3 matrix for
+## RGB data.
 ##
 ## Any property/value pairs are passed directly to the underlying patch object.
 ##
@@ -48,43 +50,49 @@
 
 function h = trisurf (tri, x, y, z, varargin)
 
-  if (nargin < 3)
+  if (nargin < 4)
     print_usage ();
   endif
 
-  if (nargin == 3)
-    triplot (tri, x, y);
-  elseif (ischar (z))
-    triplot (tri, x, y, z, varargin{:});
-  else
-    if (nargin > 4 && isnumeric (varargin{1}))
-      c = varargin{1};
-      varargin(1) = [];
-    else
-      c = z;
-    endif
-    if (! any (strcmpi (varargin, "FaceColor")))
-      nfc = numel (varargin) + 1;
-      varargin(nfc+(0:1)) = {"FaceColor", "flat"};
-    else
-      nfc = find (any (strcmpi (varargin, "FaceColor")), 1);
+  if (nargin > 4 && isnumeric (varargin{1}))
+    c = varargin{1};
+    varargin(1) = [];
+    if (isvector (c))
+      if (numel (c) != numel (z))
+        error ("trisurf: C must have 'numel (Z)' elements");
+      endif
+      c = c(:);
+    elseif (rows (c) != numel (z) || columns (c) != 3)
+      error ("trisurf: TrueColor C matrix must be 'numel (Z)' rows by 3 columns");
     endif
-    if (! any (strcmpi (varargin, "EdgeColor"))
-        && strcmpi (varargin{nfc+1}, "interp"))
-      varargin(end+(1:2)) = {"EdgeColor", "none"};
-    endif
-    hax = newplot ();
-    htmp = patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)],
-                  "FaceVertexCData", reshape (c, numel (c), 1),
-                  varargin{:});
-    if (nargout > 0)
-      h = htmp;
-    endif
+  else
+    c = z(:);
+  endif
+  ## FIXME: Is all this extra input parsing necessary?
+  ##        Is it for Matlab compatibility?
+  if (! any (strcmpi (varargin, "FaceColor")))
+    nfc = numel (varargin) + 1;
+    varargin(nfc+(0:1)) = {"FaceColor", "flat"};
+  else
+    nfc = find (any (strcmpi (varargin, "FaceColor")), 1);
+  endif
+  if (! any (strcmpi (varargin, "EdgeColor"))
+      && strcmpi (varargin{nfc+1}, "interp"))
+    varargin(end+(1:2)) = {"EdgeColor", "none"};
+  endif
 
-    if (! ishold ())
-      set (hax, "view", [-37.5, 30],
-                "xgrid", "on", "ygrid", "on", "zgrid", "on");
-    endif
+  hax = newplot ();
+
+  htmp = patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)],
+                "FaceVertexCData", c, varargin{:});
+
+  if (! ishold ())
+    set (hax, "view", [-37.5, 30], "box", "off",
+              "xgrid", "on", "ygrid", "on", "zgrid", "on");
+  endif
+
+  if (nargout > 0)
+    h = htmp;
   endif
 
 endfunction
@@ -154,3 +162,13 @@
 %! tri = delaunay (x, y);
 %! trisurf (tri, x, y, z, 'facecolor', 'interp', 'edgecolor', 'k');
 
+%% Test input validation
+%!error trisurf ()
+%!error trisurf (1)
+%!error trisurf (1,2)
+%!error trisurf (1,2,3)
+%!error <C must have 'numel \(Z\)' elements> trisurf (1,2,3,4,[5 6])
+%!error <C must have 'numel \(Z\)' elements> trisurf (1,2,3,4,[5 6]')
+%!error <TrueColor C matrix must> trisurf ([1;1],[2;2],[3;3],[4;4],zeros(3,3))
+%!error <TrueColor C matrix must> trisurf ([1;1],[2;2],[3;3],[4;4],zeros(2,2))
+
--- a/scripts/plot/uicontextmenu.m
+++ b/scripts/plot/uicontextmenu.m
@@ -28,3 +28,4 @@
   handle = __go_uicontextmenu__ (h, args{:});
 
 endfunction
+
--- a/scripts/plot/uicontrol.m
+++ b/scripts/plot/uicontrol.m
@@ -34,3 +34,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/uigetfile.m
+++ b/scripts/plot/uigetfile.m
@@ -30,12 +30,12 @@
 ## formats:
 ##
 ## @table @asis
-## @item "/path/to/filename.ext"
+## @item @qcode{"/path/to/filename.ext"}
 ## If a filename is given then the file extension is extracted and used as
 ## filter.  In addition, the path is selected as current path and the filename
 ## is selected as default file.  Example: @code{uigetfile ("myfun.m")}
 ##
-## @item A single file extension "*.ext"
+## @item A single file extension @qcode{"*.ext"}
 ## Example: @code{uigetfile ("*.ext")}
 ##
 ## @item A 2-column cell array
@@ -54,10 +54,11 @@
 ## If @var{default_file} is given then it will be selected in the GUI dialog.
 ## If, in addition, a path is given it is also used as current path.
 ##
-## The screen position of the GUI dialog can be set using the "Position" key
-## and a 2-element vector containing the pixel coordinates.
-## Two or more files can be selected when setting the "MultiSelect" key to "on".
-## In that case @var{fname} is a cell array containing the files.
+## The screen position of the GUI dialog can be set using the
+## @qcode{"Position"} key and a 2-element vector containing the pixel
+## coordinates.  Two or more files can be selected when setting the
+## @qcode{"MultiSelect"} key to @qcode{"on"}.  In that case @var{fname} is a
+## cell array containing the files.
 ## @seealso{uiputfile, uigetdir}
 ## @end deftypefn
 
@@ -102,9 +103,9 @@
       val = varargin{i};
       if (ischar (val))
         val = tolower (val);
-        if (strncmp (val, "multiselect", 11))
+        if (strcmp (val, "multiselect"))
           idx1 = i;
-        elseif (strncmp (val, "position", 8))
+        elseif (strcmp (val, "position"))
           idx2 = i;
         endif
       endif
@@ -167,13 +168,13 @@
     for i = stridx : 2 : nargin
       prop = varargin{i};
       val = varargin{i + 1};
-      if (strncmp (tolower (prop), "position", 8))
+      if (strcmpi (prop, "position"))
         if (ismatrix (val) && length (val) == 2)
           outargs{4} = val;
         else
           error ("uigetfile: expecting 2-element vector for position argument");
         endif
-      elseif (strncmp (tolower (prop), "multiselect", 11))
+      elseif (strcmpi (prop, "multiselect"))
         if (ischar (val))
           outargs{5} = tolower (val);
         else
--- a/scripts/plot/uimenu.m
+++ b/scripts/plot/uimenu.m
@@ -19,44 +19,45 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} uimenu (@var{property}, @var{value}, @dots{})
 ## @deftypefnx {Function File} {} uimenu (@var{h}, @var{property}, @var{value}, @dots{})
-## Create a uimenu object and return a handle to it.  If @var{h} is ommited
+## Create a uimenu object and return a handle to it.  If @var{h} is omitted
 ## then a top-level menu for the current figure is created.  If @var{h}
 ## is given then a submenu relative to @var{h} is created.
 ##
 ## uimenu objects have the following specific properties:
 ##
 ## @table @asis
-## @item "accelerator"
+## @item @qcode{"accelerator"}
 ## A string containing the key combination together with CTRL to execute this
-## menu entry (e.g., "x" for CTRL+x).
+## menu entry (e.g., @qcode{"x"} for CTRL+x).
 ##
-## @item "callback"
+## @item @qcode{"callback"}
 ## Is the function called when this menu entry is executed.  It can be either a
-## function string (e.g., "myfun"), a function handle (e.g., @@myfun) or a cell
-## array containing the function handle and arguments for the callback
-## function (e.g., @{@@myfun, arg1, arg2@}).
+## function string (e.g., @qcode{"myfun"}), a function handle (e.g., @@myfun)
+## or a cell array containing the function handle and arguments for the
+## callback function (e.g., @{@@myfun, arg1, arg2@}).
 ##
-## @item "checked"
-## Can be set "on" or "off".  Sets a mark at this menu entry.
+## @item @qcode{"checked"}
+## Can be set @qcode{"on"} or @qcode{"off"}.  Sets a mark at this menu entry.
 ##
-## @item "enable"
-## Can be set "on" or "off".  If disabled the menu entry cannot be selected
-## and it is grayed out.
+## @item @qcode{"enable"}
+## Can be set @qcode{"on"} or @qcode{"off"}.  If disabled the menu entry
+## cannot be selected and it is grayed out.
 ##
-## @item "foregroundcolor"
+## @item @qcode{"foregroundcolor"}
 ## A color value setting the text color for this menu entry.
 ##
-## @item "label"
-## A string containing the label for this menu entry.  A "&"-symbol can be
-## used to mark the "accelerator" character (e.g., @nospell{"E&xit"})
+## @item @qcode{"label"}
+## A string containing the label for this menu entry.  A @qcode{"&"}-symbol
+## can be used to mark the @qcode{"accelerator"} character (e.g.,
+## @nospell{@qcode{"E&xit"}})
 ##
-## @item "position"
+## @item @qcode{"position"}
 ## An scalar value containing the relative menu position.  The entry with the
 ## lowest value is at the first position starting from left or top.
 ##
-## @item "separator"
-## Can be set "on" or "off".  If enabled it draws a separator line above the
-## current position.  It is ignored for top level entries.
+## @item @qcode{"separator"}
+## Can be set @qcode{"on"} or @qcode{"off"}.  If enabled it draws a separator
+## line above the current position.  It is ignored for top level entries.
 ##
 ## @end table
 ##
--- a/scripts/plot/uipanel.m
+++ b/scripts/plot/uipanel.m
@@ -29,3 +29,4 @@
   handle = __go_uipanel__ (h, args{:});
 
 endfunction
+
--- a/scripts/plot/uipushtool.m
+++ b/scripts/plot/uipushtool.m
@@ -37,3 +37,4 @@
   handle = __go_uipushtool__ (h, args{:});
 
 endfunction
+
--- a/scripts/plot/uiputfile.m
+++ b/scripts/plot/uiputfile.m
@@ -24,27 +24,27 @@
 ## Open a GUI dialog for selecting a file.  @var{flt} contains a (list of) file
 ## filter string(s) in one of the following formats:
 ##
-## @table @code
-## @item "/path/to/filename.ext"
-## If a filename is given the file extension is
-## extracted and used as filter.
-## In addition the path is selected as current path and the filename is selected
-## as default file.
-## Example: uiputfile ("myfun.m");
+## @table @asis
+## @item @qcode{"/path/to/filename.ext"}
+## If a filename is given the file extension is extracted and used as filter.
+## In addition the path is selected as current path and the filename is
+## selected as default file.  Example: @code{uiputfile ("myfun.m")}
 ##
-## @item "*.ext"
+## @item @qcode{"*.ext"}
 ## A single file extension.
-## Example: uiputfile ("*.ext");
+## Example: @code{uiputfile ("*.ext")}
 ##
-## @item @{"*.ext","My Description"@}
+## @item @code{@{"*.ext", "My Description"@}}
 ## A 2-column cell array containing the file extension in the 1st column and
 ## a brief description in the 2nd column.
-## Example: uiputfile (@{"*.ext","My Description";"*.xyz","XYZ-Format"@});
+## Example: @code{uiputfile (@{"*.ext","My Description";"*.xyz",
+## "XYZ-Format"@})}
 ## @end table
 ##
 ## The filter string can also contain a semicolon separated list of filter
 ## extensions.
-## Example: uiputfile (@{"*.gif;*.png;*.jpg", "Supported Picture Formats"@});
+## Example: @code{uiputfile (@{"*.gif;*.png;*.jpg",
+## "Supported Picture Formats"@})}
 ##
 ## @var{dialog_name} can be used to customize the dialog title.
 ## If @var{default_file} is given it is preselected in the GUI dialog.
--- a/scripts/plot/uiresume.m
+++ b/scripts/plot/uiresume.m
@@ -39,7 +39,8 @@
       set (h, "__uiwait_state__", "triggered");
     endif
   catch
-    # Ignore exception
+    ## Ignore exception
   end_try_catch
 
 endfunction
+
--- a/scripts/plot/uitoggletool.m
+++ b/scripts/plot/uitoggletool.m
@@ -37,3 +37,4 @@
   handle = __go_uitoggletool__ (h, args{:});
 
 endfunction
+
--- a/scripts/plot/uitoolbar.m
+++ b/scripts/plot/uitoolbar.m
@@ -29,3 +29,4 @@
   handle = __go_uitoolbar__ (h, args{:});
 
 endfunction
+
--- a/scripts/plot/uiwait.m
+++ b/scripts/plot/uiwait.m
@@ -78,3 +78,4 @@
   endif
 
 endfunction
+
--- a/scripts/plot/view.m
+++ b/scripts/plot/view.m
@@ -30,11 +30,11 @@
 ## arguments or as 2-element vector.  The viewpoint can also be specified with
 ## Cartesian coordinates @var{x}, @var{y}, and @var{z}.
 ##
-## The call @code{view (2)} sets the viewpoint to @var{azimuth} = 0
-## and @var{elevation} = 90, which is the default for 2-D graphs.
+## The call @code{view (2)} sets the viewpoint to @w{@var{azimuth} = 0}
+## and @w{@var{elevation} = 90}, which is the default for 2-D graphs.
 ##
-## The call @code{view (3)} sets the viewpoint to @var{azimuth} = -37.5
-## and @var{elevation} = 30, which is the default for 3-D graphs.
+## The call @code{view (3)} sets the viewpoint to @w{@var{azimuth} = -37.5}
+## and @w{@var{elevation} = 30}, which is the default for 3-D graphs.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
@@ -46,56 +46,52 @@
 
 function [azimuth, elevation] = view (varargin)
 
-  if (nargin < 4)
-    if (nargin == 0)
-      args = {get(gca (), "view")};
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("view", varargin{:});
+  if (isempty (hax))
+    hax = gca ();
+  endif
+
+  if (nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 0)
+    x = get (hax, "view");
+    az = x(1);
+    el = x(2);
+  elseif (length (varargin) == 1)
+    x = varargin{1};
+    if (length (x) == 2)
+      az = x(1);
+      el = x(2);
+    elseif (length (x) == 3)
+      [az, el] = cart2sph (x(1), x(2), x(3));
+      az *= 180/pi;
+      az += 90;
+      el *= 180/pi;
+    elseif (x == 2)
+      az = 0;
+      el = 90;
+    elseif (x == 3)
+      az = -37.5;
+      el = 30;
     else
-      ax = varargin{1};
-      if (isaxes (ax))
-        args = varargin(2:end);
-      else
-        ax = gca;
-        args = varargin;
-      endif
+      print_usage ();
     endif
-    if (length (args) == 1)
-      x = args{1};
-      if (length (x) == 2)
-        az = x(1);
-        el = x(2);
-      elseif (length (x) == 3)
-        [az, el] = cart2sph (x(1), x(2), x(3));
-        az *= 180/pi;
-        az += 90;
-        el *= 180/pi;
-      elseif (x == 2)
-        az = 0;
-        el = 90;
-      elseif (x == 3)
-        az = -37.5;
-        el = 30;
-      else
-        print_usage ();
-      endif
-    elseif (length (args) == 2)
-      az = args{1};
-      el = args{2};
-    endif
+  elseif (length (varargin) == 2)
+    az = varargin{1};
+    el = varargin{2};
+  endif
 
-    if (nargin > 0)
-      set (ax, "view", [az, el]);
-    endif
-
+  if (nargin > 0)
+    set (hax, "view", [az, el]);
+  else
     if (nargout == 1)
-      error ("view: T = view () not implemented");
-    endif
-
-    if (nargout == 2)
+      azimuth = [az, el];
+    elseif (nargout == 2)
       azimuth = az;
       elevation = el;
     endif
-  else
-    print_usage ();
   endif
 
 endfunction
--- a/scripts/plot/waitbar.m
+++ b/scripts/plot/waitbar.m
@@ -38,7 +38,7 @@
 
 ## Author: jwe
 
-function retval = waitbar (varargin)
+function h = waitbar (varargin)
 
   persistent curr_waitbar;
 
@@ -55,20 +55,16 @@
 
   ## Use existing waitbar if it still points to a valid graphics handle.
   if (nargin == 1 && ishandle (curr_waitbar))
-    h = curr_waitbar;
+    hf = curr_waitbar;
   else
-    h = false;
+    hf = false;
   endif
 
   if (! isempty (varargin) && isnumeric (varargin{1}))
-    if (! ishandle (varargin{1}))
+    hf = varargin{1};
+    varargin(1) = [];
+    if (! isfigure (hf) || ! strcmp (get (hf, "tag"), "waitbar"))
       error ("waitbar: H must be a handle to a waitbar object");
-    else
-      h = varargin{1};
-      varargin(1) = [];
-      if (! isfigure (h) || ! strcmp (get (h, "tag"), "waitbar"))
-        error ("waitbar: H must be a handle to a waitbar object");
-      endif
     endif
   endif
 
@@ -83,16 +79,16 @@
   endif
 
   if (rem (numel (varargin), 2) != 0)
-    error ("waitbar: invalid number of property-value pairs");
+    error ("waitbar: invalid number of property/value pairs");
   endif
 
-  if (h)
-    gd = get (h, "__guidata__");
+  if (hf)
+    gd = get (hf, "__guidata__");
     ## Get the cached handles.
     ax = gd(1);
-    p = gd(2);
+    hp = gd(2);
 
-    set (p, "xdata", [0; frac; frac; 0]);
+    set (hp, "xdata", [0; frac; frac; 0]);
 
     if (ischar (msg) || iscellstr (msg))
       th = get (ax, "title");
@@ -107,38 +103,45 @@
       endif
     endif
   else
-    h = __go_figure__ (NaN, "position", [250, 500, 400, 100],
-                       "numbertitle", "off",
-                       "toolbar", "none", "menubar", "none",
-                       "integerhandle", "off",
-                       "handlevisibility", "callback",
-                       "tag", "waitbar",
-                       varargin{:});
+    ## Save and restore current figure
+    cf = get (0, "currentfigure");
 
-    ax = axes ("parent", h, "xtick", [], "ytick", [],
+    hf = figure ("position", [250, 500, 400, 100],
+                 "numbertitle", "off",
+                 "menubar", "none", "toolbar", "none",
+                 "integerhandle", "off",
+                 "handlevisibility", "callback",
+                 "tag", "waitbar",
+                 varargin{:});
+
+    ax = axes ("parent", hf,
+               "xtick", [], "ytick", [],
                "xlim", [0, 1], "ylim", [0, 1],
-               "xlimmode", "manual", "ylimmode", "manual",
                "position", [0.1, 0.3, 0.8, 0.2]);
 
-    p = patch (ax, [0; frac; frac; 0], [0; 0; 1; 1], [0, 0.35, 0.75]);
+    hp = patch (ax, [0; frac; frac; 0], [0; 0; 1; 1], [0, 0.35, 0.75]);
 
     ## Cache the axes and patch handles.
-    set (h, "__guidata__", [ax p]);
+    set (hf, "__guidata__", [ax hp]);
 
     if (! (ischar (msg) || iscellstr (msg)))
       msg = "Please wait...";
     endif
     title (ax, msg);
+
+    if (! isempty (cf))
+      set (0, "currentfigure", cf);
+    endif
   endif
 
   drawnow ();
 
   if (nargout > 0)
-    retval = h;
+    h = hf;
   endif
 
   ## If there were no errors, update current waitbar.
-  curr_waitbar = h;
+  curr_waitbar = hf;
 
 endfunction
 
@@ -192,5 +195,5 @@
 %!error <FRAC must be between 0 and 1> waitbar (-0.5)
 %!error <FRAC must be between 0 and 1> waitbar (1.5)
 %!error <MSG must be a character string> waitbar (0.5, struct ())
-%!error <invalid number of property-value pairs> waitbar (0.5, "msg", "Name")
+%!error <invalid number of property/value pairs> waitbar (0.5, "msg", "Name")
 
--- a/scripts/plot/waitforbuttonpress.m
+++ b/scripts/plot/waitforbuttonpress.m
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} waitforbuttonpress ()
-## @deftypefnx {Function File} {@var{b} =} waitforbuttonpress ()
+## @deftypefnx {Function File} {@var{a} =} waitforbuttonpress ()
 ## Wait for mouse click or key press over the current figure window.
 ##
 ## The return value of @var{b} is 0 if a mouse button was pressed or 1 if a
@@ -30,7 +30,7 @@
 ## Author: Petr Mikulik
 ## License: public domain
 
-function a = waitforbuttonpress ()
+function b = waitforbuttonpress ()
 
   if (nargin != 0 || nargout > 1)
     print_usage ();
@@ -40,10 +40,16 @@
 
   if (nargout == 1)
     if (k <= 5)
-      a = 0;
+      b = 0;
     else
-      a = 1;
+      b = 1;
     endif
   endif
 
 endfunction
+
+
+%% Test input validation
+%!error waitforbuttonpress (1)
+%!error [a,b,c] = waitforbuttonpress ()
+
--- a/scripts/plot/waterfall.m
+++ b/scripts/plot/waterfall.m
@@ -35,9 +35,9 @@
 ## given, then it is plotted over the meshgrid
 ## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
-## of @var{z} correspond to different @var{y} values.  
+## of @var{z} correspond to different @var{y} values.
 ##
-## The color of the mesh is computed by linearly scaling the @var{Z} values
+## The color of the mesh is computed by linearly scaling the @var{z} values
 ## to fit the range of the current colormap.  Use @code{caxis} and/or
 ## change the colormap to control the appearance.
 ##
@@ -82,4 +82,18 @@
 %! colormap ('default');
 %! Z = peaks ();
 %! waterfall (Z);
+%! title ('waterfall() plot of peaks() function');
 
+%!demo
+%! clf;
+%! colormap ('default');
+%! Z = peaks ();
+%! subplot (1,2,1)
+%!  meshz (Z);
+%!  daspect ([2.5, 2.5, 1]);
+%!  title ('meshz() plot');
+%! subplot (1,2,2)
+%!  waterfall (Z);
+%!  daspect ([2.5, 2.5, 1]);
+%!  title ('waterfall() plot');
+
--- a/scripts/plot/whitebg.m
+++ b/scripts/plot/whitebg.m
@@ -29,7 +29,7 @@
 ## If the optional argument @var{color} is present then the background color
 ## is set to @var{color} rather than inverted.  @var{color} may be a string
 ## representing one of the eight known colors or an RGB triplet.  The special
-## string argument "none" restores the plot to the default colors.
+## string argument @qcode{"none"} restores the plot to the default colors.
 ##
 ## If the first argument @var{hfig} is a figure handle, then operate on
 ## this figure rather than the current figure returned by @code{gcf}.  The
--- a/scripts/plot/xlim.m
+++ b/scripts/plot/xlim.m
@@ -23,17 +23,17 @@
 ## @deftypefnx {Function File} {} xlim ("auto")
 ## @deftypefnx {Function File} {} xlim ("manual")
 ## @deftypefnx {Function File} {} xlim (@var{hax}, @dots{})
-## Query or set the limits of the x-axis of the current plot.
+## Query or set the limits of the x-axis for the current plot.
 ##
 ## Called without arguments @code{xlim} returns the x-axis limits of the
-## current plot.  With the input query "mode", return the current x-limit
-## calculation mode which is either "auto" or "manual".
+## current plot.  With the input query @qcode{"mode"}, return the current
+## x-limit calculation mode which is either @qcode{"auto"} or @qcode{"manual"}.
 ##
 ## If passed a 2-element vector [@var{x_lo} @var{x_hi}], the limits of the
-## x-axis are set to these values.
+## x-axis are set to these values and the mode is set to @qcode{"manual"}.
 ##
-## The current plotting mode can be set by passing either "auto" or "manual" as
-## the argument.
+## The current plotting mode can be changed by using either @qcode{"auto"}
+## or @qcode{"manual"} as the argument.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
--- a/scripts/plot/ylim.m
+++ b/scripts/plot/ylim.m
@@ -23,17 +23,17 @@
 ## @deftypefnx {Function File} {} ylim ("auto")
 ## @deftypefnx {Function File} {} ylim ("manual")
 ## @deftypefnx {Function File} {} ylim (@var{hax}, @dots{})
-## Query or set the limits of the y-axis of the current plot.
+## Query or set the limits of the y-axis for the current plot.
 ##
 ## Called without arguments @code{ylim} returns the y-axis limits of the
-## current plot.  With the input query "mode", return the current y-limit
-## calculation mode which is either "auto" or "manual".
+## current plot.  With the input query @qcode{"mode"}, return the current
+## y-limit calculation mode which is either @qcode{"auto"} or @qcode{"manual"}.
 ##
 ## If passed a 2-element vector [@var{y_lo} @var{y_hi}], the limits of the
-## y-axis are set to these values.
+## y-axis are set to these values and the mode is set to @qcode{"manual"}.
 ##
-## The current plotting mode can be set by passing either "auto" or "manual" as
-## the argument.
+## The current plotting mode can be changed by using either @qcode{"auto"}
+## or @qcode{"manual"} as the argument.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
--- a/scripts/plot/zlabel.m
+++ b/scripts/plot/zlabel.m
@@ -77,8 +77,6 @@
 %!   z = zlabel ("zlabel_string");
 %!   assert (get (gca, "zlabel"), z);
 %!   assert (get (z, "type"), "text");
-%!   ## FIXME: visible test is failing.  Not sure why.
-%!   #assert (get (z, "visible"), "off");
 %!   assert (get (z, "string"), "zlabel_string");
 %! unwind_protect_cleanup
 %!   close (hf);
--- a/scripts/plot/zlim.m
+++ b/scripts/plot/zlim.m
@@ -23,17 +23,17 @@
 ## @deftypefnx {Function File} {} zlim ("auto")
 ## @deftypefnx {Function File} {} zlim ("manual")
 ## @deftypefnx {Function File} {} zlim (@var{hax}, @dots{})
-## Query or set the limits of the z-axis of the current plot.
+## Query or set the limits of the z-axis for the current plot.
 ##
 ## Called without arguments @code{zlim} returns the z-axis limits of the
-## current plot.  With the input query "mode", return the current z-limit
-## calculation mode which is either "auto" or "manual".
+## current plot.  With the input query @qcode{"mode"}, return the current
+## z-limit calculation mode which is either @qcode{"auto"} or @qcode{"manual"}.
 ##
 ## If passed a 2-element vector [@var{z_lo} @var{z_hi}], the limits of the
-## z-axis are set to these values.
+## x-axis are set to these values and the mode is set to @qcode{"manual"}.
 ##
-## The current plotting mode can be set by passing either "auto" or "manual" as
-## the argument.
+## The current plotting mode can be changed by using either @qcode{"auto"}
+## or @qcode{"manual"} as the argument.
 ##
 ## If the first argument @var{hax} is an axes handle, then operate on
 ## this axis rather than the current axes returned by @code{gca}.
--- a/scripts/polynomial/conv.m
+++ b/scripts/polynomial/conv.m
@@ -29,10 +29,10 @@
 ## The optional @var{shape} argument may be
 ##
 ## @table @asis
-## @item @var{shape} = "full"
+## @item @var{shape} = @qcode{"full"}
 ## Return the full convolution.  (default)
 ##
-## @item @var{shape} = "same"
+## @item @var{shape} = @qcode{"same"}
 ## Return the central part of the convolution with the same size as @var{a}.
 ## @end table
 ##
--- a/scripts/polynomial/mkpp.m
+++ b/scripts/polynomial/mkpp.m
@@ -45,12 +45,12 @@
 
 function pp = mkpp (x, P, d)
 
-  # check number of arguments
+  ## check number of arguments
   if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
-  # check x
+  ## check x
   if (length (x) < 2)
     error ("mkpp: at least one interval is needed");
   endif
--- a/scripts/polynomial/pchip.m
+++ b/scripts/polynomial/pchip.m
@@ -125,6 +125,7 @@
 
 endfunction
 
+
 %!demo
 %! x = 0:8;
 %! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0];
@@ -170,3 +171,4 @@
 
 %!error (pchip (1,2));
 %!error (pchip (1,2,3));
+
--- a/scripts/polynomial/polyeig.m
+++ b/scripts/polynomial/polyeig.m
@@ -83,9 +83,11 @@
 
 endfunction
 
+
 %!test
 %! C0 = [8, 0; 0, 4]; C1 = [1, 0; 0, 1];
 %! [v,z] = polyeig (C0, C1);
 %! assert (isequal (z(1), -8), true);
 %! d = C0*v + C1*v*z;
 %! assert (isequal (norm(d), 0.0), true);
+
--- a/scripts/polynomial/polyfit.m
+++ b/scripts/polynomial/polyfit.m
@@ -115,7 +115,7 @@
   p = r \ (q' * y);
   p(k) = p;
   
-  if (n ~= m)
+  if (n != m)
     q = p; p = zeros (n+1, 1); 
     p(polymask) = q;
   endif
@@ -137,12 +137,12 @@
     try
       C = cholinv (r.'*r)(k, k);
     catch
-      C = NaN * ones (m+1, m+1);
+      C = NaN (m+1, m+1);
     end_try_catch
 
-    if (n ~= m)
+    if (n != m)
       ## fill matrices if required
-      s.X(:, ~polymask) = 0;
+      s.X(:, !polymask) = 0;
       s.R = zeros (n+1, n+1); s.R(polymask, polymask) = r;
       s.C = zeros (n+1, n+1); s.C(polymask, polymask) = C;
     else
@@ -171,10 +171,10 @@
 ## variable is not normalized properly.
 ## Also check the usage of 2nd & 3rd output arguments.
 %!test
-%! x = [ -1196.4, -1195.2, -1194, -1192.8, -1191.6, -1190.4, -1189.2, -1188, \
+%! x = [ -1196.4, -1195.2, -1194, -1192.8, -1191.6, -1190.4, -1189.2, -1188, ...
 %!       -1186.8, -1185.6, -1184.4, -1183.2, -1182];
-%! y = [ 315571.7086, 315575.9618, 315579.4195, 315582.6206, 315585.4966,    \
-%!       315588.3172, 315590.9326, 315593.5934, 315596.0455, 315598.4201,    \
+%! y = [ 315571.7086, 315575.9618, 315579.4195, 315582.6206, 315585.4966, ...
+%!       315588.3172, 315590.9326, 315593.5934, 315596.0455, 315598.4201, ...
 %!       315600.7143, 315602.9508, 315605.1765 ];
 %! [p1, s1] = polyfit (x, y, 10);
 %! [p2, s2, mu] = polyfit (x, y, 10);
--- a/scripts/polynomial/polyout.m
+++ b/scripts/polynomial/polyout.m
@@ -32,7 +32,7 @@
 ##
 ## @end ifnottex
 ## and return it as a string or write it to the screen (if @var{nargout} is
-## zero).  @var{x} defaults to the string @code{"s"}.
+## zero).  @var{x} defaults to the string @qcode{"s"}.
 ## @seealso{polyreduce}
 ## @end deftypefn
 
--- a/scripts/polynomial/ppval.m
+++ b/scripts/polynomial/ppval.m
@@ -95,7 +95,7 @@
     yi = shiftdim (yi, nd);
   endif
 
-  ##
+  ## FIXME: Why is this commented out, rather than just removed?
   #if (d == 1)
   #  yi = reshape (yi, sxi);
   #endif
@@ -127,3 +127,4 @@
 %! ret(:,:,1) = ppval (pp, breaks');
 %! ret(:,:,2) = ppval (pp, breaks');
 %! assert (ppval (pp, [breaks',breaks']), ret)
+
--- a/scripts/polynomial/private/__splinefit__.m
+++ b/scripts/polynomial/private/__splinefit__.m
@@ -387,7 +387,7 @@
 if isempty(cc)
     cc = ones(size(xc));
 elseif numel(size(cc)) ~= 2
-    error('arguments:ccsize1','Constraint coefficients cc must be 2D.')
+    error('arguments:ccsize1','Constraint coefficients cc must be 2-D.')
 elseif size(cc,2) ~= nx
     mess = 'Last dimension of cc must equal length of xc.';
     error('arguments:ccsize2',mess)
--- a/scripts/polynomial/residue.m
+++ b/scripts/polynomial/residue.m
@@ -160,7 +160,7 @@
     ## The inputs are the residue, pole, and direct part. Solve for the
     ## corresponding numerator and denominator polynomials
     [r, p] = rresidue (b, a, varargin{1}, toler, e);
-    return
+    return;
   endif
 
   ## Make sure both polynomials are in reduced form.
--- a/scripts/polynomial/splinefit.m
+++ b/scripts/polynomial/splinefit.m
@@ -59,18 +59,18 @@
 ## the degrees of freedom are reduced to P.
 ##
 ## The optional property, @var{constaints}, is a structure specifying
-## linear constraints on the fit.  The structure has three fields, "xc",
-## "yc", and "cc".
+## linear constraints on the fit.  The structure has three fields, @qcode{"xc"},
+## @qcode{"yc"}, and @qcode{"cc"}.
 ##
 ## @table @asis
-## @item "xc"
+## @item @qcode{"xc"}
 ## Vector of the x-locations of the constraints.
 ##
-## @item "yc"
+## @item @qcode{"yc"}
 ## Constraining values at the locations @var{xc}.
 ## The default is an array of zeros.
 ##
-## @item "cc"
+## @item @qcode{"cc"}
 ## Coefficients (matrix).  The default is an array of ones.  The number of
 ## rows is limited to the order of the piecewise polynomials, @var{order}.
 ## @end table
@@ -94,7 +94,7 @@
 
 function pp = splinefit (x, y, breaks, varargin)
   if (nargin > 3)
-    n = cellfun (@ischar, varargin, "uniformoutput", true);
+    n = cellfun ("isclass", varargin, "char");
     varargin(n) = lower (varargin(n));
     try
       props = struct (varargin{:});
--- a/scripts/prefs/addpref.m
+++ b/scripts/prefs/addpref.m
@@ -69,6 +69,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/getpref.m
+++ b/scripts/prefs/getpref.m
@@ -90,6 +90,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/ispref.m
+++ b/scripts/prefs/ispref.m
@@ -55,6 +55,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/prefdir.m
+++ b/scripts/prefs/prefdir.m
@@ -17,18 +17,20 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} prefdir 
-## @deftypefnx {Function File} {@var{dir} =} prefdir 
+## @deftypefn  {Command} {} prefdir 
+## @deftypefnx {Command} {@var{dir} =} prefdir 
 ## Return the directory that contains the preferences for Octave.
 ##
 ## Examples:
 ##
 ## Display the preferences directory
+##
 ## @example
 ## prefdir
 ## @end example
 ##
 ## Change to the preferences folder
+##
 ## @example
 ## cd (prefdir)
 ## @end example
--- a/scripts/prefs/preferences.m
+++ b/scripts/prefs/preferences.m
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} preferences 
+## @deftypefn {Command} {} preferences 
 ## Display the GUI preferences dialog window for Octave.
 ## @end deftypefn
 
--- a/scripts/prefs/private/loadprefs.m
+++ b/scripts/prefs/private/loadprefs.m
@@ -38,6 +38,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/private/prefsfile.m
+++ b/scripts/prefs/private/prefsfile.m
@@ -29,6 +29,8 @@
   
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/private/saveprefs.m
+++ b/scripts/prefs/private/saveprefs.m
@@ -31,6 +31,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/prefs/setpref.m
+++ b/scripts/prefs/setpref.m
@@ -62,6 +62,8 @@
 
 endfunction
 
+
 %% Testing these functions will require some care to avoid wiping out
 %% existing (or creating unwanted) preferences for the user running the
 %% tests.
+
--- a/scripts/set/intersect.m
+++ b/scripts/set/intersect.m
@@ -60,7 +60,7 @@
       len_a = rows (a);
     else
       c = [a(:); b(:)];
-      [c, ic] = sort (c);               ## [a(:);b(:)](ic) == c
+      [c, ic] = sort (c);               # [a(:);b(:)](ic) == c
       if (iscellstr (c))
         ii = find (strcmp (c(1:end-1), c(2:end)));
       else
@@ -71,8 +71,8 @@
     endif
 
     if (nargout > 1)
-      ia = ja(ic(ii));                  ## a(ia) == c
-      ib = jb(ic(ii+1) - len_a);        ## b(ib) == c
+      ia = ja(ic(ii));                  # a(ia) == c
+      ib = jb(ic(ii+1) - len_a);        # b(ib) == c
     endif
 
     if (nargin == 2 && (rows (b) == 1 || rows (a) == 1))
--- a/scripts/set/ismember.m
+++ b/scripts/set/ismember.m
@@ -48,7 +48,7 @@
 ## @end group
 ## @end example
 ##
-## With the optional third argument @code{"rows"}, and matrices
+## With the optional third argument @qcode{"rows"}, and matrices
 ## @var{A} and @var{s} with the same number of columns, compare rows in
 ## @var{A} with the rows in @var{s}.
 ##
--- a/scripts/set/powerset.m
+++ b/scripts/set/powerset.m
@@ -24,7 +24,7 @@
 ## The set @var{a} must be a numerical matrix or a cell array of strings.  The
 ## output will always be a cell array of either vectors or strings.
 ##
-## With the optional second argument @code{"rows"}, each row of the set @var{a}
+## With the optional second argument @qcode{"rows"}, each row of the set @var{a}
 ## is considered one element of the set.  As a result, @var{a} must then be a
 ## numerical 2-D matrix.
 ##
--- a/scripts/set/private/validargs.m
+++ b/scripts/set/private/validargs.m
@@ -55,3 +55,4 @@
   endif
 
 endfunction
+
--- a/scripts/set/setdiff.m
+++ b/scripts/set/setdiff.m
@@ -26,7 +26,7 @@
 ## return a column vector, otherwise return a row vector.
 ## @var{a}, @var{b} may be cell arrays of string(s).
 ##
-## Given the optional third argument @samp{"rows"}, return the rows in
+## Given the optional third argument @qcode{"rows"}, return the rows in
 ## @var{a} that are not in @var{b}, sorted in ascending order by rows.
 ##
 ## If requested, return @var{i} such that @code{c = a(i)}.
--- a/scripts/set/union.m
+++ b/scripts/set/union.m
@@ -33,9 +33,9 @@
 ## @end group
 ## @end example
 ##
-## If the optional third input argument is the string "rows" then each row of
-## the matrices @var{a} and @var{b} will be considered as a single set element.
-## For example:
+## If the optional third input argument is the string @qcode{"rows"} then
+## each row of the matrices @var{a} and @var{b} will be considered as a
+## single set element.  For example:
 ##
 ## @example
 ## @group
--- a/scripts/set/unique.m
+++ b/scripts/set/unique.m
@@ -29,16 +29,16 @@
 ## output is always a column vector.  @var{x} may also be a cell array of
 ## strings.
 ##
-## If the optional argument @code{"rows"} is supplied, return the unique
+## If the optional argument @qcode{"rows"} is supplied, return the unique
 ## rows of @var{x}, sorted in ascending order.
 ##
 ## If requested, return index vectors @var{i} and @var{j} such that
 ## @code{x(i)==y} and @code{y(j)==x}.
 ##
-## Additionally, if @var{i} is a requested output then one of @code{"first"} or
-## @code{"last"} may be given as an input.  If @code{"last"} is specified,
-## return the highest possible indices in @var{i}, otherwise, if @code{"first"}
-## is specified, return the lowest.  The default is @code{"last"}.
+## Additionally, if @var{i} is a requested output then one of @qcode{"first"} or
+## @qcode{"last"} may be given as an input.  If @qcode{"last"} is specified,
+## return the highest possible indices in @var{i}, otherwise, if @qcode{"first"}
+## is specified, return the lowest.  The default is @qcode{"last"}.
 ## @seealso{union, intersect, setdiff, setxor, ismember}
 ## @end deftypefn
 
@@ -221,3 +221,4 @@
 %!error unique({"a", "b", "c"}, "UnknownOption1", "UnknownOption2")
 %!error unique({"a", "b", "c"}, "rows", "UnknownOption2")
 %!error unique({"a", "b", "c"}, "UnknownOption1", "last")
+
--- a/scripts/signal/arch_fit.m
+++ b/scripts/signal/arch_fit.m
@@ -116,3 +116,4 @@
   endfor
 
 endfunction
+
--- a/scripts/signal/arch_rnd.m
+++ b/scripts/signal/arch_rnd.m
@@ -100,3 +100,4 @@
   y = y(1:t);
 
 endfunction
+
--- a/scripts/signal/arch_test.m
+++ b/scripts/signal/arch_test.m
@@ -94,3 +94,4 @@
   pval = 1 - chi2cdf (lm, p);
 
 endfunction
+
--- a/scripts/signal/arma_rnd.m
+++ b/scripts/signal/arma_rnd.m
@@ -79,3 +79,4 @@
   x = x(n + 1 : t + n);
 
 endfunction
+
--- a/scripts/signal/detrend.m
+++ b/scripts/signal/detrend.m
@@ -28,8 +28,9 @@
 ## is assumed.  This corresponds to removing a linear trend.
 ##
 ## The order of the polynomial can also be given as a string, in which case
-## @var{p} must be either @t{"constant"} (corresponds to @code{@var{p}=0}) or
-## @t{"linear"} (corresponds to @code{@var{p}=1}).
+## @var{p} must be either @qcode{"constant"} (corresponds to
+## @code{@var{p}=0}) or
+## @qcode{"linear"} (corresponds to @code{@var{p}=1}).
 ## @seealso{polyfit}
 ## @end deftypefn
 
--- a/scripts/signal/durbinlevinson.m
+++ b/scripts/signal/durbinlevinson.m
@@ -91,3 +91,4 @@
   endif
 
 endfunction
+
--- a/scripts/signal/fftconv.m
+++ b/scripts/signal/fftconv.m
@@ -67,36 +67,36 @@
 
 %% FIXME: Borrow tests from conv.m.  May need a tolerance on the assert comparison
 %!test
-%!  x = ones (3,1);
-%!  y = ones (1,3);
-%!  b = 2;
-%!  c = 3;
-%!  assert (fftconv (x, x), [1; 2; 3; 2; 1], 5*eps);
-%!  assert (fftconv (y, y), [1, 2, 3, 2, 1], 5*eps);
-%!  assert (fftconv (x, y), [1, 2, 3, 2, 1], 5*eps);
-%!  assert (fftconv (y, x), [1; 2; 3; 2; 1], 5*eps);
-%!  assert (fftconv (c, x), [3; 3; 3], 5*eps);
-%!  assert (fftconv (c, y), [3, 3, 3], 5*eps);
-%!  assert (fftconv (x, c), [3; 3; 3], 5*eps);
-%!  assert (fftconv (y, c), [3, 3, 3], 5*eps);
-%!  assert (fftconv (b, c), 6, 5*eps);
+%! x = ones (3,1);
+%! y = ones (1,3);
+%! b = 2;
+%! c = 3;
+%! assert (fftconv (x, x), [1; 2; 3; 2; 1], 5*eps);
+%! assert (fftconv (y, y), [1, 2, 3, 2, 1], 5*eps);
+%! assert (fftconv (x, y), [1, 2, 3, 2, 1], 5*eps);
+%! assert (fftconv (y, x), [1; 2; 3; 2; 1], 5*eps);
+%! assert (fftconv (c, x), [3; 3; 3], 5*eps);
+%! assert (fftconv (c, y), [3, 3, 3], 5*eps);
+%! assert (fftconv (x, c), [3; 3; 3], 5*eps);
+%! assert (fftconv (y, c), [3, 3, 3], 5*eps);
+%! assert (fftconv (b, c), 6, 5*eps);
 
 %!test
-%!  a = 1:10;
-%!  b = 1:3;
-%!  assert (size (conv (a,b)), [1, numel(a)+numel(b)-1])
-%!  assert (size (conv (b,a)), [1, numel(a)+numel(b)-1])
+%! a = 1:10;
+%! b = 1:3;
+%! assert (size (conv (a,b)), [1, numel(a)+numel(b)-1]);
+%! assert (size (conv (b,a)), [1, numel(a)+numel(b)-1]);
 
-%!  a = (1:10).';
-%!  b = 1:3;
-%!  assert (size (conv (a,b)), [numel(a)+numel(b)-1, 1])
-%!  assert (size (conv (b,a)), [numel(a)+numel(b)-1, 1])
+%! a = (1:10).';
+%! b = 1:3;
+%! assert (size (conv (a,b)), [numel(a)+numel(b)-1, 1]);
+%! assert (size (conv (b,a)), [numel(a)+numel(b)-1, 1]);
 
 %!test
-%!  a = 1:10;
-%!  b = (1:3).';
-%!  assert (size (conv (a,b)), [1, numel(a)+numel(b)-1])
-%!  assert (size (conv (b,a)), [1, numel(a)+numel(b)-1])
+%! a = 1:10;
+%! b = (1:3).';
+%! assert (size (conv (a,b)), [1, numel(a)+numel(b)-1]);
+%! assert (size (conv (b,a)), [1, numel(a)+numel(b)-1]);
 
 %% Test input validation
 %!error fftconv (1)
--- a/scripts/signal/fftfilt.m
+++ b/scripts/signal/fftfilt.m
@@ -24,7 +24,7 @@
 ##
 ## Given the optional third argument, @var{n}, @code{fftfilt} uses the
 ## overlap-add method to filter @var{x} with @var{b} using an @var{n}-point
-## FFT.  The FFT size must be an even power of 2 and must be greater than
+## FFT@.  The FFT size must be an even power of 2 and must be greater than
 ## or equal to the length of @var{b}.  If the specified @var{n} does not
 ## meet these criteria, it is automatically adjusted to the nearest value
 ## that does.
--- a/scripts/signal/fftshift.m
+++ b/scripts/signal/fftshift.m
@@ -85,47 +85,47 @@
 
 
 %!test
-%!  x = [0:7];
-%!  y = fftshift (x);
-%!  assert (y, [4 5 6 7 0 1 2 3]);
-%!  assert (fftshift (y), x);
+%! x = [0:7];
+%! y = fftshift (x);
+%! assert (y, [4 5 6 7 0 1 2 3]);
+%! assert (fftshift (y), x);
 
 %!test
-%!  x = [0:6];
-%!  y = fftshift (x);
-%!  assert (y, [4 5 6 0 1 2 3]);
-%!  assert (fftshift (y), [1 2 3 4 5 6 0]);
+%! x = [0:6];
+%! y = fftshift (x);
+%! assert (y, [4 5 6 0 1 2 3]);
+%! assert (fftshift (y), [1 2 3 4 5 6 0]);
 
 %!test
-%!  x = [0:7]';
-%!  y = fftshift (x);
-%!  assert (y, [4;5;6;7;0;1;2;3]);
-%!  assert (fftshift (y), x);
+%! x = [0:7]';
+%! y = fftshift (x);
+%! assert (y, [4;5;6;7;0;1;2;3]);
+%! assert (fftshift (y), x);
 
 %!test
-%!  x = [0:6]';
-%!  y = fftshift (x);
-%!  assert (y, [4;5;6;0;1;2;3]);
-%!  assert (fftshift (y), [1;2;3;4;5;6;0]);
+%! x = [0:6]';
+%! y = fftshift (x);
+%! assert (y, [4;5;6;0;1;2;3]);
+%! assert (fftshift (y), [1;2;3;4;5;6;0]);
 
 %!test
-%!  x = [0:3];
-%!  x = [x;2*x;3*x+1;4*x+1];
-%!  y = fftshift (x);
-%!  assert (y, [[7 10 1 4];[9 13 1 5];[2 3 0 1];[4 6 0 2]]);
-%!  assert (fftshift (y), x);
+%! x = [0:3];
+%! x = [x;2*x;3*x+1;4*x+1];
+%! y = fftshift (x);
+%! assert (y, [[7 10 1 4];[9 13 1 5];[2 3 0 1];[4 6 0 2]]);
+%! assert (fftshift (y), x);
 
 %!test
-%!  x = [0:3];
-%!  x = [x;2*x;3*x+1;4*x+1];
-%!  y = fftshift (x,1);
-%!  assert (y, [[1 4 7 10];[1 5 9 13];[0 1 2 3];[0 2 4 6]]);
-%!  assert (fftshift (y,1), x);
+%! x = [0:3];
+%! x = [x;2*x;3*x+1;4*x+1];
+%! y = fftshift (x,1);
+%! assert (y, [[1 4 7 10];[1 5 9 13];[0 1 2 3];[0 2 4 6]]);
+%! assert (fftshift (y,1), x);
 
 %!test
-%!  x = [0:3];
-%!  x = [x;2*x;3*x+1;4*x+1];
-%!  y = fftshift (x,2);
-%!  assert (y, [[2 3 0 1];[4 6 0 2];[7 10 1 4];[9 13 1 5]]);
-%!  assert (fftshift (y,2), x);
+%! x = [0:3];
+%! x = [x;2*x;3*x+1;4*x+1];
+%! y = fftshift (x,2);
+%! assert (y, [[2 3 0 1];[4 6 0 2];[7 10 1 4];[9 13 1 5]]);
+%! assert (fftshift (y,2), x);
 
--- a/scripts/signal/filter2.m
+++ b/scripts/signal/filter2.m
@@ -24,13 +24,13 @@
 ## Possible values are:
 ##
 ## @table @asis
-## @item "full"
+## @item @qcode{"full"}
 ## pad @var{x} with zeros on all sides before filtering.
 ##
-## @item "same"
+## @item @qcode{"same"}
 ## unpadded @var{x} (default)
 ##
-## @item "valid"
+## @item @qcode{"valid"}
 ## trim @var{x} after filtering so edge effects are no included.
 ## @end table
 ##
--- a/scripts/signal/fractdiff.m
+++ b/scripts/signal/fractdiff.m
@@ -67,3 +67,4 @@
   endif
 
 endfunction
+
--- a/scripts/signal/freqz.m
+++ b/scripts/signal/freqz.m
@@ -44,8 +44,8 @@
 ## For fastest computation, @var{n} should factor into a small number of
 ## small primes.
 ##
-## If the fourth argument, "whole", is omitted the response is evaluated at
-## frequencies between 0 and
+## If the fourth argument, @qcode{"whole"}, is omitted the response is
+## evaluated at frequencies between 0 and
 ## @ifnottex
 ##  pi.
 ## @end ifnottex
@@ -178,7 +178,7 @@
 
 
 %!test # correct values and fft-polyval consistency
-%! # butterworth filter, order 2, cutoff pi/2 radians
+%! ## butterworth filter, order 2, cutoff pi/2 radians
 %! b = [0.292893218813452  0.585786437626905  0.292893218813452];
 %! a = [1  0  0.171572875253810];
 %! [h,w] = freqz (b,a,32);
@@ -203,3 +203,4 @@
 %! assert (h,h2.',20*eps);
 %! [h3,f3] = freqz (b,a,32,"whole",320);
 %! assert (f3,[0:31]'*10,10*eps);
+
--- a/scripts/signal/freqz_plot.m
+++ b/scripts/signal/freqz_plot.m
@@ -64,3 +64,4 @@
   axis ([w(1), w(n)], "autoy", "label");
 
 endfunction
+
--- a/scripts/signal/hurst.m
+++ b/scripts/signal/hurst.m
@@ -46,3 +46,4 @@
   H = log (RS) / log (xr);
 
 endfunction
+
--- a/scripts/signal/periodogram.m
+++ b/scripts/signal/periodogram.m
@@ -34,7 +34,7 @@
 ##
 ## @itemize
 ## @item x: data; if real-valued a one-sided spectrum is estimated,
-## if complex-valued or range indicates "@nospell{twosided}", the full
+## if complex-valued or range indicates @qcode{"@nospell{twosided}"}, the full
 ## spectrum is estimated.
 ##
 ## @item win: weight data with window, x.*win is used for further computation,
@@ -44,9 +44,10 @@
 ##
 ## @item Fs: sampling rate, default 1.
 ##
-## @item range: "@nospell{onesided}" computes spectrum from [0..nfft/2+1].
-## "@nospell{twosided}" computes spectrum from [0..nfft-1].  These strings
-## can appear at any position in the list input arguments after window.
+## @item range: @qcode{"@nospell{onesided}"} computes spectrum from [0..nfft/2+1].
+## @qcode{"@nospell{twosided}"} computes spectrum from [0..nfft-1].  These
+## strings can appear at any position in the list input arguments after
+## window.
 ##
 ## @item @nospell{Pxx}: one-, or two-sided power spectrum.
 ##
@@ -74,14 +75,14 @@
       range = varargin{k};
     else
       switch (j)
-      case 1
-        window = varargin{k};
-      case 2
-        nfft   = varargin{k};
-      case 3
-        fs     = varargin{k};
-      case 4
-        range  = varargin{k};
+        case 1
+          window = varargin{k};
+        case 2
+          nfft   = varargin{k};
+        case 3
+          fs     = varargin{k};
+        case 4
+          range  = varargin{k};
       endswitch
       j++;
     endif
@@ -188,3 +189,4 @@
   endif
 
 endfunction
+
--- a/scripts/signal/private/rectangle_lw.m
+++ b/scripts/signal/private/rectangle_lw.m
@@ -27,13 +27,10 @@
 
 function retval = rectangle_lw (n, b)
 
-  if (nargin != 2)
-    print_usage ();
-  endif
-
   retval = zeros (n, 1);
   t = floor (1 / b);
 
   retval(1:t, 1) = ones (t, 1);
 
 endfunction
+
--- a/scripts/signal/private/rectangle_sw.m
+++ b/scripts/signal/private/rectangle_sw.m
@@ -27,10 +27,6 @@
 
 function retval = rectangle_sw (n, b)
 
-  if (nargin != 2)
-    print_usage ();
-  endif
-
   retval = zeros (n, 1);
   retval(1) = 2 / b + 1;
 
@@ -41,32 +37,3 @@
 
 endfunction
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/scripts/signal/private/triangle_lw.m
+++ b/scripts/signal/private/triangle_lw.m
@@ -27,10 +27,6 @@
 
 function retval = triangle_lw (n, b)
 
-  if (nargin != 2)
-    print_usage ();
-  endif
-
   retval = 1 - (0 : n-1)' * b;
   retval = max ([retval'; (zeros (1, n))])';
 
--- a/scripts/signal/private/triangle_sw.m
+++ b/scripts/signal/private/triangle_sw.m
@@ -27,10 +27,6 @@
 
 function retval = triangle_sw (n, b)
 
-  if (nargin != 2)
-    print_usage ();
-  endif
-
   retval = zeros (n,1);
   retval(1) = 1 / b;
 
@@ -41,32 +37,3 @@
 
 endfunction
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/scripts/signal/spectral_adf.m
+++ b/scripts/signal/spectral_adf.m
@@ -17,16 +17,19 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} spectral_adf (@var{c}, @var{win}, @var{b})
+## @deftypefn  {Function File} {} spectral_adf (@var{c})
+## @deftypefnx {Function File} {} spectral_adf (@var{c}, @var{win})
+## @deftypefnx {Function File} {} spectral_adf (@var{c}, @var{win}, @var{b})
 ## Return the spectral density estimator given a vector of
 ## autocovariances @var{c}, window name @var{win}, and bandwidth,
 ## @var{b}.
 ##
-## The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
-## used to search for a function called @code{@var{win}_sw}.
+## The window name, e.g., @qcode{"triangle"} or @qcode{"rectangle"} is
+## used to search for a function called @code{@var{win}_lw}.
 ##
 ## If @var{win} is omitted, the triangle window is used.  If @var{b} is
 ## omitted, @code{1 / sqrt (length (@var{x}))} is used.
+## @seealso{spectral_xdf}
 ## @end deftypefn
 
 ## Author: FL <Friedrich.Leisch@ci.tuwien.ac.at>
@@ -34,6 +37,10 @@
 
 function retval = spectral_adf (c, win, b)
 
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
   cr = length (c);
 
   if (columns (c) > 1)
@@ -46,8 +53,10 @@
 
   if (nargin == 1)
     w = triangle_lw (cr, b);
+  elseif (! ischar (win))
+    error ("spectral_adf: WIN must be a string");
   else
-    win = str2func ([win "_lw")];
+    win = str2func ([win "_lw"]);
     w = feval (win, cr, b);
   endif
 
@@ -60,6 +69,9 @@
 endfunction
 
 
-
+%% Test input validation
+%!error spectral_adf ();
+%!error spectral_adf (1, 2, 3, 4);
+%!error spectral_adf (1, 2);
+%!error spectral_adf (1, "invalid");
 
-
--- a/scripts/signal/spectral_xdf.m
+++ b/scripts/signal/spectral_xdf.m
@@ -17,15 +17,18 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} spectral_xdf (@var{x}, @var{win}, @var{b})
+## @deftypefn  {Function File} {} spectral_xdf (@var{x})
+## @deftypefnx {Function File} {} spectral_xdf (@var{x}, @var{win})
+## @deftypefnx {Function File} {} spectral_xdf (@var{x}, @var{win}, @var{b})
 ## Return the spectral density estimator given a data vector @var{x},
 ## window name @var{win}, and bandwidth, @var{b}.
 ##
-## The window name, e.g., @code{"triangle"} or @code{"rectangle"} is
+## The window name, e.g., @qcode{"triangle"} or @qcode{"rectangle"} is
 ## used to search for a function called @code{@var{win}_sw}.
 ##
 ## If @var{win} is omitted, the triangle window is used.  If @var{b} is
 ## omitted, @code{1 / sqrt (length (@var{x}))} is used.
+## @seealso{spectral_adf}
 ## @end deftypefn
 
 ## Author: FL <Friedrich.Leisch@ci.tuwien.ac.at>
@@ -33,6 +36,10 @@
 
 function retval = spectral_xdf (x, win, b)
 
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
   xr = length (x);
 
   if (columns (x) > 1)
@@ -45,8 +52,10 @@
 
   if (nargin == 1)
     w = triangle_sw (xr, b);
+  elseif (! ischar (win))
+    error ("spectral_xdf: WIN must be a string");
   else
-    win = str2func ([win "_sw")];
+    win = str2func ([win "_sw"]);
     w = feval (win, xr, b);
   endif
 
@@ -60,3 +69,10 @@
 
 endfunction
 
+
+%% Test input validation
+%!error spectral_xdf ();
+%!error spectral_xdf (1, 2, 3, 4);
+%!error spectral_xdf (1, 2);
+%!error spectral_xdf (1, "invalid");
+
--- a/scripts/signal/stft.m
+++ b/scripts/signal/stft.m
@@ -132,3 +132,4 @@
   endif
 
 endfunction
+
--- a/scripts/signal/synthesis.m
+++ b/scripts/signal/synthesis.m
@@ -70,3 +70,4 @@
   x = reshape (z, inc * nc, 1);
 
 endfunction
+
--- a/scripts/signal/yulewalker.m
+++ b/scripts/signal/yulewalker.m
@@ -55,6 +55,3 @@
 endfunction
 
 
-
-
-
--- a/scripts/sparse/bicg.m
+++ b/scripts/sparse/bicg.m
@@ -234,10 +234,10 @@
 
 %!function y = afun (x, t, a)
 %!  switch (t)
-%!   case "notransp"
-%!     y = a * x;
-%!   case "transp"
-%!     y = a' * x;
+%!    case "notransp"
+%!      y = a * x;
+%!    case "transp"
+%!      y = a' * x;
 %!  endswitch
 %!endfunction
 %!
--- a/scripts/sparse/bicgstab.m
+++ b/scripts/sparse/bicgstab.m
@@ -145,7 +145,7 @@
     flag = 1;
 
     for iter = 1:maxit
-      rho_1 = res' * rr;
+      rho_1 = rr' * res;
 
       if (iter == 1)
         p = res;
@@ -163,7 +163,7 @@
       shat = precon (s);
 
       t = Ax (shat);
-      omega = (t' * s) / (t' * t);
+      omega = (s' * t) / (t' * t);
       x = x + alpha * phat + omega * shat;
       res = s - omega * t;
       rho_2 = rho_1;
@@ -248,3 +248,8 @@
 %! [x, flag, relres, iter, resvec] = bicgstab (A, b, tol, [], diag (diag (A)));
 %! assert (x, ones (size (b)), 1e-7);
 
+%!test
+%! A = [1 + 1i, 1 + 1i; 2 - 1i, 2 + 1i];
+%! b = A * [1; 1];
+%! [x, flag, relres, iter, resvec] = bicgstab (A, b);
+%! assert (x, [1; 1], 1e-6);
--- a/scripts/sparse/colperm.m
+++ b/scripts/sparse/colperm.m
@@ -35,3 +35,4 @@
   idx = find (diff ([j; Inf]) != 0);
   [dummy, p] = sort (idx - [0; idx(1:(end-1))]);
 endfunction
+
new file mode 100644
--- /dev/null
+++ b/scripts/sparse/eigs.m
@@ -0,0 +1,1110 @@
+## Copyright (C) 2005-2012 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{d} =} eigs (@var{A})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{k})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{k}, @var{sigma}, @var{opts})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{B})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{B}, @var{k})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{A}, @var{B}, @var{k}, @var{sigma}, @var{opts})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{B})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{k})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{k}, @var{sigma}, @var{opts})
+## @deftypefnx {Function File} {@var{d} =} eigs (@var{af}, @var{n}, @var{B}, @var{k}, @var{sigma}, @var{opts})
+## @deftypefnx {Function File} {[@var{V}, @var{d}] =} eigs (@var{A}, @dots{})
+## @deftypefnx {Function File} {[@var{V}, @var{d}] =} eigs (@var{af}, @var{n}, @dots{})
+## @deftypefnx {Function File} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{A}, @dots{})
+## @deftypefnx {Function File} {[@var{V}, @var{d}, @var{flag}] =} eigs (@var{af}, @var{n}, @dots{})
+## Calculate a limited number of eigenvalues and eigenvectors of @var{A},
+## based on a selection criteria.  The number of eigenvalues and eigenvectors to
+## calculate is given by @var{k} and defaults to 6.
+## 
+## By default, @code{eigs} solve the equation
+## @tex
+## $A \nu = \lambda \nu$,
+## @end tex
+## @ifinfo
+## @code{A * v = lambda * v},
+## @end ifinfo
+## where
+## @tex
+## $\lambda$ is a scalar representing one of the eigenvalues, and $\nu$
+## @end tex
+## @ifinfo
+## @code{lambda} is a scalar representing one of the eigenvalues, and @code{v}
+## @end ifinfo
+## is the corresponding eigenvector.  If given the positive definite matrix
+## @var{B} then @code{eigs} solves the general eigenvalue equation
+## @tex
+## $A \nu = \lambda B \nu$.
+## @end tex
+## @ifinfo
+## @code{A * v = lambda * B * v}.
+## @end ifinfo
+## 
+## The argument @var{sigma} determines which eigenvalues are returned.
+## @var{sigma} can be either a scalar or a string.  When @var{sigma} is a
+## scalar, the @var{k} eigenvalues closest to @var{sigma} are returned.  If
+## @var{sigma} is a string, it must have one of the following values.
+## 
+## @table @asis
+## @item @qcode{"lm"}
+## Largest Magnitude (default).
+## 
+## @item @qcode{"sm"}
+## Smallest Magnitude.
+## 
+## @item @qcode{"la"}
+## Largest Algebraic (valid only for real symmetric problems).
+## 
+## @item @qcode{"sa"}
+## Smallest Algebraic (valid only for real symmetric problems).
+## 
+## @item @qcode{"be"}
+## Both Ends, with one more from the high-end if @var{k} is odd (valid only for
+## real symmetric problems).
+## 
+## @item @qcode{"lr"}
+## Largest Real part (valid only for complex or unsymmetric problems).
+## 
+## @item @qcode{"sr"}
+## Smallest Real part (valid only for complex or unsymmetric problems).
+## 
+## @item @qcode{"li"}
+## Largest Imaginary part (valid only for complex or unsymmetric problems).
+## 
+## @item @qcode{"si"}
+## Smallest Imaginary part (valid only for complex or unsymmetric problems).
+## @end table
+## 
+## If @var{opts} is given, it is a structure defining possible options that
+## @code{eigs} should use.  The fields of the @var{opts} structure are:
+## 
+## @table @code
+## @item issym
+## If @var{af} is given, then flags whether the function @var{af} defines a
+## symmetric problem.  It is ignored if @var{A} is given.  The default is false.
+## 
+## @item isreal
+## If @var{af} is given, then flags whether the function @var{af} defines a
+## real problem.  It is ignored if @var{A} is given.  The default is true.
+## 
+## @item tol
+## Defines the required convergence tolerance, calculated as
+## @code{tol * norm (A)}.  The default is @code{eps}.
+## 
+## @item maxit
+## The maximum number of iterations.  The default is 300.
+## 
+## @item p
+## The number of Lanzcos basis vectors to use.  More vectors will result in
+## faster convergence, but a greater use of memory.  The optimal value of
+## @code{p} is problem dependent and should be in the range @var{k} to @var{n}.
+## The default value is @code{2 * @var{k}}.
+## 
+## @item v0
+## The starting vector for the algorithm.  An initial vector close to the
+## final vector will speed up convergence.  The default is for @sc{arpack}
+## to randomly generate a starting vector.  If specified, @code{v0} must be
+## an @var{n}-by-1 vector where @code{@var{n} = rows (@var{A})}
+## 
+## @item disp
+## The level of diagnostic printout (0|1|2).  If @code{disp} is 0 then
+## diagnostics are disabled.  The default value is 0.
+## 
+## @item cholB
+## Flag if @code{chol (@var{B})} is passed rather than @var{B}.  The default is
+## false.
+## 
+## @item permB
+## The permutation vector of the Cholesky@tie{}factorization of @var{B} if
+## @code{cholB} is true.  That is @code{chol (@var{B}(permB, permB))}.  The
+## default is @code{1:@var{n}}.
+## 
+## @end table
+## 
+## It is also possible to represent @var{A} by a function denoted @var{af}.
+## @var{af} must be followed by a scalar argument @var{n} defining the length
+## of the vector argument accepted by @var{af}.  @var{af} can be
+## a function handle, an inline function, or a string.  When @var{af} is a
+## string it holds the name of the function to use.
+## 
+## @var{af} is a function of the form @code{y = af (x)}
+## where the required return value of @var{af} is determined by
+## the value of @var{sigma}.  The four possible forms are
+## 
+## @table @code
+## @item A * x
+## if @var{sigma} is not given or is a string other than "sm".
+## 
+## @item A \ x
+## if @var{sigma} is 0 or "sm".
+## 
+## @item (A - sigma * I) \ x
+## for the standard eigenvalue problem, where @code{I} is the identity matrix of
+## the same size as @var{A}.
+## 
+## @item (A - sigma * B) \ x
+## for the general eigenvalue problem.
+## @end table
+## 
+## The return arguments of @code{eigs} depend on the number of return arguments
+## requested.  With a single return argument, a vector @var{d} of length @var{k}
+## is returned containing the @var{k} eigenvalues that have been found.  With
+## two return arguments, @var{V} is a @var{n}-by-@var{k} matrix whose columns
+## are the @var{k} eigenvectors corresponding to the returned eigenvalues.  The
+## eigenvalues themselves are returned in @var{d} in the form of a
+## @var{n}-by-@var{k} matrix, where the elements on the diagonal are the
+## eigenvalues.
+## 
+## Given a third return argument @var{flag}, @code{eigs} returns the status
+## of the convergence.  If @var{flag} is 0 then all eigenvalues have converged.
+## Any other value indicates a failure to converge.
+## 
+## This function is based on the @sc{arpack} package, written by R. Lehoucq,
+## K. Maschhoff, D. Sorensen, and C. Yang.  For more information see
+## @url{http://www.caam.rice.edu/software/ARPACK/}.
+## 
+## @seealso{eig, svds}
+## @end deftypefn
+
+function varargout = eigs (varargin)
+
+  ## For compatibility with Matlab, handle small matrix cases here
+  ## that ARPACK does not.
+
+  if (nargin == 0)
+    print_usage ();
+  endif
+
+  call_eig = false;
+  offset = 0;
+  k = 6;
+  sigma = "lm";
+
+  if (isnumeric (varargin{1}) && issquare (varargin{1}))
+    a = varargin{1};
+    if (nargin > 1 && isnumeric (varargin{2})
+        && issquare (varargin{2}) && size_equal (a, varargin{2}))
+      b = varargin{2};
+      offset = 1;
+    endif
+
+    if (rows (a) < 9)
+      call_eig = true;
+    endif
+    
+    if (nargin > 1 + offset)
+      tmp = varargin{2+offset};
+      if (isnumeric (tmp) && isscalar (tmp) && isreal (tmp)
+          && round (tmp) == tmp)
+        k = tmp;
+
+        if (rows (a) - k < 3)
+          call_eig = true;
+        endif
+      else
+        call_eig = false;
+      endif
+
+      if (nargin > 2 + offset)
+        tmp = varargin{3+offset};
+        if (ischar (tmp) || (isnumeric (tmp) && isscalar (tmp)))
+          sigma = tmp;
+        else
+          call_eig = false;
+        endif
+      endif
+    endif
+  endif
+
+  if (call_eig)
+    varargout = cell (1, min (2, max (1, nargout)));
+    if (offset)
+      real_valued = isreal (a) && isreal (b);
+      symmetric = issymmetric (a) && issymmetric (b);
+      [varargout{:}] = eig (a, b);
+    else
+      real_valued = isreal (a);
+      symmetric = issymmetric (a);
+      [varargout{:}] = eig (a);
+    endif
+    varargout = select (varargout, k, sigma, real_valued, symmetric);
+    if (nargout == 3)
+      varargout{3} = 0;
+    endif
+  else
+    varargout = cell (1, max (1, nargout));
+    [varargout{:}] = __eigs__ (varargin{:});
+  endif
+
+endfunction
+
+function out = select (args, k, sigma, real_valued, symmetric)
+
+  if (numel (args) == 1)
+    d = args{1};
+  else
+    d = diag (args{2});
+  endif
+
+  if (ischar (sigma))
+    switch (sigma)
+      case "lm"
+        [~, idx] = sort (abs (d), "descend");
+
+      case "sm"
+        [~, idx] = sort (abs (d), "ascend");
+
+      case "la"
+        if (real_valued && symmetric)
+          [~, idx] = sort (real (d), "descend");
+        else
+          error ("sigma = \"la\" requires real symmetric problem");
+        endif
+
+      case "sa"
+        if (real_valued && symmetric)
+          [~, idx] = sort (real (d), "ascend");
+        else
+          error ("sigma = \"sa\" requires real symmetric problem");
+        endif
+
+      case "be"
+        if (real_valued && symmetric)
+          [~, idx] = sort (real (d), "ascend");
+        else
+          error ("sigma = \"be\" requires real symmetric problem");
+        endif
+
+      case "lr"
+        if (! (real_valued || symmetric))
+          [~, idx] = sort (real (d), "descend");
+        else
+          error ("sigma = \"lr\" requires complex or unsymmetric problem");
+        endif
+
+      case "sr"
+        if (! (real_valued || symmetric))
+          [~, idx] = sort (real (d), "ascend");
+        else
+          error ("sigma = \"sr\" requires complex or unsymmetric problem");
+        endif
+
+      case "li"
+        if (! (real_valued || symmetric))
+          [~, idx] = sort (imag (d), "descend");
+        else
+          error ("sigma = \"li\" requires complex or unsymmetric problem");
+        endif
+
+      case "si"
+        if (! (real_valued || symmetric))
+          [~, idx] = sort (imag (d), "ascend");
+        else
+          error ("sigma = \"si\" requires complex or unsymmetric problem");
+        endif
+
+      otherwise
+        error ("unrecognized value for sigma: %s", sigma);
+    endswitch
+  endif
+
+  d = d(idx);
+
+  n = numel (d);
+
+  k = min (k, n);
+
+  if (strcmp (sigma, 'be'))
+    tmp = k / 2;
+    n1 = floor (tmp);
+    n2 = n - ceil (tmp) + 1;
+    selection = [1:floor(k/2), n2:n];
+  else
+    selection = 1:k;
+  endif
+
+  d = d(selection);
+
+  if (numel (args) == 1)
+    out{1} = d;
+  else
+    out{2} = diag (d);
+
+    v = args{1};
+    v = v(:,idx);
+    out{1} = v(selection,:);
+  endif
+
+endfunction
+
+
+#### SPARSE MATRIX VERSIONS ####
+
+## Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]);
+%! d0 = eig (A);
+%! d2 = sort (d0);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); # initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (d1, d0(end:-1:(end-k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "la");
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sa");
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "be");
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, "be");
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (eigs (A, k, 4.1), eigs (A, speye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! AA = speye (10);
+%! fn = @(x) AA * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! assert (eigs (fn, 10, AA, 3, "lm", opts), [1; 1; 1], 10*eps);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "la");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sa");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "be");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+## Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]);
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (d0));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+
+## Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]);
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_CHOLMOD
+%! d1 = eigs (A, speye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, speye (n), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, speye (n)(q,q), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, speye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, speye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK, HAVE_UMFPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*speye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+#### FULL MATRIX VERSIONS ####
+
+## Real positive definite tests, n must be even
+%!shared n, k, A, d0, d2
+%! n = 20;
+%! k = 4;
+%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),4*ones(1,n),ones(1,n-2)]));
+%! d0 = eig (A);
+%! d2 = sort (d0);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (d1, d0(end:-1:(end-k)),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "la");
+%! assert (d1, d2(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sa");
+%! assert (d1, d2(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "be");
+%! assert (d1, d2([1:floor(k/2), (end - ceil(k/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1, "be");
+%! assert (d1, d2([1:floor((k+1)/2), (end - ceil((k+1)/2) + 1):end]), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (d1(idx1), d0(idx0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (eigs (A, k, 4.1), eigs (A, eye (n), k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (d1, d0(end:-1:(end-k+1)), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (d1, d0(k:-1:1), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 1;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (d1, eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "la");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sa");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "be");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+## Real unsymmetric tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A =  full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[ones(1,n-2),1:n,-ones(1,n-2)]));
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (d0));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 1;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+## Complex hermitian tests
+%!shared n, k, A, d0
+%! n = 20;
+%! k = 4;
+%! A = full (sparse ([3:n,1:n,1:(n-2)],[1:(n-2),1:n,3:n],[1i*ones(1,n-2),4*ones(1,n),-1i*ones(1,n-2)]));
+%! d0 = eig (A);
+%! [~, idx] = sort (abs (d0));
+%! d0 = d0(idx);
+%! rand ("state", 42); % initialize generator to make eigs behavior reproducible
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k+1);
+%! assert (abs (d1), abs (d0(end:-1:(end-k))),1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sm");
+%! assert (abs (d1), abs (d0(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "lr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "sr");
+%! [~, idx] = sort (real (abs (d0)));
+%! d2 = d0(idx);
+%! assert (real (d1), real (d2(1:k)), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "li");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(end:-1:(end-k+1)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, "si");
+%! [~, idx] = sort (imag (abs (d0)));
+%! d2 = d0(idx);
+%! assert (sort (imag (d1)), sort (imag (d2(1:k))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, k, 4.1);
+%! [~, idx0] = sort (abs (d0 - 4.1));
+%! [~, idx1] = sort (abs (d1 - 4.1));
+%! assert (abs (d1(idx1)), abs (d0(idx0(1:k))), 1e-11);
+%! assert (sort (imag (d1(idx1))), sort (imag (d0(idx0(1:k)))), 1e-11);
+%!testif HAVE_ARPACK
+%! d1 = eigs (A, eye (n), k, "lm");
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! d1 = eigs (A, eye (n), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! opts.cholB = true;
+%! q = [2:n,1];
+%! opts.permB = q;
+%! d1 = eigs (A, eye (n)(q,q), k, 4.1, opts);
+%! assert (abs (abs (d1)), abs (eigs (A, k, 4.1)), 1e-11);
+%! assert (sort (imag (abs (d1))), sort (imag (eigs (A, k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (abs (eigs (A, k, 4.1)), abs (eigs (A, eye (n), k, 4.1)), 1e-11);
+%!testif HAVE_ARPACK
+%! assert (sort (imag (eigs (A, k, 4.1))), sort (imag (eigs (A, eye (n), k, 4.1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A * x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "lm", opts);
+%! assert (abs (d1), abs (d0(end:-1:(end-k+1))), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) A \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, "sm", opts);
+%! assert (abs (d1), d0(1:k), 1e-11);
+%!testif HAVE_ARPACK
+%! fn = @(x) (A - 4.1 * eye (n)) \ x;
+%! opts.issym = 0;  opts.isreal = 0;
+%! d1 = eigs (fn, n, k, 4.1, opts);
+%! assert (abs (d1), eigs (A, k, 4.1), 1e-11);
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sm");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "lr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "sr");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "li");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+%!testif HAVE_ARPACK
+%! [v1,d1] = eigs (A, k, "si");
+%! d1 = diag (d1);
+%! for i=1:k
+%!   assert (max (abs ((A - d1(i)*eye (n))*v1(:,i))), 0, 1e-11);
+%! endfor
+
+%!assert (eigs (diag (1:5), 5, "sa"), [1;2;3;4;5]);
+%!assert (eigs (diag (1:5), 5, "la"), [5;4;3;2;1]);
+%!assert (eigs (diag (1:5), 3, "be"), [1;4;5]);
+
--- a/scripts/sparse/etreeplot.m
+++ b/scripts/sparse/etreeplot.m
@@ -20,7 +20,7 @@
 ## @deftypefn  {Function File} {} etreeplot (@var{A})
 ## @deftypefnx {Function File} {} etreeplot (@var{A}, @var{node_style}, @var{edge_style})
 ## Plot the elimination tree of the matrix @var{A} or
-## @xcode{@var{A}+@var{A}'} if @var{A} in not symmetric.  The optional
+## @tcode{@var{A}+@var{A}'} if @var{A} in not symmetric.  The optional
 ## parameters @var{node_style} and @var{edge_style} define the output
 ## style.
 ## @seealso{treeplot, gplot}
@@ -34,3 +34,4 @@
 
   treeplot (etree (A+A'), varargin{:});
 endfunction
+
--- a/scripts/sparse/gmres.m
+++ b/scripts/sparse/gmres.m
@@ -234,3 +234,4 @@
 %!error <A must be a function or matrix> gmres ({1},2)
 %!error <M1 must be a function or matrix> gmres (1,2,3,4,5,{6})
 %!error <M2 must be a function or matrix> gmres (1,2,3,4,5,6,{7})
+
--- a/scripts/sparse/module.mk
+++ b/scripts/sparse/module.mk
@@ -8,6 +8,7 @@
   sparse/bicgstab.m \
   sparse/cgs.m \
   sparse/colperm.m \
+  sparse/eigs.m \
   sparse/etreeplot.m \
   sparse/gmres.m \
   sparse/gplot.m \
--- a/scripts/sparse/pcg.m
+++ b/scripts/sparse/pcg.m
@@ -391,101 +391,101 @@
 
 
 %!demo
-%!  # Simplest usage of pcg (see also 'help pcg')
-%! 
-%!  N = 10;
-%!  A = diag ([1:N]); b = rand (N, 1);
-%!  y = A \ b;  # y is the true solution
-%!  x = pcg (A, b);
-%!  printf ("The solution relative error is %g\n", norm (x - y) / norm (y));
-%! 
-%!  # You shouldn't be afraid if pcg issues some warning messages in this
-%!  # example: watch out in the second example, why it takes N iterations
-%!  # of pcg to converge to (a very accurate, by the way) solution
+%! ## Simplest usage of pcg (see also 'help pcg')
+%!
+%! N = 10;
+%! A = diag ([1:N]); b = rand (N, 1);
+%! y = A \ b;  # y is the true solution
+%! x = pcg (A, b);
+%! printf ("The solution relative error is %g\n", norm (x - y) / norm (y));
+%!
+%! ## You shouldn't be afraid if pcg issues some warning messages in this
+%! ## example: watch out in the second example, why it takes N iterations
+%! ## of pcg to converge to (a very accurate, by the way) solution
 
 %!demo
-%!  # Full output from pcg, except for the eigenvalue estimates
-%!  # We use this output to plot the convergence history
-%! 
-%!  N = 10;
-%!  A = diag ([1:N]); b = rand (N, 1);
-%!  X = A \ b;  # X is the true solution
-%!  [x, flag, relres, iter, resvec] = pcg (A, b);
-%!  printf ("The solution relative error is %g\n", norm (x - X) / norm (X));
-%!  title ("Convergence history");
-%!  semilogy ([0:iter], resvec / resvec(1), "o-g");
-%!  xlabel ("Iteration"); ylabel ("log(||b-Ax||/||b||)");
-%!  legend ("relative residual");
+%! ## Full output from pcg, except for the eigenvalue estimates
+%! ## We use this output to plot the convergence history
+%!
+%! N = 10;
+%! A = diag ([1:N]); b = rand (N, 1);
+%! X = A \ b;  # X is the true solution
+%! [x, flag, relres, iter, resvec] = pcg (A, b);
+%! printf ("The solution relative error is %g\n", norm (x - X) / norm (X));
+%! title ("Convergence history");
+%! semilogy ([0:iter], resvec / resvec(1), "o-g");
+%! xlabel ("Iteration"); ylabel ("log(||b-Ax||/||b||)");
+%! legend ("relative residual");
 
 %!demo
-%!  # Full output from pcg, including the eigenvalue estimates
-%!  # Hilbert matrix is extremely ill-conditioned, so pcg WILL have problems
-%! 
-%!  N = 10;
-%!  A = hilb (N); b = rand (N, 1);
-%!  X = A \ b;  # X is the true solution
-%!  [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], 200);
-%!  printf ("The solution relative error is %g\n", norm (x - X) / norm (X));
-%!  printf ("Condition number estimate is %g\n", eigest(2) / eigest(1));
-%!  printf ("Actual condition number is   %g\n", cond (A));
-%!  title ("Convergence history");
-%!  semilogy ([0:iter], resvec, ["o-g";"+-r"]);
-%!  xlabel ("Iteration"); ylabel ("log(||b-Ax||)");
-%!  legend ("absolute residual", "absolute preconditioned residual");
+%! ## Full output from pcg, including the eigenvalue estimates
+%! ## Hilbert matrix is extremely ill-conditioned, so pcg WILL have problems
+%!
+%! N = 10;
+%! A = hilb (N); b = rand (N, 1);
+%! X = A \ b;  # X is the true solution
+%! [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], 200);
+%! printf ("The solution relative error is %g\n", norm (x - X) / norm (X));
+%! printf ("Condition number estimate is %g\n", eigest(2) / eigest(1));
+%! printf ("Actual condition number is   %g\n", cond (A));
+%! title ("Convergence history");
+%! semilogy ([0:iter], resvec, ["o-g";"+-r"]);
+%! xlabel ("Iteration"); ylabel ("log(||b-Ax||)");
+%! legend ("absolute residual", "absolute preconditioned residual");
 
 %!demo
-%!  # Full output from pcg, including the eigenvalue estimates
-%!  # We use the 1-D Laplacian matrix for A, and cond(A) = O(N^2)
-%!  # and that's the reason we need some preconditioner; here we take
-%!  # a very simple and not powerful Jacobi preconditioner,
-%!  # which is the diagonal of A
+%! ## Full output from pcg, including the eigenvalue estimates
+%! ## We use the 1-D Laplacian matrix for A, and cond(A) = O(N^2)
+%! ## and that's the reason we need some preconditioner; here we take
+%! ## a very simple and not powerful Jacobi preconditioner,
+%! ## which is the diagonal of A.
 %!
-%!  N = 100;
-%!  A = zeros (N, N);
-%!  for i = 1 : N - 1 # form 1-D Laplacian matrix
-%!    A(i:i+1, i:i+1) = [2 -1; -1 2];
-%!  endfor
-%!  b = rand (N, 1);
-%!  X = A \ b;  # X is the true solution
-%!  maxit = 80;
-%!  printf ("System condition number is %g\n", cond (A));
-%!  # No preconditioner: the convergence is very slow!
+%! N = 100;
+%! A = zeros (N, N);
+%! for i = 1 : N - 1 # form 1-D Laplacian matrix
+%!   A(i:i+1, i:i+1) = [2 -1; -1 2];
+%! endfor
+%! b = rand (N, 1);
+%! X = A \ b;  # X is the true solution
+%! maxit = 80;
+%! printf ("System condition number is %g\n", cond (A));
+%! ## No preconditioner: the convergence is very slow!
 %!
-%!  [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit);
-%!  printf ("System condition number estimate is %g\n", eigest(2) / eigest(1));
-%!  title ("Convergence history");
-%!  semilogy ([0:iter], resvec(:,1), "o-g");
-%!  xlabel ("Iteration"); ylabel ("log(||b-Ax||)");
-%!  legend ("NO preconditioning: absolute residual");
+%! [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit);
+%! printf ("System condition number estimate is %g\n", eigest(2) / eigest(1));
+%! title ("Convergence history");
+%! semilogy ([0:iter], resvec(:,1), "o-g");
+%! xlabel ("Iteration"); ylabel ("log(||b-Ax||)");
+%! legend ("NO preconditioning: absolute residual");
 %!
-%!  pause (1);
-%!  # Test Jacobi preconditioner: it will not help much!!!
+%! pause (1);
+%! ## Test Jacobi preconditioner: it will not help much!!!
 %!
-%!  M = diag (diag (A)); # Jacobi preconditioner
-%!  [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
-%!  printf ("JACOBI preconditioned system condition number estimate is %g\n", eigest(2) / eigest(1));
-%!  hold on;
-%!  semilogy ([0:iter], resvec(:,1), "o-r");
-%!  legend ("NO preconditioning: absolute residual", ...
-%!          "JACOBI preconditioner: absolute residual");
+%! M = diag (diag (A)); # Jacobi preconditioner
+%! [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
+%! printf ("JACOBI preconditioned system condition number estimate is %g\n", eigest(2) / eigest(1));
+%! hold on;
+%! semilogy ([0:iter], resvec(:,1), "o-r");
+%! legend ("NO preconditioning: absolute residual", ...
+%!         "JACOBI preconditioner: absolute residual");
 %!
-%!  pause (1);
-%!  # Test nonoverlapping block Jacobi preconditioner: it will help much!
+%! pause (1);
+%! ## Test nonoverlapping block Jacobi preconditioner: it will help much!
 %!
-%!  M = zeros (N, N); k = 4;
-%!  for i = 1 : k : N # form 1-D Laplacian matrix
-%!    M(i:i+k-1, i:i+k-1) = A(i:i+k-1, i:i+k-1);
-%!  endfor
-%!  [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
-%!  printf ("BLOCK JACOBI preconditioned system condition number estimate is %g\n", eigest(2) / eigest(1));
-%!  semilogy ([0:iter], resvec(:,1), "o-b");
-%!  legend ("NO preconditioning: absolute residual", ...
-%!          "JACOBI preconditioner: absolute residual", ...
-%!          "BLOCK JACOBI preconditioner: absolute residual");
-%!  hold off;
+%! M = zeros (N, N); k = 4;
+%! for i = 1 : k : N # form 1-D Laplacian matrix
+%!   M(i:i+k-1, i:i+k-1) = A(i:i+k-1, i:i+k-1);
+%! endfor
+%! [x, flag, relres, iter, resvec, eigest] = pcg (A, b, [], maxit, M);
+%! printf ("BLOCK JACOBI preconditioned system condition number estimate is %g\n", eigest(2) / eigest(1));
+%! semilogy ([0:iter], resvec(:,1), "o-b");
+%! legend ("NO preconditioning: absolute residual", ...
+%!         "JACOBI preconditioner: absolute residual", ...
+%!         "BLOCK JACOBI preconditioner: absolute residual");
+%! hold off;
 
 %!test
-%! # solve small diagonal system
+%! ## solve small diagonal system
 %!
 %! N = 10;
 %! A = diag ([1:N]); b = rand (N, 1);
@@ -495,9 +495,9 @@
 %! assert (flag, 0);
 
 %!test
-%! # solve small indefinite diagonal system
-%! # despite A is indefinite, the iteration continues and converges
-%! # indefiniteness of A is detected
+%! ## solve small indefinite diagonal system
+%! ## despite A is indefinite, the iteration continues and converges
+%! ## indefiniteness of A is detected
 %!
 %! N = 10;
 %! A = diag([1:N] .* (-ones(1, N) .^ 2)); b = rand (N, 1);
@@ -507,7 +507,7 @@
 %! assert (flag, 3);
 
 %!test
-%! # solve tridiagonal system, do not converge in default 20 iterations
+%! ## solve tridiagonal system, do not converge in default 20 iterations
 %!
 %! N = 100;
 %! A = zeros (N, N);
@@ -522,9 +522,9 @@
 %! assert (iter, 20); # should perform max allowable default number of iterations
 
 %!test
-%! # solve tridiagonal system with 'perfect' preconditioner
-%! # which converges in one iteration, so the eigest does not
-%! # work and issues a warning
+%! ## solve tridiagonal system with 'perfect' preconditioner
+%! ## which converges in one iteration, so the eigest does not
+%! ## work and issues a warning
 %!
 %! N = 100;
 %! A = zeros (N, N);
--- a/scripts/sparse/pcr.m
+++ b/scripts/sparse/pcr.m
@@ -303,7 +303,7 @@
 
 
 %!demo
-%! # Simplest usage of PCR (see also 'help pcr')
+%! ## Simplest usage of PCR (see also 'help pcr')
 %!
 %! N = 20;
 %! A = diag (linspace (-3.1,3,N)); b = rand (N,1);
@@ -311,13 +311,13 @@
 %! x = pcr (A,b);
 %! printf ("The solution relative error is %g\n", norm (x-y) / norm (y));
 %!
-%! # You shouldn't be afraid if PCR issues some warning messages in this
-%! # example: watch out in the second example, why it takes N iterations
-%! # of PCR to converge to (a very accurate, by the way) solution
+%! ## You shouldn't be afraid if PCR issues some warning messages in this
+%! ## example: watch out in the second example, why it takes N iterations
+%! ## of PCR to converge to (a very accurate, by the way) solution.
 
 %!demo
-%! # Full output from PCR
-%! # We use this output to plot the convergence history
+%! ## Full output from PCR
+%! ## We use this output to plot the convergence history
 %!
 %! N = 20;
 %! A = diag (linspace (-3.1,30,N)); b = rand (N,1);
@@ -330,11 +330,11 @@
 %! semilogy ([0:iter], resvec/resvec(1), "o-g;relative residual;");
 
 %!demo
-%! # Full output from PCR
-%! # We use indefinite matrix based on the Hilbert matrix, with one
-%! # strongly negative eigenvalue
-%! # Hilbert matrix is extremely ill conditioned, so is ours,
-%! # and that's why PCR WILL have problems
+%! ## Full output from PCR
+%! ## We use indefinite matrix based on the Hilbert matrix, with one
+%! ## strongly negative eigenvalue
+%! ## Hilbert matrix is extremely ill conditioned, so is ours,
+%! ## and that's why PCR WILL have problems
 %!
 %! N = 10;
 %! A = hilb (N); A(1,1) = -A(1,1); b = rand (N,1);
@@ -350,14 +350,14 @@
 %! semilogy ([0:iter], resvec, "o-g;absolute residual;");
 
 %!demo
-%! # Full output from PCR
-%! # We use an indefinite matrix based on the 1-D Laplacian matrix for A,
-%! # and here we have cond(A) = O(N^2)
-%! # That's the reason we need some preconditioner; here we take
-%! # a very simple and not powerful Jacobi preconditioner,
-%! # which is the diagonal of A
+%! ## Full output from PCR
+%! ## We use an indefinite matrix based on the 1-D Laplacian matrix for A,
+%! ## and here we have cond(A) = O(N^2)
+%! ## That's the reason we need some preconditioner; here we take
+%! ## a very simple and not powerful Jacobi preconditioner,
+%! ## which is the diagonal of A.
 %!
-%! # Note that we use here indefinite preconditioners!
+%! ## Note that we use here indefinite preconditioners!
 %!
 %! N = 100;
 %! A = zeros (N,N);
@@ -369,7 +369,7 @@
 %! X = A \ b;  # X is the true solution
 %! maxit = 80;
 %! printf ("System condition number is %g\n", cond (A));
-%! # No preconditioner: the convergence is very slow!
+%! ## No preconditioner: the convergence is very slow!
 %!
 %! [x, flag, relres, iter, resvec] = pcr (A,b,[],maxit);
 %! clf;
@@ -378,7 +378,7 @@
 %! semilogy ([0:iter], resvec, "o-g;NO preconditioning: absolute residual;");
 %!
 %! pause (1);
-%! # Test Jacobi preconditioner: it will not help much!!!
+%! ## Test Jacobi preconditioner: it will not help much!!!
 %!
 %! M = diag (diag (A)); # Jacobi preconditioner
 %! [x, flag, relres, iter, resvec] = pcr (A,b,[],maxit,M);
@@ -386,8 +386,8 @@
 %! semilogy ([0:iter],resvec,"o-r;JACOBI preconditioner: absolute residual;");
 %!
 %! pause (1);
-%! # Test nonoverlapping block Jacobi preconditioner: this one should give
-%! # some convergence speedup!
+%! ## Test nonoverlapping block Jacobi preconditioner: this one should give
+%! ## some convergence speedup!
 %!
 %! M = zeros (N,N); k = 4;
 %! for i=1:k:N # get k x k diagonal blocks of A
@@ -399,7 +399,7 @@
 %! hold off;
 
 %!test
-%! # solve small indefinite diagonal system
+%! ## solve small indefinite diagonal system
 %!
 %! N = 10;
 %! A = diag (linspace (-10.1,10,N)); b = ones (N,1);
@@ -409,8 +409,8 @@
 %! assert (flag, 0);
 
 %!test
-%! # solve tridiagonal system, do not converge in default 20 iterations
-%! # should perform max allowable default number of iterations
+%! ## solve tridiagonal system, do not converge in default 20 iterations
+%! ## should perform max allowable default number of iterations
 %!
 %! N = 100;
 %! A = zeros (N,N);
@@ -425,8 +425,8 @@
 %! assert (iter, 20);
 
 %!test
-%! # solve tridiagonal system with "perfect" preconditioner
-%! # converges in one iteration
+%! ## solve tridiagonal system with "perfect" preconditioner
+%! ## converges in one iteration
 %!
 %! N = 100;
 %! A = zeros (N,N);
--- a/scripts/sparse/private/__sprand_impl__.m
+++ b/scripts/sparse/private/__sprand_impl__.m
@@ -75,7 +75,7 @@
     [i, j] = ind2sub ([m, n], idx);
   endif
 
-
   S = sparse (i, j, randfun (k, 1), m, n);
 
 endfunction
+
--- a/scripts/sparse/spdiags.m
+++ b/scripts/sparse/spdiags.m
@@ -91,3 +91,4 @@
 %!assert (spdiags (zeros (1,0),1,1,1), sparse (0))
 %!assert (spdiags (zeros (0,1),1,1,1), sparse (0))
 %!assert (spdiags ([0.5 -1 0.5], 0:2, 1, 1), sparse(0.5))
+
--- a/scripts/sparse/sprandn.m
+++ b/scripts/sparse/sprandn.m
@@ -75,3 +75,4 @@
 %% Test very large, very low density matrix doesn't fail 
 %!test
 %! s = sprandn(1e6,1e6,1e-7);
+
--- a/scripts/sparse/sprandsym.m
+++ b/scripts/sparse/sprandsym.m
@@ -121,7 +121,7 @@
   ## Degenerate case
   if (k == 1)
     r = 1;
-    return
+    return;
   endif
 
   ## Compute the stuff described above
--- a/scripts/sparse/svds.m
+++ b/scripts/sparse/svds.m
@@ -40,13 +40,13 @@
 ## and defaults to 6.
 ##
 ## The argument @var{sigma} specifies which singular values to find.  When
-## @var{sigma} is the string 'L', the default, the largest singular values of
-## @var{A} are found.  Otherwise, @var{sigma} must be a real scalar and the
-## singular values closest to @var{sigma} are found.  As a corollary,
+## @var{sigma} is the string @qcode{'L'}, the default, the largest singular
+## values of @var{A} are found.  Otherwise, @var{sigma} must be a real scalar
+## and the singular values closest to @var{sigma} are found.  As a corollary,
 ## @code{@var{sigma} = 0} finds the smallest singular values.  Note that for
-## relatively small values of @var{sigma}, there is a chance that the requested
-## number of singular values will not be found.  In that case @var{sigma}
-## should be increased.
+## relatively small values of @var{sigma}, there is a chance that the
+## requested number of singular values will not be found.  In that case
+## @var{sigma} should be increased.
 ##
 ## @var{opts} is a structure defining options that @code{svds} will pass
 ## to @code{eigs}.  The possible fields of this structure are documented in
@@ -99,11 +99,11 @@
   endif
 
   if (ndims (A) > 2)
-    error ("svds: A must be a 2D matrix");
+    error ("svds: A must be a 2-D matrix");
   endif
 
   if (nargin < 4)
-    opts.tol = 0;   ## use ARPACK default
+    opts.tol = 0;    # use ARPACK default
     opts.disp = 0;
     opts.maxit = 300;
   else
@@ -111,7 +111,7 @@
       error ("svds: OPTS must be a structure");
     endif
     if (!isfield (opts, "tol"))
-      opts.tol = 0;   ## use ARPACK default
+      opts.tol = 0;  # use ARPACK default
     else
       opts.tol = opts.tol / root2;
     endif
@@ -141,6 +141,9 @@
   if (isempty (max_a))
     max_a = 0;
   endif
+  ## Must initialize variable value, otherwise it may appear to interpreter
+  ## that code is trying to call flag() colormap function.
+  flag = 0;  
 
   if (max_a == 0)
     s = zeros (k, 1);  # special case of zero matrix
--- a/scripts/sparse/treelayout.m
+++ b/scripts/sparse/treelayout.m
@@ -144,7 +144,7 @@
       if (columns (idx) == 1 && top_level == 1)
         s++;
       else
-        # We aren't in top level separator now.
+        ## We aren't in top level separator now.
         top_level = 0;
       endif
       ## If there is not any descendant of "parent node":
--- a/scripts/specfun/bessel.m
+++ b/scripts/specfun/bessel.m
@@ -93,3 +93,4 @@
 
 
 %!error bessel ()
+
--- a/scripts/specfun/betaln.m
+++ b/scripts/specfun/betaln.m
@@ -55,3 +55,4 @@
 %% Test input validation
 %!error (betaln (1))
 %!error (betaln (1,2,3))
+
--- a/scripts/specfun/ellipke.m
+++ b/scripts/specfun/ellipke.m
@@ -19,19 +19,22 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} ellipke (@var{m})
-## @deftypefnx {Function File} {} ellipke (@var{m}, @var{tol})
+## @deftypefn  {Function File} {@var{k} =} ellipke (@var{m})
+## @deftypefnx {Function File} {@var{k} =} ellipke (@var{m}, @var{tol})
 ## @deftypefnx {Function File} {[@var{k}, @var{e}] =} ellipke (@dots{})
-## Compute complete elliptic integral of the first K(@var{m}) and second
+## Compute complete elliptic integrals of the first K(@var{m}) and second
 ## E(@var{m}) kind.
 ##
-## @var{m} is either real array or scalar with 0 @leq{} m @leq{} 1.
+## @var{m} must be a scalar or real array with -Inf @leq{} @var{m} @leq{} 1.
+##
+## The optional input @var{tol} is currently ignored (@sc{matlab} uses this
+## to allow a faster, less accurate approximation).
 ##
-## @var{tol} is currently ignored (@sc{matlab} uses this to allow faster,
-## less accurate approximation).
+## Called with only one output, elliptic integrals of the first kind are
+## returned.
 ##
-## Ref: Abramowitz, Milton and Stegun, Irene A. Handbook of Mathematical
-## Functions, Dover, 1965, Chapter 17.
+## Reference: Milton Abramowitz and Irene A. Stegun,
+## @cite{Handbook of Mathematical Functions}, Chapter 17, Dover, 1965.
 ## @seealso{ellipj}
 ## @end deftypefn
 
@@ -45,73 +48,72 @@
     print_usage ();
   endif
 
-  k = e = zeros (size (m));
   m = m(:);
-  if (any (!isreal (m)))
-    error ("ellipke must have real m");
-  endif
-  if (any (m > 1))
-    error ("ellipke must have m <= 1");
+  if (! isreal (m))
+    error ("ellipke: M must be real");
+  elseif (any (m > 1))
+    error ("ellipke: M must be <= 1");
   endif
 
-  Nmax = 16;
-  idx = find (m == 1);
-  if (!isempty (idx))
-    k(idx) = Inf;
-    e(idx) = 1;
-  endif
+  k = e = zeros (size (m));
 
-  idx = find (m == -Inf);
-  if (!isempty (idx))
-    k(idx) = 0;
-    e(idx) = Inf;
-  endif
+  ## Handle extreme values
+  idx_1 = (m == 1);
+  k(idx_1) = Inf;
+  e(idx_1) = 1;
+
+  idx_neginf = (m == -Inf);
+  k(idx_neginf) = 0;
+  e(idx_neginf) = Inf;
 
   ## Arithmetic-Geometric Mean (AGM) algorithm
   ## ( Abramowitz and Stegun, Section 17.6 )
-  idx = find (m != 1 & m != -Inf);
-  if (!isempty (idx))
-    idx_neg = find (m < 0 & m != -Inf);
+  Nmax = 16;
+  idx = !idx_1 & !idx_neginf;
+  if (any (idx))
+    idx_neg = find (m < 0 & !idx_neginf);
     mult_k = 1./sqrt (1 - m(idx_neg));
     mult_e = sqrt (1 - m(idx_neg));
-    m(idx_neg) = -m(idx_neg)./(1 - m(idx_neg));
-    a = ones (length (idx), 1);
+    m(idx_neg) = -m(idx_neg) ./ (1 - m(idx_neg));
+    a = ones (sum (idx), 1);
     b = sqrt (1 - m(idx));
     c = sqrt (m(idx));
     f = 0.5;
-    sum = f*c.*c;
-    for n = 2:Nmax
+    sum = f*c.^2;
+    n = 2;
+    do
       t = (a + b)/2;
       c = (a - b)/2;
       b = sqrt (a.*b);
       a = t;
-      f = f * 2;
-      sum = sum + f*c.*c;
-      if (all (c./a < eps)) break; endif
-    endfor
-    if (n >= Nmax) error ("ellipke: not enough workspace"); endif
-    k(idx) = 0.5*pi./a;
-    e(idx) = 0.5*pi.*(1 - sum)./a;
-    k(idx_neg) = mult_k.*k(idx_neg);
-    e(idx_neg) = mult_e.*e(idx_neg);
+      f *= 2;
+      sum += f*c.^2;
+    until (all (c./a < eps) || (++n > Nmax))
+    if (n >= Nmax)
+      error ("ellipke: algorithm did not converge in %d iterations", Nmax);
+    endif
+    k(idx) = 0.5*pi ./ a;
+    e(idx) = 0.5*pi*(1 - sum) ./ a;
+    k(idx_neg) = mult_k .* k(idx_neg);
+    e(idx_neg) = mult_e .* e(idx_neg);
   endif
 
 endfunction
 
-%% Test complete elliptic functions of first and second kind
-%% against "exact" solution from Mathematica 3.0
+
+## Test complete elliptic functions of first and second kind
+## against "exact" solution from Mathematica 3.0
 %!test
-%! m = [0.0; 0.01; 0.1; 0.5; 0.9; 0.99; 1.0 ];
+%! m = [0.0; 0.01; 0.1; 0.5; 0.9; 0.99; 1.0];
 %! [k,e] = ellipke (m);
 %!
-%! # K(1.0) is really infinity - see below
 %! k_exp = [1.5707963267948966192;
 %!          1.5747455615173559527;
 %!          1.6124413487202193982;
 %!          1.8540746773013719184;
 %!          2.5780921133481731882;
 %!          3.6956373629898746778;
-%!          0.0 ];
+%!          Inf ];
 %! e_exp = [1.5707963267948966192;
 %!          1.5668619420216682912;
 %!          1.5307576368977632025;
@@ -119,11 +121,10 @@
 %!          1.1047747327040733261;
 %!          1.0159935450252239356;
 %!          1.0 ];
-%! if (k(7)==Inf), k(7)=0; endif;
 %! assert (k, k_exp, 8*eps);
 %! assert (e, e_exp, 8*eps);
 
-%% Test against A&S Table 17.1
+## Test against A&S Table 17.1
 %!test
 %! m = [0:5:50]'/100;
 %! k_exp = [1.570796326794897;
@@ -152,6 +153,26 @@
 %! assert (k, k_exp, 1e-15);
 %! assert (e, e_exp, 1e-8);
 
-%% Test input validation
+## Test negative values against "exact" solution from Mathematica.
+%! m = [-0.01; -1; -5; -100; -1000; -Inf];
+%! [k,e] = ellipke (m);
+%!
+%! k_exp = [1.5668912730681963584;
+%!          1.3110287771460599052;
+%!          0.9555039270640439337;
+%!          0.3682192486091410329;
+%!          0.1530293349884987857;
+%!          0];
+%! e_exp = [1.5747159850169884130;
+%!          1.9100988945138560089;
+%!          2.8301982463458773125;
+%!          10.209260919814572009;
+%!          31.707204053711259719;
+%!          Inf ];
+%! assert (k, k_exp, 8*eps);
+%! assert (e, e_exp, 8*eps (e_exp));
+
+## Test input validation
 %!error ellipke ()
 %!error ellipke (1,2,3)
+
--- a/scripts/specfun/expint.m
+++ b/scripts/specfun/expint.m
@@ -20,24 +20,54 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} expint (@var{x})
-## Compute the exponential integral,
+## Compute the exponential integral:
 ## @tex
 ## $$
-##  E_1 (x) = \int_x^\infty {e^{-t} \over t} dt.
+## {\rm E_1} (x) = \int_x^\infty {e^{-t} \over t} dt
 ## $$
 ## @end tex
 ## @ifnottex
 ##
 ## @example
 ## @group
-##               infinity
-##              /
-## expint (x) = | exp (-t)/t dt
-##              /
-##             x
+##            infinity
+##           /
+## E_1 (x) = | exp (-t)/t dt
+##           /
+##          x
 ## @end group
 ## @end example
+## @end ifnottex
 ##
+## Note: For compatibility, this functions uses the @sc{matlab} definition
+## of the exponential integral.  Most other sources refer to this particular
+## value as @math{E_1 (x)}, and the exponential integral is
+## @tex
+## $$
+## {\rm Ei} (x) = - \int_{-x}^\infty {e^{-t} \over t} dt.
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##             infinity
+##            /
+## Ei (x) = - | exp (-t)/t dt
+##            /
+##          -x
+## @end group
+## @end example
+## @end ifnottex
+##
+## The two definititions are related, for positive real values of @var{x}, by
+## @tex
+## $
+## E_1 (-x) = -{\rm Ei} (x) - i\pi.
+## $
+## @end tex
+## @ifnottex
+## @w{@code{E_1 (-x) = -Ei (x) - i*pi}}.
 ## @end ifnottex
 ## @end deftypefn
 
@@ -47,98 +77,85 @@
     print_usage ();
   endif
 
-  y = expint_E1 (x);
-
-endfunction
+  y = x;  # Copy over all values, including NaNs
 
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{y} =} expint_E1 (@var{x})
-## Compute the exponential integral,
-## @verbatim
-##                    infinity
-##                   /
-##       expint(x) = | exp(-t)/t dt
-##                   /
-##                  x
-## @end verbatim
-## @end deftypefn
-
-function y = expint_E1 (x)
+  if (isreal (x))
+    idx = (x >= 0);
+    y(idx) = -expint_Ei (-x(idx));
 
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  y = x;
-
-  idx = (imag (x) > 0 & imag (x) != 0);
-  y(idx) = -expint_Ei (-y(idx)) - i.*pi;
+    idx = (x < 0);
+    y(idx) = -expint_Ei (-x(idx)) - i*pi;
+  else
+    idx = (imag (x) > 0);
+    y(idx) = -expint_Ei (-x(idx)) - i*pi;
 
-  idx = (imag (x) < 0 & imag (x) != 0);
-  y(idx) = -expint_Ei (-y(idx)) + i.*pi;
+    idx = (imag (x) < 0);
+    y(idx) = -expint_Ei (-x(idx)) + i*pi;
 
-  idx = (real (x) >= 0 & imag (x) == 0);
-  y(idx) = -expint_Ei (-y(idx));
+    isreal_idx = (imag (x) == 0);
+    idx = (isreal_idx & real (x) >= 0);
+    y(idx) = -expint_Ei (-x(idx));
 
-  idx = (real (x) < 0 & imag (x) == 0);
-  y(idx) = -expint_Ei (-y(idx)) - i.*pi;
+    idx = (isreal_idx & real (x) < 0);
+    y(idx) = -expint_Ei (-x(idx)) - i*pi;
+  endif
 
 endfunction
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{y} =} expint_Ei (@var{x})
-## Compute the exponential integral,
+## Compute the exponential integral:
 ## @verbatim
-##                      infinity
-##                     /
-##    expint_Ei(x) = - | exp(t)/t dt
-##                     /
-##                     -x
+##                       infinity
+##                      /
+##    expint_Ei (x) = - | exp(-t)/t dt
+##                      /
+##                    -x
 ## @end verbatim
 ## @end deftypefn
 
 function y = expint_Ei (x)
 
-  if (nargin != 1)
-    print_usage ();
-  endif
-
   y = zeros (size (x));
   F = @(x) exp (-x)./x;
-  s = prod (size (x));
 
-  for t = 1:s;
-    if (x(t) < 0 && imag (x(t)) == 0)
-      y(t) = -quad (F, -x(t), Inf);
+  for t = 1:numel (x)
+    xt = x(t);
+    if (xt < 0 && imag (xt) == 0)
+      ## Direct integration for most real inputs
+      y(t) = -quad (F, -xt, Inf, [0, 1e-10]);
+    elseif (xt > 2 && imag (xt) == 0)
+      persistent Ei_2 = 4.954234356001890;
+      y(t) = Ei_2 - quad (F, -xt, -2);
+    elseif (abs (xt) < 10)
+      ## Series Expansion for real (range [0,2]) or complex inputs (r < 10)
+      k = 1;
+      do
+        term = xt^k / (k*factorial (k));
+        y(t) += term;
+      until (abs (term) < eps (abs (y(t))) / 2 || k++ >= 100)
+      y(t) = 0.57721566490153286 + log (xt) + y(t);
     else
-      if (abs (x(t)) > 2 && imag (x(t)) == 0)
-        y(t) = expint_Ei (2) - quad (F, -x(t), -2);
+      ## FIXME: This expansion is accurate to only 1e-13 at the beginning
+      ##        near 10+i, although it becomes more accurate as the magnitude
+      ##        of xt grows.
+      if (imag (xt) <= 0)
+        persistent a1 = 4.03640;
+        persistent a2 = 1.15198;
+        persistent b1 = 5.03637;
+        persistent b2 = 4.19160;
+        y(t) = -(xt^2 - a1*xt + a2) ...
+               / ((xt^2 - b1*xt + b2) * (-xt) * exp (-xt)) ...
+               - i*pi;
       else
-        if (abs (x(t)) >= 10)
-          if (imag (x(t)) <= 0)
-            a1 = 4.03640;
-            a2 = 1.15198;
-            b1 = 5.03637;
-            b2 = 4.19160;
-            y(t) = -(x(t).^2 - a1.*x(t) + a2) ...
-                   ./ ((x(t).^2 - b1.*x(t) + b2) .* (-x(t)) .* exp (-x(t))) ...
-                   - i.*pi;
-          else
-            y(t) = conj (expint_Ei (conj (x(t))));
-          endif;
-        ## Serie Expansion
-        else
-          for k = 1:100;
-            y(t) = y(t) + x(t).^k ./ (k.*factorial (k));
-          endfor
-          y(t) = 0.577215664901532860606512090082402431 + log (x(t)) + y(t);
-        endif
-      endif
+        y(t) = conj (expint_Ei (conj (xt)));
+      endif;
     endif
   endfor
 endfunction
 
-%% Test against A&S Table 5.1
+
+## Test against A&S Table 5.1
 %!test
 %! x = [5:5:50]'/100;
 %! gamma = 0.5772156649;
@@ -198,6 +215,52 @@
 %! y = expint (x);
 %! assert (y, y_exp, 1e-9);
 
-%% Test input validation
+## Series expansion (-2 < x < 0)
+## Expected values from Mathematica
+%!test  
+%! x = [-0.1; -0.5; -1; -1.5; -2];
+%! y_exp = [ 1.6228128139692767  - i*pi;
+%!          -0.45421990486317358 - i*pi;
+%!          -1.8951178163559368  - i*pi;
+%!          -3.3012854491297978  - i*pi;
+%!          -4.9542343560018902  - i*pi];
+%! y = expint (x);
+%! assert (y, y_exp, eps (real (y_exp)));
+
+## (x < -2, x real)
+%!test  
+%! x = [-2.5; -3; -10;-15; -25];
+%! y_exp = [-7.0737658945786007   - i*pi;
+%!          -9.9338325706254165   - i*pi;
+%!          -2492.2289762418777   - i*pi;
+%!          -234955.85249076830   - i*pi;
+%!          -3.0059509065255486e9 - i*pi];
+%! y = expint (x);
+%! assert (y, y_exp, 8*eps (real (y_exp)));
+
+## Complex values
+%!test
+%! x = [i; -1-i; 10-i; 10+i];
+%! y_exp = [-0.33740392290096813   - i*0.62471325642771360;
+%!          -1.7646259855638540    + i*0.75382280207927082;
+%!          1.90746381979783120e-6 + i*3.67354374003294739e-6;
+%!          1.90746381979783120e-6 - i*3.67354374003294739e-6];
+%! y = expint (x);
+%! assert (y, y_exp, 1e-12);
+
+## Exceptional values (-Inf, Inf, NaN, 0, 0.37250741078)
+%!test  
+%! x = [-Inf; Inf; NaN; 0; -0.3725074107813668];
+%! y_exp = [-Inf - i*pi;
+%!          -Inf;  # should be 0;
+%!          NaN;
+%!          Inf;
+%!          0 - i*pi];
+%! y = expint (x);
+%! assert (y, y_exp, 5*eps);
+
+## Test input validation
 %!error expint ()
 %!error expint (1,2)
+
+
--- a/scripts/specfun/legendre.m
+++ b/scripts/specfun/legendre.m
@@ -22,12 +22,12 @@
 ## @deftypefnx {Function File} {@var{l} =} legendre (@var{n}, @var{x}, @var{normalization})
 ## Compute the Legendre function of degree @var{n} and order
 ## @var{m} = 0 @dots{} N@.  The optional argument, @var{normalization},
-## may be one of @code{"unnorm"}, @code{"sch"}, or @code{"norm"}.
-## The default is @code{"unnorm"}.  The value of @var{n} must be a
+## may be one of @qcode{"unnorm"}, @qcode{"sch"}, or @qcode{"norm"}.
+## The default is @qcode{"unnorm"}.  The value of @var{n} must be a
 ## non-negative scalar integer.
 ##
 ## If the optional argument @var{normalization} is missing or is
-## @code{"unnorm"}, compute the Legendre function of degree @var{n} and
+## @qcode{"unnorm"}, compute the Legendre function of degree @var{n} and
 ## order @var{m} and return all values for @var{m} = 0 @dots{} @var{n}.
 ## The return value has one dimension more than @var{x}.
 ##
@@ -84,7 +84,7 @@
 ## @end group
 ## @end example
 ##
-## If the optional argument @code{normalization} is @code{"sch"},
+## If the optional argument @code{normalization} is @qcode{"sch"},
 ## compute the Schmidt semi-normalized associated Legendre function.
 ## The Schmidt semi-normalized associated Legendre function is related
 ## to the unnormalized Legendre functions by the following:
@@ -127,7 +127,7 @@
 ##
 ## @end ifnottex
 ##
-## If the optional argument @var{normalization} is @code{"norm"},
+## If the optional argument @var{normalization} is @qcode{"norm"},
 ## compute the fully normalized associated Legendre function.
 ## The fully normalized associated Legendre function is related
 ## to the unnormalized Legendre functions by the following:
--- a/scripts/specfun/perms.m
+++ b/scripts/specfun/perms.m
@@ -42,7 +42,7 @@
   if (nargin != 1)
     print_usage ();
   endif
-  vidx = [1:length(v)]';
+  vidx = uint8 ([1:length(v)]');
   n = length (vidx);
 
   if (n == 0)
@@ -51,7 +51,7 @@
     p = vidx(1);
     for j = 2:n
       B = p;
-      p = zeros (prod (2:j), n);
+      p = zeros (prod (2:j), n, "uint8");
       k = rows (B);
       idx = 1:k;
       for i = j:-1:1
--- a/scripts/special-matrix/gallery.m
+++ b/scripts/special-matrix/gallery.m
@@ -162,9 +162,9 @@
 ## (reproducibility) for a given size input and @var{j} index.
 ##
 ## The final optional argument determines the class of the resulting matrix.
-## Possible values for @var{class}: "uint8", "uint16", "uint32", "int8",
-## "int16", int32", "single", "double".
-## The default is "double".
+## Possible values for @var{class}: @qcode{"uint8"}, @qcode{"uint16"},
+## @qcode{"uint32"}, @qcode{"int8"}, @qcode{"int16"}, int32", @qcode{"single"},
+## @qcode{"double"}.  The default is @qcode{"double"}.
 ##
 ## @end deftypefn
 ##
@@ -262,8 +262,8 @@
 ## (reproducibility) for a given size input and @var{j} index.
 ##
 ## The final optional argument determines the class of the resulting matrix.
-## Possible values for @var{class}: "single", "double".
-## The default is "double".
+## Possible values for @var{class}: @qcode{"single"}, @qcode{"double"}.
+## The default is @qcode{"double"}.
 ##
 ## @end deftypefn
 ##
@@ -383,8 +383,8 @@
 ## (reproducibility) for a given size input and @var{j} index.
 ##
 ## The final optional argument determines the class of the resulting matrix.
-## Possible values for @var{class}: "single", "double".
-## The default is "double".
+## Possible values for @var{class}: @qcode{"single"}, @qcode{"double"}.
+## The default is @qcode{"double"}.
 ##
 ## @end deftypefn
 ##
@@ -802,7 +802,7 @@
   if (nargin < 1 || nargin > 2)
     error ("gallery: 1 or 2 arguments are required for compar matrix.");
   elseif (! isnumeric (A) || ndims (A) != 2)
-    error ("gallery: A must be a 2D matrix for compar matrix.");
+    error ("gallery: A must be a 2-D matrix for compar matrix.");
   elseif (! isnumeric (k) || ! isscalar (k))
     error ("gallery: K must be a numeric scalar for compar matrix.");
   endif
@@ -1630,7 +1630,7 @@
   if (nargin < 1 || nargin > 3)
     error ("gallery: 1 to 3 arguments are required for krylov matrix.");
   elseif (! isnumeric (A) || ! issquare (A) || ndims (A) != 2)
-    error ("gallery: A must be a square 2D matrix for krylov matrix.");
+    error ("gallery: A must be a square 2-D matrix for krylov matrix.");
   endif
 
   n = length (A);
@@ -1949,7 +1949,7 @@
       Q(1,2:n) = ones (1, n-1);
       for i = 2:n
         Q(i,i) = -(i-1);
-      end
+      endfor
       Q = diag (sqrt ([n 1:n-1] .* [1:n])) \ Q;
 
     case (5)
@@ -2217,8 +2217,8 @@
   if (p == 1)
     A = randn (m, n);
     A = A / norm (A);
-    return
-  end
+    return;
+  endif
 
   ##  Set up vector sigma of singular values.
   switch (abs (mode))
@@ -2244,7 +2244,7 @@
   ##  Convert to diagonal matrix of singular values.
   if (mode < 0)
     sigma = sigma (p:-1:1);
-  end
+  endif
   sigma = diag (sigma);
 
   if (posdef)
@@ -2252,13 +2252,13 @@
     Q = qmult (p);
     A = Q' * sigma * Q;
     A = (A + A') / 2;  # Ensure matrix is symmetric.
-    return
+    return;
   endif
 
   if (m != n)
     ## Expand to m-by-n diagonal matrix
     sigma(m, n) = 0;
-  end
+  endif
 
   if (kl == 0 && ku == 0)
     ## Diagonal matrix requested - nothing more to do.
@@ -2464,7 +2464,7 @@
     error ("gallery: 1 to 6 arguments are required for toeppen matrix.");
   elseif (! isnumeric (n) || ! isscalar (n) || fix (n) != n)
     error ("gallery: N must be a numeric integer for toeppen matrix.");
-  elseif (any (cellfun (@(x) ! isnumeric (x) || ! isscalar (x), {a b c d e})))
+  elseif (any (! cellfun ("isnumeric", {a b c d e})) || any (cellfun ("numel", {a b c d e}) != 1))
     error ("gallery: A, B, C, D and E must be numeric scalars for toeppen matrix.");
   endif
 
@@ -2852,3 +2852,4 @@
     A = A';
   endif
 endfunction
+
--- a/scripts/special-matrix/toeplitz.m
+++ b/scripts/special-matrix/toeplitz.m
@@ -96,8 +96,8 @@
   endif
 
   if (issparse (c) && issparse (r))
-    c = c(:).';  ## enforce row vector
-    r = r(:).';  ## enforce row vector
+    c = c(:).';  # enforce row vector
+    r = r(:).';  # enforce row vector
     cidx = find (c);
     ridx = find (r);
 
--- a/scripts/startup/__finish__.m
+++ b/scripts/startup/__finish__.m
@@ -40,3 +40,4 @@
 
 ## No test needed for internal helper function.
 %!assert (1)
+
--- a/scripts/statistics/base/mean.m
+++ b/scripts/statistics/base/mean.m
@@ -39,13 +39,13 @@
 ## The following options are recognized:
 ##
 ## @table @asis
-## @item "a"
+## @item @qcode{"a"}
 ## Compute the (ordinary) arithmetic mean.  [default]
 ##
-## @item "g"
+## @item @qcode{"g"}
 ## Compute the geometric mean.
 ##
-## @item "h"
+## @item @qcode{"h"}
 ## Compute the harmonic mean.
 ## @end table
 ##
--- a/scripts/statistics/base/moment.m
+++ b/scripts/statistics/base/moment.m
@@ -45,7 +45,7 @@
 ## Valid options are:
 ##
 ## @table @asis
-## @item "c"
+## @item @qcode{"c"}
 ##   Central Moment.  The moment about the mean defined as
 ## @tex
 ## $$
@@ -62,7 +62,7 @@
 ##
 ## @end ifnottex
 ##
-## @item "a"
+## @item @qcode{"a"}
 ##   Absolute Moment.  The moment about zero ignoring sign defined as
 ## @tex
 ## $$
@@ -79,7 +79,7 @@
 ##
 ## @end ifnottex
 ##
-## @item "ac"
+## @item @qcode{"ac"}
 ##   Absolute Central Moment.  Defined as
 ## @tex
 ## $$
--- a/scripts/statistics/base/qqplot.m
+++ b/scripts/statistics/base/qqplot.m
@@ -97,3 +97,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/distributions/geocdf.m
+++ b/scripts/statistics/distributions/geocdf.m
@@ -21,6 +21,9 @@
 ## @deftypefn {Function File} {} geocdf (@var{x}, @var{p})
 ## For each element of @var{x}, compute the cumulative distribution function
 ## (CDF) at @var{x} of the geometric distribution with parameter @var{p}.
+##
+## The geometric distribution models the number of failures (@var{x}-1) of a
+## Bernoulli trial with probability @var{p} before the first success (@var{x}).
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/statistics/distributions/geoinv.m
+++ b/scripts/statistics/distributions/geoinv.m
@@ -21,6 +21,9 @@
 ## @deftypefn {Function File} {} geoinv (@var{x}, @var{p})
 ## For each element of @var{x}, compute the quantile (the inverse of
 ## the CDF) at @var{x} of the geometric distribution with parameter @var{p}.
+##
+## The geometric distribution models the number of failures (@var{x}-1) of a
+## Bernoulli trial with probability @var{p} before the first success (@var{x}).
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/statistics/distributions/geopdf.m
+++ b/scripts/statistics/distributions/geopdf.m
@@ -21,6 +21,9 @@
 ## @deftypefn {Function File} {} geopdf (@var{x}, @var{p})
 ## For each element of @var{x}, compute the probability density function
 ## (PDF) at @var{x} of the geometric distribution with parameter @var{p}.
+##
+## The geometric distribution models the number of failures (@var{x}-1) of a
+## Bernoulli trial with probability @var{p} before the first success (@var{x}).
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/statistics/distributions/geornd.m
+++ b/scripts/statistics/distributions/geornd.m
@@ -33,6 +33,9 @@
 ## 
 ## If no size arguments are given then the result matrix is the size of
 ## @var{p}.
+##
+## The geometric distribution models the number of failures (@var{x}-1) of a
+## Bernoulli trial with probability @var{p} before the first success (@var{x}).
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/statistics/distributions/tcdf.m
+++ b/scripts/statistics/distributions/tcdf.m
@@ -1,3 +1,4 @@
+## Copyright (C) 2013 Julien Bect
 ## Copyright (C) 2012 Rik Wehbring
 ## Copyright (C) 1995-2012 Kurt Hornik
 ##
@@ -51,11 +52,26 @@
   endif
 
   k = !isinf (x) & (n > 0);
+
+  xx = x .^ 2;
+  x_big_abs = (xx > n);
+
+  ## deal with the case "abs(x) big"
+  kk = k & x_big_abs;
   if (isscalar (n))
-    cdf(k) = betainc (1 ./ (1 + x(k) .^ 2 / n), n/2, 1/2) / 2;
+    cdf(kk) = betainc (n ./ (n + xx(kk)), n/2, 1/2) / 2;
   else
-    cdf(k) = betainc (1 ./ (1 + x(k) .^ 2 ./ n(k)), n(k)/2, 1/2) / 2;
+    cdf(kk) = betainc (n(kk) ./ (n(kk) + xx(kk)), n(kk)/2, 1/2) / 2;
   endif
+
+  ## deal with the case "abs(x) small"
+  kk = k & !x_big_abs;
+  if (isscalar (n))
+    cdf(kk) = 0.5 * (1 - betainc (xx(kk) ./ (n + xx(kk)), 1/2, n/2));
+  else
+    cdf(kk) = 0.5 * (1 - betainc (xx(kk) ./ (n(kk) + xx(kk)), 1/2, n(kk)/2));
+  endif
+
   k &= (x > 0);
   if (any (k(:)))
     cdf(k) = 1 - cdf(k);
@@ -92,3 +108,53 @@
 %!error tcdf (i, 2)
 %!error tcdf (2, i)
 
+## Check some reference values
+
+%!shared tol_rel
+%! tol_rel = 10 * eps;
+
+## check accuracy for small positive values
+%!assert (tcdf (10^(-10), 2.5), 0.50000000003618087, -tol_rel)
+%!assert (tcdf (10^(-11), 2.5), 0.50000000000361809, -tol_rel)
+%!assert (tcdf (10^(-12), 2.5), 0.50000000000036181, -tol_rel)
+%!assert (tcdf (10^(-13), 2.5), 0.50000000000003618, -tol_rel)
+%!assert (tcdf (10^(-14), 2.5), 0.50000000000000362, -tol_rel)
+%!assert (tcdf (10^(-15), 2.5), 0.50000000000000036, -tol_rel)
+%!assert (tcdf (10^(-16), 2.5), 0.50000000000000004, -tol_rel)
+
+## check accuracy for large negative values
+%!assert (tcdf (-10^1, 2.5), 2.2207478836537124e-03, -tol_rel)
+%!assert (tcdf (-10^2, 2.5), 7.1916492116661878e-06, -tol_rel)
+%!assert (tcdf (-10^3, 2.5), 2.2747463948307452e-08, -tol_rel)
+%!assert (tcdf (-10^4, 2.5), 7.1933970159922115e-11, -tol_rel)
+%!assert (tcdf (-10^5, 2.5), 2.2747519231756221e-13, -tol_rel)
+
+## # Reference values obtained using Python 2.7.4 and mpmath 0.17
+##
+## from mpmath import *
+##
+## mp.dps = 100
+##
+## def F(x_in, nu_in):
+##     x = mpf(x_in);
+##     nu = mpf(nu_in);
+##     t = nu / (nu + x*x)
+##     a = nu / 2
+##     b = mpf(0.5)
+##     F = betainc(a, b, 0, t, regularized=True) / 2
+##     if (x > 0):
+##         F = 1 - F
+##     return F
+##
+## nu = 2.5
+##
+## for i in range(1, 6):
+##     x = - power(mpf(10), mpf(i))
+##     print "%%!assert (tcdf (-10^%d, 2.5), %s, -eps)" \
+##         % (i, nstr(F(x, nu), 17))
+##
+## for i in range(10, 17):
+##     x = power(mpf(10), -mpf(i))
+##     print "%%!assert (tcdf (10^(-%d), 2.5), %s, -eps)" \
+##         % (i, nstr(F(x, nu), 17))
+
--- a/scripts/statistics/distributions/wienrnd.m
+++ b/scripts/statistics/distributions/wienrnd.m
@@ -52,3 +52,4 @@
   retval = [((1: n*t)' / n), retval];
 
 endfunction
+
--- a/scripts/statistics/models/logistic_regression.m
+++ b/scripts/statistics/models/logistic_regression.m
@@ -190,3 +190,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/models/private/logistic_regression_derivatives.m
+++ b/scripts/statistics/models/private/logistic_regression_derivatives.m
@@ -30,10 +30,6 @@
 
 function [dl, d2l] = logistic_regression_derivatives (x, z, z1, g, g1, p)
 
-  if (nargin != 6)
-    print_usage ();
-  endif
-
   ## first derivative
   v = g .* (1 - g) ./ p; v1 = g1 .* (1 - g1) ./ p;
   dlogp = [(diag (v) * z - diag (v1) * z1), (diag (v - v1) * x)];
@@ -45,3 +41,4 @@
       - dlogp' * dlogp;
 
 endfunction
+
--- a/scripts/statistics/models/private/logistic_regression_likelihood.m
+++ b/scripts/statistics/models/private/logistic_regression_likelihood.m
@@ -29,10 +29,6 @@
 
 function [g, g1, p, dev] = logistic_regression_likelihood (y, x, beta, z, z1)
 
-  if (nargin != 5)
-    print_usage ();
-  endif
-
   e = exp ([z, x] * beta); e1 = exp ([z1, x] * beta);
   g = e ./ (1 + e); g1 = e1 ./ (1 + e1);
   g = max (y == max (y), g); g1 = min (y > min (y), g1);
@@ -41,3 +37,4 @@
   dev = -2 * sum (log (p));
 
 endfunction
+
--- a/scripts/statistics/tests/anova.m
+++ b/scripts/statistics/tests/anova.m
@@ -108,3 +108,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/bartlett_test.m
+++ b/scripts/statistics/tests/bartlett_test.m
@@ -65,3 +65,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/chisquare_test_homogeneity.m
+++ b/scripts/statistics/tests/chisquare_test_homogeneity.m
@@ -66,3 +66,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/chisquare_test_independence.m
+++ b/scripts/statistics/tests/chisquare_test_independence.m
@@ -51,3 +51,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/cor_test.m
+++ b/scripts/statistics/tests/cor_test.m
@@ -22,18 +22,18 @@
 ## populations.
 ##
 ## The optional argument string @var{alt} describes the alternative
-## hypothesis, and can be @code{"!="} or @code{"<>"} (non-zero),
-## @code{">"} (greater than 0), or @code{"<"} (less than 0).  The
+## hypothesis, and can be @qcode{"!="} or @qcode{"<>"} (non-zero),
+## @qcode{">"} (greater than 0), or @qcode{"<"} (less than 0).  The
 ## default is the two-sided case.
 ##
 ## The optional argument string @var{method} specifies which
 ## correlation coefficient to use for testing.  If @var{method} is
-## @code{"pearson"} (default), the (usual) Pearson's product moment
+## @qcode{"pearson"} (default), the (usual) Pearson's product moment
 ## correlation coefficient is used.  In this case, the data should come
 ## from a bivariate normal distribution.  Otherwise, the other two
 ## methods offer nonparametric alternatives.  If @var{method} is
-## @code{"kendall"}, then Kendall's rank correlation tau is used.  If
-## @var{method} is @code{"spearman"}, then Spearman's rank correlation
+## @qcode{"kendall"}, then Kendall's rank correlation tau is used.  If
+## @var{method} is @qcode{"spearman"}, then Spearman's rank correlation
 ## rho is used.  Only the first character is necessary.
 ##
 ## The output is a structure with the following elements:
@@ -133,3 +133,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/f_test_regression.m
+++ b/scripts/statistics/tests/f_test_regression.m
@@ -75,3 +75,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/hotelling_test.m
+++ b/scripts/statistics/tests/hotelling_test.m
@@ -70,3 +70,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/hotelling_test_2.m
+++ b/scripts/statistics/tests/hotelling_test_2.m
@@ -84,3 +84,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/kolmogorov_smirnov_test.m
+++ b/scripts/statistics/tests/kolmogorov_smirnov_test.m
@@ -36,11 +36,11 @@
 ## that calculates the CDF of distribution @var{dist} exists.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative F
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative F
 ## != G@.  In this case, the test statistic @var{ks} follows a two-sided
-## Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
-## one-sided alternative F > G is considered.  Similarly for @code{"<"},
+## Kolmogorov-Smirnov distribution.  If @var{alt} is @qcode{">"}, the
+## one-sided alternative F > G is considered.  Similarly for @qcode{"<"},
 ## the one-sided alternative F > G is considered.  In this case, the
 ## test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
 ## distribution.  The default is the two-sided case.
@@ -121,7 +121,7 @@
 %!error kolmogorov_smirnov_test (1)
 %!error <X must be a vector> kolmogorov_smirnov_test ({}, "unif", 2, 4)
 %!error <no not_a_distcdf or not_a_dist_cdf function found>
-%!  kolmogorov_smirnov_test (1, "not_a_dist");
+%! kolmogorov_smirnov_test (1, "not_a_dist");
 %!error <alternative foo not recognized>
-%!  kolmogorov_smirnov_test (1, "unif", 2, 4, "foo");
+%! kolmogorov_smirnov_test (1, "unif", 2, 4, "foo");
 
--- a/scripts/statistics/tests/kolmogorov_smirnov_test_2.m
+++ b/scripts/statistics/tests/kolmogorov_smirnov_test_2.m
@@ -25,11 +25,11 @@
 ## G.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative F
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative F
 ## != G@.  In this case, the test statistic @var{ks} follows a two-sided
-## Kolmogorov-Smirnov distribution.  If @var{alt} is @code{">"}, the
-## one-sided alternative F > G is considered.  Similarly for @code{"<"},
+## Kolmogorov-Smirnov distribution.  If @var{alt} is @qcode{">"}, the
+## one-sided alternative F > G is considered.  Similarly for @qcode{"<"},
 ## the one-sided alternative F < G is considered.  In this case, the
 ## test statistic @var{ks} has a one-sided Kolmogorov-Smirnov
 ## distribution.  The default is the two-sided case.
@@ -102,3 +102,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/kruskal_wallis_test.m
+++ b/scripts/statistics/tests/kruskal_wallis_test.m
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {[@var{pval}, @var{k}, @var{df}] =} kruskal_wallis_test (@var{x1}, @dots{})
-## Perform a Kruskal-Wallis one-factor "analysis of variance".
+## Perform a Kruskal-Wallis one-factor analysis of variance.
 ##
 ## Suppose a variable is observed for @var{k} > 1 different groups, and
 ## let @var{x1}, @dots{}, @var{xk} be the corresponding data vectors.
@@ -36,9 +36,10 @@
 ## where @var{sum_ties} is the sum of @var{t}^2 - @var{t} over each group
 ## of ties where @var{t} is the number of ties in the group and @var{n}
 ## is the total number of values in the input data.  For more info on
-## this adjustment see "Use of Ranks in One-Criterion Variance Analysis"
-## in Journal of the American Statistical Association, Vol. 47,
-## No. 260 (Dec 1952) by William H. Kruskal and W. Allen Wallis.
+## this adjustment see William H. Kruskal and W. Allen Wallis,
+## @cite{Use of Ranks in One-Criterion Variance Analysis}, 
+## Journal of the American Statistical Association, Vol. 47,
+## No. 260 (Dec 1952).
 ##
 ## The p-value (1 minus the CDF of this distribution at @var{k}) is
 ## returned in @var{pval}.
@@ -97,3 +98,4 @@
 
 ## Test with ties
 %!assert (abs (kruskal_wallis_test ([86 86], [74]) - 0.157299207050285) < 0.0000000000001)
+
--- a/scripts/statistics/tests/manova.m
+++ b/scripts/statistics/tests/manova.m
@@ -159,3 +159,4 @@
   printf ("\n");
 
 endfunction
+
--- a/scripts/statistics/tests/mcnemar_test.m
+++ b/scripts/statistics/tests/mcnemar_test.m
@@ -63,5 +63,3 @@
 
 endfunction
 
-
-
--- a/scripts/statistics/tests/prop_test_2.m
+++ b/scripts/statistics/tests/prop_test_2.m
@@ -25,10 +25,10 @@
 ## approximately follows a standard normal distribution.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @var{p1} != @var{p2}.  If @var{alt} is @code{">"}, the one-sided
-## alternative @var{p1} > @var{p2} is used.  Similarly for @code{"<"},
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @var{p1} != @var{p2}.  If @var{alt} is @qcode{">"}, the one-sided
+## alternative @var{p1} > @var{p2} is used.  Similarly for @qcode{"<"},
 ## the one-sided alternative @var{p1} < @var{p2} is used.
 ## The default is the two-sided case.
 ##
@@ -78,3 +78,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/run_test.m
+++ b/scripts/statistics/tests/run_test.m
@@ -56,3 +56,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/sign_test.m
+++ b/scripts/statistics/tests/sign_test.m
@@ -25,12 +25,12 @@
 ## (@var{x} != @var{y})} and @var{p} = 1/2.
 ##
 ## With the optional argument @code{alt}, the alternative of interest
-## can be selected.  If @var{alt} is @code{"!="} or @code{"<>"}, the
+## can be selected.  If @var{alt} is @qcode{"!="} or @qcode{"<>"}, the
 ## null hypothesis is tested against the two-sided alternative PROB
-## (@var{x} < @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+## (@var{x} < @var{y}) != 1/2.  If @var{alt} is @qcode{">"}, the
 ## one-sided alternative PROB (@var{x} > @var{y}) > 1/2 ("x is
 ## stochastically greater than y") is considered.  Similarly for
-## @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) < 1/2
+## @qcode{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) < 1/2
 ## ("x is stochastically less than y") is considered.  The default is
 ## the two-sided case.
 ##
@@ -81,3 +81,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/t_test.m
+++ b/scripts/statistics/tests/t_test.m
@@ -25,9 +25,9 @@
 ## - 1} degrees of freedom.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @qcode{">"}, the
 ## one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
 ## Similarly for @var{"<"}, the one-sided alternative @code{mean
 ## (@var{x}) < @var{m}} is considered.  The default is the two-sided
@@ -81,3 +81,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/t_test_2.m
+++ b/scripts/statistics/tests/t_test_2.m
@@ -25,11 +25,11 @@
 ## freedom.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{mean (@var{x}) != mean (@var{y})}.  If @var{alt} is @code{">"},
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != mean (@var{y})}.  If @var{alt} is @qcode{">"},
 ## the one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is
-## used.  Similarly for @code{"<"}, the one-sided alternative @code{mean
+## used.  Similarly for @qcode{"<"}, the one-sided alternative @code{mean
 ## (@var{x}) < mean (@var{y})} is used.  The default is the two-sided
 ## case.
 ##
@@ -82,3 +82,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/t_test_regression.m
+++ b/scripts/statistics/tests/t_test_regression.m
@@ -27,9 +27,9 @@
 ## If @var{r} is omitted, a value of 0 is assumed.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @nospell{@code{@var{rr} * @var{b} != @var{r}}}.  If @var{alt} is @code{">"},
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @nospell{@code{@var{rr} * @var{b} != @var{r}}}.  If @var{alt} is @qcode{">"},
 ## the one-sided alternative
 ## @nospell{@code{@var{rr} * @var{b} > @var{r}}} is used.  Similarly for
 ## @var{"<"}, the one-sided alternative
@@ -97,3 +97,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/u_test.m
+++ b/scripts/statistics/tests/u_test.m
@@ -25,11 +25,11 @@
 ## equivalent to the Wilcoxon rank-sum test.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## PROB (@var{x} > @var{y}) != 1/2.  If @var{alt} is @code{">"}, the
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## PROB (@var{x} > @var{y}) != 1/2.  If @var{alt} is @qcode{">"}, the
 ## one-sided alternative PROB (@var{x} > @var{y}) > 1/2 is considered.
-## Similarly for @code{"<"}, the one-sided alternative PROB (@var{x} >
+## Similarly for @qcode{"<"}, the one-sided alternative PROB (@var{x} >
 ## @var{y}) < 1/2 is considered.  The default is the two-sided case.
 ##
 ## The p-value of the test is returned in @var{pval}.
@@ -83,3 +83,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/var_test.m
+++ b/scripts/statistics/tests/var_test.m
@@ -25,9 +25,9 @@
 ## degrees of freedom.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{var (@var{x}) != var (@var{y})}.  If @var{alt} is @code{">"},
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{var (@var{x}) != var (@var{y})}.  If @var{alt} is @qcode{">"},
 ## the one-sided alternative @code{var (@var{x}) > var (@var{y})} is
 ## used.  Similarly for "<", the one-sided alternative @code{var
 ## (@var{x}) > var (@var{y})} is used.  The default is the two-sided
@@ -78,3 +78,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/welch_test.m
+++ b/scripts/statistics/tests/welch_test.m
@@ -25,11 +25,11 @@
 ## Student distribution with @var{df} degrees of freedom.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @qcode{">"}, the
 ## one-sided alternative mean(x) > @var{m} is considered.  Similarly for
-## @code{"<"}, the one-sided alternative mean(x) < @var{m} is
+## @qcode{"<"}, the one-sided alternative mean(x) < @var{m} is
 ## considered.  The default is the two-sided case.
 ##
 ## The p-value of the test is returned in @var{pval}.
@@ -83,3 +83,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/wilcoxon_test.m
+++ b/scripts/statistics/tests/wilcoxon_test.m
@@ -27,11 +27,11 @@
 ## and thus is invalid for @var{n} @leq{} 25.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## PROB (@var{x} > @var{y}) != 1/2.  If alt is @code{">"}, the one-sided
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## PROB (@var{x} > @var{y}) != 1/2.  If alt is @qcode{">"}, the one-sided
 ## alternative PROB (@var{x} > @var{y}) > 1/2 is considered.  Similarly
-## for @code{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) <
+## for @qcode{"<"}, the one-sided alternative PROB (@var{x} > @var{y}) <
 ## 1/2 is considered.  The default is the two-sided case.
 ##
 ## The p-value of the test is returned in @var{pval}.
@@ -89,3 +89,4 @@
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/z_test.m
+++ b/scripts/statistics/tests/z_test.m
@@ -24,11 +24,11 @@
 ## @var{z} follows a standard normal distribution.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @code{">"}, the
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != @var{m}}.  If @var{alt} is @qcode{">"}, the
 ## one-sided alternative @code{mean (@var{x}) > @var{m}} is considered.
-## Similarly for @code{"<"}, the one-sided alternative @code{mean
+## Similarly for @qcode{"<"}, the one-sided alternative @code{mean
 ## (@var{x}) < @var{m}} is considered.  The default is the two-sided
 ## case.
 ##
@@ -78,10 +78,11 @@
   endif
 
   if (nargout == 0)
-    s = ["Z-test of mean(x) == %g against mean(x) %s %g,\n", \
-         "with known var(x) == %g:\n",                       \
-         "  pval = %g\n");
+    s = ["Z-test of mean(x) == %g against mean(x) %s %g,\n", ...
+         "with known var(x) == %g:\n",                       ...
+         "  pval = %g\n"];
     printf (s, m, alt, m, v, pval);
   endif
 
 endfunction
+
--- a/scripts/statistics/tests/z_test_2.m
+++ b/scripts/statistics/tests/z_test_2.m
@@ -24,11 +24,11 @@
 ## statistic @var{z} follows a standard normal distribution.
 ##
 ## With the optional argument string @var{alt}, the alternative of
-## interest can be selected.  If @var{alt} is @code{"!="} or
-## @code{"<>"}, the null is tested against the two-sided alternative
-## @code{mean (@var{x}) != mean (@var{y})}.  If alt is @code{">"}, the
+## interest can be selected.  If @var{alt} is @qcode{"!="} or
+## @qcode{"<>"}, the null is tested against the two-sided alternative
+## @code{mean (@var{x}) != mean (@var{y})}.  If alt is @qcode{">"}, the
 ## one-sided alternative @code{mean (@var{x}) > mean (@var{y})} is used.
-## Similarly for @code{"<"}, the one-sided alternative @code{mean
+## Similarly for @qcode{"<"}, the one-sided alternative @code{mean
 ## (@var{x}) < mean (@var{y})} is used.  The default is the two-sided
 ## case.
 ##
@@ -78,11 +78,12 @@
   endif
 
   if (nargout == 0)
-    s = ["Two-sample Z-test of mean(x) == mean(y) against ", \
-         "mean(x) %s mean(y),\n",                            \
-         "with known var(x) == %g and var(y) == %g:\n",      \
+    s = ["Two-sample Z-test of mean(x) == mean(y) against ", ...
+         "mean(x) %s mean(y),\n",                            ...
+         "with known var(x) == %g and var(y) == %g:\n",      ...
          "  pval = %g\n"];
     printf (s, alt, v_x, v_y, pval);
   endif
 
 endfunction
+
--- a/scripts/strings/base2dec.m
+++ b/scripts/strings/base2dec.m
@@ -30,7 +30,7 @@
 ##
 ## If @var{s} is a string matrix, return a column vector with one value per
 ## row of @var{s}.  If a row contains invalid symbols then the
-## corresponding value will be NaN@.  
+## corresponding value will be NaN@.
 ##
 ## If @var{s} is a cell array of strings, return a column vector with one
 ## value per cell element in @var{s}.
--- a/scripts/strings/dec2base.m
+++ b/scripts/strings/dec2base.m
@@ -62,7 +62,7 @@
     d = cell2mat (d);
   endif
 
-  # Create column vector for algorithm
+  ## Create column vector for algorithm
   if (! iscolumn (d))
     d = d(:);
   endif
--- a/scripts/strings/index.m
+++ b/scripts/strings/index.m
@@ -32,8 +32,8 @@
 ## @end group
 ## @end example
 ##
-## If @var{direction} is @samp{"first"}, return the first element found.
-## If @var{direction} is @samp{"last"}, return the last element found.
+## If @var{direction} is @qcode{"first"}, return the first element found.
+## If @var{direction} is @qcode{"last"}, return the last element found.
 ##
 ## @seealso{find, rindex}
 ## @end deftypefn
--- a/scripts/strings/isstrprop.m
+++ b/scripts/strings/isstrprop.m
@@ -35,45 +35,45 @@
 ## The second argument @var{prop} must be one of
 ##
 ## @table @asis
-## @item "alpha"
+## @item @qcode{"alpha"}
 ## True for characters that are alphabetic (letters).
 ##
-## @item "alnum"
-## @itemx "alphanum"
+## @item  @qcode{"alnum"}
+## @itemx @qcode{"alphanum"}
 ## True for characters that are alphabetic or digits.
 ##
-## @item "lower"
+## @item @qcode{"lower"}
 ## True for lowercase letters.
 ##
-## @item "upper"
+## @item @qcode{"upper"}
 ## True for uppercase letters.
 ##
-## @item "digit"
+## @item @qcode{"digit"}
 ## True for decimal digits (0-9).
 ##
-## @item "xdigit"
+## @item @qcode{"xdigit"}
 ## True for hexadecimal digits (@nospell{a-fA-F0-9}).
 ##
-## @item "space"
-## @itemx "wspace"
+## @item  @qcode{"space"}
+## @itemx @qcode{"wspace"}
 ## True for whitespace characters (space, formfeed, newline, carriage
 ## return, tab, vertical tab).
 ##
-## @item "punct"
+## @item @qcode{"punct"}
 ## True for punctuation characters (printing characters except space
 ## or letter or digit).
 ##
-## @item "cntrl"
+## @item @qcode{"cntrl"}
 ## True for control characters.
 ##
-## @item "graph"
-## @itemx "graphic"
+## @item  @qcode{"graph"}
+## @itemx @qcode{"graphic"}
 ## True for printing characters except space.
 ##
-## @item "print"
+## @item @qcode{"print"}
 ## True for printing characters including space.
 ##
-## @item "ascii"
+## @item @qcode{"ascii"}
 ## True for characters that are in the range of ASCII encoding.
 ##
 ## @end table
--- a/scripts/strings/mat2str.m
+++ b/scripts/strings/mat2str.m
@@ -29,7 +29,7 @@
 ## precision of the real part and @code{@var{n}(2)} defines the
 ## precision of the imaginary part.  The default for @var{n} is 15.
 ##
-## If the argument "class" is given then the class of @var{x} is
+## If the argument @qcode{"class"} is given then the class of @var{x} is
 ## included in the string in such a way that @code{eval} will result in the
 ## construction of a matrix of the same class.
 ##
--- a/scripts/strings/regexptranslate.m
+++ b/scripts/strings/regexptranslate.m
@@ -24,7 +24,7 @@
 ## values
 ##
 ## @table @asis
-## @item "wildcard"
+## @item @qcode{"wildcard"}
 ## The wildcard characters @code{.}, @code{*}, and @code{?} are replaced
 ## with wildcards that are appropriate for a regular expression.
 ## For example:
@@ -36,7 +36,7 @@
 ## @end group
 ## @end example
 ##
-## @item "escape"
+## @item @qcode{"escape"}
 ## The characters @code{$.?[]}, that have special meaning for regular
 ## expressions are escaped so that they are treated literally.  For example:
 ##
--- a/scripts/strings/rindex.m
+++ b/scripts/strings/rindex.m
@@ -32,7 +32,7 @@
 ## @end example
 ##
 ## The @code{rindex} function is equivalent to @code{index} with
-## @var{direction} set to @samp{"last"}.
+## @var{direction} set to @qcode{"last"}.
 ##
 ## @seealso{find, index}
 ## @end deftypefn
--- a/scripts/strings/str2num.m
+++ b/scripts/strings/str2num.m
@@ -42,7 +42,7 @@
 ## in the string @var{s}.  Use @code{str2double} for a safer and faster
 ## conversion.
 ##
-## For cell array of strings use @code{str2double}.  
+## For cell array of strings use @code{str2double}.
 ## @seealso{str2double, eval}
 ## @end deftypefn
 
--- a/scripts/strings/strcat.m
+++ b/scripts/strings/strcat.m
@@ -20,19 +20,20 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} strcat (@var{s1}, @var{s2}, @dots{})
 ## Return a string containing all the arguments concatenated
-## horizontally.  If the arguments are cells strings,  @code{strcat}
+## horizontally.  If the arguments are cell strings, @code{strcat}
 ## returns a cell string with the individual cells concatenated.
 ## For numerical input, each element is converted to the
-## corresponding ASCII character.  Trailing white space for each of
-## the inputs (@var{s1}, @var{S2}, @dots{}) is eliminated before they
-## are concatenated.
+## corresponding ASCII character.  Trailing white space for any
+## character string input is eliminated before the strings are
+## concatenated.  Note that cell string values do @strong{not} have
+## whitespace trimmed.
 ##
 ## For example:
 ##
 ## @example
 ## @group
 ## strcat ("|", " leading space is preserved", "|")
-##     @result{} | leading space is perserved|
+##     @result{} | leading space is preserved|
 ## @end group
 ## @end example
 ##
@@ -62,12 +63,12 @@
 ##
 ## @example
 ## @group
-## s = @{ "ab"; "cde" @};
+## s = @{ "ab"; "cd " @};
 ## strcat (s, s, s)
 ##     @result{}
 ##         @{
 ##           [1,1] = ababab
-##           [2,1] = cdecdecde
+##           [2,1] = cd cd cd 
 ##         @}
 ## @end group
 ## @end example
@@ -79,45 +80,46 @@
 
 function st = strcat (varargin)
 
-  if (nargin > 0)
-    if (nargin == 1)
-      st = varargin{1};
-    elseif (nargin > 1)
-      ## Convert to cells of strings
-      uo = "uniformoutput";
-      reals = cellfun ("isreal", varargin);
-      if (any (reals))
-        varargin(reals) = cellfun ("char", varargin(reals), uo, false);
-      endif
-      chars = cellfun ("isclass", varargin, "char");
-      allchar = all (chars);
-      varargin(chars) = cellfun ("cellstr", varargin(chars), uo, false);
-      if (! all (cellfun ("isclass", varargin, "cell")))
-        error ("strcat: inputs must be strings or cells of strings");
-      endif
-
-      ## We don't actually need to bring all cells to common size, because
-      ## cellfun can now expand scalar cells.
-      err = common_size (varargin{:});
-
-      if (err)
-        error ("strcat: arguments must be the same size, or be scalars");
-      endif
-
-      ## Cellfun handles everything for us.
-      st = cellfun ("horzcat", varargin{:}, uo, false);
-
-      if (allchar)
-        ## If all inputs were strings, return strings.
-        st = char (st);
-      endif
-    endif
-  else
+  if (nargin == 0)
     print_usage ();
   endif
 
+  if (nargin == 1)
+    st = varargin{1};
+  else
+    ## Convert to cells of strings
+    uo = "uniformoutput";
+    reals = cellfun ("isreal", varargin);
+    if (any (reals))
+      varargin(reals) = cellfun ("char", varargin(reals), uo, false);
+    endif
+    chars = cellfun ("isclass", varargin, "char");
+    allchar = all (chars);
+    varargin(chars) = cellfun ("cellstr", varargin(chars), uo, false);
+    if (! all (cellfun ("isclass", varargin, "cell")))
+      error ("strcat: inputs must be strings or cells of strings");
+    endif
+
+    ## We don't actually need to bring all cells to common size, because
+    ## cellfun can now expand scalar cells.
+    err = common_size (varargin{:});
+
+    if (err)
+      error ("strcat: arguments must be the same size, or be scalars");
+    endif
+
+    ## Cellfun handles everything for us.
+    st = cellfun ("horzcat", varargin{:}, uo, false);
+
+    if (allchar)
+      ## If all inputs were strings, return strings.
+      st = char (st);
+    endif
+  endif
+
 endfunction
 
+
 ## test the dimensionality
 ## 1d
 %!assert (strcat ("ab ", "ab "), "abab")
--- a/scripts/strings/strjoin.m
+++ b/scripts/strings/strjoin.m
@@ -58,13 +58,13 @@
 
   if (numel (cstr) == 1)
     rval = cstr{1};
-    return
+    return;
   endif
 
   if (ischar (delimiter))
     delimiter = do_string_escapes (delimiter);
     delimiter = {delimiter};
-  end
+  endif
  
   num = numel (cstr); 
   if (numel (delimiter) == 1 && num > 1)
@@ -85,6 +85,7 @@
 
 endfunction
 
+
 %!assert (strjoin ({"hello"}, "-"), "hello")
 %!assert (strjoin ({"hello", "world"}), "hello world")
 %!assert (strjoin ({"Octave", "Scilab", "Lush", "Yorick"}, "*"),
@@ -94,3 +95,4 @@
 %!assert (strjoin ({'Octave','Scilab'},'\n'), "Octave\nScilab")
 %!assert (strjoin ({'Octave','Scilab'},{'\n'}), "Octave\\nScilab")
 %!assert (strjoin ({},'foo'), "")
+
--- a/scripts/strings/strjust.m
+++ b/scripts/strings/strjust.m
@@ -21,8 +21,8 @@
 ## @deftypefn  {Function File} {} strjust (@var{s})
 ## @deftypefnx {Function File} {} strjust (@var{s}, @var{pos})
 ## Return the text, @var{s}, justified according to @var{pos}, which may
-## be @samp{"left"}, @samp{"center"}, or @samp{"right"}.  If @var{pos}
-## is omitted it defaults to @samp{"right"}.
+## be @qcode{"left"}, @qcode{"center"}, or @qcode{"right"}.  If @var{pos}
+## is omitted it defaults to @qcode{"right"}.
 ##
 ## Null characters are replaced by spaces.  All other character
 ## data are treated as non-white space.
--- a/scripts/strings/strmatch.m
+++ b/scripts/strings/strmatch.m
@@ -23,7 +23,7 @@
 ## @deftypefnx {Function File} {} strmatch (@var{s}, @var{A}, "exact")
 ## Return indices of entries of @var{A} which begin with the string @var{s}.
 ## The second argument @var{A} must be a string, character matrix, or a cell
-## array of strings.  If the third argument @code{"exact"} is not given, then
+## array of strings.  If the third argument @qcode{"exact"} is not given, then
 ## @var{s} only needs to match @var{A} up to the length of @var{s}.
 ## Trailing spaces and nulls in @var{s} and @var{A} are ignored when matching.
 ##
@@ -43,7 +43,7 @@
 ## @end example
 ##
 ## @strong{Caution:} @code{strmatch} is scheduled for deprecation.  Use
-## @code{strncmp} (normal case), or @code{strcmp} ("exact" case), or
+## @code{strncmp} (normal case), or @code{strcmp} (@qcode{"exact"} case), or
 ## @code{regexp} in all new code.
 ## @seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find}
 ## @end deftypefn
--- a/scripts/strings/strsplit.m
+++ b/scripts/strings/strsplit.m
@@ -159,8 +159,8 @@
     args.delimitertype = "simple";
   endif
 
-  # Save the length of the "delimitertype" parameter
-  length_deltype = numel (args.delimitertype);
+  ## Save the length of the "delimitertype" parameter
+  length_deltype = length (args.delimitertype);
 
   if (nargin == 1 || (nargin > 1 && (islogical (del) || isnumeric (del))))
     if (nargin > 1)
@@ -168,7 +168,7 @@
       args.collapsedelimiters = del;
     endif
     ## Set proper default for the delimiter type
-    if (strncmpi (args.delimitertype, "simple", numel (args.delimitertype)))
+    if (strncmpi (args.delimitertype, "simple", length (args.delimitertype)))
       del = {" ","\f","\n","\r","\t","\v"};
     else
       del = "\\s";
@@ -187,7 +187,7 @@
     else
       del = do_string_escapes (del);
     endif
-    % This is clumsy, but needed for multi-row strings
+    ## This is clumsy, but needed for multi-row strings
     del = regexprep (del, '([^\w])', '\\$1');
   endif
 
@@ -209,6 +209,7 @@
   endif
 endfunction
 
+
 %!shared str
 %! str = "The rain in Spain stays mainly in the plain.";
 % Split on all whitespace.
--- a/scripts/strings/untabify.m
+++ b/scripts/strings/untabify.m
@@ -61,7 +61,7 @@
   if (ischar (t))
     s = replace_tabs (t, tw);
   else
-    s = cellfun (@(str) replace_tabs (str, tw), t, "uniformoutput", false);
+    s = cellfun (@replace_tabs, t, {tw}, "uniformoutput", false);
   endif
 
   if (dblank)
--- a/scripts/strings/validatestring.m
+++ b/scripts/strings/validatestring.m
@@ -28,11 +28,12 @@
 ## cellstr of valid values, then @var{validstr} will be the validated form
 ## of @var{str} where validation is defined as @var{str} being a member
 ## or substring of @var{validstr}.  This is useful for both verifying
-## and expanding short options, such as "r", to their longer forms, such as
-## "red".  If @var{str} is a substring of @var{validstr}, and there are
-## multiple matches, the shortest match will be returned if all matches are
-## substrings of each other.  Otherwise, an error will be raised because the
-## expansion of @var{str} is ambiguous.  All comparisons are case insensitive.
+## and expanding short options, such as @qcode{"r"}, to their longer forms,
+## such as @qcode{"red"}.  If @var{str} is a substring of @var{validstr}, and
+## there are multiple matches, the shortest match will be returned if all
+## matches are substrings of each other.  Otherwise, an error will be raised
+## because the expansion of @var{str} is ambiguous.  All comparisons are case
+## insensitive.
 ##
 ## The additional inputs @var{funcname}, @var{varname}, and @var{position}
 ## are optional and will make any generated validation error message more
@@ -51,7 +52,7 @@
 ##    blue, black
 ## @end group
 ## @end smallexample
-## 
+##
 ## @seealso{strcmp, strcmpi}
 ## @end deftypefn
 
@@ -69,7 +70,7 @@
     position = varargin{end};
     varargin(end) = [];
   endif
-  
+
   funcname = varname = "";
   char_idx = cellfun ("isclass", varargin, "char");
   n_chararg = sum (char_idx);
@@ -111,7 +112,7 @@
     errstr(end:end+1) = ":\n";
   endif
 
-  matches = strncmpi (str, strarray(:), numel (str));
+  matches = strncmpi (str, strarray(:), length (str));
   nmatches = sum (matches);
   if (nmatches == 0)
     error ("validatestring: %s'%s' does not match any of\n%s", errstr, str,
@@ -123,9 +124,9 @@
     ## If true, choose the shortest.  If not, raise an error.
     match_idx = find (matches);
     match_len = cellfun ("length", strarray(match_idx));
-    [min_len, min_idx] = min (match_len); 
+    [min_len, min_idx] = min (match_len);
     short_str = strarray{match_idx(min_idx)};
-    submatch = strncmpi (short_str, strarray(match_idx), min_len);    
+    submatch = strncmpi (short_str, strarray(match_idx), min_len);
     if (all (submatch))
       str = short_str;
     else
--- a/scripts/testfun/__have_feature__.m
+++ b/scripts/testfun/__have_feature__.m
@@ -32,3 +32,4 @@
     retval = false;
   endif
 endfunction
+
--- a/scripts/testfun/__printf_assert__.m
+++ b/scripts/testfun/__printf_assert__.m
@@ -25,3 +25,4 @@
   global _assert_printf;
   _assert_printf = cat (2, _assert_printf, sprintf (varargin{:}));
 endfunction
+
--- a/scripts/testfun/__prog_output_assert__.m
+++ b/scripts/testfun/__prog_output_assert__.m
@@ -32,3 +32,4 @@
   endif
   _assert_printf = "";
 endfunction
+
--- a/scripts/testfun/__run_test_suite__.m
+++ b/scripts/testfun/__run_test_suite__.m
@@ -33,15 +33,15 @@
   endif
   global files_with_no_tests = {};
   global files_with_tests = {};
-  ## FIXME -- these names don't really make sense if we are running
-  ## tests for an installed copy of Octave.
+  ## FIXME: These names don't really make sense if we are running
+  ##        tests for an installed copy of Octave.
   global topsrcdir = fcnfiledir;
   global topbuilddir = testsdir;
   pso = page_screen_output ();
   warn_state = warning ("query", "quiet");
   warning ("on", "quiet");
   try
-    page_screen_output (0);
+    page_screen_output (false);
     warning ("off", "Octave:deprecated-function");
     fid = fopen ("fntests.log", "wt");
     if (fid < 0)
@@ -92,9 +92,9 @@
     endif
 
     ## Weed out deprecated and private functions
-    weed_idx = cellfun (@isempty, regexp (files_with_tests, '\bdeprecated\b|\bprivate\b', 'once'));
+    weed_idx = cellfun (@isempty, regexp (files_with_tests, '\<deprecated\>|\<private\>', 'once'));
     files_with_tests = files_with_tests(weed_idx);
-    weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\bdeprecated\b|\bprivate\b', 'once'));
+    weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\<deprecated\>|\<private\>', 'once'));
     files_with_no_tests = files_with_no_tests(weed_idx);
 
     report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
@@ -103,7 +103,7 @@
     puts ("these files (see the list in the file fntests.log).\n\n");
 
     fprintf (fid, "\nFiles with no tests:\n\n%s",
-            list_in_columns (files_with_no_tests, 80));
+                  list_in_columns (files_with_no_tests, 80));
     fclose (fid);
 
     page_screen_output (pso);
@@ -133,16 +133,17 @@
 
 function retval = has_functions (f)
   n = length (f);
-  if (n > 3 && strcmp (f((end-2):end), ".cc"))
+  if (n > 3 && strcmpi (f((end-2):end), ".cc"))
     fid = fopen (f);
     if (fid >= 0)
       str = fread (fid, "*char")';
       fclose (fid);
-      retval = ! isempty (regexp (str,'^(DEFUN|DEFUN_DLD)\b', 'lineanchors'));
+      retval = ! isempty (regexp (str,'^(DEFUN|DEFUN_DLD)\>',
+                                      'lineanchors', 'once'));
     else
       error ("fopen failed: %s", f);
     endif
-  elseif (n > 2 && strcmp (f((end-1):end), ".m"))
+  elseif (n > 2 && strcmpi (f((end-1):end), ".m"))
     retval = true;
   else
     retval = false;
@@ -154,18 +155,8 @@
   if (fid >= 0)
     str = fread (fid, "*char")';
     fclose (fid);
-    retval = ! isempty (regexp (str, '^%!(assert|error|fail|test|warning)', "lineanchors"));
-  else
-    error ("fopen failed: %s", f);
-  endif
-endfunction
-
-function retval = has_demos (f)
-  fid = fopen (f);
-  if (fid >= 0)
-    str = fread (fid, "*char")';
-    fclose (fid);
-    retval = ! isempty (regexp (str, '^%!demo', "lineanchors"));
+    retval = ! isempty (regexp (str, '^%!(assert|error|fail|test|warning)',
+                                     'lineanchors', 'once'));
   else
     error ("fopen failed: %s", f);
   endif
@@ -179,9 +170,7 @@
   for i = 1:length (lst)
     nm = lst(i).name;
     if (lst(i).isdir
-        && ! strcmp (nm, ".") && ! strcmp (nm, "..")
-        && ! strcmp (nm, "private") && nm(1) != "@"
-        && ! strcmp (nm, "CVS"))
+        && nm(1) != "." && ! strcmp (nm, "private") && nm(1) != "@")
       [p, n, xf, sk] = run_test_dir (fid, [d, filesep, nm]);
       dp += p;
       dn += n;
@@ -194,7 +183,7 @@
     chdir (d);
     for i = 1:length (lst)
       nm = lst(i).name;
-      if (length (nm) > 4 && strcmp (nm((end-3):end), ".tst"))
+      if (length (nm) > 4 && strcmpi (nm((end-3):end), ".tst"))
         p = n = xf = sk = 0;
         ffnm = fullfile (d, nm);
         if (has_tests (ffnm))
@@ -202,8 +191,6 @@
           [p, n, xf, sk] = test (nm, "quiet", fid);
           print_pass_fail (n, p);
           files_with_tests(end+1) = ffnm;
-        ##elseif (has_demos (ffnm))
-        ##  files_with_tests(end+1) = ffnm;
         else
           files_with_no_tests(end+1) = ffnm;
         endif
@@ -227,8 +214,7 @@
   dp = dn = dxf = dsk = 0;
   for i = 1:length (lst)
     nm = lst(i).name;
-    if (lst(i).isdir && ! strcmp (nm, ".") && ! strcmp (nm, "..")
-        && ! strcmp (nm, "CVS"))
+    if (lst(i).isdir && nm(1) != ".")
       [p, n, xf, sk] = run_test_script (fid, [d, filesep, nm]);
       dp += p;
       dn += n;
@@ -243,12 +229,12 @@
       continue
     endif
     f = fullfile (d, nm);
-    if ((length (nm) > 2 && strcmp (nm((end-1):end), ".m"))
+    if ((length (nm) > 2 && strcmpi (nm((end-1):end), ".m"))
         || (length (nm) > 4
-            && (strcmp (nm((end-3):end), "-tst")
-                || strcmp (nm((end-3):end), ".tst"))))
+            && (   strcmpi (nm((end-3):end), "-tst")
+                || strcmpi (nm((end-3):end), ".tst"))))
       p = n = xf = 0;
-      ## Only run if it contains %!test, %!assert %!error or %!warning
+      ## Only run if it contains %!test, %!assert, %!error, %!fail, or %!warning
       if (has_tests (f))
         tmp = strrep (f, [topsrcdir, filesep], "");
         tmp = strrep (tmp, [topbuilddir, filesep], "");
@@ -260,8 +246,6 @@
         dxf += xf;
         dsk += sk;
         files_with_tests(end+1) = f;
-      ##elseif (has_demos (f))
-      ##  files_with_tests(end+1) = f;
       else
         ## To reduce the list length, only mark .cc files that contain
         ## DEFUN definitions.
@@ -273,7 +257,7 @@
 endfunction
 
 function n = num_elts_matching_pattern (lst, pat)
-  n = sum (cellfun (@(x) !isempty (x), regexp (lst, pat, 'once')));
+  n = sum (! cellfun ("isempty", regexp (lst, pat, 'once')));
 endfunction
 
 function report_files_with_no_tests (with, without, typ)
@@ -283,3 +267,4 @@
   n_tot = n_with + n_without;
   printf ("\n%d (of %d) %s files have no tests.\n", n_without, n_tot, typ);
 endfunction
+
--- a/scripts/testfun/assert.m
+++ b/scripts/testfun/assert.m
@@ -27,7 +27,7 @@
 ## be called in three different ways.
 ##
 ## @table @code
-## @item assert (@var{cond})
+## @item  assert (@var{cond})
 ## @itemx assert (@var{cond}, @var{errmsg}, @dots{})
 ## @itemx assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
 ## Called with a single argument @var{cond}, @code{assert} produces an
@@ -47,17 +47,27 @@
 ## If @var{tol} is negative then it is a relative tolerance which will produce
 ## an error if @code{abs (@var{observed} - @var{expected}) >
 ## abs (@var{tol} * @var{expected})}.  If @var{expected} is zero @var{tol} will
-## always be interpreted as an absolute tolerance.
+## always be interpreted as an absolute tolerance.  If @var{tol} is not scalar
+## its dimensions must agree with those of @var{observed} and @var{expected}
+## and tests are performed on an element-wise basis.
 ## @end table
 ## @seealso{test, fail, error}
 ## @end deftypefn
 
-## FIXME: Output throttling: don't print out the entire 100x100 matrix,
-## but instead give a summary; don't print out the whole list, just
-## say what the first different element is, etc.  To do this, make
-## the message generation type specific.
+function assert (cond, varargin)
+
+  if (nargin == 0 || nargin > 3)
+    print_usage ();
+  endif
 
-function assert (cond, varargin)
+  persistent call_depth = -1;
+  persistent errmsg;
+
+  call_depth++;
+
+  if (call_depth == 0)
+    errmsg = "";
+  endif
 
   in = deblank (argn(1,:));
   for i = 2:rows (argn)
@@ -67,18 +77,15 @@
 
   if (nargin == 1 || (nargin > 1 && islogical (cond) && ischar (varargin{1})))
     if ((! isnumeric (cond) && ! islogical (cond)) || ! all (cond(:)))
+      call_depth--;
       if (nargin == 1)
-        ## Say which elements failed?
+        ## Perhaps, say which elements failed?
         error ("assert %s failed", in);
       else
         error (varargin{:});
       endif
     endif
   else
-    if (nargin < 2 || nargin > 3)
-      print_usage ();
-    endif
-
     expected = varargin{1};
     if (nargin < 3)
       tol = 0;
@@ -86,42 +93,80 @@
       tol = varargin{2};
     endif
 
-    if (exist ("argn") == 0)
-      argn = " ";
-    endif
-
-    coda = "";
-    iserror = 0;
-
+    ## Add to list as the errors accumulate.  If empty at end then no errors.
+    err.index = {};
+    err.observed = {};
+    err.expected = {};
+    err.reason = {};
 
     if (ischar (expected))
-      iserror = (! ischar (cond) || ! strcmp (cond, expected));
+      if (! ischar (cond))
+        err.index{end+1} = ".";
+        err.expected{end+1} = expected;
+        if (isnumeric (cond))
+          err.observed{end+1} = num2str (cond);
+          err.reason{end+1} = "Expected string, but observed number";
+        else
+          err.observed{end+1} = "O";
+          err.reason{end+1} = ["Expected string, but observed " class(cond)];
+        endif
+      elseif (! strcmp (cond, expected))
+        err.index{end+1} = "[]";
+        err.observed{end+1} = cond;
+        err.expected{end+1} = expected;
+        err.reason{end+1} = "Strings don't match";
+      endif
 
     elseif (iscell (expected))
-      if (! iscell (cond) || any (size (cond) != size (expected)))
-        iserror = 1;
+      if (! iscell (cond))
+        err.index{end+1} = ".";
+        err.observed{end+1} = "O";
+        err.expected{end+1} = "E";
+        err.reason{end+1} = ["Expected cell, but observed " class(cond)];
+      elseif (ndims (cond) != ndims (expected)
+              || any (size (cond) != size (expected)))
+        err.index{end+1} = ".";
+        err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"];
+        err.expected{end+1} = ["E(" sprintf("%dx", size(expected))(1:end-1) ")"];
+        err.reason{end+1} = "Dimensions don't match";
       else
         try
+          ## Recursively compare cell arrays
           for i = 1:length (expected(:))
             assert (cond{i}, expected{i}, tol);
           endfor
         catch
-          iserror = 1;
+          err.index{end+1} = "{}";
+          err.observed{end+1} = "O";
+          err.expected{end+1} = "E";
+          err.reason{end+1} = "Cell configuration error";
         end_try_catch
       endif
 
     elseif (isstruct (expected))
-      if (! isstruct (cond) || any (size (cond) != size (expected))
-          || rows (fieldnames (cond)) != rows (fieldnames (expected)))
-        iserror = 1;
+      if (! isstruct (cond))
+        err.index{end+1} = ".";
+        err.observed{end+1} = "O";
+        err.expected{end+1} = "E";
+        err.reason{end+1} = ["Expected struct, but observed " class(cond)];
+      elseif (ndims (cond) != ndims (expected)
+              || any (size (cond) != size (expected))
+              || rows (fieldnames (cond)) != rows (fieldnames (expected)))
+
+        err.index{end+1} = ".";
+        err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"];
+        err.expected{end+1} = ["E(" sprintf("%dx", size(expected))(1:end-1) ")"];
+        err.reason{end+1} = "Structure sizes don't match";
       else
         try
-          #empty = numel (cond) == 0;
           empty = isempty (cond);
           normal = (numel (cond) == 1);
           for [v, k] = cond
             if (! isfield (expected, k))
-              error ();
+              err.index{end+1} = ".";
+              err.observed{end+1} = "O";
+              err.expected{end+1} = "E";
+              err.reason{end+1} = ["'" k "'" " is not an expected field"];
             endif
             if (empty)
               v = {};
@@ -130,109 +175,209 @@
             else
               v = v(:)';
             endif
+            ## Recursively call assert for struct array values
             assert (v, {expected.(k)}, tol);
           endfor
         catch
-          iserror = 1;
+          err.index{end+1} = ".";
+          err.observed{end+1} = "O";
+          err.expected{end+1} = "E";
+          err.reason{end+1} = "Structure configuration error";
         end_try_catch
       endif
 
     elseif (ndims (cond) != ndims (expected)
             || any (size (cond) != size (expected)))
-      iserror = 1;
-      coda = "Dimensions don't match";
+      err.index{end+1} = ".";
+      err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"];
+      err.expected{end+1} = ["E(" sprintf("%dx", size(expected))(1:end-1) ")"];
+      err.reason{end+1} = "Dimensions don't match";
 
-    else
+    else  # Numeric comparison
       if (nargin < 3)
         ## Without explicit tolerance, be more strict.
         if (! strcmp (class (cond), class (expected)))
-          iserror = 1;
-          coda = ["Class " class (cond) " != " class(expected)];
+          err.index{end+1} = "()";
+          err.observed{end+1} = "O";
+          err.expected{end+1} = "E";
+          err.reason{end+1} = ["Class " class(cond) " != " class(expected)];
         elseif (isnumeric (cond))
           if (issparse (cond) != issparse (expected))
+            err.index{end+1} = "()";
+            err.observed{end+1} = "O";
+            err.expected{end+1} = "E";
             if (issparse (cond))
-              iserror = 1;
-              coda = "sparse != non-sparse";
+              err.reason{end+1} = "sparse != non-sparse";
             else
-              iserror = 1;
-              coda = "non-sparse != sparse";
+              err.reason{end+1} = "non-sparse != sparse";
             endif
           elseif (iscomplex (cond) != iscomplex (expected))
-            if (iscomplex (cond))
-              iserror = 1;
-              coda = "complex != real";
+            err.index{end+1} = "()";
+            err.observed{end+1} = "O";
+            err.expected{end+1} = "E";
+           if (iscomplex (cond))
+              err.reason{end+1} = "complex != real";
             else
-              iserror = 1;
-              coda = "real != complex";
+              err.reason{end+1} = "real != complex";
             endif
           endif
         endif
       endif
 
-      if (! iserror)
-        ## Numeric.
-        A = cond(:);
-        B = expected(:);
+      if (isempty (err.index))
+
+        A = cond;
+        B = expected;
+
         ## Check exceptional values.
-        if (any (isna (A) != isna (B)))
-          iserror = 1;
-          coda = "NAs don't match";
-        elseif (any (isnan (A) != isnan (B)))
-          iserror = 1;
-          coda = "NaNs don't match";
-          ## Try to avoid problems comparing strange values like Inf+NaNi.
-        elseif (any (isinf (A) != isinf (B))
-                || any (A(isinf (A) & ! isnan (A)) != B(isinf (B) & ! isnan (B))))
-          iserror = 1;
-          coda = "Infs don't match";
+        errvec = (  isna (real (A)) != isna (real (B))
+                  | isna (imag (A)) != isna (imag (B)));
+        erridx = find (errvec);
+        if (! isempty (erridx))
+          err.index(end+1:end+length (erridx)) = ...
+            ind2tuple (size (A), erridx);
+          err.observed(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (A(erridx) (:))));
+          err.expected(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (B(erridx) (:))));
+          err.reason(end+1:end+length (erridx)) = ...
+            repmat ({"'NA' mismatch"}, length (erridx), 1);
+        endif
+        errseen = errvec;
+
+        errvec = (  isnan (real (A)) != isnan (real (B))
+                  | isnan (imag (A)) != isnan (imag (B)));
+        erridx = find (errvec & !errseen);
+        if (! isempty (erridx))
+          err.index(end+1:end+length (erridx)) = ...
+            ind2tuple (size (A), erridx);
+          err.observed(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (A(erridx) (:))));
+          err.expected(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (B(erridx) (:))));
+          err.reason(end+1:end+length (erridx)) = ...
+            repmat ({"'NaN' mismatch"}, length (erridx), 1);
+        endif
+        errseen |= errvec;
+
+        errvec =   ((isinf (real (A)) | isinf (real (B))) ...
+                    & (real (A) != real (B)))             ...
+                 | ((isinf (imag (A)) | isinf (imag (B))) ...
+                    & (imag (A) != imag (B)));
+        erridx = find (errvec & !errseen);
+        if (! isempty (erridx))
+          err.index(end+1:end+length (erridx)) = ...
+            ind2tuple (size (A), erridx);
+          err.observed(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (A(erridx) (:))));
+          err.expected(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (B(erridx) (:))));
+          err.reason(end+1:end+length (erridx)) = ...
+            repmat ({"'Inf' mismatch"}, length (erridx), 1);
+        endif
+        errseen |= errvec;
+
+        ## Check normal values.
+        ## Replace exceptional values already checked above by zero.
+        A_null_real = real (A);
+        B_null_real = real (B);
+        exclude = errseen | ! isfinite (A_null_real) & ! isfinite (B_null_real);
+        A_null_real(exclude) = 0;
+        B_null_real(exclude) = 0;
+        A_null_imag = imag (A);
+        B_null_imag = imag (B);
+        exclude = errseen | ! isfinite (A_null_imag) & ! isfinite (B_null_imag);
+        A_null_imag(exclude) = 0;
+        B_null_imag(exclude) = 0;
+        A_null = complex (A_null_real, A_null_imag);
+        B_null = complex (B_null_real, B_null_imag);
+        if (isscalar (tol))
+          mtol = repmat (tol, size (A));
         else
-          ## Check normal values.
-          A = A(isfinite (A));
-          B = B(isfinite (B));
-          if (tol == 0)
-            err = any (A != B);
-            errtype = "values do not match";
-          elseif (tol >= 0)
-            err = max (abs (A - B));
-            errtype = "maximum absolute error %g exceeds tolerance %g";
-          else
-            abserr = max (abs (A(B == 0)));
-            A = A(B != 0);
-            B = B(B != 0);
-            relerr = max (abs (A - B) ./ abs (B));
-            err = max ([abserr; relerr]);
-            errtype = "maximum relative error %g exceeds tolerance %g";
+          mtol = tol;
+        endif
+
+        k = (mtol == 0);
+        erridx = find ((A_null != B_null) & k);
+        if (! isempty (erridx))
+          err.index(end+1:end+length (erridx)) = ...
+            ind2tuple (size (A), erridx);
+          err.observed(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (A(erridx) (:))));
+          err.expected(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (B(erridx) (:))));
+          err.reason(end+1:end+length (erridx)) = ...
+            ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n",...
+            [abs(A_null(erridx) - B_null(erridx))(:) mtol(erridx)(:)]')), "\n");
+        endif
+
+        k = (mtol > 0);
+        erridx = find ((abs (A_null - B_null) > mtol) & k);
+        if (! isempty (erridx))
+          err.index(end+1:end+length (erridx)) = ...
+            ind2tuple (size (A), erridx);
+          err.observed(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (A(erridx) (:))));
+          err.expected(end+1:end+length (erridx)) = ...
+            strtrim (cellstr (num2str (B(erridx) (:))));
+          err.reason(end+1:end+length (erridx)) = ...
+            ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n",...
+            [abs(A_null(erridx) - B_null(erridx))(:) mtol(erridx)(:)]')), "\n");
+        endif
+
+        k = (mtol < 0);
+        if (any (k(:)))
+          ## Test for absolute error where relative error can't be calculated.
+          erridx = find ((B_null == 0) & abs (A_null) > abs (mtol) & k);
+          if (! isempty (erridx))
+            err.index(end+1:end+length (erridx)) = ...
+              ind2tuple (size (A), erridx);
+            err.observed(end+1:end+length (erridx)) = ...
+              strtrim (cellstr (num2str (A(erridx) (:))));
+            err.expected(end+1:end+length (erridx)) = ...
+              strtrim (cellstr (num2str (B(erridx) (:))));
+            err.reason(end+1:end+length (erridx)) = ...
+              ostrsplit (deblank (sprintf ("Abs err %.5g exceeds tol %.5g\n",
+              [abs(A_null(erridx) - B_null(erridx)) -mtol(erridx)]')), "\n");
           endif
-          if (err > abs (tol))
-            iserror = 1;
-            coda = sprintf (errtype, err, abs (tol));
+          ## Test for relative error
+          Bdiv = Inf (size (B_null));
+          Bdiv(k & (B_null != 0)) = B_null(k & (B_null != 0));
+          relerr = abs ((A_null - B_null) ./ abs (Bdiv));
+          erridx = find ((relerr > abs (mtol)) & k);
+          if (! isempty (erridx))
+            err.index(end+1:end+length (erridx)) = ...
+              ind2tuple (size (A), erridx);
+            err.observed(end+1:end+length (erridx)) = ...
+              strtrim (cellstr (num2str (A(erridx) (:))));
+            err.expected(end+1:end+length (erridx)) = ...
+              strtrim (cellstr (num2str (B(erridx) (:))));
+            err.reason(end+1:end+length (erridx)) = ...
+              ostrsplit (deblank (sprintf ("Rel err %.5g exceeds tol %.5g\n",
+              [relerr(erridx)(:) -mtol(erridx)(:)]')), "\n");
           endif
         endif
       endif
 
     endif
 
-    if (! iserror)
-      return;
+    ## Print any errors
+    if (! isempty (err.index))
+      if (! isempty (errmsg))
+        errmsg = [errmsg "\n"];
+      endif
+      errmsg = [errmsg, pprint(in, err)];
     endif
 
-    ## Pretty print the "expected but got" info, trimming leading and
-    ## trailing "\n".
-    str = disp (expected);
-    idx = find (str != "\n");
-    if (! isempty (idx))
-      str = str(idx(1):idx(end));
+  endif
+
+  call_depth--;
+
+  if (call_depth == -1)
+    ## Last time through.  If there were any errors on any pass, raise a flag.
+    if (! isempty (errmsg))
+      error (errmsg);
     endif
-    str2 = disp (cond);
-    idx = find (str2 != "\n");
-    if (! isempty (idx))
-      str2 = str2 (idx(1):idx(end));
-    endif
-    msg = ["assert " in " expected\n" str "\nbut got\n" str2];
-    if (! isempty (coda))
-      msg = [msg, "\n", coda];
-    endif
-    error ("%s", msg);
   endif
 
 endfunction
@@ -241,8 +386,8 @@
 ## empty input
 %!assert ([])
 %!assert (zeros (3,0), zeros (3,0))
-%!error assert (zeros (3,0), zeros (0,2))
-%!error assert (zeros (3,0), [])
+%!error <O\(3x0\)\s+E\(0x2\)> assert (zeros (3,0), zeros (0,2))
+%!error <Dimensions don't match> assert (zeros (3,0), [])
 %!error <Dimensions don't match> assert (zeros (2,0,2), zeros (2,0))
 
 ## conditions
@@ -257,67 +402,135 @@
 %!error assert ([1,0;1,1])
 
 ## scalars
-%!error assert (3, [3,3; 3,3])
-%!error assert ([3,3; 3,3], 3)
+%!error <Dimensions don't match> assert (3, [3,3])
+%!error <Dimensions don't match> assert (3, [3,3; 3,3])
+%!error <Dimensions don't match> assert ([3,3; 3,3], 3)
 %!assert (3, 3)
+%!error <Abs err 1 exceeds tol> assert (3, 4)
 %!assert (3+eps, 3, eps)
 %!assert (3, 3+eps, eps)
-%!error assert (3+2*eps, 3, eps)
-%!error assert (3, 3+2*eps, eps)
+%!error <Abs err 4.4409e-16 exceeds tol> assert (3+2*eps, 3, eps)
+%!error <Abs err 4.4409e-16 exceeds tol> assert (3, 3+2*eps, eps)
 
 ## vectors
 %!assert ([1,2,3],[1,2,3]);
 %!assert ([1;2;3],[1;2;3]);
-%!error assert ([2;2;3],[1;2;3]);
-%!error assert ([1,2,3],[1;2;3]);
-%!error assert ([1,2],[1,2,3]);
-%!error assert ([1;2;3],[1;2]);
+%!error <Abs err 1 exceeds tol 0> assert ([2,2,3,3],[1,2,3,4]);
+%!error <Abs err 1 exceeds tol 0.5> assert ([2,2,3,3],[1,2,3,4],0.5);
+%!error <Rel err 1 exceeds tol 0.1> assert ([2,2,3,5],[1,2,3,4],-0.1);
+%!error <Abs err 1 exceeds tol 0> assert ([6;6;7;7],[5;6;7;8]);
+%!error <Abs err 1 exceeds tol 0.5> assert ([6;6;7;7],[5;6;7;8],0.5);
+%!error <Rel err .* exceeds tol 0.1> assert ([6;6;7;7],[5;6;7;8],-0.1);
+%!error <Dimensions don't match> assert ([1,2,3],[1;2;3]);
+%!error <Dimensions don't match> assert ([1,2],[1,2,3]);
+%!error <Dimensions don't match> assert ([1;2;3],[1;2]);
+
+## matrices
 %!assert ([1,2;3,4],[1,2;3,4]);
-%!error assert ([1,4;3,4],[1,2;3,4])
-%!error assert ([1,3;2,4;3,5],[1,2;3,4])
+%!error <\(1,2\)\s+4\s+2> assert ([1,4;3,4],[1,2;3,4])
+%!error <Dimensions don't match> assert ([1,3;2,4;3,5],[1,2;3,4])
+%!test  # 2-D matrix
+%! A = [1 2 3]'*[1,2];
+%! assert (A, A);
+%! fail ("assert (A.*(A!=2),A)");
+%!test  # N-D matrix
+%! X = zeros (2,2,3);
+%! Y = X;
+%! Y(1,2,3) = 1.5;
+%! fail ("assert (X,Y)", "\(1,2,3\).*Abs err 1.5 exceeds tol 0");
 
 ## must give a small tolerance for floating point errors on relative
 %!assert (100+100*eps, 100, -2*eps)
 %!assert (100, 100+100*eps, -2*eps)
-%!error assert (100+300*eps, 100, -2*eps)
-%!error assert (100, 100+300*eps, -2*eps)
-%!error assert (3, [3,3])
-%!error assert (3, 4)
+%!error <Rel err .* exceeds tol> assert (100+300*eps, 100, -2*eps)
+%!error <Rel err .* exceeds tol> assert (100, 100+300*eps, -2*eps)
 
 ## test relative vs. absolute tolerances
-%!test  assert (0.1+eps, 0.1,  2*eps);  # accept absolute
-%!error assert (0.1+eps, 0.1, -2*eps);  # fail relative
-%!test  assert (100+100*eps, 100, -2*eps);  # accept relative
-%!error assert (100+100*eps, 100,  2*eps);  # fail absolute
+%!test  assert (0.1+eps, 0.1,  2*eps);
+%!error <Rel err 2.2204e-15 exceeds tol> assert (0.1+eps, 0.1, -2*eps);
+%!test  assert (100+100*eps, 100, -2*eps);
+%!error <Abs err 2.8422e-14 exceeds tol> assert (100+100*eps, 100,  2*eps);
+
+## Corner case of relative tolerance with 0 divider
+%!error <Abs err 2 exceeds tol 0.1> assert (2, 0, -0.1)
+
+## Extra checking of inputs when tolerance unspecified.
+%!error <Class single != double> assert (single (1), 1)
+%!error <Class uint8 != uint16> assert (uint8 (1), uint16 (1))
+%!error <sparse != non-sparse> assert (sparse([1]), [1])
+%!error <non-sparse != sparse> assert ([1], sparse([1]))
+%!error <complex != real> assert (1+i, 1)
+%!error <real != complex> assert (1, 1+i)
 
 ## exceptional values
 %!assert ([NaN, NA, Inf, -Inf, 1+eps, eps], [NaN, NA, Inf, -Inf, 1, 0], eps)
-%!error assert (NaN, 1)
-%!error assert (NA, 1)
-%!error assert (-Inf, Inf)
+
+%!error <'NaN' mismatch> assert (NaN, 1)
+%!error <'NaN' mismatch> assert ([NaN 1], [1 NaN])
+%!test
+%! try
+%!   assert ([NaN 1], [1 NaN]);
+%! catch
+%!   errmsg = lasterr ();
+%!   if (sum (errmsg () == "\n") != 4)
+%!     error ("Too many errors reported for NaN assert");
+%!   elseif (strfind (errmsg, "NA"))
+%!     error ("NA reported for NaN assert");
+%!   elseif (strfind (errmsg, "Abs err NaN exceeds tol 0"))
+%!     error ("Abs err reported for NaN assert");
+%!   endif
+%! end_try_catch
+
+%!error <'NA' mismatch> assert (NA, 1)
+%!error assert ([NA 1]', [1 NA]')
+%!test
+%! try
+%!   assert ([NA 1]', [1 NA]');
+%! catch
+%!   errmsg = lasterr ();
+%!   if (sum (errmsg () == "\n") != 4)
+%!     error ("Too many errors reported for NA assert");
+%!   elseif (strfind (errmsg, "NaN"))
+%!     error ("NaN reported for NA assert");
+%!   elseif (strfind (errmsg, "Abs err NA exceeds tol 0"))
+%!     error ("Abs err reported for NA assert");
+%!   endif
+%! end_try_catch
+%!error assert ([(complex (NA, 1)) (complex (2, NA))], [(complex (NA, 2)) 2])
+
+%!error <'Inf' mismatch> assert (-Inf, Inf)
+%!error <'Inf' mismatch> assert ([-Inf Inf], [Inf -Inf])
+%!test
+%! try
+%!   assert (complex (Inf, 0.2), complex (-Inf, 0.2 + 2*eps), eps);
+%! catch
+%!   errmsg = lasterr ();
+%!   if (sum (errmsg () == "\n") != 3)
+%!     error ("Too many errors reported for Inf assert");
+%!   elseif (strfind (errmsg, "Abs err"))
+%!     error ("Abs err reported for Inf assert");
+%!   endif
+%! end_try_catch
+%!error <Abs err> assert (complex (Inf, 0.2), complex (Inf, 0.2 + 2*eps), eps)
 
 ## strings
 %!assert ("dog", "dog")
-%!error assert ("dog", "cat")
-%!error assert ("dog", 3)
-%!error assert (3, "dog")
-
-## structures
-%!shared x,y
-%! x.a = 1; x.b=[2, 2];
-%! y.a = 1; y.b=[2, 2];
-%!assert (x, y)
-%!test y.b=3;
-%!error assert (x, y)
-%!error assert (3, x)
-%!error assert (x, 3)
-%!test
-%! # Empty structures
-%! x = resize (x, 0, 1);
-%! y = resize (y, 0, 1);
-%! assert (x, y);
+%!error <Strings don't match> assert ("dog", "cat")
+%!error <Expected string, but observed number> assert (3, "dog")
+%!error <Class char != double> assert ("dog", [3 3 3])
+%!error <Expected string, but observed cell> assert ({"dog"}, "dog")
+%!error <Expected string, but observed struct> assert (struct ("dog", 3), "dog")
 
 ## cell arrays
+%!error <Expected cell, but observed double> assert (1, {1})
+%!error <Dimensions don't match> assert (cell (1,2,3), cell (3,2,1))
+%!test
+%! x = {{{1}}, 2};  # cell with multiple levels
+%! y = x;
+%! assert (x,y);
+%! y{1}{1}{1} = 3;
+%! fail ("assert (x,y)", "Abs err 2 exceeds tol 0");
+
 %!test
 %! x = {[3], [1,2,3]; 100+100*eps, "dog"};
 %! y = x;
@@ -330,8 +543,106 @@
 %! fail ("assert (x, y)");
 %! y = x; y(2,2) = "cat";
 %! fail ("assert (x, y)");
+%! y = x; y(1,1) = [2];  y(1,2) = [0, 2, 3]; y(2,1) = 101; y(2,2) = "cat";
+%! fail ("assert (x, y)");
 
-%% Test input validation
-%!error assert
+## structures
+%!error <Expected struct, but observed double> assert (1, struct ("a", 1))
+%!error <Structure sizes don't match>
+%! x(1,2,3).a = 1;
+%! y(1,2).a = 1;
+%! assert (x,y);
+%!error <Structure sizes don't match>
+%! x(1,2,3).a = 1;
+%! y(3,2,2).a = 1;
+%! assert (x,y);
+%!error <Structure sizes don't match>
+%! x.a = 1;
+%! x.b = 1;
+%! y.a = 1;
+%! assert (x,y);
+%!error <'b' is not an expected field>
+%! x.b = 1;
+%! y.a = 1;
+%! assert (x,y);
+
+%!test
+%! x.a = 1; x.b=[2, 2];
+%! y.a = 1; y.b=[2, 2];
+%! assert (x, y);
+%! y.b=3;
+%! fail ("assert (x, y)");
+%! fail ("assert (3, x)");
+%! fail ("assert (x, 3)");
+%! ## Empty structures
+%! x = resize (x, 0, 1);
+%! y = resize (y, 0, 1);
+%! assert (x, y);
+
+## vector of tolerances
+%!test
+%! x = [-40:0];
+%! y1 = (10.^x).*(10.^x);
+%! y2 = 10.^(2*x);
+%! assert (y1, y2, eps (y1));
+%! fail ("assert (y1, y2 + eps*1e-70, eps (y1))");
+
+## Multiple tolerances
+%!test
+%! x = [1 2; 3 4];
+%! y = [0 -1; 1 2];
+%! tol = [-0.1 0; -0.2 0.3];
+%! try
+%!   assert (x, y, tol);
+%! catch
+%!   errmsg = lasterr ();
+%!   if (sum (errmsg () == "\n") != 6)
+%!     error ("Incorrect number of errors reported");
+%!   endif
+%!   assert (!isempty (regexp (errmsg, '\(1,2\).*Abs err 3 exceeds tol 0\>')));
+%!   assert (!isempty (regexp (errmsg, '\(2,2\).*Abs err 2 exceeds tol 0.3')));
+%!   assert (!isempty (regexp (errmsg, '\(1,1\).*Abs err 1 exceeds tol 0.1')));
+%!   assert (!isempty (regexp (errmsg, '\(2,1\).*Rel err 2 exceeds tol 0.2')));
+%! end_try_catch
+
+## test input validation
+%!error assert ()
 %!error assert (1,2,3,4)
 
+
+## Convert all error indices into tuple format
+function cout = ind2tuple (matsize, erridx)
+
+  cout = cell (numel (erridx), 1);
+  tmp = cell (1, numel (matsize));
+  [tmp{:}] = ind2sub (matsize, erridx (:));
+  subs = [tmp{:}];
+  if (numel (matsize) == 2)
+    subs = subs(:, matsize != 1);
+  endif
+  for i = 1:numel (erridx)
+    loc = sprintf ("%d,", subs(i,:));
+    cout{i} = ["(" loc(1:end-1) ")"];
+  endfor
+
+endfunction
+
+
+## Pretty print the various errors in a condensed tabular format.
+function str = pprint (in, err)
+
+  str = ["ASSERT errors for:  assert " in "\n"];
+  str = [str, "\n  Location  |  Observed  |  Expected  |  Reason\n"];
+  for i = 1:length (err.index)
+    leni = length (err.index{i});
+    leno = length (err.observed{i});
+    lene = length (err.expected{i});
+    str = [str, sprintf("%*s%*s %*s%*s %*s%*s   %s\n",
+                        6+fix(leni/2), err.index{i}   , 6-fix(leni/2), "",
+                        6+fix(leno/2), err.observed{i}, 6-fix(leno/2), "",
+                        6+fix(lene/2), err.expected{i}, 6-fix(lene/2), "",
+                        err.reason{i})];
+  endfor
+
+endfunction
+
--- a/scripts/testfun/demo.m
+++ b/scripts/testfun/demo.m
@@ -28,9 +28,9 @@
 ## Examples are stored in the script file, or in a file with the same
 ## name but no extension located on Octave's load path.  To keep examples
 ## separate from regular script code, all lines are prefixed by @code{%!}.  Each
-## example must also be introduced by the keyword 'demo' flush left to the
-## prefix with no intervening spaces.  The remainder of the example can
-## contain arbitrary Octave code.  For example:
+## example must also be introduced by the keyword @qcode{"demo"} flush left
+## to the prefix with no intervening spaces.  The remainder of the example
+## can contain arbitrary Octave code.  For example:
 ##
 ## @example
 ## @group
@@ -67,8 +67,8 @@
 ## rather than just anonymous functions or inline functions, you will have to
 ## use @code{eval (example ("function",n))} to see them.  Because eval only
 ## evaluates one line, or one statement if the statement crosses
-## multiple lines, you must wrap your demo in "if 1 <demo stuff> endif"
-## with the 'if' on the same line as 'demo'.  For example:
+## multiple lines, you must wrap your demo in @qcode{"if 1 <demo stuff> endif"}
+## with the @qcode{"if"} on the same line as @qcode{"demo"}.  For example:
 ##
 ## @example
 ## @group
--- a/scripts/testfun/example.m
+++ b/scripts/testfun/example.m
@@ -24,7 +24,7 @@
 ## @deftypefnx {Function File} {[@var{s}, @var{idx}] =} example (@dots{})
 ##
 ## Display the code for example @var{n} associated with the function
-## "@var{name}", but do not run it.  If @var{n} is not specified, all examples
+## @var{name}, but do not run it.  If @var{n} is not specified, all examples
 ## are displayed.
 ##
 ## When called with output arguments, the examples are returned in the form of
--- a/scripts/testfun/rundemos.m
+++ b/scripts/testfun/rundemos.m
@@ -20,6 +20,9 @@
 ## @deftypefn  {Function File} {} rundemos ()
 ## @deftypefnx {Function File} {} rundemos (@var{directory})
 ## Execute built-in demos for all function files in the specified directory.
+## Also executes demos in any C++ source files found in the directory, for
+## use with dynamically linked functions.
+##
 ## If no directory is specified, operate on all directories in Octave's
 ## search path for functions.
 ## @seealso{runtests, path}
@@ -31,11 +34,16 @@
 
   if (nargin == 0)
     dirs = ostrsplit (path (), pathsep ());
+    do_class_dirs = true;
   elseif (nargin == 1)
     if (is_absolute_filename (directory))
       dirs = {directory};
+    elseif (is_rooted_relative_filename (directory))
+      dirs = {canonicalize_file_name(directory)};
     else
-      directory = regexprep (directory, ['\',filesep(),'$'], "");
+      if (directory(end) == filesep ())
+        directory = directory(1:end-1);
+      endif
       fullname = find_dir_in_path (directory);
       if (! isempty (fullname))
         dirs = {fullname};
@@ -43,23 +51,25 @@
         error ("rundemos: DIRECTORY argument must be a valid pathname");
       endif
     endif
+    do_class_dirs = false;
   else
     print_usage ();
   endif
 
   for i = 1:numel (dirs)
     d = dirs{i};
-    run_all_demos (d);
+    run_all_demos (d, do_class_dirs);
   endfor
 
 endfunction
 
-function run_all_demos (directory)
-  dirinfo = dir (directory);
-  flist = {dirinfo.name};
+function run_all_demos (directory, do_class_dirs)
+  flist = dir (directory);
+  dirs = {};
   for i = 1:numel (flist)
-    f = flist{i};
-    if (length (f) > 2 && strcmp (f((end-1):end), ".m"))
+    f = flist(i).name;
+    if ((length (f) > 2 && strcmpi (f((end-1):end), ".m")) ||
+        (length (f) > 3 && strcmpi (f((end-2):end), ".cc")))
       f = fullfile (directory, f);
       if (has_demos (f))
         try
@@ -71,8 +81,19 @@
           input ("Press <enter> to continue: ", "s");
         endif
       endif
+    elseif (flist(i).isdir && f(1) == "@")
+      f = fullfile (directory, f);
+      dirs = {dirs{:}, f};
     endif
   endfor
+
+  ## Recurse into class directories since they are implied in the path
+  if (do_class_dirs)
+    for i = 1:numel (dirs)
+      d = dirs{i};
+      run_all_demos (d, false);
+    endfor
+  endif
 endfunction
 
 function retval = has_demos (f)
--- a/scripts/testfun/runtests.m
+++ b/scripts/testfun/runtests.m
@@ -20,6 +20,9 @@
 ## @deftypefn  {Function File} {} runtests ()
 ## @deftypefnx {Function File} {} runtests (@var{directory})
 ## Execute built-in tests for all function files in the specified directory.
+## Also executes tests in any C++ source files found in the directory, for
+## use with dynamically linked functions.
+##
 ## If no directory is specified, operate on all directories in Octave's
 ## search path for functions.
 ## @seealso{rundemos, path}
@@ -31,11 +34,16 @@
 
   if (nargin == 0)
     dirs = ostrsplit (path (), pathsep ());
+    do_class_dirs = true;
   elseif (nargin == 1)
     if (is_absolute_filename (directory))
       dirs = {directory};
+    elseif (is_rooted_relative_filename (directory))
+      dirs = {canonicalize_file_name(directory)};
     else
-      directory = regexprep (directory, ['\',filesep(),'$'], "");
+      if (directory(end) == filesep ())
+        directory = directory(1:end-1);
+      endif
       fullname = find_dir_in_path (directory);
       if (! isempty (fullname))
         dirs = {fullname};
@@ -43,49 +51,82 @@
         error ("runtests: DIRECTORY argument must be a valid pathname");
       endif
     endif
+    do_class_dirs = false;
   else
     print_usage ();
   endif
 
   for i = 1:numel (dirs)
     d = dirs{i};
-    run_all_tests (d);
+    run_all_tests (d, do_class_dirs);
   endfor
 
 endfunction
 
-function run_all_tests (directory)
-  dirinfo = dir (directory);
-  flist = {dirinfo.name};
+function run_all_tests (directory, do_class_dirs)
+  flist = dir (directory);
+  dirs = {};
   no_tests = {};
   printf ("Processing files in %s:\n\n", directory);
   fflush (stdout);
   for i = 1:numel (flist)
-    f = flist{i};
-    if (length (f) > 2 && strcmp (f((end-1):end), ".m"))
+    f = flist(i).name;
+    if ((length (f) > 2 && strcmpi (f((end-1):end), ".m")) ||
+        (length (f) > 3 && strcmpi (f((end-2):end), ".cc")))
       ff = fullfile (directory, f);
       if (has_tests (ff))
         print_test_file_name (f);
         [p, n, xf, sk] = test (ff, "quiet");
         print_pass_fail (n, p);
         fflush (stdout);
-      else
+      elseif (has_functions (ff))
         no_tests{end+1} = f;
       endif
+    elseif (flist(i).isdir && f(1) == "@")
+      f = fullfile (directory, f);
+      dirs = {dirs{:}, f};
     endif
   endfor
   if (! isempty (no_tests))
     printf ("\nThe following files in %s have no tests:\n\n", directory);
     printf ("%s", list_in_columns (no_tests));
   endif
+
+  ## Recurse into class directories since they are implied in the path
+  if (do_class_dirs)
+    for i = 1:numel (dirs)
+      d = dirs{i};
+      run_all_tests (d, false);
+    endfor
+  endif
+endfunction
+
+function retval = has_functions (f)
+  n = length (f);
+  if (n > 3 && strcmpi (f((end-2):end), ".cc"))
+    fid = fopen (f);
+    if (fid >= 0)
+      str = fread (fid, "*char")';
+      fclose (fid);
+      retval = ! isempty (regexp (str,'^(DEFUN|DEFUN_DLD|DEFUNX)\>',
+                                      'lineanchors', 'once'));
+    else
+      error ("fopen failed: %s", f);
+    endif
+  elseif (n > 2 && strcmpi (f((end-1):end), ".m"))
+    retval = true;
+  else
+    retval = false;
+  endif
 endfunction
 
 function retval = has_tests (f)
   fid = fopen (f);
   if (fid >= 0)
-    str = fread (fid, "*char")';
+    str = fread (fid, "*char").';
     fclose (fid);
-    retval = ! isempty (regexp (str, '^%!(test|assert|error|warning)', "lineanchors"));
+    retval = ! isempty (regexp (str, '^%!(?:test|assert|error|warning)',
+                                     'lineanchors', 'once'));
   else
     error ("runtests: fopen failed: %s", f);
   endif
@@ -106,3 +147,8 @@
   filler = repmat (".", 1, 55-length (nm));
   printf ("  %s %s", nm, filler);
 endfunction
+
+
+%!error runtests ("foo", 1)
+%!error <DIRECTORY argument> runtests ("#_TOTALLY_/_INVALID_/_PATHNAME_#")
+
--- a/scripts/testfun/test.m
+++ b/scripts/testfun/test.m
@@ -34,14 +34,14 @@
 ## output is selected.
 ##
 ## @table @asis
-## @item "quiet"
+## @item @qcode{"quiet"}
 ##  Don't report all the tests as they happen, just the errors.
 ##
-## @item "normal"
+## @item @qcode{"normal"}
 ## Report all tests as they happen, but don't do tests which require
 ## user interaction.
 ##
-## @item "verbose"
+## @item @qcode{"verbose"}
 ## Do tests which require user interaction.
 ## @end table
 ##
@@ -58,13 +58,14 @@
 ## @var{n} and @var{max}, the number of successful tests and the total number
 ## of tests in the file @var{name} are returned.
 ##
-## If the second argument is the string "grabdemo", the contents of the demo
-## blocks are extracted but not executed.  Code for all code blocks is
-## concatenated and returned as @var{code} with @var{idx} being a vector of
-## positions of the ends of the demo blocks.
+## If the second argument is the string @qcode{"grabdemo"}, the contents of
+## the demo blocks are extracted but not executed.  Code for all code blocks
+## is concatenated and returned as @var{code} with @var{idx} being a vector
+## of positions of the ends of the demo blocks.
 ##
-## If the second argument is "explain", then @var{name} is ignored and an
-## explanation of the line markers used is written to the file @var{fid}.
+## If the second argument is @qcode{"explain"}, then @var{name} is ignored
+## and an explanation of the line markers used is written to the file
+## @var{fid}.
 ## @seealso{assert, fail, error, demo, example}
 ## @end deftypefn
 
@@ -357,7 +358,7 @@
         __name = __block(__name_position(1):__name_position(2));
         __code = __block;
         try
-          eval (__code); ## Define the function
+          eval (__code);  # Define the function
           __clear = sprintf ("%sclear %s;\n", __clear, __name);
         catch
           __success = 0;
@@ -434,7 +435,7 @@
             endif
             warning (__warnstate.state, "quiet");
             if (isempty (__err))
-              __msg = sprintf (["%swarning failed.\n" \
+              __msg = sprintf (["%swarning failed.\n" ...
                                 "Expected %s but got no warning\n"],
                                __signal_fail, __patstr);
             elseif (__mismatch)
@@ -455,7 +456,7 @@
           endif
           warning (__warnstate.state, "quiet");
           if (__warning)
-            __msg = sprintf (["%swarning failed.\n" \
+            __msg = sprintf (["%swarning failed.\n" ...
                               "Expected warning %s but got error <%s>\n"],
                              __signal_fail, __patstr, __err);
           elseif (__mismatch)
@@ -749,9 +750,9 @@
 %! % you should now see a spectrogram in the image window
 
 
-### now test test itself
+## now test 'test' itself
 
-%!## usage and error testing
+## usage and error testing
 % !fail ('test','usage.*test')           # no args, generates usage()
 % !fail ('test (1,2,3,4)','usage.*test') # too many args, generates usage()
 %!fail ('test ("test", "bogus")','unknown flag')  # incorrect args
@@ -769,7 +770,7 @@
 
 %!warning <warning message> warning ('warning message');
 
-%!## test of shared variables
+## test of shared variables
 %!shared a                # create a shared variable
 %!test   a=3;             # assign to a shared variable
 %!test   assert (a,3)     # variable should equal 3
@@ -807,17 +808,17 @@
 %! assert (x,6);
 %! assert (z,9);
 
-%!## test of assert block
+## test of assert block
 %!assert (isempty ([]))      # support for test assert shorthand
 
-%!## demo blocks
+## demo blocks
 %!demo                   # multiline demo block
 %! t = [0:0.01:2*pi]; x = sin (t);
 %! plot (t,x);
 %! % you should now see a sine wave in your figure window
 %!demo a=3               # single line demo blocks work too
 
-%!## this is a comment block. it can contain anything.
+## this is a comment block. it can contain anything.
 %!##
 %! it is the "#" as the block type that makes it a comment
 %! and it stays as a comment even through continuation lines
--- a/scripts/time/addtodate.m
+++ b/scripts/time/addtodate.m
@@ -21,8 +21,9 @@
 ## Add @var{q} amount of time (with units @var{f}) to the serial datenum,
 ## @var{d}.
 ##
-## @var{f} must be one of "year", "month", "day", "hour", "minute", "second",
-## or "millisecond".
+## @var{f} must be one of @qcode{"year"}, @qcode{"month"}, @qcode{"day"},
+## @qcode{"hour"}, @qcode{"minute"}, @qcode{"second"}, or
+## @qcode{"millisecond"}.
 ## @seealso{datenum, datevec, etime}
 ## @end deftypefn
 
--- a/scripts/time/asctime.m
+++ b/scripts/time/asctime.m
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} asctime (@var{tm_struct})
 ## Convert a time structure to a string using the following 
-## format: "ddd mmm mm HH:MM:SS yyyy".  For example:
+## format: @qcode{"ddd mmm mm HH:MM:SS yyyy"}.  For example:
 ##
 ## @example
 ## @group
--- a/scripts/time/clock.m
+++ b/scripts/time/clock.m
@@ -54,6 +54,7 @@
 
 endfunction
 
+
 %!test
 %! t1 = clock;
 %! t2 = str2num (strftime ("[%Y, %m, %d, %H, %M, %S]", localtime (time ())));
--- a/scripts/time/datenum.m
+++ b/scripts/time/datenum.m
@@ -203,3 +203,4 @@
 %!error <expected date vector containing> datenum ([1, 2])
 %!error <expected date vector containing> datenum ([1,2,3,4,5,6,7])
 %!error <all inputs must be of class double> datenum (int32 (2000), int32 (1), int32 (1))
+
--- a/scripts/time/datestr.m
+++ b/scripts/time/datestr.m
@@ -37,16 +37,16 @@
 ##
 ## @multitable @columnfractions 0.1 0.45 0.35
 ## @headitem Code @tab Format @tab Example
-## @item  0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
-## @item  1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
-## @item  2 @tab mm/dd/yy               @tab 09/07/00
-## @item  3 @tab mmm                    @tab Sep
-## @item  4 @tab m                      @tab S
-## @item  5 @tab mm                     @tab 09
-## @item  6 @tab mm/dd                  @tab 09/07
-## @item  7 @tab dd                     @tab 07
-## @item  8 @tab ddd                    @tab Thu
-## @item  9 @tab d                      @tab T
+## @item 0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
+## @item 1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
+## @item 2 @tab mm/dd/yy               @tab 09/07/00
+## @item 3 @tab mmm                    @tab Sep
+## @item 4 @tab m                      @tab S
+## @item 5 @tab mm                     @tab 09
+## @item 6 @tab mm/dd                  @tab 09/07
+## @item 7 @tab dd                     @tab 07
+## @item 8 @tab ddd                    @tab Thu
+## @item 9 @tab d                      @tab T
 ## @item 10 @tab yyyy                   @tab 2000
 ## @item 11 @tab yy                     @tab 00
 ## @item 12 @tab mmmyy                  @tab Sep00
--- a/scripts/time/datetick.m
+++ b/scripts/time/datetick.m
@@ -24,23 +24,35 @@
 ## @deftypefnx {Function File} {} datetick (@dots{}, "keepticks")
 ## @deftypefnx {Function File} {} datetick (@var{hax}, @dots{})
 ## Add date formatted tick labels to an axis.  The axis to apply the
-## ticks to is determined by @var{axis} which can take the values "x",
-## "y", or "z".  The default value is "x".  The formatting of the labels is
-## determined by the variable @var{form}, which can either be a string or
-## positive integer that @code{datestr} accepts.
+## ticks to is determined by @var{axis} which can take the values @qcode{"x"},
+## @qcode{"y"}, or @qcode{"z"}.  The default value is @qcode{"x"}.  The
+## formatting of the labels is determined by the variable @var{form}, which
+## can either be a string or positive integer that @code{datestr} accepts.
 ## @seealso{datenum, datestr}
 ## @end deftypefn
 
 function datetick (varargin)
 
-  [h, varargin, nargin] = __plt_get_axis_arg__ ("datetick", varargin{:});
+  [hax, varargin, nargin] = __plt_get_axis_arg__ ("datetick", varargin{:});
 
-  oldh = gca ();
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
+  if (isempty (hax))
+    hax = gca ();
+  endif 
+
   unwind_protect
-    axes (h);
+    ## FIXME: This will bring the axes to the top of the stack.
+    ##        This may not always be desirable if there are multiple axes
+    ##        objects.
+    axes (hax);
     __datetick__ (varargin{:});
   unwind_protect_cleanup
-    axes (oldh);
+    if (! isempty (oldfig))
+      set (0, "currentfigure", oldfig);
+    endif
   end_unwind_protect
 
 endfunction
@@ -61,7 +73,7 @@
 %! yr = 1988:2:2002;
 %! yr = datenum (yr,1,1);
 %! pr = [12.1 13.3 12.6 13.1 13.3 14.1 14.4 15.2];
-%! plot (yr, pr);
+%! plot (yr, pr, "-o");
 %! xlabel ("year");
 %! ylabel ("average price");
 %! ax = gca;
@@ -75,31 +87,26 @@
 function __datetick__ (varargin)
 
   keeplimits = false;
+  idx = strcmpi (varargin, "keeplimits");
+  if (any (idx))
+    keeplimits = true;
+    varargin = varargin(! idx);
+  endif
   keepticks = false;
-  idx = [];
-  for i = 1 : nargin
-    arg = varargin {i};
-    if (ischar (arg))
-      if (strcmpi (arg, "keeplimits"))
-        keeplimits = true;
-        idx = [idx, i];
-      elseif (strcmpi (arg, "keepticks"))
-        keepticks = true;
-        idx = [idx, i];
-      endif
-    endif
-  endfor
+  idx = strcmpi (varargin, "keepticks");
+  if (any (idx))
+    keepticks = true;
+    varargin = varargin(! idx);
+  endif
 
-  varargin(idx) = [];
-  nargin = length (varargin);
+  nargin = numel (varargin); 
   form = [];
   ax = "x";
 
   if (nargin != 0)
     arg = varargin{1};
-    if (ischar (arg) && (strcmp (arg, "x") || strcmp (arg, "y")
-                         || strcmp (arg, "z")))
-      ax = arg;
+    if (ischar (arg) && any (strcmpi (arg, {"x", "y", "z"})))
+      ax = tolower (arg);
       if (nargin > 1)
         form = varargin{2};
         varargin(1:2) = [];
@@ -121,7 +128,7 @@
 
   if (! isempty (form))
     if (isnumeric (form))
-      if (! isscalar (form) || floor (form) != form || form < 0)
+      if (! isscalar (form) || form < 0 || form != fix (form))
         error ("datetick: expecting FORM argument to be a positive integer");
       endif
     elseif (! ischar (form))
@@ -130,7 +137,7 @@
   endif
 
   if (keepticks)
-    ticks = get (gca (), strcat (ax, "tick"));
+    ticks = get (gca (), [ax "tick"]);
   else
     ## Need to do our own axis tick position calculation as
     ## year, etc, don't fallback on nice datenum values.
@@ -139,8 +146,8 @@
     xmin = NaN;
     for i = 1 : length (objs)
       fld = get (objs (i));
-      if (isfield (fld, strcat (ax, "data")))
-        xdata = getfield (fld, strcat (ax, "data"))(:);
+      if (isfield (fld, [ax "data"]))
+        xdata = getfield (fld, [ax "data"])(:);
         xmin = min (xmin, min (xdata));
         xmax = max (xmax, max (xdata));
       endif
@@ -209,7 +216,7 @@
       ## days
       form = 8;
     elseif (r < 365)
-      ## FIXME -- FORM should be 19 for European users who use dd/mm
+      ## FIXME: FORM should be 19 for European users who use dd/mm
       ## instead of mm/dd.  How can that be determined automatically?
       ## months
       form = 6;
@@ -243,17 +250,17 @@
 
   if (keepticks)
     if (keeplimits)
-      set (gca (), strcat (ax, "ticklabel"), sticks);
+      set (gca (), [ax "ticklabel"], sticks);
     else
-      set (gca (), strcat (ax, "ticklabel"), sticks, strcat (ax, "lim"),
-      [min(ticks), max(ticks)]);
+      set (gca (), [ax "ticklabel"], sticks,
+                   [ax "lim"], [min(ticks), max(ticks)]);
     endif
   else
     if (keeplimits)
-      set (gca (), strcat (ax, "tick"), ticks, strcat (ax, "ticklabel"), sticks);
+      set (gca (), [ax "tick"], ticks, [ax "ticklabel"], sticks);
     else
-      set (gca (), strcat (ax, "tick"), ticks, strcat (ax, "ticklabel"), sticks,
-      strcat (ax, "lim"), [min(ticks), max(ticks)]);
+      set (gca (), [ax "tick"], ticks, [ax "ticklabel"], sticks,
+                   [ax "lim"], [min(ticks), max(ticks)]);
     endif
   endif
 endfunction
--- a/scripts/time/weekday.m
+++ b/scripts/time/weekday.m
@@ -24,14 +24,14 @@
 ##
 ## @var{d} is a serial date number or a date string.
 ##
-## If the string @var{format} is not present or is equal to "short" then
+## If the string @var{format} is not present or is equal to @qcode{"short"} then
 ## @var{s} will contain the abbreviated name of the weekday.  If @var{format}
-## is "long" then @var{s} will contain the full name.
+## is @qcode{"long"} then @var{s} will contain the full name.
 ##
 ## Table of return values based on @var{format}:
 ##
 ## @multitable @columnfractions .06 .13 .16
-## @headitem @var{n} @tab "short" @tab "long"
+## @headitem @var{n} @tab @qcode{"short"} @tab @qcode{"long"}
 ## @item 1 @tab Sun @tab Sunday
 ## @item 2 @tab Mon @tab Monday
 ## @item 3 @tab Tue @tab Tuesday
--- a/scripts/ui/errordlg.m
+++ b/scripts/ui/errordlg.m
@@ -24,7 +24,7 @@
 ## The message may have multiple lines separated by newline characters
 ## ("\n"), or it may be a cellstr array with one element for each
 ## line.  The optional input @var{title} (character string) can be used to
-## set the dialog caption.  The default title is "Error Dialog".
+## set the dialog caption.  The default title is @qcode{"Error Dialog"}.
 ##
 ## The return value is always 1.
 ## @seealso{helpdlg, inputdlg, listdlg, msgbox, questdlg, warndlg}
@@ -48,3 +48,4 @@
 %!demo
 %! disp ('- test errordlg with prompt and caption.');
 %! errordlg ('Oops another error','This is a very long and informative caption');
+
--- a/scripts/ui/helpdlg.m
+++ b/scripts/ui/helpdlg.m
@@ -24,7 +24,7 @@
 ## The message may have multiple lines separated by newline characters
 ## ("\n"), or it may be a cellstr array with one element for each
 ## line.  The optional input @var{title} (character string) can be used to
-## set the dialog caption.  The default title is "Help Dialog".
+## set the dialog caption.  The default title is @qcode{"Help Dialog"}.
 ##
 ## The return value is always 1.
 ## @seealso{errordlg, inputdlg, listdlg, msgbox, questdlg, warndlg}
--- a/scripts/ui/inputdlg.m
+++ b/scripts/ui/inputdlg.m
@@ -32,7 +32,8 @@
 ## A cell array with strings labeling each text field.  This input is required. 
 ##
 ## @item title
-## String to use for the caption of the dialog.  The default is "Input Dialog".
+## String to use for the caption of the dialog.  The default is @qcode{"Input
+## Dialog"}.
 ##
 ## @item rowscols
 ## Specifies the size of the text fields and can take three forms:
@@ -65,7 +66,7 @@
 
   if (iscell (prompt))
     ## Silently extract only char elements
-    prompt = prompt(cellfun ("ischar", prompt));
+    prompt = prompt(cellfun ("isclass", prompt, "char"));
   elseif (ischar (prompt))
     prompt = {prompt};
   else
--- a/scripts/ui/listdlg.m
+++ b/scripts/ui/listdlg.m
@@ -27,37 +27,37 @@
 ## The indices in @var{sel} are 1-based.
 ##
 ## The arguments are specified in form of @var{key}, @var{value} pairs. 
-## The "ListString" argument pair must be specified.
+## The @qcode{"ListString"} argument pair must be specified.
 ##
 ## Valid @var{key} and @var{value} pairs are:
 ##
 ## @table @asis
-## @item "ListString"
+## @item @qcode{"ListString"}
 ## a cell array of strings comprising the content of the list.
 ##
-## @item "SelectionMode"
-## can be either "Single" or "Multiple" (default).
+## @item @qcode{"SelectionMode"}
+## can be either @qcode{"Single"} or @qcode{"Multiple"} (default).
 ##
-## @item "ListSize"
+## @item @qcode{"ListSize"}
 ## a vector with two elements @var{width} and @var{height} defining
 ## the size of the list field in pixels.  Default is [160 300].
 ##
-## @item "InitialValue"
+## @item @qcode{"InitialValue"}
 ## a vector containing 1-based indices of preselected elements.  Default
 ## is 1 (first item).
 ##
-## @item "Name"
+## @item @qcode{"Name"}
 ## a string to be used as the dialog caption.  Default is "".
 ##
-## @item "PromptString"
+## @item @qcode{"PromptString"}
 ## a cell array of strings to be displayed above the list field.  Default
 ## is @{@}.
 ##
-## @item "OKString"
-## a string used to label the OK button.  Default is "OK".
+## @item @qcode{"OKString"}
+## a string used to label the OK button.  Default is @qcode{"OK"}.
 ##
-## @item "CancelString"
-## a string used to label the Cancel button.  Default is "Cancel".
+## @item @qcode{"CancelString"}
+## a string used to label the Cancel button.  Default is @qcode{"Cancel"}.
 ## @end table
 ##
 ## Example:
--- a/scripts/ui/msgbox.m
+++ b/scripts/ui/msgbox.m
@@ -23,13 +23,13 @@
 ## Display @var{msg} using a message dialog box. 
 ##
 ## The message may have multiple lines separated by newline characters
-## (@code{"\n"}), or it may be a cellstr array with one element for each
+## (@qcode{"\n"}), or it may be a cellstr array with one element for each
 ## line.  The optional input @var{title} (character string) can be used to
 ## decorate the dialog caption.
 ##
 ## The optional argument @var{icon} selects a dialog icon. 
-## It can be one of @code{"none"} (default), @code{"error"}, @code{"help"}, or
-## @code{"warn"}.
+## It can be one of @qcode{"none"} (default), @qcode{"error"},
+## @qcode{"help"}, or @qcode{"warn"}.
 ##
 ## The return value is always 1.
 ## @seealso{errordlg, helpdlg, inputdlg, listdlg, questdlg, warndlg}
@@ -45,10 +45,12 @@
 
 endfunction
 
-%!demo
-%!  disp('- test msgbox message only.');
-%!  msgbox("Below, you should see 3 lines:\nline #1\nline #2, and\nline #3.");
 
 %!demo
-%!  disp('- test msgbox message and caption.');
-%!  msgbox('You should see a single line.','A msgbox');
+%! disp('- test msgbox message only.');
+%! msgbox("Below, you should see 3 lines:\nline #1\nline #2, and\nline #3.");
+
+%!demo
+%! disp('- test msgbox message and caption.');
+%! msgbox('You should see a single line.','A msgbox');
+
--- a/scripts/ui/private/message_dialog.m
+++ b/scripts/ui/private/message_dialog.m
@@ -63,3 +63,4 @@
   endif
 
 endfunction
+
--- a/scripts/ui/questdlg.m
+++ b/scripts/ui/questdlg.m
@@ -38,7 +38,8 @@
 ## @var{btn3}.
 ##
 ## If only @var{msg} and @var{title} are specified, three buttons with
-## the default captions "Yes", "No", and "Cancel" are used.
+## the default captions @qcode{"Yes"}, @qcode{"No"}, and @qcode{"Cancel"} are
+## used.
 ##
 ## If only two button captions, @var{btn1} and @var{btn2}, are specified 
 ## the dialog will have only these two buttons.
@@ -81,7 +82,7 @@
       options{4} = varargin{1};  # default
       if (! any (strcmp (options{4}, options(1:3))))
         error (defbtn_error_msg);
-      end
+      endif
 
     case 3
       ## two buttons and default button string
@@ -91,7 +92,7 @@
       options{4} = varargin{3};  # default
       if (! any (strcmp (options{4}, options([1 3]))))
         error (defbtn_error_msg);
-      end
+      endif
 
     case 4
       ## three buttons and default button string
@@ -101,7 +102,7 @@
       options{4} = varargin{4};  # default
       if (! any (strcmp (options{4}, options(1:3))))
         error (defbtn_error_msg);
-      end
+      endif
 
     otherwise
       print_usage ();
--- a/scripts/ui/warndlg.m
+++ b/scripts/ui/warndlg.m
@@ -24,7 +24,7 @@
 ## The message may have multiple lines separated by newline characters
 ## ("\n"), or it may be a cellstr array with one element for each
 ## line.  The optional input @var{title} (character string) can be used to
-## set the dialog caption.  The default title is "Warning Dialog".
+## set the dialog caption.  The default title is @qcode{"Warning Dialog"}.
 ##
 ## @seealso{helpdlg, inputdlg, listdlg, questdlg}
 ## @end deftypefn
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -98,6 +98,7 @@
   $(GENERATED_BC_OVERLOADS_FILES)
 
 DISTCLEANFILES = \
+  .gdbinit \
   fntests.log
 
 fixedtestsdir := $(octtestsdir)/fixed
--- a/test/args.tst
+++ b/test/args.tst
@@ -123,98 +123,98 @@
 %!  assert (x, 0);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## numeric vector (spaces)
 %!function f (x = [0 1 2])
 %!  assert (x, [0 1 2]);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## numeric vector (range)
 %!function f (x = 1:3)
 %!  assert (x, 1:3);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## numeric vector (commas)
 %!function f (x = [0,1,2])
 %!  assert (x, [0 1 2]);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## numeric vector (commas and spaces)
 %!function f (x = [0, 1, 2])
 %!  assert (x, [0 1 2]);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## numeric matrix
 %!function f (x = [0, 1, 2;3, 4, 5])
 %!  assert (x, [0 1 2;3 4 5]);
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## empty cell
 %!function f (x = {})
 %!  assert (x, {});
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## full cell
 %!function f (x = {1})
 %!  assert (x, {1});
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## many cells
 %!function f (x = {1 'a' "b" 2.0 struct("a", 3)})
 %!  assert (x, {1 'a' "b" 2.0 struct("a", 3)});
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## struct
 %!function f (x = struct("a", 3))
 %!  assert (x, struct ("a", 3));
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## char (double quotes)
 %!function f (x = "a")
 %!  assert (x, "a");
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## char (single quotes)
 %!function f (x = 'a')
 %!  assert (x, "a");
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## char (string, double quotes)
 %!function f (x = "abc123")
 %!  assert (x, "abc123");
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## char (string, double quotes, punctuation)
 %!function f (x = "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\")
 %!  assert (x, "abc123`1234567890-=~!@#$%^&*()_+[]{}|;':\",./<>?\\");
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## Function handle (builtin)
 %!function f (x = @sin)
@@ -223,7 +223,7 @@
 %!  assert (isa (x, "function_handle") && strcmp (fname, "sin"));
 %!endfunction
 %!test
-%!  f()
+%! f()
 
 ## Function handle (anonymous)
 %!function f (x = @(x) x.^2)
@@ -232,5 +232,5 @@
 %!  assert (isa (x, "function_handle") && strcmp (ftype, "anonymous"));
 %!endfunction
 %!test
-%!  f()
+%! f()
 
--- a/test/build-sparse-tests.sh
+++ b/test/build-sparse-tests.sh
@@ -325,7 +325,7 @@
 %!test
 %! sv = as.^bf;
 %! fv = af.^bf;
-%! idx = find (af~=0);
+%! idx = find (af!=0);
 %! assert (sv(:)(idx), sparse (fv(:)(idx)), 100*eps)
 
 EOF
@@ -342,7 +342,7 @@
 %!test
 %! sv = as.^bs;
 %! fv = af.^bf;
-%! idx = find (af~=0);
+%! idx = find (af!=0);
 %! assert(sv(:)(idx), sparse (fv(:)(idx)), 100*eps)
 
 EOF
@@ -577,11 +577,11 @@
 %!assert (issparse (as.'))
 %!assert (issparse (as'))
 %!assert (issparse (-as))
-%!assert (~as, sparse (~af))
+%!assert (!as, sparse (!af))
 %!assert (as.', sparse (af.'));
 %!assert (as',  sparse (af'));
 %!assert (-as, sparse (-af));
-%!assert (~as, sparse (~af));
+%!assert (!as, sparse (!af));
 %!error [i,j] = size (af);as(i-1,j+1);
 %!error [i,j] = size (af);as(i+1,j-1);
 %!test
@@ -653,7 +653,7 @@
 %!testif HAVE_UMFPACK   # simple LU + row permutations
 %! [L,U,P] = lu (bs);
 %! assert (P'*L*U, bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -662,7 +662,7 @@
 %!testif HAVE_UMFPACK   # simple LU + row/col permutations
 %! [L,U,P,Q] = lu (bs);
 %! assert (P'*L*U*Q', bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -671,7 +671,7 @@
 %!testif HAVE_UMFPACK   # LU with vector permutations
 %! [L,U,P,Q] = lu (bs,'vector');
 %! assert (L(P,:)*U(:,Q), bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -680,7 +680,7 @@
 %!testif HAVE_UMFPACK   # LU with scaling
 %! [L,U,P,Q,R] = lu (bs);
 %! assert (R*P'*L*U*Q', bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -757,7 +757,7 @@
 %!testif HAVE_UMFPACK   # simple LU + row permutations
 %! [L,U,P] = lu (bs);
 %! assert (P'*L*U, bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -766,7 +766,7 @@
 %!testif HAVE_UMFPACK   # simple LU + row/col permutations
 %! [L,U,P,Q] = lu (bs);
 %! assert (P'*L*U*Q', bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -775,7 +775,7 @@
 %!testif HAVE_UMFPACK   # LU with vector permutations
 %! [L,U,P,Q] = lu (bs,'vector');
 %! assert (L (P,:)*U (:,Q), bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -784,7 +784,7 @@
 %!testif HAVE_UMFPACK   # LU with scaling
 %! [L,U,P,Q,R] = lu (bs);
 %! assert (R*P'*L*U*Q', bs, 1e-10);
-%! # triangularity
+%! ## triangularity
 %! [i,j,v] = find (L);
 %! assert (i-j>=0);
 %! [i,j,v] = find (U);
@@ -1204,7 +1204,7 @@
 gen_section
 gen_save_tests
 gen_section
-echo '%!test bf = bf+1i*(bf~=0);' >> $TESTS
+echo '%!test bf = bf+1i*(bf!=0);' >> $TESTS
 gen_rectangular_tests
 gen_section
 
@@ -1242,7 +1242,7 @@
 echo '%! as = sparse (af);' >> $TESTS
 gen_square_tests
 gen_section
-echo '%!test bf = bf+1i*(bf~=0);' >> $TESTS
+echo '%!test bf = bf+1i*(bf!=0);' >> $TESTS
 echo '%! bs = sparse (bf);' >> $TESTS
 gen_square_tests
 gen_section
--- a/test/classes/@Snork/end.m
+++ b/test/classes/@Snork/end.m
@@ -1,6 +1,6 @@
 function r = end (snk, index_pos, num_indices)
 
-  if (num_indices ~= 1)
+  if (num_indices != 1)
     error ('Snork object may only have one index')
   end
 
--- a/test/classes/@Snork/mpower.m
+++ b/test/classes/@Snork/mpower.m
@@ -1,6 +1,6 @@
 function s = mpower (s1, x)
 
-  if (~isa (s1, 'Snork') || isa (x, 'Snork'))
+  if (!isa (s1, 'Snork') || isa (x, 'Snork'))
     error ('mpower Snork!!!');
   end
 
--- a/test/classes/@Snork/ne.m
+++ b/test/classes/@Snork/ne.m
@@ -1,5 +1,5 @@
 function b = ne (s1, s2)
 
-  b = ~(s1 == s2);
+  b = !(s1 == s2);
 
 end
--- a/test/classes/@Snork/power.m
+++ b/test/classes/@Snork/power.m
@@ -1,6 +1,6 @@
 function s = power (s1, x)
 
-  if (~isa (s1, 'Snork') || isa (x, 'Snork'))
+  if (!isa (s1, 'Snork') || isa (x, 'Snork'))
     error ('power Snork!!!');
   end
 
--- a/test/classes/@Snork/subsasgn.m
+++ b/test/classes/@Snork/subsasgn.m
@@ -6,7 +6,7 @@
   switch (s(1).type)
     case '()'
       ind = s(1).subs;
-      if (numel (ind) ~= 1)
+      if (numel (ind) != 1)
         error ('Snork: need exactly one index');
       else
         if (length (s) == 1)
@@ -17,7 +17,7 @@
       end
     case '{}'
       ind = s(1).subs;
-      if (numel (ind) ~= 1)
+      if (numel (ind) != 1)
         error ('Snork: need exactly one index');
       else
         if (length (s) == 1)
--- a/test/classes/@Snork/subsref.m
+++ b/test/classes/@Snork/subsref.m
@@ -6,14 +6,14 @@
   switch (s(1).type)
     case '()'
       ind = s(1).subs;
-      if (numel (ind) ~= 1)
+      if (numel (ind) != 1)
         error ('Snork: need exactly one index');
       else
         b = snk.cack(ind{1});
       end
     case '{}'
       ind = s(1).subs;
-      if (numel (ind) ~= 1)
+      if (numel (ind) != 1)
         error ('Snork: need exactly one index');
       else
         b = snk.cack(ind{1});
--- a/test/classes/@Spork/loadobj.m
+++ b/test/classes/@Spork/loadobj.m
@@ -1,7 +1,7 @@
 function out = loadobj (in)
 
   out = in;
-  if (~isa (in, 'Spork'))
+  if (!isa (in, 'Spork'))
     out.cack = [];
   end
 
--- a/test/classes/classes.tst
+++ b/test/classes/classes.tst
@@ -59,9 +59,9 @@
 %! assert (isobject (snk));
 %! assert (isequal (class (snk), 'Snork'));
 %! assert (isa (snk, 'Snork'));
-%! assert (~isa (snk, 'Sneetch'));
+%! assert (!isa (snk, 'Sneetch'));
 %! assert (ismethod (snk, 'gick'));
-%! assert (~ismethod (snk, 'bletch'));
+%! assert (!ismethod (snk, 'bletch'));
 %! assert (exist ('snk') == 1);
 %! assert (exist ('blink') == 0);
 %!test snk1 = Snork (snk);
@@ -272,17 +272,17 @@
 %!assert (s1 == s1)
 %!assert (s1 == x1)
 %!assert (x1 == s1)
-%!assert (~(s1 == (s1 + 1)))
-%!assert (~(s1 == (x1 + 1)))
-%!assert (~(x1 == (s1 + 1)))
+%!assert (!(s1 == (s1 + 1)))
+%!assert (!(s1 == (x1 + 1)))
+%!assert (!(x1 == (s1 + 1)))
 
-%% Test overloaded ne (~=) for the Snork class
-%!assert (~(s1 ~= s1))
-%!assert (~(s1 ~= x1))
-%!assert (~(x1 ~= s1))
-%!assert (s1 ~= (s1 + 1))
-%!assert (x1 ~= (s1 + 1))
-%!assert (s1 ~= (x1 + 1))
+%% Test overloaded ne (!=) for the Snork class
+%!assert (!(s1 != s1))
+%!assert (!(s1 != x1))
+%!assert (!(x1 != s1))
+%!assert (s1 != (s1 + 1))
+%!assert (x1 != (s1 + 1))
+%!assert (s1 != (x1 + 1))
 
 %% Test overloaded lt (<) for the Snork class
 %!assert (s1 < (s1 + 1))
--- a/test/for.tst
+++ b/test/for.tst
@@ -19,7 +19,7 @@
 %!test
 %! for i = 1
 %!   __printf_assert__ ("%d", i);
-%! end
+%! end  # "end" is part of test, check not using "endfor"
 %! __printf_assert__ ("\n");
 %! assert (__prog_output_assert__ ("1"));
 
@@ -101,10 +101,25 @@
 %!   assert (i, {1 + 2*j; 2 + 2*j++})
 %! endfor
 
-%% test parsing of single-quoted character string appearing at the
-%% beginning of a for loop
+## test parsing of single-quoted character string appearing at the
+## beginning of a for loop
 %!test
 %! for i = 1:5
 %!   'foo';
 %! endfor
 %! assert (i, 5);
+
+%!test
+%! parfor i = 1
+%!   __printf_assert__ ("%d", i);
+%! end  # "end" is part of test, check not using "endparfor"
+%! __printf_assert__ ("\n");
+%! assert (__prog_output_assert__ ("1"));
+
+%!test
+%! parfor i = 1:4
+%!   __printf_assert__ ("%d", i);
+%! endparfor
+%! __printf_assert__ ("\n");
+%! assert (__prog_output_assert__ ("1234"));
+
--- a/test/global.tst
+++ b/test/global.tst
@@ -39,8 +39,8 @@
 %!  global H = 1;
 %!endfunction
 %!test
-%!  f;
-%!  fail ("H");
+%! f;
+%! fail ("H");
 
 %!function f ()
 %!  global H = 1;
--- a/test/if.tst
+++ b/test/if.tst
@@ -21,7 +21,7 @@
 %! if (i == 0)
 %!   i++;
 %!   __printf_assert__ ("%d\n", i);
-%! endif
+%! end  # "end" is part of test, check not using "endif"
 %! assert (__prog_output_assert__ ("1"));
 
 %!test
@@ -29,7 +29,7 @@
 %!   __printf_assert__ ("fail\n");
 %! else
 %!   __printf_assert__ ("pass\n");
-%! end
+%! endif
 %! assert (__prog_output_assert__ ("pass"));
 
 %!test
@@ -50,7 +50,7 @@
 %!   __printf_assert__ ("fail\n");
 %! elseif (y)
 %!   __printf_assert__ ("pass\n");
-%! end
+%! endif
 %! assert (__prog_output_assert__ ("pass"));
 
 %!test
@@ -76,11 +76,11 @@
 %!   __printf_assert__ ("fail\n");
 %! elseif (x)
 %!   __printf_assert__ ("fail\n");
-%! end
+%! endif
 %! assert (__prog_output_assert__ ("pass"));
 
-%% test parsing of single-quoted character string appearing at the
-%% beginning of an if condition
+## test parsing of single-quoted character string appearing at the
+## beginning of an if condition
 %!test
 %! if (1)
 %!   'foo';
@@ -88,8 +88,8 @@
 %! endif
 %! assert (x, 13);
 
-%% test parsing of single-quoted character string appearing at the
-%% beginning of an if condition
+## test parsing of single-quoted character string appearing at the
+## beginning of an if condition
 %!test
 %! if (0)
 %!   x = 42;
@@ -98,3 +98,4 @@
 %!   x = 13;
 %! endif
 %! assert (x, 13);
+
--- a/test/index.tst
+++ b/test/index.tst
@@ -134,7 +134,7 @@
 %!assert (b([],3), zeros (0,1))
 
 %!shared x
-%! # Dummy shared block to clear any previous definitions
+%! ## Dummy shared block to clear any previous definitions
 %! x = 1;
 
 %!test
--- a/test/io.tst
+++ b/test/io.tst
@@ -178,7 +178,7 @@
 %!  ret = 1;
 %!endfunction
 
-%!test
+%!testif HAVE_ZLIB
 %!
 %! [save_status, save_files] = testls (0);
 %! [load_status, load_files] = testls (1);
@@ -222,7 +222,7 @@
 %! matrix1 = rand (100, 2);
 %! save -ascii matrix.ascii matrix1
 %! matrix2 = load ("matrix.ascii");
-%! assert (matrix1, matrix2, 1e-9)
+%! assert (matrix1, matrix2, 1e-9);
 %!
 %! delete matrix.ascii;
 
@@ -237,7 +237,6 @@
 %!assert (puts (1),-1)
 
 %!error <Invalid call to puts> puts ()
-
 %!error <Invalid call to puts> puts (1, 2)
 
 %!assert (sscanf ('123456', '%10c'), '123456')
@@ -245,11 +244,11 @@
 
 %!assert (sscanf (['ab'; 'cd'], '%s'), 'acbd')
 
-%!assert (sscanf ('02:08:30', '%i:%i:%i'), [2; 0]);
-%!assert (sscanf ('02:08:30', '%d:%d:%d'), [2; 8; 30]);
+%!assert (sscanf ('02:08:30', '%i:%i:%i'), [2; 0])
+%!assert (sscanf ('02:08:30', '%d:%d:%d'), [2; 8; 30])
 
-%!assert (sscanf ('0177 08', '%i'), [127; 0; 8]);
-%!assert (sscanf ('0177 08', '%d'), [177; 8]);
+%!assert (sscanf ('0177 08', '%i'), [127; 0; 8])
+%!assert (sscanf ('0177 08', '%d'), [177; 8])
 
 %!test
 %! [val, count, msg, pos] = sscanf ("3I2", "%f");
@@ -282,9 +281,7 @@
 %! && v2 == [1; 2] && c2 == 2 && ischar (m2)));
 
 %!error <Invalid call to sscanf> sscanf ()
-
 %!error sscanf (1, 2)
-
 %!error <Invalid call to sscanf> sscanf ("foo", "bar", "C", 1)
 
 %!test
@@ -305,24 +302,28 @@
 %! assert (str, "test:1");
 
 %!error printf (1)
-
 %!error <Invalid call to printf> printf ()
 
 %!test
 %! [s, msg, status] = sprintf ("%s: %d\n", "test", 1);
-%!
 %! assert (s == "test: 1\n" && ischar (msg) && status == 8);
 
-%!error sprintf (1)
+%!assert (sprintf ("%-+6.2f", Inf), "+Inf  ")
+%!assert (sprintf ("%-6.2f", Inf), "Inf   ")
+%!assert (sprintf ("%-+6.2f", nan), "+NaN  ")  # lowercase nan is part of test
+%!assert (sprintf ("%-6.2f", nan), "NaN   ")
+%!assert (sprintf ("%-+6.2f", NA), "+NA   ")
+%!assert (sprintf ("%-6.2f", NA), "NA    ")
 
 %!error <Invalid call to sprintf> sprintf ()
+%!error <format TEMPLATE must be a string> sprintf (1)
 
 %!test
-%! arch_list = {"native"; "ieee-le"; "ieee-be"; "vaxd"; "vaxg"; "cray"};
-%! warning ("off", "Octave:fopen-mode")
+%! arch_list = {"native"; "ieee-le"; "ieee-be"};
+%! warning ("off", "Octave:fopen-mode");
 %! status = 1;
 %!
-%! for i = 1:6
+%! for i = 1:3
 %!   arch = arch_list{i};
 %!   for j = 1:4
 %!     if (j == 1)
@@ -386,17 +387,14 @@
 %! assert (__prog_output_assert__ ("error:"));
 
 %!error <Invalid call to fopen> fopen ()
-
 %!error <Invalid call to fopen> fopen ("foo", "wb", "native", 1)
 
 %!error fclose (0)
-
 %!error <Invalid call to fclose> fclose (1, 2)
 
 %!assert (ischar (tmpnam ()))
 
 %!warning tmpnam (1);
-
 %!warning tmpnam ("foo", 1);
 
 %!error <Invalid call to tmpnam> tmpnam (1, 2, 3)
@@ -472,81 +470,60 @@
 %! endif
 %! unlink (nm);
 
-%!error <Invalid call to fputs> fputs ()
-
-%!error <Invalid call to fputs> fputs (1, "foo", 1)
-
 %!assert (fputs (1, 1),-1)
 
-%!error <Invalid call to fgetl> fgetl ()
-
-%!error <Invalid call to fgetl> fgetl (1, 2, 3)
+%!error <Invalid call to fputs> fputs ()
+%!error <Invalid call to fputs> fputs (1, "foo", 1)
 
 %!error fgetl ("foo", 1)
 
-%!error <Invalid call to fgets> fgets ()
-
-%!error <Invalid call to fgets> fgets (1, 2, 3)
+%!error <Invalid call to fgetl> fgetl ()
+%!error <Invalid call to fgetl> fgetl (1, 2, 3)
 
 %!error fgets ("foo", 1)
 
-%!error <Invalid call to fprintf> fprintf ()
-
-%!error <Invalid call to fprintf> fprintf (1)
+%!error <Invalid call to fgets> fgets ()
+%!error <Invalid call to fgets> fgets (1, 2, 3)
 
 %!test
 %! s.a = 1;
 %! fail ("fprintf (s)", "Invalid call to fprintf");
 
+%!error <Invalid call to fprintf> fprintf ()
+%!error <Invalid call to fprintf> fprintf (1)
 %!error fprintf (1, 1)
-
 %!error fprintf (-1, "foo")
 
-%!error <Invalid call to fscanf> fscanf ()
-
-%!error <Invalid call to fscanf> fscanf (1)
-
 %!error fscanf ("foo", "bar")
 
-%!error <Invalid call to fread> fread ()
+%!error <Invalid call to fscanf> fscanf ()
+%!error <Invalid call to fscanf> fscanf (1)
 
+%!error <Invalid call to fread> fread ()
 %!error <Invalid call to fread> fread (1, 2, "char", 1, "native", 2)
-
 %!error fread ("foo")
 
 %!error <Invalid call to fwrite> fwrite ()
-
 %!error <Invalid call to fwrite> fwrite (1, rand (10), "char", 1, "native", 2)
-
 %!error fwrite ("foo", 1)
 
 %!error <Invalid call to feof> feof ()
-
 %!error <Invalid call to feof> feof (1, 2)
-
 %!error feof ("foo")
 
 %!error <Invalid call to ferror> ferror ()
-
 %!error <Invalid call to ferror> ferror (1, 'clear', 2)
-
 %!error ferror ("foo")
 
 %!error <Invalid call to ftell> ftell ()
-
 %!error <Invalid call to ftell> ftell (1, 2)
-
 %!error ftell ("foo")
 
 %!error <Invalid call to fseek> fseek ()
-
 %!error <Invalid call to fseek> fseek (1, 0, SEEK_SET, 1)
-
 %!error fseek ("foo", 0, SEEK_SET)
 
 %!error <Invalid call to frewind> frewind ()
-
 %!error <Invalid call to frewind> frewind (1, 2)
-
 %!error frewind ("foo")
 
--- a/test/jit.tst
+++ b/test/jit.tst
@@ -18,11 +18,18 @@
 
 ## Author: Max Brister <max@2bass.com>
 
+## Turn on JIT and set defaults before running tests
+%!testif HAVE_LLVM
+%! global __old_jit_enable__;
+%! global __old_jit_startcnt__;
+%! __old_jit_enable__ = jit_enable (true);
+%! __old_jit_startcnt__ = jit_startcnt (1000);
+
 ## Test some simple cases that compile.
 
-%!test
+%!testif HAVE_LLVM
 %! for i=1:1e6
-%!   if i < 5
+%!   if (i < 5)
 %!     break;
 %!   else
 %!     break;
@@ -30,24 +37,33 @@
 %! endfor
 %! assert (i, 1);
 
-%!test
-%! while 1
-%!   if 1
+%!testif HAVE_LLVM
+%! while (1)
+%!   if (1)
 %!     break;
-%!  else
-%!    break;
-%!  endif
+%!   else
+%!     break;
+%!   endif
 %! endwhile
 
-%!test
+%!testif HAVE_LLVM
 %! for i=1:1e6
-%!   if i == 100
+%!   if (i == 100)
 %!     break;
 %!   endif
 %! endfor
 %! assert (i, 100);
 
-%!test
+## Also test parfor keyword
+%!testif HAVE_LLVM
+%! parfor i=1:1e6
+%!   if (i == 100)
+%!     break;
+%!   endif
+%! endparfor
+%! assert (i, 100);
+
+%!testif HAVE_LLVM
 %! inc = 1e-5;
 %! result = 0;
 %! for ii = 0:inc:1
@@ -55,7 +71,7 @@
 %! endfor
 %! assert (abs (result - 1/9) < 1e-5);
 
-%!test
+%!testif HAVE_LLVM
 %! inc = 1e-5;
 %! result = 0;
 %! for ii = 0:inc:1
@@ -64,20 +80,20 @@
 %! endfor
 %! assert (abs (result - 1/9) < 1e-5);
 
-%!test
+%!testif HAVE_LLVM
 %! temp = 1+1i;
 %! nan = NaN;
-%! while 1
+%! while (1)
 %!   temp = temp - 1i;
 %!   temp = temp * nan;
 %!   break;
 %! endwhile
 %! assert (imag (temp), 0);
 
-%!test
+%!testif HAVE_LLVM
 %! temp = 1+1i;
 %! nan = NaN+1i;
-%! while 1
+%! while (1)
 %!   nan = nan - 1i;
 %!   temp = temp - 1i;
 %!   temp = temp * nan;
@@ -85,15 +101,15 @@
 %! endwhile
 %! assert (imag (temp), 0);
 
-%!test
+%!testif HAVE_LLVM
 %! temp = 1+1i;
-%! while 1
+%! while (1)
 %!   temp = temp * 5;
 %!   break;
 %! endwhile
 %! assert (temp, 5+5i);
 
-%!test
+%!testif HAVE_LLVM
 %! nr = 1001;
 %! mat = zeros (1, nr);
 %! for i = 1:nr
@@ -101,7 +117,7 @@
 %! endfor
 %! assert (mat == 1:nr);
 
-%!test
+%!testif HAVE_LLVM
 %! nr = 1001;
 %! mat = 1:nr;
 %! mat(end) = 0; # force mat to a matrix
@@ -111,19 +127,19 @@
 %! endfor
 %! assert (sum (mat) == total);
 
-%!test
+%!testif HAVE_LLVM
 %! nr = 1001;
 %! mat = [3 1 5];
 %! try
 %!   for i = 1:nr
-%!     if i > 500
+%!     if (i > 500)
 %!       result = mat(100);
 %!     else
 %!       result = i;
 %!     endif
 %!   endfor
 %! catch
-%! end
+%! end_try_catch
 %! assert (result == 500);
 
 %!function result = gen_test (n)
@@ -144,26 +160,26 @@
 %!  n = numel (A);
 %!  counter = 0;
 %!  for ii=1:n
-%!    if z(ii)
+%!    if (z(ii))
 %!      counter = counter + 1;
 %!    else
-%!      if counter > 0 && counter < K
+%!      if (counter > 0 && counter < K)
 %!        z(ii-counter:ii-1) = 0;
 %!      endif
 %!      counter = 0;
 %!    endif
 %!  endfor
 %!
-%!  if counter > 0 && counter < K
+%!  if (counter > 0 && counter < K)
 %!    z(end-counter+1:end) = 0;
 %!  endif
 %!endfunction
 
-%!test
+%!testif HAVE_LLVM
 %! test_set = gen_test (10000);
 %! assert (all (vectorized (test_set, 3) == loopy (test_set, 3)));
 
-%!test
+%!testif HAVE_LLVM
 %! niter = 1001;
 %! i = 0;
 %! while (i < niter)
@@ -171,7 +187,7 @@
 %! endwhile
 %! assert (i == niter);
 
-%!test
+%!testif HAVE_LLVM
 %! niter = 1001;
 %! result = 0;
 %! m = [5 10];
@@ -180,7 +196,7 @@
 %! endfor
 %! assert (result == m(end) * niter);
 
-%!test
+%!testif HAVE_LLVM
 %! ndim = 100;
 %! result = 0;
 %! m = zeros (ndim);
@@ -194,7 +210,7 @@
 %! endwhile
 %! assert (result == sum (sum (m)));
 
-%!test
+%!testif HAVE_LLVM
 %! ndim = 100;
 %! m = zeros (ndim);
 %! i = 1;
@@ -208,7 +224,7 @@
 %! m2(:) = 1:(ndim^2);
 %! assert (all (m == m2));
 
-%!test
+%!testif HAVE_LLVM
 %! ndim = 2;
 %! m = zeros (ndim, ndim, ndim, ndim);
 %! result = 0;
@@ -242,17 +258,22 @@
 %! end_unwind_protect
 %!endfunction
 
-%!error <division by zero> test_divide ()
+%!testif HAVE_LLVM
+%! lasterr ("");
+%! try
+%!   test_divide ();
+%! end_try_catch
+%! assert (strcmp (lasterr (), "division by zero"));
 
-%!test
-%! while 1
+%!testif HAVE_LLVM
+%! while (1)
 %!   a = 0;
 %!   result = a / 1;
 %!   break;
 %! endwhile
 %! assert (result, 0);
 
-%!test
+%!testif HAVE_LLVM
 %! m = zeros (2, 1001);
 %! for i=1:1001
 %!   m(end, i) = i;
@@ -263,7 +284,7 @@
 %! m2(2, :) = 1:1001;
 %! assert (m, m2);
 
-%!test
+%!testif HAVE_LLVM
 %! m = [1 2 3];
 %! for i=1:1001
 %!   m = sin (m);
@@ -271,21 +292,21 @@
 %! endfor
 %! assert (m == sin ([1  2 3]));
 
-%!test
+%!testif HAVE_LLVM
 %! i = 0;
 %! while i < 10
 %!   i += 1;
 %! endwhile
 %! assert (i == 10);
 
-%!test
+%!testif HAVE_LLVM
 %! i = 0;
 %! while i < 10
 %!   a = ++i;
 %! endwhile
 %! assert (i == 10);
 %! assert (a == 10);
-%!test
+%!testif HAVE_LLVM
 %! i = 0;
 %! while i < 10
 %!   a = i++;
@@ -293,7 +314,7 @@
 %! assert (i == 10);
 %! assert (a == 9);
 
-%!test
+%!testif HAVE_LLVM
 %! num = 2;
 %! a = zeros (1, num);
 %! i = 1;
@@ -315,17 +336,23 @@
 %!   endif;
 %! endwhile
 
-%!error test_compute_idom ()
+%!testif HAVE_LLVM
+%! lasterr ("");
+%! try
+%!   test_compute_idom ();
+%! end_try_catch
+%! assert (! isempty (lasterr ()));
 
 %!function x = test_overload (a)
-%!  while 1
+%!  while (1)
 %!    x = a;
 %!    break;
 %!  endwhile
 %!endfunction
 
-%!assert (test_overload (1), 1);
-%!assert (test_overload ([1 2]), [1 2]);
+%!testif HAVE_LLVM
+%! assert (test_overload (1), 1);
+%! assert (test_overload ([1 2]), [1 2]);
 
 %!function a = bubble (a = [3 2 1])
 %!  swapped = 1;
@@ -333,7 +360,7 @@
 %!  while (swapped)
 %!    swapped = 0;
 %!    for i = 1:n-1
-%!      if a(i) > a(i + 1)
+%!      if (a(i) > a(i + 1))
 %!        swapped = 1;
 %!        temp = a(i);
 %!        a(i) = a(i + 1);
@@ -343,9 +370,10 @@
 %!  endwhile
 %!endfunction
 
-%!assert (bubble (), [1 2 3]);
+%!testif HAVE_LLVM
+%! assert (bubble (), [1 2 3]);
 
-%!test
+%!testif HAVE_LLVM
 %! a = 0;
 %! b = 1;
 %! for i=1:1e3
@@ -356,10 +384,10 @@
 %! assert (a, 2000);
 %! assert (b, 1);
 
-%!test
+%!testif HAVE_LLVM
 %! a = [1+1i 1+2i];
 %! b = 0;
-%! while 1
+%! while (1)
 %!   b = a(1);
 %!   break;
 %! endwhile
@@ -371,13 +399,33 @@
 %!  endfor
 %!endfunction
 
-%!error <undefined near> (test_undef);
+%!testif HAVE_LLVM
+%! lasterr ("");
+%! try
+%!   test_undef ();
+%! end_try_catch
+%! assert (strncmp (lasterr (), "'XXX' undefined near", 20));
 
 %!shared id
 %! id = @(x) x;
 
-%!assert (id (1), 1)
-%!assert (id (1+1i), 1+1i)
-%!assert (id (1, 2), 1)
-%!error <undefined> (id ())
+%!testif HAVE_LLVM
+%! assert (id (1), 1);
+%! assert (id (1+1i), 1+1i);
+%! assert (id (1, 2), 1);
 
+%!testif HAVE_LLVM
+%! lasterr ("");
+%! try
+%!   id ();
+%! end_try_catch
+%! assert (strncmp (lasterr (), "'x' undefined near", 18));
+
+## Restore JIT settings
+%!testif HAVE_LLVM
+%! global __old_jit_enable__;
+%! global __old_jit_startcnt__;
+%! jit_enable (__old_jit_enable__);
+%! jit_startcnt (__old_jit_startcnt__);
+%! clear -g __old_jit_enable__ __old_jit_startcnt__;
+
--- a/test/line-continue.tst
+++ b/test/line-continue.tst
@@ -77,3 +77,8 @@
 %! y = [1,2];
 %! assert  (y, x);
 
+%!test
+%! x = [ 1 , ...anything after the ... is ignored
+%! 2];
+%! y = [1,2];
+%! assert  (y, x);
--- a/test/nest/varg_nest2.m
+++ b/test/nest/varg_nest2.m
@@ -6,7 +6,7 @@
     x = a;
   endif
 
-  function a, b = f
+  function [a, b] = f
     if nargout == 2
       a = b = 5;
     endif
--- a/test/parser.tst
+++ b/test/parser.tst
@@ -35,217 +35,229 @@
 ## Level 13 (parentheses and indexing)
 ## Overrides all other levels
 %!test
-%!  a.b = 1;
-%!  assert (a. b++, 1)
-%!  assert (a.b, 2)
-%!  clear a;
-%!  a.b = [0 1];
-%!  b = 2;
-%!  assert (a.b', [0;1])
-%!  assert (!a .b, logical ([1 0]))
-%!  assert (3*a .b, [0 3])
-%!  assert (a. b-1, [-1 0])
-%!  assert (a. b:3, 0:3)
-%!  assert (a. b>0.5, logical ([0 1]))
-%!  assert (a. b&0, logical ([0 0]))
-%!  assert (a. b|0, logical ([0 1]))
-%!  a.b = [1 2];
-%!  assert (a. b&&0, false)
-%!  assert (a. b||0, true)
-%!  a.b += a. b*2;
-%!  assert (a.b, [3 6])
+%! a.b = 1;
+%! assert (a. b++, 1);
+%! assert (a.b, 2);
+%! clear a;
+%! a.b = [0 1];
+%! b = 2;
+%! assert (a.b', [0;1]);
+%! assert (!a .b, logical ([1 0]));
+%! assert (3*a .b, [0 3]);
+%! assert (a. b-1, [-1 0]);
+%! assert (a. b:3, 0:3);
+%! assert (a. b>0.5, logical ([0 1]));
+%! assert (a. b&0, logical ([0 0]));
+%! assert (a. b|0, logical ([0 1]));
+%! a.b = [1 2];
+%! assert (a. b&&0, false);
+%! assert (a. b||0, true);
+%! a.b += a. b*2;
+%! assert (a.b, [3 6]);
 ## Level 12 (postfix increment and decrement)
 %!test
-%!  a = [3 5];
-%!  assert (2.^a ++, [8 32])
-%!  assert (a, [4 6])
-%!  assert (a--', [4; 6])
-%!  assert (a, [3 5])
-%!  a = 0;
-%!  assert (!a --, true)
-%!  assert (-a ++, 1)
-%!  assert (3*a ++, 0)
-%!  assert (a++-2, -1)
-%!  assert (1:a ++, 1:2)
-%!  assert (4>a++, true)
-%!  a = [0 -1];
-%!  assert ([1 1] & a++, logical ([0 1]))
-%!  assert ([0 0] | a++, logical ([1 0]))
-%!  a = 0;
-%!  assert (1 && a ++, false)
-%!  assert (0 || a --, true)
-%!  a = 5; b = 2;
-%!  b +=a ++;
-%!  assert (b, 7)
+%! a = [3 5];
+%! assert (2.^a ++, [8 32]);
+%! assert (a, [4 6]);
+%! assert (a--', [4; 6]);
+%! assert (a, [3 5]);
+%! a = 0;
+%! assert (!a --, true);
+%! assert (-a ++, 1);
+%! assert (3*a ++, 0);
+%! assert (a++-2, -1);
+%! assert (1:a ++, 1:2);
+%! assert (4>a++, true);
+%! a = [0 -1];
+%! assert ([1 1] & a++, logical ([0 1]));
+%! assert ([0 0] | a++, logical ([1 0]));
+%! a = 0;
+%! assert (1 && a ++, false);
+%! assert (0 || a --, true);
+%! a = 5; b = 2;
+%! b +=a ++;
+%! assert (b, 7);
 
 ## Level 11 (transpose and exponentiation)
 %!test
-%!  assert (-2 ^2, -4)
-%!  assert (!0 ^0, false)
-%!  assert (2*3 ^2, 18)
-%!  assert (2+3 ^2, 11)
-%!  assert ([1:10](1:2 ^2), [1 2 3 4])
-%!  assert (3>2 ^2, false)
-%!  assert (1&0 ^0, true)
-%!  assert (0|0 ^0, true)
-%!  assert (1&&0 ^0, true)
-%!  assert (0||0 ^0, true)
-%!  a = 3;
-%!  a *= 0 ^0;
-%!  assert (a, 3)
+%! assert (-2 ^2, -4);
+%! assert (!0 ^0, false);
+%! assert (2*3 ^2, 18);
+%! assert (2+3 ^2, 11);
+%! assert ([1:10](1:2 ^2), [1 2 3 4]);
+%! assert (3>2 ^2, false);
+%! assert (1&0 ^0, true);
+%! assert (0|0 ^0, true);
+%! assert (1&&0 ^0, true);
+%! assert (0||0 ^0, true);
+%! a = 3;
+%! a *= 0 ^0;
+%! assert (a, 3);
 ## Level 10 (unary plus/minus, prefix increment/decrement, not)
 %!test
-%!  a = 2;
-%!  assert (++ a*3, 9)
-%!  assert (-- a-2, 0)
-%!  assert (a, 2)
-%!  assert (! a-2, -2)
-%!  assert ([1:10](++ a:5), 3:5)
-%!  a = [1 0];
-%!  assert (! a>=[1 0], [false true])
-%!  a = 0;
-%!  assert (++ a&1, true)
-%!  assert (-- a|0, false)
-%!  assert (-- a&&1, true)
-%!  assert (++ a||0, false)
-%!  a = 3;
-%!  a *= ++a;
-%!  assert (a, 16)
+%! a = 2;
+%! assert (++ a*3, 9);
+%! assert (-- a-2, 0);
+%! assert (a, 2);
+%! assert (! a-2, -2);
+%! assert ([1:10](++ a:5), 3:5);
+%! a = [1 0];
+%! assert (! a>=[1 0], [false true]);
+%! a = 0;
+%! assert (++ a&1, true);
+%! assert (-- a|0, false);
+%! assert (-- a&&1, true);
+%! assert (++ a||0, false);
+%! a = 3;
+%! a *= ++a;
+%! assert (a, 16);
 ## Level 9 (multiply, divide)
 %!test
-%!  assert (3+4 * 5, 23)
-%!  assert (5 * 1:6, [5 6])
-%!  assert (3>1 * 5, false)
-%!  assert (1&1 * 0, false)
-%!  assert (1|1 * 0, true)
-%!  assert (1&&1 * 0, false)
-%!  assert (1||1 * 0, true)
-%!  a = 3;
-%!  a /= a * 2;
-%!  assert (a, 0.5)
+%! assert (3+4 * 5, 23);
+%! assert (5 * 1:6, [5 6]);
+%! assert (3>1 * 5, false);
+%! assert (1&1 * 0, false);
+%! assert (1|1 * 0, true);
+%! assert (1&&1 * 0, false);
+%! assert (1||1 * 0, true);
+%! a = 3;
+%! a /= a * 2;
+%! assert (a, 0.5);
 ## Level 8 (add, subtract)
 %!test
-%!  assert ([2 + 1:6], 3:6)
-%!  assert (3>1 + 5, false)
-%!  assert (1&1 - 1, false)
-%!  assert (0|1 - 2, true)
-%!  assert (1&&1 - 1, false)
-%!  assert (0||1 - 2, true)
-%!  a = 3;
-%!  a *= 1 + 1;
-%!  assert (a, 6)
+%! assert ([2 + 1:6], 3:6);
+%! assert (3>1 + 5, false);
+%! assert (1&1 - 1, false);
+%! assert (0|1 - 2, true);
+%! assert (1&&1 - 1, false);
+%! assert (0||1 - 2, true);
+%! a = 3;
+%! a *= 1 + 1;
+%! assert (a, 6);
 ## Level 7 (colon)
 %!test
-%!  assert (5:-1: 3>4, [true false false])
-%!  assert (1: 3&1, [true true true])
-%!  assert (1: 3|0, [true true true])
-%!  assert (-1: 3&&1, false)
-%!  assert (-1: 3||0, false)
-%!  a = [1:3];
-%!  a += 3 : 5;
-%!  assert (a, [4 6 8])
+%! assert (5:-1: 3>4, [true false false]);
+%! assert (1: 3&1, [true true true]);
+%! assert (1: 3|0, [true true true]);
+%! assert (-1: 3&&1, false);
+%! assert (-1: 3||0, false);
+%! a = [1:3];
+%! a += 3 : 5;
+%! assert (a, [4 6 8]);
 ## Level 6 (relational)
 %!test
-%!  assert (0 == -1&0, false)
-%!  assert (1 == -1|0, false)
-%!  assert (0 == -1&&0, false)
-%!  assert (1 == -1||0, false)
-%!  a = 2;
-%!  a *= 3 > 1;
-%!  assert (a, 2)
+%! assert (0 == -1&0, false);
+%! assert (1 == -1|0, false);
+%! assert (0 == -1&&0, false);
+%! assert (1 == -1||0, false);
+%! a = 2;
+%! a *= 3 > 1;
+%! assert (a, 2);
 ## Level 5 (element-wise and)
 %!test
-%!  assert (0 & 1|1, true)
-%!  assert ([0 1] & 1&&1, false)
-%!  assert (0 & 1||1, true)
-%!  a = 2;
-%!  a *= 3 & 1;
-%!  assert (a, 2)
+%! assert (0 & 1|1, true);
+%! assert ([0 1] & 1&&1, false);
+%! assert (0 & 1||1, true);
+%! a = 2;
+%! a *= 3 & 1;
+%! assert (a, 2);
 ## Level 4 (element-wise or)
 %!test
-%!  assert ([0 1] | 1&&0, false)
-%!  assert ([0 1] | 1||0, true)
-%!  a = 2;
-%!  a *= 0 | 1;
-%!  assert (a, 2)
+%! assert ([0 1] | 1&&0, false);
+%! assert ([0 1] | 1||0, true);
+%! a = 2;
+%! a *= 0 | 1;
+%! assert (a, 2);
 ## Level 3 (logical and)
 %!test
-%!  assert (0 && 1||1, true)
-%!  a = 2;
-%!  a *= 3 && 1;
-%!  assert (a, 2)
+%! assert (0 && 1||1, true);
+%! a = 2;
+%! a *= 3 && 1;
+%! assert (a, 2);
 ## Level 2 (logical or)
 %!test
-%!  a = 2;
-%!  a *= 0 || 1;
-%!  assert (a, 2)
+%! a = 2;
+%! a *= 0 || 1;
+%! assert (a, 2);
 
 ## Tests for operator precedence within each level where ordering should
 ## be left to right except for postfix and assignment operators.
 
 ## Level 13 (parentheses and indexing)
 %!test
-%!  a.b1 = 2;
-%!  assert (a.(strcat('b','1'))++, 2)
-%!  assert (a.b1, 3)
-%!  b = {1 2 3 4 5};
-%!  assert (b{(a. b1 + 1)}, 4)
-%!  b = 1:5;
-%!  assert (b(a. b1 + 1), 4)
-%!  assert ([2 3].^2', [4; 9])
+%! a.b1 = 2;
+%! assert (a.(strcat('b','1'))++, 2);
+%! assert (a.b1, 3);
+%! b = {1 2 3 4 5};
+%! assert (b{(a. b1 + 1)}, 4);
+%! b = 1:5;
+%! assert (b(a. b1 + 1), 4);
+%! assert ([2 3].^2', [4; 9]);
 ## Level 12 (postfix increment and decrement)
 ## No tests possible since a++-- is not valid
 ## Level 11 (transpose and exponentiation)
-## Note: Exponentiation works left to right for compatibility with Matlab.
-%!  assert (2^3**2, 64)
-%!  assert ([2 3].^2.', [4;9])
-%!  assert ([2 3].'.^2, [4;9])
-%!  assert (3*4i'.', 0 - 12i)
-%!  assert (3*4i.'.', 0 + 12i)
+## Note: Exponentiation should be left-to-right, but Octave does right-to-left.
+##       See bug #33304.
+%!test
+%! assert (2^3**2, 64);
+%! assert ([2 3].^2.', [4;9]);
+%! assert ([2 3].'.^2, [4;9]);
+%! assert (3*4i'.', 0 - 12i);
+%! assert (3*4i.'.', 0 + 12i);
+%! assert (2^-4^3, (1/16)^3);
+%! assert (2^+4^3, 16^3);
+%! assert (2^~0^2, 4);
+
+## Note: Exponentiation should be left-to-right, but Octave does right-to-left.
+##       See bug #33304.
+
 ## Level 10 (unary plus/minus, prefix increment/decrement, not)
 %!test
-%!  assert (+-+1, -1)
-%!  a = -1;
-%!  assert (!++a, true)
-%!  assert (a, 0)
-%!  assert (-~a, -1)
-%!  assert (!~--a, true)
-%!  assert (a, -1)
+%! assert (+-+1, -1);
+%! a = -1;
+%! assert (!++a, true);
+%! assert (a, 0);
+%! assert (-~a, -1);
+%! assert (!~--a, true);
+%! assert (a, -1);
 ## Level 9 (multiply, divide)
 %!test
-%!  assert (3 * 4 / 5, 2.4)
-%!  assert (3 ./ 4 .* 5, 3.75)
-%!  assert (2 * 4 \ 6, 0.75)
-%!  assert (2 .\ 4 .* 6, 12)
+%! assert (3 * 4 / 5, 2.4);
+%! assert (3 ./ 4 .* 5, 3.75);
+%! assert (2 * 4 \ 6, 0.75);
+%! assert (2 .\ 4 .* 6, 12);
 ## Level 8 (add, subtract)
 %!test
-%!  assert (-3 - 4 + 1 + 3 * 2, 0)
+%! assert (-3 - 4 + 1 + 3 * 2, 0);
 ## Level 7 (colon)
-## No tests possible because colon operator can't be combined with second colon operator
+## No tests possible because colon operator can't be combined
+## with second colon operator.
 ## Level 6 (relational)
 %!test
-%!  assert (0 < 1 <= 0.5 == 0 >= 0.5 > 0, true)
-%!  assert (1 < 1 == 0 != 0, true)
-%!  assert (1 < 1 == 0 ~= 0, true)
+%! assert (0 < 1 <= 0.5 == 0 >= 0.5 > 0, true);
+%! assert (1 < 1 == 0 != 0, true);
+%! assert (1 < 1 == 0 ~= 0, true);
 ## Level 5 (element-wise and)
-## No tests possible.  Only one operator (&) at this precedence level and operation is associative.
+## No tests possible.  Only one operator (&) at this precedence level
+## and operation is associative.
 ## Level 4 (element-wise or)
-## No tests possible.  Only one operator (|) at this precedence level and operation is associative.
+## No tests possible.  Only one operator (|) at this precedence level
+## and operation is associative.
 ## Level 3 (logical and)
 %!test
-%!  a = 1;
-%!  assert (1 && 0 && ++a, false)
-%!  assert (a, 1)
+%! a = 1;
+%! assert (1 && 0 && ++a, false);
+%! assert (a, 1);
 ## Level 2 (logical or)
 %!test
-%!  a = 1;
-%!  assert (0 || 1 || ++a, true)
-%!  assert (a, 1)
+%! a = 1;
+%! assert (0 || 1 || ++a, true);
+%! assert (a, 1);
 ## Level 1 (assignment)
 %!test
 %! a = 2; b = 5; c = 7;
-%! assert (a += b *= c += 1, 42)
-%! assert (b == 40 && c == 8)
+%! assert (a += b *= c += 1, 42);
+%! assert (b == 40 && c == 8);
 
 ## Test creation of anonymous functions
 
--- a/test/slice.tst
+++ b/test/slice.tst
@@ -18,7 +18,7 @@
 
 %!function x = set_slice (size, dim, slice)
 %!  x = ones (size);
-%!  switch dim
+%!  switch (dim)
 %!    case 11
 %!      x(slice) = 2;
 %!    case 21
--- a/test/switch.tst
+++ b/test/switch.tst
@@ -21,10 +21,11 @@
 %! b = 2;
 %! c = 3;
 %!
-%! switch 0 case 1 x = a; case 2 x = b; otherwise x = c; endswitch
-%! switch 1 case 1 y = a; case 2 y = b; otherwise y = c; endswitch
-%! switch 2 case 1 z = a; case 2 z = b; otherwise z = c; endswitch
-%! switch 3 case 1 p = a; case 2 p = b; otherwise p = c; endswitch
+%! ## "end" is part of test, check not using "endswitch"
+%! switch (0) case 1 x = a; case 2 x = b; otherwise x = c; end
+%! switch (1) case 1 y = a; case 2 y = b; otherwise y = c; endswitch
+%! switch (2) case 1 z = a; case 2 z = b; otherwise z = c; endswitch
+%! switch (3) case 1 p = a; case 2 p = b; otherwise p = c; endswitch
 %!
 %! assert (x == c && y == a && z == b && p == c);
 
@@ -40,11 +41,11 @@
 %! for i = 0:3
 %! switch (i)
 %!   case a
-%!    x(k) = a;
+%!     x(k) = a;
 %!   case b
-%!    x(k) = b;
+%!     x(k) = b;
 %!   otherwise
-%!    x(k) = c;
+%!     x(k) = c;
 %!   endswitch
 %!   k++;
 %! endfor
@@ -62,8 +63,8 @@
 %!
 %! for i = 0:3
 %!   switch (i)
-%!   case a
-%!    x(k) = a;
+%!     case a
+%!       x(k) = a;
 %!   endswitch
 %!   k++;
 %! endfor
@@ -73,9 +74,9 @@
 %!test
 %! a = 1;
 %!
-%! switch 1
-%! otherwise
-%!   a = 2;
+%! switch (1)
+%!   otherwise
+%!     a = 2;
 %! endswitch
 %!
 %! assert (a == 2);
--- a/test/system.tst
+++ b/test/system.tst
@@ -140,7 +140,7 @@
 %!
 %! assert (deblank (s1.modestr), "-rw-rw-rw-");
 %! assert (deblank (s2.modestr), "----------");
-%! # Restore original umask value
+%! ## Restore original umask value
 %! umask (orig_umask);
 
 %!error <Invalid call to umask> umask ()
@@ -285,7 +285,7 @@
 %! d1 = pwd ();
 %! cd (xdir);
 %! if (ispc () && ! isunix ())
-%!   # should be a drive letter
+%!   ## should be a drive letter
 %!   assert (length (d1), 3);
 %!   assert (d1(2), ":");
 %!   assert (d1(3), "\\");
--- a/test/try.tst
+++ b/test/try.tst
@@ -20,7 +20,7 @@
 %! try
 %! catch
 %!   error ("Shoudn't get here");
-%! end_try_catch
+%! end  # "end" is part of test, check not using "end_try_catch"
 
 %!test
 %! try
@@ -127,3 +127,56 @@
 %!   assert (lasterr()(1:22), "rethrow: 'a' undefined");
 %! end_try_catch
 
+%!test
+%! clear myerr;
+%! try
+%!   error ("user-defined error");
+%! catch myerr
+%!   assert (myerr.message, "user-defined error");
+%! end_try_catch
+
+%!test
+%! try
+%!   clear a;
+%!   error ("user-defined error");
+%! catch a=1;
+%!   assert (lasterr, "user-defined error");
+%!   assert (a, 1);
+%! end_try_catch
+
+%!test
+%! clear myerr1
+%! clear myerr2
+%! try
+%!   try
+%!     clear a;
+%!     a;
+%!   catch myerr1
+%!     error (myerr1);
+%!   end_try_catch
+%! catch myerr2
+%!   assert (myerr1.message, myerr2.message);
+%!   assert (myerr1.identifier, myerr2.identifier);
+%! end_try_catch
+
+%!test
+%! x = 1;
+%! try error ("foo"); catch x; assert (x.message, "foo"); end_try_catch
+
+%!test
+%! x = 1;
+%! try error ("foo"); catch x end_try_catch
+%! assert (x.message, "foo");
+
+%!test
+%! x = 1;
+%! try error ("foo"); catch, x; assert (x, 1); end_try_catch
+
+%!test
+%! x = 1;
+%! try error ("foo"); catch; x; assert (x, 1); end_try_catch
+
+%!test
+%! x = 1;
+%! try error ("foo"); catch
+%!   x; assert (x, 1); end_try_catch
--- a/test/unwind.tst
+++ b/test/unwind.tst
@@ -28,7 +28,7 @@
 %!  unwind_protect_cleanup
 %!    g = save_g;
 %!    y = [y, g];
-%!  end_unwind_protect
+%!  end  # "end" is part of test, check not using "end_unwind_protect"
 %!endfunction
 %!
 %!test
--- a/test/while.tst
+++ b/test/while.tst
@@ -21,7 +21,7 @@
 %! while (eye (2))
 %!   i++;
 %!   __printf_assert__ ("%d\n", i);
-%! endwhile
+%! end  # "end" is part of test, check not using "endwhile"
 %! assert (__prog_output_assert__ (""));
 
 %!test