## Contents

- introduction
- --- syntax
- --- input
- --- output
- --- summary of options
- arrays and tables
- --- definitions
- --- formatting
- --- arrays
- --- creating tables using row/column options
- --- creating tables using the default format
- --- printing arrays that contain a predefined table
- --- leading and trailing text
- CELL conversion options
- --- 2D character arrays and ND cell arrays of ND character strings
- --- full mixed real and/or complex numeric arrays
- --- sparse mixed real and/or complex numeric arrays
- --- logical arrays
- --- NaN/Inf
- --- hexadecimal representation of numeric input
- cell arrays
- --- empty CELLs and other data types
- --- surrounding text of CELLs
- ND arrays
- ND cell arrays of mixed content
- --- page indexing
- ND structures
- --- anomalous structures
- ND arrays and ND cell arrays of other objects
- output files
- --- creating output files
- --- appending to files
- --- using a template file
- --- replacing tokens in template files
- option processing
- --- option precedence
- --- option preferences across MATLAB sessions
- --- reading and writing option files
- --- option structures
- engine options
- --- TAB size and TAB replacement in CELLs
- --- runtime printout
- output
- --- macros
- --- arguments
- --- input to xlswrite

## introduction

    % CPRINTF	us 11-Jun-2009 08:58:55 / us@neurol.unizh.ch
    %
    %		- converts an ND array of any MATLAB data type
    %		  to a 2D character array
    %		- the input may be a cell array formatted as a table with
    %		  row/column labels and row/column separators
    %		- any input can be formatted as a table using
    %		  any combination of
    %		  row/column labels and row/column separators
    %
    %		  use ML's web browser with html proportional text
    %		  set to a fixed font to see the HTML file with
    %		  proper formatting

## --- syntax

    %		[T,TC,AC,P] = CPRINTF(A,OPT1,...,OPTn)
    %				converts A
    %		 P          = CPRINTF
    %				returns  the engine parameters
    %		              CPRINTF
    %				displays the help

## --- input

    % A	:	an ND array of
    %  		- real and/or complex full   numeric data
    %  		- real and/or complex sparse numeric data
    %  		- logical data
    %  		- char strings
    %		- structures
    %  		- other objects
    %  		an ND cell array of any combination of the above

## --- output

    % T	:	character array with same number of rows and
    %		delimiter separated columns as A
    % TC	:	cell array of T
    % AC	:	cell array of A (useful if A is displayed as a table)
    % P	:	structure with engine parameters
    %
    % NOTE	:	unless an output argument is present, CPRINTF
    %		DOES print the result even if an [;] is added
    %		at the end to suppress printing

## --- summary of options

    % OPTION	argument	description		default
    % ----------------------------------------------------------------
    %		SC		a single CHAR
    %		CS		a CHAR string
    %		FS		a format spec
    % ----------------------------------------------------------------
    % CELL				data type
    % ----------------------------------------------------------------
    %    -c	:	FS		character string	'%s'
    %    -n	:	FS		numeric real		'%g'
    %   -cr	:	FS		numeric complex real	'%g'
    %   -ci	:	FS		numeric complex imag	'%+gi'
    %   -cd	:	FS		numeric complex delim	' '
    %    -s	:	FS		numeric sparse indices	'(%g %g)'
    %    -f	:	FS		false			'F'
    %    -t	:	FS		true			'T'
    %    -E	:	FS		empty CELL		'E(class)'
    %    -I	:	FS		±Inf			'±INF'
    %    -N	:	FS		NaN			'NAN'
    %   -hs	:	T|F		convert to single hex	[F]
    %   -hd	:	T|F		convert to double hex	[F]
    %  -nex	:	T|F		no char CELL expansion	[F]
    %    -O	:	FS		other objects		[built-in]
    %   -Or	:	T|F		other objects raw mode	[built-in]
    %    -C	:	FS		text surrounding CELLs	'%s'
    %   -la	:	T|F		cell content alignment	[F]
    %  -cla	:	T|F		complex alignment	[F]
    %				F = right align
    %				T = left  align
    %
    % ROW				content
    % ----------------------------------------------------------------
    %    -L	:	CS		leading   row text	''
    %    -T	:	CS		trailing  row text	''
    %    -d	:	SC		separator between CELLs	' '
    %   -dt	:	SC		separator table columns	' '
    %   -nd	:	T|F		show ND page indices	[F]
    %
    % TABLE				content / processing
    % ----------------------------------------------------------------
    %   -Ct	:	FS		text surrounding body	'%s'
    %				but not label CELLs
    %   -nc	:	FS		numeric real col	'%g'
    %   -nr	:	FS		numeric real row
    %   -Lh	:	{tn}		table  name		{' '}
    %   -Lc	:	{c1...cn}	column labels
    %   -Lr	:	{r1...rn}	row    labels
    %  -Lcs	:	SC		column separator	''
    %  -Lrs	:	SC		row    separator	''
    %   -it	:	T|F		input is a       table	[F]
    %   -mt	:	T|F		convert input to table	[F]
    %   -ic	:	T|F		column width		[F]
    %				F = max of all  cols
    %				T = max of each col
    %
    % OUTPUT FILES
    % ----------------------------------------------------------------
    %   -fa	:	name		append to output file	[]
    %   -fc	:	name		create    output file	[]
    %   -fi	:	name		input  file		[]
    %   -fm	:	marker		insert result at marker	[]
    %				in file [-fin]
    %   -fr	:	{t1,r1,...}	replace token tx with	[]
    %				value rx
    %
    % PROCESSING
    % ----------------------------------------------------------------
    %    -p	:	T|F		do NOT use preferences	[F]
    %  -opt	:	struct		use struct.option	[]
    %  -ini	:	name		read options from file	[]
    %  -sav	:	name		save options to   file	[]
    %  -tab	:	n		use n SPACES/TAB	[8]
    % -ntab	:	T|F		keep TABs in CELLs	[F]
    %    -q	:	n		do not display result	[F]
    %   -so	:	T|F		collect all output in	[F]
    %				a structure
    %   -db	:	T|F		show processing stages	[F]

## arrays and tables

## --- definitions

    % each element of an array of any data type including a cell array
    %    is considered a CELL
    % CELLs can be formatted in various ways according to the data type
    % a separator is printed between two CELLs
    %
    % CPRINTF optionally prints the input as a table consisting of
    %    default or user definable
    %    - table name
    %    - row and/or column labels
    %    - row and/or column separators
    %    in any combination
    % any input of min size 3x3 may be	printed   as a table	[-it]
    % any input of any size may be		converted to a table	[-mt]
    %
    % CPRINTF optionally prints LEADING and/or TRAILING text
    %    before and after each row of an array or a table

## --- formatting

    % sequence of formatting
    %
    % 1: CELL			each CELL's content is displayed according to
    %				   the various CELL formatting options
    %				by default, CELLs of Mx1 or ND character strings
    %				   are expanded unless the [-nex] option is used
    %				by default, all column widths of the array are
    %				   the maximun width of all columns after conversion
    %				   unless the [-ic] option is used, in which case
    %				   each column's max width is used
    %				a CELL's text may be left aligned [-la] with
    %				   respect to the column width
    % 2: CELL surroundings		each CELL's output may be embedded in additional
    %				   text options [-C]/[-Ct]
    % 3: CELL separators		a separator is inserted between two CELLs according
    %				   to the [-d] option
    % 4: ROW/COL labels		each label's numeric content is displayed according
    %				   to table [-nc]/[-nr] options
    % 5: ROW/COL separators		separators are displayed according to
    %				   various options and depend
    %				   on the content of the separator as well as
    %				   the content of the individual column separator
    %				   of a predefined table [-it]
    % 6: table name			is added at position (1,1) and formatted according
    %				   to the common [-n] option
    % 7: L/T text			row text delimiters are added
    %				   before (L) and/or after (T) the array or table
    %
    % options to create a format string
    %
    % 1:				an ANSI C format string, eg,
    %				      'a number %g'
    % 2:				an anonymous function returning a string, eg,
    %				      @(x) sprintf('a number %10d',x)
    % 3:				a handle to a user defined function
    %				   returning a string, eg,
    %				      @mynumber
    %				   where mynumber.m is a function file
    % 4:				a handle to a ML stock function
    %				   returning a string, eg,
    %				      @dec2bin

## --- arrays

    % NOTE:	all data is collected in structure S to not clutter the workspace

    % simple real numeric matrix

    	clear s;
    	s.r=reshape(1:4*6,[4,6]);

    	disp(s.r);

         1     5     9    13    17    21
         2     6    10    14    18    22
         3     7    11    15    19    23
         4     8    12    16    20    24

    % CPRINTF default output
    % - all CELL widths have the same max CELL width
    % - a CELL separator [-d] is inserted between CELLs 2:end-1 including
    %      row labels and separators if the output is a table

    % NOTE:	the [-tab] option (see section -engine options-) has NO effect
    %	on the column separator [-d] if it contains TABs

    	cprintf(s.r);

     1  5  9 13 17 21
     2  6 10 14 18 22
     3  7 11 15 19 23
     4  8 12 16 20 24

