Add --table-look command line option and SET TLOOK command.
authorBen Pfaff <blp@cs.stanford.edu>
Tue, 22 Dec 2020 07:49:26 +0000 (23:49 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 22 Dec 2020 07:49:38 +0000 (23:49 -0800)
NEWS
doc/invoking.texi
doc/utilities.texi
src/language/utilities/set.q
src/output/pivot-table.c
src/output/pivot-table.h
src/ui/terminal/terminal-opts.c

diff --git a/NEWS b/NEWS
index 6bae9849004851a14d8d75efaa8fe8039d692c90..7da3c91cbf02a210843bc395fbec896a9a59d8b5 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -21,12 +21,15 @@ Changes from 1.4.1 to 1.5.2:
  * The user manual, in its Info and HTML versions, now includes
    graphical output examples and screenshots.
 
- * Output driver changes:
+ * Output improvements:
 
    - New drivers for output to TeX source files and to PNG files.
 
-   - New option "trim" to remove empty space from PDF, PostScript, SVG,
-     and PNG output files.
+   - Table output styles may now be set with the new option
+     --table-look and the new SET TLOOK command.
+
+   - New driver option "trim" to remove empty space from PDF,
+     PostScript, SVG, and PNG output files.
 
    - The HTML output driver has a new option "bare".
 
index 4800fc6997991f341ce52758dfc52f2440a3ff56..b9a0df8acf09f6b17e068b66e3ec2496ddc4b686 100644 (file)
@@ -52,6 +52,7 @@ corresponding short options.
 -O format=@var{format}
 -O device=@{terminal|listing@}
 --no-output
+--table-look=@var{file}
 -e, --error-file=@var{error-file}
 @end example
 
@@ -125,6 +126,23 @@ Disables output entirely, if neither @option{-o} nor @option{-O} is
 also used.  If one of those options is used, @option{--no-output} has
 no effect.
 
+@item @option{--table-look=@var{file}}
+Reads a table style from @var{file} and applies it to all @pspp{}
+table output.  The file should be a TableLook @file{.stt} or
+@file{.tlo} file.  @pspp{} searches for @var{file} in the current
+directory, then in @file{.pspp/looks} in the user's home directory,
+then in a @file{looks} subdirectory inside @pspp{}'s data directory
+(usually @file{/usr/local/share/pspp}).  If @pspp{} cannot find
+@var{file} under the given name, it also tries adding a @file{.stt}
+extension.
+
+When this option is not specified, @pspp{} looks for
+@file{default.stt} using the algorithm above, and otherwise it falls
+back to a default built-in style.
+
+Using @code{SET TLOOK} in @pspp{} syntax overrides the style set on
+the command line (@pxref{SET}).
+
 @item @option{-e @var{error-file}}
 @itemx @option{--error-file=@var{error-file}}
 Configures a file to receive @pspp{} error, warning, and note messages in
index a5db44b5a6312b94a8c97641a663e2f961f2168e..0ddbcbb06ce56b7a8430ffbee917a5ea2e4259fc 100644 (file)
@@ -525,6 +525,7 @@ SET
         /WIDTH=@{NARROW,WIDTH,@var{n_characters}@}
         /TNUMBERS=@{VALUES,LABELS,BOTH@}
         /TVARS=@{NAMES,LABELS,BOTH@}
+        /TLOOK=@{NONE,@var{file}@}
 
 (logging)
         /JOURNAL=@{ON,OFF@} ['@var{file_name}']
@@ -840,6 +841,13 @@ has been set.  If no label has been set, then the name is used.
 (@xref{VARIABLE LABELS}.)
 If @subcmd{TVARS} is set to @subcmd{BOTH}, then variables are displayed with both their label
 (if any) and their name in parentheses.
+@item TLOOK
+The @subcmd{TLOOK} option sets the style used for subsequent table
+output.  Specifying @subcmd{NONE} makes @pspp{} use the default
+built-in style.  Otherwise, specifying @var{file} makes @pspp{} search
+for an @file{.stt} or @file{.tlo} file in the same way as specifying
+@option{--table-look=@var{file}} the @pspp{} command line (@pxref{Main
+Options}).
 @end table
 
 @cindex headers
index 301cc645e8583257e80a69d599902710c5ede594..ddc7fc629da3b671a85b25f435999371aee0647c 100644 (file)
@@ -48,6 +48,7 @@
 #include "math/random.h"
 #include "output/driver.h"
 #include "output/journal.h"
+#include "output/pivot-table.h"
 
 #if HAVE_LIBTERMCAP
 #if HAVE_TERMCAP_H
@@ -113,6 +114,7 @@ int tgetnum (const char *);
      tvars=custom;
      tb1=string;
      tbfonts=string;
+     tlook=custom;
      undefined=undef:warn/nowarn;
      wib=wib:msbfirst/lsbfirst/vax/native;
      wrb=wrb:native/isl/isb/idl/idb/vf/vd/vg/zs/zl;
@@ -383,6 +385,34 @@ stc_custom_tvars (struct lexer *lexer,
   return 1;
 }
 
+static int
+stc_custom_tlook (struct lexer *lexer,
+                  struct dataset *ds UNUSED,
+                  struct cmd_set *cmd UNUSED, void *aux UNUSED)
+{
+  lex_match (lexer, T_EQUALS);
+
+  if (lex_match_id (lexer, "NONE"))
+    pivot_table_look_set_default (pivot_table_look_builtin_default ());
+  else if (lex_is_string (lexer))
+    {
+      struct pivot_table_look *look;
+      char *error = pivot_table_look_read (lex_tokcstr (lexer), &look);
+      lex_get (lexer);
+
+      if (error)
+        {
+          msg (SE, "%s", error);
+          free (error);
+          return 0;
+        }
+
+      pivot_table_look_set_default (look);
+      pivot_table_look_unref (look);
+    }
+
+  return 1;
+}
 
 /* Parses the EPOCH subcommand, which controls the epoch used for
    parsing 2-digit years. */
index 7eeee46ce621855e16baecbccf9bdb330e817493..3d76ea2afa93ce79f88667380ce789641280757b 100644 (file)
 #include "data/settings.h"
 #include "data/value.h"
 #include "data/variable.h"
+#include "data/file-name.h"
 #include "libpspp/hash-functions.h"
 #include "libpspp/i18n.h"
 #include "output/driver.h"
+#include "output/spv/spv-table-look.h"
 
 #include "gl/c-ctype.h"
+#include "gl/configmake.h"
 #include "gl/intprops.h"
 #include "gl/minmax.h"
+#include "gl/relocatable.h"
 #include "gl/xalloc.h"
 #include "gl/xmemdup0.h"
 #include "gl/xsize.h"
@@ -131,6 +135,70 @@ pivot_table_sizing_uninit (struct pivot_table_sizing *sizing)
 \f
 /* Pivot table looks. */
 
+static const struct pivot_table_look *
+default_look (const struct pivot_table_look *new)
+{
+  static struct pivot_table_look *look;
+  if (new)
+    {
+      pivot_table_look_unref (look);
+      look = pivot_table_look_ref (new);
+    }
+  else if (!look)
+    {
+      char *error = pivot_table_look_read ("default.stt", &look);
+      if (error)
+        look = pivot_table_look_ref (pivot_table_look_builtin_default ());
+    }
+  return look;
+}
+
+const struct pivot_table_look *
+pivot_table_look_get_default (void)
+{
+  return default_look (NULL);
+}
+
+void
+pivot_table_look_set_default (const struct pivot_table_look *look)
+{
+  default_look (look);
+}
+
+char * WARN_UNUSED_RESULT
+pivot_table_look_read (const char *name, struct pivot_table_look **lookp)
+{
+  *lookp = NULL;
+
+  /* Construct search path. */
+  const char *path[4];
+  size_t n = 0;
+  path[n++] = ".";
+  const char *home = getenv ("HOME");
+  if (home != NULL)
+    path[n++] = xasprintf ("%s/.pspp/looks", home);
+  char *allocated;
+  path[n++] = relocate2 (PKGDATADIR "/looks", &allocated);
+  path[n++] = NULL;
+
+  /* Search path. */
+  char *file = fn_search_path (name, (char **) path);
+  if (!file)
+    {
+      char *name2 = xasprintf ("%s.stt", name);
+      file = fn_search_path (name2, (char **) path);
+      free (name2);
+    }
+  free (allocated);
+  if (!file)
+    return xasprintf ("%s: not found", name);
+
+  /* Read file. */
+  char *error = spv_table_look_read (file, lookp);
+  free (file);
+  return error;
+}
+
 const struct pivot_table_look *
 pivot_table_look_builtin_default (void)
 {
@@ -770,7 +838,7 @@ pivot_table_create__ (struct pivot_value *title, const char *subtype)
   table->title = title;
   table->subtype = subtype ? pivot_value_new_text (subtype) : NULL;
   table->command_c = output_get_command_name ();
-  table->look = pivot_table_look_ref (pivot_table_look_builtin_default ());
+  table->look = pivot_table_look_ref (pivot_table_look_get_default ());
 
   hmap_init (&table->cells);
 
index 94adcca73eaeb63799d983df794dafd404c6df5a..c613e55efc81d557c03d67b28f45ce72f23c31da 100644 (file)
@@ -402,6 +402,12 @@ struct pivot_table_look
     size_t n_orphan_lines;
   };
 
+const struct pivot_table_look *pivot_table_look_get_default (void);
+void pivot_table_look_set_default (const struct pivot_table_look *);
+
+char *pivot_table_look_read (const char *, struct pivot_table_look **)
+  WARN_UNUSED_RESULT;
+
 const struct pivot_table_look *pivot_table_look_builtin_default (void);
 struct pivot_table_look *pivot_table_look_new_builtin_default (void);
 struct pivot_table_look *pivot_table_look_ref (
index 284d2c9d6115e9f4ae7477caac58544599ada0a6..eeb10356d8ecf7f971dc82f7c280b12231c1e504 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-
 #include "data/settings.h"
 #include "language/lexer/include-path.h"
 #include "libpspp/argv-parser.h"
@@ -38,6 +37,7 @@
 #include "output/driver.h"
 #include "output/driver-provider.h"
 #include "output/msglog.h"
+#include "output/pivot-table.h"
 
 #include "gl/error.h"
 #include "gl/localcharset.h"
@@ -59,6 +59,7 @@ struct terminal_opts
     enum lex_syntax_mode *syntax_mode;
     bool *process_statrc;
     char **syntax_encoding;
+    char *table_look;
   };
 
 enum
@@ -72,6 +73,7 @@ enum
     OPT_INTERACTIVE,
     OPT_SYNTAX_ENCODING,
     OPT_NO_STATRC,
+    OPT_TABLE_LOOK,
     OPT_HELP,
     OPT_VERSION,
     N_TERMINAL_OPTIONS
@@ -88,6 +90,7 @@ static struct argv_option terminal_argv_options[N_TERMINAL_OPTIONS] =
     {"interactive", 'i', no_argument, OPT_INTERACTIVE},
     {"syntax-encoding", 0, required_argument, OPT_SYNTAX_ENCODING},
     {"no-statrc", 'r', no_argument, OPT_NO_STATRC},
+    {"table-look", 0, required_argument, OPT_TABLE_LOOK},
     {"help", 'h', no_argument, OPT_HELP},
     {"version", 'V', no_argument, OPT_VERSION},
   };
@@ -157,6 +160,7 @@ Output options:\n\
   -O device={terminal|listing}  override device type for previous -o\n\
   -e, --error-file=FILE     append errors, warnings, and notes to FILE\n\
   --no-output               disable default output driver\n\
+  --table-look=FILE         use output style read from FILE\n\
 Supported output formats: %s\n\
 \n\
 Language options:\n\
@@ -235,6 +239,10 @@ terminal_option_callback (int id, void *to_)
       *to->process_statrc = false;
       break;
 
+    case OPT_TABLE_LOOK:
+      to->table_look = optarg;
+      break;
+
     case OPT_HELP:
       usage ();
       exit (EXIT_SUCCESS);
@@ -290,5 +298,16 @@ terminal_opts_done (struct terminal_opts *to, int argc, char *argv[])
     msglog_create ("-");
 
   string_map_destroy (&to->options);
+
+  if (to->table_look)
+    {
+      struct pivot_table_look *look;
+      char *s = pivot_table_look_read (to->table_look, &look);
+      if (s)
+        error (1, 0, "%s", s);
+      pivot_table_look_set_default (look);
+      pivot_table_look_unref (look);
+    }
+
   free (to);
 }