function dispx(str)
%dispx: Display styled string in xterm.
% dispx(str) displays the string, str, very much like disp(str) with the
% added feature that str can contain embedded commands to cause the text
% to be in a bold font, underlined, blinking, colored and/or with a colored
% background. This function only works in an xterm that supports these
% features via standard ANSI escape sequences. Normally, you will have
% started MATLAB with "matlab -nodesktop".
%
% The commands are:
% \bf{<text>} to display <text> in a bold font
% \ul{<text>} to underline <text>
% \bl{<text>} to cause <text> to blink
% \fg{<color>}{<text>} to set the foreground color of <text> to <color>
% \bg{<color>}{<text>} to set the background color of <text> to <color>
%
% <color> must be a single letter to specify the following colors:
% r => red m => magenta
% g => green y => yellow
% b => blue k => black
% c => cyan w => white
%
% In order to include the characters \, {, or }, escape them by prepending
% a \, i.e., \\, \{ and \}.
%
% Examples:
% dispx('The word \ul{underlined} will be underlined.')
% dispx('The word \fg{r}{DANGER} will be red.')
% dispx('The word \bg{g}{NORMAL} will have a green background.')
% dispx('\fg{y}{\bg{k}{\ul{HI!}}} will be yellow on black and underlined.')
% Version: 1.0, 11 June 2006
% Author: Douglas M. Schwarz
% Email: dmschwarz=ieee*org, dmschwarz=urgrad*rochester*edu
% Real_email = regexprep(Email,{'=','*'},{'@','.'})
% Input checks.
error(nargchk(1,1,nargin))
if ~ischar(str)
error('Input argument must be a string.')
end
% Use a regular expression to split str into logical entities.
re = '(\\[a-z]{2}(\{[rgbcmykw]\})?\{)|\\\{|\\\}|\\\\|.*?';
[split,tok] = regexp(str,re,'match','tokens');
% Compute depth of nested braces. Set colors to default.
depth = cumsum(~cellfun(@isempty,tok) - strcmp(split,'}'));
fg_color = repmat({'d'},1,length(depth));
bg_color = repmat({'d'},1,length(depth));
% Initialize some variables.
esc = char(27);
colors = {'r','g','b','c','m','y','k','w','d'};
codes = {'1','2','4','6','5','3','0','7','9'};
% Compute where depth changes in order to pair up possibly nested braces.
up = find(diff([0,depth]) == 1);
dn = find(diff(depth) == -1);
a = depth(up);
b = depth(dn);
[as,ai] = sort(a);
[bs,bi] = sort(b);
k(ai) = bi;
pairs = [up;dn(k)+1];
% Loop over number of pairs, replacing commands and closing braces with ANSI
% escape sequences.
n = size(pairs,2);
for i = 1:n
cmd = split{pairs(1,i)};
switch cmd(2:3)
case 'bf'
split{pairs(1,i)} = [esc,'[1m'];
split{pairs(2,i)} = [esc,'[22m'];
case 'ul'
split{pairs(1,i)} = [esc,'[4m'];
split{pairs(2,i)} = [esc,'[24m'];
case 'bl'
split{pairs(1,i)} = [esc,'[5m'];
split{pairs(2,i)} = [esc,'[25m'];
case 'fg'
fg_color(pairs(1,i):pairs(2,i)-1) = {cmd(5)};
split{pairs(1,i)} = [esc,'[3',codes{strcmp(cmd(5),colors)},'m'];
split{pairs(2,i)} = [esc,'[3',...
codes{strcmp(bg_color{pairs(2,i)},colors)},'m'];
case 'bg'
bg_color(pairs(1,i):pairs(2,i)-1) = {cmd(5)};
split{pairs(1,i)} = [esc,'[4',codes{strcmp(cmd(5),colors)},'m'];
split{pairs(2,i)} = [esc,'[4',...
codes{strcmp(bg_color{pairs(2,i)},colors)},'m'];
end
end
% Join cells back into a string. Replace escaped characters with proper
% single characters.
str2 = [split{:}];
str2 = regexprep(str2,{'\\\\','\\{','\\}'},{'\','{','}'});
% Display result to xterm.
disp(str2)