## --- creating tables using row/column options

    % label and separator options
    %-------------------------------------------------------------------------------
    % -Lh		name of the table at position (1,1)	{name}
    %		- numeric data is converted
    %		  according to the [-n] option
    %		- names are always left aligned
    % -Lc		col labels				{cl1,...,cln}
    % -Lr		row labels				{rl1,...,rln}
    %		- label(s) will be repeated or cut
    %		  automatically to fit the table size
    % -nc		format of numeric col labels		FS		['%g']
    % -nr		format of numeric row labels		FS		['%g']
    % -Lcs		col  separator				'csep'
    % -Lrs		row  separator				'rsep'
    % -d		CELL separator				'csep'
    %		- also apply to labels and
    %		  row/col separators
    %		- a '\t' is printed as TAB
    % -dt		CELL separator				'csep'
    %		- only apply to col labels
    %		  and separators in a table
    %		- a '\t' is printed as TAB

    % tables are constructed according to these input options

    	s.clab={'apple','orange','banana','kiwi','peach','pear','NOTUSED'};
    	s.rlab={'sweet','sour','salty','bitter'};

    	cprintf(s.r,...
    		'-Lc',	s.clab);

    apple orange banana   kiwi  peach   pear
        1      5      9     13     17     21
        2      6     10     14     18     22
        3      7     11     15     19     23
        4      8     12     16     20     24

    	cprintf(s.r,...
    		'-Lr',	s.rlab);

     sweet 1  5  9 13 17 21
      sour 2  6 10 14 18 22
     salty 3  7 11 15 19 23
    bitter 4  8 12 16 20 24

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lcs',	'=');

           apple orange banana   kiwi  peach   pear
    ===============================================
     sweet     1      5      9     13     17     21
      sour     2      6     10     14     18     22
     salty     3      7     11     15     19     23
    bitter     4      8     12     16     20     24

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-Lh',	{'A table'});

    A table |  apple orange banana   kiwi  peach   pear
    ===================================================
      sweet |      1      5      9     13     17     21
       sour |      2      6     10     14     18     22
      salty |      3      7     11     15     19     23
     bitter |      4      8     12     16     20     24

    % alignment of CELL content
    % by default, each CELL's content is right aligned within the cols max width
    %-------------------------------------------------------------------------------
    % -la:		left align				T|F	[F]

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-la',	1);

           | apple  orange banana kiwi   peach  pear
    ==================================================
    sweet  | 1      5      9      13     17     21
    sour   | 2      6      10     14     18     22
    salty  | 3      7      11     15     19     23
    bitter | 4      8      12     16     20     24

    % widths of CELL content
    % by default, the width of all CELLs is the max of all CELLs' width
    %-------------------------------------------------------------------------------
    % -ic		adjust each column width according	T|F	[F]
    %		to its max CELL width

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-ic',	1);

           | apple orange banana kiwi peach pear
    ============================================
     sweet |     1      5      9   13    17   21
      sour |     2      6     10   14    18   22
     salty |     3      7     11   15    19   23
    bitter |     4      8     12   16    20   24

    % CELL separators
    %-------------------------------------------------------------------------------
    % -d		CELL separator				'csep'
    % -dt		CELL separator of table body CELLs only	'csep'

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-d',	'<.>');				% global CELL separator

          <.>|<.> apple<.>orange<.>banana<.>  kiwi<.> peach<.>  pear
    ================================================================
     sweet<.>|<.>     1<.>     5<.>     9<.>    13<.>    17<.>    21
      sour<.>|<.>     2<.>     6<.>    10<.>    14<.>    18<.>    22
     salty<.>|<.>     3<.>     7<.>    11<.>    15<.>    19<.>    23
    bitter<.>|<.>     4<.>     8<.>    12<.>    16<.>    20<.>    24

    % using different separators in a table

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'#',...
    		'-Lcs',	'=',...
    		'-dt',	'|',...				% table body CELLs' separator
    		'-d',	'.');				% global CELL separator

          .#. apple|orange|banana|  kiwi| peach|  pear
    ==================================================
     sweet.#.     1|     5|     9|    13|    17|    21
      sour.#.     2|     6|    10|    14|    18|    22
     salty.#.     3|     7|    11|    15|    19|    23
    bitter.#.     4|     8|    12|    16|    20|    24

    % if the separators contain TAB(s), CELL separators will not be continuous
    %    for reasons of consistency

    	cprintf(s.r,...
    		'-Lr',	s.rlab,...
    		'-Lc',	s.clab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-dt',	'|',...				% table body CELLs' separator
    		'-d',	'\t');				% global CELL separator

          	|	 apple|orange|banana|  kiwi| peach|  pear
    ======	=	======|======|======|======|======|======
     sweet	|	     1|     5|     9|    13|    17|    21
      sour	|	     2|     6|    10|    14|    18|    22
     salty	|	     3|     7|    11|    15|    19|    23
    bitter	|	     4|     8|    12|    16|    20|    24

    % formatting of numeric row/column labels (see also [-n] below)

    	s.cclab=s.clab;
    	s.rrlab=s.rlab;
    	s.cclab([1,2])={1,20};
    	s.rrlab([1,4])={pi,-4*pi};
    	s.cfmt='col:%d';				% a char spec
    	s.rfmt=@(x) sprintf('row:%d/%8.4f',sign(x),x);	% a function handle

    	cprintf(s.r,...
    		'-Lr',	s.rrlab,...
    		'-Lc',	s.cclab,...
    		'-Lrs',	'|',...
    		'-Lcs',	'=',...
    		'-nc',	s.cfmt,...
    		'-nr',	s.rfmt);

                    |  col:1 col:20 banana   kiwi  peach   pear
    ===========================================================
     row:1/  3.1416 |      1      5      9     13     17     21
               sour |      2      6     10     14     18     22
              salty |      3      7     11     15     19     23
    row:-1/-12.5664 |      4      8     12     16     20     24

## --- creating tables using the default format

    % an array can be displayed as a table using default options
    %-------------------------------------------------------------------------------
    % -mt		create a table				T|F	[F]

    	cprintf(s.r,...
    		'-mt',	1);

        | c:1 c:2 c:3 c:4 c:5 c:6
    -----------------------------
    r:1 |   1   5   9  13  17  21
    r:2 |   2   6  10  14  18  22
    r:3 |   3   7  11  15  19  23
    r:4 |   4   8  12  16  20  24

    % any row [-Lr]/[-Lrs] and/or column option [-Lc]/[-Lcs] overrides
    %    the default option

    	cprintf(s.r,...
    		'-mt',	1,...
    		'-Lcs',	'=',...
    		'-Lr',	s.rlab,...
    		'-Lh',	{'TBL.1'});

    TBL.1  | c:1 c:2 c:3 c:4 c:5 c:6
    ================================
     sweet |   1   5   9  13  17  21
      sour |   2   6  10  14  18  22
     salty |   3   7  11  15  19  23
    bitter |   4   8  12  16  20  24

## --- printing arrays that contain a predefined table

    % an input cell array, which is already in the format of a complete table,
    %    can be displayed using the auto-formatting option
    %-------------------------------------------------------------------------------
    % -it		assumes the input is a complete table	T|F	[F]
    %		consisting of
    %		- col labels and separators
    %		- row labels and separators

    	s.tbl={
    %	row	row
    %	labels	separators
    	'tbl',	'|',		'C1','C2','C3','C4','C5','C6'	% col labels
    	'=',	'=',		'=','-','=','sep','=','-'	% col separators
    	'R1',	'sep',		1,2,3,4,5,6
    	'R2',	'#',		1,2,3,4,5,6
    	};

    % raw output of the cell

    	disp(s.tbl);
    	cprintf(s.tbl);

        'tbl'    '|'      'C1'    'C2'    'C3'    'C4'     'C5'    'C6'
        '='      '='      '='     '-'     '='     'sep'    '='     '-'
        'R1'     'sep'    [ 1]    [ 2]    [ 3]    [  4]    [ 5]    [ 6]
        'R2'     '#'      [ 1]    [ 2]    [ 3]    [  4]    [ 5]    [ 6]

    tbl   |  C1  C2  C3  C4  C5  C6
      =   =   =   -   = sep   =   -
     R1 sep   1   2   3   4   5   6
     R2   #   1   2   3   4   5   6

    % output as a table

    % NOTE:	single char col separators are repeated to the width of each col
    %	multi  char col separators are printed according to the [-la] option
    %	the [-ic] CELL width option may be applied

    	cprintf(s.tbl,...
    		'-it',	1);

    tbl   |  C1  C2  C3  C4  C5  C6
    ===========----==== sep====----
     R1 sep   1   2   3   4   5   6
     R2   #   1   2   3   4   5   6

    % any row [-Lr]/[-Lrs] and/or column option [-Lc]/[-Lcs] overrides
    %    the default option

    	cprintf(s.tbl,...
    		'-it',	1,...
    		'-Lr',	{'a','b'},...
    		'-Lcs',	'*');

    tbl   | C1 C2 C3 C4 C5 C6
    *************************
      a sep  1  2  3  4  5  6
      b   #  1  2  3  4  5  6

## --- leading and trailing text

    % text can be added before or after an array or table
    %-------------------------------------------------------------------------------
    % -L		leading  text				character string
    % -T		trailing text				character string

    	cprintf(s.r,...
    		'-L',	'row\t');

    row	 1  5  9 13 17 21
    row	 2  6 10 14 18 22
    row	 3  7 11 15 19 23
    row	 4  8 12 16 20 24

    	cprintf(s.tbl,...
    		'-it',	1,...
    		'-L',	'my rows\t',...
    		'-T',	'\teor');

    my rows	tbl   |  C1  C2  C3  C4  C5  C6	eor
    my rows	===========----==== sep====----	eor
    my rows	 R1 sep   1   2   3   4   5   6	eor
    my rows	 R2   #   1   2   3   4   5   6	eor

## CELL conversion options

    % NOTE: the [-mt] option is used throughout for ease of visibility

