No BSD License  

Highlights from
TABD

image thumbnail
from TABD by Gaetan Koers
A function to create tables rows in text.

tabd(varargin)
function tabd(varargin)

% TABD table display
%
%   TABD(X) is equivalent to DISP(X)
%
%   TABD(C, TABS) prints out the strings or scalars in the cell array C,
%    left aligned to the tabs given in increasing order in TABS, in
%    character units. The number of tabs should equal the number of
%    elements in C.
%    
%   TABD(C, TABS, ALIG) aligns the column data to the tabs according to the
%    alignment method given by the string ALIG. ALIG should contain 1 or as
%    many as tabs of the characters 'l', 'r', 'c' which stand for left,
%    right or center alignment, respectively.
%
%    Strings or string conversions in C which are longer than the spacing
%    to neighbouring tabs are truncated to fit the tab distance. When
%    strings overlap neighbouring strings (e.g. the strings at a left
%    aligned tab coming before a right aligned tab), strings that come
%    later in the order of C overwrite strings that come before.
%
% TABD is free software; you can redistribute it and/or modify it under the
% terms of the Use As You Like But Don't Blame Me License as never
% published by Any Software Foundation; either version sinh(1.44363548E00)
% of the License, or (at your option) any later version.
% 
% TABD 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. Don't waste your time by reading the Use As You
% Like BDBM License for more details.
% 
% You shouldn't have received a copy of the Use As You Like BDBM License
% along with TABD; if you did, be polite and write to gkoers@telenet.be.

if nargout > 0, error('Too many output arguments.'), end

switch nargin
    case 0
        return
    case 1
        disp(varargin{1});
        return
    case {2, 3}
        cstr = varargin{1};
        if ischar(cstr)
            cstr = {cstr};
            n = 1;
        elseif isnumeric(cstr)
            n = numel(cstr);
            cstr = num2cell(cstr(:));
             % the next FOR loop sucks but NUM2STR on a column vector appends
             % blanks in the front, which are not removed by CELLSTR
            for i=1:n
                cstr{i} = num2str(cstr{i});
            end
        elseif iscellstr(cstr)
            cstr = cstr(:);
            n = numel(cstr);
        elseif iscell(cstr)
            cstr = cstr(:);
            n = numel(cstr);
            for i=1:n
                if isnumeric(cstr{i})
                    if numel(cstr{i})~=1, error('Invalid argument size: expecting a cell array of strings and/or scalars'), end
                    cstr{i} = num2str(cstr{i});
                end
            end
        end
        tabs = varargin{2};
        if ~isnumeric(tabs), error('Invalid input argument: expecting a numeric array'), end
        if numel(tabs)~=n, error('Invalid argument size: the number of tabs must equal the number of strings'), end
        tabs = round(real(tabs));
        tabs = sort(tabs);
        if any(tabs < 0), error('Invalid input argument: tabs must be positive.'), end
        alig = repmat('l', 1, n);
        if nargin > 2
            alig = varargin{3};
            if ~ischar(alig), error('Invalid input argument: expecting a string.'), end
            if numel(alig)==1
                alig = repmat(alig, 1, n);
            elseif numel(alig)~=n
                error('Invalid argument size: the number of alignment characters must be 1 or equal the number of tabs.')
            end
            alig = lower(alig);            
            if ~isempty(regexpi(alig, '[^lrc]'))
                error('Invalid argument value: the alignment string can only contain ''r'', ''l'' or ''c''.')
            end
            ci = find(alig=='c');
            for i=1:numel(ci)
                c = ci(i);
                spl = floor(length(cstr{c})/2);
                tmp = cstr{c}(spl+1:end);
                cstr{c} = cstr{c}(1:spl);
                if c==n
                    cstr = [cstr; tmp];
                    tabs = [tabs tabs(n)];
                    alig(n) = 'r'; alig(n+1) = 'l';
                else
                    cstr = [cstr(1:c); tmp; cstr(c+1:n)];
                    tabs = [tabs(1:c) tabs(c) tabs(c+1:n)];
                    alig = [alig(1:c-1) 'rl' alig(c+1:n)];
                end
                n = n + 1;
                ci = ci + 1;
            end
        end
    otherwise
        error('Too many input arguments')
end

%cw = command_window_width;
str = [];
for i=1:n
    strlen = length(str);
    switch alig(i)
        case 'l' % left aligned
            if isempty(str) % fill up with spaces up to the tab
                str = sprintf('%s%s', repmat(' ', 1, tabs(i)), cstr{i});
            else % nibble some of the existing string or fill up with spaces up to the tab
                str = sprintf('%s%s%s', str(1:min(strlen, tabs(i))), repmat(' ', 1, max(0, tabs(i)-strlen)), cstr{i});
            end
        case 'r' % right aligned
            lstr = length(cstr{i});      
            if isempty(str)
                fstr =  tabs(i) - lstr;
                if fstr >= 0 % there's room between the tabs, so fill up
                    str = sprintf('%s%s', repmat(' ', 1, fstr), cstr{i});
                else % nibble some of the beginning of the current string
                    str = cstr{i}(1-fstr:end);
                end
            elseif (i > 1) & (alig(i-1)=='r') % there is a previous right aligned tab which we cannot cross
                fstr = tabs(i) - tabs(i-1) - lstr;
                if fstr >=0 % there's room between the tabs, so fill up
                    str = sprintf('%s%s%s', str, repmat(' ', 1, fstr), cstr{i});
                else % nibble some of the beginning of the current string           
                    str = sprintf('%s%s', str, cstr{i}(1-fstr:end));
                end
            else % no previous right aligned tab
                fstr = tabs(i) - strlen - lstr;
                if fstr >= 0 % there's room between the current tab and the previous string, so fill up
                    str = sprintf('%s%s%s', str, repmat(' ', 1, fstr), cstr{i});
                else
                    if (tabs(i) - lstr) < 0 % the current string doesn't fit on screen
                        str = cstr{i}(1:end-fstr);
                    else % nibble some of the end of the string
                        str = sprintf('%s%s', str(1:end+fstr), cstr{i});
                    end
                end
            end
    end
end

disp(str)
% -------------------------------------
function y = command_window_width

y = get(0, 'CommandWindowSize');
y = y(1);

Contact us