KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PrintTable.m
Go to the documentation of this file.
1 
2 
3 /* (Autoinserted by mtoc++)
4  * This source code has been filtered by the mtoc++ executable,
5  * which generates code that can be processed by the doxygen documentation tool.
6  *
7  * On the other hand, it can neither be interpreted by MATLAB, nor can it be compiled with a C++ compiler.
8  * Except for the comments, the function bodies of your M-file functions are untouched.
9  * Consequently, the FILTER_SOURCE_FILES doxygen switch (default in our Doxyfile.template) will produce
10  * attached source files that are highly readable by humans.
11  *
12  * Additionally, links in the doxygen generated documentation to the source code of functions and class members refer to
13  * the correct locations in the source code browser.
14  * However, the line numbers most likely do not correspond to the line numbers in the original MATLAB source files.
15  */
16 
18  :public handle {
242  public:
243 
244  integer TabCharLen = PrintTable.getDefaultTabCharLen;
256  char ColSep = " | ";
303  .enum Format = "txt";
316  char Caption = "";
355  public: /* ( Dependent ) */
356 
386  public:
387 
440  private:
441 
442  fTexMMode = true;
443 
444 
445  public:
446 
447  PrintTable(char caption,cell varargin) {
448  this.clear;
449  if nargin > 0
450  if ~isempty(varargin)
451  this.Caption= sprintf(caption,varargin[:]);
452  else
453  this.Caption= caption;
454  end
455  end
456  }
468  function display() {
469  for i = 1:length(this)
470  this(i).print(1);
471  end
472  }
481  function print(integer outfile) {
482  if nargin == 1
483  outfile = 1;
484  end
485  for i = 1:length(this)
486  t = this(i);
487  if strcmp(t.Format," txt ")
488  t.printPlain(outfile);
489  elseif any(strcmp(t.Format,[" tex "," pdf "]))
490  t.printTex(outfile);
491  else
492  error(" Unsupported format: %s ",t.Format);
493  end
494  end
495  }
507  function charstr = toString() {
508  f = fopen(" tmpout "," w+ ");
509  this.print(f);
510  fclose(f);
511  str = fileread(" tmpout ");
512  delete(" tmpout ");
513  }
522  function saveToFile(char filename,logical openfile) {
523 
524  /* Case 1: No file name given */
525  if nargin < 2 || isempty(filename)
526  initdir = getpref(" PrintTable "," LastDir ",pwd);
527  choices = [" *.txt ", " Text files (*.txt) ";...
528  " *.tex ", " LaTeX files (*.tex) ";...
529  " *.pdf ", " PDF files (*.pdf) "];
530  [fname, path, extidx] = uiputfile(choices, ...
531  sprintf(" Save table '%s' as ",this.Caption), initdir);
532  /* Abort if no file was selected */
533  if fname == 0
534  return;
535  end
536  setpref(" PrintTable "," LastDir ",path);
537  ext = choices[extidx,1](2:end);
538  filename = fullfile(path, fname);
539  /* Take off the extension of the fname (automatically added
540  * by uiputfile) */
541  fname = fname(1:end-4);
542  /* Case 2: File name given. Determine format by file
543  * extension */
544  else
545  [path, fname, ext] = fileparts(filename);
546  if isempty(ext)
547  ext = [" . " this.Format];
548  elseif ~any(strcmp(ext,[" .txt "," .tex "," .pdf "]))
549  error(" Valid file formats are *.txt, *.tex, *.pdf ");
550  end
551  if isempty(path)
552  path = " . ";
553  end
554  /* Try to create directory if not existing */
555  if ~isempty(path) && exist(path," dir ") ~= 7
556  mkdir(path);
557  end
558  end
559  if nargin < 3
560  openfile = false;
561  end
562 
563  oldfmt = this.Format; /* store old format */
564 
565  this.Format= ext(2:end);
566  /* PDF export */
567  if strcmp(ext," .pdf ")
568  this.pdfExport(path, fname);
569  /* Text export in either plain or LaTeX format */
570  else
571  fid = fopen(filename," w ");
572  this.print(fid);
573  fclose(fid);
574  end
575  this.Format= oldfmt; /* restore old format */
576 
577  if openfile
578  open(filename);
579  end
580  }
603  function addMatrix(titles,data,varargin) {
604  for k=1:size(data,1)
605  hlp = num2cell(data(k,:));
606  this.addRow(titles[k],hlp[:],varargin[:]);
607  end
608  }
609 
610 
611  function addRow(varargin) {
612  if isempty(varargin)
613  error(" Not enough input arguments. ");
614  end
615  hasformat = iscell(varargin[end]);
616  if iscell(varargin[1])
617  error(" Invalid input argument. Cells cannot be added to the PrintTable, and if you wanted to specify a sprintf format you forgot the actual value to add. ");
618 /* elseif hasformat && length(varargin)-1 ~= length(varargin{end})
619  * error('Input argument mismatch. If you specify a format string cell the number of arguments (=%d) to add must equal the number of format strings (=%d).',length(varargin)-1,length(varargin{end})); */
620  end
621  if isempty(this.data)
622  [this.data[1], this.mathmode] = this.stringify(varargin);
623  this.contlen= ones(1,length(this.data[1]));
624  else
625  /* Check new number of columns */
626  newlen = length(varargin);
627  if hasformat
628  newlen = newlen-1;
629  end
630  if length(this.data[1]) ~= newlen
631  error(" Inconsistent row length. Current length: %d, passed: %d ",length(this.data[1]),newlen);
632  end
633  /* Add all values */
634  [this.data[end+1], this.mathmode(end+1,:)] = this.stringify(varargin);
635  end
636  /* Record content length while building the table */
637  this.updateContentLengthAt(length(this.data));
638  /* Check if a latex command might be contained
639  * (so far no re-computation is done on row removal) */
640  texcmdfun = @(s)~isempty([strfind(s," \ ") strfind(s," _ ") strfind(s," ^ ")]);
641  this.haslatexcommand= this.haslatexcommand ...
642  || any(cellfun(texcmdfun,this.data[end]));
643  }
654  function clear() {
655  this.data= [];
656  this.contlen= [];
657  this.Caption= ;
658  }
665  function removeRow(integer idx) {
666  if idx < 1 || idx > length(this.data)
667  error(" Invalid row index: %d ",idx);
668  end
669  this.data(idx) = [];
670  this.updateContentLengths;
671  }
680  function this = sort(integer colnr,char direction) {
681  if nargin < 3
682  direction = " ascend ";
683  if nargin < 2
684  if this.HasHeader
685  colnr = 2;
686  else
687  colnr = 1;
688  end
689  end
690  end
691 
692  if isempty(this.data)
693  return;
694  elseif colnr < 1 || colnr > length(this.data[1])
695  error(" Please specify a valid column number ");
696  end
697 
698  vals = [];
699  for k = 1:length(this.data)
700  vals[k] = this.data[k][colnr];/* #ok */
701 
702  end
703  [~, sidx] = sort(vals);
704  /* "Manually" choose direction */
705  if strcmpi(direction," descend ")
706  sidx = fliplr(sidx);
707  end
708  copy = this.data;
709  copym = this.mathmode;
710  for k = 1:length(this.data)
711  copy[k] = this.data[sidx(k)];
712  copym(k,:) = this.mathmode(sidx(k),:);
713  end
714  this.data= copy;
715  this.mathmode= copym;
716  }
740  function transposed = ctranspose() {
741  transposed = this.clone;
742  hlp = reshape([this.data[:]],length(this.data[1]),[]);
743  transposed.data= [];
744  for k=1:size(hlp,1)
745  transposed.data[k] = hlp(k,:);
746  end
747  transposed.contlen= cellfun(@(row)max(cellfun(@(el)length(el),row)),...
748  this.data);
749  /* Trigger correct content length guessing if need be */
750  transposed.TexMathModeDetection= this.fTexMMode;
751  transposed.mathmode= this.mathmode^t;
752  }
753 
754 
755  function copy = clone() {
756  copy = PrintTable(this.Caption);
757  copy.ColSep= this.ColSep;
758  copy.HasHeader= this.HasHeader;
759  copy.HasRowHeader= this.HasRowHeader;
760  copy.Format= this.Format;
761  copy.TightPDF= this.TightPDF;
762  copy.data= this.data;
763  copy.contlen= this.contlen;
764  copy.mathmode= this.mathmode;
765  copy.fTexMMode= this.fTexMMode;
766  copy.haslatexcommand= this.haslatexcommand;
767  copy.StripInsertedTabChars= this.StripInsertedTabChars;
768  }
778  function joined = append(PrintTable table,rowvec<integer> columns) {
779  if isempty(this.data)
780  error(" No table rows exists to append to. Why would you want to do that? ");
781  end
782 
783  joined = this.clone;
784  /* Check data compatibility */
785  if ~isa(table," PrintTable ")
786  error(" Argument must be a PrintTable instance ");
787  end
788  if table.NumRows == 0
789  return;
790  end
791  if nargin < 3
792  columns = 1:length(table.data[1]);
793  end
794  if length(this.data[1]) ~= length(columns)
795  error(" Invalid column number: Have %d but want to append %d ",length(this.data[1]),length(columns));
796  end
797  /* Augment data */
798  start = 1;
799  if table.HasHeader
800  start = 2;
801  end
802  for k=start:length(table.data)
803  joined.data[end+1] = table.data[k](columns);
804  end
805  joined.contlen= max(this.contlen,table.contlen(columns));
806  joined.mathmode= [this.mathmode; table.mathmode(:,columns)];
807  joined.haslatexcommand= this.haslatexcommand || table.haslatexcommand;
808  /* Transfer Caption if not set locally */
809  if ~isempty(joined.Caption)
810  joined.Caption= table.Caption;
811  end
812  }
828 #if 0 //mtoc++: 'set.ColSep'
829 function ColSep(value) {
830  if ~isempty(value) && ~isa(value," char ")
831  error(" ColSep must be a char array. ");
832  end
833  this.ColSep= value;
834  }
835 
836 #endif
837 
838 
839  /* % Getter & Setter */
840  public:
841 
842 
843 #if 0 //mtoc++: 'set.HasHeader'
844 function HasHeader(value) {
845  if ~islogical(value) || ~isscalar(value)
846  error(" HasHeader must be a logical scalar. ");
847  end
848  this.HasHeader= value;
849  }
850 
851 #endif
852 
853 
854 
855 #if 0 //mtoc++: 'set.HasRowHeader'
856 function HasRowHeader(value) {
857  if ~islogical(value) || ~isscalar(value)
858  error(" HasRowHeader must be a logical scalar. ");
859  end
860  this.HasRowHeader= value;
861  }
862 
863 #endif
864 
865 
866 
867 #if 0 //mtoc++: 'set.Caption'
868 function Caption(value) {
869  if ~isempty(value) && ~ischar(value)
870  error(" Caption must be a character array. ");
871  end
872  this.Caption= value;
873  }
874 
875 #endif
876 
877 
878 
879 #if 0 //mtoc++: 'set.Format'
880 function Format(value) {
881  if ~any(strcmp([" txt "," tex "," pdf "],value))
882  error(" Format must be either "" txt "" or "" tex "" . ");
883  end
884  this.Format= value;
885  end
886 
887  function set.TabCharLen(this, value)
888  if isscalar(value) && value > 0 && round(value) == value
889  this.TabCharLen= value;
890  else
891  error(" Invalid argument for TabCharLen. Must be a positive integer scalar. ");
892  end
893  end
894 
895  function value = get.NumRows(this)
896  value = length(this.data);
897  if this.HasHeader
898  value = max(0,value-1);
899  end
900  }
901 
902 #endif
903 
911 #if 0 //mtoc++: 'set.TexMathModeDetection'
912 function TexMathModeDetection(value) {
913  if this.fTexMMode ~= value
914  if ~islogical(value) || ~isscalar(value)
915  error(" TexMathModeDetection must be true or false. ");
916  end
917  this.fTexMMode= value;
918  this.updateContentLengths;
919  end
920  }
921 
922 #endif
923 
924 
925 
926 #if 0 //mtoc++: 'get.TexMathModeDetection'
927 function value = TexMathModeDetection() {
928  value = this.fTexMMode;
929  }
930 
931 #endif
932 
933 
934  /* % Internal helpers */
935  private:
936 
937 
938  function updateContentLengthAt(idx) {
939  fun = @(str,num)length(str) + 2*num; /* 2 characters for local $ tex environment */
940 
941  ismm = num2cell(this.mathmode(idx,:));
942  this.contlen= max([this.contlen; cellfun(fun,this.data[idx],ismm)]);
943  }
944 
945 
946  function updateContentLengths() {
947  if ~isempty(this.data)
948  this.contlen= ones(1,length(this.data[1]));
949  for idx = 1:length(this.data)
950  this.updateContentLengthAt(idx);
951  end
952  end
953  }
954 
955 
956  function printPlain(outfile) {
957  if ~isempty(this.Caption)
958  fprintf(outfile," Table "" %s "" :\n ",this.Caption);
959  end
960  for ridx = 1:length(this.data)
961  this.printRow(ridx,outfile,this.ColSep);
962  fprintf(outfile," \n ");
963  if ridx == 1 && this.HasHeader
964  /* Compute number of tabs */
965  ttabs = 0;
966  for i = 1:length(this.data[ridx])
967  ttabs = ttabs + ceil((length(this.ColSep)*(i~=1)+this.contlen(i))/this.TabCharLen);
968  end
969  fprintf(outfile," %s\n ",repmat(" _ ",1,(ttabs+1)*this.TabCharLen));
970  end
971  end
972  }
980  function printTex(outfile) {
981 
982  if ~this.TexMathModeDetection && this.haslatexcommand
983  warning(" PrintTable:TexExport ",...
984  " No TexMathModeDetection enabled but LaTeX commands have been detected. Export might produce invalid LaTeX code. ");
985  end
986 
987  /* Add verbose comment */
988  if ~isempty(this.Caption)
989  fprintf(outfile," %% PrintTable '%s' generated on %s\n ",this.Caption,datestr(clock));
990  else
991  fprintf(outfile," %% PrintTable generated on %s\n ",datestr(clock));
992  end
993  d = dbstack;
994  d = d(find(~strcmp([d(:).file]," PrintTable.m "),1));
995  if ~isempty(d)
996  fprintf(outfile," %% Created in %s:%d at %s\n ",d.name,d.line,which(d.file));
997  end
998  /* Add an informative comment to make the user aware of it's options :-) */
999  fprintf(outfile," %% Export settings: TexMathModeDetection %d, HasHeader %d, HasRowHeader %d, StripInsertedTabChars %d, IsPDF %d, TightPDF %d\n ",...
1001  strcmp(this.Format," pdf "),this.TightPDF);
1002  cols = 0;
1003  if ~isempty(this.data)
1004  cols = length(this.data[1]);
1005  end
1006  /* Only add surroundings for pure tex output or full-sized PDF
1007  * generation */
1008  if strcmp(this.Format," tex ") || ~this.TightPDF
1009  fprintf(outfile," \\begin{table}[!hb]\n\t\\centering\n\t\\def\\arraystretch{1.3}\n\t ");
1010  elseif ~isempty(this.Caption)
1011  /* Enable this if you want, but i found no straight way of putting the caption
1012  * above the table (for the given time&resources :-))
1013  *fprintf(outfile,'Table: %s\n',this.Caption); */
1014  end
1015  if this.HasRowHeader
1016  aligns = [" r " repmat(" l ",1,cols-1)];
1017  else
1018  aligns = repmat(" l ",1,cols);
1019  end
1020  fprintf(outfile," \\begin{tabular}{%s}\n ",aligns);
1021  /* Print all rows */
1022  for ridx = 1:length(this.data)
1023  fprintf(outfile," \t\t ");
1024  this.printRow(ridx,outfile," & ");
1025  fprintf(outfile," \\\\\n ");
1026  if ridx == 1 && this.HasHeader
1027  fprintf(outfile," \t\t\\hline\\\\\n ");
1028  end
1029  end
1030  fprintf(outfile, " \t\\end{tabular}\n ");
1031  /* Only add surroundings for pure tex output or full-sized PDF
1032  * generation */
1033  if strcmp(this.Format," tex ") || ~this.TightPDF
1034  if ~isempty(this.Caption)
1035  fprintf(outfile," \t\\caption{%s}\n ",this.Caption);
1036  end
1037  fprintf(outfile, " \\end{table}\n ");
1038  end
1039  }
1047  function pdfExport(path,fname) {
1048  [status, msg] = system(" pdflatex --version ");
1049  if status ~= 0
1050  error(" pdfLaTeX not found or not working:\n%s ",msg);
1051  else
1052  cap = " table ";
1053  if ~isempty(this.Caption)
1054  cap = [ this.Caption ];
1055  end
1056  fprintf(" Exporting %s to PDF using '%s'...\n ",cap,msg(1:strfind(msg,sprintf(" \n "))-1));
1057  end
1058 
1059  texfile = fullfile(path, [fname " .tex "]);
1060  fid = fopen(texfile," w ");
1061  fprintf(fid," \\documentclass{article}\n\\begin{document}\n ");
1062  if this.TightPDF
1063  fprintf(fid," \\newsavebox{\\tablebox}\n\\begin{lrbox}{\\tablebox}\n ");
1064  else
1065  fprintf(fid, " \\thispagestyle{empty}\n ");
1066  end
1067  /* Print actual tex table */
1068  this.print(fid);
1069  if this.TightPDF
1070  fprintf(fid, [" \\end{lrbox}\n\\pdfhorigin=0pt\\pdfvorigin=0pt\n "...
1071  " \\pdfpagewidth=\\wd\\tablebox\\pdfpageheight=\\ht\\tablebox\n "...
1072  " \\advance\\pdfpageheight by \\dp\\tablebox\n "...
1073  " \\shipout\\box\\tablebox\n "]);
1074  end
1075  fprintf(fid," \\end{document} ");
1076  fclose(fid);
1077  [status, msg] = system(sprintf(" pdflatex -interaction=nonstopmode -output-directory='%s' %s ",path,texfile));/* #ok */
1078 
1079  if 0 ~= status
1080  delete(fullfile(path, [fname " .pdf "]));
1081  fprintf(2," PDF export failed, pdflatex finished with errors. See the <a href='matlab:edit( "" %s "" )'>LaTeX logfile</a> for details.\n ",fullfile(path, [fname " .log "]));
1082  else
1083  delete(fullfile(path, [fname " .log "]));
1084  fprintf(" done!\n ");
1085  end
1086  delete(texfile,fullfile(path, [fname " .aux "]));
1087  }
1088 
1089 
1090  function printRow(rowidx,outfile,sep) {
1091  row = this.data[rowidx];
1092  /* Check if mathmode has been determined */
1093  if ~isempty(this.mathmode)
1094  ismm = this.mathmode(rowidx,:);
1095  else
1096  ismm = false(size(row));
1097  end
1098  /* Check if we are producing tex-based output */
1099  istex = any(strcmp(this.Format,[" tex ", " pdf "]));
1100  sl = length(sep);
1101  for i = 1:length(row)-1
1102  str = row[i];
1103  if istex && this.fTexMMode && ismm(i)
1104  str = [" $ " str " $ "];/* #ok */
1105 
1106  end
1107  fillstabs = floor((sl*(i~=1)+length(str))/this.TabCharLen);
1108  tottabs = ceil((sl*(i~=1)+this.contlen(i))/this.TabCharLen);
1109  fprintf(outfile," %s%s ",[str repmat(char(9),1,tottabs-fillstabs)],sep);
1110  end
1111  str = row[end];
1112  if istex && this.fTexMMode && ismm(end)
1113  str = [" $ " str " $ "];
1114  end
1115  fprintf(outfile," %s ",str);
1116  }
1125  function [str , ismm ] = stringify(data) {
1126 
1127  /* Format cell array given */
1128  if iscell(data[end])
1129  /* if format cell is only one item but have more values,
1130  * apply same format string */
1131  if length(data[end]) == 1 && length(data)-1 > 1
1132  data[end] = repmat(data[end],1,length(data)-1);
1133  elseif this.HasRowHeader && length(data[end]) == length(data)-2
1134  data[end] = [" %s " data[end]];
1135  elseif length(data[end]) ~= length(data)-1
1136  error(" Either provide a single format string or one for each column. ");
1137  end
1138  str = cell(1,length(data)-1);
1139  /* Apply sprintf pattern to each element */
1140  start = 1;
1141  if this.HasRowHeader
1142  str(1) = this.stringify(data(1));
1143  start = 2;
1144  end
1145  for i=start:length(data)-1
1146  if isa(data[end][i]," function_handle ")
1147  if nargin(data[end][i]) > 1
1148  tmpstr = data[end][i](data[i],i);
1149  else
1150  tmpstr = data[end][i](data[i]);
1151  end
1152  else
1153  tmpstr = sprintf(data[end][i],data[i]);
1154  end
1155  tmpstr = strrep(tmpstr,char(10),);
1156  /* Strip tab chars if set */
1157  if this.StripInsertedTabChars
1158  str[i] = strrep(tmpstr,char(9),);
1159  else
1160  str[i] = tmpstr;
1161  end
1162  end
1163  else /* convert to strings if no specific format is given */
1164 
1165  str = cell(1,length(data));
1166  for i=1:length(data)
1167  el = data[i];
1168  if isa(el," char ")
1169  el = strrep(el,char(10),);
1170  /* Use char array directly and strip tab characters if desired */
1171  if this.StripInsertedTabChars
1172  str[i] = strrep(el,char(9),);
1173  else
1174  str[i] = el;
1175  end
1176  elseif isinteger(el)
1177  if numel(el) > 1
1178  str[i] = [" [ " this.implode(el(:)," , "," %d ") " ] "];
1179  else
1180  str[i] = sprintf(" %d ",el);
1181  end
1182  elseif isnumeric(el)
1183  if numel(el) > 1
1184  if isvector(el) && length(el) < 100
1185  str[i] = [" [ " this.implode(el(:)," , "," %g ") " ] "];
1186  else
1187  str[i] = [" [ " this.implode(size(el)," x "," %d ") " " class(el) " ] "];
1188  end
1189  else
1190  if isempty(el)
1191  str[i] = " [] ";
1192  else
1193  str[i] = sprintf(" %g ",el);
1194  end
1195  end
1196  elseif isa(el," function_handle ")
1197  str[i] = func2str(el);
1198  elseif isa(el," handle ")
1199  mc = metaclass(el);
1200  str[i] = mc.Name;
1201  elseif islogical(el)
1202  if numel(el) > 1
1203  str[i] = this.implode(el(:)," , "," %d ");
1204  else
1205  str[i] = sprintf(" %d ",el);
1206  end
1207  else
1208  error(" Cannot automatically convert an argument of type %s for PrintTable display. ",class(el));
1209  end
1210  end
1211  end
1212  /* Detect if any of the cell contents are numerical values */
1213  fun = @(arg)~isempty(arg) && arg(1) ~= " $ " && arg(end) ~= " $ " ...
1214  && (~isnan(str2double(arg)) || ~isempty(strfind(arg," \ ")) || ~isempty(strfind(arg," _ ")) || ~isempty(strfind(arg," ^ ")));
1215  ismm = cellfun(fun,str);
1216  }
1225  function str = implode(data,glue,format) {
1226  str = ;
1227  if ~isempty(data)
1228  if nargin < 3
1229  format = " %2.3e ";
1230  if nargin < 2
1231  glue = " , ";
1232  end
1233  end
1234  if isa(data," cell ")
1235  str = data[1];
1236  for idx = 2:length(data)
1237  str = [str glue data[idx]];/* #ok */
1238 
1239  end
1240  elseif isnumeric(data)
1241  /* first n-1 entries */
1242  if numel(data) > 1
1243  str = sprintf([format glue],data(1:end-1));
1244  end
1245  /* append last, no glue afterwards needed */
1246  str = [str sprintf(format,data(end))];
1247  else
1248  error(" Can only pass cell arrays of strings or a vector with sprintf format pattern ");
1249  end
1250  end
1251  }
1252 
1253 
1254  /* % Tests */
1255  public: /* ( Static ) */
1256 
1257  static function [res , doublet ] = test_PrintTable() {
1258  t = PrintTable;
1259  t.Caption= " This is my PrintTable test. ";
1260  t.addRow(" A "," B "," C ");
1261  t.addRow(" 123 ",456E10," 789 ");
1262  t.addRow(1234567," 12345 "," 789 ");
1263  t.addRow(" 1234567 ",123456," 789 ");
1264  t.addRow(" 34 "," \sin(x)+4 "," somestring ");
1265  t.addRow(" foo "," bar ",datestr(clock));
1266  t.addRow(123.45678,pi,789,[" %2.3f "," $%4.4g$ "," decimal: %d "]);
1267 
1268  /* If HasHeader is set, the format args can be omitted for the first column. */
1269  t.HasRowHeader= true;
1270  t.addRow(123.45678,pi,789,[" $%4.4g$ "," decimal: %d "]);
1271  t.HasRowHeader= false;
1272 
1273  t.addRow(" 12345678 "," \latexcommand{foo}+5 "," 789 ");
1274  t.addRow(" yet "," 123 "," 789 ");
1275  t.addRow(123.45678,pi,789,[" %2.3f ",@(v)sprintf(" functioned pi=%g! ",v-3)," decimal: %d "]);
1276  t.addRow(2,2,2,[@(v,colidx)sprintf(" callback using column index: %d! ",v^colidx)]);
1277  t.addRow(" single ",pi," fun with colidx ",[" %s ",@(v,colidx)sprintf(" value at column %d: %g! ",colidx,v)," %s "]);
1278  t.addRow(" next col with tabs ",char(9)," StripInsertedTabChars on ",[" %s "," >\t>%s>\t> "," %s "]);
1279 
1280  fprintf(2," test_PrintTable: Plain text display:\n ");
1281  t.display;
1282 
1283  fprintf(2," test_PrintTable: Plain text display with no tab stripping:\n ");
1284  t.StripInsertedTabChars= false;
1285  t.addRow(" next col with tabs ",char(9)," StripInsertedTabChars off (destroys layout) ",[" %s "," >\t>%s>\t> "," %s "]);
1286  t.display;
1287  t.removeRow(t.NumRows);
1288 
1289  fprintf(2," test_PrintTable: Plain text display with header:\n ");
1290  t.HasHeader= true;
1291  t.display;
1292 
1293  fprintf(2," test_PrintTable: LaTeX display:\n ");
1294  t.HasHeader= false;
1295  t.Format= " tex ";
1296  t.print;
1297 
1298  fprintf(2," test_PrintTable: LaTeX display with header:\n ");
1299  t.HasHeader= true;
1300  t.print;
1301  t.HasHeader= false;
1302 
1303  fprintf(2," test_PrintTable: LaTeX display and no TexMathModeDetection:\n ");
1304  t.TexMathModeDetection= false;
1305  t.print;
1306  t.TexMathModeDetection= true;
1307 
1308  fprintf(2," test_PrintTable: LaTeX display of transposed:\n ");
1309  tt = t^t;
1310  tt.print;
1311 
1312  fprintf(2," test_PrintTable: Plain text display of transposed:\n ");
1313  tt.Format= " txt ";
1314  tt.print;
1315  res = true;
1316  }
1326  static function [res , doublet ] = test_PrintTable_Misc() {
1327  t = PrintTable(" This is PrintTable Misc Features test, created on %s ",datestr(now));
1328  t.HasRowHeader= true;
1329  t.HasHeader= true;
1330  t.addRow(" A "," B "," C ");
1331  t.addRow(" header-autofmt ",456,789,[" %d "]);
1332  t.addRow(1234.345,456,789,[" %2.2E "," %d "," %d "]);
1333  t.addRow(" header-expl-fmt ",456,pi,[" %s "," %d "," %2.2f "]);
1334  t.addRow(" nofmt-header ",456,pi,[" %d "," %f "]);
1335  t.addRow(" 1234567 "," 12345 "," 789 ");
1336  t.addRow(" foo "," bar ",datestr(clock));
1337  t.addRow(123.45678,pi,789,[" %2.3f "," %4.4g "," decimal: %d "]);
1338  t.addRow(12345678," 123 "," 789 ");
1339  t.addRow(12345.6789," 123 "," 789 ");
1340  t.display;
1341 
1342  fprintf(2," test_PrintTable_Misc: Tex-Format:\n ");
1343  t.Format= " tex ";
1344  t.print;
1345 
1346  fprintf(2," test_PrintTable_Misc: Tex-Format with Row Header:\n ");
1347  t.HasHeader= true;
1348  t.print;
1349 
1350  fprintf(2," test_PrintTable_Misc: Self-Appended:\n ");
1351  t.Format= " txt ";
1352  ta = t.append(t);
1353  ta.display;
1354 
1355  t2 = PrintTable(" dummy ");
1356  t2.addRow(" A "," B "," C "," D "," E ");
1357  t2.addRow(" header1 ",456,789,1,34,[" %d "]);
1358  t2.addRow(12345.6789," 123 "," 789 "," foo "," bar ");
1359  t2.addRow(" header2 ",4656,35789,351,4);
1360 
1361  fprintf(2," test_PrintTable_Misc: Test table to append:\n ");
1362  t2.display;
1363 
1364  fprintf(2," test_PrintTable_Misc: Appending some test table columns (with header):\n ");
1365  ta = t.append(t2,[1 3 5]);
1366  ta.display;
1367 
1368  fprintf(2," test_PrintTable_Misc: Appending some test table columns (without header):\n ");
1369  t2.HasHeader= true;
1370  ta = t.append(t2,[4 2 1]);
1371  ta.display;
1372 
1373  /* Empty table append test */
1374  t2.clear;
1375  t.append(t2);
1376 
1377  res = true;
1378  }
1388  static function [res , doublet ] = test_PrintTable_LaTeX_Export() {
1389  t = PrintTable(" LaTeX/PDF export demo, %s ",datestr(now));
1390  t.HasRowHeader= true;
1391  t.HasHeader= true;
1392  t.addRow(" A "," B "," C ");
1393  t.addRow(" Data 1 ",456,789,[" %d "]);
1394  t.addRow(1234.345,456,789,[" $%2.2E$ "," $%d$ "," $%d$ "]);
1395  t.addRow(" header-expl-fmt ",456,pi,[" %s "," %d "," %2.2f "]);
1396  t.addRow(" 1234567 "," 12345 "," 789 ");
1397  x = 4;
1398  t.addRow(" x=4 "," \sin(x) ",sin(x),[" %s "," %f "]);
1399  /* Explicit wrapping directly or with $$ per format string */
1400  t.addRow(" x=4 "," 25 (5*5)= ",5*5,[" $%s$ "," %d "]);
1401  /* (have HasRowHeader, thus the first format string is not necessary (but yet
1402  * possible to define)) */
1403  t.addRow(" $x=4,\alpha=.2$ "," \alpha\exp(x)\cos(x) ",.2*exp(x)*cos(x),[" $%s$ "," %f "]);
1404  t.display;
1405 
1406  /* LaTeX */
1407  t.saveToFile(" myLaTeXexportedPrintTable.tex ",true);
1408 
1409  /* Tight PDF */
1410  t.saveToFile(" mytable_tightpdf.pdf ",true);
1411 
1412  /* Whole page PDF */
1413  t.TightPDF= false;
1414  t.TexMathModeDetection= true;
1415  t.saveToFile(" mytable_fullpage.pdf ",true);
1416  res = true;
1417  }
1427  static function [res , doublet ] = test_PrintTable_Failed_LaTeX_Export() {
1428  t = PrintTable(" LaTeX/PDF export demo (THIS MUST FAIL!), %s ",datestr(now));
1429  t.HasRowHeader= true;
1430  t.HasHeader= true;
1431  t.TexMathModeDetection= false;
1432  t.addRow(" A "," B "," C ");
1433  t.addRow(" Data 1 ",456,789,[" %d "]);
1434  t.addRow(1234.345,456,789,[" $%2.2E$ "," $%d$ "," $%d$ "]);
1435  t.addRow(" header-expl-fmt ",456,pi,[" %s "," %d "," %2.2f "]);
1436  t.addRow(1234567," 12345 ",45.3463E-4);
1437  x = 4;
1438  /* This is the offending latex line */
1439  t.addRow(" x=4 "," \sin(x) ",sin(x),[" %s "," %f "]);
1440  /* Explicit wrapping directly or with $$ per format string */
1441  t.addRow(" x=4 "," 25 (5*5)= ",5*5,[" $%s$ "," %d "]);
1442  t.addRow(" $x=4,\alpha=.2$ "," \alpha\exp(x)\cos(x) ",.2*exp(x)*cos(x),[" $%s$ "," %f "]);
1443  t.display;
1444  try
1445  t.saveToFile(" mytable_tightpdf_nodetection.pdf ",true);
1446  catch ME
1447  fprintf(2," TEST FAILED AS EXPECTED, WARNING HAS BEEN ISSUED. ALL GOOD.\n ");
1448  res = true;
1449  return;
1450  end
1451  res = false;
1452  }
1453 
1454 
1455  private: /* ( Static ) */
1456 
1457  static function l = getDefaultTabCharLen() {
1458 
1459  /* Use default value 8 */
1460  defaultLen = 8;
1461 
1462  jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
1463  /* Display of output in command window */
1464  if ~isempty(jDesktop.getClient(" Command Window "))
1465  /* Display of output in console etc */
1466  l = com.mathworks.services.Prefs.getIntegerPref(" CommandWindowSpacesPerTab ",-1);
1467  if l < 0
1468  l = com.mathworks.services.Prefs.getIntegerPref(" EditorSpacesPerTab ",defaultLen);
1469  end
1470  elseif isunix
1471  [c, l] = system(" echo -n $ "" \t "" | wc -L ");
1472  if c == 0
1473  l = str2double(l);
1474  else
1475  l = defaultLen;
1476  end
1477  else
1478  /* Not checked yet for windows command line, but i guess this will be a rare
1479  * occasion. Please share if you encounter this situation. */
1480  l = defaultLen;
1481  end
1482  }
1526 };
1527 
logical HasHeader
Flag that determines if the first row should be used as table header.
Definition: PrintTable.m:266
static function [ res , double t ] = test_PrintTable()
A simple test for PrintTable.
Definition: PrintTable.m:1257
function saveToFile(char filename,logical openfile)
Prints the current table to a file.
Definition: PrintTable.m:522
data
The string cell data.
Definition: PrintTable.m:388
char ColSep
A char sequence to separate the different columns.
Definition: PrintTable.m:256
function clear()
Clears the current PrintTable contents and caption.
Definition: PrintTable.m:654
A MatLab cell array or matrix.
function copy = clone()
Returns a new instance of PrintTable with the same content.
Definition: PrintTable.m:755
function addMatrix(titles, data, varargin)
Definition: PrintTable.m:603
haslatexcommand
Flag to maximize user convenience; this is set whenever a row adding resulted in a string containing ...
Definition: PrintTable.m:425
integer TabCharLen
Equivalent length of a tab character in single-space characters.
Definition: PrintTable.m:244
char Caption
A caption for the table.
Definition: PrintTable.m:316
reshape
hanges the dimensions of the handle object array to the specified dimensions. See the MATLAB reshape ...
function display()
Overload for the default builtin display method.
Definition: PrintTable.m:468
An integer value.
A MatLab function handle.
Matlab's base handle class (documentation generation substitute)
mathmode
Flag matrix to indicate if a cell value is numeric or not.
Definition: PrintTable.m:399
function print(integer outfile)
Prints the current table to a file pointer.
Definition: PrintTable.m:481
function this = sort(integer colnr,char direction)
Sorts this table in alphanumeric order.
Definition: PrintTable.m:680
function removeRow(integer idx)
Removes a row from the PrintTable.
Definition: PrintTable.m:665
A boolean value.
logical HasRowHeader
Flag that determines if there is a row header for the table.
Definition: PrintTable.m:278
function joined = append(PrintTable table,rowvec< integer > columns)
Appends the cell contents from another table to this table.
Definition: PrintTable.m:778
A variable number of input arguments.
logical TexMathModeDetection
Flag that tells the PrintTable to surround numerical values with dollar signs "$$" to obtain a more s...
Definition: PrintTable.m:370
logical TightPDF
Flag that indicates if exported tables in PDF format should be sized to the actual table size or be c...
Definition: PrintTable.m:330
contlen
Maximum content length for each colummn.
Definition: PrintTable.m:414
PrintTable: Class that allows table-like output spaced by tabs for multiple rows. ...
Definition: PrintTable.m:17
function char str = toString()
Returns a character array representation of the current table.
Definition: PrintTable.m:507
function addRow(varargin)
Adds a row to the current table.
Definition: PrintTable.m:611
PrintTable(char caption,cell varargin)
Creates a new PrintTable instance.
Definition: PrintTable.m:447
integer NumRows
The number of rows in the current table.
Definition: PrintTable.m:357
function transposed = ctranspose()
Definition: PrintTable.m:740
A MatLab character array.
enum Format
The output format of the table when using the print method.
Definition: PrintTable.m:303
static function [ res , double t ] = test_PrintTable_Misc()
A simple test for PrintTable.
Definition: PrintTable.m:1326
logical StripInsertedTabChars
Flag that determines if inserted tab characters are stripped from any string to preserve the correct ...
Definition: PrintTable.m:342