## --- 2D character arrays and ND cell arrays of ND character strings

    % by default, Mx1 or ND character strings are expanded to 2D arrays
    %    before conversion
    %-------------------------------------------------------------------------------
    % -nex		do NOT expand				T|F	[F]
    %		use [-O] option display style

    % a simple array of character strings

    	s.sc=[
    		'this is a'
    		'  test   '
    	];

    % white spaces are kept and the [-la] option has NO effect

    	cprintf(s.sc,...
    		'-mt',	1,...
    		'-la',	1);				% left align

        | c:1
    ---------------
    r:1 | this is a
    r:2 |   test

    % a cell array of 1xN character strings

    	s.cs={
    		'this is'	'yet another'
    		'test'		'    example'		% (2,2) has SPACEs!
    	};

    	cprintf(s.cs,...
    		'-mt',	1);

        |         c:1         c:2
    -----------------------------
    r:1 |     this is yet another
    r:2 |        test     example

    % NOTE:	the [-la] option has an effect EXCEPT for embedded SPACEs

    	cprintf(s.cs,...
    		'-mt',	1,...
    		'-la',	1);				% left align

        | c:1         c:2
    -----------------------------
    r:1 | this is     yet another
    r:2 | test            example

    % a cell array of mixed MxN character strings

    	s.ndcs={'foo','GOO'.';'HOO'.','ioo'};

    	disp(s.ndcs);

        'foo'         [3x1 char]
        [3x1 char]    'ioo'

    % NOTE:	placeholders for 1xN character arrays

    	cprintf(s.ndcs,...
    		'-mt',	1,...
    		'-la',	1,...				% left align
    		'-d',	'\t');				% delimiter: TAB

       	|	c:1	c:2
    ---	-	---	---
    r:1	|	foo	G
    r:2	|	   	O
    r:3	|	   	O
    r:4	|	H  	ioo
    r:5	|	O
    r:6	|	O

    	s.ndsc={
    		s.sc,		[s.sc;s.sc;s.sc],	s.sc
    		s.sc,		'FOO',			[s.sc;s.sc]
    		'XXX'.',	s.sc			[s.sc;s.sc]
    	};

    	disp(s.ndsc);

        [2x9 char]    [6x9 char]    [2x9 char]
        [2x9 char]    'FOO'         [4x9 char]
        [3x1 char]    [2x9 char]    [4x9 char]

    	cprintf(s.ndsc,...
    		'-mt',	1,...
    		'-la',	1,...				% left align
    		'-d',	'   ');				% delimiter: 3 SPACEs

           |   c:1         c:2         c:3
    --------------------------------------------
    r:01   |   this is a   this is a   this is a
    r:02   |     test        test        test
    r:03   |               this is a
    r:04   |                 test
    r:05   |               this is a
    r:06   |                 test
    r:07   |   this is a   FOO         this is a
    r:08   |     test                    test
    r:09   |                           this is a
    r:10   |                             test
    r:11   |   X           this is a   this is a
    r:12   |   X             test        test
    r:13   |   X                       this is a
    r:14   |                             test

    % a ND cell array of MxN character strings

    	s.ndnd(:,:,1)=s.ndsc;
    	s.ndnd(:,:,2)=s.ndsc;

    	disp(s.ndnd);

    (:,:,1) =

        [2x9 char]    [6x9 char]    [2x9 char]
        [2x9 char]    'FOO'         [4x9 char]
        [3x1 char]    [2x9 char]    [4x9 char]

    (:,:,2) =

        [2x9 char]    [6x9 char]    [2x9 char]
        [2x9 char]    'FOO'         [4x9 char]
        [3x1 char]    [2x9 char]    [4x9 char]

    	cprintf(s.ndnd,...
    		'-mt',	1,...
    		'-dt',	'|');

         |       c:1|      c:2|      c:3
    ------------------------------------
    r:01 | this is a|this is a|this is a
    r:02 |   test   |  test   |  test
    r:03 |          |this is a|
    r:04 |          |  test   |
    r:05 |          |this is a|
    r:06 |          |  test   |
    r:07 | this is a|      FOO|this is a
    r:08 |   test   |         |  test
    r:09 |          |         |this is a
    r:10 |          |         |  test
    r:11 |         X|this is a|this is a
    r:12 |         X|  test   |  test
    r:13 |         X|         |this is a
    r:14 |          |         |  test
    r:15 | this is a|this is a|this is a
    r:16 |   test   |  test   |  test
    r:17 |          |this is a|
    r:18 |          |  test   |
    r:19 |          |this is a|
    r:20 |          |  test   |
    r:21 | this is a|      FOO|this is a
    r:22 |   test   |         |  test
    r:23 |          |         |this is a
    r:24 |          |         |  test
    r:25 |         X|this is a|this is a
    r:26 |         X|  test   |  test
    r:27 |         X|         |this is a
    r:28 |          |         |  test

    % do not expand non-1xN character strings

    	cprintf(s.ndnd,...
    		'-mt',	1,...
    		'-nex',	1);

        |           c:1           c:2           c:3
    -----------------------------------------------
    r:1 | O(2:2x9:char) O(2:6x9:char) O(2:2x9:char)
    r:2 | O(2:2x9:char)           FOO O(2:4x9:char)
    r:3 | O(2:3x1:char) O(2:2x9:char) O(2:4x9:char)
    r:4 | O(2:2x9:char) O(2:6x9:char) O(2:2x9:char)
    r:5 | O(2:2x9:char)           FOO O(2:4x9:char)
    r:6 | O(2:3x1:char) O(2:2x9:char) O(2:4x9:char)

## --- full mixed real and/or complex numeric arrays

    % formatting options for numeric data (see section -formatting-)
    %-------------------------------------------------------------------------------
    % -n		real numbers				FS	['%g']
    % -cr		real      part of complex numbers	FS	['%g']
    % -ci		imaginary part of complex numbers	FS	['%+gi]
    % -cd		delimiter between real/imaginary part	FS	[' ']
    % -cla		left align imaginary parts		T|F	[F]

    	s.m=[
    		1,		2,		3+3i
    		nan-4.2i,	nan,		inf
    		-inf,		inf+3i*inf,	inf+5.5i
    	];

    	disp(num2cell(s.m));

        [                1]    [          2]    [  3 +          3i]
        [NaN -        4.2i]    [        NaN]    [              Inf]
        [             -Inf]    [NaN +  Infi]    [Inf +        5.5i]

    % unlike DISP, CPRINTF prints real numbers
    %    at the position of the real part of the complex number
    %    for reasons of consistency
    % column widths of real and imaginary parts are adjusted to the respective max
    %    width of each component (see c:2)

    	cprintf(s.m,...
    		'-mt',	1);

        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i

    % left align imaginary parts of complex numbers [-cla]

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-cla',	1);

        |        c:1        c:2        c:3
    --------------------------------------
    r:1 | 1          2          3    +3i
    r:2 | NaN  -4.2i NaN        Inf
    r:3 | -Inf       NaN  +Infi Inf  +5.5i

    % using various numeric options

    % NOTE:	only real numbers use the [-n] option
    %	the [-cd] separator is applied to ALL numbers

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-n',	@(x) sprintf('%g=%s',x,num2hex(single(x))),...
    		'-cr',	'R %g',...
    		'-ci',	'I %+gi',...
    		'-cd',	' / ');

        |                     c:1                     c:2                     c:3
    -----------------------------------------------------------------------------
    r:1 |    1=3f800000 /            2=40000000 /                   R 3 /   I +3i
    r:2 |         R NaN / I -4.2i  NaN=ffc00000 /          Inf=7f800000 /
    r:3 | -Inf=ff800000 /                 R NaN / I +Infi         R Inf / I +5.5i

## --- sparse mixed real and/or complex numeric arrays

    % sparse arrays are displayed in accordance with ML's DISP functionality
    % col 1		indices
    % col 2		values
    %
    % formatting options for numeric data (see section -formatting-)
    %-------------------------------------------------------------------------------
    % -s		sparse indices must take TWO args	FS	[('%g %g)']

    	s.s=sparse(4,4);

    % output of empty sparse arrays show max indices with a value of zero

    	cprintf(s.s,...
    		'-mt',	1);

        |   c:1   c:2
    -----------------
    r:1 | (4 4)     0

    	s.s(1,1)=nan;
    	s.s(1,2)=inf;
    	s.s(1,3)=-inf;
    	s.s(1,4)=pi;
    	s.s(2,1)=4+3i;
    	s.s(2,2)=5+4i*inf;
    	s.s(2,3)=6+5i*nan;

    	disp(s.s);

       (1,1)             NaN
       (2,1)               4 +          3i
       (1,2)             Inf
       (2,2)             NaN +        Infi
       (1,3)            -Inf
       (2,3)             NaN +        NaNi
       (1,4)          3.1416

    	cprintf(s.s,...
    		'-mt',	1);

        |           c:1           c:2
    ---------------------------------
    r:1 |         (1 1)     NaN
    r:2 |         (2 1)       4   +3i
    r:3 |         (1 2)     Inf
    r:4 |         (2 2)     NaN +Infi
    r:5 |         (1 3)    -Inf
    r:6 |         (2 3)     NaN  NaNi
    r:7 |         (1 4) 3.14159

    % using various options

    	cprintf(s.s,...
    		'-mt',	1,...
    		'-ic',	1,...				% use individual col width
    		'-n',	'    value: %6.2f',...		% real numbers
    		'-cr',	'    value: %6.2f',...		% real part of complex numbers
    		'-s',	@(x,y) sprintf('R=%d C=%d',x,y));

        |     c:1                     c:2
    -------------------------------------
    r:1 | R=1 C=1     value:    NaN
    r:2 | R=2 C=1     value:   4.00   +3i
    r:3 | R=1 C=2     value:    Inf
    r:4 | R=2 C=2     value:    NaN +Infi
    r:5 | R=1 C=3     value:   -Inf
    r:6 | R=2 C=3     value:    NaN  NaNi
    r:7 | R=1 C=4     value:   3.14

## --- logical arrays

    % formatting options for logical data (see section -formatting-)
    %-------------------------------------------------------------------------------
    % -t		TRUE  values				FS	['T']
    % -f		FALSE values				FS	['F']

    	cprintf(real(s.m)>4,...
    		'-mt',	1);

        | c:1 c:2 c:3
    -----------------
    r:1 |   F   F   F
    r:2 |   F   F   T
    r:3 |   F   F   T

    	cprintf(imag(s.m)<1,...
    		'-mt',	1,...
    		'-f',	'NO',...
    		'-t',	'yes');

        | c:1 c:2 c:3
    -----------------
    r:1 | yes yes  NO
    r:2 | yes yes yes
    r:3 | yes  NO  NO

## --- NaN/Inf

    % formatting options for NaN/Inf (see section -formatting-)
    %-------------------------------------------------------------------------------
    % -N:		NaN      values				FS	[ML def]
    % -I:		-Inf/Inf values				FS	[ML def]
    %
    % NOTE:	[-N] and/or [-I] options override ALL other options for numeric
    %	data types for reasons of consistency

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-d',	'\t');				% use TAB as CELL separator

       	|	       c:1	       c:2	       c:3
    ---	-	----------	----------	----------
    r:1	|	   1      	   2      	   3   +3i
    r:2	|	 NaN -4.2i	 NaN      	 Inf
    r:3	|	-Inf      	 NaN +Infi	 Inf +5.5i

    % using various options

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-d',	'\t',...			% use TAB as CELL separator
    		'-n',	'%5.2f',...			% real numbers
    		'-N',	'#fff#',...			% NaNs, eg, for a spreadsheet
    		'-I',	@(x) sprintf('%dI',sign(x)),...	% Infs
    		'-ci',	'%5.2fi');			% imaginary part of complex numbers

       	|	         c:1	         c:2	         c:3
    ---	-	------------	------------	------------
    r:1	|	 1.00       	 2.00       	    3  3.00i
    r:2	|	#fff# -4.20i	#fff#       	   1I
    r:3	|	  -1I       	#fff#     1I	   1I  5.50i

