1## Copyright (C) 2009 VZLU Prague, a.s.
2##
3## This program is free software; you can redistribute it and/or modify it under
4## the terms of the GNU General Public License as published by the Free Software
5## Foundation; either version 3 of the License, or (at your option) any later
6## version.
7##
8## This program is distributed in the hope that it will be useful, but WITHOUT
9## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11## details.
12##
13## You should have received a copy of the GNU General Public License along with
14## this program; if not, see <http://www.gnu.org/licenses/>.
15
16## -*- texinfo -*-
17## @deftypefn{Function File} colorboard (@var{m}, @var{palette}, @var{options})
18## Displays a color board corresponding to a numeric matrix @var{m}.
19## @var{m} should contain zero-based indices of colors.
20## The available range of indices is given by the @var{palette} argument,
21## which can be one of the following:
22##
23## @itemize
24## @item "b&w"
25##   Black & white, using reverse video mode. This is the default if @var{m} is logical.
26## @item "ansi8"
27##   The standard ANSI 8 color palette. This is the default unless @var{m} is logical.
28## @item "aix16"
29##   The AIXTerm extended 16-color palette. Uses codes 100:107 for bright colors.
30## @item "xterm16"
31##   The first 16 system colors of the Xterm 256-color palette.
32## @item "xterm216"
33##   The 6x6x6 color cube of the Xterm 256-color palette.
34##   In this case, matrix can also be passed as a MxNx3 RGB array with values 0..5.
35## @item "grayscale"
36##   The 24 grayscale levels of the Xterm 256-color palette.
37## @item "xterm256"
38##   The full Xterm 256-color palette. The three above palettes together.
39## @end itemize
40##
41## @var{options} comprises additional options. The recognized options are:
42##
43## @itemize
44## @item "indent"
45##   The number of spaces by which the board is indented. Default 2.
46## @item "spaces"
47##   The number of spaces forming one field. Default 2.
48## @item "horizontalseparator"
49##   The character used for horizontal separation of the table. Default "#".
50## @item "verticalseparator"
51##   The character used for vertical separation of the table. Default "|".
52## @end itemize
53## @end deftypefn
54
55function colorboard (m, palette, varargin)
56  if (nargin < 1)
57    print_usage ();
58  endif
59
60  nopt = length (varargin);
61
62  ## default options
63
64  indent = 2;
65  spc = 2;
66  vsep = "|";
67  hsep = "#";
68
69  ## parse options
70
71  while (nopt > 1)
72    switch (tolower (varargin{nopt-1}))
73    case "indent"
74      indent = varargin{nopt};
75    case "spaces"
76      spc = varargin{nopt};
77    case "verticalseparator"
78      vsep = varargin{nopt};
79    case "horizontalseparator"
80      hsep = varargin{nopt};
81    otherwise
82      error ("unknown option: %s", varargin{nopt-1});
83    endswitch
84    nopt -= 2;
85  endwhile
86
87  if (nargin == 1)
88    if (islogical (m))
89      palette = "b&w";
90    else
91      palette = "ansi8";
92    endif
93  endif
94
95  persistent digs = char (48:55); # digits 0..7
96
97  switch (palette)
98  case "b&w"
99    colors = ["07"; "27"];
100  case "ansi8"
101    i = ones (1, 8);
102    colors = (["4"(i, 1), digs.']);
103  case "aix16"
104    i = ones (1, 8);
105    colors = (["04"(i, :), digs.'; "10"(i, :), digs.']);
106  case "xterm16"
107    colors = xterm_palette (0:15);
108  case "xterm216"
109    colors = xterm_palette (16:231);
110    if (size (m, 3) == 3)
111      m = (m(:,:,1)*6 + m(:,:,2))*6 + m(:,:,3);
112    endif
113  case "grayscale"
114    colors = xterm_palette (232:255);
115  case "xterm256"
116    colors = xterm_palette (0:255);
117  otherwise
118    error ("colorboard: invalid palette");
119  endswitch
120
121  nc = rows (colors);
122
123  persistent esc = char (27);
124  escl = [esc, "["](ones (1, nc), :);
125  escr = ["m", blanks(spc)](ones (1, nc), :);
126
127  colors = [escl, colors, escr].';
128
129  [rm, cm] = size (m);
130
131  if (isreal (m) && max (m(:)) <= 1)
132    m = min (floor (nc * m), nc-1);
133  endif
134
135  try
136    board = reshape (colors(:, m + 1), [], rm, cm);
137  catch
138    error ("colorboard: m is not a valid index into palette");
139  end_try_catch
140
141  board = permute (board, [2, 1, 3])(:, :);
142
143  persistent reset = [esc, "[0m"];
144
145  indent = blanks (indent);
146  vline = [indent, hsep(1, ones (1, spc*cm+2))];
147  hlinel = [indent, vsep](ones (1, rm), :);
148  hliner = [reset, vsep](ones (1, rm), :);
149
150  oldpso = page_screen_output (0);
151  unwind_protect
152
153    disp ("");
154    disp (vline);
155    disp ([hlinel, board, hliner]);
156    disp (vline);
157    disp ("");
158
159    puts (reset); # reset terminal
160
161  unwind_protect_cleanup
162    page_screen_output (oldpso);
163  end_unwind_protect
164
165endfunction
166
167function pal = xterm_palette (r)
168  if (max (r) < 100)
169    fmt = "48;5;%02d"; l = 7;
170  else
171    fmt = "48;5;%03d"; l = 8;
172  endif
173  pal = reshape (sprintf (fmt, r), l, length (r)).';
174endfunction
175