## --- hexadecimal representation of numeric input

    % conversion to singles/doubles IEEE hexadecimal strings
    %-------------------------------------------------------------------------------
    % -hs		all numeric CELLs are converted to
    %		   single hex				T|F	[F]
    % -hd		   double hex				T|F	[F]

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-hs',	1);

        |               c:1               c:2               c:3
    -----------------------------------------------------------
    r:1 | 3f800000          40000000          40400000 40400000
    r:2 | ffc00000 c0866666 ffc00000          7f800000
    r:3 | ff800000          ffc00000 7f800000 7f800000 40b00000

## cell arrays

    % ALL CELLs of a cell array are formatted according to the above formatting rules
    % if a CELL contains complex data, ALL numbers will be displayed using
    %    the complex spacing mode (see above)
    % if a CELL contains sparse data, it is converted to full
    %    prior to conversion
    % a cell array of any (mixed) content can be displayed as a table

    	s.ss=sparse(1,1,-pi);
    	s.cc={
    		'this',		'is',	false,	2-3i,	nan
    		'a cell',	pi,	1000,	s.ss,	true
    	};

    	cprintf(s.cc,...
    		'-mt',	1);

        |          c:1          c:2          c:3          c:4          c:5
    ----------------------------------------------------------------------
    r:1 |         this           is            F        2 -3i      NaN
    r:2 |       a cell  3.14159         1000     -3.14159                T

## --- empty CELLs and other data types

    % formatting options for empty CELLs and other data types
    %    (see section -formatting-)
    %-------------------------------------------------------------------------------
    % -E		empty CELLs				FS	['E(class)']
    %		EXCEPT empty character strings
    % -O		other data types			FS	[built-in]
    %		including ND arrays of any type
    %		default output according to the input
    %		logical:	L(dim:size:class)
    %		numeric:	N(dim:size:class.g.s.c)
    %		      g:	is global
    %		      s:	is sparse
    %		      c:	is complex
    %		cell   :	C(dim:size:class)
    %		struct :	S(dim:size:class)
    %		func   :	F(@function)
    %		other  :	O(dim:size:class)
    % -Or		only show content within brackets, eg,	T|F	[F]
    %		to save function handle definitions
    %		in an ASCII file

    % NOTE:	the [-O] option will be applied to ALL other data types
    %	the engine structure returns a function handle, which
    %	may be used to check conversion (see section -macros-)
    %
    %		p=cprintf;	% returns the engine structure
    %		r=p.other(magic(3)+4i)
    %		r = N(2:3x3:double.c)
    %
    %	users can write their own functions, which must return
    %	a 1xN character string
    %
    %		cprintf(...,'-O',@myother)

    % NOTE:	difference of default output of various empty/other data

    	cprintf([],...
    		'-Lr',	{'empty array             []'},...
    		'-mt',	1);

    	cprintf({[]},...
    		'-Lr',	{'cell with empty array {[]}'},...
    		'-mt',	1);

    	cprintf({},...
    		'-Lr',	{'empty cell              {}'},...
    		'-mt',	1);

    	cprintf({{}},...
    		'-Lr',	{'cell with empty cell  {{}}'},...
    		'-mt',	1);

                               |       c:1
    --------------------------------------
    empty array             [] | E(double)
                               |       c:1
    --------------------------------------
    cell with empty array {[]} | E(double)
                               |     c:1
    ------------------------------------
    empty cell              {} | E(cell)
                               |      c:1
    -------------------------------------
    cell with empty cell  {{}} | C(2:0x0)

    	s.cc(1,1)={@(x) x};
    	s.cc(1,3)={[]};
    	s.cc(2,3)={sparse(3,3,-pi)};
    	s.cc(2,1)={repmat(struct('a','b'),[2,3,3])};
    	s.cc(3,1)={cell([3,3,3])};
    	s.cc(3,2)={s.cc};
    	s.cc(3,3)={repmat(struct('a',{'a'}),[2,2,3])};

    	disp(s.cc);

      Columns 1 through 4

        @(x)x             'is'                      []    [2 -          3i]
        [2x3x3 struct]    [  3.1416]    [3x3   double]    [        -3.1416]
        {3x3x3 cell  }    {3x5 cell}    [2x2x3 struct]                   []

      Column 5

        [NaN]
        [  1]
           []

    	cprintf(s.cc,...
    		'-mt',	1);

        |             c:1             c:2             c:3             c:4             c:5
    -------------------------------------------------------------------------------------
    r:1 |        F(@(x)x)              is       E(double)           2 -3i         NaN
    r:2 |      S(3:2x3x3)     3.14159     N(2:3x3:double)    -3.14159                   T
    r:3 |      C(3:3x3x3)        C(2:3x5)      S(3:2x2x3)       E(double)       E(double)

    % using [-E]/[-O] options

    	s.O=@(x) sprintf('o:%d/%s',ndims(x),class(x));

    	cprintf(s.cc,...
    		'-mt',	1,...
    		'-E',	'empty',...			% EMPYT CELLs
    		'-O',	s.O);				% OTHER CELL content

        |                 c:1                 c:2                 c:3                 c:4                 c:5
    ---------------------------------------------------------------------------------------------------------
    r:1 | o:2/function_handle                  is               empty               2 -3i             NaN
    r:2 |          o:3/struct         3.14159              o:2/double        -3.14159                       T
    r:3 |            o:3/cell            o:2/cell          o:3/struct               empty               empty

## --- surrounding text of CELLs

    % CELLs may be displayed with an additional surrounding text
    %-------------------------------------------------------------------------------
    % -C		surrounding of EACH CELL		FS	['%s']
    %		including labels and separators
    % -Ct		surrounding of table body CELLs only	FS	['%s']

    % NOTE:	FS must only contain %s format specs

    % embedding all CELLs

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-C',	'<%s>');

    < >   <|>        <c:1>        <c:2>        <c:3>
    ------------------------------------------------
    <r:1> <|> <   1      > <   2      > <   3   +3i>
    <r:2> <|> < NaN -4.2i> < NaN      > < Inf      >
    <r:3> <|> <-Inf      > < NaN +Infi> < Inf +5.5i>

    % only embedding table body CELLs

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-Ct',	'{%s\t}');

        |                  c:1                  c:2                  c:3
    --------------------------------------------------------------------
    r:1 | {   1              } {   2              } {   3   +3i        }
    r:2 | { NaN -4.2i        } { NaN              } { Inf              }
    r:3 | {-Inf              } { NaN +Infi        } { Inf +5.5i        }

## ND arrays

    % ND arrays are displayed according to ML's display rules
    %    all arrays are converted to their 2D equivalent
    %

    	s.nda=reshape(1:2*4*2*2*2,[2,4,2,2,2]);

    	disp(s.nda);

    (:,:,1,1,1) =

         1     3     5     7
         2     4     6     8

    (:,:,2,1,1) =

         9    11    13    15
        10    12    14    16

    (:,:,1,2,1) =

        17    19    21    23
        18    20    22    24

    (:,:,2,2,1) =

        25    27    29    31
        26    28    30    32

    (:,:,1,1,2) =

        33    35    37    39
        34    36    38    40

    (:,:,2,1,2) =

        41    43    45    47
        42    44    46    48

    (:,:,1,2,2) =

        49    51    53    55
        50    52    54    56

    (:,:,2,2,2) =

        57    59    61    63
        58    60    62    64

    	cprintf(s.nda,...
    		'-mt',	1);

         | c:1 c:2 c:3 c:4
    ----------------------
    r:01 |   1   3   5   7
    r:02 |   2   4   6   8
    r:03 |   9  11  13  15
    r:04 |  10  12  14  16
    r:05 |  17  19  21  23
    r:06 |  18  20  22  24
    r:07 |  25  27  29  31
    r:08 |  26  28  30  32
    r:09 |  33  35  37  39
    r:10 |  34  36  38  40
    r:11 |  41  43  45  47
    r:12 |  42  44  46  48
    r:13 |  49  51  53  55
    r:14 |  50  52  54  56
    r:15 |  57  59  61  63
    r:16 |  58  60  62  64

## ND cell arrays of mixed content

    % ND cell arrays are converted according to their CELL content
    %    the cell array is converted to its 2D equivalent

    	s.cmc=reshape(num2cell(1:2*2*2*2),[2,2,2,2]);
    	s.cmc(1,1,1,1)={magic(3)};
    	s.cmc(2,2,1,1)={s.ndcs};
    	s.cmc(1:2,1:2,2,1)=s.ndcs;
    	s.cmc(1,1,1,2)={'foo'};
    	s.cmc(1:2,2,1,2)={false,true};
    	s.cmc(1,1:2,2,2)={nan,-inf};
    	s.cmc(2,1:2,2,2)={-100-2i,100+2i};

    	disp(s.cmc);

    (:,:,1,1) =

        [3x3 double]    [       3]
        [         2]    {2x2 cell}

    (:,:,2,1) =

        'foo'         [3x1 char]
        [3x1 char]    'ioo'

    (:,:,1,2) =

        'foo'    [0]
        [ 10]    [1]

    (:,:,2,2) =

        [               NaN]    [             -Inf]
        [-100 -          2i]    [100 +          2i]

    % NOTE:	display of vertical character strings
    %	with proper spacing of other content
    %	all numbers are displayed in complex style

    	cprintf(s.cmc,...
    		'-mt',	1,...
    		'-f',	'NO',...
    		'-t',	'YES',...
    		'-N',	'a nan',...
    		'-Ct',	'<%s>',...
    		'-dt',	' | ',...
    		'-d',	'\t');

        	|	              c:1 |               c:2
    ----	-	----------------- | -----------------
    r:01	|	<N(2:3x3:double)> |       <    3    >
    r:02	|	      <    2    > |        <C(2:2x2)>
    r:03	|	            <foo> |               <G>
    r:04	|	               <> |               <O>
    r:05	|	               <> |               <O>
    r:06	|	              <H> |             <ioo>
    r:07	|	              <O> |                <>
    r:08	|	              <O> |                <>
    r:09	|	            <foo> |              <NO>
    r:10	|	      <   10    > |             <YES>
    r:11	|	      <a nan    > |       < -Inf    >
    r:12	|	      < -100 -2i> |       <  100 +2i>

## --- page indexing

    % a page index may be displayed, which adheres to the common ML display rules
    %-------------------------------------------------------------------------------
    % -nd		show page indices			T|F	[F]

    % NOTE:	if the [-Lr] option is used, only data rows
    %	must be labelled
    %	page index rows are labelled 'page' by default

    	cprintf(s.nda,...
    		'-mt',	1,...
    		'-nd',	1);

         |             c:1             c:2             c:3             c:4
    ----------------------------------------------------------------------
    page | (1:2,1:4,1,1,1)
    r:01 |               1               3               5               7
    r:02 |               2               4               6               8
    page | (1:2,1:4,2,1,1)
    r:03 |               9              11              13              15
    r:04 |              10              12              14              16
    page | (1:2,1:4,1,2,1)
    r:05 |              17              19              21              23
    r:06 |              18              20              22              24
    page | (1:2,1:4,2,2,1)
    r:07 |              25              27              29              31
    r:08 |              26              28              30              32
    page | (1:2,1:4,1,1,2)
    r:09 |              33              35              37              39
    r:10 |              34              36              38              40
    page | (1:2,1:4,2,1,2)
    r:11 |              41              43              45              47
    r:12 |              42              44              46              48
    page | (1:2,1:4,1,2,2)
    r:13 |              49              51              53              55
    r:14 |              50              52              54              56
    page | (1:2,1:4,2,2,2)
    r:15 |              57              59              61              63
    r:16 |              58              60              62              64

    	cprintf(s.cmc,...
    		'-mt',	1,...
    		'-nd',	1);

         |             c:1             c:2
    --------------------------------------
    page |   (1:2,1:2,1,1)
    r:01 | N(2:3x3:double)           3
    r:02 |           2            C(2:2x2)
    page |   (1:2,1:2,2,1)
    r:03 |             foo               G
    r:04 |                               O
    r:05 |                               O
    r:06 |               H             ioo
    r:07 |               O
    r:08 |               O
    page |   (1:2,1:2,1,2)
    r:09 |             foo               F
    r:10 |          10                   T
    page |   (1:2,1:2,2,2)
    r:11 |         NaN            -Inf
    r:12 |        -100 -2i         100 +2i

## ND structures

    % a (ND) structure is displayed in the form
    %
    %	fieldname separator fieldcontent
    %
    % any content of a field is formatted according to the CELL formatting rules
    % if the table option [-mt] is used, both fieldname(s) and fieldcontent have
    %    their own column(s)
    % the layout of ND structures follows the general ML rules for ND data types
    %    and the [-nd] option may be used

    % an ND structure with unique fieldcontent reflecting the indices

    	s.siz=[2,2,3,2];
    	s.fh=cprintf;
    	s.ns=num2cell(s.fh.comb(s.siz));
    	s.st=struct('a','','bb','','ccc','');
    	s.st=repmat(s.st,s.siz);
    for	ii=1:size(s.ns,1)
    	s.txt=sprintf('%d.',s.ns{ii,:});
    	s.txt(end)='';
    	s.st(s.ns{ii,:}).a=sprintf('%s-A',s.txt);
    	s.st(s.ns{ii,:}).bb=sprintf('%s-B',s.txt);
    	s.st(s.ns{ii,:}).ccc='XYZ'.';			% a 3x1 character string
    end
    	clear ii;

    	disp(s.st);
    	disp('structure with indices (1,1,3,2)');
    	disp(s.st(1,1,3,2));

    4-D struct array with fields:
        a
        bb
        ccc

    structure with indices (1,1,3,2)
          a: '1.1.3.2-A'
         bb: '1.1.3.2-B'
        ccc: [3x1 char]

    % NOTE:	display of Mx1 character string

    	cprintf(s.st(1,1,3,2),...
    		'-mt',	1,...
    		'-Lc',	{'fieldname','value'},...
    		'-dt',	' :  ');

        | fieldname :      value
    ----------------------------
    r:1 |         a :  1.1.3.2-A
    r:2 |        bb :  1.1.3.2-B
    r:3 |       ccc :          X
    r:4 |           :          Y
    r:5 |           :          Z

    % NOTE:	page indices 1 and 2 display the number of structures and
    %	NOT the number of fieldnames and columns

    	cprintf(s.st,...
    		'-mt',	1,...
    		'-nd',	1,...				% show page indices
    		'-nex',	1,...				% do not expand char strings
    		'-dt',	'|');				% table cell separator

         |           c:1|          c:2|          c:3|          c:4
    --------------------------------------------------------------
    page | (1:2,1:2,1,1)|             |             |
    r:01 |             a|    1.1.1.1-A|            a|    1.2.1.1-A
    r:02 |            bb|    1.1.1.1-B|           bb|    1.2.1.1-B
    r:03 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:04 |             a|    2.1.1.1-A|            a|    2.2.1.1-A
    r:05 |            bb|    2.1.1.1-B|           bb|    2.2.1.1-B
    r:06 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    page | (1:2,1:2,2,1)|             |             |
    r:07 |             a|    1.1.2.1-A|            a|    1.2.2.1-A
    r:08 |            bb|    1.1.2.1-B|           bb|    1.2.2.1-B
    r:09 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:10 |             a|    2.1.2.1-A|            a|    2.2.2.1-A
    r:11 |            bb|    2.1.2.1-B|           bb|    2.2.2.1-B
    r:12 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    page | (1:2,1:2,3,1)|             |             |
    r:13 |             a|    1.1.3.1-A|            a|    1.2.3.1-A
    r:14 |            bb|    1.1.3.1-B|           bb|    1.2.3.1-B
    r:15 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:16 |             a|    2.1.3.1-A|            a|    2.2.3.1-A
    r:17 |            bb|    2.1.3.1-B|           bb|    2.2.3.1-B
    r:18 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    page | (1:2,1:2,1,2)|             |             |
    r:19 |             a|    1.1.1.2-A|            a|    1.2.1.2-A
    r:20 |            bb|    1.1.1.2-B|           bb|    1.2.1.2-B
    r:21 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:22 |             a|    2.1.1.2-A|            a|    2.2.1.2-A
    r:23 |            bb|    2.1.1.2-B|           bb|    2.2.1.2-B
    r:24 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    page | (1:2,1:2,2,2)|             |             |
    r:25 |             a|    1.1.2.2-A|            a|    1.2.2.2-A
    r:26 |            bb|    1.1.2.2-B|           bb|    1.2.2.2-B
    r:27 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:28 |             a|    2.1.2.2-A|            a|    2.2.2.2-A
    r:29 |            bb|    2.1.2.2-B|           bb|    2.2.2.2-B
    r:30 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    page | (1:2,1:2,3,2)|             |             |
    r:31 |             a|    1.1.3.2-A|            a|    1.2.3.2-A
    r:32 |            bb|    1.1.3.2-B|           bb|    1.2.3.2-B
    r:33 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)
    r:34 |             a|    2.1.3.2-A|            a|    2.2.3.2-A
    r:35 |            bb|    2.1.3.2-B|           bb|    2.2.3.2-B
    r:36 |           ccc|O(2:3x1:char)|          ccc|O(2:3x1:char)

    % show content of a LINE graphics handle

    	s.fh=figure('visible','off');
    	cprintf(struct(handle(line)),...
    		'-mt',	1,...
    		'-dt',	' :  ');
    	delete(s.fh);					% clean up

         |                    c:1 :                     c:2
    -------------------------------------------------------
    r:01 |            DisplayName :
    r:02 |             Annotation :  O(2:1x1:hg.Annotation)
    r:03 |                  Color :         N(2:1x3:double)
    r:04 |              LineStyle :                       -
    r:05 |              LineWidth :                     0.5
    r:06 |                 Marker :                    none
    r:07 |             MarkerSize :                       6
    r:08 |        MarkerEdgeColor :                    auto
    r:09 |        MarkerFaceColor :                    none
    r:10 |                  XData :         N(2:1x2:double)
    r:11 |                  YData :         N(2:1x2:double)
    r:12 |                  ZData :               E(double)
    r:13 |           BeingDeleted :                     off
    r:14 |          ButtonDownFcn :               E(double)
    r:15 |               Children :               E(double)
    r:16 |               Clipping :                      on
    r:17 |              CreateFcn :               E(double)
    r:18 |              DeleteFcn :               E(double)
    r:19 |             BusyAction :                   queue
    r:20 |       HandleVisibility :                      on
    r:21 |                HitTest :                      on
    r:22 |          Interruptible :                      on
    r:23 |               Selected :                     off
    r:24 |     SelectionHighlight :                      on
    r:25 |                    Tag :
    r:26 |                   Type :                    line
    r:27 |          UIContextMenu :               E(double)
    r:28 |               UserData :               E(double)
    r:29 |                Visible :                      on
    r:30 |                 Parent :                 171.001

## --- anomalous structures

    % anomalous structures of the form

    	s.san=struct('a',{},'b',1);

    % are valid MATLAB constructs

    	s.san
    	clear ans;					% clean up

    % but yield an error if used like
    %{
    	val=s.san.a
    ??? Too many outputs requested.  Most likely cause is missing [] around
    left hand side that has a comma separated list expansion.
    %}

    % they are displayed with a fieldcontent of [?]

    	cprintf(s.san,...
    		'-mt',	1,...
    		'-Lc',	{'fieldname','value'},...
    		'-dt',	' :  ');

    ans =

    0x0 struct array with fields:
        a
        b

        | fieldname :      value
    ----------------------------
    r:1 |         a :        [?]
    r:2 |         b :        [?]

## ND arrays and ND cell arrays of other objects

    % other objects are displayed according to the [-O] options

    if	ispc

    	s.fh=figure('visible','off');
    	s.com=actxcontrol('mscal.Calendar',[20 20 300 300],s.fh);
    	s.fun=@(x) x+10;

    	s.O=@(x) sprintf('%s(%s )',class(x),sprintf(' %d',size(x)));

    	cprintf([s.com;s.com],...
    		'-mt',	1,...
    		'-O',	s.O);				% show class:size

        |                       c:1
    -------------------------------
    r:1 | COM.mscal_Calendar( 2 1 )

    	s.com={s.com,s.fun;s.fun,s.com};

    	cprintf(s.com,...				% using the built-in other engine
    		'-mt',	1);

        |                         c:1                         c:2
    -------------------------------------------------------------
    r:1 | O(2:1x1:COM.mscal_Calendar)                 F(@(x)x+10)
    r:2 |                 F(@(x)x+10) O(2:1x1:COM.mscal_Calendar)

    	cprintf(s.com,...
    		'-mt',	1,...
    		'-O',	s.O);				% show class:size

    	delete(s.fh);

        |                       c:1                       c:2
    ---------------------------------------------------------
    r:1 | COM.mscal_Calendar( 1 1 )    function_handle( 1 1 )
    r:2 |    function_handle( 1 1 ) COM.mscal_Calendar( 1 1 )

    end

## output files

    % results can be written or appended to ASCII files
    % file templates can be used to insert results and replace token templates
    %    with user defined values
    %-------------------------------------------------------------------------------
    % -fa		append to output file			aname	[]
    % -fc		create output file			cname	[]
    %		precedence: [-fa] > [-fc]
    %
    % -fi		template file				tname	[]
    %		may contain markers as single line
    %		entries where the result is
    %		inserted
    %		for each run, only the FIRST marker
    %		is being used
    %		if no marker is found and the
    %		[-fa] option is used, the result is
    %		appended to the content of the template
    %		file before creating the output file
    % -fm		marker for the [-fi] option		marker	[]
    %		must be a 1xN character string
    % -fr		cell of token/value pairs		{t,v...}
    %		must be 1xN character strings
    %		all tokens are replaced with their
    %		values in a [-fi] template file
    %		before insertion of the result

    % NOTE:	output files contain the exact result including
    %	TAB characters
    %	markers and tokens are replaced using the
    %	regular expression engine
    %	therefor, if special characters are used,
    %	they must be marked as literal by \char
    %
    % the accompanying file CPTMPL.TXT is used for demonstration
    % a file CP_00X.00X is created during the demonstration and
    % removed afterwards

    	s.ftmpl='cptmpl.txt';
    	s.fout='cp_00X.00X';

    	type(s.ftmpl);

    a test FO for CPRINTF file routines
    FO   : cptmpl.txt
    created: <DATE>
    -----------------------------------
    % output $1
    $MARK$
    % output $2
    $MARK$

## --- creating output files

    % using a return argument prevents the result from being displayed after
    %    runtime
    % a print message is always printed to confirm the writing process

    	s.p=cprintf(s.m,...
    		'-mt',	1,...
    		'-fc',	s.fout);
    	type(s.fout);

    CP|   create  :        200 b cp_00X.00X

        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i

## --- appending to files

    	s.p=cprintf(s.r,...
    		'-mt',	1,...
    		'-fa',	s.fout,...
    		'-dt',	'|');
    	type(s.fout);
    	delete(s.fout);

    CP|   append  :        186 b cp_00X.00X

        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i
        | c:1|c:2|c:3|c:4|c:5|c:6
    -----------------------------
    r:1 |   1|  5|  9| 13| 17| 21
    r:2 |   2|  6| 10| 14| 18| 22
    r:3 |   3|  7| 11| 15| 19| 23
    r:4 |   4|  8| 12| 16| 20| 24

## --- using a template file

    	type(s.ftmpl);
    	s.p=cprintf(s.m,...
    		'-mt',	1,...
    		'-fc',	s.fout,...
    		'-fi',	s.ftmpl,...
    		'-fm',	'\$MARK\$');			% note liteal \$

    % NOTE:	only marker #1 is replaced

    	type(s.fout);

    a test FO for CPRINTF file routines
    FO   : cptmpl.txt
    created: <DATE>
    -----------------------------------
    % output $1
    $MARK$
    % output $2
    $MARK$
    CP| template  :              cptmpl.txt
    CP|   create  :        480 b cp_00X.00X

    a test FO for CPRINTF file routines
    FO   : cptmpl.txt
    created: <DATE>
    -----------------------------------
    % output $1
        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i
    % output $2
    $MARK$

    % to replace other markers, the newly created FOUT must be used

    	s.p=cprintf(s.r,...
    		'-mt',	1,...
    		'-dt',	'|',...
    		'-fc',	s.fout,...
    		'-fi',	s.fout,...
    		'-fm',	'\$MARK\$');
    	type(s.fout);
    	delete(s.fout);

    CP| template  :              cp_00X.00X
    CP|   create  :        680 b cp_00X.00X

    a test FO for CPRINTF file routines
    FO   : cptmpl.txt
    created: <DATE>
    -----------------------------------
    % output $1
        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i
    % output $2
        | c:1|c:2|c:3|c:4|c:5|c:6
    -----------------------------
    r:1 |   1|  5|  9| 13| 17| 21
    r:2 |   2|  6| 10| 14| 18| 22
    r:3 |   3|  7| 11| 15| 19| 23
    r:4 |   4|  8| 12| 16| 20| 24

## --- replacing tokens in template files

    	s.tok={
    		'FO',		'file'
    		'<DATE>',	datestr(clock)
    		'output \$',	'result #'
    	};
    	s.p=cprintf(s.r,...
    		'-mt',	1,...
    		'-dt',	'|',...
    		'-fc',	s.fout,...
    		'-fi',	s.ftmpl,...
    		'-fr',	s.tok,...
    		'-fm',	'\$MARK\$');
    	s.p=cprintf(s.m,...
    		'-mt',	1,...
    		'-dt',	'|',...
    		'-fa',	s.fout,...
    		'-fi',	s.fout,...
    		'-fr',	s.tok,...
    		'-fm',	'\$MARK\$');

    % NOTE:	no marker exists in S.FOUT during the second call
    %	the result is appended       with the [-fa] option
    %	whereas an error would occur with the [-fc] option

    	type(s.fout);
    	delete(s.fout);

    CP| template  :              cptmpl.txt
    CP|   create  :        507 b cp_00X.00X

    CP| template  :              cp_00X.00X
    CP|   create  :        680 b cp_00X.00X

    a test file for CPRINTF file routines
    file   : cptmpl.txt
    created: 11-Jun-2009 08:59:04
    -----------------------------------
    % result #1
        | c:1|c:2|c:3|c:4|c:5|c:6
    -----------------------------
    r:1 |   1|  5|  9| 13| 17| 21
    r:2 |   2|  6| 10| 14| 18| 22
    r:3 |   3|  7| 11| 15| 19| 23
    r:4 |   4|  8| 12| 16| 20| 24
    % result #2
        |        c:1|       c:2|       c:3
    --------------------------------------
    r:1 |    1      |   2      |   3   +3i
    r:2 |  NaN -4.2i| NaN      | Inf
    r:3 | -Inf      | NaN +Infi| Inf +5.5i

## option processing

## --- option precedence

    % options are resolved in this order of precedence from lowest to highest
    %
    %	1) getpref					low
    %	2) option file
    %	3) option structure
    %	4) command line					high
    %
    % NOTE:	if multiple options are set, the LAST values is used

## --- option preferences across MATLAB sessions

    % user may define preferred options, which are kept across MATLAB sessions, by
    %
    %	setpref('cprintf','opt',{'OPT1',VAL1,...,'OPTn',VALn});

    % setting [-mt] options by default

    	s.opref=getpref('cprintf');			% save old state
    	setpref('cprintf','opt',{'-mt',1});

    	cprintf(s.r);

        | c:1 c:2 c:3 c:4 c:5 c:6
    -----------------------------
    r:1 |   1   5   9  13  17  21
    r:2 |   2   6  10  14  18  22
    r:3 |   3   7  11  15  19  23
    r:4 |   4   8  12  16  20  24

    % modification of preferred options
    %-------------------------------------------------------------------------------
    % -p		do NOT use preferred options		[F]

    % NOTE:	[-p] requires NO value

    	cprintf(s.r,...
    		'-p',...				% do NOT use preferred options
    		'-d',	' | ');

     1 |  5 |  9 | 13 | 17 | 21
     2 |  6 | 10 | 14 | 18 | 22
     3 |  7 | 11 | 15 | 19 | 23
     4 |  8 | 12 | 16 | 20 | 24

    % in addition, any runtime option will override a preferred option

    	cprintf(s.r,...
    		'-mt',	0,...				% override preferred [-mt]
    		'-d',	' | ');

    if	~isempty(s.opref)
    	setpref('cprintf','opt',s.opref.opt);		% reset
    else
    	rmpref('cprintf');				% clean up
    end

     1 |  5 |  9 | 13 | 17 | 21
     2 |  6 | 10 | 14 | 18 | 22
     3 |  7 | 11 | 15 | 19 | 23
     4 |  8 | 12 | 16 | 20 | 24

## --- reading and writing option files

    % options can be retrieved from any user created ASCII file
    % there are two possible file formats:
    % 1)		user created files, which contain a sequence of option/value pairs
    %		as if typed on the command line
    %		if it is an m-file, the extension is not necessary, otherwise, it
    %		must be added to identify the file
    % 2)		files generated by CPRINTF, which contain a sequence of commands
    %		that create an option structure
    %		these files are m-files with a short help header,
    %		which may be used as stand-alones as well to
    %		retrieve the option structure
    %
    % read and create option files
    %-------------------------------------------------------------------------------
    % -ini		read options from file			iname	[]
    %		format: user created or CPRINTF
    % -sav		save options to   file			sname	[]
    %		which are created from a [-ini] file
    %		if this option is not used, a temporary
    %		ASCII file is created in the current
    %		folder and discarded immediately after
    %		loading
    %
    %		see also -macros- below for possibilities
    %		to read/create option files without running
    %		CPRINTF
    %
    % NOTE:	if the [-ini] option is used without
    %	the [-sav] option, a temporary files is
    %	created and removed right after options
    %	are read if the [-ini] and [-sav] use
    %	the same file name, a new copy of the
    %	file is saved without warning
    %	only command line options are saved

    % user created ASCII files
    % - option/values must be written as if typed at the command line, eg,
    %		'-mt',1,'-Lc',{1,2,'a'}
    % - the parsing/decoding of these files starts at the first occurrence of
    %   an option
    % - option names must be convertible to valid structure fieldnames
    % - values may contain any regular, valid ML expression and must be
    %   separated by at least one <,> from the option
    % - comments may be used according the ML's common rules
    % - white spaces, <;>, and multiple <,>s are discarded
    % - newlines are discarded

    % CPINI.TXT is an exemplary [-ini] file showing some syntax possibilities,
    % which typically are less disorganized and chaotic
    % - parsing starts at '-begin'
    % - note several ML type comments starting with a <%>
    % - non-CPRINTF options may be used; they are created but discarded at runtime
    % - any valid ML command in between option/value pairs will be created during
    %   runtime and results may be displayed in the command window if it is not
    %   suppressed by a <;>

    	s.fini='cpini.txt';
    	s.fout=sprintf('cpini_%s',num2hex(rand(1,2)));	% a unique file name
    							% extension not required

    	type(s.fini);

    CPINIT.TXT	a cprintf ini file example
    created:
    	us	10-Jan-2008 us@neurol.unizh.ch
    modified:
    	us	11-Jun-2009 08:58:55
    localid:	us@USZ|ws-nos-36362|x86|Windows XP|7.7.0.471.R2008b
    --------------------------------------------------------------------------------
    ,,	,	;
    note nonsense options FOO_xx
    decoding starts after FIRST occurrence of a typical option pair:
    '-begin','start of options'; % an option comment
    '-FOO_x1',{
    		1 2 3	% a cell comment
    		3 2 1
    	};
    % a line comment
    '-mt',1,'-nd',pi
    '-Lcs','=',
    '-Lr'	,	,	,  ,	  ,num2cell(--5:-10*-1);
    ,,,'-Lc'	,	{'X','Y'}.'
    '-FOO_x2',{{'abc',1,'12'},'foo',--12:--23}

    '-FOO_x3',rand(2,2,3)
    '-FOO_x4',,,,'-FOO_x5','-E',@(x) sprintf('%s',class(x));;'-t','+';,;,,;
    '-FOO_x6'={
    1 2 3
    3 2 1
    };'-FOO_x7',{1,2,3;4,5,6};,,'-FOO_x8','-',;;
    '-tab',10,,,'-f','-',,,,,
    '-FOO_x8','foo'	;	,;

    % load CPINI.TXT during runtime and save it as a CPRINTF option file

    % NOTE:	correct formatting of table elements according to options

    	cprintf(bitand(s.r,1)~=0,...
    		'-mt',	1,...
    		'-ini',	s.fini,...
    		'-sav',	s.fout);

    CP| file      :              F:\usr\matlab\tmp\fex\acprint\cpini.txt
    CP| create    :              cpini_33ffee8977f214d71100324575201d4a
    CP| options   :         18   unique/user defined

        | X Y X Y X Y
    =================
    r:5 | + + + + + +
    r:6 | - - - - - -
    r:7 | + + + + + +
    r:8 | - - - - - -

    % output and standalone use of CPRINTF created m-file

    % NOTE:	correct formatting of multiline commands
    %	positioning of comments
    %	the option structure contains all option/value pairs

    	disp('***** FILE CONTENT');
    	type(s.fout);

    ***** FILE CONTENT

    %CPRINTF	option file cpini_33ffee8977f214d71100324575201d4a.m
    %version	11-Jun-2009 08:58:55
    %created	11-Jun-2009 08:59:04
    %options	18 unique/user defined
    %
    %SYNTAX		opt = cpini_33ffee8977f214d71100324575201d4a.m;
    %--------------------------------------------------------------------
    function	o = cpini_33ffee8977f214d71100324575201d4a(varargin)

    %%%	section ----------- CPRINTF ---------- user data
    	o. magic = 'CPRINTF';
    	o.   ver = '11-Jun-2009 08:58:55';
    	o. MLver = '7.8.0.347 (R2009a)';
    	o. begin = 'start of options';% an option comment;
    	o.FOO_x1 = {
    		1 2 3	% a cell comment
    		3 2 1
    	};% a line comment;
    	o.    mt = 1;
    	o.    nd = pi;
    	o.   Lcs = '=';
    	o.    Lr = num2cell(--5:-10*-1);
    	o.    Lc = {'X','Y'}.';
    	o.FOO_x2 = {{'abc',1,'12'},'foo',--12:--23};
    	o.FOO_x3 = rand(2,2,3);
    	o.FOO_x4 = [];
    	o.FOO_x5 = [];
    	o.     E = @(x) sprintf('%s',class(x));
    	o.     t = '+';
    	o.FOO_x6 = {
    1 2 3
    3 2 1
    };
    	o.FOO_x7 = {1,2,3;4,5,6};
    	o.FOO_x8 = '-';
    	o.   tab = 10;
    	o.     f = '-';
    	o.FOO_x8 = 'foo';
    %%%	section ----------- CPRINTF ---------- user data
    end

    	disp('***** HELP SECTION');
    	help(s.fout);

    ***** HELP SECTION
     CPRINTF	option file cpini_33ffee8977f214d71100324575201d4a.m
     version	11-Jun-2009 08:58:55
     created	11-Jun-2009 08:59:04
     options	18 unique/user defined

     SYNTAX		opt = cpini_33ffee8977f214d71100324575201d4a.m;
     --------------------------------------------------------------------

    	disp('***** OPTION STRUCTURE');
    	s.val=feval(s.fout);				% typically: s.val=foo;
    	disp(s.val);

    ***** OPTION STRUCTURE
         magic: 'CPRINTF'
           ver: '11-Jun-2009 08:58:55'
         MLver: '7.8.0.347 (R2009a)'
         begin: 'start of options'
        FOO_x1: {2x3 cell}
            mt: 1
            nd: 3.1416
           Lcs: '='
            Lr: {[5]  [6]  [7]  [8]  [9]  [10]}
            Lc: {2x1 cell}
        FOO_x2: {{1x3 cell}  'foo'  [12 13 14 15 16 17 18 19 20 21 22 23]}
        FOO_x3: [2x2x3 double]
        FOO_x4: []
        FOO_x5: []
             E: @(x)sprintf('%s',class(x))
             t: '+'
        FOO_x6: {2x3 cell}
        FOO_x7: {2x3 cell}
        FOO_x8: 'foo'
           tab: 10
             f: '-'

## --- option structures

    % a predefined option structure may be used to easily enter options
    %-------------------------------------------------------------------------------
    % -opt		an option structure			os	[]

    % NOTE:	an option structure consists of
    %
    %		s.option = value
    %
    %	where option is a valid CPRINTF option
    %	without the [-] and a valid value
    %	unused options are discarded
    %	CPRINTF created [-ini] files produce option structures

    	s.sopt.a='a';					% currently not an option
    	s.sopt.Lc={1,'XYZ',2};
    	s.sopt.Lcs='=';
    	s.sopt.Lr=s.rlab;

    	cprintf(s.r,...
    		'-mt',	1,...
    		'-opt',	s.sopt);

           | c:1 XYZ c:2 c:1 XYZ c:2
    ================================
     sweet |   1   5   9  13  17  21
      sour |   2   6  10  14  18  22
     salty |   3   7  11  15  19  23
    bitter |   4   8  12  16  20  24

    % using a CPRINTF created ini file, which returns an option structure

    	cprintf(s.r>12,...
    		'-mt',	1,...
    		'-opt',	feval(s.fout));			% typically: '-opt','foo'

    	delete([s.fout,'.m']);				% to clean up we need the extension

        | X Y X Y X Y
    =================
    r:5 | - - - + + +
    r:6 | - - - + + +
    r:7 | - - - + + +
    r:8 | - - - + + +

## engine options

## --- TAB size and TAB replacement in CELLs

    % conversion of TAB [\t] characters to SPACES for format specs
    %    OTHER than the CELL separator [-d]
    %-------------------------------------------------------------------------------
    % -tab		number of SPACES/TAB			n	[8]
    % -ntab		do NOT replace TABs in CELLs		T|F	[F]

    % compare with output above

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-Ct',	'{%s\t}',...
    		'-tab',	2);

        |            c:1            c:2            c:3
    --------------------------------------------------
    r:1 | {   1        } {   2        } {   3   +3i  }
    r:2 | { NaN -4.2i  } { NaN        } { Inf        }
    r:3 | {-Inf        } { NaN +Infi  } { Inf +5.5i  }

    % NOTE:	replacement of CELL TABS with TAB size SPACES in the output

    	s.stab={sprintf('a\t\t\ttab'),sprintf('b\t\ttab'),'c d';100,200,300};
    	cprintf(s.stab,...
    		'-mt',	1);

        |                          c:1                          c:2                          c:3
    --------------------------------------------------------------------------------------------
    r:1 | a                        tab         b                tab                          c d
    r:2 |                          100                          200                          300

    % NOTE:	with the [-ntab] option, table colums have an additional length
    %	of one char <\t> per TAB and the TABs are kept in the output
    %	this may be required in other applications

    	s.res=cprintf(s.stab,...
    		'-mt',	1,...
    		'-ntab',1);

    	s.rres=strrep(cellstr(s.res),sprintf('\t'),'.');
    	disp(sprintf('\noriginal output\n'));
    	disp(s.res);
    	disp(sprintf('\noriginal output with later TAB replacements\n'));
    	disp(char(s.rres));

    original output

        |     c:1     c:2     c:3
    -----------------------------
    r:1 | a			tab  b		tab     c d
    r:2 |     100     200     300

    original output with later TAB replacements

        |     c:1     c:2     c:3
    -----------------------------
    r:1 | a...tab  b..tab     c d
    r:2 |     100     200     300

## --- runtime printout

    % runtime processing and timing of conversion stages can be print out
    %-------------------------------------------------------------------------------
    % -db		show processing of conversions		T|F	[F]
    % -q		quiet mode				T|F	[F]
    %		except for [-db] output ALL
    %		runtime processing for
    %		[-fc]/[-fa]/[-ini] options
    %		as well as the display of the result
    %		is suppressed even if the command
    %		does NOT end with a <;>

    	cprintf(s.m,...
    		'-mt',	1,...
    		'-db',	1);

    % explanation of runtime output
    %-------------------------------------------------------------------------------
    % - numeric col 1:	 # of cells remaining
    %			-# of cells converted
    %			if the array contains complex numbers, the -# will
    %			   be larger than the #
    % - numeric col 2:	time [sec] used to convert

    % NOTE:	after formatting, 0 c should be left to convert

    CP| --------- :
    CP| format    :                     9 c
    CP| type      :      empty =        9 c
    CP| type      :      empty = -      0 c 0.000000 sec
    CP| type      :    logical =        9 c
    CP| type      :    logical = -      0 c 0.000000 sec
    CP| type      :    numeric =        9 c
    CP| type      :    numeric = -     13 c 0.000000 sec
    CP| format    :       done =        0 c 0.000000 sec
    CP| print     :                    25 c
    CP| print     :       done =            0.000000 sec
    CP| --------- :       done =            0.000000 sec
    ----------------------------------------------------
        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i

## output

## --- macros

    % several macros (function handles) are available if the engine structure
    %    is retrieved, which may be helpful to prepare and/or organize often
    %    used options
    % if no output argument is selected, macros do NOT return the default
    %    ANS
    %-------------------------------------------------------------------------------
    % .getpar	to create an option structure from
    %		command line parameters
    % .setpar	to create a CPRINTF options only
    %		option structure from a user defined
    %		option structure
    % .ini		to read/create ini files
    % .write	to write an output file
    % .other	to test the [-O] display engine, which
    %		must produce an output for any data
    %		type and array size
    % .comb		to create a page index sequence

    % macros can be retrieved by a simple call to CPRINTF without arguments,
    %    returns a structure with the engine parameters; see also -arguments-

    	s.mac=cprintf;

    % GETPAR	OS = P.getpar(OPT1,VAL1,...,OPTn,VALn)

    % NOTE:	options currently not used by CPRINTF are discarded
    %	values, which would not be active during runtime
    %	are discarded as well, eg, [-nd]

    	s.opt=s.mac.getpar('-foo','goo','-Lc',{'a',1,'b'},'-mt',0,'-nd',[]);
    	disp(s.opt);

        Lc: {'a'  [1]  'b'}
        mt: 0

    % SETPAR	OS = P.setpar(OS)

    % NOTE:	same as GETPAR
    %	the input may be a CPRINTF created [-sav] file

    %	s.opt=s.mac.setpar('CPRINTF_savfile');
    	s.opt=s.mac.setpar(s.val);				% [-ini] created option structure
    	disp(s.opt);

          E: @(x)sprintf('%s',class(x))
         Lc: {2x1 cell}
        Lcs: '='
         Lr: {[5]  [6]  [7]  [8]  [9]  [10]}
          f: '-'
         mt: 1
         nd: 3.1416
          t: '+'
        tab: 10

    % INI		OS = P.ini(INIFILE,[SAVFILE],['-q',1,...,OPTn,VALn]);

    % NOTE:	see section -option files- for rules regarding the creation of output files
    %	to add options, SAVFILE must be set
    %	to create a temporary file, SAVFILE can be set to ''

    	s.opt=s.mac.ini(s.fini);
    	disp(s.opt);

    CP| file      :              F:\usr\matlab\tmp\fex\acprint\cpini.txt
    CP| create    :              temporary file removed
    CP| options   :         18   unique/user defined

         magic: 'CPRINTF'
           ver: '11-Jun-2009 08:58:55'
         MLver: '7.8.0.347 (R2009a)'
         begin: 'start of options'
        FOO_x1: {2x3 cell}
            mt: 1
            nd: 3.1416
           Lcs: '='
            Lr: {[5]  [6]  [7]  [8]  [9]  [10]}
            Lc: {2x1 cell}
        FOO_x2: {{1x3 cell}  'foo'  [12 13 14 15 16 17 18 19 20 21 22 23]}
        FOO_x3: [2x2x3 double]
        FOO_x4: []
        FOO_x5: []
             E: @(x)sprintf('%s',class(x))
             t: '+'
        FOO_x6: {2x3 cell}
        FOO_x7: {2x3 cell}
        FOO_x8: 'foo'
           tab: 10
             f: '-'

    % WRITE		[ARG,...] = P.write(A,OPT1,VAL1,...,OPTn,VALn)

    % NOTE:	mimicks the command
    %
    %		[arg,...] = cprintf(A,WOPT,WVAL,OPT1,VAL1,...,OPTn,VALn)
    %
    %	one of the WOPTs must be a [-fc]/[-fa] file creation command
    %	the [-q] silent processing flag is turned on [T] by default
    %	the [-mt] table option is turned off [F] by default and
    %	must be set if this feature is required

    	s.fwrite='CP_00X.00X';
    	s.mac.write(s.r,'-fc',s.fwrite);
    	type(s.fwrite);
    	delete(s.fwrite);				% clean up

     1  5  9 13 17 21
     2  6 10 14 18 22
     3  7 11 15 19 23
     4  8 12 16 20 24

    % OTHER		OVAL = P.other(O1,...,On)

    	s.oval={pi,magic(3)+1i,cell(2,2),sparse(2,2,3+1i),@(x) x+10};
    	s.oval=s.mac.other(s.oval{:});
    	disp(s.oval);

        'N(2:1x1:double)'
        'N(2:3x3:double.c)'
        'C(2:2x2)'
        'N(2:2x2:double.s.c)'
        'F(@(x)x+10)'

    % COMB		PIX = P.comb(ARRAYSIZE)

    	s.pix=s.mac.comb(size(rand([2,2,1,2])));
    	disp(s.pix);

         1     1     1     1
         2     1     1     1
         1     2     1     1
         2     2     1     1
         1     1     1     2
         2     1     1     2
         1     2     1     2
         2     2     1     2

## --- arguments

    % the engine structure is returned by a call to CPRINTF without input arguments
    % this may be useful to access several CPRINTF functions
    %
    	s.p=cprintf;

    %	s.p.other()	check other display output

    % several outputs are available to import the result into other programs,
    %    in particular, spreadsheets, which take cell input, eg,
    %    XLSWRITE (see OUTPUT section)
    % all output can be collected into a single structure
    %-------------------------------------------------------------------------------
    % -so		collect output				T|F	[F]

    % NOTE:	the result is NOT displayed during runtime because of
    %	1) output arguments and 2) the semicolon at the end

    	[s.rs,s.rc,s.mc,s.par]=cprintf(s.m,...
    		'-mt',	1);

    % the result

    	disp(s.rs);

        |        c:1        c:2        c:3
    --------------------------------------
    r:1 |    1          2          3   +3i
    r:2 |  NaN -4.2i  NaN        Inf
    r:3 | -Inf        NaN +Infi  Inf +5.5i

    % the output prior to conversion

    	disp(s.mc);

        [                1]    [          2]    [  3 +          3i]
        [NaN -        4.2i]    [        NaN]    [              Inf]
        [             -Inf]    [NaN +  Infi]    [Inf +        5.5i]

    % the output in a cell array with formatted CELLs

    	disp(s.rc);

        ' '      '|'    'c:1'           'c:2'           'c:3'
        '-'      '-'    '-'             '-'             '-'
        'r:1'    '|'    '   1      '    '   2      '    '   3   +3i'
        'r:2'    '|'    ' NaN -4.2i'    ' NaN      '    ' Inf      '
        'r:3'    '|'    '-Inf      '    ' NaN +Infi'    ' Inf +5.5i'

    % all output collected in a structure

    	s.p=cprintf(s.m,...
    		'-mt',	1,...
    		'-so',	1);

    % show engine parameters, input, and output

    	disp(s.p);

             magic: 'CPRINTF'
               ver: '11-Jun-2009 08:58:55'
             MLver: '7.8.0.347 (R2009a)'
        section_10: '---------- INPUT   ------------'
               arg: [3x3 double]
             class: 'double'
         isnumeric: 1
        section_20: '---------- OPTIONS ------------'
              otbl: {53x2 cell}
           hasotbl: [53x1 logical]
               opt: [1x1 struct]
            hasopt: [1x1 struct]
             islog: {17x1 cell}
        section_30: '---------- ENGINE  ------------'
              fpar: {6x6 cell}
              ctbl: {5x5 cell}
               ndc: 2
               nsc: [3 3]
               nnc: 9
                pr: 5
                pc: 5
                in: [25x1 logical]
             sconv: 13
              type: [1x1 struct]
             istbl: 1
            hastbl: [2 2]
            tlabel: [-1 -2 -1 -2]
             tbody: [3 5 3 5]
              sepr: {3x1 cell}
              sepc: {'-'  '-'  '-'  '-'  '-'}
               fmt: '%3.3s %1.1s %10.10s %10.10s %10.10s'
              fmts: [3 1 10 10 10]
              dels: 1
             delst: 1
              tabc: '	'
              tabs: '        '
              nmod: 1
        section_31: '---------- macros   -----------'
            getpar: @(varargin)CPRINTF_parse_option(0,varargin{:})
            setpar: @(varargin)CPRINTF_struct2opt(0,varargin{:})
               ini: @(varargin)CPRINTF_ini2opt(0,varargin{:})
             write: @(varargin)CPRINTF_ascii2file(varargin{:})
             other: @CPRINTF_other
              comb: @(varargin)CPRINTF_comb([varargin{:}])
              disp: @CPRINTF_nodisp
               s2f: @str2func
        section_40: '---------- OUTPUT  ------------'
              text: [5x38 char]
              cell: {5x5 cell}
              carg: {3x3 cell}

    % same as RC above

    	disp(s.p.cell);

        ' '      '|'    'c:1'           'c:2'           'c:3'
        '-'      '-'    '-'             '-'             '-'
        'r:1'    '|'    '   1      '    '   2      '    '   3   +3i'
        'r:2'    '|'    ' NaN -4.2i'    ' NaN      '    ' Inf      '
        'r:3'    '|'    '-Inf      '    ' NaN +Infi'    ' Inf +5.5i'

## --- input to xlswrite

    % use RC as input to xlswrite
    %{
    	s.rc=strtrim(s.rc);	% if leading/trailing spaces need to be removed
    	s.fnam='foo.xls';
    	xlswrite(s.fnam,s.rc);
    	winopen(s.fnam);
    %}